[genius] Mon Aug 18 17:10:59 2014 Jiri (George) Lebl <jirka 5z com>



commit 92e17891f2d7b324b62f69c5ca3da238f921d6c1
Author: Jiri (George) Lebl <jiri lebl gmail com>
Date:   Mon Aug 18 17:11:03 2014 -0500

    Mon Aug 18 17:10:59 2014  Jiri (George) Lebl <jirka 5z com>
    
        * help/C/genius.xml: improve docs, mark when things were added,
          document the new float:float:float behaviour, and document all
          the new stuff added below
    
        * src/funclib.c, src/eval.[ch]: Add SetElement and SetVElement
          functions to set specific elements in a global matrix/vector
    
        * src/geniustests.txt: test SetElement and SetVElement

 ChangeLog           |   11 +++
 NEWS                |    4 +-
 help/C/genius.xml   |  144 ++++++++++++++++++++++++++++++--
 help/genius.txt     |  232 +++++++++++++++++++++++++++++++++++++++++++++------
 src/eval.c          |  218 ++++++++++++++++++++++++------------------------
 src/eval.h          |    5 +-
 src/funclib.c       |  126 ++++++++++++++++++++++++++++
 src/geniustests.txt |   11 +++
 8 files changed, 606 insertions(+), 145 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index c6f5262..c804db5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+Mon Aug 18 17:10:59 2014  Jiri (George) Lebl <jirka 5z com>
+
+       * help/C/genius.xml: improve docs, mark when things were added,
+         document the new float:float:float behaviour, and document all
+         the new stuff added below
+
+       * src/funclib.c, src/eval.[ch]: Add SetElement and SetVElement
+         functions to set specific elements in a global matrix/vector
+
+       * src/geniustests.txt: test SetElement and SetVElement
+
 Sun Aug 17 14:39:15 2014  Jiri (George) Lebl <jirka 5z com>
 
        * src/graphing.c, src/gnome-genius.[ch]: When errors are given during
diff --git a/NEWS b/NEWS
index 128d5e9..e8cc387 100644
--- a/NEWS
+++ b/NEWS
@@ -2,9 +2,9 @@ Changes to 1.0.18
 
 * New general functions: KroneckerProduct (alias TensorProduct), NewtonsMethod,
   HalleysMethod, LambertW, LambertWm1, NonzeroColumns, NonzeroElements,
-  DisplayVariables, PrintTable
+  DisplayVariables, PrintTable, SetElement, SetVElement
 * New plotting functions: PlotCanvasFreeze/PlotCanvasThaw to improve flicker
-  if doing animations with genius, LinePlotDrawPoints function to draw just
+  if doing animations with genius, and LinePlotDrawPoints function to draw just
   points without the line
 * While plotting errors are no longer forced into a dialog, and presence
   of errors is indicated in the graph window below the graph
diff --git a/help/C/genius.xml b/help/C/genius.xml
index fd2206f..351b553 100644
--- a/help/C/genius.xml
+++ b/help/C/genius.xml
@@ -198,6 +198,12 @@
        the graphical user interface.
     </para>
 
+    <para>
+           Generally, when some feature of the language (function, operator, etc...)
+           is new is some version past 1.0.5, it is mentioned, but
+           below 1.0.5 you would have to look at the NEWS file.
+    </para>
+
   </chapter>
 
 <!-- =========== Getting Started ============================== -->
@@ -1729,6 +1735,27 @@ different from <literal>=</literal> because it never gets translated to a
 `[1, 3, 5, 7, 9]
 </programlisting>
            </para>
+          <para>
+            When the numbers involved are floating point numbers, for example
+            <userinput>1.0:0.4:3.0</userinput>, the output is what is expected
+            even though adding 0.4 to 1.0 five times is actually just slightly
+            more than 3.0 due to the way that floating point numbers are
+            stored in base 2 (there is no 0.4, the actual number stored is
+            just ever so slightly bigger).  The way this is handled is the
+            same as in the for, sum, and prod loops.  If the end is within
+            <userinput>2^-20</userinput> times the step size of the endpoint,
+            the endpoint is used and we assume there were roundoff errors.
+            This is not perfect, but it handles the majority of the cases.
+            This check is done only from version 1.0.18 onwards, so execution
+            of your code may differ on older versions.  If you want to avoid
+            dealing with this issue, use actual rational numbers, possibly
+            useing the <function>float</function> if you wish to get floating
+            point numbers in the end.  For example
+            <userinput>1:2/5:3</userinput> does the right thing and
+            <userinput>float(1:2/5:3)</userinput> even gives you floating
+            point numbers and is ever so slightly more precise than
+            <userinput>1.0:0.4:3.0</userinput>.
+           </para>
          </listitem>
         </varlistentry>
 
@@ -2101,6 +2128,11 @@ or:
          reference.
         </para>
        <para>
+               See also the
+               <link linkend="gel-function-SetElement"><function>SetElement</function></link> and
+               <link linkend="gel-function-SetVElement"><function>SetVElement</function></link> functions.
+       </para>
+       <para>
          So to recap in a more technical language:  Genius operates with
          different numbered contexts.  The top level is the context 0
          (zero).  Whenever a function is entered, the context is raised,
@@ -2518,7 +2550,7 @@ first compile it with <command>genius --compile loader.gel &gt; lib.cgel</comman
     <sect1 id="genius-gel-loading-programs">
       <title>Loading Programs</title>
       <para>
-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 
<filename>~/.geniusinit</filename> file. Or if you want to load up a file in a middle of a session (or from 
within another file), you can type <command>load &lt;list of filenames&gt;</command> 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:
+Sometimes you have a larger program you wrote into a file and want to read that file into &app;. In these 
situations, you have two options. You can keep the functions you use most inside the 
<filename>~/.geniusinit</filename> file. Or if you want to load up a file in a middle of a session (or from 
within another file), you can type <command>load &lt;list of filenames&gt;</command> 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:
 <programlisting>load program1.gel program2.gel
 load "Weird File Name With SPACES.gel"
 </programlisting>
@@ -2536,7 +2568,7 @@ ls *.gel
     <title>Matrices in GEL</title>
 
     <para>
-      Genius has support for vectors and matrices and a sizable library of
+      Genius has support for vectors and matrices and posesses a sizable library of
       matrix manipulation and linear algebra functions.
     </para>
 
@@ -2883,6 +2915,7 @@ pressed.  That is, returns 1 if the first button was pressed, 2 if the second
 button was pressed, and so on.  If the user closes the window (or simply hits
 enter in text mode), then <constant>null</constant> is returned.  The execution
 of the program is blocked until the user responds.</para>
+         <para>Version 1.0.10 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -2894,7 +2927,7 @@ of the program is blocked until the user responds.</para>
           <para>Asks a question and lets the user enter a string, which
 it then returns.  If the user cancels or closes the window, then
 <constant>null</constant> is returned.  The execution of the program
-is blocked until the user responds.  If <varname>default</varname> is given, then it is pre-typed in for the 
user to just press enter on.</para>
+is blocked until the user responds.  If <varname>default</varname> is given, then it is pre-typed in for the 
user to just press enter on (version 1.0.6 onwards).</para>
          </listitem>
         </varlistentry>
 
@@ -3093,6 +3126,7 @@ is called inside a block that was evaluated using modular arithmetic (using <lit
          <listitem>
           <synopsis>CurrentTime</synopsis>
           <para>Returns the current UNIX time with microsecond precision as a floating point number.  That 
is, returns the number of seconds since January 1st 1970.</para>
+         <para>Version 1.0.15 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -3120,6 +3154,7 @@ is called inside a block that was evaluated using modular arithmetic (using <lit
            then all variables are printed including a stacktrace similar to
            <guilabel>Show user variables</guilabel> in the graphical version.
          </para>
+         <para>Version 1.0.18 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -3187,6 +3222,7 @@ made into a string before being printed.</para>
            If <varname>v</varname> is a positive integer, then the table of
            integers from 1 up to and including v will be used.
          </para>
+         <para>Version 1.0.18 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -3207,6 +3243,7 @@ avoid them being accidentally overridden.</para>
 functions from being modified.  This is used on the internal GEL functions to
 avoid them being accidentally overridden.  Normally &app; considers
 unprotected variables as user defined.</para>
+         <para>Version 1.0.7 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -3215,12 +3252,54 @@ unprotected variables as user defined.</para>
          <listitem>
           <synopsis>set (id,val)</synopsis>
           <para>Set a global variable.  The <varname>id</varname>
-            can be either a string or a quoted identifier as follows.
+            can be either a string or a quoted identifier.
            For example:
            <programlisting>set(`x,1)
            </programlisting>
            will set the global variable <varname>x</varname> to the value 1.
          </para>
