# &appname; Manual

1997-2009
Jiří (George) Lebl
2004
Kai Willadsen

&legal;

Jiří
Lebl
University of Illinois, Urbana-Champaign

     jirka@5z.com

Kai
Willadsen
University of Queensland, Australia

     kaiw@itee.uq.edu.au

This manual describes version &appversion; of &appname;.

## Feedback

To report a bug or make a suggestion regarding the &app; application or this manual, follow the directions in the GNOME Feedback Page.

## Introduction

The &app; application is a general calculator for use as a desktop calculator, an educational tool in mathematics, and is useful even for research. The language used in &app; is designed to be ‘mathematical’ in the sense that it should be ‘what you mean is what you get’. Of course that is not an entirely attainable goal. &app; features rationals, arbitrary precision integers and multiple precision floats using the GMP library. It handles complex numbers using cartesian notation. It has good vector and matrix manipulation and can handle basic linear algebra. The programming language allows user defined functions, variables and modification of parameters.

&app; comes in two versions. One version is the graphical GNOME version, which features an IDE style interface and the ability to plot functions of one or two variables. The command line version does not require GNOME, but of course does not implement any feature that requires the graphical interface.

This manual describes mostly the graphical version of the calculator, but the language is of course the same. The command line only version lacks the graphing capabilities and all other capabilities that require the graphical user interface.

## Getting Started

### To Start &app;

You can start &app; in the following ways:

Applications menu

  Depending on your operating system and version, the menu item for &app; could appear in a number of different places. It can be in the Education, Accessories, Office, Science, or similar submenu, depending on your particular setup. The menu item name you are looking for is Genius Math Tool. Once you locate this menu item click on it to start &app;.

Run dialog

  Depending on your system installation the menu item may not be available. If it is not, you can open the Run dialog and execute `gnome-genius`.

Command line

  To start the GNOME version of &app; execute `gnome-genius` from the command line.

  To start the command line only version, execute the following command: `genius`. This version does not include the graphical environment and some functionality such as plotting will not be available.

### When You Start &appname;

When you start the GNOME edition of &app;, the window pictured in is displayed.

#### &app; Window

Shows &app; main window. Contains titlebar, menubar, toolbar and working area. Menubar contains File, Edit, Calculator, Settings, and Help menus.

The &app; window contains the following elements:

Menubar.

  The menus on the menubar contain all of the commands that you need to work with files in &app;. The File menu contains items for loading and saving items and creating new programs. The Load and Run... command does not open a new window for the program, but just executes the program directly. It is equivalent to the `load` command.

  The Calculator menu controls the calculator engine. It allows you to run the currently selected program or to interrupt the current calculation. You can also look at the full expression of the last answer (useful if the last answer was too large to fit onto the console), or you can view a listing of the values of all user defined variables. Finally it allows plotting functions using a user friendly dialog box.

  The other menus have same familiar functions as in other applications.

Toolbar.

  The toolbar contains a subset of the commands that you can access from the menubar.

Working area

  The working area is the primary method of interacting with the application.

  The working area initially has just the Console tab which is the main way of interacting with the calculator. Here you type expressions and the results are immediately returned after you hit the Enter key.

  Alternatively you can write longer programs and those can appear in separate tabs and can be stored in files for later retrieval.

## Basic Usage

### Using the Work Area

Normally you interact with the calculator in the Console tab of the work area. If you are running the text only version then the console will be the only thing that is available to you. If you want to use &app; as a calculator only, just type in your expression here and it willg et evaluated.

Type your expression into the Console work area and press enter and the expression will be evaluated. Expressions are written in a language called GEL. The most simple GEL expression just looks like mathematics. For example

    genius> 30*70 + 67^3.0 + ln(7) * (88.8/100)

or

    genius> 62734 + 812634 + 77^4 mod 5

or

    genius> | sin(37) - e^7 |

or

    genius> sum n=1 to 70 do 1/n

(Last is the harmonic sum from 1 to 70)

To get a list of functions and commands, type:

    genius> help

If you wish to get more help on a specific function, type:

    genius> help FunctionName

To view this manual, type:

    genius> manual

Suppose you have previously saved some GEL commands as a program to a file and you now want to execute them. To load this program from the file `path/to/program.gel`, type

    genius> load path/to/program.gel

&app; keeps track of the current directory. To list files in the current directory type `ls`, to change directory do `cd directory` as in the unix command shell.

### To Create a New Program

To start writing a new program, choose File New Program. A new tab will appear in the work area. You can write a GEL program in this work area. Once you have written your program you can run it by Calculator Run. This will execute your program and will display any output on the Console tab. Executing a program is equivalent of taking the text of the program and typing it into the console. The only difference is that this input is done independent of the console and just the output goes onto the console. Calculator Run will always run the currently selected program even if you are on the Console tab. The currently selected program has its tab in bold type. To select a program, just click on its tab.

To save the program you've just written, choose File Save As...

### To Open and Run a Program

To open a file, choose File Open. A new tab containing the file will appear in the work area. You can use this to edit the file.

To run a program from a file, choose File Load and Run.... This will run the program without opening it in a separate tab. This is equivalent to the `load` command.

## Plotting

Plotting support is only available in the graphical GNOME version. All plotting accessible from the graphical interface is available from the Create Plot window. You can access this window by either clicking on the Plot button on the toolbar or selecting Plot from the Calculator menu. You can also access the plotting functionality by using the plotting functions of the GEL language. See to find out how to enter expressions that &appname; understands.

### Line Plots

To graph real valued functions of one variable open the Create Plot window. You can also use the `LinePlot` function on the command line (see its documentation).

Once you click the Plot button, a window opens up with some notebooks in it. You want to be in the Function line plot notebook tab, and inside you want to be on the Functions / Expressions notebook tab. See .

#### Create Plot Window

Shows the line plotting window.

Into the text boxes just type in expressions where `x` is the independent variable. You can also just give names of functions such as `cos` rather then having to type `cos(x)`. You can graph up to ten functions. If you make a mistake and &appname; cannot parse the input it will signify this with a warning icon on the right of the text input box where the error occurred, as well as giving you an error dialog. You can change the ranges of the dependent and independent variables in the bottom part of the dialog. Pressing the Plot button produces the graph shown in .

