Welcome Guest ( Log In | Register )



 
Reply to this topicStart new topic
> Emacs Lisp, A quick calcualtion tool
mitchellmckain
post Aug 6 2006, 08:51 AM
Post #1


Premium Member
Group Icon

Group: [HOSTED]
Posts: 361
Joined: 28-April 05
From: Salt Lake City, Utah
Member No.: 4,500



This tutorial seeks to teach by example since I find this the most efficient way to learn a computer language myself.

I want to introduce what has been an extremely valuable tool in my work. It was difficult to decide whether to put it under programming or software, for although the use of it that I am suggesting involves programming in lisp, it is the specific software called emacs that I am introducing as a useful tool. However this could also be considered a tutorial in emacs lisp.

You can get a free copy for your pc from
http://www.gnu.org/software/emacs/windows/ntemacs.html

Emacs is a text editor and lisp interpreter combined. First of all it is a powerful and useful alternative to Notepad allowing you to handle control characters in your text files more readily (for example) among many other things. Second, it is a quick and easy way to do calculations without all the preliminaries required in using other programming languages. When you combine the text manipulation commands with the lisp interpreter it becomes a powerful analytical tool.

Before explaining this lets start on the basics of lisp programing. Lisp is a calculation based language, meaning that Lisp is composed of expression that are evaluted to produce some calculated result. A lisp program is such an expression and the calculated result of this expression is automatically displayed. A lisp expression is placed between two brackets (also known as parentheses), starting with an operation identifier and followed by the arguments of that operation separated by spaces.

Since I am typing this in emacs (in lisp interaction mode) you will see the actual output when the progam is run, which I get by pressing control j after the program (after the last close parentheses) right in the same place where I am typing this text. Emacs just inserts the result of the program on the next line in the text. So after each lisp program I write I will use control j and you will see the output immediately following the lisp program. You can also press control x control e at the end of the program to execute the program and display the results at the bottom of the screen without inserting the result into the text.

The following are some examples of simple lisp programs consisting of a single simple mathematical expression.

(+ 1 2)
3

(+ pi 2)
5.141592653589793

(cos pi)
-1.0

(log 2)
0.6931471805599453

For a y^x calculation you use the expt operation

(expt 5 3)
125

In order to do multiple operations you nest the parentheses like this

(cos (/ pi 4.0))
0.7071067811865476

As you can see the cosine is in radians and the logarithm is the natural logarithm. However the common base 10 logarithm is also available and is called log10. But if you want a cosine in degrees, you have to program your own fuction with the "defun" operation.

(defun cosd (x)
(cos (* pi (/ x 180.0))))
cosd

When you press the control j at the end of this program (after the last parentheses), the interpreter prints just out the name of the function like this and after this you can use this function in other lisp programs like this:

(cosd 45)
0.7071067811865476

Now that you have been introduced to the lisp language, I will now show you will show you what I found this emacs system so useful for, before continuing with an introductory tutorial in emacs lisp. Emacs is very useful in manipulating and calculating with charts of data in plain text format. For example, the following are the top 10 entries of a webpage listing the 10 brightest stars, with their distance in light years, their visual magnitude, their absolute magnitude, and their spectral classification.

Sun - -26.72 4.8 G2V
Sirius Alpha CMa 8.6 -1.46 1.4 A1Vm
Canopus Alpha Car 74 -0.72 -2.5 A9II
Rigil Kentaurus Alpha Cen 4.3 -0.27 4.4 G2V + K1V
Arcturus Alpha Boo 34 -0.04 0.2 K1.5IIIp
Vega Alpha Lyr 25 0.03 0.6 A0Va
Capella Alpha Aur 41 0.08 0.4 G6III + G2III
Rigel Beta Ori ~1400 0.12 -8.1 B81ae
Procyon Alpha CMi 11.4 0.38 2.6 F5IV-V
Achernar Alpha Eri 69 0.46 -1.3 B3Vnp

Now if I use tab-to-tab-stop (esc i) command I can line up the numbers to make this easier to read. Actually most of tabulated data like this on the internet is already aligned into collumns so you dont usually have to do this.

