[genius] Wed Aug 24 17:58:18 2016 Jiri (George) Lebl <jirka 5z com>



commit eb69f9dcb0ea43efda3a0b8c21f8dc07a7affc6d
Author: Jiri (George) Lebl <jiri lebl gmail com>
Date:   Wed Aug 24 17:58:35 2016 -0500

    Wed Aug 24 17:58:18 2016  Jiri (George) Lebl <jirka 5z com>
    
        * examples/complex-analysis-mesh.gel,
          examples/complex-analysis-wandering-ball.gel: two visualizations of
          complex mappings
    
        * src/graphing.c: LinePlotDrawPoints and LinePlotDrawLine now accept
          a column vector of complex numbers to draw.
    
        * help/C/genius.xml: document the above.

 ChangeLog                                    |   11 +++
 examples/Makefile.am                         |    4 +-
 examples/complex-analysis-mesh.gel           |  113 ++++++++++++++++++++++++++
 examples/complex-analysis-wandering-ball.gel |   96 ++++++++++++++++++++++
 help/C/genius.xml                            |   34 +++++++-
 src/graphing.c                               |   34 +++++++-
 6 files changed, 285 insertions(+), 7 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index bd46d58..efb8843 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+Wed Aug 24 17:58:18 2016  Jiri (George) Lebl <jirka 5z com>
+
+       * examples/complex-analysis-mesh.gel,
+         examples/complex-analysis-wandering-ball.gel: two visualizations of
+         complex mappings
+       
+       * src/graphing.c: LinePlotDrawPoints and LinePlotDrawLine now accept
+         a column vector of complex numbers to draw.
+
+       * help/C/genius.xml: document the above.
+
 Sat Jul 09 00:14:53 2016  Jiri (George) Lebl <jirka 5z com>
 
        * help/C/genius.xml, src/funclib.c,
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 8d6adfa..d74c5c6 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -22,7 +22,9 @@ example_DATA = \
        rsa.gel \
        easy-matrix-examples.gel \
        peano.gel \
-       vibrating-drumhead-modes.gel
+       vibrating-drumhead-modes.gel \
+       complex-analysis-wandering-ball.gel \
+       complex-analysis-mesh.gel
 
 EXTRA_DIST = \
        $(example_DATA)