#### Plot Window

The graph produced.

From here you can print out the plot, create encapsulated postscript or a PNG version of the plot or change the zoom. If the dependent axis was not set correctly you can have &appname; fit it by finding out the extrema of the graphed functions.

For plotting using the command line see the documentation of the `LinePlot` function.

### Parametric Plots

In the create plot window, you can also choose the Parametric notebook tab to create two dimensional parametric plots. This way you can plot a single parametric function. You can either specify the points as x and y, or giving a single complex number. See .

#### Parametric Plot Tab

Parametric plotting tab in the Create Plot window.

An example of a parametric plot is given in . Similar operations can be done on such graphs as can be done on the other line plots. For plotting using the command line see the documentation of the `LinePlotParametric` or `LinePlotCParametric` function.

#### Parametric Plot

Parametric plot produced

### Slopefield Plots

In the create plot window, you can also choose the Slope field notebook tab to create a two dimensional slope field plot. Similar operations can be done on such graphs as can be done on the other line plots. For plotting using the command line see the documentation of the `SlopefieldPlot` function.

When a slope field is active, there is an extra Solver menu available, through which you can bring up the solver dialog. Here you can have &appname; plot specific solutions for the given initial conditions. You can either specify initial conditions in the dialog, or you can click on the plot directly to specify the initial point. While the solver dialog is active, the zooming by clicking and dragging does not work. You have to close the dialog first if you want to zoom using the mouse.

The solver uses the standard Runge-Kutta method. The plots will stay on the screen until cleared. The solver will stop whenever it reaches the boundary of the plot window. Zooming does not change the limits or parameters of the solutions, you will have to clear and redraw them with appropriate parameters. You can also use the `SlopefieldDrawSolution` function to draw solutions from the command line or programs.

### Vectorfield Plots

In the create plot window, you can also choose the Vector field notebook tab to create a two dimensional vector field plot. Similar operations can be done on such graphs as can be done on the other line plots. For plotting using the command line see the documentation of the `VectorfieldPlot` function.

By default the direction and magnitude of the vector field is shown. To only show direction and not the magnitude, check the appropriate checkbox to normalize the arrow lengths.

When a vector field is active, there is an extra Solver menu available, through which you can bring up the solver dialog. Here you can have &appname; plot specific solutions for the given initial conditions. You can either specify initial conditions in the dialog, or you can click on the plot directly to specify the initial point. While the solver dialog is active, the zooming by clicking and dragging does not work. You have to close the dialog first if you want to zoom using the mouse.

The solver uses the standard Runge-Kutta method. The plots will stay on the screen until cleared. Zooming does not change the limits or parameters of the solutions, you will have to clear and redraw them with appropriate parameters. You can also use the `VectorfieldDrawSolution` function to draw solutions from the command line or programs.

### Surface Plots

&appname; can also plot surfaces. Select the Surface plot tab in the main notebook of the Create Plot window. Here you can specify a single expression which should use either `x` and `y` as real independent variables or `z` as a complex variable (where `x` is the real part of `z` and `y` is the imaginary part). For example to plot the modulus of the cosine function for complex parameters, you could enter `|cos(z)|`. This would be equivalent to `|cos(x+1i*y)|`. See . For plotting using the command line see the documentation of the `SurfacePlot` function.

#### Surface Plot

Modulus of the complex cosine function.

## GEL Basics

GEL stands for Genius Extension Language. It is the language you use to write programs in &appname;. A program in GEL is simply an expression that evaluates to a number. &app; can therefore be used as a simple calculator, or as a powerful theoretical research tool. The syntax is meant to have as shallow of a learning curve as possible, especially for use as a calculator.

### Values

Values in GEL can be numbers, Booleans or strings. Values can be used in calculations, assigned to variables and returned from functions, among other uses.

#### Numbers

Integers are the first type of number in GEL. Integers are written in the normal way.

    1234

Hexidecimal and octal numbers can be written using C notation. For example:

    0x123ABC
    01234

Or you can type numbers in an arbitrary base using `<base>\<number>`. Digits higher than 10 use letters in a similar way to hexadecimal. For example, a number in base 23 could be written:

    23\1234ABCD

The second type of GEL number is rationals. Rationals are simply achieved by dividing two integers. So one could write:

    3/4

to get three quarters. Rationals also accept mixed fraction notation. So in order to get one and three tenths you could write:

    1 3/10

The next type if number is floating point. These are entered in a similar fashion to C notation. You can use `E`, `e` or `@` as the exponent delimiter. Note that using the exponent delimiter gives a float even if there is no decimal point in the number. Examples:

    1.315
    7.887e77
    7.887e-77
    .3
    0.3
    77e5

When &appname; prints a floating point number it will always append a `.0` even if the number is whole. This is to indicate that floating point numbers are taken as imprecise quantities. When a number is written in the scientific notation, it is always a floating point number and thus &appname; does not print the `.0`.

The final type of number in gel is the complex numbers. You can enter a complex number as a sum of real and imaginary parts. The imaginary part ends with an `i`. Here are examples of entering complex numbers:

    1+2i
    8.01i
    77*e^(1.3i)

When entering imaginary numbers, a number must be in front of the `i`. If you use `i` by itself, &appname; will interpret this as referring to the variable `i`. If you need to refer to `i` by itself, use `1i` instead.

In order to use mixed fraction notation with imaginary numbers you must have the mixed fraction in parentheses. (i.e., `(1 2/5)i`)

#### Booleans

&appname; also supports native Boolean values. The two Boolean constants are defined as `true` and `false`; these identifiers can be used like any other variable. You can also use the identifiers `True`, `TRUE`, `False` and `FALSE` as aliases for the above.

At any place where a Boolean expression is expected, you can use a Boolean value or any expression that produces either a number or a Boolean. If &appname; needs to evaluate a number as a Boolean it will interpret 0 as `false` and any other number as `true`.

In addition, you can do arithmetic with Boolean values. For example:

    ( (1 + true) - false ) * true