CODE


Sun                                          -              -26.72 4.8  G2V            
Sirius Alpha CMa                             8.6            -1.46  1.4  A1Vm          
Canopus Alpha Car                            74             -0.72  -2.5 A9II          
Rigil Kentaurus Alpha Cen                    4.3            -0.27  4.4  G2V + K1V      
Arcturus Alpha Boo                           34             -0.04  0.2  K1.5IIIp      
Vega Alpha Lyr                               25             0.03   0.6  A0Va          
Capella Alpha Aur                            41             0.08   0.4  G6III + G2III  
Rigel Beta Ori                               ~1400          0.12   -8.1 B81ae          
Procyon Alpha CMi                            11.4           0.38   2.6  F5IV-V        
Achernar Alpha Eri                           69             0.46   -1.3 B3Vnp          



Now what makes emacs so powerful for charts like this are a set of commands that allow you to cut and paste rectangular portions of text. First we set the rectangle by moving the cursor to one corner and pressing control space then moving the cursor to an opposite corner. Next the control x control k command will cut the rectangle so that when we move the cursor and press control x control y it will paste this rectangle in the new position (after and below the cursor). We can use this on the above chart to move the column of spectral classifications like this.

CODE

Sun                                          G2V            -              -26.72 4.8  
Sirius Alpha CMa                             A1Vm           8.6            -1.46  1.4  
Canopus Alpha Car                            A9II           74             -0.72  -2.5
Rigil Kentaurus Alpha Cen                    G2V + K1V      4.3            -0.27  4.4  
Arcturus Alpha Boo                           K1.5IIIp       34             -0.04  0.2  
Vega Alpha Lyr                               A0Va           25             0.03   0.6  
Capella Alpha Aur                            G6III + G2III  41             0.08   0.4  
Rigel Beta Ori                               B81ae          ~1400          0.12   -8.1
Procyon Alpha CMi                            F5IV-V         11.4           0.38   2.6  
Achernar Alpha Eri                           B3Vnp          69             0.46   -1.3


Now supposed we wanted to check the numbers in this chart for accuracy. We can use the magnitudes to make our own distance calculation using the formula:
d = 3.26 10^(.2 (a - v + 5))
and compare this with the distance listed in the chart.

First we program a function in lisp to do this calculation.
(defun dist (v a)
(* 3.26 (expt 10.0 (* .2 (- v a -5)))))
dist

Next I insert "(dist " before the third column using paste (control y), and then I add an end parentheses ")" at the end of each line to get this

CODE

Sun                                          G2V            -              (dist -26.72 4.8  )
Sirius Alpha CMa                             A1Vm           8.6            (dist -1.46  1.4  )
Canopus Alpha Car                            A9II           74             (dist -0.72  -2.5 )
Rigil Kentaurus Alpha Cen                    G2V + K1V      4.3            (dist -0.27  4.4  )
Arcturus Alpha Boo                           K1.5IIIp       34             (dist -0.04  0.2  )
Vega Alpha Lyr                               A0Va           25             (dist 0.03   0.6  )
Capella Alpha Aur                            G6III + G2III  41             (dist 0.08   0.4  )
Rigel Beta Ori                               B81ae          ~1400          (dist 0.12   -8.1 )
Procyon Alpha CMi                            F5IV-V         11.4           (dist 0.38   2.6  )
Achernar Alpha Eri                           B3Vnp          69             (dist 0.46   -1.3 )


So now when I go the the end of each line and press control j I get

CODE

Sun                                          G2V            -              (dist -26.72 4.8  )
1.6188909679280947e-005

Sirius Alpha CMa                             A1Vm           8.6            (dist -1.46  1.4  )
8.734088738910044

Canopus Alpha Car                            A9II           74             (dist -0.72  -2.5 )
73.9975941714126

Rigil Kentaurus Alpha Cen                    G2V + K1V      4.3            (dist -0.27  4.4  )
3.7950508558782015

Arcturus Alpha Boo                           K1.5IIIp       34             (dist -0.04  0.2  )
29.188891356916752