+         <para>The function returns the <varname>val</varname>, to be
+         usable in chaining.</para>
+         </listitem>
+        </varlistentry>
+
+        <varlistentry>
+         <term><anchor id="gel-function-SetElement"/>SetElement</term>
+         <listitem>
+          <synopsis>SetElement (id,row,col,val)</synopsis>
+         <para>Set an element of a global variable which is a matrix.
+                 The <varname>id</varname>
+            can be either a string or a quoted identifier.
+           For example:
+           <programlisting>SetElement(`x,2,3,1)
+           </programlisting>
+           will set the second row third column element of the global variable <varname>x</varname> to the 
value 1.  If no global variable of the name exists, or if it is set to something that's not a matrix, a new 
zero matrix of appropriate size will be created.
+         </para>
+         <para>The <varname>row</varname> and <varname>col</varname> can also be ranges, and the semantics 
are the same as for regular setting of the elements with an equals sign.
+         </para>
+         <para>The function returns the <varname>val</varname>, to be
+         usable in chaining.</para>
+         <para>Available from 1.0.18 onwards.</para>
+         </listitem>
+        </varlistentry>
+
+        <varlistentry>
+         <term><anchor id="gel-function-SetVElement"/>SetVElement</term>
+         <listitem>
+          <synopsis>SetElement (id,elt,val)</synopsis>
+         <para>Set an element of a global variable which is a vector.
+                 The <varname>id</varname>
+            can be either a string or a quoted identifier.
+           For example:
+           <programlisting>SetElement(`x,2,1)
+           </programlisting>
+           will set the second element of the global vector variable <varname>x</varname> to the value 1.  
If no global variable of the name exists, or if it is set to something that's not a vector (matrix), a new 
zero row vector of appropriate size will be created.
+         </para>
+         <para>The <varname>elt</varname> can also be a range, and the semantics are the same as for regular 
setting of the elements with an equals sign.
+         </para>
+         <para>The function returns the <varname>val</varname>, to be
+         usable in chaining.</para>
+         <para>Available from 1.0.18 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -3265,6 +3344,7 @@ unprotected variables as user defined.</para>
            only removes the global definition of symbols not local ones,
            so that it may be run from inside other functions safely.
          </para>
+         <para>Version 1.0.7 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -3282,6 +3362,7 @@ unprotected variables as user defined.</para>
           <synopsis>UserVariables ()</synopsis>
           <para>Return a vector of identifiers of
            user defined (unprotected) global variables.</para>
+         <para>Version 1.0.7 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -3292,6 +3373,8 @@ unprotected variables as user defined.</para>
           <para>Waits a specified number of seconds.  <varname>secs</varname>
 must be non-negative.  Zero is accepted and nothing happens in this case,
 except possibly user interface events are processed.</para>
+         <para>Since version 1.0.18, <varname>secs</varname> can be a noninteger number, so
+                 <userinput>wait(0.1)</userinput> will wait for one tenth of a second.</para>
          </listitem>
         </varlistentry>
 
@@ -3439,6 +3522,7 @@ except possibly user interface events are processed.</para>
           <para>Tells genius to draw the axis labels for <link 
linkend="genius-gel-function-list-plotting">line plotting
          functions</link> such as <link linkend="gel-function-LinePlot"><function>LinePlot</function></link>.
           </para>
+         <para>Version 1.0.16 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -3449,6 +3533,7 @@ except possibly user interface events are processed.</para>
           <para>Tells genius which variable names are used as default names  for <link 
linkend="genius-gel-function-list-plotting">line plotting
          functions</link> such as <link linkend="gel-function-LinePlot"><function>LinePlot</function></link> 
and friends.
           </para>
+         <para>Version 1.0.10 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -3578,6 +3663,7 @@ greater than or equal to
           <para>Sets the number of vertical and horizontal ticks in a
 slopefield plot.  (See <link 
linkend="gel-function-SlopefieldPlot"><function>SlopefieldPlot</function></link>).
           </para>