is the same as:

    ( (true or true) or not false ) and true

Only addition, subtraction and multiplication are supported. If you mix numbers with Booleans in an expression then the numbers are converted to Booleans as described above. This means that, for example:

    1 == true

always evaluates to `true` since 1 will be converted to `true` before being compared to `true`.

#### Strings

Like numbers and Booleans, strings in GEL can be stored as values inside variables and passed to functions. You can also concatenate a string with another value using the plus operator. For example:

    a=2+3;"The result is: "+a

will create the string:

    The result is: 5

You can also use C-like escape sequences such as `\n`,`\t`,`\b`,`\a` and `\r`. To get a `\` or `"` into the string you can quote it with a `\`. For example:

    "Slash: \\ Quotes: \" Tabs: \t1\t2\t3"

will make a string:

    Slash: \ Quotes: " Tabs: 	1	2	3

In addition, you can use the library function `string` to convert anything to a string. For example:

    string(22)

will return

    "22"

Strings can also be compared with `==` (equal), `!=` (not equal) and `<=>` (comparison) operators

#### Null

There is a special value called `null`. No operations can be performed on it, and nothing is printed when it is returned. Therefore, `null` is useful when you do not want output from an expression. The value `null` can be obtained as an expression when you type `.`, the contant `null` or nothing. By nothing we mean that if you end an expression with a separator `;`, it is equivalent to ending it with a separator followed by a `null`.

Example:

    x=5;.
    x=5;

Some functions return `null` when no value can be returned or an error happened. Also `null` is used as an empty vector or matrix, or an empty reference.

### Using Variables

Syntax:

    VariableName

Example:

    genius> e
    = 2.71828182846

To evaluate a variable by itself, just enter the name of the variable. This will return the value of the variable. You can use a variable anywhere you would normally use a number or string. In addition, variables are necessary when defining functions that take arguments (see ).

#### Using Tab completion

You can use Tab completion to get &appname; to complete variable names for you. Try typing the first few letters of the name and pressing `Tab`.

#### Variable names are case sensitive

The names of variables are case sensitive. That means that variables named `hello`, `HELLO` and `Hello` are all different variables.

#### Setting Variables

Syntax:

    <identifier> = <value>
    <identifier> := <value>

Example:

    x = 3
    x := 3

To assign to a variable, use the `=` or `:=` operators. These operators set the value of the variable and return the number you set, so you can do things like

    a = b = 5

The `=` and `:=` operators can both be used to set variables. The difference between them is that the `:=` operator always acts as an assignment operator, whereas the `=` operator may be interpreted as testing for equality when used in a context where a Boolean expression is expected.

For issues regarding the scope of variables, see .

#### Built-in Variables

GEL has a number of built-in ‘variables’, such as `e`, `pi` or `GoldenRatio`. These are widely used constants with a preset value, and they cannot be assigned new values. There are a number of other built-in variables. See for a full list.

#### Previous Result Variable

The `Ans` and `ans` variables can be used to get the result of the last expression. For example, if you had performed some calculation, to add 389 to the result you could do:

    Ans+389

### Using Functions

Syntax:

    FunctionName(argument1, argument2, ...)

Example:

    Factorial(5)
    cos(2*pi)
    gcd(921,317)

To evaluate a function, enter the name of the function, followed by the arguments (if any) to the function in parentheses. This will return the result of applying the function to its arguments. The number of arguments to the function is, of course, different for each function.

There are many built-in functions, such as `sin`, `cos` and `tan`. You can use the `help` built-in function to get a list of available functions, or see for a full listing.

#### Using Tab completion

You can use Tab completion to get &appname; to complete function names for you. Try typing the first few letters of the name and pressing `Tab`.

#### Function names are case sensitive

The names of functions are case sensitive. That means that functions named `dosomething`, `DOSOMETHING` and `DoSomething` are all different functions.

#### Defining Functions

Syntax:

    function <identifier>(<comma separated arguments>) = <function body>
    <identifier> = (`() = <function body>)

The ``` is the backquote character, and signifies an anonymous function. By setting it to a variable name you effectively define a function.

A function takes zero or more comma separated arguments, and returns the result of the function body. Defining your own functions is primarily a matter of convenience; one possible use is to have sets of functions defined in GEL files which &appname; can load in order to make available. Example:

    function addup(a,b,c) = a+b+c

then `addup(1,4,9)` yields 14

#### Variable Argument Lists

If you include `...` after the last argument name in the function declaration, then &appname; will allow any number of arguments to be passed in place of that argument. If no arguments were passed then that argument will be set to `null`. Otherwise, it will be a horizontal vector containing all the arguments. For example:

    function f(a,b...) = b

Then `f(1,2,3)` yields `[2,3]`, while `f(1)` yields a `null`.

#### Passing Functions to Functions

In &appname;, it is possible to pass a function as an argument to another function. This can be done using either ‘function nodes’ or anonymous functions.

If you do not enter the parentheses after a function name, instead of being evaluated, the function will instead be returned as a ‘function node’. The function node can then be passed to another function. Example:

    function f(a,b) = a(b)+1;
    function b(x) = x*x;
    f(b,2)

If you want to pass a function that doesn’t exist yet, you can use an anonymous function (see ).

Syntax:

    function(<comma separated arguments>) = <function body>
    `(<comma separated arguments>) = <function body>

Example:

    function f(a,b) = a(b)+1;
    f(`(x) = x*x,2)

#### Operations on Functions

Some functions allow arithmetic operations, and some single argument functions such as `exp` or `ln`, to operate on the function. For example,

    exp(sin*cos+4)

will return a function that does

    exp(sin(x)*cos(x)+4)

This can be useful when quickly defining functions. For example to create a function to perform the above operation, you can just type:

    f = exp(sin*cos+4)

This can also be used in plotting. For example, to plot sin squared you can enter:

    LinePlot(sin^2)

Not all functions can be used in this way. In addition, when you use a binary operation the functions must take the same arguments.

### Absolute Value / Modulus

You can make an absolute value of something by putting the `|`'s around it. For example:

    |a-b|