Vega Alpha Lyr                               A0Va           25             (dist 0.03   0.6  )
25.073652353343473

Capella Alpha Aur                            G6III + G2III  41             (dist 0.08   0.4  )
28.133100657203222

Rigel Beta Ori                               B81ae          ~1400          (dist 0.12   -8.1 )
1436.208855031364

Procyon Alpha CMi                            F5IV-V         11.4           (dist 0.38   2.6  )
11.727828326077196

Achernar Alpha Eri                           B3Vnp          69             (dist 0.46   -1.3 )
73.31918015024647



If you look at the results above you will see something than I observed years ago, the data found in charts like this on the internet are not always very consistent. Capella is the worst here, comparing 28.133 light years to 41 light years we see this is off by more than 45%. Since the result for the sun has no comparison, lets multiply by the number of seconds in a year:
(* 60.0 60.0 24.0 365.25)
31557600.0

to get the distance to the sun in light seconds

(* 31557600.0 1.6188909679280923e-005)
510.8831360948757

which we can compare to the usual value of 499 light seconds.

Now lets go back to the topic of emacs lisp and cover some of the usual programing basics for this language in a quick summary, just in case you need them.

To set the value of a variable for use in a program you can use the setq operation.

(setq i 0)
0

For temporary variables within a program you can use the let operation. The following sets the variables a, b, and c to values which are used in each of the operations inside the let.

(let ((a 1.3) (b (log 2)) (c (log 10)))
(+ a b c)
(- (* a b c) (* a b) (* a c)))
-1.819612480849552

Notice that only the result of the final calculation is displayed. To display something else during the running of a program you can use the print operation.

(let ((a 1.3) (b (log 2)) (c (log 10)))
(print (+ a b c ))
(- (* a b c) (* a b) (* a c)))

4.295732273553991
-1.819612480849552

Since the let operation also lets you combine a series of calculations into a single program, you can use the let operation with an empty list of assignments just so you can take advantage of this feature. But rembember that only the result of the last calculation will be displayed unless you use the print command as follows.

(let ()
(print (* 2 3 4))
(print (* 3 4 5))
(print (* 4 5 6))
(* 5 6 7))

24

60

120
210

Logical testing operations like < = > <= and >= are also available. The following computes (log 2) and (log 10) and tests to see if the first is less than the second.

(< (log 2) (log 10))
t

Here it tests to see if log 2 is greater than log 10.

(> (log 2) (log 10))
nil

Notice that these testing operations display "t" for true and "nil" for false

The if operation uses these testing operations like this:

(if (< (log 2) (log 10))
(sin 2)
(sin 10))
0.9092974268256817

The if lisp operation takes three arguements, the first is the test, the second is the program which is run or value which is returned if the test returns true (t) and the third is the program that runs or value which is returned if the test is false (nil). So in the above example, only the first program calculating the sine of 2 is performed and displayed because the test evaluates to true.

After seting a few variables we can use the while operation for a loop to calculate the first five factorials. The first argument of the while operation is also a test, but this is followed by any number of calculations all of which are performed repeatedly as long as the test evaluates to true. The variables can be set using the setq operations but since i and j are temporary variables it makes more sense to use a let operation and this will make re-running the program much easier.

(let ((i 0) (j 1))
(while (< i 5)
(setq i (+ i 1))
(setq j (* j i))
(print j))
(list j 'is i 'factorial))

1

2

6

24

120
(120 is 5 factorial)


But the more usual way to do a loop in the lisp programming language is with a recursion. A recursion is a function that calls itself. When you do this it is important to test the input to check whether it is time to stop calling itself or you get an infinite loop.

(defun fact (x)
(if (= x 1) x
(* x (fact (- x 1)))))
fact

This defines the factorial function so we can get any factorial up to 99! when the maximum number of recursions is reached.

(fact 5)
120

(fact 99.0)
9.33262154439441e+155

Notice that I used 99.0 rather than 99. This was to make lisp use floating point arithmetic to avoid exceeding the maximum sized integer allowed.

