Again a lot of work on the tutorials, the examples, and the help texts.

Some improvements have been done to the help function, including some changes in the help menu. The man help now contains an overview and a help on the user interface.

I also improved the tutorial about Tiny C programming and a lot of other tutorials.

The file "util/EMT.xml" contains now a syntax import for Notepad++.

EMT can now handle Python 3. I could test it with Python 3.8. I suggest installing a version from the main Python site.

https://www.python.org/downloads/release/python-380/

It might be necessary to add the directory of Python to the path. At least, EMT needs to be able to use python38.dll.

To enable Python38, uncheck "Use Python 2.7" in the program options before using Python.

Fixed the function drop(v,i) which now works only for row vectors v and i. The index vector can contain negative indices. Note that the index vector will be sorted by this function.

>v=[10:20]

[10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

Drop the last element and the element at positions 2 and 3.

>drop(v,[-1,2,3])

[10, 13, 14, 15, 16, 17, 18, 19]

For matrices, use droprows() or dropcols(),

>droprows([1,2,3;4,5,6],1)

[4, 5, 6]

>dropcols([1,2,3;4,5,6],2)

1 3 4 6

There are the new functions butlast() and butfirst() now.

>butlast(1:10), butfirst(1:10)

[1, 2, 3, 4, 5, 6, 7, 8, 9] [2, 3, 4, 5, 6, 7, 8, 9, 10]

Alt-Backspace now deletes the commands as before and adds it to the undo buffer. But the undo buffer is cleared now for each delete unless the key is pressed several times without changing the current line. This allows deleting and inserting several successive lines.

Alt-U inserts the current undo at the current position in the notebook (i.e., in front of the current line). It also clears the undo buffer.

For more control, use Cut and Paste.

Internal update of the web page.

Extended "map" so that the result of the function does not have to be either real or complex. In previous versions, "map" took the first function result to determine the type of the resulting vector. If any successive result was different the result was an error.

>function map f(x) ... if x~=0 then return 0; // real result else return 2*x; // might be complex endif endfunction

This works, even if the first vector element of the result is real.

>f((0:2)*I)

[ 0+0i , 0+2i, 0+4i ]

Or if there is a real result between the complex results.

>f((-1:1)*I)

[ 0-2i, 0+0i , 0+2i ]

The parameter >hue for plot3d is no longer automatically changed to >zhue if the plot contains z-levels. This looks better for plots which would otherwise be very dark in larger areas.

>plot3d("exp(-x^2-y^2)",r=3,levels=exp(-(0:0.5:5)^2),>hue,n=100):

The default >zhue is not computed by the light shining on the plot, but by the z-values.

>plot3d("x*y",levels=-2:0.1:2):

Fixed a crash when nelder() was called without arguments. Thanks to Th. Risse.

>nelder

Need string f, vector v, real d, real eps, args for f for nelder Error in: nelder ... ^

Improved the documentation of the elliptical functions.

>help ellrf

ellrf is an Euler function. function map ellrf (x, y, z, eps) Default for eps : none Function in file : functions Carlson's elliptic integral of the first kind RF (x; y; z). The iteration is implemented in the Euler language. x, y, and z must be non-negative, and at most one can be zero. Computes 1/2 integrate(1/sqrt((t+x)*(t+y)*(t+z)),t=0..inf) See: ellrd, ellf

Fixed 13 and 10 in strings. Both generate a new line in the output now, as well any sequence 13/10 or 10/13.

>"A"+char(10)+"B"+char(13)+"C"+ ... char(10)+char(13)+"D"+char(13)+char(10)+"E"

A B C D E

This is just a cleanup of the code.

Fixed F11 (to resize the windows to full screen automatically) for getting the cursor position and screen length correctly.

Euler has now been compiled with "Visual Studio Cummunity 2019". The source file contains the project file "euler.vcxproj".

The formats "shortformat", "short" and "shortest" have been updated.

>A=normal(5,5); short A,

-1.4301 -0.34767 0.67098 -0.53247 1.4476 -0.42454 1.3617 -0.54124 0.41228 -0.23808 -0.43401 -1.6732 -1.1987 0.43725 0.39076 0.74429 -0.83521 0.63074 -0.17178 -0.70387 -0.43498 -1.891 -0.3104 -0.37765 0.24254

The download is no longer from my site, but from the Files section at SourceForge. The reason for this change is that the files are checked thouroughly by SourceForge for viruses. It becomes important more and more to prove that the download is clean.

The fonts are now saved again.

The official forum for Euler Math Toolbox is now at SourceForge at

https://sourceforge.net/p/eumat/discussion/

I will also try to keep the files section in SourceForge up to date with the most recent version. The HTML files remain on my server at Strato, as well as the downloads.

The 32-bit version will no longer be updated, or only at very special request. The version of May 2017 will remain on the server.

Moreover, there will no longer be a Maxima-less version of Euler Math Toolbox. The internet is fast enough now for a download of the full version (around 100 MB).

Now the right mouse button works in the following ways:

(1) Clicking into a comment opens the comment window.

(2) Clicking into a program opens the internal editor.

Euler does no longer use the registry. Instead, the configuration is written to the file ".euler.cfg" in the home directory of the user. For old users, the registry is read once to keep old settings.

Fixed the drop routine. It does no longer sort the vector of elements to be dropped.

>a=1:10; b=[6,5,4]; drop(a,b)

Variable or function a not found. Error in: ea=1:10; b=[6,5,4]; drop(a,b) ... ^

>b

[6, 5, 4]

Fixed frac(x) which now works for very small elements, just like fraction and fracprint().

>frac(1e-15)

0

Added an Euler file for the simplex algorithm in Gauss-Jordan form. See the documentation.

>// load pivp

The help window now searches for strings automatically if no topic is found.

The function mset() is now fixed and works, even if there is nothing to set.

>v=dup(1:3,2); mset(v,mnonzeros(v<0),0)

1 2 3 1 2 3

There is no v[i]<0. But in the following v, there are v[i]<0.

>v=dup(-1:1,2); mset(v,mnonzeros(v<0),0)

0 0 1 0 0 1

Note how mnonzeros(v<0) works. It returns the indices, where this is true.

>mnonzeros(v<0)

1 1 2 1

For vectors, you can also use the following.

>v=-5:5; v[nonzeros(v<0)]=0

[0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5]

There is a new modifier "usenan". It evaluates the command with "errors off" and sets "errors on" afterwards.

>usenan log(-3:3)

[NAN, NAN, NAN, NAN, 0, 0.693147, 1.09861]

E.g., let us compute sum(1/v), where v is not 0.

>v=0:5; usenan w=1/v

[NAN, 1, 0.5, 0.333333, 0.25, 0.2]

Now, we eliminate the NANs before we sum up.

>sum(w[nonzeros(!isNAN(w))])

2.28333333333

The plot3d(x,y,z) routine for plotting surfaces now respects >zscale. In this case, z is assumed to be a function value. The function is scaled so that everything fits into a unit cube. But the function values are scaled with respect to x and y first.

>x=-10:10; y=x'; z=x*y^2; plot3d(x,y,z,>zscale,angle=-40°,zoom=2):

The value of zscale is used to scale into that direction.

>plot3d(x,y,z,zscale=0.6,angle=-40°,zoom=2):

Additionally, scale=[sx,sy,sz] can be used.

>plot3d(x,y,z,>zscale,scale=[1,1.5,0.5],angle=-40°,zoom=2):

I have removed the ancient function scale() and replaced it with something more useful. Now scale(A) scales the matrix A into [epsilon,1].

>sort(scale(random(10)))

[3.20579e-012, 0.116789, 0.117949, 0.142182, 0.163337, 0.351734, 0.467792, 0.656083, 0.984992, 1]

This is useful for plots. E.g., we disturb the matrix (i*j) randomly. To get spectral colors, we scale the result to [0,1]. This will be a noisy plot of x*y.

>n=50; A=(1:n)*(1:n)'; clg; plotrgb(getspectral(scale(A+n*normal(n,n)))):

If you plot the same with plot3d, you do not need to scale, because plot3d() has its own scaling parameter. It needs to print the labels correctly.

>plot3d(A+n*normal(n,n), ... scale=[80,80,1],angle=-70°,center=[0,0,0.5],zoom=1.7):

I have also expanded the function crossproduct(). It will work now for matrices with three rows, and it will return the results in such a matrix.

>v=[2,3,4]'; crossproduct(v,v|(v+1))

0 -1 0 2 0 -1

I also added the Gram determinant. It computes the volume of the parallelotope spanned by the columns of a matrix. For two vectors in three dimensions, this happens to be the same as the cross product.

>w=[3,4,-2]'; gramdet(v|w), norm(crossproduct(v,w))

27.2213151776 27.2213151776

The generalized cross product is added too. It returns a vector perpendicular to all n-1 columns of a matrix with n rows. The length of the vector is equal to the area of the parallelotope spanned by the columns.

>M=normal(4,3); v=vectorproduct(M); M'.v, norm(v), gramdet(M)

0 0 0 0.906895530849 0.906895530849

I added a function fzeros() which finds all zeros of another function in an interval. It makes use of fextrema() and bisectin().

>fx := "cheb(x,10)+2*x^2"; ... plot2d(fx,-1,1); w=fzeros(fx,-1,1); plot2d(w,fx(w),>points,>add):

Due to user demand, there is now a Python mode.

>pythonmode on

Python mode is on

From now on every command, is interpreted as a Python command.

>print "This is Python"

This is Python

Multi-lines work as expected. For Python control structures, you must use multi-lines and indentation.

>n=1 ... for k in range(2,40): ... n=n*k ... print n

20397882081197443358640281739902897356800000000

You can use "function python" for multi-line commands too.

>function python ... n=1 for k in range(2,40): n=n*k print n endfunction

20397882081197443358640281739902897356800000000

You can define functions with "def" in a multi-line command, or as a "python" function.

>def fak(n): ... m=1 ... for k in range(2,n): ... m=m*k ... return m >print fak(40)

20397882081197443358640281739902897356800000000

The alternative is a python function. That would work outside of python mode too.

>function python fak(n) ... m=1 for k in range(2,n): m=m*k return m endfunction

>print fak(40)

20397882081197443358640281739902897356800000000

Maxima lines work too.

>:: 40!

815915283247897734345611269596115894272000000000

EMT works in this mode with "euler".

>euler 40!

8.15915283248e+047

>pythonmode off

Python mode is off

Note that the Python function as defined with "function python fak(n)" is available outside of Python mode now.

>fak(40)

2.03978820812e+046

Some Maxima replacements got fixes to make things more logical. To escape any character in a symbolic expression you can now use \c.

The following defines an infix operator | in Maxima which simply multiplies to values. We need to escape the | and the := in symbolic expressions.

>&infix("\|",115); &a\|b \:= a*b; &3\|4

12

It might be easier to use the direct mode for this as written in the Maxima documentation.

>::: infix("|",115)$ a|b := a*b$ 3|4

12

Furthermore, &!... will prevent any replacements in the symbolic expression. (If you need an expression to start with ! enter &!!...)

>&!(a+b)|(a+b)

2 (b + a)

There are some changes in the web pages that are installed with EMT. Now, links on these pages show the installed documentation. There is a link to the web site in the link box. The PDF files are also linked to the web site, as well as the search results.

There have been some fixed in the Maxima interface, nothing the ordinary user would notice.

In purely symbolic functions := is now replaced by : to make those mre readable. If you do not want this use the direct mode ":::".

>function cfx(n) &&= block([x], ... for i:=1 thru n do x:=1+1/x, x); >&cfx(3)

1 --------- + 1 1 ----- + 1 1 - + 1 x

It is now possible to define purely symbolic strings with the following syntax. Note that s in the following definition is a string, not an expression.

>s &&= ""sin(pi/5)""; &s

sin(pi/5)

The function frac() got a a local epsilon.

>frac(1/7+1e-9,eps=1e-4), frac(1/7+1e-9)

1/7 20408163/142857140

Even more improvements in the documentation and a more concise web page. Nowadays, people do not bother to read long texts on home pages.

The following does work now.

>A=[1,2;0,1]; A.A^2.A

1 8 0 1

Previously, A^2.A did not work because "2." was taken as the number "2".

I also fixed the following which was not working. It is an abuse of the matrix product anyway.

>pi.pi

9.86960440109

Note that "2.A" does not work due to incompatible dimensions. You have to write

>2*A

2 4 0 2

This is only an update of the documentation with many error fixes and improvements. There is also a new tutorial intended for teachers.

The code for the redraw of the screen has been changed a little bit. This should prevent flicker on weaker machines. I hope it has no serious side effects.

Besides some minor fixes in the documentation, I added knots and nautical miles to the units.

>180kts -> " km/h"

333.5840928 km/h

I made it more clear in the documentation that units can be overridden by variables. It is safest to use the $ sign with units all the time.

>nm=0; // now 5nm would no longer work ... 5nm$ -> " km"

9.2662248 km

Due a post in the forum I expanded plotcubes() a little bit. It works now better. But it is still not perfect. For photo realistic scenes, you should use Povray via EMT.

>function p (M) ... clg; plotcubes(M,rgb(0.5,0.5,linspace(0.5,1,rows(M)))); endfunction

>n=4; >x=0:1/n:1; {X,Y}=field(x,x); ... X=flatten(X)'; Y=flatten(Y)'; Z=random(size(X)); ... h=1/(2*n); M=X|(X+h)|Y|(Y+h)|Z|(Z+h); >plot3d({{"p",M}},>own,>user,zoom=4,center=[-0.5,-0.5,-0.5]):

The Ctrl-Z to restore a line became more functionality. It will now remember the 8 last version of this line. A new version is stored whenever the line is executed. Moreover, Ctrl-Y does now undo the restore.

I wrote a utility file scilab.e to interface with Scilab. Currently, results from Scilab can only be read, if they are simple numbers.

>load scilab

Interface for the SciLab program.

We can optionally start the Scilab process manually.

>// slstart;

Otherwise it is started whenever it is used.

Now it is possible to interpret results of Scilab and convert them to numbers in EMT with slget():

>slget("sum((1:10)^2)")

385

For multi-line returns, EMT cannot interpret the result. Use the function "sl" to send a command to Scilab. (See below for this new type of functions).

>sl 1:24

column 1 to 12 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. column 13 to 23 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. column 24 24.

sl() will return a string of vectors. You can store the result for later.

>s=sl("1:2:10");

The Scilab process is killed with slend(). If EMT is exited, it will also be killed.

>slend;

Here is the stored result.

>s

1. 3. 5. 7. 9.

The output of Scilab is truncated by default. Empty lines at the start and the end, and the line "ans =" are then deleted. Set the variables "stripstart", "stripend", "stripans" to change this.

For the Scilab interface, a new type of function was needed, which reads the complete input line as a parameter.

>function prefixline readall (s:string) := ">"+s+"<"; >readall Read everything from this line

>Read everything from this line<

There was an error in the function game(A), which finds the optimal strategy for a game with matrix A.

>load games

game(A), computes an optimal strategy for the game with matrix A.

>A=[1,-1,4,1;-2,5,2,1;4,1,-3,1]

1 -1 4 1 -2 5 2 1 4 1 -3 1

The meaning of this is: You select a column j, and the other player selects a row i. Then you get the value A[i,j].

For an optimal strategy, you have to select the columns of the matrix with the following probabilities.

>{p,res}=game(A); p, res,

[0.426966, 0.303371, 0.269663, 0] 1.20224719101

Note that you should never select column 1. This will safely gain 1, but the strategy p is better. It will gain more than 1 on average.

The mathematical problem is

Fixed a glitch in the adaptive evaluation for plot2d(). For small intervals, the result took too many points.

>plot2d("x^2",-1e-6,1e-6,grid=9):

There were some changes in shrinkwindow() and fullwindow(). The windows are now actually square always, and the full window is a bit larger. The plot3d() functions now makes a bit larger and more centered plots.

This is only a tiny correction. With proper individual settings, plots can now fill more of the image.

>plot3d("x^2+y^3",>spectral,>levels,angle=-40°, ... zoom=2.7,center=[0,0,0.4],n=100):

The plot window should now be exactly square. The plot coordinates will be square only with the >square parameter, however.

>plot2d("x^3-x",>square):

There was a bug in xgrid() and ygrid() which needed to be fixed.

>plot2d("x^2",0.01,0.02):

If you like to format the grids labels yourself use xgrid(), ygrid(). The factor f can be used to avoid large numbers.

>plot2d("x^2",0.01,0.02,<ticks,grid=4); ... xgrid(0.01:0.001:0.02,f=0.001); ... ygrid(0:0.0001:0.001,f=0.0001):

I added a new function adaptive() which adaptively evaluates a function. It works for real and complex scalars and column vectors. The similar functions adaptiveeval() and adaptiveevalone() for plotting are not changed by this new function.

>{x,y}=adaptive("sin(1/(x^2-1))",0,1-epsilon); ... plot2d(x,y):

As you see when looking at the differences the step sizes vary considerably.

>plot2d(differences(x),>logplot):

Here is another example, where f is vector valued.

>function f(t,a,b) := [sum(sin(t*a)*b);sum(cos(t*a)*b)]; ... {t,X}=adaptive({{"f",[1,3,7],[1,0.3,0.3]}},0,2pi); ... plot2d(X[1],X[2],r=2,>filled,fillcolor=lightgray):

There is now a function colsum(), which sums the columns of matrices.

>A=random(3,3); A_colsum(A)

0.655416 0.200995 0.893622 0.281887 0.525 0.314127 0.444616 0.299474 0.28269 1.38192 1.02547 1.49044

Of course, this is the same as the following.

>A_sum(A')'

0.655416 0.200995 0.893622 0.281887 0.525 0.314127 0.444616 0.299474 0.28269 1.38192 1.02547 1.49044

The xgrid() and xtick() functions have been fixed to allow labels.

>plot2d("x^3-x",-1.2,1.2,<ticks); xgrid([-1,0,1],xt=["a","b","c"]):

Using xtick(), this allows Latex formulas.

>plot2d("x^3-x",-1.2,1.2,<ticks); ... xtick([-1,0,1],["x_1","x_2","x_3"],>latex):

Vectors and matrices can now be declared "zerobased". This makes the indices start with 0 instead of 1.

>v=1:5; zerobase v; v[0]=v[4]

[5, 2, 3, 4, 5]

Note that linspace(a,b,n) returns n+1 values. Often, you might want to refer to these values as x[0] to x[n]. This is now possible.

>n=10; x=linspace(0,1,n); zerobase x;

The following is an upper Riemann sum for the integral of x^2 in [0,1]. The first value of x, x[0], is not used.

>sum(x[1:n]^2)/n

0.385

Note setting x to a new vector makes it restart with base 1.

>x=1:10; x[1]

1

Moreover, the property cannot be set inside a function to an array passed as an argument to the function. The new base 1 will only be used inside this function.

>function test (x) ... zerobase x; x[0]=77; return endfunction

The original x is changed properly. But it will use base 1 still.

>test(x), x[1]

77

Assigning a zero based vector to another vector copies the flag.

>w=v; w[0]

5

Thus it is possible to write functions, which return zero based vectors or matrices.

>function linspace0 (a,b,n) ... v=linspace(a,b,n); zerobase v; return v; endfunction

>v=linspace(0,1,10); v[1]

0

>v=linspace0(0,1,10); v[0]

0

The function gauss() did not work with call collections. This has been fixed.

>function f(x,a) := x^a; ... gauss({{"f",4}},0,1)

0.2

Likewise, the function adaptiveint() did have problems with call collections.

>adaptiveint({{"f",4}},0,1)

0.2

EMT now searches in the current directory first when a file is opened, an Euler file is loaded or help is searched from an Euler file. In previous versions, the existence of a file with the same name in the start directory of EMT would have prevented the user file from being used.

This of course means that the user can manipulate his installation by putting Euler files in the directory of the loaded notebook. To prevent the worst, the file "euler.cfg" now switches to the start directory of EMT to load its files.

The Gauss method now vectorizes the function or expression by default.

>function f(x:scalar) ... if x<0 then return x^2; else return x^3; endif; endfunction

Note the type check "scalar" which makes sure that f() is not abused!

The following did not work in previous versions since f() does not work for vector input. Note that integrate() uses the adaptive Gauss algorithm, which in turn uses the Gauss algorithm.

>fraction integrate("f",-1,1)

7/12

For another example, let us compute

>function map f(p:scalar; T:vector) := sum(T^p)^(1/p);

Since the function f() already vectorizes to p (but not to T because of the semicolon) we do not need to map in the Gauss method. So we turn off the vectorization.

>integrate({{"f",[1,3,2]}},1,2,<maps)

4.49846360039

I added a parameter for Latex formulas in label boxes.

>plot2d(["x^2/2","x^3"],color=[2,3]); ... labelbox(["\frac{x^2}{2}","x^3"],colors=[2,3], ... x=0.3,>latex,scale=1.5):

There is now an option to split a line without adding "...". The keyboard shortcut for this is Shift+Control+Return.

This version dumps the snippets menu in favor of a menu "Tasks" which links to section of the help file explaining taks you might want to do in EMT.

The User Menu is still there and can be filled with snippets as needed. It does also contain a submenu with loaded Euler files. Calling the menu items in this submenu opens the help window with a list of definitions in the Euler file.

I have started a tutorial for R users on EMT. Along the way, I learn a lot about R. The tutorial is based on the "Introduction to R" which is installed with the R project on Windows as a PDF.

23 - Introduction for Users of the R Project

The command line switch "-pipe script.e" now exits EMT on any errors. It will no longer open the notebook window. Here is an example of a script in R, which dumps the command output to some file, and saves the current graphics to a PNG.

dump("output.txt"); expr&=diff(sin(x)*exp(x),x), "Integral from 0 to pi = "+integrate(expr,0,1), "Exact = "+(sin(1)*E), plot2d(expr,0,1); savepng("output.png"); dump;

The output is

x x E sin(x) + E cos(x)

Integral from 0 to pi = 2.28735528718 Exact = 2.28735528718

A lot more functions now accept "call collections". This term stand for a function or expression plus additional parameters in a collection. Call collections are also documented in a better way now including links in the functions that can use them.

>expr &= factor(diff(exp(-s*x^2)/(x^2+1),x))

2 2 - s x 2 x (s x + s + 1) E - -------------------------- 2 2 (x + 1)

>plot2d({{&expr*x,s=1}},0,1):

>romberg({{&expr*x,s=1}},0,1)

-0.434882242722

The function fmin() can now search from a single point or in an interval.

>fmin({{&expr*x,s=1}},0)

0.722066270034

The new method for passing arguments with a function did not work for adaptive integration. This has been fixed.

>adaptiveint({{"a*x^3",a=2}},0,1)

0.5

Protected variables became unprotected if they were changed as global variables inside a function. This has been fixed. Now plot2d() works after plot2d() and a subsequent "clearall". (plot2d() changes global variables like verticallabels).

>plot2d("x^2"); clearall; plot2d("x^2");

Units in expressions can no longer be abused as simple variables. They need a number in front of them.

>"2cm"()

0.02

EMT now is installed with the recent version 5.35.1 of Maxima. The drawback is that LAPACK is no longer working with this version. This should not be a major problem. You can use the routines provided by the numerical part of EMT. Some missing routines from LAPACK will be added in the future.

The new version of Maxima is quite different internally. So the program is now started via the command "sbcl.exe". To make this possible, some internal things had to be changed in the code of EMT. Moreover, the Maxima version is now installed in a subdirectory "maxima", including Gnuplot.

A new tutorial with more details on Maxima has been added to the tutorials.

"listvars" is now possible instead of "listvar".

>x=pi; listvars

x 3.14159265358979

"listvars" will also list global lists. But there is "listlists" too.

>glist("One"); glist("Two"); listlists

One global list Two global list

Like with "listvars" it is possible to add a string.

>listlists ne

One global list

The function glistput(list,pos,value) now adds a value at the list position even if there was a value before. If the list is empty or the position is behind the end of the list, it appends the element to the list.

>glistput("One",1,"First"); glistadd("One","Second"); glistput("One",1,"Alt");

The function glistvar(list,pos) has been replaced by glistget(list,pos).

>for k=1 to glistlength("One"); glistget("One",k), end;

Alt Second

The evaluation of a string now can use units.

>"4cm"()

0.04

This is used by readTable() to read a table with units. Moreover, the expressions in the values of a table can now contain global variables.

EMT has now a collection type, It is in primary beta for the moment, and probably will receive more features along the way.

A collection is declared with {{...}} and can contain any objects.

>L={{4,3,5,6}}

4 3 5 6

Elements can be accessed like vector elements.

>loop 1 to length(L); L[#], end;

4 3 5 6

Collections are good to keep return values of functions in one place. Instead of returning multiple return values a function can return a collection.

>function f(x) := {{x,x^2}}; >f(5)

5 25

However, it is also possible to put the multiple results of an existing function into a collection. In the example, sort() returns the sorted vector and the indices of the sorted elements. The collection L contains both vectors.

>L={{sort(random(6))}}

[0.217693, 0.270906, 0.308411, 0.445363, 0.704419, 0.883227] [4, 2, 6, 5, 3, 1]

Another feature is the execution of a collection, where the first element is the name of a function or an expression.

>function f(x,a) := sin(a*x) >L={{"f",5}}; L(pi/5)

0

This trick is applied in many plot functions and numerical functions now. It avoid the previous semicolon parameters.

>plot2d({{"f",5}},0,2pi):

The same works with expression. But the variables in the collection must be named in this case.

>plot2d({{"sin(omega*x)*exp(-x)",omega=5}},0,2pi):

This works in many numerical functions too.

>integrate({{"sin(omega*x)*exp(-x)",omega=5}},0,2pi)

0.191948568705

The : for insimg() has been fixed. It did not work properly after a loop and inserted the image many times.

>plot2d("sin(x)",0,2pi); ... for k=2 to 5; plot2d("sin(k*x)",>add,color=getspectral(k/6)); end:

The PDF introduction is now in a better state. There are still some things to add.

EMT allows assigned arguments only to override parameters with default values unless the argument is assigned with :=. For functions, which are designed to use a lot of assigned arguments, this can now be released with the modifier "allowassigned".

>function allowassigned f(x) := x*a >f(4,a=6)

24

However, it is possible to declare variables with :=.

>function g(x) := x*a >g(4,a:=6)

24

With >best, the iterate() function now continues to itereate until the error does no longer improve.

>longest iterate("cos(x)",1,>best), longest iterate("cos(x)",1)

0.7390851332151607 0.7390851332157368

The problem is that iterating will take very long if the limit is 0 and >best is turned on.

>{x,count}=iterate("x/2",1,>best); longest x, count,

4.940656458412465e-324 1074

By the way, iterate() also works for vectors. We solve

by iteration.

>function f([x,y]) := [cos(x+y)/2,cos(y)+x^2]; >v=iterate("f",[1,1],>best); longest v, longest f(v)

0.2558264481813221 0.777862408428445 0.2558264481813384 0.7778624084282351

The code Ctrl-Back now joins the line to the previous no matter where the cursor is in that line. Of course, Ctrl-Return splits the line at the cursor.

The parameter grid=0 was not working for implicit plots.

Moreover, the style "#" did still use a black contour line for filled contour plots. This is now disabled. Use "O#" for a contour.

>fullwindow(); plot2d("(x^2+y^2-1)^3-x^2*y^3",r=1.4,level=[-2;0], ... color=rgb(1,0.9,0.9),<grid,style="#",n=200):

I updated the introduction in PDF for the recent version. The work is almost completely done. Three chapters are still missing. This will be continued.

The marker size is no longer global. Previously, the following code worked only for the graphics screen, but failed for the PNG export.

>function test () ... X=random(3,100); {v,i}=sort(-X[3]); X=X[,i]; plot2d(none,r=0.6,cx=0.5,cy=0.5,<grid); markerstyle("o#"); hold on; loop 1 to cols(X) markersize(X[3,#]*50+20); c=1-X[3,#]/2; color(rgb(c,0,c)); mark(X[1,#],X[2,#]); end; hold off; endfunction

>test:

The help for Euler Files has been improved. Now it prints simple comment lines (//...) and comment functions via "maximafunction". Moreover, this help will open if a command line containing "load filename" is double clicked.

With Ctrl-Shift-O a second process for EMT can be started. The second version of EMT will have no graphics window and display the graphics in its notebook window. Moreover, it will not save any settings.

This helps to look up things in a tutorial file or in any previous notebook.

Latex formulas now work with a changed background color now. The bar style "0" now shows the rectangle in the selected color. The SVG export of a graphics with another background color also works now.

>setcolor(0,0.9,0.9,0.9); window(100,100,950,900); ... plot2d("x^3-x",color=blue); ... textbox(latex("y=x^3-x",color=blue,factor=1.5), ... color=blue,style="O",x=0.55,y=0.8):

The function reset() now colors resetcolors(), which now correctly resets the default values of the colors.

>reset;

The parameter >frame now draws a frame even if <grid is set.

>plot2d("x^3-x",<grid,>frame); xgrid(-2:2); ygrid(-6:2:6):

I improved the ibisect() method for guaranteed interval solutions. It did not work optimally, if the zero was accidentally met. Now I made it a trisection method, which works much better.

>ibisect("x",0,2,y=1)

~0.9999999999991,1.000000000001~

It does also work for functions with interval parameters.

>function f(x,a) := a^x-x^a;

The following calls the function by name with "a" given as a semicolon argument.

>ibisect("f",0.5,1.5;1±0.01)

~0.988,1.02~

As usual, expressions are also possible, if the argument is constant or a global variable.

>ibisect("f(x,1±0.01)",0.5,1.5)

~0.988,1.02~

The behavior of the operator "^" had to be fixed once more. Previously EMT evaluated 2^-3^4 as 2^((-3)^4). Now, it follows the convention of Maxima to evaluate this as follows.

>2^-3^2, 2^(-(3^2))

0.001953125 0.001953125

Maxima has the same rule.

>& 2^-3^2, %()

1 --- 512 0.001953125

There have been some fixes in the graphics routines. E.g., the function ylabel() did only work for the default centered position.

>plot2d("exp(-x)",-1,1,0,2,<ticks,title="y = exp(-x)"); ... x0=0.5; y0=exp(-0.5); plot2d(x0,y0,>points,>add); ... plot2d([-1,x0,x0],[y0,y0,0],>add,style="--"); ... ylabel("y = "+print(y0,5,0),y0); xlabel("x = "+x0,x0):

Moreover, the documentation of "plot.e" has been improved.

I switched back to the previous behavior of the order of the evaluation of powers.

>2^2^3, 2^(2^3), (2^2)^3

256 256 64

This is the way Maxima handles powers.

>&2^2^3

256

It seems most algebra programs evaluate from right to left. But Matlab evaluates from left to right. See the following online resources.

Mathematica

Wolfram Alpha

Matlab

There is a new function diffc() for numerical differentiation, which works for analytic functions. The function must evaluate for complex values.

>longest diff("exp(x)",1), longest diffc("exp(x)",1), longest E,

2.718281828460438 2.718281828459045 2.718281828459045

The expression "1e" no longer is interpreted as "1e0". In fact, EMT will issue an error message on exponential numbers which are not well-formed.

Note, that 'E' and 'e' can be used for the exponential format to be able to read external files from other systems. This is sometimes confusing, since E is the Euler number in EMT.

>5E-4, 5*E-4

0.0005 9.5914091423

A problem with global variables in recursive subroutines has been fixed. It appeared only when the global variable changed its size.

The alias feature for functions was not documented.

>function f(x) := x^4; >alias falias f; falias(4)

256

Removing f will also remove g.

>forget f; falias(5)

Function falias not found. Try list ... to find functions! Error in: forget f; falias(5) ... ^

It is now possible to search through the help topics in the help window. Enter "?string" to find the string in the help topics. You can double click on the topic to open it.

You can now debug errors with

>trace errors

If an error occurs in a function you can inspect local variables or expressions containing these variables. Restarting EMT resets all tracing to off.

Now the packages are listed as included packages and provided packages. The latter need to be loaded. I inserted some of the Euler files in the examples into the provided packages.

The settings for the size of the windows and dialogs now depend on the screen size.

The plot function plot2d() got a new flag >addpoints. This allows the same simple overlay as in statplot() without >add. It works only for data plots.

>plot2d(0:10,bin(10,0:10),>addpoints,pointstyle="o"):

The function cimean() computes an interval estimator for the true mean of a normal random variable when a vector of data of these data is given.

>data=randnormal(1,7,1000,50), cimean(data,alpha=1%)

[976.11, 957.904, 1066.25, 1081.34, 1055.23, 1047.58, 1040.13] [966.677, 1097.48]

The function cinormal() computes a confidence interval for normal distributed variables with known mean and standard deviation.

>cinormal(1000,10,alpha=1%)

[974.242, 1025.76]

The file menu got entries for saving and loading in the "Euler Files" directory of the user home folder. Moreover, the shortcuts are now the more logical Alt-S and Alt-O.

It is now documented that the default method for integrate() must get a vectorized function. The error message has been improved.

The statistical functions bindis() and invbindis() are now documented in the tutorials. binsum() is no longer used.

In plot2d(), yl= now works for figures.

>figure(2,2); ... for k=1:4; figure(k); plot2d("x^k",yl="y=x^"+k,xl="x",title=""+k); end; ... figure(0):

The non-vertical labels now align correctly on the left edge.

>plot2d("x^3-x",yl="y=x^3-x",xl="x",<vertical,>smaller):

The Clopper-Pearson confidence interval is an interval such that for probabilities p outside this interval, the observed result is rare. The default level is alpha=0.05.

>clopperpearson(510,1000)

[0.478526, 0.541415]

But you can use a smaller alpha and get a wider interval.

>clopperpearson(510,1000,0.01)

[0.468812, 0.551091]

Some commands now require a semicolon or a line end. This should prevent errors like the following.

>function f(x) ... useglobal a; return a*x; endfunction

>a=5; f(6)

Command "useglobal" needs a semicolon! Try "trace errors" to inspect local variables after errors. f: useglobal a;

The Alt-U now works differently. It inserts all deleted lines and clears the delete buffer. Previously, the buffer was cleared, if the lines were not deleted in successive order. Alt-Del will delete the undo buffer.

Multi-line commands will now be deleted together as one block.

To avoid confusion between expressions and functions, EMT now follows the following rules.

- Expressions take precedence over functions with the same name. - Expressions should be named fx, fxy etc. - A function kills a global symbolic expression with the same name.

>fx &= "x^x"; fx(3)

27

Do not define functions with such names! The following is for demonstration only. The variable fx will be killed.

>function fx(x) := x^2; ... fx(3)

9

Inside of a function, expressions are used instead of functions with the same name. This is what the user expects.

>function h(fx,x) := fx(x);

This does not call the function fx() defined above.

>h("sin",pi/2)

1

I improved the behavior for stack overflows. Now, EMT prevents stack overflows in a better way. This is not fool proof but should work in most cases.

>function f(x) := f(f(x)); >if errorlevel("f(2)") then "Some error occured!", endif;

Some error occured!

If a stack overflow still happens, EMT will crash as before. But the new crash dialog contains an error code now.