In case the expression is a complex number the result will be the modulus (distance from the origin). For example: `|3 * e^(1i*pi)|` returns 3.

### Separator

In GEL if you want to type more than one command you have to use the `;` operator, which is a way to separate expressions, such a combined expression will return whatever is the result of the last one, so suppose you type the following:

    3 ; 5

This expression will yield 5.

This will require some parenthesizing to make it unambiguous sometimes, especially if the `;` is not the top most primitive. This slightly differs from other programming languages where the `;` is a terminator of statements, whereas in GEL it’s actually a binary operator. If you are familiar with pascal this should be second nature. However genius can let you pretend it is a terminator somewhat, if a `;` is found at the end of a parenthesis or a block, genius will itself append a null node to it as if you would have written `;null`. This is usefull in case you do not want to return a value from say a loop, or if you handle the return differently. Note that it will slightly slow down the code if it is executed too often as there is one more operator involved.

### Modular Evaluation

Sometimes when working with large numbers, it might be faster if results are modded after each calculation. To use it you just add "mod <integer>" after the expression. Example:

    2^(5!) * 3^(6!) mod 5

You can calculate the inverses of numbers mod some integer by just using rational numbers (of course the inverse has to exist). Examples:

    10^-1 mod 101
    1/10 mod 101

You can also do modular evaluation with matrices including taking inverses, powers and dividing. Example:

    A = [1,2;3,4]
    B = A^-1 mod 5
    A*B mod 5

This should yield the identity matrix as B will be the inverse of A mod 5.

Some functions such as `sqrt` or `log` work in a different way when in modulo mode. These will then work like their discrete versions working within the ring of integers you selected. For example:

    genius> sqrt(4) mod 7
    =
    [2, 5]
    genius> 2*2 mod 7
    = 4

`sqrt` will actually return all the possible square roots.

### List of GEL Operators

As everything in gel is really just an expression, it is really just all connected together with operators. Here is a list of the operators in GEL.

    a;b

  The separator, just evaluates both `a` and `b`, but returns only the result of `b`.

    a=b

  The assignment operator. This assigns `b` to `a` (`a` must be a valid lvalue) (note however that this operator may be translated to `==` if used in a place where boolean expression is expected)

    a:=b

  The assignment operator. Assigns `b` to `a` (`a` must be a valid lvalue). This is different from `=` because it never gets translated to a `==`.

    |a|

  Absolute value or modulus (if `a` is a complex number).

  See Mathworld for more information.

    a^b

  Exponentiation, raises `a` to the `b`th power.

    a.^b

  Element by element exponentiation. Raise each element of a matrix `a` to the `b`th power. Or if `b` is a matrix of the same size as `a`, then do the operation element by element. If `a` is a number and `b` is a matrix then it creates matrix of the same size as `b` with `a` raised to all the different powers in `b`.

    a+b

  Addition. Adds two numbers, matrices, functions or strings. If you add a string to anything the result will just be a string.

    a-b

  Subtraction. Subtract two numbers, matrices or functions.

    a*b

  Multiplication. This is the normal matrix multiplication.

    a.*b

  Element by element multiplication if `a` and `b` are matrices.

    a/b

  Division.

    a./b

  Element by element division.

    a\b

  Back division. That is this is the same as `b/a`.

    a.\b

  Element by element back division.

    a%b

  The mod operator. This does not turn on the modular mode, but just returns the remainder of `a/b`.

    a.%b

  Element by element the mod operator. Returns the remaineder after element by element `a./b`.

    a mod b

  Modular evaluation operator. The expression `a` is evaluated modulo `b`. See . Some functions and operators behave differently modulo an integer.

    a!

  Factorial operator. This is like `1*...*(n-2)*(n-1)*n`.

    a!!

  Double factorial operator. This is like `1*...*(n-4)*(n-2)*n`.

    a==b

  Equality operator (returns `true` or `false`).

    a!=b

  Inequality operator, returns `true` if `a` does not equal `b` else returns `false`.

    a<>b

  Alternative inequality operator, returns `true` if `a` does not equal `b` else returns `false`.

    a<=b

  Less than or equal operator, returns `true` if `a` is less than or equal to `b` else returns `false`.

    a>=b

  Greater than or equal operator, returns `true` if `a` is greater than or equal to `b` else returns `false`.

    a<=>b

  Comparison operator. If `a` is equal to `b` it returns 0, if `a` is less than `b` it returns -1 and if `a` is greater than `b` it returns 1.

    a and b

  Logical and.

    a or b

  Logical or.

    a xor b

  Logical xor.

    not a

  Logical not.

    -a

  Negation operator.

    &a

  Variable referencing (to pass a reference to something). See .

    *a

  Variable dereferencing (to access a referenced varible). See .

    a'

  Matrix conjugate transpose.

    a.'

  Matrix transpose, does not conjugate the entries.

    a@(b,c)

  Get element of a matrix in row `b` and column `c`. If `b`, `c` are vectors, then this gets the corresponding rows columns or submatrices.

    a@(b,)

  Get row of a matrix (or rows if `b` is a vector).

    a@(b,:)

  Same as above.

    a@(,c)

  Get column of a matrix (or columns if `c` is a vector).

    a@(:,c)

  Same as above.

    a@(b)

  Get an element from a matrix treating it as a vector. This will traverse the matrix row-wise.

    a:b

  Build a vector from `a` to `b` (or specify a row, column region for the `@` operator). For example to get rows 2 to 4 of mamtrix `A` we could do

      A@(2:4,)

  as `2:4` will return a vector `[2,3,4]`.

    a:b:c

  Build a vector from `a` to `c` with `b` as a step. That is for example

      genius> 1:2:9
      =
      `[1, 3, 5, 7, 9]

    (a)i

  Make a imaginary number (multiply `a` by the imaginary). Note that normally the number `i` is written as `1i`. So the above is equal to

      (a)*1i

    `a

  Quote an identifier so that it doesn't get evaluated. Or quote a matrix so that it doesn't get expanded.