Now perhaps I should mention that lisp was specifically designed to handle lists and in fact the name lisp comes from "list processing". A list is a series of space separated items inside parentheses. So for example a lisp program is itself a list. There are a number of operation in lisp used to create, combine, and extract portions of lists.

The list operation combines a series of arguments into a list
(list 1 2 3)
(1 2 3)

The cons operation appends an item to the front of a list. The single quotation mark is used in front of a list to prevent it from being evaluated like a program.

(cons 1 '(2 3))
(1 2 3)

car extracts the item at the beginning of a list.

(car '(1 2 3))
1

cdr extracts the list that remains when the first item is removed.

(cdr '(1 2 3))
(2 3)

cadr extracts the item second item of a list and it is called cadr because it is the same as the successive operations of cdr then car.

(cadr '(1 2 3))
2

(car (cdr '(1 2 3)))
2

cddr extract the the list that remains when the first two times are removed and it is called cddr because it is the same as the successive operation of cdr and cdr again.

(cddr '(1 2 3))
(3)

If a list is a program you can use the eval operation to run it.

(eval '(+ 1 2))
3

Here, for example, is a function that takes a list of programs and runs them to create a list of results. null tests a list to see if it is empty '() and nil is another way of representing the empty list.

(defun evalist (x)
(if (null x) nil
(cons (eval (car x)) (evalist (cdr x)))))
evalist

Now lets try this function out.

(evalist '((+ 1 2) (- 1 2) (* 1 2)))
(3 -1 2)

Now the whole emacs text editor is really a lisp interpreter and all of the text editing commands are lisp operations.

So if you press control x control e at the end of the following program it will actually move the cursor to the second line of the file that is loaded into emacs.

(goto-line 2)

To play around with this it would be more convenient to use two seperate windows in emacs (created using the split-window operation or control x 2). One with the file to edit in one window and your lisp programs in the other.

The following program will goto the begining of the file in the other window and then find every # character and ask you if you want it replaced by a % character.

(let ()
(other-window 1)
(goto-line 0)
(query-replace "#" "%"))

For more details on emacs lisp and a more careful explanation of the operations see http://www.gnu.org/software/emacs/emacs-lisp-intro/

There is also a detailed manual at http://www.tac.nyc.ny.us/manuals/elisp/elisp_toc.html

This post has been edited by mitchellmckain: Aug 13 2006, 08:50 PM
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic

Collapse

> Similar Topics

Topics Topics
  1. Hotkeys / Keyboard Quick Launch Keys In Linux(5)
  2. Switch Network Settings With Batch Files(16)
  3. A Vital Tool For Your System!(8)
  4. Free Modeling Software Softimage Xsi 4.2 Mod Tool(2)
  5. Keyword Research Tool(8)
  6. Quick Html!(3)
  7. How To Set Up A Secure Socket Layer (ssl) Into Your Website?(5)
  8. Just A Quick Question.(3)
  9. How To Get Quick And Easy Levels In Runescape(12)
  10. Sketching Tool(1)
  11. Scar(2)
  12. Learning To Use The Pen Tool In Photoshop(0)
  13. Searching For A Good Dvd Video Editing Tool(0)
  14. Freeware Dvd Authoring Tool(1)
  15. Linux - Handy Tool If You Can't Unmount Due To Open Files(0)
  1. A Single Effective Tool To Completely Clean Up Your Pc(0)
  2. Amazing Results From Reverse Ip Domain Check Tool(7)
  3. Does Google Provide This Tool?(9)
  4. Overclocking Core 2 Quad(4)
  5. A Quick Start Guide Anyone?(6)
  6. Clean Memory, A Useful System Tool(4)
  7. Url Rewriting Tool(0)
  8. Access Linux Box From Windows Machine- Putty Tool(2)
  9. C/c++ -gdb Linux Debug Tool(0)
  10. Website To Country Seo Tool(0)
  11. Code To Text Ratio Tool(0)
  12. Spider Simulator Tool(0)
  13. Site Link Analyzer Tool(1)


 



- Lo-Fi Version Time is now: 4th July 2008 - 03:15 AM