diff --git a/examples/complex-analysis-mesh.gel b/examples/complex-analysis-mesh.gel
new file mode 100644
index 0000000..e25ae65
--- /dev/null
+++ b/examples/complex-analysis-mesh.gel
@@ -0,0 +1,113 @@
+# Category: Complex Analysis
+# Name: Visualizing complex mappings, point mesh
+#
+# Shows where either a rectangular or a circular mesh of points is mapped
+# under a complex mapping.  It is also possible to just show the boundary
+# points.  Source points in blue, target in red.
+#
+
+#The function to plot
+function f(z) = z+(1+0.5i);
+#function f(z) = 2*z;
+#function f(z) = 1i*z;
+#function f(z) = (3+1i)*z;
+#function f(z) = (3+1i)*z+(1+0.5i);
+#function f(z) = 0.2*(z-5)*(z+5);
+#function f(z) = 0.2*z^2;
+#function f(z) = 0.1*(z-10)^2*z;
+#function f(z) = exp(z);
+#function f(z) = z^2+1i*z+0.1*sin(z^2);
+
+#approximately square grid
+LinePlotWindow = [-13,13,-10,10];
+
+#shape = "circle";
+shape = "rectangle";
+
+# if to plot only outline of the rectangle or the circle
+only_outline = false;
+
+
+#the rectangle we transform
+plot_range = [-3,3,-2,2];
+plot_stepx = 0.125;
+plot_stepy = 0.125;
+
+#the circle we transform
+plot_circle_rad = 3; #center is 0
+plot_steptheta = 0.05;
+plot_stepr = 0.1;
+# The theta step corresponds to the theta step on the outside of the circle.
+
+
+
+#in outline mode make steps 1/4 the size
+if only_outline then (
+       plot_stepx = plot_stepx/4;
+       plot_stepy = plot_stepy/4;
+       plot_steptheta = plot_steptheta/4;
+);
+
+
+
+LinePlotDrawLegends = false;
+LinePlotClear();
+PlotWindowPresent(); # Make sure the window is raised
+
+points_from = null;
+points_to = null;
+
+if shape == "rectangle" then (
+       if only_outline then (
+               for x = plot_range@(1) to plot_range@(2) by plot_stepx do (
+                       y = plot_range@(3);
+                       w = f(x+1i*y);
+                       points_from = [points_from;[x,y]];
+                       points_to = [points_to;[Re(w),Im(w)]];
+                       y = plot_range@(4);
+                       w = f(x+1i*y);
+                       points_from = [points_from;[x,y]];
+                       points_to = [points_to;[Re(w),Im(w)]]
+               );
+               for y = plot_range@(3)+plot_stepy to plot_range@(4)-plot_stepy by plot_stepy do (
+                       x = plot_range@(1);
+                       w = f(x+1i*y);
+                       points_from = [points_from;[x,y]];
+                       points_to = [points_to;[Re(w),Im(w)]];
+                       x = plot_range@(2);
+                       w = f(x+1i*y);
+                       points_from = [points_from;[x,y]];
+                       points_to = [points_to;[Re(w),Im(w)]]
+               )
+       ) else (
+               for x = plot_range@(1) to plot_range@(2) by plot_stepx do (
+                       for y = plot_range@(3) to plot_range@(4) by plot_stepy do (
+                               w = f(x+1i*y);
+                               points_from = [points_from;[x,y]];
+                               points_to = [points_to;[Re(w),Im(w)]]
+                       )
+               )
+       )
+) else if shape == "circle" then (
+       if only_outline then (
+               for theta = 0 to 2*pi by plot_steptheta do (
+                       z = plot_circle_rad*exp(1i*theta);
+                       w = f(z);
+                       points_from = [points_from;[Re(z),Im(z)]];
+                       points_to = [points_to;[Re(w),Im(w)]]
+               )
+       ) else (
+               for r = 0 to plot_circle_rad by plot_stepr do (
+                       t = r/plot_circle_rad;
+                       for theta = 0 to 2*pi by plot_steptheta*(1/(t+0.000001)) do (
+                               z = r*exp(1i*theta);
+                               w = f(z);
+                               points_from = [points_from;[Re(z),Im(z)]];
+                               points_to = [points_to;[Re(w),Im(w)]]
+                       )
+               )
+       )
+);
+
+LinePlotDrawPoints(points_from,"color","blue");
+LinePlotDrawPoints(points_to,"color","red");
diff --git a/examples/complex-analysis-wandering-ball.gel b/examples/complex-analysis-wandering-ball.gel
new file mode 100644
index 0000000..837d382
--- /dev/null
+++ b/examples/complex-analysis-wandering-ball.gel
@@ -0,0 +1,96 @@
+# Category: Complex Analysis
+# Name: Visualizing complex mappings, wandering ball
+#
+# Shows a bouncing wandering ball and its image under a complex map.
+# Source is in blue and the target is in red.
+#
+
+#The function to plot
+#function f(z) = z+(1+0.5i);
+#function f(z) = 2*z;
+#function f(z) = 1i*z;
+#function f(z) = (3+1i)*z;
+#function f(z) = (3+1i)*z+(1+0.5i);
+function f(z) = 0.2*(z-5)*(z+5);
+#function f(z) = 0.2*z^2;
+#function f(z) = 0.1*(z-10)^2*z;
+#function f(z) = exp(z);
+#function f(z) = z^2+1i*z+0.1*sin(z^2);
+
+LinePlotDrawLegends = false;
+PlotWindowPresent(); # Make sure the window is raised
+
+#approximately square grid
+LinePlotWindow = [-13,13,-10,10];
+
+#confine possibly to a smaller window.
+#You can also zoom out during the animation.
+#confine_window = [-8,8,-7,7];
+confine_window = LinePlotWindow;
+
+#the circle
+radius = 3;
+#step = 0.025;
+step = 0.05;
+
+
+# precision multiplier.  Increasing this number increases the
+# number of points
+mult=1;
+#mult = 3;
+#mult = 10;
+
+
+circlepts = ApplyOverMatrix((0:(80*mult))',`(k)=radius*exp(k*1i*2*pi/(80*mult)));
+line1pts = ApplyOverMatrix((0:(30*mult))',`(k)=radius*(2.0*k/(30*mult)-1));
+line2pts = ApplyOverMatrix((0:(30*mult))',`(k)=1i*radius*(2.0*k/(30*mult)-1));
+
+
+dir = exp(1i*rand()*2*pi);
+pt = 0;
+
+while true do (
+       PlotCanvasFreeze ();
+       LinePlotClear ();
+
+       points = pt + circlepts;
+       LinePlotDrawLine(points,"color","blue");
+       points = ApplyOverMatrix(points,f);
+       LinePlotDrawLine(points,"color","red");
+
+       points = pt + line1pts;
+       LinePlotDrawLine(points,"color","blue");
+       points = ApplyOverMatrix(points,f);
+       LinePlotDrawLine(points,"color","red");
+
+       points = pt + line2pts;
+       LinePlotDrawLine(points,"color","blue");
+       points = ApplyOverMatrix(points,f);
+       LinePlotDrawLine(points,"color","red");
+
+
+
+       PlotCanvasThaw ();
+
+
+       pt = pt+step*dir;
+
+       if (Re(pt) < confine_window@(1)+radius) then (
+               pt = (confine_window@(1)+radius) + 1i*Im(pt);
+               dir = -1i*conj(1i*dir)
+       );
+       if (Re(pt) > confine_window@(2)-radius) then (
+               pt = (confine_window@(2)-radius) + 1i*Im(pt);
+               dir = -1i*conj(1i*dir)
+       );
+       if (Im(pt) < confine_window@(3)+radius) then (
+               pt = Re(pt) + 1i*(confine_window@(3)+radius);
+               dir = conj(dir)
+       );
+       if (Im(pt) > confine_window@(4)-radius) then (
+               pt = Re(pt) + 1i*(confine_window@(4)-radius);
+               dir = conj(dir)
+       );
+
+       dir = dir*exp(1i*(rand()*0.2-0.1));
+);
diff --git a/help/C/genius.xml b/help/C/genius.xml
index 7469570..060768f 100644
--- a/help/C/genius.xml
+++ b/help/C/genius.xml
@@ -4,7 +4,7 @@
   <!ENTITY app "<application>Genius Mathematics Tool</application>">
   <!ENTITY appname "Genius">
   <!ENTITY appversion "1.0.21">
-  <!ENTITY date "July 2016">
+  <!ENTITY date "August 2016">
 
   <!ENTITY legal SYSTEM "legal.xml">
 
@@ -8791,6 +8791,9 @@ and has period <userinput>b-a</userinput>.</para>
            <varname>x1</varname>,<varname>y1</varname>,
            <varname>x2</varname>,<varname>y2</varname> can be replaced by an
            <varname>n</varname> by 2 matrix for a longer polyline.
+           Alternatively the vector <varname>v</varname> may be a column vector of complex numbers,
+           that is an <varname>n</varname> by 1 matrix and each complex number is then
+           considered a point in the plane.
           </para>
           <para>
            Extra parameters can be added to specify line color, thickness,
@@ -8840,6 +8843,16 @@ and has period <userinput>b-a</userinput>.</para>
 <prompt>genius></prompt> <userinput>for r=0.0 to 1.0 by 0.1 do 
LinePlotDrawLine([0,0;1,r],"color",[r,(1-r),0.5],"window",[0,1,0,1])</userinput>
 </screen>
           </para>
+         <para>
+                 Unlike many other functions that do not care if they take a
+                 column or a row vector, if specifying points as a vector of
+                 complex values, due to possible ambiguities, it must always
+                 be given as a column vector.
+         </para>
+         <para>
+                 Specifying <varname>v</varname> as a column vector of complex numbers is
+                 implemented from version 1.0.22 and onwards.
+         </para>
          </listitem>
         </varlistentry>
 
@@ -8853,9 +8866,12 @@ and has period <userinput>b-a</userinput>.</para>
                  The input can be an <varname>n</varname> by 2 matrix
                  for <varname>n</varname> different points.  This function has essentially the same
                  input as <link linkend="gel-function-LinePlotDrawLine">LinePlotDrawLine</link>.
+                 Alternatively the vector <varname>v</varname> may be a column vector of complex numbers,
+                 that is an <varname>n</varname> by 1 matrix and each complex number is then
+                 considered a point in the plane.
           </para>
           <para>
-           Extra parameters can be added to specify line color, thickness,
+           Extra parameters can be added to specify color, thickness,
            the plotting window, or legend.
            You can do this by adding an argument string <userinput>"color"</userinput>, 
            <userinput>"thickness"</userinput>,
@@ -8890,10 +8906,22 @@ and has period <userinput>b-a</userinput>.</para>
           <screen><prompt>genius></prompt> 
<userinput>LinePlotDrawPoints(0,0,"color","blue","thickness",3)</userinput>
 <prompt>genius></prompt> <userinput>LinePlotDrawPoints([0,0;1,-1;-1,-1])</userinput>
 <prompt>genius></prompt> 
<userinput>LinePlotDrawPoints(RungeKuttaFull(`(x,y)=y,0,3,100),"color","blue","legend","The 
Solution")</userinput>
+<prompt>genius></prompt> <userinput>LinePlotDrawPoints([1;1+1i;1i;0],"thickness",5)</userinput>
+<prompt>genius></prompt> 
<userinput>LinePlotDrawPoints(ApplyOverMatrix((0:6)',`(k)=exp(k*2*pi*1i/7)),"thickness",3,"legend","The 7th 
roots of unity")</userinput>
 </screen>
           </para>
          <para>
-                 Available from version 1.0.18 onwards.
+                 Unlike many other functions that do not care if they take a
+                 column or a row vector, if specifying points as a vector of
+                 complex values, due to possible ambiguities, it must always
+                 be given as a column vector.  Therefore, notice in the
+                 last example the transpose of the vector <userinput>0:6</userinput>
+                 to make it into a column vector.
+         </para>
+         <para>
+                 Available from version 1.0.18 onwards.  Specifying
+                 <varname>v</varname> as a column vector of complex numbers is
+                 implemented from version 1.0.22 and onwards.
          </para>
          </listitem>
         </varlistentry>
diff --git a/src/graphing.c b/src/graphing.c
index 066da5f..07d0517 100644
--- a/src/graphing.c
+++ b/src/graphing.c
@@ -8443,17 +8443,25 @@ get_line_numbers (GelETree *a, double **x, double **y, int *len,
 
        m = a->mat.matrix;
 
-       if G_UNLIKELY ( ! gel_is_matrix_value_only_real (m)) {
+       if G_UNLIKELY ( ! gel_is_matrix_value_only (m)) {
                gel_errorout (_("%s: Points should be given as a real, n by 2 matrix "
-                               "with columns for x and y, n>=%d"),
+                               "with columns for x and y, n>=%d, or as a complex "
+                               "valued n by 1 matrix"),
                              funcname, minn);
                return FALSE;
        }
 
        if (gel_matrixw_width (m) == 2 &&
            gel_matrixw_height (m) >= minn) {
+               if G_UNLIKELY ( ! gel_is_matrix_value_only_real (m)) {
+                       gel_errorout (_("%s: If points are given as an n by 2 matrix, then this matrix must 
be real"),
+                                     funcname);
+                       return FALSE;
+               }
+
                *len = gel_matrixw_height (m);
 
+
                *x = g_new (double, *len);
                *y = g_new (double, *len);
 
@@ -8466,6 +8474,24 @@ get_line_numbers (GelETree *a, double **x, double **y, int *len,
                        UPDATE_MINMAX
                }
        } else if (gel_matrixw_width (m) == 1 &&
+                  gel_matrixw_height (m) >= minn) {
+               *len = gel_matrixw_height (m);
+
+
+               *x = g_new (double, *len);
+               *y = g_new (double, *len);
+
+               for (i = 0; i < *len; i++) {
+                       double xx, yy;
+                       GelETree *t = gel_matrixw_index (m, 0, i);
+                       mpw_get_complex_double (t->val.value, &xx, &yy);
+                       (*x)[i] = xx;
+                       (*y)[i] = yy;
+                       UPDATE_MINMAX
+               }
+               /*
+                * This was undocumented and conflicts with using complex numbers
+       } else if (gel_matrixw_width (m) == 1 &&
                   gel_matrixw_height (m) % 2 == 0 &&
                   gel_matrixw_height (m) >= 2*minn) {
                *len = gel_matrixw_height (m) / 2;
@@ -8497,9 +8523,11 @@ get_line_numbers (GelETree *a, double **x, double **y, int *len,
                        (*y)[i] = yy = mpw_get_double (t->val.value);
                        UPDATE_MINMAX
                }
+               */
        } else {
                gel_errorout (_("%s: Points should be given as a real, n by 2 matrix "
-                               "with columns for x and y, n>=%d"),
+                               "with columns for x and y, n>=%d, or as a complex "
+                               "valued n by 1 matrix"),
                              funcname, minn);
                return FALSE;
        }


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