The @() operator makes the : operator most useful. With this you can specify regions of a matrix. So that a@(2:4,6) is the rows 2,3,4 of the column 6. Or a@(,1:2) will get you the first two columns of a matrix. You can also assign to the @() operator, as long as the right value is a matrix that matches the region in size, or if it is any other type of value.

The comparison operators (except for the <=> operator which behaves normally), are not strictly binary operators, they can in fact be grouped in the normal mathematical way, e.g.: (1<x<=y<5) is a legal boolean expression and means just what it should, that is (1<x and x≤y and y<5)

The unitary minus operates in a different fashion depending on where it appears. If it appears before a number it binds very closely, if it appears in front of an expression it binds less than the power and factorial operators. So for example `-1^k` is really `(-1)^k`, but `-foo(1)^k` is really `-(foo(1)^k)`. So be careful how you use it and if in doubt, add parentheses.

## Programming with GEL

### Conditionals

Syntax:

    if <expression1> then <expression2> [else <expression3>]

If `else` is omitted, then if the `expression1` yields `false` or 0, `NULL` is returned.

Examples:

    if(a==5)then(a=a-1)
    if b<a then b=a
    if c>0 then c=c-1 else c=0
    a = ( if b>0 then b else 1 )

Note that `=` will be translated to `==` if used inside the expression for `if`, so

    if a=5 then a=a-1

will be interpreted as:

    if a==5 then a:=a-1

### Loops

#### While Loops

Syntax:

    while <expression1> do <expression2>
    until <expression1> do <expression2>
    do <expression2> while <expression1>
    do <expression2> until <expression1>

These are similiar to other languages, however they return the result of the last iteration or `NULL` if no iteration was done. In the boolean expression, `=` is translated into `==` just as for the `if` statement.

#### For Loops

Syntax:

    for <identifier> = <from> to <to> do <body>
    for <identifier> = <from> to <to> by <increment> do <body>

Loop with identifier being set to all values from `<from>` to `<to>`, optionally using an increment other than 1. These are faster, nicer and more compact than the normal loops such as above, but less flexible. The identifier must be an identifier and can't be a dereference. The value of identifier is the last value of identifier, or `<from>` if body was never evaluated. The variable is guaranteed to be initialized after a loop, so you can safely use it. Also the `<from>`, `<to>` and `<increment>` must be non complex values. The `<to>` is not guaranteed to be hit, but will never be overshot, for example the following prints out odd numbers from 1 to 19:

    for i = 1 to 20 by 2 do print(i)

#### Foreach Loops

Syntax:

    for <identifier> in <matrix> do <body>

For each element, going row by row from left to right do the body. To print numbers 1,2,3 and 4 in this order you could do:

    for n in [1,2:3,4] do print(n)

If you wish to run through the rows and columns of a matrix, you can use the RowsOf and ColumnsOf functions which return a vector of the rows or columns of the matrix. So,

    for n in RowsOf ([1,2:3,4]) do print(n)

will print out [1,2] and then [3,4].

#### Break and Continue

You can also use the `break` and `continue` commands in loops. The continue `continue` command will restart the current loop at its next iteration, while the `break` command exits the current loop.

    while(<expression1>) do (
      if(<expression2>) break
      else if(<expression3>) continue;
      <expression4>
    )

### Sums and Products

Syntax:

    sum <identifier> = <from> to <to> do <body>
    sum <identifier> = <from> to <to> by <increment> do <body>
    sum <identifier> in <matrix> do <body>
    prod <identifier> = <from> to <to> do <body>
    prod <identifier> = <from> to <to> by <increment> do <body>
    prod <identifier> in <matrix> do <body>

If you substitute `for` with `sum` or `prod`, then you will get a sum or a product instead of a `for` loop. Instead of returning the last value, these will return the sum or the product of the values respectively.

If no body is executed (for example `sum i=1 to 0 do ...`) then `sum` returns 0 and `prod` returns 1 as is the standard convention.

### Comparison Operators

The following standard comparison operators are supported in GEL and have the obvious meaning: `==`, `>=`, `<=`, `!=`, `<>`, `<`, `>`. They return `true` or `false`. The operators `!=` and `<>` are the same thing and mean "is not equal to". GEL also supports the operator `<=>`, which returns -1 if left side is smaller, 0 if both sides are equal, 1 if left side is larger.

Normally `=` is translated to `==` if it happens to be somewhere where GEL is expecing a condition such as in the if condition. For example

    if a=b then c
    if a==b then c

are the same thing in GEL. However you should really use `==` or `:=` when you want to compare or assign respectively if you want your code to be easy to read and to avoid mistakes.

All the comparison operators (except for the `<=>` operator which behaves normally), are not strictly binary operators, they can in fact be grouped in the normal mathematical way, e.g.: (`1<x<=y<5`) is a legal boolean expression and means just what it should, that is (1<x and x≤y and y<5)

To build up logical expressions use the words `not`, `and`, `or`, `xor`. The operators `or` and `and` are special beasts as they evaluate their arguemnts one by one, so the usual trick for conditional evaluation works here as well. For example, `1 or a=1` will not set `a=1` since the first argument was true.

### Global Variables and Scope of Variables

Like most programming languages, GEL has two different types of variables: local and global. A local variable only exists in the context of the function where it is set and all functions called from inside this function. A global variable exists in all contexts. When you set a variable on the toplevel command line, outside of any function, then it will be a global. All functions will see it.

When you set a variable inside a function, it will only be seen inside the function, including all function calls that are made inside this function. This is where GEL differs from a language such as C. One could describe local variables as being semi global in this sense. For example the following code will print out 5. but the function `g` cannot be called on the top level as `a` will not be defined.

    function f() = (a:=5; g());
    function g() = print(a);
    f();

Suppose you assign a value to an identifier inside a function, and this identifier is also used for a global variable, or a variable set in a calling function. Then this has the effect of creating a new local variable inside the function. For example the following code will print out 6 and not 5.

    a=6;
    function f() = (a:=5);
    print(a);

