This document contains the documentation for EULER. The information here is valid for all versions of EULER.
This section gives information about the origins of EULER, the author and the copyright notice. Topics are
I will not take responsibility for any damage EULER does to your data, files or computer, or any other damage. You use EULER on your own risk. You may not sell EULER. You may distribute all freeware versions of EULER. But charges may only cover copy and shipping costs. The copyright remains with the author.
EULER is a program for quickly and interactively
computing with real and complex numbers and matrices, or with intervals. It can draw your functions in two and
three dimensions. However, it should be stressed that EULER is not a computer algebra program. You should start
the demo for more information. If you are using a notebook version, you can start with loading
the welcome notebook.
The most recent versions of are made available on am.ku-eichstaett.de in the directories /pub by anonymous ftp.
The Copyright on EULER remains with the program author (About the author).
Refer to the following sections for further information.
Please, send bug reports and other comments
to the address below.
The author is interested in applications of EULER and will collect them. These applications will then be included in program updates. Some interesting applications are included (with extension *.E).
The author wishes anyone success using EULER. Please send me bug reports. I will do my best to make EULER as bug free as possible.
Dr. R. Grothmann Ahornweg 5a D-85117 Eitensheim Germany EMail: grothm@am.ku-eichstaett.de
Visit my hompage or mail me.
This section briefly introduces EULER and shows what it is all about. Available Topics are
The idea of EULER is a system with the following features
Most version are in a notebook style. You can edit old commands and execute them again. Moreover, you can add text to every command. The notebook supports a color scheme to distinguish between commands, text and output.
EULER is an ideal tool for the tasks such as
EULER consists of the following files at least
There are some additional files, which help using the program
You should name your EULER program files *.E.
To exit EULER issue the command> quit or close the EULER window.
The best way to get a good introduction into EULER is to run the demo. To do that issue the command
>load demo
Do not enter the prompt ">" and press the Return key. Of course, the file DEMO must be in the active directory. This is usually the progs directory and shoudl be set up automatically. There is also an automatic, non-interactive demo, which you might load with
>load autodemo
You can learn to program EULER by studying the demo file, of course.
If you are using a notebook version, you should start by loading the welcome.en notebook.
You can select Help from the menu bar or press the F1 key to see the help text. Also
>help function
will show the help text of a function (see "programming EULER"). For user defined functions, this is a very good way to remember their purpose and give some documentation to the user.
For builtin functions and commands, the help command will display the help text from HELP.TXT. This file is loaded at the start of EULER and is ASCII readable. The format is simple and you are welcome to extend this file with your own comments. It does also contain help for brackets, as in
>help (
This information is only valid for The Windows and the OS/2 versions of Euler. Available topics are
EULER uses two windows. The text window and the graphics window.
The text window contains the menu and is designed for user input and output of EULER. It is a scrollable window. One can use the scrollbar to scroll through available text or the page keys. All user input is preceded by a prompt (>). (See about the line editor for information about user input.)
The graphics window is displayed, whenever EULER draws output. Unless the graphics screen has been cleared, EULER will redraw the screen automatically using an internal meta file. The graphics screen is visible as long as there is no text output. In this case, EULER pops the text screen to the forground.
This applies only to notebook interfaces. They contain the command texts and output in notebooks. I.e., old commands can be edited and changed. Text may be added to commands to explain them. This is a smooth and flexible interface. Furthermore, notebook files can be given to other people or can be kept as documented computations. However, collections of functions should still be kept in *.E files. A notebook could accompany the definitions, which explains the use of the functions. Another idea is to use notbooks for teaching mathematics.
The most important fact about notebooks is that EULER still uses the sequence of commands as they are executed. So if you change the value of a variable and go to previous command, the changed value is used.
You may not only change previous commands, but also delete them or insert new commands. Use the notebook menu to do this. If you change a command and execute it, its output is removed and EULER proceeds to the next command, unless you choose to insert new commands. In this case, a new command is inserted after the one, you just executed.
You can delete the output of commands. To do this, select a text area and use the command in the notebook menu. All output of selected commands will be deleted.
Notebooks can be loaded from all versions of EULER. However, you cannot edit them. Use
>notebook filename
for that purpose. It will prompt you after each command. If you press the escape key, the file will be closed immediately. Otherwise, the command is executed. You can turn the prompt off with
>prompt off
This section explains the use of the EULER command line, the menu options and other topics. Available topics are
Text can be entered after the prompt (>) using the keyboard. If a letter is wrong, it can be cancelled with the Backspace key. The cursor keys -> and< - position the cursor back and forth in the line. The line editor is always in insert mode, so any character is inserted at the cursor position. Pos 1 (Home) positions the cursor to the beginning of the line, and end to the end of the line. Escape clears all input. Shift plus -> or< - position the cursor one word to the right or left. Finally, the input is entered by pressing Return. Then EULER will start to interpret the command. The cursor can be at any position of the input line, when Return is pressed.
Previous input can be recalled with the cursor-up and cursor-down keys. (On the notebook version use these keys with SHIFT). If a command is recalled this way and entered with Return, cursor-down recalls the next command; i.e., cursor-up and cursor-down are always based on the last recalled command. Clearing the input line also makes the last command the base for recalling (use Escape or Control-Cursor-Up). Thus Escape plus cursor-up recalls the previous command.
The notebook interface uses the escape key to end a function definition. It will not clear the input line. Use Control-Cursor-Up instead.
Pressing the Insert key extends incomplete commands. Pressing this key again gives another extension, if there is one. The search goes through the command history, the implemented functions, the user defined functions and the built-in commands in that order.
There are some other special keys. The Tabulator key switches to the Graphics screen and from there any key switches back. The Escape key stops any running EULER program and some internal functions, like the 3-dimensional plots, the linear equation solver and the polynomial root finder.
The Page-Up and Page-Down keys provide a means to look at previous output from EULER. EULER keeps a record of the last output. When the command line becomes invisible, pressing any key will make it reappear.
Input can spread over several lines by the use of "..". The two dots are allowed at any place, where a space is acceptable. E.g.
>3+ .. some comment >4
is equivalent to
>3+4
Comments can follow the ".." and are skipped.
The function keys may be programmed by the command
>setkey(number,"text");
The number must be between 1 and 10 and the "text" may be any EULER string. Then the corresponding function key will produce the text, when it is pressed together with the ALT key . If the function key text is to contain a ", one can use char(34) and the EULER string concatenation, as in the example
>setkey(1,"load "|char(34)|"test"|char(34)|";");
which puts
>load "test";
on the function key Shift-F1.
To abbreviate tedious input one may generate a file containing EULER input. This file can be generated with any editor. To load that file enter
>load filename
All lines of that file are then interpreted just as any other input from the keyboard. Also a loaded file may itself contain a load command. If an error occurs, the loading is stopped and an error message is displayed. There is a default extension ".e", which you should use for your files. You need not specify this extension in the load command. The filename may be included in double quotes. If you are using a string expression, include it in round brackets.
EULER looks for the specified file in the active directory by default. You may specify a path with the path statement
>path "..."
where the string should contain a path like ".;myspecial". This would put the active directory into the path and a subdirectory named myspecial. The path command is handy for network setups. The best use of a load file is to define functions in that file. EULER files should have the extension .E (e.g., DEMO.E).
A file may contain a comments. Comments look like this
comment This is a comment. Comments can spread several lines. Also empty lines are allowed. endcomment
endcomment must be the first string of a line.
You can turn comment printing off with
comment off
Otherwise all comments in a file are displayed, when the file is loaded.
comment on
turns this feature on.
This sections explains EULER expressions etc., but omits programming aspects. Available topics are
EULER uses the following data types
The meaning of the first five data types should be clear. EULER tries to keep an evaluation real. But as soon, as complex data is involved the computation gets complex. That is why
>sqrt(-1)
results in a wrong answer, but
>sqrt(complex(-1))
is 0+1*i. complex(x) is a way to make a real number complex.
Strings are used for explaining output, file names, passing functions to functions, expression strings and function key texts. There are only two some operators, like the concetanation | and the compare operators.
References are used internally for parameters of functions (see the programming section).
Functions are the user defined functions including the functions in UTIL.
All these data are kept on the stack. Usually, the user does not have to worry about the stack, since EULER uses normal mathematical notation for expressions. Internally, the evaluation of an expression uses the stack rather heavily. Programs are kept in the lower area of the stack. The stack is also used to pass parameters to built-in or user defined functions and to keep the local variables of these functions.
Finally, we remark that the data explained in this section are different from built-in functions which can be used in the same places as user defined functions. There are also commands, which cannot be used in expressions. Built-in functions and commands are part of the code of EULER.
A complete list of built-in functions, commands and user defined functions is printed by
>list
A list of all variables can be obtained with
>listvar
If size information is needed, the command
>memorydump
is available. A hexdump of any data can be obtained with
>hexdump name
but it will only be useful for insiders.
>store("filename")
stores the content of the EULER stack into a file.
>restore("filename")
loads that file. This is a short way of storing a session including the global variables and functions.
Explains the basic input types, such as
EULER input is either a "command", an "expression" or an "assignment".
An example for a command is
>quit
which quits the EULER system. By and by, we will mention a few others. Another example is "load".
An expression is a valid EULER expression, which has a resulting value. If it is entered on its own or followed by a ",", this value is printed.
>3+4*5
prints the value 23.00000. The print is surpressed, if the expression is followed by a ";". This makes sense, since some functions have side effects and their result is not needed, or since the user does not want to see the long output of an assignment.
The printing is done with a format determined by the function
>format([n,m])
where n is the total width of print and m is the number of digits after the decimal dot.
>format(n,m)
does the same thing, but is a little bit slower since it is a function in UTIL. The output automatically switches to exponential format, if there is not enough space to display the number in fixed format. There is also the command
>goodformat(n,m)
which does ommit decimal digits, if they are zero.
>longformat()
is a function in UTIL, which sets a longer output format, while
>shortformat()
sets a shorter one. Both use goodformat.
You can specify to have exponential format or fixedformat with
>expformat(n,m) >fixedformat(n,m)
The format of goodformat command will switch between exponential and fixed format.
There is also support for output as a fraction (like 1/3).
>fracformat(n,eps)
will output numbers with n places and an accuracy of eps as fractions. Default for n is 20 and, for eps is the internal epsilon. Usually fracformat() will would be used. The other formats (like shortformat) switch this type of output off.
For intervals, you may use
>iformat(n)
This will print as many digits as necessary to show the differences between left and right interval bounds. The output width will be at least n.
>iformat(0)
switches back to the usual format.
An assignment looks like
>variablename=value
The variable name must start with an alphanumeric, and continue with alphanumeric characters or digits. The command assigns the value to the variable, which is declared by the assignment, and prints the value. If the assignment is followed by a ";", then the printing is surpressed. An assignment may be followed by ",", which prints the right hand side of the assignment.
The syntax is of a multiple assignment is
>{x,y,...}=expression
This does make sense only in cases, when the expression is the result of a function with multiple values. If a multiple expression is assigned to a single variable, only the first value is used.
Describes the syntax of EULER expressions. E.g.,
The most simple expressions are variables. Their value is the value of the variable, and their type is the type of the variable. If the variable is undefined, interpreting the expressions will stop with an error message.
The basic constant expressions are numbers. Those are entered in the usual form 100, 100.0, 1e2, or 1.0e+2. The letter "small e" indicates powers of 10. An appendix "i" indicates multiples of the complex unit "i". "1+1i" is in fact a sum of 1 and 1i.
A matrix is entered in the brackets "[" and "]" row by row. The columns are seperated by "," and the rows by ";". Example
>A=[1,2,3;4,5;6]
This is equivalent with
>A=[1,2,3;4,5,0;6,0,0]
The matrix is real, if all entries are real, otherwise it is complex. If an entry of a matrix is an interval, the matrix becomes an interval matrix.
If a row is shorter than the others, it is filled with zeros. A matrix constant can spread over several lines.
One can also use a 1xn matrix as part of another matrix, like in
>x=[1,2,3,4] >A=[7,x]
A will be [7,1,2,3,4] then.
A submatrix is a matrix, which is made up by the entries of another matrix. The simplest example is a matrix element
>A[1,1]
which is the element in the first row and column of A. Note, that submatrices can be assigned values. Thus
>A[1,1]=4.5
is a legal statement. However, if the submatrix has more than one element, the value must either be a matrix of equal size or a scalar. I.e.
>A[1:2,:]=0
will set the first two rows of A to 0. If a submatrix gets complex, the matrix gets complex. If v is a 1xN or Nx1 matrix (i.e., a vector), then v[1] is the first element of v; i.e.,
>v=[1.5,-2,0,4.8]; v[3]
is 0. Let us assume now that A is a matrix and r and c are vectors. Then A[r,c] results in a matrix, which consists of the rows r[1],r[2],... of A, and from these rows, only the columns c[1],c[2],... are taken. Example
>A[[1,2],[1,2]]
is the upper left 2x2 submatrix of A. If a row or column does not exist, it is simply neglected. Thus, if A is a 4x4 matrix, then A[[4,7],[4,7]] results in the value A[4,4]. A special thing is A[1], which is the first row of A. To be precise, if only one index is present, then the second index is assumed to be ":". A ":" indicates all rows or columns; i.e., A[,1] is the first column of A, and A[,] is A itself. Another example
>v=[-1,-2,-3,-4,-5]; v[[5,4,3,2,1,1]]
is the vector [-5,-4,-3,-2,-1,-1]. If A is a 4x4 matrix, then A[[2,1]] is a 2x4 matrix, which consists of the second row of A on top of the first row. Note, that there may be a 0xN or Nx0 matrix.
For compatibility reasons, the square brackets can be replaced by round brackets. Thus, A(1,1) is the same thing as A[1,1]. But A[1,1] is faster. Furthermore, if there is a function A, then A(1,1) will result in a function call to A.
A{i} is the i-th element of the matrix A, as if the NxM Matrix A was a vector of length N*M. This is useful for making functions work for matrices, and is really the quickest way to access a matrix element. It works also, if the matrix A is to small or a real or complex scalar variable. Then the result is the last element of A.
String constants are enclosed in double quotes, like in
>string="This is a text"
or in two single quotes to make it possible to include quotes in strings
>string=''This is a "text"''
The section on the line editor shows how to insert a double quote into a string. A single character with ASCII code n can be produced by
>char(n)
The ":" serves to generate a vector quickly. Thus
>1:10
generates the vector [1,2,3,4,5,6,7,8,9,10]. A step size may be given as in the example
>5:-1.5:1
which yields [5,3.5,2]. By numerical reasons, one cannot expect to hit 1 exactly with 00.11. However, the program uses the internal epsilon to stop generating the vector, so that 00.11 yields the desired result. By default, the internal epsilon is set so that even
>0:0.0001:1
works correctly.
If A is a matrix expression (an expression of type matrix), then A' is the transposed matrix.
The binary operator "|" puts a matrix aside another; i.e., if A is a NxM matrix and B is a NxK matrix, then A|B is a Nx(M+K) matrix, which consists of A left of B. Analogously, A_B puts A atop of B. These operators work also for numbers, which are treated as 1x1 matrices. They do even work, if A is a Nx0 or 0xN matrix.
The mathematical operators +,-,*,/ work as usual for numbers. For matrices they work elementwise. If a is a number and B a matrix, then a+B or B+a computes the sum of all elements of B with a. If v is a 1xN vector and A an MxN matrix, then v+A adds v to each row of A. A+v yields the same result. If v is an Mx1 vector and A an MxN matrix, then each element of v is added to all elements in the corresponding row of A. If v is an Mx1 vector, and w is a 1xN vector, then v+w is an MxN matrix, which has the sums of corresponding elements of v and w as entries (The i-j-th elements is v[i]+w[j]). w+v yields the same result.
Of course, the same rules hold for all other operands and functions of two parameters. The reason for these rules will become apparant later on. But the guidline is, that one can easily generate tables of functions for tables of parameters.
Of course, -A negates all elements of A. EULER knows the rule, to compute "*" and "/" before "+" and "-". One can also write ".*","./" for compatibility reasons. If A has a different size as B, and neither A or B is a 1x1 matrix or a number, then A+B results in error.
Note, that the matrix product is computed with "A.B".
Of course, one can use the round brackets ( and ) to group expressions like in
>(1+5)*(6+7^(1+3))
The power operator can be written "^" or "**" (or ".^"). It computes the power elementwise, like all the other operators. So
>[1,2,3]^2
yields [1,4,9]. The power may also be negative; i.e., the integer powers of all numbers are defined. For a matrix, inv(A) computes the inverse of A (not "A^-1"!). Note, that "^" has precedence, so
>-2^2
is -4.
Comparison of values can be done with> ,> =,< ,< =, != (not equal) or == (equal). They result in 1 or 0, where 1 is TRUE. Again, these operators work elementwise; i.e,
>[1,2,3,4]>2
yields [0,0,1,1].
>!A
(not A) is a matrix, which is 1 on all zero elements of A, and 0 on all nonzero elements of A.
>A && B
is a matrix, which is 1 whenever the corresponding elements of A and B are nonzero.
>A || B
is 1 whenever the corresponding element of A is nonzero or the corresponding element of B is nonzero.
>any(A)
yields 1 if any element of A is nonzero.
One can change dimensions of a matrix with
>B=redim(A,[n,m])
or
>B=redim(A,n,m)
This will copy the content of A to B filling with 0 if necessary. A matrix is stored row by row.
There are several built-in functions which generate matrices. The most elementary ones are zeros([N,M]) and ones([N,M]), which can also be written zeros(N,M) and ones(N,M). They produce a NxM matrix, which is filled with ones or zeros respectively. The input for zeros and ones is the output of the "size" function, which is [N,M] for size(A), if A is an NxM matrix. Note, that one can also generate 0xN and Nx0 matrices. So
>zeros[0,5]_v_v
is a legal statement, if v is a 1x5 vector.
>size(A)
returns the size of the matrix A as a 1x2 vector [n,m]. It is also possible to give size several arguments. Then
>size(A,B,...)
results in the size of the largest matrix of A,B,... However, all matrixes in the list must have the same size, unless their size is 1x1. The use of this feature will become apparent later on. Also
>cols(A) >rows(A)
return the number of columns and rows of a matrix A.
>length(A)
it the maximum of the number of columns and rows. More generally,
>matrix([N,M],x)
or matrix(N,M,x) returns a NxM matrix filled with x, which may be real or complex.
>diag([N,M],K,v)
produces a NxM matrix, which has the vector v on its K-th diagonal and is 0 everywhere else. If v is not long enough, the last element of v is taken for the rest of the diagonal. The 0-th diagonal is the main diagonal, the 1-st the one above, and the -1-st the one below. So
>diag([5,5],0,1)
produces the 5x5 identity matrix. The same can be achieved with
>id(5)
from UTIL. One can also write diag(N,M,K,v), as this is defined in UTIL.
>diag(A,K)
is a vector, which is the K-th diagonal of A.
>dup(v,N)
duplicates the 1xM vector N times, such that a NxM matrix is generated, which has v in each row. If v is an Mx1 vector, then v is duplicated into the N columns of a MxN matrix. dup works also, if v is a number. Then it generates a column vector.
>B=band(A,N,M)
sets all elements of A[i,j] to 0, unless N< = i-j< = M.
>B=setdiag(A,N,v)
sets the N-th diagonal of A to v. v may be a number or a vector.
>bandmult(A,B)
multiplies to matrices A and B (like A.B), but is considerably faster, if A and B contain lots of zeros.
>symmult(A,B)
multiplies symmetric matrices A and B and saves half of the time.
Furthermore,
>flipx(A)
flips the matrix, such that the last column becomes the first, the first column the last.
>flipy(A)
does the same to the rows.
In this section some basic built-in functions are explained. Topics are
There are the usual functions
abs, sqrt, exp, log, sin, cos, tan, asin, acos, atan, re, im, conj.
They all work for complex values. In this case they yield the principle value. There are some functions which make sense only for real values
floor, ceil, sign, fak, bin, logfak, logbin.
floor and ceil give integer approximations to a real number. "bin(n,m)" computes the binomial coefficient of n and m. logbin(n,m) computes the logarithm of that (for large values of n,m)
>pi()
(or simply ">pi") is a built-in constant.
>mod(x,y)
return x modulus y.
Note, that most of these internal functions work for matrix input. They simply evaluate to any element of the matrix. If this is not the case, or if you have written an own function, which does not accept matrix input, you can map it to a matrix with
$gt;map("function",...)
where the elements of the matrix parameters ... are passed to a the function. This mapping obeys the rules explained in the matrix section.
>max(x,y)
and min(x,y) return the maximum (minimum resp.) of x and y.
>max(A)
and min(A) return a column vector containting the maxima (minima resp.) of the rows of A. The functions totalmax and totalmin from UTIL compute the maximum about all elements of a matrix.
If A is a NxM matrix, then
>extrema(A)
is a Nx4 matrix, which contains in each row a vector of the form [min imin max imax], where min and max are the minima and maxima of the corresponding row of A, and imin and imax are the indices, where those are obtained.
If v is a 1xN vector, then
>nonzeros(v)
returns a vector, containing all indices i, where v[i] is not zero. Furthermore,
>count(v,M)
returns a 1xM vector, the i-th component of which contains the number of v[i] in the interval [i-1,i).
>find(v,x)
assumes that the elements of v are ordered. It returns the index (or indices, if x is a vector) i such that v[i]< = x< v[i+1], or 0 if there is no such i.
>sort(v)
sorts the elements of v with the quicksort algorithm. It returns the sorted vector and the rearranged indices. If
>{w,i}=sort(v);
then v[i] is equal to w.
If A is NxM matrix
>sum(A)
returns a column vector containing the sums of the rows of A. Analoguously,
>prod(A)
returns the products.
>cumsum(A)
returns a NxM matrix containing the cumulative sums of the columns of A.
>cumprod(A)
works the same way. E.g.,
>cumprod(1:20)
returns a vector with the faculty function at 1 to 20.
>round(x,n)
rounds x to n digits after the decimal dot. It also works for complex numbers. x may be a matrix.
The only string functions in EULER are
>stringcompare("string1","string2")
which returns 0, if the strings are equal, -1 if string1 is alphabetically prior to string2, and 1 else, and the comparation operators ==,< ,> ,< =,> =.
Besides this, you can concatenate strings with |.
Furthermore,
>interpret("expression");
will interpret the expression and return the result of the evaluation.
>time()
returns a timer in seconds. It is useful for benchmarks etc.
>wait(n)
waits for n seconds or until a key was pressed. It returns the actual wating time in seconds.
>key()
waits for a keypress and returns the internal scan code, or the ASCII code of the key. You can check this ascii code against a character with key()==ascii("a").
EULER contains an interval arithmetic. Intervals are number ranges instead of single numbers. Intervals are entered in the form
>~a,b~
or
>interval(a,b)
which stands for [a,b], whenever a and b are two reals or real vectors. If a matrix contains an interval, the matrix will become an interval matrix. Complex intervals are not yet implemented.
You may also use the notation
>~x~
if x is a real or a real matrix. However, in this case EULER computes a small interval with nonempty interior, which contains x. Thus ~x,x~ is different from ~x~!
If x is alread of interval type, ~x~ will be identical to x.
You can do all basic and most other operations on intervals. E.g.
>~1,2~ * ~2,3~
is the interval of all st, where s in [1,2] and t in [2,3]. Thus [2,6]. An operation on one or several intervals results in an interval, which is guaranteed to contain all the possible results, if the operations is performed on members of the intervals.
Some operations do not give the smallest possible interval. I traded speed for accuracy (e.g. sin and cos). However, they will give reasonable intervals for small input. Some functions do not work for interval input.
Special functions are
>left(x)
and
>right(x)
which give the right and left end of an interval.
>middle(x)
is its middle point and
>diameter(x)
its diameter. Note, that this is not equal to the diameter of a product of intervals. To the diameter of an interval vector, use
>sqrt(sum(diameter(x)^2))
The function
>expand(x,f)
will expand an interval x, such that the diameter becomes f times bigger. If x is non-interval and real, it will produce an interval with midpoint x and diameter 2*f.
You can, check if an interval is contained in another interval, using
>x << y
This will return true (1), if the interval x is properly contained in the interval y.
>x <<= y
tests for proper containment or equality.
You can intersect to intervals with
>x && y
unless the intersection is empty. This would yield an error. The function
>intersects(x,y)
tests for empty intersection. An interval containing the union of x and y is constructed with
>x || y
Sometimes it is necessary to compute with higher accuracy. E.g., the solution of a linear system A.x=b can be improved by computing the residuum r=A.x-b and iterating with x=x-A\r. However, this makes sense only if the residuum is computed with higher accuracy. You can do this in Euler with
>r=residuum(A,x,b)
The result is exact up to the last digit. Just enter 0 for b, if you just want A.x.
The computation is done using a long accumulator. This is about 10 times slower than A.x-b. You can access the accumulator (two of them for complex values and intervals) with
>accuload(v)
for any vector v. This will exactly compute sum(v). The accumulator is not cleared afterwards. You can add another vector with
>accuadd(v)
Likewise,
>accuload(v,w); accuadd(v1,w1),
will compute the scalar product of v and w and the scalar product of v1 and w1. These functions return the last value of the accumulator. You can get the complete accumulator into a vector with
>h=accu();
(or accure, accuim, accua, accub for complex accus and intervals). sum(h) will then be the value of the accumulator.
There are lots of built-in functions to perform linear algebra. The matrix product has already been discussed. The operation
>A\b
takes a NxN matrix A and a Nx1 vector b and returns the vector x such that Ax=b. If in
>A\B
B is a NxM matrix, then the systems A\B[,i] are solved simultanuously. An error is issued if the determinant of A turns out to be to small relative to the internal epsilon.
There is also a more precise version, which uses a residual iteration. This usualy yields very good results.
>xlgs(A,b)
You may add an additional maximal number of iterations.
>inv(A)
computes the invers of A. This is a function in UTIL defined as
>A\id(cols(A))
There are also more primitive functions, like
>lu(A)
for NxM matrices A. It returns multiple values (seeMultiple Assignments) You can assign its return values to variables with
>{Res,ri,ci,det}=lu(A)
If you use only
>Res=lu(A)
all other output values are dropped. To explain the output of lu, lets start with Res. Res is a NxM matrix containing the LU-decomposition of A; i.e., L.U=A with a lower triangle matrix L and an upper triangle matrix U. L has ones in the diagonal, which are omitted so that L and U can be stored in Res. det is of course the determinant of A. ri contains the indices of the rows of Res, since during the algorithm the rows may have been swept. ci is not important if A is nonsingular. If A is singular, however, Res contains the result of the Gauss algorithm. ri contains 1 and 0 such that the columns with 1 form a basis for the columns of A.
To make an example
>A=random(3,3); >{LU,r,c,d}=lu(A); >LU1=LU[r]; >L=band(LU1,-2,-1)+id(3); R=band(LU1,0,2); >B=L.R,
will yield the matrix A[r]. To get A, with must compute the inverse permutation r1
>{rs,r1}=sort(r); B[r1]
will be A.
Once we have an LU-decomposition of A, we can use it to quickly solve linear systems A.x=b. This is equivalent to A[r].x=b[r], and LU[r] is a decomposition of A[r], thus x is equal to
>lusolve(LU[r],b[r])
where LU is the result of lu(LU,r,c,A). There is also a more exact version
>xlusolve(A,b)
wich can be used if A is in LU form. E.g., it works for lower triangular matrices A. This may be used for exact evaluation if arithmetic expressions.
lu is used by several functions in UTIL. E.g.,
>kernel(A)
is a basis of the kernel of A; i.e., the vectors x with Ax=0.
>image(A)
is a basis of the vectors Ax. You may add an additional value parameter eps=... to kernal and image, which replaces the internal epsilon in these functions. These function normalize the matrix with
>norm(A)
which returns the maximal row sum of abs(A).
There is an implementation of the singular value decomposition. The basic function is
>{U,w,V}=svd(A)
As you see, it returns three values. A must be an mxn real matrix, and U will be an mxn matrix, w a 1xn vector and V an nxn matrix. The columns of U and V are orthogonal. We have A=U.W.V', where W the a nxn diagonal matrix, having w in its diagonal, i.e.
>A=U.diag(size(V),0,w).V'
This decomposition can be used in many circumstances. The file SVD.E (loaded at system start) contains the applications svdkernel and svdimage, which compute orthogonal basis of the kernel and image of A. Moreover, svddet computes the determinant of A, and svdcondition a condition number.
>fit(A,b) >svdsolve(A,b)
find a solution of A.x=b for singular matrices A (even non-rectangular) by minimizing the norm of A.x-b. The function svdsolve is more stable and should be preferred. By the way, U,w and V can be used to compute solutions of A.x=b with
>x=V.diag(size(V),0,1/w).U'
if w contains no zeros. This is a similar procedure as with the lu function above.
The primitive function for computing eigenvalues is
>charpoly(A)
which computes the characteristic polynomial of A. This is used by
>eigenvalues(A)
to compute the eigenvalues of A. Then
>eigenspace(A,l)
computes a basis of the eigenspace of l. This function uses kernel, and will fail, when the eigenvalue not exact enough.
>{l,x}=xeigenvalue(A,l)
will improve the eigenvalue l, which must be a simple eigenvalue. It returns the improved value l and an eigenvector. You can provide an extra parameter, which is an approximation of the eigenvector.
>{l,X}=eigen(A)
returns the eigenvalues of A in l and the eigenvectors in X. There is an improved but slower version eigen1, which will succeed more often then eigen.
>jacobi(a)
will use Jacobi's method to compute the eigenvalues of a symmetric real nxn matrix a. A specialty is the generation of Toeplitz matrices with toeplitz. The parameter is a 1x2n-1 vector r and the output a matrix R with R(i,j)=r(n-i+j), i.e. the last row of R agrees with the first n elements of r, and all columns above are shifted one to the left from bottom up. You can solve a linear system with a toeplitz matrix, using
>toeplitzsolve(r,b)
where b is a nxq vector. The result satisfies toeplitz(r).x=b.
>epsilon()
is an internal epsilon, used by many functions and the operator ~= which compares two values and returns 1 if the absolute difference is smaller than epsilon. This epsilon can be changed with the statement
>setepsilon(value)
EULER has a built in Simplex algorithm, which minimizes c'*x among all x, satisfying x>=0 and A*x<=b.
>simplex(A,b,c)
will compute the solution x. To check for feasibility and boundedness, use
>{x,r}=simplex(A,b,c)
r will be 0, if x is a correct minimum. If r is -1, the problem is not feasible. If r is 1, the problem is unbounded. In this case, x contains a feasible point. In any case A must be a real mxn matrix, b an mx1 matrix (a column vector), and c a 1xn matrix (a row vector). x will be a nx1 column vector.
Note, that the internal epsilon is used for numerical computations.
EULER supports statistical functions, such as distribution integrals and random variables.
First of all,
>random(N,M)
or random([N,M]) generates an NxM random matrix with uniformly distributed values in [0,1]. The function
>normal(N,M)
or normal([N,M]) returns normally distributed random variables with mean value 0 and standart deviation 1. You should scale the function for other mean values or deviations.
You can set a seed for the random number generators with seed(x), where x is in (0,1). There are also faster versions, using the doubtful generator of C (fastnormal, fastrandom), which are about two times faster.
>shuffle(v)
shuffle the vector v (1xN vector) randomly.
A function for the mean value or the standart deviation has not been implemented, since it is easily defined in EULER; e.g,
>m=sum(x)/cols(x)
is the mean value of the vector x, and
>d=sqrt(sum((x-m)^2)/(cols(x)-1))
the standart deviation.
Rather, some distributions are implemented.
>normaldis(x)
returns the probability of a normally distributed random variable being less than x.
>invnormaldis(p)
is the inverse to the above function. These functions are only accurate to about 4 digits. However, this is enough for practical purposes and an improved version is easily implemented with the Romberg or Gauss integration method.
Another distribution is
>tdis(x,n)
It the T-distrution of x with n degrees of freedom; i.e., the probability that n the sum of normally distributed random variables scaled with their mean value and standart deviation are less than x.
>invtdis(p,n)
returns the inverse of this function.
>chidis(x,n)
returns the chi^2 distribution; i.e., the distribution of the sum of the squares n normally distributed random variables.
>fdis(x,n,m)
returns the f-distribution with n and m degrees of freedom.
Other functions have been mentioned above, like bin, fak, count, etc., which may be useful for statistical purposes.
There is also the gamma function and the incomplete gamma function
>gamma(x) >gamma(x,a)
and the incomplete gamma function. There is also the Beta function and its incomplete counterpart
>beta(a,b) >beta(x,a,b)
as well as the Bessel functions of the first and second kind besselj, bessely and the modified Bessel functions of the first and second kind besseli, besselk
>besselj(x,a)
where a is the order. The parameter x must be positive, and the order must be non-negative.
Describes the way EULER handles polynomials (plus FFT). Available Topics are
EULER stores a polynomial a+bx+...+cx^n in the form [a,b,...,c]. This is different from MatLab. It can evaluate a polynomial with the Horner scheme
>polyval(p,x)
where x can be a matrix, of course. If you want a more exact answer in case of a badly conditioned polynomial, you may use
>xpolyval(p,x)
You may add an additional maximal number of iterations. This function uses the exact scalar product for a residual iteration.
It can multiply polynomials with
>polymult(p,q)
or add them with
>polyadd(p,q)
Of course, the polynomials need not have the same degree.
>polydiv(p,q)
divides p by q and returns {result,remainder}.
>polytrunc(p)
truncates a polynomial to its true degree (using epsilon). In UTIL
>polydif(p)
is defined. It differentiates the polynomial once. To construct a polynomial with prescribed zeros z=[z1,...,zn]
>polycons(z)
is used. The reverse is obtained with
>polysolve(p)
This function uses the Bauhuber method, which converges very stably to the zeros. However, there is always the problem with multiple zeros destroying the accuracy (but not the speed of convergence). Another problem is the scaling of the polynomial, which can improve the stability and accuracy of the method considerably.
Polynomial interpolation can be done by
>d=interp(t,s)
where t and s are vectors. The result is a polynomial in divided differences (Newton) form, and can be evaluated by
>interpval(t,d,x)
at x. To transform the Newton form to the usual polynomial form
>polytrans(t,d)
may be used.
Interpolation in the roots of unity can be done with the fast Fourier transform
>p=ifft(s)
Then p(exp(2*pi*i*k/n))=s[k+1], 0<=k<n-1. For maximal speed, n should be a power of 2. The reverse evaluates a polynomial at the roots of unity simultanuously
>s=fft(p)
Note, that polynomials have the lowest coefficient first.
If A is a matrix
>fft(A)
will compute the two dimensional Fast Fourier Transform of A. This time, the number of columns and rows of A must be power of 2. ifft(A) returns the inverse.
Describes the graphic section of the program. Available topics are
The best part of EULER is its graphic capability. There are two screens, the text screen and the graphic screen. Text output automatically displays the text screen, and graphic output displays the graphic screen. One may also switch to the graphic screen by pressing TAB on input or with the command
>shg;
There are two coordinate systems. The screen coordinates are a 1024x1024 grid with (0,0) in the upper left corner. Furthermore, each plot generates plot coordinates mapping a rectangle of the plane on the screen with the smallest x value left and the smallest y value at the bottom. To be precise, the rectangle is mapped to the screen window, which may only cover a part of the display area. See below for more information on windows.
If x and y are 1xN vectors, the function
>plot(x,y)
connects the points (x[i],y[i]) with straight lines and plots these lines. It first clears the screen and draws a frame around the screen window. The plot coordinates are chosen such that the plot fits exactly into the screen window. This behaviour is called autoscaling. You can set your own plot coordinates with
>setplot(xmin,xmax,ymin,ymax)
(or setplot([...])). The autoscaling is then turned off. To turn it on again, use
>setplot()
Force EULER to use a square coordinate window with
>keepsquare(1)
Correspondingly keepsquare(0) will turn this off.
>scaling(flag)
will stop (flag=0) or resume (flag=1) the autoscaling of the next plot. If scaling is off, then the plot region of the last plot (or the one set with setplot) is used.
By the way, the plot command returns the plot coordinates; i.e., a vector [xmin,xmax,ymin,ymax].
The screen window is a rectangle on the screen which can be set by
>window(cmin,cmax,rmin,rmax)
(or window([...])) in screen coordinates.
If x is a 1xN vector and A MxN matrix,
>plot(x,A)
plots several functions. The same is true with
>plot(B,A)
if B is a MxN matrix. In this case, the plot is done for corresponding rows of A and B.
The graphic screen is cleared by the plot command. This can be turned off with
>hold on;
or
>holding(1);
To turn holding off,
>hold off;
or
>holding(0);
is used. The function holding returns the old state of the holding flag. This is a way to draw several plots into the same frame. Combining window and holding is a way to draw several plots in several windows on the screen.
>xplot(x,y)
works like plot but does also show axis grids. Actually, xplot has default parameters grid=1 and ticks=1, which determine, if a grid is plotted and axis laballing is done. Thus
>xplot(x,y,1,0)
does no ticks. Also
>xplot(x,y,ticks=0)
may be used for the same purpose (see below in the section about EULER programming for details on default parameters).
>xplot()
plots the axis and ticks only.
You may set vertical to 1, if you wish vertical axis labels for the y-axis. You should call shrinkwindow again after doing so, because you will not need so much space to the left of the picture now. Put the command into EULER.CFG to make it permanent (after loading UTIL). However, this does make sense only if you have chosen a small outline font like (O)Courier at about 40 lines per page.
>xplot(z)
will plot xplot(re(z),im(z)), if z is a complex vector.
>cplot(z)
ca be used to plot a grid pattern, if z is a complex matrix.
>histogram(data,n)
will plot a histogram of the data distribution. It will divide the interval into n equally spaced parts and plot the number of d[i] in each subinterval.
You should use
>shrinkwindow()
if you intend to use labels (ticks) on the axis. This leaves some space around the plot.
>fullwindow()
resizes the plots to the full size. You may also set the x axis grids on your own with
>xgrid([x1,x2,x3,...])
or
>xgrid([x1,x2,x3,...],f)
the latter producing digits at the edge of the plot (ygrid(...) works respectively). Actually, these functions are defined in UTIL.
To plot with logarithmic scale is not straightforward. Assume the data is t=1100 and s=1100. You first plot
>plot(t,log(s))
Then you set the grid for both axes manually.
>xgrid(100:100:1000); >ticks=2^(0:9); ygrid1(log(t),t);
So xgrid sets grids at 100,200,...,1000 and ygrid1 sets ticks at the logarithms of 2,4,8,..,512 but using the labels 2,4,8,...,512 instead of the actual logarithmic values. This scheme allows for any scaling, not only for logarithmic.
>plotarea(x,y)
sets the plot area for the next plot like plot(x,y), but it does not actually plot.
>reset
is a function in UTIL, which calls shrinkwindow, hold off and some other stuff to reset the plot coordinates to default values.
>title("text")
draws a title above the plot. It is a function in UTIL using
>ctext("text",[col,row])
which plots the text centered at screen coordinates (col,row).
>text("text",[col,row])
plots the text left justified. The width and height of the charcters can be asked with
>textsize()
returning the vector [width,height] in screen coordinates. There is also
>rtext("text",[col,row])
which alignes text to the right. Vertical text can be printed with
>vtext("text",[col,row]);
vctext would center the text vertically, and vrtext would allign it at text end. The functions vutext, vcutext and vrutext work the same way with text going from bottom up.
If a color monitor is used, EULER can produce colored plots. The plot color can be modified with
>color(n)
where n=1 is black, and n=0 is white. Other colors depend on your system settings. The textcolor and framecolor can be set the same way.
There is the possibility to use dotted and dashed lines, or even invisible lines erasing the background. This is done with one of the commands
>style(".") >linestyle(".")
("-" for solid lines, "--" for dashed lines, "->" for arrowed lines and "i" for white lines). The function linestyle, also
>linestyle("")
returns the previous line style. The lines can have a width greater than 0. This is set with
>linewidth(n)
The function returns the previous setting.
The command
>mark(x,y)
works like plot. But it does not connect the points but plots single markers at (x[i],y[i]). The style of the marker can be set with one of the commands
>style("mx") >markerstyle("mx")
for a cross. Other styles are "m<>" for diamonds, "m." for dots, "m+" for plus signs, "m[]" for rectangles and "m*" for stars. The function returns the previous marker style. The markersize can be set with
>markersize(x)
in screen coordinates (0..1024). There is also the command
>xmark(x,y)
which works like xplot.
A rectangle area of the screen can be filled with
>bar([xleft,yup,xright,ydown])
The coordinates are screen coordinates. But there is the utility function
>plotbar(x,w,y,h);
which plots in plot coordinates. The style of the bar is determined by the barcolor(c) and the barstyle(s) functions. The color is an index from 0 to 15 and the style is a string. Available are "#" for solid, "O#" for solid framed, "#" for framed, "/", "\" and "\/" for hatched bars.
The easiest way to produce 3D-plots
is
>mesh(Z)
If Z is a NxM matrix, its elements are interpreted as z-values of a function defined on a grid of points (i,j). The plot is a three dimensional plot with hidden lines of the points (i,j,Z[i,j]). It is autoscaled to fit onto the screen window. The point (1,1,z[1,1]) is the front left point. To improve the look of the plot, one can use
>triangles(1)
However, this way is considerably slower. Of course,
>triangles(0)
turns this feature off again. One can also turn off the different fill styles mesh uses for the two sides of the plot with
>twosides(0)
This function works also for solid plots described below. It is a faster way than the use of triangles to avoid seeing the errors, that the mesh plot frequently makes. By the way, both functions return the old values of the flags.
>meshbar(Z)
works similar, but plots the heights of Z as square columns.
There is a function which produces matrices X and Y such that X[i,j] and Y[i,j] are the coordinates in the plane of a point in a rectangular grid parametrized by (i,j). This function is
>{X,Y}=field(x,y)
where x and y are row vectors. Then X[i,j] is equal to x[i] and Y[i,j] is equal to y[j]. So you can easily generate a matrix of function values; e.g.,
>Z=X*X+Y*Y
However, you can do this more easily, by defining y as a column vector, x as a row vector. Then
>Z=x*x+y*y
will work just as expected. This is due to the rules for operand, which operate on matrices. Even a more complex expression, like x*y+3*x+y^3 would be evaluated correctly.
A nicer way to plot a surface is
>solid(x,y,z)
or
>framedsolid(x,y,z)
where x, y and z are NxM matrices. The surface parameters are then (i,j) and (x[i,j],y[i,j],z[i,j]) are points on the surface. The function would work, if x is a row vector, y a column vector, just as an operator.
The surface should not self intersect; or else plot errors will occur. The surface is projected onto the screen in central projection, with the view centered to (0,0,0). You can set the viewing distance, a zooming parameter, the angles of the eye from the negative y- to the positive x-axis, and the height of the eye on the x-y-plane, by
>view(distance,tele,angle,height)
(or view([...])). view returns the previous values and view() merely returns the old values. framedsolid has a default parameter scale, which scales the image to fit into a cube with side length 2*scale, centered at 0, unless scale=0, which is the default value (no scaling). Thus
>framedsolid(x,y,z,2)
will scale the plot so that |x|,|y|,|z|<=2.
>wire(x,y,z)
and
>framedwire(x,y,z)
work the same way, but the plotting is not solid. If x, y and z are vectors, then a path in three dimensions is drawn. The color of the wires is set by
>wirecolor(c)
If you add an extra value to framedwire or framedsolid like in
>framedwire(x,y,z,scale)
the plot is scaled to fit into a cube of side length 2*scale. The function
>{x1,y1}=project(x,y,z)
projects the coordinates x,y,z to the screen and is useful for 3D path plots. There is a function
>scalematrix(A)
which scale the matrix A linearly so that its entries are between 0 and 1.
>solid(x,y,z,i)
is a special form of solid. If i=[i1,...,in], then the ij-th row of (x,y,z) is not connected to the ij+1-st row. I.e., the plot consists of n+1 parts.
A contour plot of a matrix is produced by
>contour(A,[v1,...,vn])
The contour lines are then at the heights v1 to vn. The interpretation of A is the same as in mesh(A).
A density plot is a plot of a matrix, that uses shades to make the values visible. It is produced with
>density(A)
The integer part of the values is cut off. So the shades run through the available shades, if A runs from 0 to 1. A can be scaled to 0 to f with
>density(A,f)
f=1 is the most important value. The shades can be controlled with
>huecolor(color)
Any positive color produces shades in that color with varying intensity. The color 0 uses a rainbow color scheme.
>solidhue(x,y,z,h)
makes a solid view with shades. h are the shading values as in density.
>framedsolidhue(x,y,z,h,scale,f)
works like a mixture of framedsolid and solidhue. scale=0 and f=1 are the default values.
The plotting of a user defined function f(x,...) can be done with
>fplot("f",a,b) >fplot("f",a,b,n) >fplot("f",a,b,,...)
The extra parameters ... are passed to f. n is the number of subintervals. Note the extra ',', if n is omitted. If a and b are omitted, as in
>fplot("f",,,,...)
or
>fplot("f")
then the plot coordinates of the last plot are used.
You can use an expression instead of a function name.
>fplot("x^2",-1,1)
This will plot te function x^2 on the interval [-1,1].
You can zoom in with the mouse by
>setplotm(); fplot("f");
This lets you select a square region of the screen. In any case, setplotm() sets the plot coordinates to the user selected square.
It is possible to sample coordinates from the graphics screen with the mouse.
>mouse()
displays the graphics screen and a mouse pointer and waits for a mouse click. It returns a vector [x,y] which are the plot coordinates of the clicked spot. Using
>{x,y}=select()
returns several x coordinates and y coordinates at the points, which the user selected by the mouse. The selection stops, if the user clicks above the plot window.
A 3D-plot can be done with
>f3dplot("f")
f can be a function name of a function f(x,y), or an expression in x and y. Additional parameters are
>f3dplot("f",xmin,xmax,ymin,ymax,nx,my)
Explains the EULER programming language and its use.
Explains the basics on EULER functions and their parameters. Subtopics are
EULER would not be as powerful as it is, if there wasn't the possibility to extend it with user defined functions. A function can be entered from the keyboard or better from a file. Since there may be errors in a function, it is best to call an editor, edit the function in a file and then load that file.
Loading a file is done with
>load "filename"
A function is declared by the following commands
>function name (parameter,...,parameter) >... >endfunction
It can have several parameters or none. If the function is entered from the keyboard, the prompt changes to "$". "endfunction" finishes the function definition. An example
>function cosh (x) $ return (exp(x)+exp(-x))/2 $endfunction
Every function must have a return statement, which ends the execution of the function and defines the value it returns. A function can be used in any expression, just as the built-in functions. If a function is not used in an assignment and with surpressed output (followed by ";"), it is used like a procedure and its result is evidently lost. However, the function may have had some side effect.
A function can call itself recursively. In this case, you have to take care that the recursion stops. If a function overrides an internal function, you can call the internal function with an underscore _ before its name. Thus a function is able to call the internal function, even if it has the same name. This is useful to give enhanced flexibility to built-in functions.
Inside a function one cannot access global variables or variables of the function which called the function. To use global variables use the command
>global variablename
in the function body. Of course, one can use other functions in expressions inside a function, one can even use the function inside itself recursively. All variables defined inside a function are local to that function and undefined after the return from the function. There is no way to define global variables or change the type or size of global variables from within a function, even if one defines these variables in a "global" statement.
>useglobal
lets you access all global variables from inside the function. This is only valid for the function containing the useglobal command.
Variables are passed as references.
That means that a change of a parameter results in the change of the variable, which was passed as the parameter. For example
>function test(x) $ x=3; $ return x $endfunction >a=5; >test(a); >a
prints the value 3. There is an exeption to this. A submatrix is passed by value. Thus
>a=[1,2,3]; >test(a(1)); >a(1)
prints the value 1.
A function can have a variable number of parameters. The number of parameters passed to a function can be determined with the built-in function "argn()". If the parameters are not named in the function definition, they are given the names arg1, arg2 and so on.
You can access the parameters from the n-th parameter on with args(n). This functions returns multiple values (argn,...) and these values may be passed to another function as several parameters. p. args() will return all paremeters from the first non-named parameter. These additional parameters may be passed to a function. If the parameter list in the function call contains a semicolon (;), args() will return all parameters after the semicolon.
Parameters can have default values. The syntax ist parameter=value in the parameter definition; e.g.,
>function f(x=3,y,z=1:10)
assigns the default value 3 to x and the vector 1 to 10 to z, if the function is called in the form
>f(,4,)
If the function is called
>f(1,4)
x has the value 1, y the value 4, and z the value 110.
The function can even be given a named parameter. Consider the function
>function f(x,y,z=4,w=4,t=5)
Then
>f(1,2,t=7)
calls the function, as if
>f(1,2,4,4,7)
was entered. Actually the name needs not be a parameter name. Thus
>f(1,2,s=7)
defines a local variable s with value 7.
A function can return multiple values. This is done with the return statement
> return {x,y,...}
You can assign all the return values of a function to variables, using
>{a,b,...}=function(...);
If the result of such a function is assigned to a number of variables smaller than the number of returned values, only the first values are used. If is is assigned to a larger number of variables, the last value is used more than once. Some built-in functions return multiple values.
Comments can be included, starting with ##. Comments are not entered in the function definition and do not appear, when you type the function with
>type functionname
If the lines immediately after the function header start with ##, then those lines are considered to be help text. They can be displayed with
>help functionname
This is a good way to remember the parameters of the function. Also
>list
can be used to display the names of the user defined functions.
A function or several functions can be removed with
>forget name,...
By the way, a variable can be removed with
>clear name,...
Like in any other programming language, in EULER there are commands for changing the flow of evaluation. These commands can only be used inside user defined functions.
First there is the "if" command.
>if expression; ...; >else; ....; >endif;
The expression is any EULER numerical expression. If it is a matrix, and all its entries are different from zero, then the part from the ";" to the "else;" is evaluated. Else the part from "else;" to "endif" is evaluated. Of course "..." may spread over several lines. To work correctly, keywords like "if", "else", "endif" and others should be the first nonblank characters in a line, or should be preceded by "," or ";" (plus blanks or TABs). The "else" may be omitted. In this case the evaluation skips behind the "endif", if the matrix contains nonzero elements (resp. the number is nonzero).
You may also include one or several elseif commands
>if expression; ...; >elseif expression; ...; >else; ....; >endif;
This is the same as an if command inside the else part. However, you do not have to type several endifs.
There is the function "any(A)", which yields 1, if there is any nonzero element in A, 0 otherwise. The function is useful in connection with the if statement.
Next, there are several loops.
>repeat; ...; end; >loop a to b; ...; end; >for i=a to b step c; ...; end;
All loops can be aborted by the break command (usually inside an "if"), especially the seemingly infinite "repeat". "loop" loops are fast long integer loops. The looping index can be accessed with the function "index()" or with "#". In a "for" loop the looping index is the variable left of the "=". The step size can be omitted. Then it is assumed to be 1. As an example, the following loops count from 1 to 10
> i=1; > repeat; > i, i=i+1; > if i>10; break; endif; > end;
and
> loop 1 to 10; #, end;
and
> for i=1 to 10; i, end;
The command
>trace on
sets tracing of all functions on. Then any new line in a user defined function will be printed with the function name before it is executed. The uses has to press a key, before execution continues
Any other key will display the available keys. Note that the help key is mapped to the insert key on a PC.
>trace off
switches tracing off.
Note, that with F4 you can evaluate any expression, even if it contains local variables or subroutine calls. Tracing is switched off during evaluation of the expression.
A single function can be traced with
>trace function
or
>trace "function"
Execution will stop only in this function. The same command switches the trace bit of this function off.
>trace alloff
switches tracing for all functions off.
All internal EULER functions can handle vector or matrix input. And so should user defined functions. To achieve this, sometimes nothing special needs to be done. E.g., the function
>function kap (r,i,n) > p=1+i/100; > return p*r*(p^n-1)/(p-1) >endfunction
is automatically capable to handle matrix intput. Thus
>kap(1000,5:0.1:10,10)
will produce a vector of values. However, if the function uses a more complicated algorithm, one needs to take extra care. E.g.,
>function lambda1 (a,b) > return max(abs(polysolve([1,a,b,1]))); >endfunction >function lambda (a,b) > return map("lambda1",a,b); >endfunction
shows the fastest way to achieve the aim.
Forthermore, as a matter of good style, one should use the help lines extensively. One should explain all parameters of the function and its result. This is a good way to remember what the function really does.
It is possible to pass functions to a function. E.g., the function "bisect" in UTIL finds the zero of a function using bisection. One uses this function in the following way
>function f(x) > return x*x-2 >endfunction >bisect("f",1,2)
The result will be sqrt(2). If "f" needs extra paramters, those can also be passed to "bisect"
>function f(x,a) > return x*x-a >endfunction >bisect("f",0,a,a)
will result in sqrt(a) (for a>=0). The search interval is set to [0,a].
The way to write a function like "bisect" is to use the "args" function.
>function bisect (function,a,b) >... > y=function(x,args(4)); >... >endfunction
Then "function" will be called with the parameter "x" and all parameters from the 4-th on (if any) which have been passed to "bisect". Of course, "function" should be assigned a string, containing the name of the function which we want the zero of.
Another way to achieve this result is the use of args() without parameter. This will return all parameters from the first additional parameter on. If the user calls bisect like this
>bisect ("f",a,b;4,5)
All parameter after the ";" will be passed to function, when it is called
>y=function(x,args());
Clearly, EULER is designed to run interactively. The user loads a file containing the functions he needs. The file may inform the user of its content by simply printing some messages with commands like
>"The content of this file is:", >...
Alternatively, the file could contain a comment section.
comment Any comment! Even in several lines. endcomment
Then the user can use the help facility to retrieve further information on the functions, its parameters and so on. He (or she) then calls the particular function with the parameters he desires.
However, it is also possible to run a file as a standalone program. If you start EULER from a shell simply put the file into the command line.
If you wish a standalone application, the user will have to enter data. You can prompt him with
>data=input("prompt");
The prompt
prompt? >
will appear and the user may enter any valid EULER expression, even if it uses variables. Errors are catched and force the user to reenter the input. If you wish the user to enter a string, use
>string=lineinput("prompt");
The string may then be evaluated with
>data=interpret(string);
and if it does not consist of a valid EULER expression the result is the string "error". Also
>errorlevel(string)
returns a nonzero number, if there is an error in the string.
Output is printed to screen. All expressions and assignments produce output unless followed by ";". If formated output is wanted, use
>printf("formatstring",realdata)
The format string obeys the C syntax; e.g., "%15.10f" prints the data on 15 places with 10 digits after decimal dot, and "%20.10e" produces the exponential format. You can concatenate strings with | to longer output in a single line.
Output is surpressed globally with
>output off;
and
>output on;
turns the output on again. This is useful if a dump file is defined by
>dump "filename";
Then all output is echoed into the dump file. The command
>dump;
turns the dump off. Note that the dump is always appended to the file. Furthermore, that file may not be edited while dump is on! In UTIL the function
>varwrite(x,"x")
is defined, which writes x in a format readable by EULER on input. If you omit the name "x", the name of x is used automatically. This is done with the help of the function
>name(x)
which is a string containing the name of x.
>cls;
clears the screen.
>clg;
clears the graphics. Also to show graphics to the user, use
>shg;
Subsequent output will switch back to the text screen.
Finally, an error can be issued with the function
>error("error text")
This section describes some special commands. Available topics are
The active directory can be changed with
>cd "path"
where path is the new directory and may include a drive letter, like
>cd "a:\progs"
The changedir function does the same. It will return the active directory when it is called with "".
The command
>dir "*.e"
displays all files in the active directory, which fit with the pattern. An empty string fits all files.
The function
>searchfile("*.e");
returns the first file that fits to the pattern. Further calls of searchfile without any parameters return further files until "" indicates that there are no more fits.
There are some primitive file input and output routines. The normal method is viadump. However,
>open("test.dat","w")
will open the file test.dat for writing, erasing it if it exists. The two parameters of open must be strings and work just like fopen. So
>open("test.dat","r")
opens the file for reading. Opening in binary mode can be achieved with "wb" or "rb". "a" stand for append and will write to the end of the file. You can only open a single file at any time. Opening a second one will close the first one.
>close()
will close the file again.
>putchar(c)
puts a character with code c to a binary file. If c is a 1xn real vector, it will put n characters to the file.
>putword(x) >putlongword(x)
Puts a word or a vector of words (long words) to the file in binary format.
>c=getchar()
reads a character.
>v=getchar(n)
reads a vector of n characters.
>x=getword() >x=getlongword()
reads a word or long word.
>x=getword(n) >x=getlongword(n)
reads n words (long words) from a binary file.
>s=getstring(n)
reads a string of length n from a binary file.
You can check for the end of the file with
>eof()
It will return 1, if the file is completely read.
>write("string")
is a function, which writes a string to a text file. You can add a newline with
>write("string"|asc(10))
Often, you have numbers stored in files in a unpredictable format. You can use
>getvector(n)
to get a vector of these numbers. The functions will read over any nonumeric data and will stop after reading n numbers. You can use
>{v,m}=getvector(n)
to get the vector v and the actually read numbers m.
But there is also the utility function
>A=getmatrix(n,m,filename)
which will do all work for you. If the filename is empty, the function will assume that you already opened a file for reading. Otherwise, it will open and close the file for you. This way, you can read several matrices in a single file. The converse is
>putmatrix(A,filename)
If the filename is not empty, the file will be created (beware!) and closed. Otherwise, you need to open and close the file yourself.
In UTIL some fuctions are defined, which will to be of general use. First there are some functions for solving equations.
>bisect("f",a,b,...)
uses the bisetion method to solve f(x,...)=0. f must be a function of the real variable x which may have additional parameters "...". These parameters can be passed to bisect and are in turn passed to f. You can use the syntax
>bisect("f",a,b;v)
to pass the additional parameter v to f(x,v). This syntax applies to all functions below, which accept additional parameters to be passed to a function.
The method uses the internal epsilon to stop the iteration. You can specify an own epsilon with
>biscet("f",a,b,eps=0.1)
Note, that parameters with values must be the last parameters of all. The eps parameter can be applied to many functions in this section.
It is possible to pass an expression to bisect. This expression must be a string containing a valid EULER expression for f(x). The name of the unknown variable must be x.
>bisect("x^2-2",1,2);
All functions in this section will work with expressions in x.
>secant("f",a,b,...)
uses the secant method for the same purpose. "f" may again be an expression containing the variable x.
If you want to find the root of an expression, which contains one variable or many variables, you can use
>root("expr",x)
expr must be any valid EULER expression. All variables in this expression must be global variables of type real. This function is not to be used in other functions, unless this functions sets the global variables first! x must be the name of the variable, which you want to solve expr==0 for. The new value of x solves the expression. E.g.,
>a=2; x=1; root("x^2-a",x)
will set x equal to sqrt(2).
The minimum of a convex function (maximum of a concave function) can be computed with fmin (fmax). E.g.
>fmin("x^3-x",0,1)
If f is a function, you may also use fmin("f",0,1). As always, additional parameters are passed to f.
The function fmin uses the Golden Ratio method. However, Brent's method may be faster and is available with
>brentmin("x^3-x",0.5)
where the parameters are an initial try, and optionally a step size for the search and an stopping criterion epsilon. The basic built-in function is brent. All minima and maxima of a function or expression (in x) are computed with
>fextrema("x^3-x",a,b)
where a and b are the interval ends. There may be an optional n parameter to determine the number of subintervals to be investigated. The minimum of a function in several variables can be found with the Nelder-Mean simplex algorithm.
>neldermin("f",v)
This time, f must take a 1xn vector as an argument and return a real number. Or you may pass an expression in x, which evaluates for a 1xn vector x to a real. V is a starting point for the search. The basic built-in function is nelder. Optionally, you may pass a delta as size of the first simplex and a stopping epsilon.
>broyden("f",x)
or
>broyden("f",x,J,...)
uses the Broyden method to find the roots of f(x,...)=0. This time, f may be a function f Then x is a vector. J is an approximation of the Jacobian at x, the starting point. If J==0 or J is missing, then the function computes J. Again, additional parameters are passed to f.
>simpson("f",a,b)
or
>simpson("f",a,b,n,...)
computes the Simpson integral with of f in [a,b]. n is the discretization and additional parameters are passed to f(x,...). f must be able to handle vector input for x. Again, "f" may be an expression in x.
>gauss("f",a,b)
or
>gauss("f",a,b,n,...)
performs gauss integration with 10 knots. If n is specified, then the interval is subdivided into n subintervals. f(x,...) must be able to handle vector intput for x. "f" may be an expression in x.
>romberg("f",a,b)
or
>romberg("f",a,b,n,...)
uses the Romberg method for integration. n is the starting discretization. All other parameters are as in "simpson". Again, "f" may be an expression containing the variable x.
There is also an adaptive integrator
>adaptiveint("f",a,b,eps)
where eps is the desired accuracy. Optionally, you may pass the number of initial subdivisions. Further parameters are passed to f.
To take the derivative, one may use the dif function, as in
>dif("f",x) >dif("f",x,n)
(the latter for the n-th derivative). Again, "f" may be an expression in "x". There are some approximation tools. Polynomial interpolation has been discussed above. There is also spline interpolation
>sp=spline(t,s)
which returns the second derivatives of the natural cubic spline through (t[i],s[i]). To evaluate this spline at x,
>splineval(t,s,sp,x)
is available.
>polyfit(t,s,n)
fits a polynomial of n-th degree to (t[i],s[i]) in least square mode. This is an application of
>fit(A,b)
which computes x such that the L_2-norm of Ax-b is minimal.
>iterate("f",x,...)
seeks a fixed point of f by iterating the function from x. If you provide additional arguments ..., these are passed to f. Of course, f must be a function of type
>function f(x) $... $endfunction
If you want see the iterations, use the following variant.
>niterate("f",x,n,...)
iterates f starting at x n times and returns the vector of iterated values.
>steffenson("f",x);
Seeks a fixed point starting from f using the Steffenson operator. nsteffenson is similar to niterate.
>newton("f","f1",x,...)
finds a zero of f using the Newton method. You must provide the derivative of f in f1. Similarily
>newton2("f","Df",x,...)
is used for several parameters. f(x) must compute an 1xn vector y from the 1xn vector x. Df(x) must compute the nxn derivative matrix at x.
>map("f",x,...)
evaluates the function f(x,...) at all elements of x, if f(x,...) does not work because the function f does not accept vectors x.
One of the differential equation solvers is the Heun method. To use it, write the function f, which defines the differential equation y=f(t,y). y can be a 1xN vector. Then call
>heun("f",t,y0,...)
The extra parameters ... are passed to f. y0 is the starting value y(t[1]) and t must be a vector of points t. The function returns the values of the solution at t. The accuracy depends of the distances from t[i] to t[i+1]. Heun is implemented via a UTIL function. A faster solver, implemented as a built-in function, is the Runge-Kutta method and its adaptive variant.
>runge("f",t,y0)
does the same as heun. Optionally, a number of steps to take between the points of t can be passed. Thus you have to pass addtional arguments for f as
>runge("f",t,y0;...)
The adaptive Runge-Kutta method is called adaptiverunge, and takes an epsilon and an initial step size as optional arguments. Internally, these functions use the built-in runge1 and runge2 respectively.
This file provides some interval procedures, which produce guaranteed inclusions. The underlying algorithms may be found in the work of Rump, Alefeld, Herzberger and Moore. Please refer to the mathematical literature for more information.
>y=idgl("f",x,y0);
y is then an inclusion of the solution of the differential equation y'=f(x,y). f is an EULER function with two arguments like
function f (x,y) return x*y; endfunction
x is a vector of x values, where the solution is to be computed. The accuracy will depend on the step size in x. y0 is a starting value for y[1]. y is a vector of interval values containing the solution.
>x=ilgs(A,b); >x=ilgs(A,b,R);
This is a linear system solver, producing an inclusion of the solution of Ax=b. You may provide a matrix R, which is close to the inverse of A. The procedure may fail.
>iinv(A);
This produces an inclusion of the inverse of A.
>ipolyval(p,t)
This computes an inclusion of the value of the polynomial p at t. t may be a vector.
>inewton("f","f1",~a,b~)
This is the interval Newton method. f must be a function and f1 its derivative. ~a,b~ is a starting interval, which must contain a zero. If it does not contain a zero, there will most probably occur an empty intersection. If the starting interval is replaced by a non-interval real number, the function calls the Newton method and expands the result to an interval, which is taken as a starting interval. Of course, f1 must not be zero in ~a,b~. The function returns the inclusion interval and a flag, which is nonzero if the interval is a verified solution.
This function accepts expressions instead of functions. E.g.
>inewton("x^2-2","2*x",~1,2~);
will compute and inclusion of sqrt(2).
>newton2("f","f1",x); >inewton2("f","f1",x);
newton2 is the Newton method for several dimensions. f must be a function, which computes a 1xn vector f(x) from a 1xn vector x. f1(x) must procude the Jacobian matrix at x. inewton does the same, but produces an interval inclusion. The start interval vector x must contain a solution.
This paragraph describes some special function of EULER, which are useful in doing statistical investigations.
First of all, we show how to read data from a file. Suppose the file test.dat contains an unknown number (less than 1000) of data, separated by any non-digit characters. Then you can read the data with
>open("test.dat","r"); {a,n}=getvector(1000); close(); >a=a[1:n];
To write a vector a to the file, you can use
>open("test.dat","w"); printformat(a'); close();
This will print the data formatted with the %g format of C. To get a longer output, use printformat with an additional parameter "%30.15f".
You will have to load the statist.e file for most of the functions described here. This is done with the command
>load statist
The first function computes the mean value
>mean(x) >mean(x,f)
where x is a row vector of data and f are optional frequencies for the data (multiplicities). Correspondingly,
>dev(x) >dev(x,f)
computes the standard deviation of a measured sample x. Having computed these values, you may test for a specific mean value, using the Student T-test
>ttest(m,d,n,mu)
where the mean m and the deviation d are measured and tested against having the mean mu. N is the number of data. This function returns the probablility, that the true mean value is mu or more (assuming mu>m). I.e., the error you make, if you reject the hypothesis that the measurement has mean mu or more. Note, that the data must be normally distributed for this test to make sense. To make a two sided test, you have to check with m=0 and use the doubled error probability. You may also test several samples of normally distributed data for equal mean with
>varanalysis(x,y,z,...)
where all parameters are row vectors. A small answer means, that you have a low error, if you reject the equal mean. Assume, you have measurements, which you assume to obey a discrete probability p. Then
>chitest(x,p)
returns the error that you make, if you reject that x obeys the distribution p. Note, that you have to normalize both values before you use this test. E.g., assume you have 600 dice throws with certain results. Test for a false dice with
>chitest([90,103,114,101,103,89],dup(100,6)')
This will again return the error probability to reject the hypothesis of a correct dice. Small results mean a false dice. Another chi^2 test is the table test for dependence of the entries from the rows.
>tabletest(A)
will return the error that you make if you assume that the entries of A depend on the rows. The first non-parametric test in this file is the median test, which test two samples for same distribution.
>mediantest(a,b)
A low answer means, that you may reject the hypothesis of equal distribution. This test uses only the order of data. A sharper test is the rank test
>ranktest(a,b)
This test uses the sizes of the data to obtain sharper results. If the two distributions are evaluated on the same test cases. So both samples have the same size. To test for if a has larger values than b, use
>signtest(a,b)
or, if you want to include the sizes of the differences for a sharper test
>wilcoxon(a,b)
A special example is the comparison of two medical treatments, done on the same subject. The statist.e file does also compute two frequent distributions. The first is the binomial distribution
>binsum(i,n,p)
which returns the probability of I or less hits in N trials, if the chance for each hit is p. And
>hypergeomsum(i1,n1,i,n)
returns the probablitly of i1 or less hits, if you choose n1 balls from a bowl of n balls, containing I good choices.
>normalsum(i,n,p)
is a fast approximation of binsum for large n and medium p, and
>invbinsum(x,n,p)
is the inverse of binsum. There is also a special function to plot ranges of data in a histogram style. Assume you have bounds of ranges r(1),...,r(n+1) and frequencies f(1),...,f(n). You may use
>xplotrange(r,v)
to plot these data.
One can make all sorts of mistakes in EULER. This section tries to warn you of the more common ones, most os which the author has some experience with.
As already mentioned, you should not assign to the parameter of a function. This will generally produce strange errors, which are difficult to debug.
The next mistake is to produce matrices with 0 rows or columns. EULER can not do any computation with these matrices. Make sure that every index you use is in range. And use special handling, if there is nothing to do. However, you may generate such matrices for the special purpose of appending vectors to it.
Another subtlety concerns the use of multiple return values. The following simply does not work
>x=random(1,10); sin(sort(x))
The reason is that sort returns not only the sorted array but also the indices of the sorted elements. This works as if sin was passed two parameters and EULER will not recognize that use of sin. To work around this either assign the sorted array to a variable or put extra brackets around it
>x=random(1,10); sin((sort(x)))
Also a return statement like
>return {sort(x),y}
really returns 3 (or more) values! Use
>return {(sort(x)),y}
One further misfortune results from the use of strings as functions, like in
>function test(f,x) > return f(x*x) >endfunction >test("sin",4)
This works well as long as there is no function by the name of "f". If there is, this function is called rather than the sine function. The only way to avoid this is to use really strange names for function parameters. I prefer "test(ffunction,x)" and used it throughout UTIL.
Finally, we like to stress that built-in functions are searched before the user defined functions. If a built-in function with a matching number of arguments exists, it will be called.
This section explaines some of the *.e files, which are included with EULER.
You probably know this one. Just load it. You can start a selfrunning demo with demo(n), where n is a time interval in seconds.
This file is loaded from EULER.CFG. It contains lots of functions. Most of them are (should be) explained in this documentation.
These are some test suites to test, if your EULER system works correctly.
This is a benchmark for EULER. Just run test.
This is a nice plot of the Mandelbrot apple set and its potential. Just load the file.
This allows some nice plots of mappings from (x,y) to z. You first need to define a function f(x,y), -1< = x,y< = 1, like
function f(x,y) return x*y; endfunction
Then you can get plots of it with
>f3d("f"); >f3dpolar("f"); >fcontour("f");
In all cases "f" may be a valid EULER expression using x and y (and other global variables). This avoids the definition of a function. The function f3dplot is contained in UTIL already.
This file computes some Bezier curves and survaces. Some demo functions are available.
beziertest lets you click at points to define (x,y) values and computes and shows the bezier curve to these points. It is based on the function bezier(p,t), which evaluates the Bezier curve through the columns of the matrix p in t. bezier3dtest displays a Bezier curve in 3D-space.
nurbstest shows some quadratic nurbs with increasing weight in the middle point. It is bases on nurbs(p,b,t), which works like bezier(p,t), but needs a weight vector b.
beziersurftest shows a bezier surface with its determining grid of points. beziersurf(x,y,z) computes the surface. x,y,z are the coordinates of the grid points (kxl-matrices). It returns three values {xb,yb,zb}, which are the coordinates of the (n+1)^2 surface points.
c1test is another demo.
This computes the optimal strategy for some simple games. Read the help for a description of the games (gambling,scissors,poker).
game(A) computes the optimal strategy for a game with matrix A.
Computes seat distributions for votes.
hondt(v,n) and best(v,n) take the votes for the parties and the numer of seats as parameters and compute a vector of seats for the parties.
Computes the interest rate of an investment.
The general purpose functions are rate(x) or rate2(x,n). Both compute the interest rate of a payment vector x, with positive or negative entries. The first function assumes times 0,...,n and the latter times n[1],....,n[m].
investment computes the interest rate of an investment with a start installment, several payments (positive) and a final installment. See the help for more information.
With this file, you can load or save mono WAV files in 8 or 16 bit.
v=loadwave(filename) loads a WAV file into a vector v. It does also return the sampling rate r and will save this to the global variable defaultrate.
savewave(filename,v) will save the sound with the defaultrate and 8 bits. You may specify the rate and bits as extra parameters.
analyze(v) does a spectrum decomposition of the sound. the full parameter list is analyze(v,fmin,fmax,rate,points). fmin and fmax are the minimal and maximal frequencies of interest, rate is the sampling rate and points are the number of points to be used (should be a power of 2).
mapsound(v) does an analysis for the sound at certain time increments. It will procude a nice density plot of the frequencies. the full parameter list is mapsound(v,dt,fmin,fmax,simpl,rate), where dt is the time increment in seconds, simp is a simplification factor (take 1), and rate is the sampling rate