+         <para>Version 1.0.10 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -3612,6 +3698,7 @@ slopefield plot.  (See <link linkend="gel-function-SlopefieldPlot"><function>Slo
           <para>Tells genius to draw the legends for <link 
linkend="genius-gel-function-list-plotting">surface plotting
          functions</link> such as <link 
linkend="gel-function-SurfacePlot"><function>SurfacePlot</function></link>.
           </para>
+         <para>Version 1.0.16 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -3624,6 +3711,7 @@ slopefield plot.  (See <link linkend="gel-function-SlopefieldPlot"><function>Slo
           Note that the <varname>z</varname> does not refer to the dependent (vertical) axis, but to the 
indepent complex variable
           <userinput>z=x+iy</userinput>.
           </para>
+         <para>Version 1.0.10 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -3652,6 +3740,7 @@ slopefield plot.  (See <link linkend="gel-function-SlopefieldPlot"><function>Slo
           <para>Sets the number of vertical and horizontal ticks in a
 vectorfield plot.  (See <link 
linkend="gel-function-VectorfieldPlot"><function>VectorfieldPlot</function></link>).
           </para>
+         <para>Version 1.0.10 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -5529,6 +5618,7 @@ functions make this check.  Values can be any number including complex numbers.<
          <listitem>
           <synopsis>NonzeroColumns (M)</synopsis>
           <para>Returns a row vector of the indices of nonzero columns in the matrix 
<varname>M</varname>.</para>
+         <para>Version 1.0.18 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -5537,6 +5627,7 @@ functions make this check.  Values can be any number including complex numbers.<
          <listitem>
           <synopsis>NonzeroElements (v)</synopsis>
           <para>Returns a row vector of the indices of nonzero elements in the vector 
<varname>v</varname>.</para>
+         <para>Version 1.0.18 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -5604,7 +5695,8 @@ something(r)</userinput>.</para>
          <term><anchor id="gel-function-ShuffleVector"/>ShuffleVector</term>
          <listitem>
           <synopsis>ShuffleVector (v)</synopsis>
-         <para>Shuffle elements in a vector.  Return <constant>null</constant> if given 
<constant>null</constant></para>
+         <para>Shuffle elements in a vector.  Return <constant>null</constant> if given 
<constant>null</constant>.</para>
+         <para>Version 1.0.13 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -6146,6 +6238,7 @@ determinant.
            <ulink url="http://planetmath.org/encyclopedia/KroneckerProduct.html";>Planetmath</ulink> or
            <ulink url="http://mathworld.wolfram.com/KroneckerProduct.html";>Mathworld</ulink> for more 
information.
           </para>
+         <para>Version 1.0.18 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -6982,6 +7075,7 @@ extended to be periodic with period <userinput>2*L</userinput>.</para>
            and
            <link linkend='gel-function-PeriodicExtension'>PeriodicExtension</link>.
          </para>
+         <para>Version 1.0.7 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -7104,6 +7198,7 @@ computed by numerical integration using
            <ulink url="http://en.wikipedia.org/wiki/Fourier_series";>Wikipedia</ulink> or
            <ulink url="http://mathworld.wolfram.com/FourierSeries.html";>Mathworld</ulink> for more 
information.
           </para>
+         <para>Version 1.0.7 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -7123,6 +7218,7 @@ computed by numerical integration using
            <ulink url="http://en.wikipedia.org/wiki/Fourier_series";>Wikipedia</ulink> or
            <ulink url="http://mathworld.wolfram.com/FourierSeries.html";>Mathworld</ulink> for more 
information.
           </para>
+         <para>Version 1.0.7 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -7147,6 +7243,7 @@ the term <userinput>cos(x*(n-1)*pi/L)</userinput>.</para>
            <ulink url="http://en.wikipedia.org/wiki/Fourier_series";>Wikipedia</ulink> or
            <ulink url="http://mathworld.wolfram.com/FourierCosineSeries.html";>Mathworld</ulink> for more 
information.
           </para>
+         <para>Version 1.0.7 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -7167,6 +7264,7 @@ computed by numerical integration using
            <ulink url="http://en.wikipedia.org/wiki/Fourier_series";>Wikipedia</ulink> or
            <ulink url="http://mathworld.wolfram.com/FourierCosineSeries.html";>Mathworld</ulink> for more 
information.
           </para>
+         <para>Version 1.0.7 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -7188,6 +7286,7 @@ computed by numerical integration using
            <ulink url="http://en.wikipedia.org/wiki/Fourier_series";>Wikipedia</ulink> or
            <ulink url="http://mathworld.wolfram.com/FourierSineSeries.html";>Mathworld</ulink> for more 
information.
           </para>
+         <para>Version 1.0.7 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -7208,6 +7307,7 @@ computed by numerical integration using
            <ulink url="http://en.wikipedia.org/wiki/Fourier_series";>Wikipedia</ulink> or
            <ulink url="http://mathworld.wolfram.com/FourierSineSeries.html";>Mathworld</ulink> for more 
information.
           </para>
+         <para>Version 1.0.7 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -7258,6 +7358,7 @@ extended to be periodic with period <userinput>2*L</userinput>.</para>
            and
            <link linkend='gel-function-PeriodicExtension'>PeriodicExtension</link>.
          </para>
+         <para>Version 1.0.7 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -7290,6 +7391,7 @@ and has period <userinput>b-a</userinput>.</para>
            and
            <link linkend='gel-function-EvenPeriodicExtension'>EvenPeriodicExtension</link>.
          </para>
+         <para>Version 1.0.7 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -7341,6 +7443,7 @@ and has period <userinput>b-a</userinput>.</para>
            See
            <ulink url="http://en.wikipedia.org/wiki/Bessel_functions";>Wikipedia</ulink> for more information.
          </para>
+         <para>Version 1.0.16 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -7353,6 +7456,7 @@ and has period <userinput>b-a</userinput>.</para>
            See
            <ulink url="http://en.wikipedia.org/wiki/Bessel_functions";>Wikipedia</ulink> for more information.
          </para>
+         <para>Version 1.0.16 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -7365,6 +7469,7 @@ and has period <userinput>b-a</userinput>.</para>
            See
            <ulink url="http://en.wikipedia.org/wiki/Bessel_functions";>Wikipedia</ulink> for more information.
          </para>
+         <para>Version 1.0.16 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -7377,6 +7482,7 @@ and has period <userinput>b-a</userinput>.</para>
            See
            <ulink url="http://en.wikipedia.org/wiki/Bessel_functions";>Wikipedia</ulink> for more information.
          </para>
+         <para>Version 1.0.16 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -7389,6 +7495,7 @@ and has period <userinput>b-a</userinput>.</para>
            See
            <ulink url="http://en.wikipedia.org/wiki/Bessel_functions";>Wikipedia</ulink> for more information.
          </para>
+         <para>Version 1.0.16 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -7401,6 +7508,7 @@ and has period <userinput>b-a</userinput>.</para>
            See
            <ulink url="http://en.wikipedia.org/wiki/Bessel_functions";>Wikipedia</ulink> for more information.
          </para>
+         <para>Version 1.0.16 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -7485,6 +7593,7 @@ and has period <userinput>b-a</userinput>.</para>
            See
            <ulink url="http://en.wikipedia.org/wiki/Lambert_W_function";>Wikipedia</ulink> for more 
information.
          </para>
+         <para>Version 1.0.18 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -7655,6 +7764,7 @@ and has period <userinput>b-a</userinput>.</para>
            See
            <ulink url="http://en.wikipedia.org/wiki/Sinc";>Wikipedia</ulink> for more information.
          </para>
+         <para>Version 1.0.16 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -7769,6 +7879,7 @@ and has period <userinput>b-a</userinput>.</para>
            <ulink url="http://mathworld.wolfram.com/EulerForwardMethod.html";>Mathworld</ulink>, or
            <ulink url="http://en.wikipedia.org/wiki/Eulers_method";>Wikipedia</ulink> for more information.
          </para>
+         <para>Version 1.0.10 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -7841,6 +7952,7 @@ and has period <userinput>b-a</userinput>.</para>
            See
            <ulink url="http://en.wikipedia.org/wiki/Halley%27s_method";>Wikipedia</ulink> for more 
information.
          </para>
+         <para>Version 1.0.18 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -7866,6 +7978,7 @@ and has period <userinput>b-a</userinput>.</para>
            See
            <ulink url="http://en.wikipedia.org/wiki/Newtons_method";>Wikipedia</ulink> for more information.
          </para>
+         <para>Version 1.0.18 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -8008,6 +8121,7 @@ and has period <userinput>b-a</userinput>.</para>
            <ulink url="http://mathworld.wolfram.com/Runge-KuttaMethod.html";>Mathworld</ulink>, or
            <ulink url="http://en.wikipedia.org/wiki/Runge-Kutta_methods";>Wikipedia</ulink> for more 
information.
          </para>
+         <para>Version 1.0.10 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -8314,6 +8428,7 @@ and has period <userinput>b-a</userinput>.</para>
          <listitem>
           <synopsis>MacaulayBound (c,d)</synopsis>
           <para>For a Hilbert function that is c for degree d, given the Macaulay bound for the Hilbert 
function of degree d+1 (The c^&lt;d&gt; operator from Green's proof).</para>
+         <para>Version 1.0.15 onwards.</para>
          </listitem>
         </varlistentry>
        
@@ -8322,6 +8437,7 @@ and has period <userinput>b-a</userinput>.</para>
          <listitem>
           <synopsis>MacaulayLowerOperator (c,d)</synopsis>
           <para>The c_&lt;d&gt; operator from Green's proof of Macaulay's Theorem.</para>
+         <para>Version 1.0.15 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -8330,6 +8446,7 @@ and has period <userinput>b-a</userinput>.</para>
          <listitem>
           <synopsis>MacaulayRep (c,d)</synopsis>
           <para>Return the dth Macaulay representation of a positive integer c.</para>
+         <para>Version 1.0.15 onwards.</para>
          </listitem>
         </varlistentry>
       </variablelist>
@@ -8462,6 +8579,7 @@ and has period <userinput>b-a</userinput>.</para>
 <prompt>genius></prompt> <userinput>ExportPlot("/directory/file","eps")</userinput>
 </screen>
           </para>
+         <para>Version 1.0.16 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -8529,7 +8647,7 @@ and has period <userinput>b-a</userinput>.</para>
            <userinput>"window"</userinput>, 
            <userinput>"arrow"</userinput>, or <userinput>"legend"</userinput>, and after it specify
            the color, the thickness, the window
-           as 4-vector, type of arrow, or the legend.
+           as 4-vector, type of arrow, or the legend.  (Arrow and window are from version 1.0.6 onwards.)
          </para>
          <para>
            The color should be either a string indicating the common english word for the color
@@ -8538,8 +8656,9 @@ and has period <userinput>b-a</userinput>.</para>
            Alternatively the color can be specified in RGB format as
            <userinput>"#rgb"</userinput>, <userinput>"#rrggbb"</userinput>, or
            <userinput>"#rrrrggggbbbb"</userinput>, where the r, g, or b are hex digits of the red, green, 
and blue
-           components of the color.  Finally the color can also be specified as a real vector specifying the 
red green
-           and blue components where the components are between 0 and 1.
+           components of the color.  Finally, since version 1.0.18, the color
+           can also be specified as a real vector specifying the red green and
+           blue components where the components are between 0 and 1, e.g. 
<userinput>[1.0,0.5,0.1]</userinput>.
          </para>
          <para>
            The window should be given as usual as <userinput>[x1,x2,y1,y2]</userinput>, or
@@ -8620,6 +8739,9 @@ and has period <userinput>b-a</userinput>.</para>
 <prompt>genius></prompt> 
<userinput>LinePlotDrawPoints(RungeKuttaFull(`(x,y)=y,0,3,100),"color","blue","legend","The 
Solution")</userinput>
 </screen>
           </para>
+         <para>
+                 Available from version 1.0.18 onwards.
+         </para>
          </listitem>
         </varlistentry>
 
@@ -8692,6 +8814,7 @@ optionally the limits as <userinput>x1,x2,y1,y2</userinput>.
                  a new command line is shown for example the plot canvas is thawed automatically.  Also note 
that
                  calls to freeze and thaw may be safely nested.
           </para>
+         <para>Version 1.0.18 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -8705,6 +8828,7 @@ optionally the limits as <userinput>x1,x2,y1,y2</userinput>.
                  and rewdraw the canvas immediately.  The canvas is also always thawed after end of execution
                  of any program.
           </para>
+         <para>Version 1.0.18 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -8834,6 +8958,7 @@ optionally the limits as <userinput>x1,x2,y1,y2</userinput>.
 <prompt>genius></prompt> <userinput>SurfacePlotData(d)</userinput>
 </screen>
           </para>
+         <para>Version 1.0.16 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -8870,6 +8995,7 @@ optionally the limits as <userinput>x1,x2,y1,y2</userinput>.
 <prompt>genius></prompt> <userinput>SurfacePlotDataGrid(d,[-1,1,0,1],"half a saddle")</userinput>
 </screen>
           </para>
+         <para>Version 1.0.16 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -8882,6 +9008,7 @@ optionally the limits as <userinput>x1,x2,y1,y2</userinput>.
            <link 
linkend="gel-function-VectorfieldDrawSolution"><function>VectorfieldDrawSolution</function></link>
            function.
           </para>
+         <para>Version 1.0.6 onwards.</para>
          </listitem>
         </varlistentry>
 
@@ -8900,6 +9027,7 @@ optionally the limits as <userinput>x1,x2,y1,y2</userinput>.
            You can also use the graphical interface to draw solutions and specify
            initial conditions with the mouse.
           </para>
+         <para>Version 1.0.6 onwards.</para>
          </listitem>
         </varlistentry>
 
diff --git a/help/genius.txt b/help/genius.txt
index e57191d..0e9ee03 100644
--- a/help/genius.txt
+++ b/help/genius.txt
@@ -12,7 +12,7 @@ Kai Willadsen
 
     <kaiw itee uq edu au>
 
-   Copyright © 1997-2013 Jiř (George) Lebl
+   Copyright © 1997-2014 Jiř (George) Lebl
 
    Copyright © 2004 Kai Willadsen
 
@@ -75,8 +75,8 @@ Kai Willadsen
    Feedback
 
    To report a bug or make a suggestion regarding the Genius
-   Mathematics Tool application or this manual, follow the
-   directions in the GNOME Feedback Page.
+   Mathematics Tool application or this manual, please visit the
+   Genius Web page or email me at <jirka 5z com>.
      __________________________________________________________
 
    Table of Contents
@@ -237,6 +237,11 @@ Chapter 1. Introduction
    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.
+
+   Generally, when some feature of the language (function,
+   operator, etc...) is new is some version past 1.0.5, it is
+   mentioned, but below 1.0.5 you would have to look at the NEWS
+   file.
      __________________________________________________________
 
 Chapter 2. Getting Started
@@ -1278,6 +1283,26 @@ genius> 1:2:9
 =
 `[1, 3, 5, 7, 9]
 
+          When the numbers involved are floating point numbers,
+          for example 1.0:0.4:3.0, the output is what is expected
+          even though adding 0.4 to 1.0 five times is actually
+          just slightly more than 3.0 due to the way that floating
+          point numbers are stored in base 2 (there is no 0.4, the
+          actual number stored is just ever so slightly bigger).
+          The way this is handled is the same as in the for, sum,
+          and prod loops. If the end is within 2^-20 times the
+          step size of the endpoint, the endpoint is used and we
+          assume there were roundoff errors. This is not perfect,
+          but it handles the majority of the cases. This check is
+          done only from version 1.0.18 onwards, so execution of
+          your code may differ on older versions. If you want to
+          avoid dealing with this issue, use actual rational
+          numbers, possibly useing the float if you wish to get
+          floating point numbers in the end. For example 1:2/5:3
+          does the right thing and float(1:2/5:3) even gives you
+          floating point numbers and is ever so slightly more
+          precise than 1.0:0.4:3.0.
+
 (a)i
 
           Make a imaginary number (multiply a by the imaginary).
@@ -1574,6 +1599,8 @@ set("a",3)
    way to set a local variable in some function from a subroutine.
    If this is required, must use passing by reference.
 
+   See also the SetElement and SetVElement functions.
+
    So to recap in a more technical language: Genius operates with
    different numbered contexts. The top level is the context 0
    (zero). Whenever a function is entered, the context is raised,
@@ -1911,19 +1938,19 @@ function f(g,x) = (
 
 7.6. 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:
+   Sometimes you have a larger program you wrote into a file and
+   want to read that file into Genius Mathematics Tool. 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"
 
@@ -1937,8 +1964,9 @@ ls *.gel
 
 Chapter 8. Matrices in GEL
 
-   Genius has support for vectors and matrices and a sizable
-   library of matrix manipulation and linear algebra functions.
+   Genius has support for vectors and matrices and posesses a
+   sizable library of matrix manipulation and linear algebra
+   functions.
      __________________________________________________________
 
 8.1. Entering Matrices
@@ -2203,6 +2231,8 @@ AskButtons (query, button1, ...)
           returned. The execution of the program is blocked until
           the user responds.
 
+          Version 1.0.10 onwards.
+
    AskString
 
 AskString (query)
@@ -2214,7 +2244,7 @@ AskString (query, default)
           window, then null is returned. The execution of the
           program is blocked until the user responds. If default
           is given, then it is pre-typed in for the user to just
-          press enter on.
+          press enter on (version 1.0.6 onwards).
 
    Compose
 
@@ -2376,6 +2406,8 @@ CurrentTime
           as a floating point number. That is, returns the number
           of seconds since January 1st 1970.
 
+          Version 1.0.15 onwards.
+
    display
 
 display (str,expr)
@@ -2400,6 +2432,8 @@ DisplayVariables()
           then all variables are printed including a stacktrace
           similar to Show user variables in the graphical version.
 
+          Version 1.0.18 onwards.
+
    error
 
 error (str)
@@ -2457,6 +2491,8 @@ PrintTable (f,[0:10])
           If v is a positive integer, then the table of integers
           from 1 up to and including v will be used.
 
+          Version 1.0.18 onwards.
+
    protect
 
 protect (id)
@@ -2475,17 +2511,69 @@ ProtectAll ()
           overridden. Normally Genius Mathematics Tool considers
           unprotected variables as user defined.
 
+          Version 1.0.7 onwards.
+
    set
 
 set (id,val)
 
           Set a global variable. The id can be either a string or
-          a quoted identifier as follows. For example:
+          a quoted identifier. For example:
 
 set(`x,1)
 
           will set the global variable x to the value 1.
 
+          The function returns the val, to be usable in chaining.
+
+   SetElement
+
+SetElement (id,row,col,val)
+
+          Set an element of a global variable which is a matrix.
+          The id can be either a string or a quoted identifier.
+          For example:
+
+SetElement(`x,2,3,1)
+
+          will set the second row third column element of the
+          global variable x to the value 1. If no global variable
+          of the name exists, or if it is set to something that's
+          not a matrix, a new zero matrix of appropriate size will
+          be created.
+
+          The row and col can also be ranges, and the semantics
+          are the same as for regular setting of the elements with
+          an equals sign.
+
+          The function returns the val, to be usable in chaining.
+
+          Available from 1.0.18 onwards.
+
+   SetVElement
+
+SetElement (id,elt,val)
+
+          Set an element of a global variable which is a vector.
+          The id can be either a string or a quoted identifier.
+          For example:
+
+SetElement(`x,2,1)
+
+          will set the second element of the global vector
+          variable x to the value 1. If no global variable of the
+          name exists, or if it is set to something that's not a
+          vector (matrix), a new zero row vector of appropriate
+          size will be created.
+
+          The elt can also be a range, and the semantics are the
+          same as for regular setting of the elements with an
+          equals sign.
+
+          The function returns the val, to be usable in chaining.
+
+          Available from 1.0.18 onwards.
+
    string
 
 string (s)
@@ -2525,6 +2613,8 @@ UndefineAll ()
           so that it may be run from inside other functions
           safely.
 
+          Version 1.0.7 onwards.
+
    unprotect
 
 unprotect (id)
@@ -2538,6 +2628,8 @@ UserVariables ()
           Return a vector of identifiers of user defined
           (unprotected) global variables.
 
+          Version 1.0.7 onwards.
+
    wait
 
 wait (secs)
@@ -2547,6 +2639,9 @@ wait (secs)
           this case, except possibly user interface events are
           processed.
 
+          Since version 1.0.18, secs can be a noninteger number,
+          so wait(0.1) will wait for one tenth of a second.
+
    version
 
 version
@@ -2662,6 +2757,8 @@ LinePlotDrawAxisLabels = true
           Tells genius to draw the axis labels for line plotting
           functions such as LinePlot.
 
+          Version 1.0.16 onwards.
+
    LinePlotVariableNames
 
 LinePlotVariableNames = ["x","y","z","t"]
@@ -2670,6 +2767,8 @@ LinePlotVariableNames = ["x","y","z","t"]
           names for line plotting functions such as LinePlot and
           friends.
 
+          Version 1.0.10 onwards.
+
    LinePlotWindow
 
 LinePlotWindow = [x1,x2,y1,y2]
@@ -2763,6 +2862,8 @@ SlopefieldTicks = [vertical,horizontal]
           Sets the number of vertical and horizontal ticks in a
           slopefield plot. (See SlopefieldPlot).
 
+          Version 1.0.10 onwards.
+
    SumProductNumberOfTries
 
 SumProductNumberOfTries = number
@@ -2790,6 +2891,8 @@ SurfacePlotDrawLegends = true
           Tells genius to draw the legends for surface plotting
           functions such as SurfacePlot.
 
+          Version 1.0.16 onwards.
+
    SurfacePlotVariableNames
 
 SurfacePlotVariableNames = ["x","y","z"]
@@ -2800,6 +2903,8 @@ SurfacePlotVariableNames = ["x","y","z"]
           (vertical) axis, but to the indepent complex variable
           z=x+iy.
 
+          Version 1.0.10 onwards.
+
    SurfacePlotWindow
 
 SurfacePlotWindow = [x1,x2,y1,y2,z1,z2]
@@ -2820,6 +2925,8 @@ VectorfieldTicks = [vertical,horizontal]
 
           Sets the number of vertical and horizontal ticks in a
           vectorfield plot. (See VectorfieldPlot).
+
+          Version 1.0.10 onwards.
      __________________________________________________________
 
 11.4. Constants
@@ -4199,6 +4306,8 @@ NonzeroColumns (M)
           Returns a row vector of the indices of nonzero columns
           in the matrix M.
 
+          Version 1.0.18 onwards.
+
    NonzeroElements
 
 NonzeroElements (v)
@@ -4206,6 +4315,8 @@ NonzeroElements (v)
           Returns a row vector of the indices of nonzero elements
           in the vector v.
 
+          Version 1.0.18 onwards.
+
    OuterProduct
 
 OuterProduct (u,v)
@@ -4258,7 +4369,9 @@ SetMatrixSize (M,rows,columns)
 
 ShuffleVector (v)
 
-          Shuffle elements in a vector. Return null if given null
+          Shuffle elements in a vector. Return null if given null.
+
+          Version 1.0.13 onwards.
 
    SortVector
 
@@ -4673,6 +4786,8 @@ KroneckerProduct (M, N)
           See Wikipedia, Planetmath or Mathworld for more
           information.
 
+          Version 1.0.18 onwards.
+
    LUDecomposition
 
 LUDecomposition (A, L, U)
@@ -5315,6 +5430,8 @@ EvenPeriodicExtension (f,L)
 
           See also OddPeriodicExtension and PeriodicExtension.
 
+          Version 1.0.7 onwards.
+
    FourierSeriesFunction
 
 FourierSeriesFunction (a,b,L)
@@ -5412,6 +5529,8 @@ NumericalFourierSeriesCoefficients (f,L,N)
 
           See Wikipedia or Mathworld for more information.
 
+          Version 1.0.7 onwards.
+
    NumericalFourierSeriesFunction
 
 NumericalFourierSeriesFunction (f,L,N)
@@ -5426,6 +5545,8 @@ NumericalFourierSeriesFunction (f,L,N)
 
           See Wikipedia or Mathworld for more information.
 
+          Version 1.0.7 onwards.
+
    NumericalFourierCosineSeriesCoefficients
 
 NumericalFourierCosineSeriesCoefficients (f,L,N)
@@ -5442,6 +5563,8 @@ NumericalFourierCosineSeriesCoefficients (f,L,N)
 
           See Wikipedia or Mathworld for more information.
 
+          Version 1.0.7 onwards.
+
    NumericalFourierCosineSeriesFunction
 
 NumericalFourierCosineSeriesFunction (f,L,N)
@@ -5456,6 +5579,8 @@ NumericalFourierCosineSeriesFunction (f,L,N)
 
           See Wikipedia or Mathworld for more information.
 
+          Version 1.0.7 onwards.
+
    NumericalFourierSineSeriesCoefficients
 
 NumericalFourierSineSeriesCoefficients (f,L,N)
@@ -5470,6 +5595,8 @@ NumericalFourierSineSeriesCoefficients (f,L,N)
 
           See Wikipedia or Mathworld for more information.
 
+          Version 1.0.7 onwards.
+
    NumericalFourierSineSeriesFunction
 
 NumericalFourierSineSeriesFunction (f,L,N)
@@ -5484,6 +5611,8 @@ NumericalFourierSineSeriesFunction (f,L,N)
 
           See Wikipedia or Mathworld for more information.
 
+          Version 1.0.7 onwards.
+
    NumericalIntegral
 
 NumericalIntegral (f,a,b)
@@ -5522,6 +5651,8 @@ OddPeriodicExtension (f,L)
 
           See also EvenPeriodicExtension and PeriodicExtension.
 
+          Version 1.0.7 onwards.
+
    OneSidedFivePointFormula
 
 OneSidedFivePointFormula (f,x0,h)
@@ -5543,6 +5674,8 @@ PeriodicExtension (f,a,b)
 
           See also OddPeriodicExtension and EvenPeriodicExtension.
 
+          Version 1.0.7 onwards.
+
    RightLimit
 
 RightLimit (f,x0)
@@ -5582,6 +5715,8 @@ BesselJ0 (x)
 
           See Wikipedia for more information.
 
+          Version 1.0.16 onwards.
+
    BesselJ1
 
 BesselJ1 (x)
@@ -5591,6 +5726,8 @@ BesselJ1 (x)
 
           See Wikipedia for more information.
 
+          Version 1.0.16 onwards.
+
    BesselJn
 
 BesselJn (n,x)
@@ -5600,6 +5737,8 @@ BesselJn (n,x)
 
           See Wikipedia for more information.
 
+          Version 1.0.16 onwards.
+
    BesselY0
 
 BesselY0 (x)
@@ -5609,6 +5748,8 @@ BesselY0 (x)
 
           See Wikipedia for more information.
 
+          Version 1.0.16 onwards.
+
    BesselY1
 
 BesselY1 (x)
@@ -5618,6 +5759,8 @@ BesselY1 (x)
 
           See Wikipedia for more information.
 
+          Version 1.0.16 onwards.
+
    BesselYn
 
 BesselYn (n,x)
@@ -5627,6 +5770,8 @@ BesselYn (n,x)
 
           See Wikipedia for more information.
 
+          Version 1.0.16 onwards.
+
    DirichletKernel
 
 DirichletKernel (n,t)
@@ -5687,6 +5832,8 @@ LambertW (x)
 
           See Wikipedia for more information.
 
+          Version 1.0.18 onwards.
+
    LambertWm1
 
 LambertWm1 (x)
@@ -5809,6 +5956,8 @@ sinc (x)
           sinc(pi*x).
 
           See Wikipedia for more information.
+
+          Version 1.0.16 onwards.
      __________________________________________________________
 
 11.13. Equation Solving
@@ -5890,6 +6039,8 @@ d","Second");
 
           See Mathworld, or Wikipedia for more information.
 
+          Version 1.0.10 onwards.
+
    FindRootBisection
 
 FindRootBisection (f,a,b,TOL,N)
@@ -5960,6 +6111,8 @@ genius> HalleysMethod(`(x)=x^2-10,`(x)=2*x,`(x)=2,3,10^-10,100)
 
           See Wikipedia for more information.
 
+          Version 1.0.18 onwards.
+
    NewtonsMethod
 
 NewtonsMethod (f,df,guess,epsilon,maxn)
@@ -5978,6 +6131,8 @@ genius> NewtonsMethod(`(x)=x^2-10,`(x)=2*x,3,10^-10,100)
 
           See Wikipedia for more information.
 
+          Version 1.0.18 onwards.
+
    PolynomialRoots
 
 PolynomialRoots (p)
@@ -6073,6 +6228,8 @@ genius> LinePlotDrawPoints(secondline,"color","red","thickness",3,"legen
 d","Second");
 
           See Mathworld, or Wikipedia for more information.
+
+          Version 1.0.10 onwards.
      __________________________________________________________
 
 11.14. Statistics
@@ -6312,6 +6469,8 @@ MacaulayBound (c,d)
           Macaulay bound for the Hilbert function of degree d+1
           (The c^<d> operator from Green's proof).
 
+          Version 1.0.15 onwards.
+
    MacaulayLowerOperator
 
 MacaulayLowerOperator (c,d)
@@ -6319,12 +6478,16 @@ MacaulayLowerOperator (c,d)
           The c_<d> operator from Green's proof of Macaulay's
           Theorem.
 
+          Version 1.0.15 onwards.
+
    MacaulayRep
 
 MacaulayRep (c,d)
 
           Return the dth Macaulay representation of a positive
           integer c.
+
+          Version 1.0.15 onwards.
      __________________________________________________________
 
 11.18. Miscellaneous
@@ -6429,6 +6592,8 @@ ExportPlot (file)
 genius> ExportPlot("file.png")
 genius> ExportPlot("/directory/file","eps")
 
+          Version 1.0.16 onwards.
+
    LinePlot
 
 LinePlot (func1,func2,func3,...)
@@ -6478,7 +6643,8 @@ LinePlotDrawLine (v,...)
           can do this by adding an argument string "color",
           "thickness", "window", "arrow", or "legend", and after
           it specify the color, the thickness, the window as
-          4-vector, type of arrow, or the legend.
+          4-vector, type of arrow, or the legend. (Arrow and
+          window are from version 1.0.6 onwards.)
 
           The color should be either a string indicating the
           common english word for the color that GTK will
@@ -6486,10 +6652,10 @@ LinePlotDrawLine (v,...)
           Alternatively the color can be specified in RGB format
           as "#rgb", "#rrggbb", or "#rrrrggggbbbb", where the r,
           g, or b are hex digits of the red, green, and blue
-          components of the color. Finally the color can also be
-          specified as a real vector specifying the red green and
-          blue components where the components are between 0 and
-          1.
+          components of the color. Finally, since version 1.0.18,
+          the color can also be specified as a real vector
+          specifying the red green and blue components where the
+          components are between 0 and 1, e.g. [1.0,0.5,0.1].
 
           The window should be given as usual as [x1,x2,y1,y2], or
           alternatively can be given as a string "fit" in which
@@ -6556,6 +6722,8 @@ genius> LinePlotDrawPoints([0,0;1,-1;-1,-1])
 genius> LinePlotDrawPoints(RungeKuttaFull(`(x,y)=y,0,3,100),"color","blu
 e","legend","The Solution")
 
+          Available from version 1.0.18 onwards.
+
    LinePlotParametric
 
 LinePlotParametric (xfunc,yfunc,...)
@@ -6617,6 +6785,8 @@ PlotCanvasFreeze ()
           automatically. Also note that calls to freeze and thaw
           may be safely nested.
 
+          Version 1.0.18 onwards.
+
    PlotCanvasThaw
 
 PlotCanvasThaw ()
@@ -6625,6 +6795,8 @@ PlotCanvasThaw ()
           rewdraw the canvas immediately. The canvas is also
           always thawed after end of execution of any program.
 
+          Version 1.0.18 onwards.
+
    SlopefieldClearSolutions
 
 SlopefieldClearSolutions ()
@@ -6732,6 +6904,8 @@ genius> d:=null; for r=0 to 1 by 0.1 do for theta=0 to 2*pi by pi/5 do d
 =[d;[r*cos(theta),r*sin(theta),-r^2*theta]];
 genius> SurfacePlotData(d)
 
+          Version 1.0.16 onwards.
+
    SurfacePlotDataGrid
 
 SurfacePlotDataGrid (data,[x1,x2,y1,y2])
@@ -6764,6 +6938,8 @@ genius> d:=null; for i=1 to 20 do for j=1 to 10 d@(i,j) = (0.1*i-1)^2-(0
 .1*j)^2;
 genius> SurfacePlotDataGrid(d,[-1,1,0,1],"half a saddle")
 
+          Version 1.0.16 onwards.
+
    VectorfieldClearSolutions
 
 VectorfieldClearSolutions ()
@@ -6771,6 +6947,8 @@ VectorfieldClearSolutions ()
           Clears the solutions drawn by the
           VectorfieldDrawSolution function.
 
+          Version 1.0.6 onwards.
+
    VectorfieldDrawSolution
 
 VectorfieldDrawSolution (x, y, dt, tlen)
@@ -6784,6 +6962,8 @@ VectorfieldDrawSolution (x, y, dt, tlen)
           graphical interface to draw solutions and specify
           initial conditions with the mouse.
 
+          Version 1.0.6 onwards.
+
    VectorfieldPlot
 
 VectorfieldPlot (funcx, funcy)
diff --git a/src/eval.c b/src/eval.c
index f2e5aa9..c13c899 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -5495,7 +5495,7 @@ iter_get_index_regions (GelETree *i1, GelETree *i2,
 }
 
 static GelMatrixW *
-iter_get_matrix_p(GelETree *m, gboolean *new_matrix)
+iter_get_matrix_p (GelETree *m)
 {
        GelMatrixW *mat = NULL;
        
@@ -5525,7 +5525,6 @@ iter_get_matrix_p(GelETree *m, gboolean *new_matrix)
 
                                f = d_makevfunc(m->id.id,t);
                                d_addfunc(f);
-                               if(new_matrix) *new_matrix = TRUE;
                        }
                } else if G_UNLIKELY (f->type != GEL_USER_FUNC &&
                                      f->type != GEL_VARIABLE_FUNC) {
@@ -5542,7 +5541,6 @@ iter_get_matrix_p(GelETree *m, gboolean *new_matrix)
                        gel_matrixw_set_size(t->mat.matrix,1,1);
 
                        d_set_value(f,t);
-                       if(new_matrix) *new_matrix = TRUE;
                }
                mat = f->data.user->mat.matrix;
        } else if(m->type == GEL_OPERATOR_NODE ||
@@ -5587,7 +5585,6 @@ iter_get_matrix_p(GelETree *m, gboolean *new_matrix)
                        gel_matrixw_set_size(t->mat.matrix,1,1);
 
                        d_set_value(f->data.ref,t);
-                       if(new_matrix) *new_matrix = TRUE;
                }
                mat = f->data.ref->data.user->mat.matrix;
        } else {
@@ -5616,6 +5613,97 @@ set_parameter (GelToken *token, GelETree *val)
        }
 }
 
+gboolean
+_gel_iter_set_velement(GelMatrixW *mat, GelETree *r, GelETree *index)
+{
+       if (index->type == GEL_VALUE_NODE) {
+               int i;
+
+               i = iter_get_matrix_index_num (index, INT_MAX);
+               if G_UNLIKELY (i < 0)
+                       return FALSE;
+
+               if (r->type == GEL_VALUE_NODE &&
+                   mpw_exact_zero_p (r->val.value))
+                       gel_matrixw_set_velement (mat, i, NULL);
+               else
+                       gel_matrixw_set_velement (mat, i, gel_copynode (r));
+       } else if (index->type == GEL_MATRIX_NODE) {
+               int *reg;
+               int len;
+
+               if G_UNLIKELY( ! iter_get_index_region (index, INT_MAX,
+                                                       &reg, &len))
+                       return FALSE;
+
+               if (r->type == GEL_MATRIX_NODE)
+                       gel_matrixw_set_vregion (mat, r->mat.matrix, reg, len);
+               else
+                       gel_matrixw_set_vregion_etree (mat, r, reg, len);
+               g_free (reg);
+       } else {
+               gel_errorout (_("Matrix index not an integer or a vector"));
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+gboolean
+_gel_iter_set_element(GelMatrixW *mat, GelETree *r, GelETree *index1, GelETree *index2)
+{
+       if (index1->type == GEL_VALUE_NODE &&
+           index2->type == GEL_VALUE_NODE) {
+               int x, y;
+
+               x = iter_get_matrix_index_num (index2, INT_MAX);
+               if G_UNLIKELY (x < 0)
+                       return FALSE;
+               y = iter_get_matrix_index_num (index1, INT_MAX);
+               if G_UNLIKELY (y < 0)
+                       return FALSE;
+
+               if (r->type == GEL_VALUE_NODE &&
+                   mpw_exact_zero_p (r->val.value))
+                       gel_matrixw_set_element (mat, x, y, NULL);
+               else
+                       gel_matrixw_set_element (mat, x, y, gel_copynode (r));
+       } else if ((index1->type == GEL_VALUE_NODE ||
+                   index1->type == GEL_MATRIX_NODE) &&
+                  (index2->type == GEL_VALUE_NODE ||
+                   index2->type == GEL_MATRIX_NODE)) {
+               int *regx, *regy;
+               int lx, ly;
+
+               if ( ! iter_get_index_regions (index1, index2,
+                                              INT_MAX, INT_MAX,
+                                              &regy, &regx,
+                                              &ly, &lx))
+                       return FALSE;
+
+               if G_UNLIKELY (r->type == GEL_MATRIX_NODE &&
+                              (gel_matrixw_width (r->mat.matrix) != lx ||
+                               gel_matrixw_height (r->mat.matrix) != ly)) {
+                       g_free (regx);
+                       g_free (regy);
+                       gel_errorout (_("Wrong matrix dimensions when setting"));
+                       return FALSE;
+               }
+
+               if (r->type == GEL_MATRIX_NODE)
+                       gel_matrixw_set_region (mat, r->mat.matrix, regx, regy, lx, ly);
+               else
+                       gel_matrixw_set_region_etree (mat, r, regx, regy, lx, ly);
+               g_free (regx);
+               g_free (regy);
+       } else {
+               gel_errorout (_("Matrix index not an integer or a vector"));
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
 static void
 iter_equalsop(GelETree *n)
 {
@@ -5706,109 +5794,23 @@ iter_equalsop(GelETree *n)
                GelETree *index1, *index2;
                GEL_GET_XRR (l, index1, index2);
 
-               if (index1->type == GEL_VALUE_NODE &&
-                   index2->type == GEL_VALUE_NODE) {
-                       int x, y;
-
-                       x = iter_get_matrix_index_num (index2, INT_MAX);
-                       if G_UNLIKELY (x < 0)
-                               return;
-                       y = iter_get_matrix_index_num (index1, INT_MAX);
-                       if G_UNLIKELY (y < 0)
-                               return;
-
-                       mat = iter_get_matrix_p (l->op.args, NULL);
-                       if G_UNLIKELY (mat == NULL)
-                               return;
-
-                       if (r->type == GEL_VALUE_NODE &&
-                           mpw_exact_zero_p (r->val.value))
-                               gel_matrixw_set_element (mat, x, y, NULL);
-                       else
-                               gel_matrixw_set_element (mat, x, y, gel_copynode (r));
-               } else if ((index1->type == GEL_VALUE_NODE ||
-                           index1->type == GEL_MATRIX_NODE) &&
-                          (index2->type == GEL_VALUE_NODE ||
-                           index2->type == GEL_MATRIX_NODE)) {
-                       int *regx, *regy;
-                       int lx, ly;
-
-                       if ( ! iter_get_index_regions (index1, index2,
-                                                      INT_MAX, INT_MAX,
-                                                      &regy, &regx,
-                                                      &ly, &lx))
-                               return;
-
-                       if G_UNLIKELY (r->type == GEL_MATRIX_NODE &&
-                                      (gel_matrixw_width (r->mat.matrix) != lx ||
-                                       gel_matrixw_height (r->mat.matrix) != ly)) {
-                               g_free (regx);
-                               g_free (regy);
-                               gel_errorout (_("Wrong matrix dimensions when setting"));
-                               return;
-                       }
-
-                       mat = iter_get_matrix_p (l->op.args, NULL);
-                       if G_UNLIKELY (mat == NULL) {
-                               g_free (regx);
-                               g_free (regy);
-                               return;
-                       }
+               mat = iter_get_matrix_p (l->op.args);
+               if G_UNLIKELY (mat == NULL)
+                       return;
 
-                       if (r->type == GEL_MATRIX_NODE)
-                               gel_matrixw_set_region (mat, r->mat.matrix, regx, regy, lx, ly);
-                       else
-                               gel_matrixw_set_region_etree (mat, r, regx, regy, lx, ly);
-                       g_free (regx);
-                       g_free (regy);
-               } else {
-                       gel_errorout (_("Matrix index not an integer or a vector"));
+               if ( ! _gel_iter_set_element (mat, r, index1, index2))
                        return;
-               }
        } else if(l->op.oper == GEL_E_GET_VELEMENT) {
                GelMatrixW *mat;
                GelETree *index;
                GEL_GET_XR (l, index);
 
-               if (index->type == GEL_VALUE_NODE) {
-                       int i;
-
-                       i = iter_get_matrix_index_num (index, INT_MAX);
-                       if G_UNLIKELY (i < 0)
-                               return;
-
-                       mat = iter_get_matrix_p (l->op.args, NULL);
-                       if G_UNLIKELY (mat == NULL)
-                               return;
-
-                       if (r->type == GEL_VALUE_NODE &&
-                           mpw_exact_zero_p (r->val.value))
-                               gel_matrixw_set_velement (mat, i, NULL);
-                       else
-                               gel_matrixw_set_velement (mat, i, gel_copynode (r));
-               } else if (index->type == GEL_MATRIX_NODE) {
-                       int *reg;
-                       int len;
-
-                       if G_UNLIKELY( ! iter_get_index_region (index, INT_MAX,
-                                                               &reg, &len))
-                               return;
-
-                       mat = iter_get_matrix_p (l->op.args, NULL);
-                       if G_UNLIKELY (mat == NULL) {
-                               g_free (reg);
-                               return;
-                       }
+               mat = iter_get_matrix_p (l->op.args);
+               if G_UNLIKELY (mat == NULL)
+                       return;
 
-                       if (r->type == GEL_MATRIX_NODE)
-                               gel_matrixw_set_vregion (mat, r->mat.matrix, reg, len);
-                       else
-                               gel_matrixw_set_vregion_etree (mat, r, reg, len);
-                       g_free (reg);
-               } else {
-                       gel_errorout (_("Matrix index not an integer or a vector"));
+               if G_UNLIKELY ( ! _gel_iter_set_velement (mat, r, index))
                        return;
-               }
        } else /*l->data.oper == GEL_E_GET_COL_REGION GEL_E_GET_ROW_REGION*/ {
                GelMatrixW *mat;
                GelETree *index;
@@ -5840,7 +5842,7 @@ iter_equalsop(GelETree *n)
                                }
                        }
 
-                       mat = iter_get_matrix_p (l->op.args, NULL);
+                       mat = iter_get_matrix_p (l->op.args);
                        if G_UNLIKELY (mat == NULL) {
                                g_free (regx);
                                g_free (regy);
@@ -6008,7 +6010,7 @@ iter_incrementop (GelETree *n)
                        if G_UNLIKELY (y < 0)
                                return;
 
-                       mat = iter_get_matrix_p (l->op.args, NULL);
+                       mat = iter_get_matrix_p (l->op.args);
                        if G_UNLIKELY (mat == NULL)
                                return;
 
@@ -6026,7 +6028,7 @@ iter_incrementop (GelETree *n)
                                                       &ly, &lx))
                                return;
 
-                       mat = iter_get_matrix_p (l->op.args, NULL);
+                       mat = iter_get_matrix_p (l->op.args);
                        if G_UNLIKELY (mat == NULL) {
                                g_free (regx);
                                g_free (regy);
@@ -6052,7 +6054,7 @@ iter_incrementop (GelETree *n)
                        if G_UNLIKELY (i < 0)
                                return;
 
-                       mat = iter_get_matrix_p (l->op.args, NULL);
+                       mat = iter_get_matrix_p (l->op.args);
                        if G_UNLIKELY (mat == NULL)
                                return;
 
@@ -6065,7 +6067,7 @@ iter_incrementop (GelETree *n)
                                                      &reg, &len))
                                return;
 
-                       mat = iter_get_matrix_p (l->op.args, NULL);
+                       mat = iter_get_matrix_p (l->op.args);
                        if G_UNLIKELY (mat == NULL) {
                                g_free (reg);
                                return;
@@ -6096,7 +6098,7 @@ iter_incrementop (GelETree *n)
                                        return;
                        }
 
-                       mat = iter_get_matrix_p (l->op.args, NULL);
+                       mat = iter_get_matrix_p (l->op.args);
                        if G_UNLIKELY (mat == NULL) {
                                g_free (regx);
                                g_free (regy);
@@ -6173,7 +6175,7 @@ do_swapwithop (GelETree *l, GelETree *r)
                                if G_UNLIKELY (y < 0)
                                        return;
 
-                               mat = iter_get_matrix_p (r->op.args, NULL);
+                               mat = iter_get_matrix_p (r->op.args);
                                if G_UNLIKELY (mat == NULL)
                                        return;
 
@@ -6204,7 +6206,7 @@ do_swapwithop (GelETree *l, GelETree *r)
                                if G_UNLIKELY (i < 0)
                                        return;
 
-                               mat = iter_get_matrix_p (r->op.args, NULL);
+                               mat = iter_get_matrix_p (r->op.args);
                                if G_UNLIKELY (mat == NULL)
                                        return;
 
@@ -6234,11 +6236,11 @@ do_swapwithop (GelETree *l, GelETree *r)
                return;
        }
 
-       matl = iter_get_matrix_p (l->op.args, NULL);
+       matl = iter_get_matrix_p (l->op.args);
        if G_UNLIKELY (matl == NULL)
                return;
 
-       matr = iter_get_matrix_p (r->op.args, NULL);
+       matr = iter_get_matrix_p (r->op.args);
        if G_UNLIKELY (matr == NULL)
                return;
 
diff --git a/src/eval.h b/src/eval.h
index 69f6ec3..79dc611 100644
--- a/src/eval.h
+++ b/src/eval.h
@@ -1,5 +1,5 @@
 /* GENIUS Calculator
- * Copyright (C) 1997-2013 Jiri (George) Lebl
+ * Copyright (C) 1997-2014 Jiri (George) Lebl
  *
  * Author: Jiri (George) Lebl
  *
@@ -149,6 +149,9 @@ gboolean gel_mod_integer_rational (mpw_t num, mpw_t mod);
 
 mpw_ptr gel_find_pre_function_modulo (GelCtx *ctx);
 
+/* useful in funclib, but really internal */
+gboolean _gel_iter_set_velement(GelMatrixW *mat, GelETree *r, GelETree *index);
+gboolean _gel_iter_set_element(GelMatrixW *mat, GelETree *r, GelETree *index1, GelETree *index2);
 
 /*compare nodes, return TRUE if equal
   makes them the same type as a side effect*/
diff --git a/src/funclib.c b/src/funclib.c
index a7d3e58..7069719 100644
--- a/src/funclib.c
+++ b/src/funclib.c
@@ -565,6 +565,130 @@ set_op (GelCtx *ctx, GelETree * * a, gboolean *exception)
        return gel_stealnode (a[1]);
 }
 
+static GelETree *
+SetElement_op (GelCtx *ctx, GelETree * * a, gboolean *exception)
+{
+       GelToken *id;
+       GelEFunc *func;
+       GelMatrixW *mat;
+
+       if G_UNLIKELY ( ! check_argument_string_or_identifier (a, 0, "SetElement"))
+               return NULL;
+       if (a[0]->type == GEL_IDENTIFIER_NODE) {
+               id = a[0]->id.id;
+       } else /* GEL_STRING_NODE */ {
+               id = d_intern (a[0]->str.str);
+       }
+
+       if G_UNLIKELY (id->protected_) {
+               gel_errorout (_("%s: trying to set a protected id!"),
+                             "set");
+               return NULL;
+       }
+       if G_UNLIKELY (id->parameter) {
+               /* FIXME: fix this, this should just work too */
+               gel_errorout (_("%s: trying to set a parameter, use the equals sign"),
+                             "set");
+               return NULL;
+       }
+
+       func = d_lookup_only_global (id);
+
+       if (func == NULL ||
+           func->type != GEL_VARIABLE_FUNC ||
+           func->data.user->type != GEL_MATRIX_NODE) {
+               GelETree *t;
+
+               GEL_GET_NEW_NODE (t);
+               t->type = GEL_MATRIX_NODE;
+               mat = t->mat.matrix = gel_matrixw_new ();
+               t->mat.quoted = FALSE;
+               gel_matrixw_set_size (mat, 1, 1);
+
+               if G_UNLIKELY ( ! _gel_iter_set_element (mat, a[3], a[1], a[2])) {
+                       gel_freetree (t);
+                       return NULL;
+               }
+
+               func = d_makevfunc (id, t);
+               /* make function global */
+               func->context = 0;
+               d_addfunc_global (func);
+       } else {
+               mat = func->data.user->mat.matrix;
+               if G_UNLIKELY ( ! _gel_iter_set_element (mat, a[3], a[1], a[2])) {
+                       return NULL;
+               }
+       }
+
+       /*
+        * Evil optimization to avoid copying the node from the argument
+        */
+       return gel_stealnode (a[3]);
+}
+
+static GelETree *
+SetVElement_op (GelCtx *ctx, GelETree * * a, gboolean *exception)
+{
+       GelToken *id;
+       GelEFunc *func;
+       GelMatrixW *mat;
+
+       if G_UNLIKELY ( ! check_argument_string_or_identifier (a, 0, "SetVElement"))
+               return NULL;
+       if (a[0]->type == GEL_IDENTIFIER_NODE) {
+               id = a[0]->id.id;
+       } else /* GEL_STRING_NODE */ {
+               id = d_intern (a[0]->str.str);
+       }
+
+       if G_UNLIKELY (id->protected_) {
+               gel_errorout (_("%s: trying to set a protected id!"),
+                             "set");
+               return NULL;
+       }
+       if G_UNLIKELY (id->parameter) {
+               /* FIXME: fix this, this should just work too */
+               gel_errorout (_("%s: trying to set a parameter, use the equals sign"),
+                             "set");
+               return NULL;
+       }
+
+       func = d_lookup_only_global (id);
+
+       if (func == NULL ||
+           func->type != GEL_VARIABLE_FUNC ||
+           func->data.user->type != GEL_MATRIX_NODE) {
+               GelETree *t;
+
+               GEL_GET_NEW_NODE (t);
+               t->type = GEL_MATRIX_NODE;
+               mat = t->mat.matrix = gel_matrixw_new ();
+               t->mat.quoted = FALSE;
+               gel_matrixw_set_size (mat, 1, 1);
+
+               if G_UNLIKELY ( ! _gel_iter_set_velement (mat, a[2], a[1])) {
+                       gel_freetree (t);
+                       return NULL;
+               }
+
+               func = d_makevfunc (id, t);
+               /* make function global */
+               func->context = 0;
+               d_addfunc_global (func);
+       } else {
+               mat = func->data.user->mat.matrix;
+               if G_UNLIKELY ( ! _gel_iter_set_velement (mat, a[2], a[1])) {
+                       return NULL;
+               }
+       }
+
+       /*
+        * Evil optimization to avoid copying the node from the argument
+        */
+       return gel_stealnode (a[2]);
+}
+
 static void
 display_all_vars (void)
 {
@@ -6826,6 +6950,8 @@ gel_funclib_addall(void)
        FUNC (printn, 1, "str", "basic", N_("Prints an expression without a trailing newline"));
        FUNC (display, 2, "str,expr", "basic", N_("Display a string and an expression"));
        FUNC (set, 2, "id,val", "basic", N_("Set a global variable"));
+       FUNC (SetElement, 4, "id,row,col,val", "basic", N_("Set an element in a global variable which is a 
matrix"));
+       FUNC (SetVElement, 3, "id,elt,val", "basic", N_("Set an element in a global variable which is a 
vector"));
        VFUNC (DisplayVariables, 1, "var", "basic", N_("Display values of variables, or all if called without 
arguments"));
 
        FUNC (SetHelp, 3, "id,category,desc", "basic", N_("Set the category and help description line for a 
function"));
diff --git a/src/geniustests.txt b/src/geniustests.txt
index 4a28dec..1d06972 100644
--- a/src/geniustests.txt
+++ b/src/geniustests.txt
@@ -1159,6 +1159,17 @@ m=randint(2,5,5);NonzeroColumns(MakeVector(m.').')==NonzeroElements(m)   true
 1.0:0.5:2.0                                                    `[1.0,1.5,2.0]
 1.0:0.5:1.9999                                                 `[1.0,1.5]
 1.0:0.5:1.9999999                                              `[1.0,1.5,1.9999999]
+function f() = (set(`r,[1,2;3,4])); f(); r                     [1,2;3,4]
+function f() = (set("r",[1,2;3,4]);r=1); f(); r                        [1,2;3,4]
+function f() = (r=2;set("r",[1,2;3,4]);r=1); f(); r            [1,2;3,4]
+r=[1,2;3,4];function f() = (r@(1,2)=99;set(`r,r)); f(); r      [1,99;3,4]
+function f() = (SetElement(`r,2,3,99)); f(); r                 [0,0,0;0,0,99]
+r=[1,2;3,4];function f() = (SetElement(`r,1,2,99)); f(); r     [1,99;3,4]
+function f() = (SetVElement(`r,3,99)); f(); r                  [0,0,99]
+r=[1,2,3];function f() = (SetVElement(`r,3,99)); f(); r                [1,2,99]
+r=[1,2,3];function f() = (SetVElement(`r,4,99)); f(); r                [1,2,3,99]
+r=[1;2;3];function f() = (SetVElement("r",5,99)); f(); r       [1;2;3;0;99]
+SetElement("r",-1,2,99)                                                SetElement("r",-1,2,99)
 load "nullspacetest.gel"                                       true
 load "longtest.gel"                                            true
 load "testprec.gel"                                            true


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]