Sometimes however it is neccessary to set a global variable from inside a function. For this, use the `set` function. Passing a string or a quoted identifier to this function sets the variable globally. For example, to set `a` to the value 3 you could call:

    set(`a,3)

or:

    set("a",3)

The `set` function always sets the toplevel global. There is no way to set a local variable in some function from a subroutine. For this you must use passing by reference.

### Returning

Normally a function is one or several expressions separated by a semicolon, and the value of the last expression is returned. This is fine for simple functions, but sometimes you do not want a function to return the last thing calculated. You may, for example, want to return from a middle of a function. In this case, you can use the `return` keyword. `return` takes one argument, which is the value to be returned.

Example:

    function f(x) = (
      y=1;
      while true do (
        if x>50 then return y;
        y=y+1;
        x=x+1
      )
    )

### References

It may be neccessary for some functions to return more than one value. This may be accomplished by returning a vector of values, but many times it is convenient to use passing a reference to a variable. You pass a reference to a variable to a function, and the function will set the variable for you using a dereference. You do not have to use references only for this purpose, but this is their main use.

When using functions which return values through references in the argument list, just pass the variable name with an ampersand. For example the following code will compute an eigenvalue of a matrix `A` with initial eigenvector guess `x`, and store the computed eigenvector into the variable named `v`:

    RayleighQuotientIteration (A,x,0.001,100,&v)

The details of how references work and the syntax is similar to the C language. The operator `&` references a variable and `*` dereferences a variable. Both can only be applied to an identifier, so `**a` is not a legal expression in GEL.

References are best explained by an example:

    a=1;
    b=&a;
    *b=2;

now `a` contains 2. You can also reference functions:

    function f(x) = x+1;
    t=&f;
    *t(3)

gives us 4.

### Lvalues

An lvalue is the left hand side of an assignment. In other words, an lvalue is what you assign something to. Valid lvalues are:

`a`

  Identifier. Here we would be setting the varable of name `a`.

`*a`

  Dereference of an identifier. This will set whatever variable `a` points to.

`a@(<region>)`

  A region of a matrix. Here the region is specified normally as with the regular @() operator, and can be a single entry, or an entire region of the matrix.

Examples:

    a:=4
    *tmp := 89
    a@(1,1) := 5
    a@(4:8,3) := [1,2,3,4,5]'

Note that both `:=` and `=` can be used interchangably. Except if the assignment appears in a condition. It is thus always safer to just use `:=` when you mean assignment, and `==` when you mean comparison.

## Advanced Programming with GEL

### Error Handling

If you detect an error in your function, you can bail out of it. For normal errors, such as wrong types of arguments, you can fail to compute the function by adding the statement `bailout`. If something went really wrong and you want to completely kill the current computation, you can use `exception`.

For example if you want to check for arguments in your function. You could use the following code.

    function f(M) = (
      if not IsMatrix (M) then (
        error ("M not a matrix!");
        bailout
      );
      ...
    )

### Toplevel Syntax

The synatax is slightly different if you enter statements on the top level versus when they are inside parentheses or inside functions. On the top level, enter acts the same as if you press return on the command line. Therefore think of programs as just sequence of lines as if were entered on the command line. In particular, you do not need to enter the separator at the end of the line (unless it is of course part of several statements inside parenteses).

The following code will produce an error when entered on the top level of a program, while it will work just fine in a function.

    if Something() then
      DoSomething()
    else
      DoSomethingElse()

The problem is that after &app; sees the end of line after the second line, it will decide that we have whole statement and it will execute it. After the execution is done, &app; will go on to the next line, it will see `else`, and it will produce a parsing error. To fix this, use parentheses. &app; will not be satisfied until it has found that all parenteses are closed.

    if Something() then (
      DoSomething()
    ) else (
      DoSomethingElse()
    )

### Returning Functions

It is possible to return functions as value. This way you can build functions which construct special purpose functions according to some parameters. The tricky bit is what variables does the function see. The way this works in GEL is that when a function returns another function, all identifiers referenced in the function body are prepended a private dictionary of the returned function. So the function will see all variables that were in scope when it was defined. For example we define a function which returns a function which adds 5 to its argument.

    function f() = (
      k = 5;
      `(x) = (x+k)
    )

Notice that the function adds `k` to `x`. You could use this as follows.

    g = f();
    g(5)

And `g(5)` should return 10.

One thing to note is that the value of `k` that is used is the one that's in effect when the `f` returns. So for example

    function f() = (
      k = 5;
      r = `(x) = (x+k);
      k = 10;
      r
    )

will return a function that adds 10 to its argument rather than 5. This is because the extra dictionary is created only when the context in which the function was defined ends, which is when the function `f` returns. This is consistent with how you would expect the function `r` to work inside the function `f` according to the rules of scope of variables in GEL. Only those variables are added to the extra dictionary that are in the context that just ended and no longer exists. Variables used in the function that are in still valid contexts will work as usual, using the current value of the variable.

### GEL Startup Procedure

First the program looks for the installed library file (the compiled version `lib.cgel`) in the installed directory, then it looks into the current directory, and then it tries to load an uncompiled file called `~/.geniusinit`.

If you ever change the the library its installed place, you’ll have to first compile it with `genius --compile loader.gel > lib.cgel`

### Loading Programs

Sometimes you have a larger program that you wrote into a file and want to read in that file. In these situations, you have two options. You can keep the functions you use most inside the `~/.geniusinit` file. Or if you want to load up a file in a middle of a session (or from within another file), you can type `load <list of filenames>` at the prompt. This has to be done on the top level and not inside any function or whatnot, and it cannot be part of any expression. It also has a slightly different syntax than the rest of genius, more similiar to a shell. You can enter the file in quotes. If you use the '' quotes, you will get exactly the string that you typed, if you use the "" quotes, special characters will be unescaped as they are for strings. Example:

    load program1.gel program2.gel
    load "Weird File Name With SPACES.gel"

There are also `cd`, `pwd` and `ls` commands built in. `cd` will take one argument, `ls` will take an argument which is like the glob in the unix shell (i.e., you can use wildcards). `pwd` takes no arguments. For example:

    cd directory_with_gel_programs
    ls *.gel

## Matrices in GEL

Genius has support for vectors and matrices and a sizable library of matrix manipulation and linear algebra functions.

### Entering Matrices

To enter matrixes, you can use one of the following two syntaxes. You can either enter the matrix on one line, separating values by commas and rows by semicolons. Or you can enter each row on one line, separating values by commas. You can also just combine the two methods. So to enter a 3x3 matrix of numbers 1-9 you could do

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

or

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

Do not use both ';' and return at once on the same line though.

You can also use the matrix expansion functionality to enter matricies. For example you can do:

    a = [ 1, 2, 3
          4, 5, 6
          7, 8, 9]
    b = [ a,  10
          11, 12]

and you should get

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

similiarly you can build matricies out of vectors and other stuff like that.

Another thing is that non-specified spots are initialized to 0, so

    [1, 2, 3
     4, 5
     6]

will end up being

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

When matrices are evaluated, they are evaluated and traversed row-wise. This is just like the `M@(j)` operator which traverses the matrix row-wise.

Be careful about using returns for expressions inside the `[ ]` brackets, as they have a slightly different meaning there. You will start a new row.

### Conjugate Transpose and Transpose Operator

You can conjugate transpose a matrix by using the `'` operator. That is the entry in the `i`th column and the `j`th row will be the complex conjugate of the entry in the `j`th column and the `i`th row of the original matrix. For example:

    [1,2,3]*[4,5,6]'

We transpose the second vector to make matrix multiplication possible. If you just want to transpose a matrix without conjugating it, you would use the `.'` operator. For example:

    [1,2,3]*[4,5,6i].'

Note that normal transpose, that is the `.'` operator, is much faster and will not create a new copy of the matrix in memory. The conjugate transpose does create a new copy unfortunately. It is recommended to always use the `.'` operator when working with real matrices and vectors.

### Linear Algebra

&appname; implements many useful linear algebra and matrix manipulation routines. See the Linear Algebra and Matrix Manipulation sections of the GEL function listing.

The linear algebra routines implemented in GEL do not currently come from a well tested numerical package, and thus should not be used for critical numerical computation. On the other hand, Genius implements very well many linear algebra operations with rational and integer coefficients. These are inherently exact and in fact will give you much better results than common double precision routines for linear algebra.

For example, it is pointless to compute the rank and nullspace of a floating point matrix since for all practical purposes, we need to consider the matrix as having some slight errors. You are likely to get a different result than you expect. The problem is that under a small perturbation every matrix is of full rank and invertible. If the matrix however is of rational numbers, then the rank and nullspace are always exact.

In general when &appname; computes the basis of a certain vectorspace (for example with the `NullSpace`) it will give the basis as a matrix, in which the columns are the vectors of the basis. That is, when &appname; talks of a linear subspace it means a matrix whose column space is the given linear subspace.

It should be noted that &appname; can remember certain properties of a matrix. For example, it will remember that a matrix is in row reduced form. If many calls are made to functions which internally use row reduced form of the matrix, we can just row reduce the matrix beforehand once. Successive calls to `rref` will be very fast.

## Polynomials in GEL

Currently &appname; can handle polynomials of one variable written out as vectors, and do some basic operations with these. It is planned to expand this support further.

### Using Polynomials

Currently polynomials in one variable are just horizontal vectors with value only nodes. The power of the term is the position in the vector, with the first position being 0. So,

    [1,2,3]

translates to a polynomial of

    1 + 2*x + 3*x^2

You can add, subtract and multiply polynomials using the `AddPoly`, `SubtractPoly`, and `MultiplyPoly` functions respectively. You can print a polynomial using the `PolyToString` function. For example,

    PolyToString([1,2,3],"y")

gives

    3*y^2 + 2*y + 1

You can also get a function representation of the polynomial so that you can evaluate it. This is done by using `PolyToFunction`, which returns an anonymous function which you can assign to something.

    f = PolyToFunction([0,1,1])
    f(2)

It is also possible to find roots of polynomials of degrees 1 through 4 by using the function `PolynomialRoots`, which calls the appropriate formula function. Higher degree polynomials must be converted to functions and solved numerically using a function such as `FindRootBisection`, `FindRootFalsePosition`, `FindRootMullersMethod`, or `FindRootSecant`.

See in the function list for the rest of functions acting on polynomials.

## Set Theory in GEL

&appname; has some basic set theoretic functionality built in. Currently a set is just a vector (or a matrix). Every distinct object is treated as a different element.

### Using Sets

Just like vectors, objects in sets can include numbers, strings, `null`, matrices and vectors. It is planned in the future to have a dedicated type for sets, rather than using vectors. Note that floating point numbers are distinct from integers, even if they appear the same. That is, &appname; will treat `0` and `0.0` as two distinct elements. The `null` is treated as an empty set.

To build a set out of a vector, use the `MakeSet` function. Currently, it will just return a new vector where every element is unique.

    genius> MakeSet([1,2,2,3])
    = [1, 2, 3]

Similarly there are functions `Union`, `Intersection`, `SetMinus`, which are rather self explanatory. For example:

    genius> Union([1,2,3], [1,2,4])
    = [1, 2, 4, 3]

Note that no order is guaranteed for the return values. If you wish to sort the vector you should use the `SortVector` function.

For testing membership, there are functions `IsIn` and `IsSubset`, which return a boolean value. For example:

    genius> IsIn (1, [0,1,2])
    = true

The input `IsIn(x,X)` is of course equivalent to `IsSubset([x],X)`. Note that since the empty set is a subset of every set, `IsSubset(null,X)` is always true.

## List of GEL functions

&gel-function-list;

## Example Programs in GEL

Here is a function that calculates factorials:

    function f(x) = if x <= 1 then 1 else (f(x-1)*x)

With indentation it becomes:

    function f(x) = (
      if x <= 1 then
        1
      else
        (f(x-1)*x)
    )

This is a direct port of the factorial function from the bc manpage. The syntax seems similar to bc, but different in that in GEL, the last expression is the one that is returned. Using the `return` function instead, it would be:

    function f(x) = (
      if (x <= 1) then return (1);
      return (f(x-1) * x)
    )

By far the easiest way to define a factorial function would be using the product loop as follows. This is not only the shortest and fastest, but also probably the most readable version.

    function f(x) = prod k=1 to x do k

Here is a larger example, this basically redefines the internal `ref` function to calculate the row echelon form of a matrix. The function `ref` is built in and much faster, but this example demonstrates some of the more complex features of GEL.

    # Calculate the row-echelon form of a matrix
    function MyOwnREF(m) = (
      if not IsMatrix(m) or not IsValueOnly(m) then
        (error("ref: argument not a value only matrix");bailout);
      s := min(rows(m), columns(m));
      i := 1;
      d := 1;
      while d <= s and i <= columns(m) do (

        # This just makes the anchor element non-zero if at
        # all possible
        if m@(d,i) == 0 then (
          j := d+1;
          while j <= rows(m) do (
            if m@(j,i) == 0 then
              (j=j+1;continue);
            a := m@(j,);
            m@(j,) := m@(d,);
            m@(d,) := a;
            j := j+1;
            break
          )
        );
        if m@(d,i) == 0 then
          (i:=i+1;continue);

        # Here comes the actual zeroing of all but the anchor
        # element rows
        j := d+1;
        while j <= rows(m)) do (
          if m@(j,i) != 0 then (
            m@(j,) := m@(j,)-(m@(j,i)/m@(d,i))*m@(d,)
          );
          j := j+1
        );
        m@(d,) := m@(d,) * (1/m@(d,i));
        d := d+1;
        i := i+1
      );
      m
    )

## Settings

To configure &app;, choose Settings Preferences. There are several basic parameters provided by the calculator in addition to the ones provided by the standard library. These control how the calculator behaves.

### Changing Settings with GEL

Many of the settings in &appname; are simply global variables, and can be evaluated and assigned to in the same way as normal variables. See about evaluating and assigning to variables, and for a list of settings that can be modified in this way.

As an example, you can set the maximum number of digits in a result to 12 by typing:

    MaxDigits = 12

### Output

Maximum digits to output

  The maximum digits in a result (`MaxDigits`)

Results as floats

  If the results should be always printed as floats (`ResultsAsFloats`)

Floats in scientific notation

  If floats should be in scientific notation (`ScientificNotation`)

Always print full expressions

  Should we print out full expressions for non-numeric return values (longer than a line) (`FullExpressions`)

Use mixed fractions

  If fractions should be printed as mixed fractions such as "1 1/3" rather than "4/3". (`MixedFractions`)

Display 0.0 when floating point number is less than 10^-x (0=never chop)

  How to chop output. But only when other numbers nearby are large. See the documentation of the paramter `OutputChopExponent`.

Only chop numbers when another number is greater than 10^-x

  When to chop output. This is set by the paramter `OutputChopWhenExponent`. See the documentation of the paramter `OutputChopExponent`.

Remember output settings across sessions

  Should the output settings in the Number/Expression output options frame be remembered for next session. Does not apply to the Error/Info output options frame.

  If unchecked, either the default or any previously saved settings are used each time &appname; starts up. Note that settings are saved at the end of the session, so if you wish to change the defaults check this box, restart &app; and then uncheck it again.

Display errors in a dialog

  If set the errors will be displayed in a seprate dialog, if unset the errors will be printed on the console.

Display information messages in a dialog

  If set the information messages will be displayed in a seprate dialog, if unset the information messages will be printed on the console.

Maximum errors to display

  The maximum number of errors to return on one evaluation (`MaxErrors`). If you set this to 0 then all errors are always returned. Usually if some loop causes many errors, then it is unlikely that you will be able to make sense out of more than a few of these, so seeing a long list of errors is usually not helpful.

In addition to these preferences, there are some preferences that can only be changed by setting them in the workspace console. For others that may affect the output see .

`IntegerOutputBase`

  The base that will be used to output integers

`OutputStyle`

  A string, can be `"normal"`, `"latex"`, `"mathml"` or `"troff"` and it will effect how matrices (and perhaps other stuff) is printed, useful for pasting into documents. Normal style is the default human readable printing style of &app;. The other styles are for typsetting in LaTeX, MathML (XML), or in Troff.

### Precision

Floating point precision

  The floating point precision in bits (`FloatPrecision`). Note that changing this only affects newly computed quantities. Old values stored in variables are obviously still in the old precision and if you want to have them more precise you will have to recompute them. Exceptions to this are the system constants such as `pi` or `e`.

Remember precision setting across sessions

  Should the precision setting be remembered for the next session. If unchecked, either the default or any previously saved setting is used each time &appname; starts up. Note that settings are saved at the end of the session, so if you wish to change the default check this box, restart genius and then uncheck it again.

### Terminal

Terminal refers to the console in the work area.

Scrollback lines

  Lines of scrollback in the terminal.

Font

  The font to use on the terminal.

Black on white

  If to use black on white on the terminal.

Blinking cursor

  If the cursor in the terminal should blink when the terminal is in focus. This can sometimes be annoying and it generates idle traffic if you are using &appname; remotely.

### Memory

Maximum number of nodes to allocate

  Internally all data is put onto small nodes in memory. This gives a limit on the maximum number of nodes to allocate for computations. This avoids the problem of running out of memory if you do something by mistake which uses too much memory, such as a recursion without end. This could slow your computer and make it hard to even interrupt the program.

  Once the limit is reached, &app; asks if you wish to interrupt the computation or if you wish to continue. If you continue, no limit is applied and it will be possible to run your computer out of memory. The limit will be applied again next time you execute a program or an expression on the Console regardless of how you answered the question.

  Setting the limit to zero means there is no limit to the amount of memory that genius uses.

## About &app;

&app; was written by Jiří (George) Lebl (jirka@5z.com). The history of &app; goes back to late 1997. It was the first calculator program for GNOME, but it then grew beyond being just a desktop calculator. To find more information about &app;, please visit the Genius Web page.

To report a bug or make a suggestion regarding this application or this manual, follow the directions in this document.

This program is distributed under the terms of the GNU General Public license as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. A copy of this license can be found at this link, or in the file COPYING included with the source code of this program.