This is maxima.info, produced by makeinfo version 7.3 from maxima.texi.

This is a Texinfo Maxima Manual

   Copyright 1994,2001 William F. Schelter

INFO-DIR-SECTION Math
START-INFO-DIR-ENTRY
* Maxima: (maxima).     A computer algebra system.
END-INFO-DIR-ENTRY


File: maxima.info,  Node: Functions and Variables for pictures,  Next: Functions and Variables for worldmap,  Prev: Functions and Variables for draw,  Up: Package draw

55.3 Functions and Variables for pictures
=========================================

 -- Function: get_pixel (<pic>,<x>,<y>)
     Returns pixel from picture.  Coordinates <x> and <y> range from 0
     to ‘width-1’ and ‘height-1’, respectively.

 -- Function: make_level_picture
          make_level_picture (<data>)
          make_level_picture (<data>,<width>,<height>)

     Returns a levels <picture> object.  ‘make_level_picture (<data>)’
     builds the <picture> object from matrix <data>.
     ‘make_level_picture (<data>,<width>,<height>)’ builds the object
     from a list of numbers; in this case, both the <width> and the
     <height> must be given.

     The returned <picture> object contains the following four parts:

       1. symbol ‘level’
       2. image width
       3. image height
       4. an integer array with pixel data ranging from 0 to 255.
          Argument <data> must contain only numbers ranged from 0 to
          255; negative numbers are substituted by 0, and those which
          are greater than 255 are set to 255.

     Example:

     Level picture from matrix.
          (%i1) make_level_picture(matrix([3,2,5],[7,-9,3000]));
          (%o1)         picture(level, 3, 2, {Array:  #(3 2 5 7 0 255)})

     Level picture from numeric list.
          (%i1) make_level_picture([-2,0,54,%pi],2,2);
          (%o1)            picture(level, 2, 2, {Array:  #(0 0 54 3)})

 -- Function: make_rgb_picture (<redlevel>,<greenlevel>,<bluelevel>)
     Returns an rgb-coloured <picture> object.  All three arguments must
     be levels picture; with red, green and blue levels.

     The returned <picture> object contains the following four parts:

       1. symbol ‘rgb’
       2. image width
       3. image height
       4. an integer array of length <3*width*height> with pixel data
          ranging from 0 to 255.  Each pixel is represented by three
          consecutive numbers (red, green, blue).

     Example:

          (%i1) red: make_level_picture(matrix([3,2],[7,260]));
          (%o1)           picture(level, 2, 2, {Array:  #(3 2 7 255)})
          (%i2) green: make_level_picture(matrix([54,23],[73,-9]));
          (%o2)           picture(level, 2, 2, {Array:  #(54 23 73 0)})
          (%i3) blue: make_level_picture(matrix([123,82],[45,32.5698]));
          (%o3)          picture(level, 2, 2, {Array:  #(123 82 45 33)})
          (%i4) make_rgb_picture(red,green,blue);
          (%o4) picture(rgb, 2, 2,
                        {Array:  #(3 54 123 2 23 82 7 73 45 255 0 33)})

 -- Function: negative_picture (<pic>)
     Returns the negative of a (<level> or <rgb>) picture.

 -- Function: picture_equalp (<x>,<y>)
     Returns ‘true’ in case of equal pictures, and ‘false’ otherwise.

 -- Function: picturep (<x>)
     Returns ‘true’ if the argument is a well formed image, and ‘false’
     otherwise.

 -- Function: read_xpm (<xpm_file>)
     Reads a file in xpm and returns a picture object.

 -- Function: rgb2level (<pic>)
     Transforms an <rgb> picture into a <level> one by averaging the
     red, green and blue channels.

 -- Function: take_channel (<im>,<color>)
     If argument <color> is ‘red’, ‘green’ or ‘blue’, function
     ‘take_channel’ returns the corresponding color channel of picture
     <im>.  Example:

          (%i1) red: make_level_picture(matrix([3,2],[7,260]));
          (%o1)           picture(level, 2, 2, {Array:  #(3 2 7 255)})
          (%i2) green: make_level_picture(matrix([54,23],[73,-9]));
          (%o2)           picture(level, 2, 2, {Array:  #(54 23 73 0)})
          (%i3) blue: make_level_picture(matrix([123,82],[45,32.5698]));
          (%o3)          picture(level, 2, 2, {Array:  #(123 82 45 33)})
          (%i4) make_rgb_picture(red,green,blue);
          (%o4) picture(rgb, 2, 2,
                        {Array:  #(3 54 123 2 23 82 7 73 45 255 0 33)})
          (%i5) take_channel(%,'green);  /* simple quote!!! */
          (%o5)           picture(level, 2, 2, {Array:  #(54 23 73 0)})


File: maxima.info,  Node: Functions and Variables for worldmap,  Prev: Functions and Variables for pictures,  Up: Package draw

55.4 Functions and Variables for worldmap
=========================================

55.4.1 Variables and Functions
------------------------------

 -- Global variable: boundaries_array
     Default value: ‘false’

     ‘boundaries_array’ is where the graphic object ‘geomap’ looks for
     boundaries coordinates.

     Each component of ‘boundaries_array’ is an array of floating point
     quantities, the coordinates of a polygonal segment or map boundary.

     See also *note geomap::.

 -- Function: numbered_boundaries (<nlist>)
     Draws a list of polygonal segments (boundaries), labeled by its
     numbers (‘boundaries_array’ coordinates).  This is of great help
     when building new geographical entities.

     Example:

     Map of Europe labeling borders with their component number in
     ‘boundaries_array’.
          (%i1) load("worldmap")$
          (%i2) european_borders:
                     region_boundaries(-31.81,74.92,49.84,32.06)$
          (%i3) numbered_boundaries(european_borders)$

 -- Function: make_poly_continent
          make_poly_continent (<continent_name>)
          make_poly_continent (<country_list>)

     Makes the necessary polygons to draw a colored continent or a list
     of countries.

     Example:

          (%i1) load("worldmap")$
          (%i2) /* A continent */
                make_poly_continent(Africa)$
          (%i3) apply(draw2d, %)$

     (Figure worldmap_make_poly_continent)
          (%i4) /* A list of countries */
                make_poly_continent([Germany,Denmark,Poland])$
          (%i5) apply(draw2d, %)$

     (Figure worldmap_make_poly_continent2)

 -- Function: make_poly_country (<country_name>)
     Makes the necessary polygons to draw a colored country.  If islands
     exist, one country can be defined with more than just one polygon.

     Example:

          (%i1) load("worldmap")$
          (%i2) make_poly_country(India)$
          (%i3) apply(draw2d, %)$

     (Figure worldmap_make_poly_country)

 -- Function: make_polygon (<nlist>)
     Returns a ‘polygon’ object from boundary indices.  Argument <nlist>
     is a list of components of ‘boundaries_array’.

     Example:

     Bhutan is defined by boundary numbers 171, 173 and 1143, so that
     ‘make_polygon([171,173,1143])’ appends arrays of coordinates
     ‘boundaries_array[171]’, ‘boundaries_array[173]’ and
     ‘boundaries_array[1143]’ and returns a ‘polygon’ object suited to
     be plotted by ‘draw’.  To avoid an error message, arrays must be
     compatible in the sense that any two consecutive arrays have two
     coordinates in the extremes in common.  In this example, the two
     first components of ‘boundaries_array[171]’ are equal to the last
     two coordinates of ‘boundaries_array[173]’, and the two first of
     ‘boundaries_array[173]’ are equal to the two first of
     ‘boundaries_array[1143]’; in conclusion, boundary numbers 171, 173
     and 1143 (in this order) are compatible and the colored polygon can
     be drawn.
          (%i1) load("worldmap")$
          (%i2) Bhutan;
          (%o2)                        [[171, 173, 1143]]
          (%i3) boundaries_array[171];
          (%o3) {Array:
                 #(88.750549 27.14727 88.806351 27.25305 88.901367 27.282221
                   88.917877 27.321039)}
          (%i4) boundaries_array[173];
          (%o4) {Array:
                 #(91.659554 27.76511 91.6008 27.66666 91.598022 27.62499
                   91.631348 27.536381 91.765533 27.45694 91.775253 27.4161
                   92.007751 27.471939 92.11441 27.28583 92.015259 27.168051
                   92.015533 27.08083 92.083313 27.02277 92.112183 26.920271
                   92.069977 26.86194 91.997192 26.85194 91.915253 26.893881
                   91.916924 26.85416 91.8358 26.863331 91.712479 26.799999
                   91.542191 26.80444 91.492188 26.87472 91.418854 26.873329
                   91.371353 26.800831 91.307457 26.778049 90.682457 26.77417
                   90.392197 26.903601 90.344131 26.894159 90.143044 26.75333
                   89.98996 26.73583 89.841919 26.70138 89.618301 26.72694
                   89.636093 26.771111 89.360786 26.859989 89.22081 26.81472
                   89.110237 26.829161 88.921631 26.98777 88.873016 26.95499
                   88.867737 27.080549 88.843307 27.108601 88.750549
                   27.14727)}
          (%i5) boundaries_array[1143];
          (%o5) {Array:
                 #(91.659554 27.76511 91.666924 27.88888 91.65831 27.94805
                   91.338028 28.05249 91.314972 28.096661 91.108856 27.971109
                   91.015808 27.97777 90.896927 28.05055 90.382462 28.07972
                   90.396088 28.23555 90.366074 28.257771 89.996353 28.32333
                   89.83165 28.24888 89.58609 28.139999 89.35997 27.87166
                   89.225517 27.795 89.125793 27.56749 88.971077 27.47361
                   88.917877 27.321039)}
          (%i6) Bhutan_polygon: make_polygon([171,173,1143])$
          (%i7) draw2d(Bhutan_polygon)$

     (Figure worldmap_make_polygon)

 -- Function: region_boundaries (<x1>,<y1>,<x2>,<y2>)
     Detects polygonal segments of global variable ‘boundaries_array’
     fully contained in the rectangle with vertices (<x1>,<y1>) -upper
     left- and (<x2>,<y2>) -bottom right-.

     Example:

     Returns segment numbers for plotting southern Italy.
          (%i1) load("worldmap")$
          (%i2) region_boundaries(10.4,41.5,20.7,35.4);
          (%o2)                [1846, 1863, 1864, 1881, 1888, 1894]
          (%i3) draw2d(geomap(%))$

     (Figure worldmap_region_boundaries)

 -- Function: region_boundaries_plus (<x1>,<y1>,<x2>,<y2>)
     Detects polygonal segments of global variable ‘boundaries_array’
     containing at least one vertex in the rectangle defined by vertices
     (<x1>,<y1>) -upper left- and (<x2>,<y2>) -bottom right-.

     Example:

          (%i1) load("worldmap")$
          (%i2) region_boundaries_plus(10.4,41.5,20.7,35.4);
          (%o2) [1060, 1062, 1076, 1835, 1839, 1844, 1846, 1858,
                 1861, 1863, 1864, 1871, 1881, 1888, 1894, 1897]
          (%i3) draw2d(geomap(%))$

     (Figure worldmap_region_boundaries_plus)

55.4.2 Graphic objects
----------------------

 -- Graphic object: geomap
          geomap (<numlist>)
          geomap (<numlist>,<3Dprojection>)

     Draws cartographic maps in 2D and 3D.

     2D

     This function works together with global variable
     ‘boundaries_array’.

     Argument <numlist> is a list containing numbers or lists of
     numbers.  All these numbers must be integers greater or equal than
     zero, representing the components of global array
     ‘boundaries_array’.

     Each component of ‘boundaries_array’ is an array of floating point
     quantities, the coordinates of a polygonal segment or map boundary.

     ‘geomap (<numlist>)’ flattens its arguments and draws the
     associated boundaries in ‘boundaries_array’.

     This object is affected by the following graphic options:
     ‘line_width’, ‘line_type’ and ‘color’.

     Examples:

     A simple map defined by hand:
          (%i1) load("worldmap")$
          (%i2) /* Vertices of boundary #0: {(1,1),(2,5),(4,3)} */
             ( bnd0: make_array(flonum,6),
               bnd0[0]:1.0, bnd0[1]:1.0, bnd0[2]:2.0,
               bnd0[3]:5.0, bnd0[4]:4.0, bnd0[5]:3.0 )$
          (%i3) /* Vertices of boundary #1: {(4,3),(5,4),(6,4),(5,1)} */
             ( bnd1: make_array(flonum,8),
               bnd1[0]:4.0, bnd1[1]:3.0, bnd1[2]:5.0, bnd1[3]:4.0,
               bnd1[4]:6.0, bnd1[5]:4.0, bnd1[6]:5.0, bnd1[7]:1.0)$
          (%i4) /* Vertices of boundary #2: {(5,1), (3,0), (1,1)} */
             ( bnd2: make_array(flonum,6),
               bnd2[0]:5.0, bnd2[1]:1.0, bnd2[2]:3.0,
               bnd2[3]:0.0, bnd2[4]:1.0, bnd2[5]:1.0 )$
          (%i5) /* Vertices of boundary #3: {(1,1), (4,3)} */
             ( bnd3: make_array(flonum,4),
               bnd3[0]:1.0, bnd3[1]:1.0, bnd3[2]:4.0, bnd3[3]:3.0)$
          (%i6) /* Vertices of boundary #4: {(4,3), (5,1)} */
             ( bnd4: make_array(flonum,4),
               bnd4[0]:4.0, bnd4[1]:3.0, bnd4[2]:5.0, bnd4[3]:1.0)$
          (%i7) /* Pack all together in boundaries_array */
             ( boundaries_array: make_array(any,5),
               boundaries_array[0]: bnd0, boundaries_array[1]: bnd1,
               boundaries_array[2]: bnd2, boundaries_array[3]: bnd3,
               boundaries_array[4]: bnd4 )$
          (%i8) draw2d(geomap([0,1,2,3,4]))$

     (Figure worldmap_geomap)

     The auxiliary package ‘worldmap’ sets the global variable
     ‘boundaries_array’ to real world boundaries in (longitude,
     latitude) coordinates.  These data are in the public domain and
     come from
     <https://web.archive.org/web/20100310124019/http://www-cger.nies.go.jp/grid-e/gridtxt/grid19.html>.
     Package ‘worldmap’ defines also boundaries for countries,
     continents and coastlines as lists with the necessary components of
     ‘boundaries_array’ (see file ‘share/draw/worldmap.mac’ for more
     information).  Package ‘worldmap’ automatically loads package
     ‘worldmap’.
          (%i1) load("worldmap")$
          (%i2) c1: gr2d(geomap([Canada,United_States,
                                 Mexico,Cuba]))$
          (%i3) c2: gr2d(geomap(Africa))$
          (%i4) c3: gr2d(geomap([Oceania,China,Japan]))$
          (%i5) c4: gr2d(geomap([France,Portugal,Spain,
                                 Morocco,Western_Sahara]))$
          (%i6) draw(columns  = 2,
                     c1,c2,c3,c4)$

     (Figure worldmap_geomap2)

     Package ‘worldmap’ is also useful for plotting countries as
     polygons.  In this case, graphic object ‘geomap’ is no longer
     necessary and the ‘polygon’ object is used instead.  Since lists
     are now used and not arrays, maps rendering will be slower.  See
     also ‘make_poly_country’ and ‘make_poly_continent’ to understand
     the following code.
          (%i1) load("worldmap")$
          (%i2) mymap: append(
             [color      = white],  /* borders are white */
             [fill_color = red],             make_poly_country(Bolivia),
             [fill_color = cyan],            make_poly_country(Paraguay),
             [fill_color = green],           make_poly_country(Colombia),
             [fill_color = blue],            make_poly_country(Chile),
             [fill_color = "#23ab0f"],       make_poly_country(Brazil),
             [fill_color = goldenrod],       make_poly_country(Argentina),
             [fill_color = "midnight-blue"], make_poly_country(Uruguay))$
          (%i3) apply(draw2d, mymap)$

     (Figure worldmap_geomap3)

     3D

     ‘geomap (<numlist>)’ projects map boundaries on the sphere of
     radius 1 centered at (0,0,0).  It is possible to change the sphere
     or the projection type by using ‘geomap
     (<numlist>,<3Dprojection>)’.

     Available 3D projections:

        • ‘[spherical_projection,<x>,<y>,<z>,<r>]’: projects map
          boundaries on the sphere of radius <r> centered at
          (<x>,<y>,<z>).
               (%i1) load("worldmap")$
               (%i2) draw3d(geomap(Australia), /* default projection */
                            geomap(Australia,
                                   [spherical_projection,2,2,2,3]))$

          (Figure worldmap_geomap4)

        • ‘[cylindrical_projection,<x>,<y>,<z>,<r>,<rc>]’: re-projects
          spherical map boundaries on the cylinder of radius <rc> and
          axis passing through the poles of the globe of radius <r>
          centered at (<x>,<y>,<z>).
               (%i1) load("worldmap")$
               (%i2) draw3d(geomap([America_coastlines,Eurasia_coastlines],
                                   [cylindrical_projection,2,2,2,3,4]))$

          (Figure worldmap_geomap5)

        • ‘[conic_projection,<x>,<y>,<z>,<r>,<alpha>]’: re-projects
          spherical map boundaries on the cones of angle <alpha>, with
          axis passing through the poles of the globe of radius <r>
          centered at (<x>,<y>,<z>).  Both the northern and southern
          cones are tangent to sphere.
               (%i1) load("worldmap")$
               (%i2) draw3d(geomap(World_coastlines,
                                   [conic_projection,0,0,0,1,90]))$

     (Figure worldmap_geomap6)

     See also
     <https://riotorto.users.sourceforge.net/Maxima/gnuplot/geomap/> for
     more elaborated examples.


File: maxima.info,  Node: Package drawdf,  Next: Package dynamics,  Prev: Package draw,  Up: Top

56 Package drawdf
*****************

* Menu:

* Introduction to drawdf::
* Functions and Variables for drawdf::


File: maxima.info,  Node: Introduction to drawdf,  Next: Functions and Variables for drawdf,  Prev: Package drawdf,  Up: Package drawdf

56.1 Introduction to drawdf
===========================

The function ‘drawdf’ draws the direction field of a first-order
Ordinary Differential Equation (ODE) or a system of two autonomous
first-order ODE's.

   Since this is an additional package, in order to use it you must
first load it with ‘load("drawdf")’.  Drawdf is built upon the ‘draw’
package, which requires Gnuplot 4.2.

   To plot the direction field of a single ODE, the ODE must be written
in the form:
            dy
            -- = F(x,y)
            dx

   and the function <F> should be given as the argument for ‘drawdf’.
If the independent and dependent variables are not <x>, and <y>, as in
the equation above, then those two variables should be named explicitly
in a list given as an argument to the drawdf command (see the examples).

   To plot the direction field of a set of two autonomous ODE's, they
must be written in the form
            dx             dy
            -- = G(x,y)    -- = F(x,y)
            dt             dt

   and the argument for ‘drawdf’ should be a list with the two functions
<G> and <F>, in that order; namely, the first expression in the list
will be taken to be the time derivative of the variable represented on
the horizontal axis, and the second expression will be the time
derivative of the variable represented on the vertical axis.  Those two
variables do not have to be <x> and <y>, but if they are not, then the
second argument given to drawdf must be another list naming the two
variables, first the one on the horizontal axis and then the one on the
vertical axis.

   If only one ODE is given, ‘drawdf’ will implicitly admit ‘x=t’, and
‘G(x,y)=1’, transforming the non-autonomous equation into a system of
two autonomous equations.


File: maxima.info,  Node: Functions and Variables for drawdf,  Prev: Introduction to drawdf,  Up: Package drawdf

56.2 Functions and Variables for drawdf
=======================================

56.2.1 Functions
----------------

 -- Function: drawdf
          drawdf (<dydx>, ...options and objects...)
          drawdf (<dvdu>, [<u>,<v>], ...options and objects...)
          drawdf (<dvdu>, [<u>,<umin>,<umax>], [<v>,<vmin>,<vmax>],
          ...options and objects...)
          drawdf ([<dxdt>,<dydt>], ...options and objects...)
          drawdf ([<dudt>,<dvdt>], [<u>,<v>], ...options and objects...)

          drawdf ([<dudt>,<dvdt>], [<u>,<umin>,<umax>],
          [<v>,<vmin>,<vmax>], ...options and objects...)

     Function ‘drawdf’ draws a 2D direction field with optional solution
     curves and other graphics using the ‘draw’ package.

     The first argument specifies the derivative(s), and must be either
     an expression or a list of two expressions.  <dydx>, <dxdt> and
     <dydt> are expressions that depend on <x> and <y>.  <dvdu>, <dudt>
     and <dvdt> are expressions that depend on <u> and <v>.

     If the independent and dependent variables are not <x> and <y>,
     then their names must be specified immediately following the
     derivative(s), either as a list of two names ‘[’<u>,<v>‘]’, or as
     two lists of the form ‘[’<u>,<umin>,<umax>‘]’ and
     ‘[’<v>,<vmin>,<vmax>‘]’.

     The remaining arguments are graphic options, graphic objects, or
     lists containing graphic options and objects, nested to arbitrary
     depth.  The set of graphic options and objects supported by
     ‘drawdf’ is a superset of those supported by ‘draw2d’ and ‘gr2d’
     from the ‘draw’ package.

     The arguments are interpreted sequentially: graphic options affect
     all following graphic objects.  Furthermore, graphic objects are
     drawn on the canvas in order specified, and may obscure graphics
     drawn earlier.  Some graphic options affect the global appearance
     of the scene.

     The additional graphic objects supported by ‘drawdf’ include:
     ‘solns_at’, ‘points_at’, ‘saddles_at’, ‘soln_at’, ‘point_at’, and
     ‘saddle_at’.

     The additional graphic options supported by ‘drawdf’ include:
     ‘field_degree’, ‘soln_arrows’, ‘field_arrows’, ‘field_grid’,
     ‘field_color’, ‘show_field’, ‘tstep’, ‘nsteps’, ‘duration’,
     ‘direction’, ‘field_tstep’, ‘field_nsteps’, and ‘field_duration’.

     Commonly used graphic objects inherited from the ‘draw’ package
     include: ‘explicit’, ‘implicit’, ‘parametric’, ‘polygon’, ‘points’,
     ‘vector’, ‘label’, and all others supported by ‘draw2d’ and ‘gr2d’.

     Commonly used graphic options inherited from the ‘draw’ package
     include:
     ‘points_joined’, ‘color’, ‘point_type’, ‘point_size’, ‘line_width’,
     ‘line_type’, ‘key’, ‘title’, ‘xlabel’, ‘ylabel’, ‘user_preamble’,
     ‘terminal’, ‘dimensions’, ‘file_name’, and all others supported by
     ‘draw2d’ and ‘gr2d’.

     See also ‘draw2d’, ‘rk’, ‘desolve’ and *note ode2::.

     Users of wxMaxima or Imaxima may optionally use ‘wxdrawdf’, which
     is identical to ‘drawdf’ except that the graphics are drawn within
     the notebook using ‘wxdraw’.

     To make use of this function, write first ‘load("drawdf")’.

     Examples:

          (%i1) load("drawdf")$
          (%i2) drawdf(exp(-x)+y)$        /* default vars: x,y */
          (%i3) drawdf(exp(-t)+y, [t,y])$ /* default range: [-10,10] */
          (%i4) drawdf([y,-9*sin(x)-y/5], [x,1,5], [y,-2,2])$

     For backward compatibility, ‘drawdf’ accepts most of the parameters
     supported by plotdf.

          (%i5) drawdf(2*cos(t)-1+y, [t,y], [t,-5,10], [y,-4,9],
                       [trajectory_at,0,0])$

     ‘soln_at’ and ‘solns_at’ draw solution curves passing through the
     specified points, using a slightly enhanced 4th-order Runge Kutta
     numerical integrator.

          (%i6) drawdf(2*cos(t)-1+y, [t,-5,10], [y,-4,9],
                       solns_at([0,0.1],[0,-0.1]),
                       color=blue, soln_at(0,0))$

     ‘field_degree=2’ causes the field to be composed of quadratic
     splines, based on the first and second derivatives at each grid
     point.  ‘field_grid=[’<COLS>,<ROWS>‘]’ specifies the number of
     columns and rows in the grid.

          (%i7) drawdf(2*cos(t)-1+y, [t,-5,10], [y,-4,9],
                       field_degree=2, field_grid=[20,15],
                       solns_at([0,0.1],[0,-0.1]),
                       color=blue, soln_at(0,0))$

     ‘soln_arrows=true’ adds arrows to the solution curves, and (by
     default) removes them from the direction field.  It also changes
     the default colors to emphasize the solution curves.

          (%i8) drawdf(2*cos(t)-1+y, [t,-5,10], [y,-4,9],
                       soln_arrows=true,
                       solns_at([0,0.1],[0,-0.1],[0,0]))$

     ‘duration=40’ specifies the time duration of numerical integration
     (default 10).  Integration will also stop automatically if the
     solution moves too far away from the plotted region, or if the
     derivative becomes complex or infinite.  Here we also specify
     ‘field_degree=2’ to plot quadratic splines.  The equations below
     model a predator-prey system.

          (%i9) drawdf([x*(1-x-y), y*(3/4-y-x/2)], [x,0,1.1], [y,0,1],
                       field_degree=2, duration=40,
                       soln_arrows=true, point_at(1/2,1/2),
                       solns_at([0.1,0.2], [0.2,0.1], [1,0.8], [0.8,1],
                                [0.1,0.1], [0.6,0.05], [0.05,0.4],
                                [1,0.01], [0.01,0.75]))$

     ‘field_degree='solns’ causes the field to be composed of many small
     solution curves computed by 4th-order Runge Kutta, with better
     results in this case.

          (%i10) drawdf([x*(1-x-y), y*(3/4-y-x/2)], [x,0,1.1], [y,0,1],
                        field_degree='solns, duration=40,
                        soln_arrows=true, point_at(1/2,1/2),
                        solns_at([0.1,0.2], [0.2,0.1], [1,0.8],
                                 [0.8,1], [0.1,0.1], [0.6,0.05],
                                 [0.05,0.4], [1,0.01], [0.01,0.75]))$

     ‘saddles_at’ attempts to automatically linearize the equation at
     each saddle, and to plot a numerical solution corresponding to each
     eigenvector, including the separatrices.  ‘tstep=0.05’ specifies
     the maximum time step for the numerical integrator (the default is
     0.1).  Note that smaller time steps will sometimes be used in order
     to keep the x and y steps small.  The equations below model a
     damped pendulum.

          (%i11) drawdf([y,-9*sin(x)-y/5], tstep=0.05,
                        soln_arrows=true, point_size=0.5,
                        points_at([0,0], [2*%pi,0], [-2*%pi,0]),
                        field_degree='solns,
                        saddles_at([%pi,0], [-%pi,0]))$

     ‘show_field=false’ suppresses the field entirely.

          (%i12) drawdf([y,-9*sin(x)-y/5], tstep=0.05,
                        show_field=false, soln_arrows=true,
                        point_size=0.5,
                        points_at([0,0], [2*%pi,0], [-2*%pi,0]),
                        saddles_at([3*%pi,0], [-3*%pi,0],
                                   [%pi,0], [-%pi,0]))$

     ‘drawdf’ passes all unrecognized parameters to ‘draw2d’ or ‘gr2d’,
     allowing you to combine the full power of the ‘draw’ package with
     ‘drawdf’.

          (%i13) drawdf(x^2+y^2, [x,-2,2], [y,-2,2], field_color=gray,
                        key="soln 1", color=black, soln_at(0,0),
                        key="soln 2", color=red, soln_at(0,1),
                        key="isocline", color=green, line_width=2,
                        nticks=100, parametric(cos(t),sin(t),t,0,2*%pi))$

     ‘drawdf’ accepts nested lists of graphic options and objects,
     allowing convenient use of makelist and other function calls to
     generate graphics.

          (%i14) colors : ['red,'blue,'purple,'orange,'green]$
          (%i15) drawdf([x-x*y/2, (x*y - 3*y)/4],
                        [x,2.5,3.5], [y,1.5,2.5],
                        field_color = gray,
                        makelist([ key   = concat("soln",k),
                                   color = colors[k],
                                   soln_at(3, 2 + k/20) ],
                                 k,1,5))$


File: maxima.info,  Node: Package dynamics,  Next: Package engineering-format,  Prev: Package drawdf,  Up: Top

57 Package dynamics
*******************

* Menu:

* The dynamics package::
* Graphical analysis of discrete dynamical systems::
* Visualization with VTK::


File: maxima.info,  Node: The dynamics package,  Next: Graphical analysis of discrete dynamical systems,  Prev: Package dynamics,  Up: Package dynamics

57.1 The dynamics package
=========================

Package ‘dynamics’ includes functions for 3D visualization, animations,
graphical analysis of differential and difference equations and
numerical solution of differential equations.  The functions for
differential equations are described in the section on ‘Numerical
Methods’ and the functions to plot the Mandelbrot and Julia sets are
described in the section on *note Plotting::.

   All the functions in this package will be loaded automatically the
first time they are used.


File: maxima.info,  Node: Graphical analysis of discrete dynamical systems,  Next: Visualization with VTK,  Prev: The dynamics package,  Up: Package dynamics

57.2 Graphical analysis of discrete dynamical systems
=====================================================

 -- Function: chaosgame ([[<x1>, <y1>]...[<xm>, <ym>]], [<x0>, <y0>],
          <b>, <n>, <options>, ...);

     Implements the so-called chaos game: the initial point (<x0>, <y0>)
     is plotted and then one of the <m> points [<x1>, <y1>]...<xm>,
     <ym>] will be selected at random.  The next point plotted will be
     on the segment from the previous point plotted to the point chosen
     randomly, at a distance from the random point which will be <b>
     times that segment's length.  The procedure is repeated <n> times.
     The options are the same as for *note plot2d::.

     *Example*.  A plot of Sierpinsky's triangle:

          (%i1) chaosgame([[0, 0], [1, 0], [0.5, sqrt(3)/2]], [0.1, 0.1], 1/2,
                           30000, [style, dots]);

 -- Function: evolution (<F>, <y0>, <n>, ..., <options>, ...);

     Draws <n+1> points in a two-dimensional graph, where the horizontal
     coordinates of the points are the integers 0, 1, 2, ..., <n>, and
     the vertical coordinates are the corresponding values <y(n)> of the
     sequence defined by the recurrence relation
                  y(n+1) = F(y(n))

     With initial value <y(0)> equal to <y0>.  <F> must be an expression
     that depends only on one variable (in the example, it depend on
     <y>, but any other variable can be used), <y0> must be a real
     number and <n> must be a positive integer.  This function accepts
     the same options as *note plot2d::.

     *Example*.

          (%i1) evolution(cos(y), 2, 11);

 -- Function: evolution2d ([<F>, <G>], [<u>, <v>], [<u0>, <y0>], <n>,
          <options>, ...);

     Shows, in a two-dimensional plot, the first <n+1> points in the
     sequence of points defined by the two-dimensional discrete
     dynamical system with recurrence relations
                  u(n+1) = F(u(n), v(n))    v(n+1) = G(u(n), v(n))

     With initial values <u0> and <v0>.  <F> and <G> must be two
     expressions that depend only on two variables, <u> and <v>, which
     must be named explicitly in a list.  The options are the same as
     for *note plot2d::.

     *Example*.  Evolution of a two-dimensional discrete dynamical
     system:

          (%i1) f: 0.6*x*(1+2*x)+0.8*y*(x-1)-y^2-0.9$
          (%i2) g: 0.1*x*(1-6*x+4*y)+0.1*y*(1+9*y)-0.4$
          (%i3) evolution2d([f,g], [x,y], [-0.5,0], 50000, [style,dots]);

     And an enlargement of a small region in that fractal:

          (%i9) evolution2d([f,g], [x,y], [-0.5,0], 300000, [x,-0.8,-0.6],
                            [y,-0.4,-0.2], [style, dots]);

 -- Function: ifs ([<r1>, ..., <rm>], [<A1>,..., <Am>], [[<x1>, <y1>],
          ..., [<xm>, <ym>]], [<x0>, <y0>], <n>, <options>, ...);

     Implements the Iterated Function System method.  This method is
     similar to the method described in the function *note chaosgame::.
     but instead of shrinking the segment from the current point to the
     randomly chosen point, the 2 components of that segment will be
     multiplied by the 2 by 2 matrix <Ai> that corresponds to the point
     chosen randomly.

     The random choice of one of the <m> attractive points can be made
     with a non-uniform probability distribution defined by the weights
     <r1>,...,<rm>.  Those weights are given in cumulative form; for
     instance if there are 3 points with probabilities 0.2, 0.5 and 0.3,
     the weights <r1>, <r2> and <r3> could be 2, 7 and 10.  The options
     are the same as for *note plot2d::.

     *Example*.  Barnsley's fern, obtained with 4 matrices and 4 points:

          (%i1) a1: matrix([0.85,0.04],[-0.04,0.85])$
          (%i2) a2: matrix([0.2,-0.26],[0.23,0.22])$
          (%i3) a3: matrix([-0.15,0.28],[0.26,0.24])$
          (%i4) a4: matrix([0,0],[0,0.16])$
          (%i5) p1: [0,1.6]$
          (%i6) p2: [0,1.6]$
          (%i7) p3: [0,0.44]$
          (%i8) p4: [0,0]$
          (%i9) w: [85,92,99,100]$
          (%i10) ifs(w, [a1,a2,a3,a4], [p1,p2,p3,p4], [5,0], 50000, [style,dots]);

 -- Function: orbits (<F>, <y0>, <n1>, <n2>, [<x>, <x0>, <xf>, <xstep>],
          <options>, ...);

     Draws the orbits diagram for a family of one-dimensional discrete
     dynamical systems, with one parameter <x>; that kind of diagram is
     used to study the bifurcations of an one-dimensional discrete
     system.

     The function <F(y)> defines a sequence with a starting value of
     <y0>, as in the case of the function ‘evolution’, but in this case
     that function will also depend on a parameter <x> that will take
     values in the interval from <x0> to <xf> with increments of
     <xstep>.  Each value used for the parameter <x> is shown on the
     horizontal axis.  The vertical axis will show the <n2> values of
     the sequence <y(n1+1)>,..., <y(n1+n2+1)> obtained after letting the
     sequence evolve <n1> iterations.  In addition to the options
     accepted by ‘plot2d’, it accepts an option <pixels> that sets up
     the maximum number of different points that will be represented in
     the vertical direction.

     *Example*.  Orbits diagram of the quadratic map, with a parameter
     <a>:

          (%i1) orbits(x^2+a, 0, 50, 200, [a, -2, 0.25], [style, dots]);

     To enlarge the region around the lower bifurcation near x ‘=’ -1.25
     use:
          (%i2) orbits(x^2+a, 0, 100, 400, [a,-1,-1.53], [x,-1.6,-0.8],
                       [nticks, 400], [style,dots]);

 -- Function: staircase (<F>, <y0>, <n>,<options>,...);

     Draws a staircase diagram for the sequence defined by the
     recurrence relation
                  y(n+1) = F(y(n))

     The interpretation and allowed values of the input parameters is
     the same as for the function *note evolution::.  A staircase
     diagram consists of a plot of the function <F(y)>, together with
     the line <G(y)> ‘=’ <y>.  A vertical segment is drawn from the
     point (<y0>, <y0>) on that line until the point where it intersects
     the function <F>.  From that point a horizontal segment is drawn
     until it reaches the point (<y1>, <y1>) on the line, and the
     procedure is repeated <n> times until the point (<yn>, <yn>) is
     reached.  The options are the same as for *note plot2d::.

     *Example*.

          (%i1) staircase(cos(y), 1, 11, [y, 0, 1.2]);


File: maxima.info,  Node: Visualization with VTK,  Prev: Graphical analysis of discrete dynamical systems,  Up: Package dynamics

57.3 Visualization with VTK
===========================

Function scene creates 3D images and animations using the _Visualization
ToolKit_ (VTK) software.  In order to use that function, Xmaxima and VTK
should be installed in your system (including the TCL bindings of VTK,
which in some system might come in a separate package).

 -- Function: scene (<objects>, ..., <options>, ...);

     Accepts an empty list or a list of several ‘objects’ and ‘options’.
     The program launches Xmaxima, which opens an external window
     representing the given objects in a 3-dimensional space and
     applying the options given.  Each object must belong to one of the
     following 4 classes: sphere, cube, cylinder or cone (see ‘Scene
     objects’).  Objects are identified by giving their name or by a
     list in which the first element is the class name and the following
     elements are options for that object.

     *Example*.  A hexagonal pyramid with a blue background:
          (%i1) scene(cone, [background,"#9980e5"])$

     By holding down the left button of the mouse while it is moved on
     the graphics window, the camera can be rotated showing different
     views of the pyramid.  The two plot options ‘elevation’ and
     ‘azimuth’ can also be used to change the initial orientation of the
     viewing camera.  The camera can be moved by holding the middle
     mouse button while moving it and holding the right-side mouse
     button while moving it up or down will zoom in or out.

     Each object option should be a list starting with the option name,
     followed by its value.  The list of allowed options can be found in
     the ‘Scene object's options’ section.

     *Example*.  This will show a sphere falling to the ground and
     bouncing off without losing any energy.  To start or pause the
     animation, press the play/pause button.

          (%i1) p: makelist ([0,0,2.1- 9.8*t^2/2], t, 0, 0.64, 0.01)$

          (%i2) p: append (p, reverse(p))$

          (%i3) ball: [sphere, [radius,0.1], [thetaresolution,20],
            [phiresolution,20], [position,0,0,2.1], [color,red],
            [animate,position,p]]$

          (%i4) ground: [cube, [xlength,2], [ylength,2], [zlength,0.2],
            [position,0,0,-0.1],[color,violet]]$

          (%i5) scene (ball, ground, restart)$

     The <restart> option was used to make the animation restart
     automatically every time the last point in the position list is
     reached.  The accepted values for the colors are the same as for
     the ‘color’ option of plot2d.

57.3.1 Scene options
--------------------

 -- Scene option: azimuth [azimuth, <angle>]
     Default value: ‘135’

     The rotation of the camera on the horizontal (x, y) plane.  <angle>
     must be a real number; an angle of 0 means that the camera points
     in the direction of the y axis and the x axis will appear on the
     right.

 -- Scene option: background [background, <color>]
     Default value: ‘black’

     The color of the graphics window's background.  It accepts color
     names or hexadecimal red-green-blue strings (see the ‘color’ option
     of plot2d).

 -- Scene option: elevation [elevation, <angle>]
     Default value: ‘30’

     The vertical rotation of the camera.  The <angle> must be a real
     number; an angle of 0 means that the camera points on the
     horizontal, and the default angle of 30 means that the camera is
     pointing 30 degrees down from the horizontal.

 -- Scene option: height [height, <pixels>]
     Default value: ‘500’

     The height, in pixels, of the graphics window.  <pixels> must be a
     positive integer number.

 -- Scene option: restart [restart, <value>]
     Default value: ‘false’

     A true value means that animations will restart automatically when
     the end of the list is reached.  Writing just "restart" is
     equivalent to [restart, <true>].

 -- Scene option: tstep [tstep, <time>]
     Default value: ‘10’

     The amount of time, in mili-seconds, between iterations among
     consecutive animation frames.  <time> must be a real number.

 -- Scene option: width [width, <pixels>]
     Default value: ‘500’

     The width, in pixels, of the graphics window.  <pixels> must be a
     positive integer number.

 -- Scene option: windowname [windowtitle, <name>]
     Default value: ‘.scene’

     <name> must be a string that can be used as the name of the Tk
     window created by Xmaxima for the ‘scene’ graphics.  The default
     value ‘.scene’ implies that a new top level window will be created.

 -- Scene option: windowtitle [windowtitle, <name>]
     Default value: ‘Xmaxima: scene’

     <name> must be a string that will be written in the title of the
     window created by ‘scene’.

57.3.2 Scene objects
--------------------

 -- Scene object: cone [cone, <options>]

     Creates a regular pyramid with height equal to 1 and a hexagonal
     base with vertices 0.5 units away from the axis.  Options ‘height’
     and ‘radius’ can be used to change those defaults and option
     ‘resolution’ can be used to change the number of edges of the base;
     higher values will make it look like a cone.  By default, the axis
     will be along the x axis, the middle point of the axis will be at
     the origin and the vertex on the positive side of the x axis; use
     options ‘orientation’ and ‘center’ to change those defaults.

     *Example*.  This shows a pyramid that starts rotating around the z
     axis when the play button is pressed.

          (%i1) scene([cone, [orientation,0,30,0], [tstep,100],
             [animate,orientation,makelist([0,30,i],i,5,360,5)]], restart)$

 -- Scene object: cube [cube, <options>]

     A cube with edges of 1 unit and faces parallel to the xy, xz and yz
     planes.  The lengths of the three edges can be changed with options
     ‘xlength’, ‘ylength’ and ‘zlength’, turning it into a rectangular
     box and the faces can be rotated with option ‘orientation’.

 -- Scene object: cylinder [cylinder, <options>]

     Creates a regular prism with height equal to 1 and a hexagonal base
     with vertices 0.5 units away from the axis.  Options ‘height’ and
     ‘radius’ can be used to change those defaults and option
     ‘resolution’ can be used to change the number of edges of the base;
     higher values will make it look like a cylinder.  The default
     height can be changed with the option ‘height’.  By default, the
     axis will be along the x axis and the middle point of the axis will
     be at the origin; use options ‘orientation’ and ‘center’ to change
     those defaults.

 -- Scene object: sphere [sphere, <options>]

     A sphere with default radius of 0.5 units and center at the origin.

57.3.3 Scene object's options
-----------------------------

 -- Object option: animation [animation, <property>, <positions>]

     <property> should be one of the following 4 object's properties:
     ‘origin’, ‘scale’, ‘position’ or ‘orientation’ and <positions>
     should be a list of points.  When the play button is pressed, the
     object property will be changed sequentially through all the values
     in the list, at intervals of time given by the option ‘tstep’.  The
     rewind button can be used to point at the start of the sequence
     making the animation restart after the play button is pressed
     again.

     See also ‘track’.

 -- Object option: capping [capping, <number>]
     Default value: ‘1’

     In a cone or a cylinder, it defines whether the base (or bases)
     will be shown.  A value of 1 for <number> makes the base visible
     and a value of 0 makes it invisible.

 -- Object option: center [center, <point>]
     Default value: ‘[0, 0, 0]’

     The coordinates of the object's geometric center, with respect to
     its ‘position’.  <point> can be a list with 3 real numbers, or 3
     real numbers separated by commas.  In a cylinder, cone or cube it
     will be at half its height and in a sphere at its center.

 -- Object option: color [color, <colorname>]
     Default value: ‘white’

     The color of the object.  It accepts color names or hexadecimal
     red-green-blue strings (see the ‘color’ option of plot2d).

 -- Object option: endphi [endphi, <angle>]
     Default value: ‘180’

     In a sphere phi is the angle on the vertical plane that passes
     through the z axis, measured from the positive part of the z axis.
     <angle> must be a number between 0 and 180 that sets the final
     value of phi at which the surface will end.  A value smaller than
     180 will eliminate a part of the sphere's surface.

     See also ‘startphi’ and ‘phiresolution’.

 -- Object option: endtheta [endtheta, <angle>]
     Default value: ‘360’

     In a sphere theta is the angle on the horizontal plane (longitude),
     measured from the positive part of the x axis.  <angle> must be a
     number between 0 and 360 that sets the final value of theta at
     which the surface will end.  A value smaller than 360 will
     eliminate a part of the sphere's surface.

     See also ‘starttheta’ and ‘thetaresolution’.

 -- Object option: height [height, <value>]
     Default value: ‘1’

     <value> must be a positive number which sets the height of a cone
     or a cylinder.

 -- Object option: linewidth [linewidth, <value>]
     Default value: ‘1’

     The width of the lines, when option ‘wireframe’ is used.  <value>
     must be a positive number.

 -- Object option: opacity [opacity, <value>]
     Default value: ‘1’

     <value> must be a number between 0 and 1.  The lower the number,
     the more transparent the object will become.  The default value of
     1 means a completely opaque object.

 -- Object option: orientation [orientation, <angles>]
     Default value: ‘[0, 0, 0]’

     Three angles by which the object will be rotated with respect to
     the three axis.  <angles> can be a list with 3 real numbers, or 3
     real numbers separated by commas.  *Example*: ‘[0, 0, 90]’ rotates
     the x axis of the object to the y axis of the reference frame.

 -- Object option: origin [origin, <point>]
     Default value: ‘[0, 0, 0]’

     The coordinates of the object's origin, with respect to which its
     other dimensions are defined.  <point> can be a list with 3 real
     numbers, or 3 real numbers separated by commas.

 -- Object option: phiresolution [phiresolution, <num>]
     Default value: ‘’

     The number of sub-intervals into which the phi angle interval from
     ‘startphi’ to ‘endphi’ will be divided.  <num> must be a positive
     integer.

     See also ‘startphi’ and ‘endphi’.

 -- Object option: points [points]

     Only the vertices of the triangulation used to render the surface
     will be shown.  *Example*: ‘[sphere, [points]]’

     See also ‘surface’ and ‘wireframe’.

 -- Object option: pointsize [pointsize, <value>]
     Default value: ‘1’

     The size of the points, when option ‘points’ is used.  <value> must
     be a positive number.

 -- Object option: position [position, <point>]
     Default value: ‘[0, 0, 0]’

     The coordinates of the object's position.  <point> can be a list
     with 3 real numbers, or 3 real numbers separated by commas.

 -- Object option: radius [radius, <value>]
     Default value: ‘0.5’

     The radius or a sphere or the distance from the axis to the base's
     vertices in a cylinder or a cone.  <value> must be a positive
     number.

 -- Object option: resolution [resolution, <number>]
     Default value: ‘6’

     <number> must be an integer greater than 2 that sets the number of
     edges in the base of a cone or a cylinder.

 -- Object option: scale [scale, <factors>]
     Default value: ‘[1, 1, 1]’

     Three numbers by which the object will be scaled with respect to
     the three axis.  <factors> can be a list with 3 real numbers, or 3
     real numbers separated by commas.  *Example*: ‘[2, 0.5, 1]’
     enlarges the object to twice its size in the x direction, reduces
     the dimensions in the y direction to half and leaves the z
     dimensions unchanged.

 -- Object option: startphi [startphi, <angle>]
     Default value: ‘0’

     In a sphere phi is the angle on the vertical plane that passes
     through the z axis, measured from the positive part of the z axis.
     <angle> must be a number between 0 and 180 that sets the initial
     value of phi at which the surface will start.  A value bigger than
     0 will eliminate a part of the sphere's surface.

     See also ‘endphi’ and ‘phiresolution’.

 -- Object option: starttheta [starttheta, <angle>]
     Default value: ‘0’

     In a sphere theta is the angle on the horizontal plane (longitude),
     measured from the positive part of the x axis.  <angle> must be a
     number between 0 and 360 that sets the initial value of theta at
     which the surface will start.  A value bigger than 0 will eliminate
     a part of the sphere's surface.

     See also ‘endtheta’ and ‘thetaresolution’.

 -- Object option: surface [surface]

     The surfaces of the object will be rendered and the lines and
     points of the triangulation used to build the surface will not be
     shown.  This is the default behavior, which can be changed using
     either the option ‘points’ or ‘wireframe’.

 -- Object option: thetaresolution [thetaresolution, <num>]
     Default value: ‘’

     The number of sub-intervals into which the theta angle interval
     from ‘starttheta’ to ‘endtheta’ will be divided.  <num> must be a
     positive integer.

     See also ‘starttheta’ and ‘endtheta’.

 -- Object option: track [track, <positions>]

     <positions> should be a list of points.  When the play button is
     pressed, the object position will be changed sequentially through
     all the points in the list, at intervals of time given by the
     option ‘tstep’, leaving behind a track of the object's trajectory.
     The rewind button can be used to point at the start of the sequence
     making the animation restart after the play button is pressed
     again.

     *Example*.  This will show the trajectory of a ball thrown with
     speed of 5 m/s, at an angle of 45 degrees, when the air resistance
     can be neglected:

          (%i1) p: makelist ([0,4*t,4*t- 9.8*t^2/2], t, 0, 0.82, 0.01)$

          (%i2) ball: [sphere, [radius,0.1], [color,red], [track,p]]$

          (%i3) ground: [cube, [xlength,2], [ylength,4], [zlength,0.2],
                [position,0,1.5,-0.2],[color,green]]$

          (%i4) scene (ball, ground)$

     See also ‘animation’.

 -- Object option: xlength [xlength, <length>]
     Default value: ‘1’

     The height of a cube in the x direction.  <length> must be a
     positive number.  See also ‘ylength’ and ‘zlength’.

 -- Object option: ylength [ylength, <length>]
     Default value: ‘1’

     The height of a cube in the y direction.  <length> must be a
     positive number.  See also ‘xlength’ and ‘zlength’.

 -- Object option: zlength [zlength, <length>]
     Default value: ‘1’

     The height of a cube in z the direction.  <length> must be a
     positive number.  See also ‘xlength’ and ‘ylength’.

 -- Object option: wireframe [wireframe]

     Only the edges of the triangulation used to render the surface will
     be shown.  *Example*: ‘[cube, [wireframe]]’

     See also ‘surface’ and ‘points’.


File: maxima.info,  Node: Package engineering-format,  Next: Package ezunits,  Prev: Package dynamics,  Up: Top

58 Package engineering-format
*****************************

Engineering-format changes the way maxima outputs floating-point numbers
to the notation engineers are used to: ‘a*10^b’ with ‘b’ dividable by
three.
* Menu:

* Functions and Variables for engineering-format::


File: maxima.info,  Node: Functions and Variables for engineering-format,  Prev: Package engineering-format,  Up: Package engineering-format

58.1 Functions and Variables for engineering-format
===================================================

 -- Option variable: engineering_format_floats
     Default value: ‘true’

     This variable allows to temporarily switch off engineering-format.
          (%i1) load("engineering-format");
          (%o1) /home/gunter/src/maxima-code/share/contrib/engineering-for\
          mat.lisp
          (%i2) float(sin(10)/10000);
          (%o2)                - 54.40211108893698e-6
          (%i3) engineering_format_floats:false$
          (%i4) float(sin(10)/10000);
          (%o4)                - 5.440211108893698e-5

     See also ‘fpprintprec’ and *note float::.

 -- Option variable: engineering_format_min
     Default value: ‘0.0’

     The minimum absolute value that isn't automatically converted to
     the engineering format.  See also ‘engineering_format_max’ and
     *note engineering_format_floats::.

          (%i1) lst: float([.05,.5,5,500,5000,500000]);
          (%o1)       [0.05, 0.5, 5.0, 500.0, 5000.0, 500000.0]
          (%i2) load("engineering-format");
          (%o2) /home/gunter/src/maxima-code/share/contrib/engineering-for\
          mat.lisp
          (%i3) lst;
          (%o3) [50.0e-3, 500.0e-3, 5.0e+0, 500.0e+0, 5.0e+3, 500.0e+3]
          (%i4) engineering_format_min:.1$
          (%i5) engineering_format_max:1000$
          (%i6) lst;
          (%o6)     [50.0e-3, 0.5, 5.0, 500.0, 5.0e+3, 500.0e+3]

 -- Option variable: engineering_format_max
     Default value: ‘0.0’

     The maximum absolute value that isn't automatically converted to
     the engineering format.  See also ‘engineering_format_min’ and
     *note engineering_format_floats::.


File: maxima.info,  Node: Package ezunits,  Next: Package f90,  Prev: Package engineering-format,  Up: Top

59 Package ezunits
******************

* Menu:

* Introduction to ezunits::
* Introduction to physical_constants::
* Functions and Variables for ezunits::


File: maxima.info,  Node: Introduction to ezunits,  Next: Introduction to physical_constants,  Prev: Package ezunits,  Up: Package ezunits

59.1 Introduction to ezunits
============================

‘ezunits’ is a package for working with dimensional quantities,
including some functions for dimensional analysis.  ‘ezunits’ can carry
out arithmetic operations on dimensional quantities and unit
conversions.  The built-in units include Systeme Internationale (SI) and
US customary units, and other units can be declared.  See also
‘physical_constants’, a collection of physical constants.

   ‘load("ezunits")’ loads this package.  ‘demo("ezunits")’ displays
several examples.  The convenience function ‘known_units’ returns a list
of the built-in and user-declared units, while
‘display_known_unit_conversions’ displays the set of known conversions
in an easy-to-read format.

   An expression a ` b represents a dimensional quantity, with ‘a’
indicating a nondimensional quantity and ‘b’ indicating the dimensional
units.  A symbol can be used as a unit without declaring it as such;
unit symbols need not have any special properties.  The quantity and
unit of an expression a ` b can be extracted by the ‘qty’ and ‘units’
functions, respectively.

   A symbol may be declared to be a dimensional quantity, with specified
quantity or specified units or both.

   An expression a ` b `` c converts from unit ‘b’ to unit ‘c’.
‘ezunits’ has built-in conversions for SI base units, SI derived units,
and some non-SI units.  Unit conversions not already known to ‘ezunits’
can be declared.  The unit conversions known to ‘ezunits’ are specified
by the global variable ‘known_unit_conversions’, which comprises
built-in and user-defined conversions.  Conversions for products,
quotients, and powers of units are derived from the set of known unit
conversions.

   As Maxima generally prefers exact numbers (integers or rationals) to
inexact (float or bigfloat), so ‘ezunits’ preserves exact numbers when
they appear in dimensional quantities.  All built-in unit conversions
are expressed in terms of exact numbers; inexact numbers in declared
conversions are coerced to exact.

   There is no preferred system for display of units; input units are
not converted to other units unless conversion is explicitly indicated.
‘ezunits’ recognizes the prefixes m-, k-, M, and G- (for milli-, kilo-,
mega-, and giga-) as applied to SI base units and SI derived units, but
such prefixes are applied only when indicated by an explicit conversion.

   Arithmetic operations on dimensional quantities are carried out by
conventional rules for such operations.

   • (x ` a) * (y ` b) is equal to (x * y) ` (a * b).
   • (x ` a) + (y ` a) is equal to (x + y) ` a.
   • (x ` a)^y is equal to x^y ` a^y when ‘y’ is nondimensional.

   ‘ezunits’ does not require that units in a sum have the same
dimensions; such terms are not added together, and no error is reported.

   ‘ezunits’ includes functions for elementary dimensional analysis,
namely the fundamental dimensions and fundamental units of a dimensional
quantity, and computation of dimensionless quantities and natural units.
The functions for dimensional analysis were adapted from similar
functions in another package, written by Barton Willis.

   For the purpose of dimensional analysis, a list of fundamental
dimensions and an associated list of fundamental units are maintained;
by default the fundamental dimensions are length, mass, time, charge,
temperature, and quantity, and the fundamental units are the associated
SI units, but other fundamental dimensions and units can be declared.


File: maxima.info,  Node: Introduction to physical_constants,  Next: Functions and Variables for ezunits,  Prev: Introduction to ezunits,  Up: Package ezunits

59.2 Introduction to physical_constants
=======================================

‘physical_constants’ is a collection of physical constants, copied from
CODATA 2006 recommended values
(<https://physics.nist.gov/cuu/Constants/>).  ‘load
("physical_constants")’ loads this package, and loads ‘ezunits’ also, if
it is not already loaded.

   A physical constant is represented as a symbol which has a property
which is the constant value.  The constant value is a dimensional
quantity, as represented by ‘ezunits’.  The function ‘constvalue’
fetches the constant value; the constant value is not the ordinary value
of the symbol, so symbols of physical constants persist in evaluated
expressions until their values are fetched by ‘constvalue’.

   ‘physical_constants’ includes some auxiliary information, namely, a
description string for each constant, an estimate of the error of its
numerical value, and a property for TeX display.  To identify physical
constants, each symbol has the ‘physical_constant’ property;
‘propvars(physical_constant)’ therefore shows the list of all such
symbols.

   ‘physical_constants’ comprises the following constants.

‘%c’
     speed of light in vacuum
‘%mu_0’
     magnetic constant
‘%e_0’
     electric constant
‘%Z_0’
     characteristic impedance of vacuum
‘%G’
     Newtonian constant of gravitation
‘%h’
     Planck constant
‘%h_bar’
     Planck constant
‘%m_P’
     Planck mass
‘%T_P’
     Planck temperature
‘%l_P’
     Planck length
‘%t_P’
     Planck time
‘%%e’
     elementary charge
‘%Phi_0’
     magnetic flux quantum
‘%G_0’
     conductance quantum
‘%K_J’
     Josephson constant
‘%R_K’
     von Klitzing constant
‘%mu_B’
     Bohr magneton
‘%mu_N’
     nuclear magneton
‘%alpha’
     fine-structure constant
‘%R_inf’
     Rydberg constant
‘%a_0’
     Bohr radius
‘%E_h’
     Hartree energy
‘%ratio_h_me’
     quantum of circulation
‘%m_e’
     electron mass
‘%N_A’
     Avogadro constant
‘%m_u’
     atomic mass constant
‘%F’
     Faraday constant
‘%R’
     molar gas constant
‘%%k’
     Boltzmann constant
‘%V_m’
     molar volume of ideal gas
‘%n_0’
     Loschmidt constant
‘%ratio_S0_R’
     Sackur-Tetrode constant (absolute entropy constant)
‘%sigma’
     Stefan-Boltzmann constant
‘%c_1’
     first radiation constant
‘%c_1L’
     first radiation constant for spectral radiance
‘%c_2’
     second radiation constant
‘%b’
     Wien displacement law constant
‘%b_prime’
     Wien displacement law constant

   Reference: <https://physics.nist.gov/cuu/Constants/>

   Examples:

   The list of all symbols which have the ‘physical_constant’ property.

     (%i1) load ("physical_constants")$
     (%i2) propvars (physical_constant);
     (%o2) [%c, %mu_0, %e_0, %Z_0, %G, %h, %h_bar, %m_P, %T_P, %l_P,
     %t_P, %%e, %Phi_0, %G_0, %K_J, %R_K, %mu_B, %mu_N, %alpha,
     %R_inf, %a_0, %E_h, %ratio_h_me, %m_e, %N_A, %m_u, %F, %R, %%k,
     %V_m, %n_0, %ratio_S0_R, %sigma, %c_1, %c_1L, %c_2, %b, %b_prime]

   Properties of the physical constant ‘%c’.

     (%i1) load ("physical_constants")$
     (%i2) constantp (%c);
     (%o2)                         true
     (%i3) get (%c, description);
     (%o3)               speed of light in vacuum
     (%i4) constvalue (%c);
                                           m
     (%o4)                     299792458 ` -
                                           s
     (%i5) get (%c, RSU);
     (%o5)                           0
     (%i6) tex (%c);
     $$c$$
     (%o6)                         false

   The energy equivalent of 1 pound-mass.  The symbol ‘%c’ persists
until its value is fetched by ‘constvalue’.

     (%i1) load ("physical_constants")$
     (%i2) m * %c^2;
                                     2
     (%o2)                         %c  m
     (%i3) %, m = 1 ` lbm;
                                   2
     (%o3)                       %c  ` lbm
     (%i4) constvalue (%);
                                                 2
                                            lbm m
     (%o4)              89875517873681764 ` ------
                                               2
                                              s
     (%i5) E : % `` J;
     Computing conversions to base units; may take a moment.
                          366838848464007200
     (%o5)                ------------------ ` J
                                  9
     (%i6) E `` GJ;
                           458548560580009
     (%o6)                 --------------- ` GJ
                              11250000
     (%i7) float (%);
     (%o7)              4.0759872051556356e+7 ` GJ


File: maxima.info,  Node: Functions and Variables for ezunits,  Prev: Introduction to physical_constants,  Up: Package ezunits

59.3 Functions and Variables for ezunits
========================================

 -- Operator: `

     The dimensional quantity operator.  An expression a ` b represents
     a dimensional quantity, with ‘a’ indicating a nondimensional
     quantity and ‘b’ indicating the dimensional units.  A symbol can be
     used as a unit without declaring it as such; unit symbols need not
     have any special properties.  The quantity and unit of an
     expression a ` b can be extracted by the ‘qty’ and ‘units’
     functions, respectively.

     Arithmetic operations on dimensional quantities are carried out by
     conventional rules for such operations.

        • (x ` a) * (y ` b) is equal to (x * y) ` (a * b).
        • (x ` a) + (y ` a) is equal to (x + y) ` a.
        • (x ` a)^y is equal to x^y ` a^y when ‘y’ is nondimensional.

     ‘ezunits’ does not require that units in a sum have the same
     dimensions; such terms are not added together, and no error is
     reported.

     ‘load ("ezunits")’ enables this operator.

     Examples:

     SI (Systeme Internationale) units.

          (%i1) load ("ezunits")$
          (%i2) foo : 10 ` m;
          (%o2)                        10 ` m
          (%i3) qty (foo);
          (%o3)                          10
          (%i4) units (foo);
          (%o4)                           m
          (%i5) dimensions (foo);
          (%o5)                        length

     "Customary" units.

          (%i1) load ("ezunits")$
          (%i2) bar : x ` acre;
          (%o2)                       x ` acre
          (%i3) dimensions (bar);
                                             2
          (%o3)                        length
          (%i4) fundamental_units (bar);
                                          2
          (%o4)                          m

     Units ad hoc.

          (%i1) load ("ezunits")$
          (%i2) baz : 3 ` sheep + 8 ` goat + 1 ` horse;
          (%o2)           8 ` goat + 3 ` sheep + 1 ` horse
          (%i3) subst ([sheep = 3*goat, horse = 10*goat], baz);
          (%o3)                       27 ` goat
          (%i4) baz2 : 1000`gallon/fortnight;
                                          gallon
          (%o4)                   1000 ` ---------
                                         fortnight
          (%i5) subst (fortnight = 14*day, baz2);
                                    500   gallon
          (%o5)                     --- ` ------
                                     7     day

     Arithmetic operations on dimensional quantities.

          (%i1) load ("ezunits")$
          (%i2) 100 ` kg + 200 ` kg;
          (%o2)                       300 ` kg
          (%i3) 100 ` m^3 - 100 ` m^3;
                                            3
          (%o3)                        0 ` m
          (%i4) (10 ` kg) * (17 ` m/s^2);
                                           kg m
          (%o4)                      170 ` ----
                                             2
                                            s
          (%i5) (x ` m) / (y ` s);
                                        x   m
          (%o5)                         - ` -
                                        y   s
          (%i6) (a ` m)^2;
                                        2    2
          (%o6)                        a  ` m

 -- Operator: ``

     The unit conversion operator.  An expression a ` b `` c converts
     from unit ‘b’ to unit ‘c’.  ‘ezunits’ has built-in conversions for
     SI base units, SI derived units, and some non-SI units.  Unit
     conversions not already known to ‘ezunits’ can be declared.  The
     unit conversions known to ‘ezunits’ are specified by the global
     variable ‘known_unit_conversions’, which comprises built-in and
     user-defined conversions.  Conversions for products, quotients, and
     powers of units are derived from the set of known unit conversions.

     There is no preferred system for display of units; input units are
     not converted to other units unless conversion is explicitly
     indicated.  ‘ezunits’ does not attempt to simplify units by
     prefixes (milli-, centi-, deci-, etc) unless such conversion is
     explicitly indicated.

     ‘load ("ezunits")’ enables this operator.

     Examples:

     The set of known unit conversions.

          (%i1) load ("ezunits")$
          (%i2) display2d : false$
          (%i3) known_unit_conversions;
          (%o3) {acre = 4840*yard^2,Btu = 1055*J,cfm = feet^3/minute,
                 cm = m/100,day = 86400*s,feet = 381*m/1250,ft = feet,
                 g = kg/1000,gallon = 757*l/200,GHz = 1000000000*Hz,
                 GOhm = 1000000000*Ohm,GPa = 1000000000*Pa,
                 GWb = 1000000000*Wb,Gg = 1000000*kg,Gm = 1000000000*m,
                 Gmol = 1000000*mol,Gs = 1000000000*s,ha = hectare,
                 hectare = 100*m^2,hour = 3600*s,Hz = 1/s,inch = feet/12,
                 km = 1000*m,kmol = 1000*mol,ks = 1000*s,l = liter,
                 lbf = pound_force,lbm = pound_mass,liter = m^3/1000,
                 metric_ton = Mg,mg = kg/1000000,MHz = 1000000*Hz,
                 microgram = kg/1000000000,micrometer = m/1000000,
                 micron = micrometer,microsecond = s/1000000,
                 mile = 5280*feet,minute = 60*s,mm = m/1000,
                 mmol = mol/1000,month = 2629800*s,MOhm = 1000000*Ohm,
                 MPa = 1000000*Pa,ms = s/1000,MWb = 1000000*Wb,
                 Mg = 1000*kg,Mm = 1000000*m,Mmol = 1000000000*mol,
                 Ms = 1000000*s,ns = s/1000000000,ounce = pound_mass/16,
                 oz = ounce,Ohm = s*J/C^2,
                 pound_force = 32*ft*pound_mass/s^2,
                 pound_mass = 200*kg/441,psi = pound_force/inch^2,
                 Pa = N/m^2,week = 604800*s,Wb = J/A,yard = 3*feet,
                 year = 31557600*s,C = s*A,F = C^2/J,GA = 1000000000*A,
                 GC = 1000000000*C,GF = 1000000000*F,GH = 1000000000*H,
                 GJ = 1000000000*J,GK = 1000000000*K,GN = 1000000000*N,
                 GS = 1000000000*S,GT = 1000000000*T,GV = 1000000000*V,
                 GW = 1000000000*W,H = J/A^2,J = m*N,kA = 1000*A,
                 kC = 1000*C,kF = 1000*F,kH = 1000*H,kHz = 1000*Hz,
                 kJ = 1000*J,kK = 1000*K,kN = 1000*N,kOhm = 1000*Ohm,
                 kPa = 1000*Pa,kS = 1000*S,kT = 1000*T,kV = 1000*V,
                 kW = 1000*W,kWb = 1000*Wb,mA = A/1000,mC = C/1000,
                 mF = F/1000,mH = H/1000,mHz = Hz/1000,mJ = J/1000,
                 mK = K/1000,mN = N/1000,mOhm = Ohm/1000,mPa = Pa/1000,
                 mS = S/1000,mT = T/1000,mV = V/1000,mW = W/1000,
                 mWb = Wb/1000,MA = 1000000*A,MC = 1000000*C,
                 MF = 1000000*F,MH = 1000000*H,MJ = 1000000*J,
                 MK = 1000000*K,MN = 1000000*N,MS = 1000000*S,
                 MT = 1000000*T,MV = 1000000*V,MW = 1000000*W,
                 N = kg*m/s^2,R = 5*K/9,S = 1/Ohm,T = J/(m^2*A),V = J/C,
                 W = J/s}

     Elementary unit conversions.

          (%i1) load ("ezunits")$
          (%i2) 1 ` ft `` m;
          Computing conversions to base units; may take a moment.
                                      381
          (%o2)                       ---- ` m
                                      1250
          (%i3) %, numer;
          (%o3)                      0.3048 ` m
          (%i4) 1 ` kg `` lbm;
                                      441
          (%o4)                       --- ` lbm
                                      200
          (%i5) %, numer;
          (%o5)                      2.205 ` lbm
          (%i6) 1 ` W `` Btu/hour;
                                     720   Btu
          (%o6)                      --- ` ----
                                     211   hour
          (%i7) %, numer;
                                                  Btu
          (%o7)               3.412322274881517 ` ----
                                                  hour
          (%i8) 100 ` degC `` degF;
          (%o8)                      212 ` degF
          (%i9) -40 ` degF `` degC;
          (%o9)                     (- 40) ` degC
          (%i10) 1 ` acre*ft `` m^3;
                                  60228605349    3
          (%o10)                  ----------- ` m
                                   48828125
          (%i11) %, numer;
                                                    3
          (%o11)                1233.48183754752 ` m

     Coercing quantities in feet and meters to one or the other.

          (%i1) load ("ezunits")$
          (%i2) 100 ` m + 100 ` ft;
          (%o2)                  100 ` m + 100 ` ft
          (%i3) (100 ` m + 100 ` ft) `` ft;
          Computing conversions to base units; may take a moment.
                                     163100
          (%o3)                      ------ ` ft
                                      381
          (%i4) %, numer;
          (%o4)                428.0839895013123 ` ft
          (%i5) (100 ` m + 100 ` ft) `` m;
                                      3262
          (%o5)                       ---- ` m
                                       25
          (%i6) %, numer;
          (%o6)                      130.48 ` m

     Dimensional analysis to find fundamental dimensions and fundamental
     units.

          (%i1) load ("ezunits")$
          (%i2) foo : 1 ` acre * ft;
          (%o2)                      1 ` acre ft
          (%i3) dimensions (foo);
                                             3
          (%o3)                        length
          (%i4) fundamental_units (foo);
                                          3
          (%o4)                          m
          (%i5) foo `` m^3;
          Computing conversions to base units; may take a moment.
                                  60228605349    3
          (%o5)                   ----------- ` m
                                   48828125
          (%i6) %, numer;
                                                    3
          (%o6)                 1233.48183754752 ` m

     Declared unit conversions.

          (%i1) load ("ezunits")$
          (%i2) declare_unit_conversion (MMBtu = 10^6*Btu, kW = 1000*W);
          (%o2)                         done
          (%i3) declare_unit_conversion (kWh = kW*hour, MWh = 1000*kWh,
                                         bell = 1800*s);
          (%o3)                         done
          (%i4) 1 ` kW*s `` MWh;
          Computing conversions to base units; may take a moment.
                                       1
          (%o4)                     ------- ` MWh
                                    3600000
          (%i5) 1 ` kW/m^2 `` MMBtu/bell/ft^2;
                                 1306449      MMBtu
          (%o5)                 ---------- ` --------
                                8242187500          2
                                             bell ft

 -- Function: constvalue (<x>)

     Shows the value and the units of one of the constants declared by
     package ‘physical_constants’, which includes a list of physical
     constants, or of a new constant declared in package ‘ezunits’ (see
     ‘declare_constvalue’).

     Note that constant values as recognized by ‘constvalue’ are
     separate from values declared by ‘numerval’ and recognized by
     ‘constantp’.

     Example:

          (%i1) load ("physical_constants")$
          (%i2) constvalue (%G);
                                               3
                                              m
          (%o2)                    6.67428 ` -----
                                                 2
                                             kg s
          (%i3) get ('%G, 'description);
          (%o3)           Newtonian constant of gravitation

 -- Function: declare_constvalue (<a>, <x>)

     Declares the value of a constant to be used in package ‘ezunits’.
     This function should be loaded with ‘load ("ezunits")’.

     Example:

          (%i1) load ("ezunits")$
          (%i2) declare_constvalue (FOO, 100 ` lbm / acre);
                                           lbm
          (%o2)                      100 ` ----
                                           acre
          (%i3) FOO * (50 ` acre);
          (%o3)                     50 FOO ` acre
          (%i4) constvalue (%);
          (%o4)                      5000 ` lbm

 -- Function: remove_constvalue (<a>)

     Reverts the effect of *note declare_constvalue::.  This function
     should be loaded with ‘load ("ezunits")’.

 -- Function: units (<x>)

     Returns the units of a dimensional quantity <x>, or returns 1 if
     <x> is nondimensional.

     <x> may be a literal dimensional expression a ` b, a symbol with
     declared units via ‘declare_units’, or an expression containing
     either or both of those.

     This function should be loaded with ‘load ("ezunits")’.

     Example:

          (%i1) load ("ezunits")$
          (%i2) foo : 100 ` kg;
          (%o2)                       100 ` kg
          (%i3) bar : x ` m/s;
                                            m
          (%o3)                         x ` -
                                            s
          (%i4) units (foo);
          (%o4)                          kg
          (%i5) units (bar);
                                          m
          (%o5)                           -
                                          s
          (%i6) units (foo * bar);
                                        kg m
          (%o6)                         ----
                                         s
          (%i7) units (foo / bar);
                                        kg s
          (%o7)                         ----
                                         m
          (%i8) units (foo^2);
                                           2
          (%o8)                          kg

 -- Function: declare_units (<a>, <u>)

     Declares that ‘units’ should return units <u> for <a>, where <u> is
     an expression.  This function should be loaded with ‘load
     ("ezunits")’.

     Example:

          (%i1) load ("ezunits")$
          (%i2) units (aa);
          (%o2)                           1
          (%i3) declare_units (aa, J);
          (%o3)                           J
          (%i4) units (aa);
          (%o4)                           J
          (%i5) units (aa^2);
                                          2
          (%o5)                          J
          (%i6) foo : 100 ` kg;
          (%o6)                       100 ` kg
          (%i7) units (aa * foo);
          (%o7)                         kg J

 -- Function: qty (<x>)

     Returns the nondimensional part of a dimensional quantity <x>, or
     returns <x> if <x> is nondimensional.  <x> may be a literal
     dimensional expression a ` b, a symbol with declared quantity, or
     an expression containing either or both of those.

     This function should be loaded with ‘load ("ezunits")’.

     Example:

          (%i1) load ("ezunits")$
          (%i2) foo : 100 ` kg;
          (%o2)                       100 ` kg
          (%i3) qty (foo);
          (%o3)                          100
          (%i4) bar : v ` m/s;
                                            m
          (%o4)                         v ` -
                                            s
          (%i5) foo * bar;
                                            kg m
          (%o5)                     100 v ` ----
                                             s
          (%i6) qty (foo * bar);
          (%o6)                         100 v

 -- Function: declare_qty (<a>, <x>)

     Declares that ‘qty’ should return <x> for symbol <a>, where <x> is
     a nondimensional quantity.  This function should be loaded with
     ‘load ("ezunits")’.

     Example:

          (%i1) load ("ezunits")$
          (%i2) declare_qty (aa, xx);
          (%o2)                          xx
          (%i3) qty (aa);
          (%o3)                          xx
          (%i4) qty (aa^2);
                                           2
          (%o4)                          xx
          (%i5) foo : 100 ` kg;
          (%o5)                       100 ` kg
          (%i6) qty (aa * foo);
          (%o6)                        100 xx

 -- Function: unitp (<x>)

     Returns ‘true’ if <x> is a literal dimensional expression, a symbol
     declared dimensional, or an expression in which the main operator
     is declared dimensional.  ‘unitp’ returns ‘false’ otherwise.

     ‘load ("ezunits")’ loads this function.

     Examples:

     ‘unitp’ applied to a literal dimensional expression.

          (%i1) load ("ezunits")$
          (%i2) unitp (100 ` kg);
          (%o2)                         true

     ‘unitp’ applied to a symbol declared dimensional.

          (%i1) load ("ezunits")$
          (%i2) unitp (foo);
          (%o2)                         false
          (%i3) declare (foo, dimensional);
          (%o3)                         done
          (%i4) unitp (foo);
          (%o4)                         true

     ‘unitp’ applied to an expression in which the main operator is
     declared dimensional.

          (%i1) load ("ezunits")$
          (%i2) unitp (bar (x, y, z));
          (%o2)                         false
          (%i3) declare (bar, dimensional);
          (%o3)                         done
          (%i4) unitp (bar (x, y, z));
          (%o4)                         true

 -- Function: declare_unit_conversion (<u> = <v>, ...)

     Appends equations <u> = <v>, ...  to the list of unit conversions
     known to the unit conversion operator ``.  <u> and <v> are both
     multiplicative terms, in which any variables are units, or both
     literal dimensional expressions.

     At present, it is necessary to express conversions such that the
     left-hand side of each equation is a simple unit (not a
     multiplicative expression) or a literal dimensional expression with
     the quantity equal to 1 and the unit being a simple unit.  This
     limitation might be relaxed in future versions.

     ‘known_unit_conversions’ is the list of known unit conversions.

     This function should be loaded with ‘load ("ezunits")’.

     Examples:

     Unit conversions expressed by equations of multiplicative terms.

          (%i1) load ("ezunits")$
          (%i2) declare_unit_conversion (nautical_mile = 1852 * m,
                                         fortnight = 14 * day);
          (%o2)                         done
          (%i3) 100 ` nautical_mile / fortnight `` m/s;
          Computing conversions to base units; may take a moment.
                                      463    m
          (%o3)                       ---- ` -
                                      3024   s

     Unit conversions expressed by equations of literal dimensional
     expressions.

          (%i1) load ("ezunits")$
          (%i2) declare_unit_conversion (1 ` fluid_ounce = 2 ` tablespoon);
          (%o2)                         done
          (%i3) declare_unit_conversion (1 ` tablespoon = 3 ` teaspoon);
          (%o3)                         done
          (%i4) 15 ` fluid_ounce `` teaspoon;
          Computing conversions to base units; may take a moment.
          (%o4)                     90 ` teaspoon

 -- Function: declare_dimensions (<a_1>, <d_1>, ..., <a_n>, <d_n>)

     Declares <a_1>, ..., <a_n> to have dimensions <d_1>, ..., <d_n>,
     respectively.

     Each <a_k> is a symbol or a list of symbols.  If it is a list, then
     every symbol in <a_k> is declared to have dimension <d_k>.

     ‘load ("ezunits")’ loads these functions.

     Examples:

          (%i1) load ("ezunits") $
          (%i2) declare_dimensions ([x, y, z], length, [t, u], time);
          (%o2)                         done
          (%i3) dimensions (y^2/u);
                                             2
                                       length
          (%o3)                        -------
                                        time
          (%i4) fundamental_units (y^2/u);
          0 errors, 0 warnings
                                          2
                                         m
          (%o4)                          --
                                         s

 -- Function: remove_dimensions (<a_1>, ..., <a_n>)

     Reverts the effect of ‘declare_dimensions’.  This function should
     be loaded with ‘load ("ezunits")’.

 -- Function: declare_fundamental_dimensions (<d_1>, <d_2>, <d_3>, ...)
 -- Function: remove_fundamental_dimensions (<d_1>, <d_2>, <d_3>, ...)
 -- Global variable: fundamental_dimensions

     ‘declare_fundamental_dimensions’ declares fundamental dimensions.
     Symbols <d_1>, <d_2>, <d_3>, ...  are appended to the list of
     fundamental dimensions, if they are not already on the list.

     ‘remove_fundamental_dimensions’ reverts the effect of
     ‘declare_fundamental_dimensions’.

     ‘fundamental_dimensions’ is the list of fundamental dimensions.  By
     default, the list comprises several physical dimensions.

     ‘load ("ezunits")’ loads these functions.

     Examples:

          (%i1) load ("ezunits") $
          (%i2) fundamental_dimensions;
          (%o2) [length, mass, time, current, temperature, quantity]
          (%i3) declare_fundamental_dimensions (money, cattle, happiness);
          (%o3)                         done
          (%i4) fundamental_dimensions;
          (%o4) [length, mass, time, current, temperature, quantity,
                                                  money, cattle, happiness]
          (%i5) remove_fundamental_dimensions (cattle, happiness);
          (%o5)                         done
          (%i6) fundamental_dimensions;
          (%o6) [length, mass, time, current, temperature, quantity, money]

 -- Function: declare_fundamental_units (<u_1>, <d_1>, ..., <u_n>,
          <d_n>)
 -- Function: remove_fundamental_units (<u_1>, ..., <u_n>)

     ‘declare_fundamental_units’ declares <u_1>, ..., <u_n> to have
     dimensions <d_1>, ..., <d_n>, respectively.  All arguments must be
     symbols.

     After calling ‘declare_fundamental_units’, ‘dimensions(<u_k>)’
     returns <d_k> for each argument <u_1>, ..., <u_n>, and
     ‘fundamental_units(<d_k>)’ returns <u_k> for each argument <d_1>,
     ..., <d_n>.

     ‘remove_fundamental_units’ reverts the effect of
     ‘declare_fundamental_units’.

     ‘load ("ezunits")’ loads these functions.

     Examples:

          (%i1) load ("ezunits") $
          (%i2) declare_fundamental_dimensions (money, cattle, happiness);
          (%o2)                         done
          (%i3) declare_fundamental_units (dollar, money, goat, cattle,
                                           smile, happiness);
          (%o3)                 [dollar, goat, smile]
          (%i4) dimensions (100 ` dollar/goat/km^2);
                                       money
          (%o4)                    --------------
                                                2
                                   cattle length
          (%i5) dimensions (x ` smile/kg);
                                      happiness
          (%o5)                       ---------
                                        mass
          (%i6) fundamental_units (money*cattle/happiness);
          0 errors, 0 warnings
                                     dollar goat
          (%o6)                      -----------
                                        smile

 -- Function: dimensions (<x>)
 -- Function: dimensions_as_list (<x>)

     ‘dimensions’ returns the dimensions of the dimensional quantity <x>
     as an expression comprising products and powers of base dimensions.

     ‘dimensions_as_list’ returns the dimensions of the dimensional
     quantity <x> as a list, in which each element is an integer which
     indicates the power of the corresponding base dimension in the
     dimensions of <x>.

     ‘load ("ezunits")’ loads these functions.

     Examples:

          (%i1) load ("ezunits")$
          (%i2) dimensions (1000 ` kg*m^2/s^3);
                                          2
                                    length  mass
          (%o2)                     ------------
                                           3
                                       time
          (%i3) declare_units (foo, acre*ft/hour);
                                       acre ft
          (%o3)                        -------
                                        hour
          (%i4) dimensions (foo);
                                             3
                                       length
          (%o4)                        -------
                                        time

          (%i1) load ("ezunits")$
          (%i2) fundamental_dimensions;
          (%o2)  [length, mass, time, charge, temperature, quantity]
          (%i3) dimensions_as_list (1000 ` kg*m^2/s^3);
          (%o3)                 [2, 1, - 3, 0, 0, 0]
          (%i4) declare_units (foo, acre*ft/hour);
                                       acre ft
          (%o4)                        -------
                                        hour
          (%i5) dimensions_as_list (foo);
          (%o5)                 [3, 0, - 1, 0, 0, 0]

 -- Function: fundamental_units
          fundamental_units (<x>)
          fundamental_units ()

     ‘fundamental_units(<x>)’ returns the units associated with the
     fundamental dimensions of <x>.  as determined by ‘dimensions(<x>)’.

     <x> may be a literal dimensional expression a ` b, a symbol with
     declared units via ‘declare_units’, or an expression containing
     either or both of those.

     ‘fundamental_units()’ returns the list of all known fundamental
     units, as declared by ‘declare_fundamental_units’.

     ‘load ("ezunits")’ loads this function.

     Examples:

          (%i1) load ("ezunits")$
          (%i2) fundamental_units ();
          (%o2)                 [m, kg, s, A, K, mol]
          (%i3) fundamental_units (100 ` mile/hour);
                                          m
          (%o3)                           -
                                          s
          (%i4) declare_units (aa, g/foot^2);
                                          g
          (%o4)                         -----
                                            2
                                        foot
          (%i5) fundamental_units (aa);
                                         kg
          (%o5)                          --
                                          2
                                         m

 -- Function: dimensionless (<L>)

     Returns a basis for the dimensionless quantities which can be
     formed from a list <L> of dimensional quantities.

     ‘load ("ezunits")’ loads this function.

     Examples:

          (%i1) load ("ezunits") $
          (%i2) dimensionless ([x ` m, y ` m/s, z ` s]);
          0 errors, 0 warnings
          0 errors, 0 warnings
                                         y z
          (%o2)                         [---]
                                          x

     Dimensionless quantities derived from fundamental physical
     quantities.  Note that the first element on the list is
     proportional to the fine-structure constant.

          (%i1) load ("ezunits") $
          (%i2) load ("physical_constants") $
          (%i3) dimensionless([%h_bar, %m_e, %m_P, %%e, %c, %e_0]);
          0 errors, 0 warnings
          0 errors, 0 warnings
                                        2
                                     %%e        %m_e
          (%o3)                [--------------, ----]
                                %c %e_0 %h_bar  %m_P

 -- Function: natural_unit (<expr>, [<v_1>, ..., <v_n>])

     Finds exponents <e_1>, ..., <e_n> such that ‘dimension(<expr>) =
     dimension(<v_1>^<e_1> ... <v_n>^<e_n>)’.

     ‘load ("ezunits")’ loads this function.

     Examples:


File: maxima.info,  Node: Package f90,  Next: Package finance,  Prev: Package ezunits,  Up: Top

60 Package f90
**************

* Menu:

* Functions for f90::


File: maxima.info,  Node: Functions for f90,  Prev: Package f90,  Up: Package f90

60.1 Package f90
================

 -- Option variable: f90_output_line_length_max
     Default value: 65

     ‘f90_output_line_length_max’ is the maximum number of characters of
     Fortran code which are output by ‘f90’ per line.  Longer lines of
     code are divided, and printed with an ampersand ‘&’ at the end of
     an output line and an ampersand at the beginning of the following
     line.

     ‘f90_output_line_length_max’ must be a positive integer.

     Example:

          (%i1) load ("f90")$
          (%i2) foo : expand ((xxx + yyy + 7)^4);
                   4            3         3        2    2             2
          (%o2) yyy  + 4 xxx yyy  + 28 yyy  + 6 xxx  yyy  + 84 xxx yyy
                    2        3             2
           + 294 yyy  + 4 xxx  yyy + 84 xxx  yyy + 588 xxx yyy + 1372 yyy
                4         3          2
           + xxx  + 28 xxx  + 294 xxx  + 1372 xxx + 2401
          (%i3) f90_output_line_length_max;
          (%o3)                          65
          (%i4) f90 ('foo = foo);
          foo = yyy**4+4*xxx*yyy**3+28*yyy**3+6*xxx**2*yyy**2+84*xxx*yyy**2&
          &+294*yyy**2+4*xxx**3*yyy+84*xxx**2*yyy+588*xxx*yyy+1372*yyy+xxx**&
          &4+28*xxx**3+294*xxx**2+1372*xxx+2401
          (%o4)                         false
          (%i5) f90_output_line_length_max : 40 $
          (%i6) f90 ('foo = foo);
          foo = yyy**4+4*xxx*yyy**3+28*yyy**3+6*xx&
          &x**2*yyy**2+84*xxx*yyy**2+294*yyy**2+4*x&
          &xx**3*yyy+84*xxx**2*yyy+588*xxx*yyy+1372&
          &*yyy+xxx**4+28*xxx**3+294*xxx**2+1372*xx&
          &x+2401
          (%o6)                         false

 -- Function: f90 (<expr_1>, ..., <expr_n>)

     Prints one or more expressions <expr_1>, ..., <expr_n> as a Fortran
     90 program.  Output is printed to the standard output.

     ‘f90’ prints output in the so-called "free form" input format for
     Fortran 90: there is no special attention to column positions.
     Long lines are split at a fixed width with the ampersand ‘&’
     continuation character; the number of output characters per line,
     not including ampersands, is specified by
     ‘f90_output_line_length_max’.  ‘f90’ outputs an ampersand at the
     end of a split line and another at the beginning of the next line.

     ‘load("f90")’ loads this function.  See also the function *note
     fortran::.

     Examples:

          (%i1) load ("f90")$
          (%i2) foo : expand ((xxx + yyy + 7)^4);
                   4            3         3        2    2             2
          (%o2) yyy  + 4 xxx yyy  + 28 yyy  + 6 xxx  yyy  + 84 xxx yyy
                    2        3             2
           + 294 yyy  + 4 xxx  yyy + 84 xxx  yyy + 588 xxx yyy + 1372 yyy
                4         3          2
           + xxx  + 28 xxx  + 294 xxx  + 1372 xxx + 2401
          (%i3) f90 ('foo = foo);
          foo = yyy**4+4*xxx*yyy**3+28*yyy**3+6*xxx**2*yyy**2+84*xxx*yyy**2&
          &+294*yyy**2+4*xxx**3*yyy+84*xxx**2*yyy+588*xxx*yyy+1372*yyy+xxx**&
          &4+28*xxx**3+294*xxx**2+1372*xxx+2401
          (%o3)                         false

     Multiple expressions.  Capture standard output into a file via the
     ‘with_stdout’ function.

          (%i1) load ("f90")$
          (%i2) foo : sin (3*x + 1) - cos (7*x - 2);
          (%o2)              sin(3 x + 1) - cos(7 x - 2)
          (%i3) with_stdout ("foo.f90",
                             f90 (x=0.25, y=0.625, 'foo=foo, 'stop, 'end));
          (%o3)                         false
          (%i4) printfile ("foo.f90");
          x = 0.25
          y = 0.625
          foo = sin(3*x+1)-cos(7*x-2)
          stop
          end
          (%o4)                        foo.f90


File: maxima.info,  Node: Package finance,  Next: Package format,  Prev: Package f90,  Up: Top

61 Package finance
******************

* Menu:

* Introduction to finance::
* Functions and Variables for finance::


File: maxima.info,  Node: Introduction to finance,  Next: Functions and Variables for finance,  Prev: Package finance,  Up: Package finance

61.1 Introduction to finance
============================

This is the Finance Package (Ver 0.1).

   In all the functions, <rate> is the compound interest rate, <num> is
the number of periods and must be positive and <flow> refers to cash
flow so if you have an Output the flow is negative and positive for
Inputs.

   Note that before using the functions defined in this package, you
have to load it writing ‘load("finance")$’.

   Author: Nicolas Guarin Zapata.


File: maxima.info,  Node: Functions and Variables for finance,  Prev: Introduction to finance,  Up: Package finance

61.2 Functions and Variables for finance
========================================

 -- Function: days360 (<year1>,<month1>,<day1>,<year2>,<month2>,<day2>)

     Calculates the distance between 2 dates, assuming 360 days years,
     30 days months.

     Example:

          (%i1) load("finance")$
          (%i2) days360(2008,12,16,2007,3,25);
          (%o2)                      - 621

 -- Function: fv (<rate>,<PV>,<num>)

     We can calculate the future value of a Present one given a certain
     interest rate.  <rate> is the interest rate, <PV> is the present
     value and <num> is the number of periods.

     Example:

          (%i1) load("finance")$
          (%i2) fv(0.12,1000,3);
          (%o2)                     1404.928

 -- Function: pv (<rate>,<FV>,<num>)

     We can calculate the present value of a Future one given a certain
     interest rate.  <rate> is the interest rate, <FV> is the future
     value and <num> is the number of periods.

     Example:

          (%i1) load("finance")$
          (%i2) pv(0.12,1000,3);
          (%o2)                711.7802478134108

 -- Function: graph_flow (<val>)

     Plots the money flow in a time line, the positive values are in
     blue and upside; the negative ones are in red and downside.  The
     direction of the flow is given by the sign of the value.  <val> is
     a list of flow values.

     Example:

          (%i1) load("finance")$
          (%i2) graph_flow([-5000,-3000,800,1300,1500,2000])$

 -- Function: annuity_pv (<rate>,<PV>,<num>)

     We can calculate the annuity knowing the present value (like an
     amount), it is a constant and periodic payment.  <rate> is the
     interest rate, <PV> is the present value and <num> is the number of
     periods.

     Example:

          (%i1) load("finance")$
          (%i2) annuity_pv(0.12,5000,10);
          (%o2)                884.9208207992202

 -- Function: annuity_fv (<rate>,<FV>,<num>)

     We can calculate the annuity knowing the desired value (future
     value), it is a constant and periodic payment.  <rate> is the
     interest rate, <FV> is the future value and <num> is the number of
     periods.

     Example:

          (%i1) load("finance")$
          (%i2) annuity_fv(0.12,65000,10);
          (%o2)                3703.970670389863

 -- Function: geo_annuity_pv (<rate>,<growing_rate>,<PV>,<num>)

     We can calculate the annuity knowing the present value (like an
     amount), in a growing periodic payment.  <rate> is the interest
     rate, <growing_rate> is the growing rate, <PV> is the present value
     and <num> is the number of periods.

     Example:

          (%i1) load("finance")$
          (%i2) geo_annuity_pv(0.14,0.05,5000,10);
          (%o2)                802.6888176505123

 -- Function: geo_annuity_fv (<rate>,<growing_rate>,<FV>,<num>)

     We can calculate the annuity knowing the desired value (future
     value), in a growing periodic payment.  <rate> is the interest
     rate, <growing_rate> is the growing rate, <FV> is the future value
     and <num> is the number of periods.

     Example:

          (%i1) load("finance")$
          (%i2) geo_annuity_fv(0.14,0.05,5000,10);
          (%o2)                216.5203395312695

 -- Function: amortization (<rate>,<amount>,<num>)

     Amortization table determined by a specific rate.  <rate> is the
     interest rate, <amount> is the amount value, and <num> is the
     number of periods.

     Example:

          (%i1) load("finance")$
          (%i2) amortization(0.05,56000,12)$
                "n"    "Balance"     "Interest"   "Amortization"  "Payment"
               0.000     56000.000         0.000         0.000         0.000
               1.000     52481.777      2800.000      3518.223      6318.223
               2.000     48787.643      2624.089      3694.134      6318.223
               3.000     44908.802      2439.382      3878.841      6318.223
               4.000     40836.019      2245.440      4072.783      6318.223
               5.000     36559.597      2041.801      4276.422      6318.223
               6.000     32069.354      1827.980      4490.243      6318.223
               7.000     27354.599      1603.468      4714.755      6318.223
               8.000     22404.106      1367.730      4950.493      6318.223
               9.000     17206.088      1120.205      5198.018      6318.223
              10.000     11748.170       860.304      5457.919      6318.223
              11.000      6017.355       587.408      5730.814      6318.223
              12.000         0.000       300.868      6017.355      6318.223

 -- Function: arit_amortization (<rate>,<increment>,<amount>,<num>)

     The amortization table determined by a specific rate and with
     growing payment can be calculated by ‘arit_amortization’.  Notice
     that the payment is not constant, it presents an arithmetic
     growing, increment is then the difference between two consecutive
     rows in the "Payment" column.  <rate> is the interest rate,
     <increment> is the increment, <amount> is the amount value, and
     <num> is the number of periods.

     Example:

          (%i1) load("finance")$
          (%i2) arit_amortization(0.05,1000,56000,12)$
                "n"    "Balance"     "Interest"   "Amortization"  "Payment"
               0.000     56000.000         0.000         0.000         0.000
               1.000     57403.679      2800.000     -1403.679      1396.321
               2.000     57877.541      2870.184      -473.863      2396.321
               3.000     57375.097      2893.877       502.444      3396.321
               4.000     55847.530      2868.755      1527.567      4396.321
               5.000     53243.586      2792.377      2603.945      5396.321
               6.000     49509.443      2662.179      3734.142      6396.321
               7.000     44588.594      2475.472      4920.849      7396.321
               8.000     38421.703      2229.430      6166.892      8396.321
               9.000     30946.466      1921.085      7475.236      9396.321
              10.000     22097.468      1547.323      8848.998     10396.321
              11.000     11806.020      1104.873     10291.448     11396.321
              12.000        -0.000       590.301     11806.020     12396.321

 -- Function: geo_amortization (<rate>,<growing_rate>,<amount>,<num>)

     The amortization table determined by rate, amount, and number of
     periods can be found by ‘geo_amortization’.  Notice that the
     payment is not constant, it presents a geometric growing,
     <growing_rate> is then the quotient between two consecutive rows in
     the "Payment" column.  <rate> is the interest rate, <amount> is the
     amount value, and <num> is the number of periods.

     Example:

          (%i1) load("finance")$
          (%i2) geo_amortization(0.05,0.03,56000,12)$
                "n"    "Balance"     "Interest"   "Amortization"  "Payment"
               0.000     56000.000         0.000         0.000         0.000
               1.000     53365.296      2800.000      2634.704      5434.704
               2.000     50435.816      2668.265      2929.480      5597.745
               3.000     47191.930      2521.791      3243.886      5765.677
               4.000     43612.879      2359.596      3579.051      5938.648
               5.000     39676.716      2180.644      3936.163      6116.807
               6.000     35360.240      1983.836      4316.475      6300.311
               7.000     30638.932      1768.012      4721.309      6489.321
               8.000     25486.878      1531.947      5152.054      6684.000
               9.000     19876.702      1274.344      5610.176      6884.520
              10.000     13779.481       993.835      6097.221      7091.056
              11.000      7164.668       688.974      6614.813      7303.787
              12.000         0.000       358.233      7164.668      7522.901

 -- Function: saving (<rate>,<amount>,<num>)

     The table that represents the values in a constant and periodic
     saving can be found by ‘saving’.  <amount> represents the desired
     quantity and num the number of periods to save.

     Example:

          (%i1) load("finance")$
          (%i2) saving(0.15,12000,15)$
                "n"    "Balance"     "Interest"   "Payment"
               0.000         0.000         0.000         0.000
               1.000       252.205         0.000       252.205
               2.000       542.240        37.831       252.205
               3.000       875.781        81.336       252.205
               4.000      1259.352       131.367       252.205
               5.000      1700.460       188.903       252.205
               6.000      2207.733       255.069       252.205
               7.000      2791.098       331.160       252.205
               8.000      3461.967       418.665       252.205
               9.000      4233.467       519.295       252.205
              10.000      5120.692       635.020       252.205
              11.000      6141.000       768.104       252.205
              12.000      7314.355       921.150       252.205
              13.000      8663.713      1097.153       252.205
              14.000     10215.474      1299.557       252.205
              15.000     12000.000      1532.321       252.205

 -- Function: npv (<rate>,<val>)

     Calculates the present value of a value series to evaluate the
     viability in a project.  <val> is a list of varying cash flows.

     Example:

          (%i1) load("finance")$
          (%i2) npv(0.25,[100,500,323,124,300]);
          (%o2)                714.4703999999999

 -- Function: irr (<val>,<IO>)

     IRR (Internal Rate of Return) is the value of rate which makes Net
     Present Value zero.  <flowValues> is a list of varying cash flows,
     <I0> is the initial investment.

     Example:

          (%i1) load("finance")$
          (%i2) res:irr([-5000,0,800,1300,1500,2000],0)$
          (%i3) rhs(res[1][1]);
          (%o3)                .03009250374237132

 -- Function: benefit_cost (<rate>,<input>,<output>)

     Calculates the ratio Benefit/Cost.  Benefit is the Net Present
     Value (NPV) of the inputs, and Cost is the Net Present Value (NPV)
     of the outputs.  Notice that if there is not an input or output
     value in a specific period, the input/output would be a zero for
     that period.  <rate> is the interest rate, <input> is a list of
     input values, and <output> is a list of output values.

     Example:

          (%i1) load("finance")$
          (%i2) benefit_cost(0.24,[0,300,500,150],[100,320,0,180]);
          (%o2)               1.427249324905784


File: maxima.info,  Node: Package format,  Next: Package fractals,  Prev: Package finance,  Up: Top

62 Package format
*****************

* Menu:

* Introduction to format::
* Functions and Variables for format::


File: maxima.info,  Node: Introduction to format,  Next: Functions and Variables for format

62.1 Introduction to format
===========================

The ‘format’ package was written by Bruce R. Miller, NIST
(miller-at-cam.nist.gov).

   ‘format’ is a package for formatting algebraic expressions in Maxima.
It provides facilities for user-directed hierarchical structuring of
expressions, as well as for directing simplifications to selected
subexpressions.  It emphasizes a semantic rather than syntactic
description of the desired form.  The package also provides utilities
for obtaining efficiently the coefficients of polynomials, trigonometric
sums and power series.

   In a general purpose Computer Algebra System (CAS), any particular
mathematical expression can take on a variety of forms: expanded form,
factored form or anything in between.  Each form may have advantages; a
given form may be more compact than another, or allow clear expression
of certain algorithms.  Or it may simply be more informative,
particularly if it has physical significance.  A CAS contains many tools
for transforming expressions.  However, most are like Maxima's ‘factor’
and ‘expand’, operating only on the entire expression or its top level.
At the other extreme are operations like ‘substpart’ which extract a
specific part of an expression, then transform and replace it.
Unfortunately, the means of specifying the piece of interest is purely
syntactic, requiring the user to keep close watch on the form of the
arguments to avoid error.

   The package described here gives users of Maxima more control over
the structure of expressions, and it does so using a more semantic,
almost algebraic, language describing the desired structure.  It also
provides a semantic means of addressing parts of an expression for
particular simplifications.  For example, to rearrange an expression
into a series in ‘eps’ through order 5, whose terms will be polynomials
in ‘x’ and ‘y’, whose coefficients, in turn, will be trigonometric sums
in ‘l’ and ‘g’ with factored coefficients one uses the command:

‘format(foo; %series(eps; 5); %poly(x; y);%trig(l; g); %factor);’

The principal tool, ‘format’, is described in section *note Functions
and Variables for format::.  It uses procedures in ‘coeflist’ which
obtain coefficients of polynomials, trigonometric sums and power series.


File: maxima.info,  Node: Functions and Variables for format,  Prev: Introduction to format

62.2 Functions and Variables for format
=======================================

 -- Function: format (<expr>, <template_{1}>, ...)
     Each ‘template’ indicates the desired form for an expression;
     either the expected form or that into which it will be transformed.
     At the same time, the indicated form implies a set of _pieces_; the
     next template in the chain applies to those pieces.  For example,
     ‘%poly(x)’ specifies the transformation into a polynomial in ‘x’,
     with the pieces being the coefficients.  The passive ‘%frac’ treats
     the expression as a fraction; the pieces are the numerator and
     denominator.  Whereas the next template formats all pieces of the
     previous layer, positional _subtemplates_ may be used to specify
     formats for each piece individually.  This is most useful when the
     pieces have unique roles and need to be treated differently, such
     as a fraction's numerator and denominator.

The full syntax of a template is

   ‘keyword (parameter ; ...)[subtemplate ; ...]’

   The recognized keywords are described below under *note Template
keywords::.  The parameters (if not needed) and subtemplates (along with
parentheses and brackets) are optional.

   In addition to the keyword templates, arithmetic patterns are
recognized.  This is an expression involving addition, multiplication
and exponentiation containing a single instance of a keyword template.
In effect, the system 'solves' the expression to be formatted for the
corresponding part, formats it accordingly and reinserts it.  For
example, ‘format(X,a+%factor)’ is equivalent to ‘a+factor(X-a)’.  Any
other template is assumed to be a function to be applied to the
expression; the result is then formatted according to the rest of the
template chain.

   Examples for general restructuring:
     (%i1) load("format")$
     (%i2) format((a+b*x)*(c-x)^2,%poly(x),factor);
                 3                2                        2
     (%o2)    b x  - (2 b c - a) x  + c (b c - 2 a) x + a c
     (%i3) format((1+2*eps*(q+r*cos(g))^2)^4,%series(eps,2),%trig(g),factor);
                        2      2                2
     (%o3) 1 + eps (4 (r  + 2 q ) + 4 cos(2 g) r  + 16 cos(g) q r)
           2        4       2  2      4                4
      + eps  (3 (3 r  + 24 q  r  + 8 q ) + 3 cos(4 g) r
                       3                     2      2
      + 24 cos(3 g) q r  + 24 cos(g) q r (3 r  + 4 q )
                     2   2      2
      + 12 cos(2 g) r  (r  + 6 q )) + . . .
     (%i4) format((1+2*a+a^2)*b + a*(1+2*b+b^2),%sum,%product,%factor);
                                   2          2
     (%o4)                a (b + 1)  + (a + 1)  b
     (%i5) format(expand((a+x)^3-a^3),%f-a^3);
                                      3    3
     (%o5)                     (x + a)  - a

62.2.1 Template keywords
------------------------

Keywords come in several _classes_: Algebraic, Sums, Products,
Fractions, Complex, Bags, General, Targeting, Control, Subtemplate Aids,
and Convenience.

   A few remarks about keywords: A passive keyword does not transform
the expression but treats it as a sum, fraction or whatever.  The order
of the pieces corresponds to the internal ordering; subtemplate usage
may be awkward.  See the documentation of ‘coerce_bag’ for a description
of the coercions used.  Targeting templates are basically shorthand
equivalents of structuring templates using subtemplates.

Template(w/abbrev.)    Coersion to                   Pieces and Ordering
-----------------------------------------------------------------------------------
*Class: _Algebraic_*
‘%poly(<x>_{1},...),   polynomial in <x_{i}>         coefficients (ascending
%p’                                                  exps.)
‘%series(_eps_,_n_),   series in _eps_ through       coefficients (ascending
%s’                    order _n_                     exps.)
‘%Taylor(_eps_,_n_)’   Taylor in _eps_ through       coefficients (ascending
                       order _n_                     exps.)
‘%monicpoly(<x_{1}>,...),%mp’monic polynomial in <x_{i}>leading coef then coefs
‘%trig(<x_{1}>,...),   trigonometric sum in          ‘sin’ coefs (ascending),
%t’                    <x_{i}>                       then ‘cos’
‘%coeff(<v>,<n>)’      polynomial in <v>             coefficient of <v^{n}> and
                                                     remainder


Template(w/abbrev.)    Coersion to                   Pieces and Ordering
-----------------------------------------------------------------------------------
*Class: _Sums_*
‘%sum’                 _passive_                     terms (‘inpart’ order)
‘%partfrac(<x>),       partial fraction decomp in    terms (‘inpart’ order)
%pf’                   <x>


Template(w/abbrev.)    Coersion to                   Pieces and Ordering
-----------------------------------------------------------------------------------
*Class: _Products_*
‘%product, %prod’      _passive_                     factors (‘inpart’ order)
‘%factor, %f’          factored form                 factors (‘inpart’ order)
‘%factor(_minpoly_),   factored with element         factors (‘inpart’ order)
%f’                    adjoined
‘%sqfr, %sf’           square-free factored form     factors (‘inpart’ order)


Template(w/abbrev.)    Coersion to                   Pieces and Ordering
-----------------------------------------------------------------------------------
*Class: _Fractions_*
‘%frac’                _passive_                     numerator and denominator
‘%ratsimp, %r’         rationally simplified         numerator and denominator


Template(w/abbrev.)    Coersion to                   Pieces and Ordering
-----------------------------------------------------------------------------------
*Class: _Complex_*
‘%rectform, %g’        gaussian form                 real and imaginary parts
‘%polarform’           polar form                    magnitude and phase


Template(w/abbrev.)    Coersion to                   Pieces and Ordering
-----------------------------------------------------------------------------------
*Class: _Bags_*
‘%equation, %eq’       equation                      l.h.s.  and r.h.s.
‘%relation(<r>),       relation; <r> in              l.h.s.  and r.h.s.
%rel’                  ‘(=,>,>=,<,<=,!=)’
‘%list’                list                          elements
‘%matrix’              matrix                        rows (use ‘%list’ for
                                                     elements)


Template(w/abbrev.)    Coersion to                   Pieces and Ordering
-----------------------------------------------------------------------------------
*Class: _General_*
‘%expression, %expr’   _passive_                     the operands (‘inpart’
                                                     order)
‘%preformat(<T_{1}>,...)’format accord.  to chain    the result, not the parts
                       <T_{i}>


Template(w/abbrev.)    Function
--------------------------------------------------------------------------
*Class: _Targeting_*
‘%arg(n)’              formats the ‘n’-th argument
‘%lhs(<r>)’            formats the l.h.s.  of an eqn.  or relation
                       (default '=')
‘%rhs(<r>)’            formats the l.h.s.  of an eqn.
‘%element(i,...),      formats an element of a matrix
%el’
‘%num, %denom’         formats the numerator or denominator of a
                       fraction
‘%match(<P>)’          formats all subexpressions for which <P(_expr_)>
                       returns true


Template(w/abbrev.)    Function
--------------------------------------------------------------------------
*Class: _Control_*
‘%if(<P_{1}>,...)[<T_{1}>,...,<T_{n+1}>]’Find first <P_{i}(_expr_)> → ‘true’, then format
                       _expr_ using <T_{i}>, else <T_{n+1}>


Template(w/abbrev.)    Function
--------------------------------------------------------------------------
*Class: _Subtemplate
Aids_*
‘%noop’                does nothing; used to fill a subtemplate slot
‘[<T_{1}>,<T_{2}>,...]’creates a template chain where an individual
                       template was expected
‘%ditto(<T>)’          repeats the template so that it applies to
                       following pices


Template(w/abbrev.)    Function
--------------------------------------------------------------------------
*Class:
_Convenience_*
‘%subst(_eqns_,...)’   substitutes _eqns_ into expression; result is
                       formatted at next layer
‘%ratsubst(_eqns_,...)’‘lratsubst’'s _eqns_ into expression; result is
                       formatted at next layer

   Example with simplification on subexpression:
     (%i1) load("format")$
     (%i2) foo:x^2*sin(y)^4-2*x^2*sin(y)^2+x^4*cos(y)^4-2*x^4*cos(y)^2+x^4+x^2+1$
     (%i3) trigsimp(foo);
                   4    2     4         4    2       4
     (%o3)       (x  + x ) cos (y) - 2 x  cos (y) + x  + 1
     (%i4) format(foo,%p(x),trigsimp);
                         4    4       2    4
     (%o4)              x  sin (y) + x  cos (y) + 1
     (%i5) format([a=b,c=d,e=f],%equation);
     (%o5)                 [a, c, e] = [b, d, f]
     (%i6) format(%,%list);
     (%o6)                 [a = b, c = d, e = f]
     (%i7) m1:matrix([a^2+2*a+1=q,b^2+2*b+1=r], [c^2+2*c+1=s,d^2+2*d+1=t])$
     (%i8) format(m1,%equation,%matrix[%noop,%list[%noop,%factor]]);
                 [  2             2           ]
                 [ a  + 2 a + 1  b  + 2 b + 1 ]   [ q  r ]
     (%o8)       [                            ] = [      ]
                 [  2                     2   ]   [ s  t ]
                 [ c  + 2 c + 1    (d + 1)    ]
   The following examples illustrate the usage with 'bags.'
     (%i1) format([a=b,c=d,e=f],%equation);
     (%o1) [a, c, e] = [b, d, f]
     (%i2) format(%,%list);
     (%o2) [a = b, c = d, e = f]
     (%i3) m1:matrix([a^2+2*a+1=q,b^2+2*b+1=r], [c^2+2*c+1=s,d^2+2*d+1=t])$
     (%i4) format(m1,%equation,%matrix[%noop,%list[%noop,%factor]]);
                        [  2             2           ]
                        [ a  + 2 a + 1  b  + 2 b + 1 ]   [ q  r ]
     (%o4)              [                            ] = [      ]
                        [  2                     2   ]   [ s  t ]
                        [ c  + 2 c + 1    (d + 1)    ]

62.2.2 User defined templates
-----------------------------

New templates can be defined by giving the template keyword the property
‘formatter’; the value should be a function (or lambda expression) of
the expression to be formatted and any parameters for the template.  For
example, ‘%rectform’ and ‘%if’ could be defined as

   ‘put(%rectform,lambda([c],block([r:rectformlist(c)],
      format-piece(r[1]) +%I* format-piece(r[2]))),formatter)’

   ‘put(%if, lambda([x,test],
      if test(x) then format-piece(x,1)
        else
          format-piece(x,2)),formatter)’

Functions used for defining templates are the following.

 -- function: %format_piece (<piece>,<nth>)
     ‘lratsubst’'s ‘eqns’ into expression and the result is formatted at
     the next layer.  Format a given piece of an expression,
     automatically accounting for subtemplates and the remaining
     template chain.  A specific subtemplate, rather than the next one,
     can be selected by specifying <nth>.

 -- function: %coerce_bag (<op>,<expr>)
     Attempts to coerce <expr> into an expression with <op> (one of ‘=,
     #, <, <=, >, >=, [’ or matrix) as the top-level operator.  It
     coerces the expression by swapping operands between layers but only
     if adjacent layers are also lists, matrices or relations.  This
     model assumes that a list of equations, for example, can be viewed
     as an equation whose sides are lists.  Certain combinations,
     particularly those involving inequalities may not be meaningful,
     however, so some caution is advised.

62.2.3 Determining coefficients
-------------------------------

We define the 'algebras' of polynomials, trigonometric sums and power
series to be those expressions that can be cast into the following
forms.

   The variables <v_{i}> may be any atomic expression in the sense of
‘ratvars’.  The shorthands ‘operator(op)’ and ‘match(predicate)’ may be
used to specify all subexpressions having op as an operator, or that
pass the predicate, respectively.

   The coefficients <c_{i}> and <s_{i}> are general Maxima expressions.
In principle they would be independent of the variables <v_{i}>, but in
practice they may contain non-polynomial dependence (or
non-trigonometric, in the trigonometric case).  These non-polynomial
cases would include expressions like ‘(1 + x)^{n}’, where ‘n’ is
symbolic.  Likewise, ‘(x^{a})^{b}’ is, in general, multivalued; unless
‘a = 1’ or ‘b’ is a member of ‘Z’, or ‘radexpand=all’, it will not be
interpreted as ‘x^{ab}’ is a member of *P*. Furthermore, we extend the
algebras to include lists, vectors, matrices and equations, by
interpreting a list of polynomials, say, as a polynomial with lists as
coefficients.

   The exponents <p_{i}> in series are restricted to numbers, but the
exponents <c_{j,i}> and multiples <m_{j,i}> for polynomials and
trigonometric sums may be general expressions (excluding bags).

   The following functions construct a list of the coefficients and
'keys', that is, the exponents or multiples.  Note that these are sparse
representations; no coefficients are zero.

‘coeffs(P,v_{1},...) → [[%poly,v_{1},...],[c_{1},p_{1,1},...],...] ’
‘trig_coeffs(T,v_{1},...) →’
           
‘[[%trig,v_{1},...],[[c_{1},m_{1,1},...],...],[[s_{1},m'_{1,1},...],...]]’
‘series_coeffs(S,v,O) → [[%series,v,O],[c_{1},p_{1}],...,[c_{n},p_{n}]’
‘Taylor_coeffs(S,v,O) → [[%Taylor,v,O],[c_{1},p_{1}],...,[c_{n},p_{n}]’

   The latter two functions both expand an expression through order ‘O’,
but the series version only carries expands arithmetic operations and is
often considerably faster than ‘Taylor_coeffs’.

   Examples:
     (%i1) load("format")$
     (%i2) cl1:coeffs((a+b*x)*(c-x)^2,x);
                            2          2
     (%o2) [[%poly, x], [a c , 0], [b c  - 2 a c, 1], [a - 2 b c, 2],
                                                               [b, 3]]
     (%i3) map('first,rest(coeffs((a+b*x)*(c-x)^2=q0+q1*x+q2*x^2+q3*x^3,x)));
               2          2
     (%o3) [a c  = q0, b c  - 2 a c = q1, a - 2 b c = q2, b = q3]
     (%i4) trig_coeffs(2*(a+cos(x))*cos(x+3*y),x,y);
     (%o4) [[%trig, x, y], [], [[1, 0, 3], [2 a, 1, 3], [1, 2, 3]]]
     (%i5) series_coeffs((a+b*x)*(c-x)^2,x,2);
                                 2          2
     (%o5) [[%series, x, 2], [a c , 0], [b c  - 2 a c, 1],
                                                       [a - 2 b c, 2]]
     (%i6) coeffs((a+b*x)*sin(x),x);
     (%o6)      [[%poly, x], [a sin(x), 0], [b sin(x), 1]]
     (%i7) coeffs((a+log(b)*x)*(c-log(x))^2,operator(log));
                                         2           2
     (%o7) [[%poly, log(x), log(b)], [a c , 0, 0], [c  x, 0, 1],
               [- 2 a c, 1, 0], [- 2 c x, 1, 1], [a, 2, 0], [x, 2, 1]]

62.2.4 Related functions
------------------------

 -- function: get_coef (<clist>,<k_{1}>,...)
     Gets the coefficient from the coefficient list <clist>
     corresponding to the keys <k_{i}>.  The keys are matched to
     variable powers when <clist> is a ‘%poly’, ‘%series’ or ‘%Taylor’
     form.  If <clist> is a ‘%trig’ then <k_{1}> should be ‘sin’ or
     ‘cos’ and the remaining keys are matched to multipliers.

 -- function: uncoef (<clist>)
     Reconstructs the expression from a coefficient list <clist>.  The
     coefficient list can be any of the coefficient list forms.

 -- function: partition_poly (<expr>,<test>,<v_{1}>,...)
     Partitions <expr> into two polynomials; the first is made of those
     monomials for which the function test returns true and the second
     is the remainder.  The test function is called on the powers of the
     <v_{i}>.

 -- function: partition_trig (<expr>,<sintest>,<costest>,<v_{1}>,...)
     Trigonometric analog to partition poly; The functions <sintest> and
     <costest> select sine and cosine terms, respectively; each are
     called on the multipliers of the <v_{i}>.

 -- function: partition_series (<expr>,<test>,<v>,<O>)

 -- function: partition_Taylor (<expr>,<test>,<v>,<O>)
     Analog to ‘partition_poly’ for series.

Example:
     (%i1) load("format")$
     (%i2) partition_poly((a+b*x)*(c-x)^2,'evenp,x);
                           2      2     3       2
     (%o2)   [(a - 2 b c) x  + a c , b x  + (b c  - 2 a c) x]



*Support functions*

 -- function: matching_parts (<expr>,<predicate>,<args>...)
     Returns a list of all subexpressions of <expr> for which the
     application ‘predicate(piece,args ... )’ returns ‘true’.

 -- function: function_calls (<expr>,<functions>...)
     Returns a list of all calls in <expr> involving any of <functions>.

 -- function: function_arguments (<expr>,<functions>...)
     Returns a list of all argument lists for calls to <functions> in
     <expr>.

Examples:
     (%i1) load("format")$
     (%i2) t2:(a+log(b)*x)*(c-log(x))^2$
     (%i3) matching_parts(t2,constantp);
     (%o3)                       [2, - 1]
     (%i4) function_calls(t2,log);
     (%o4)                   [log(x), log(b)]

62.2.5 Implementation
---------------------

Original documentation is located in the share/contrib/format directory
and contains an appendix describing the implementation algorithm in more
detail.


File: maxima.info,  Node: Package fractals,  Next: Package gentran,  Prev: Package format,  Up: Top

63 Package fractals
*******************

* Menu:

* Introduction to fractals::
* Definitions for IFS fractals::
* Definitions for complex fractals::
* Definitions for Koch snowflakes::
* Definitions for Peano maps::


File: maxima.info,  Node: Introduction to fractals,  Next: Definitions for IFS fractals,  Prev: Package fractals,  Up: Package fractals

63.1 Introduction to fractals
=============================

This package defines some well known fractals:

   - with random IFS (Iterated Function System): the Sierpinsky
triangle, a Tree and a Fern

   - Complex Fractals: the Mandelbrot and Julia Sets

   - the Koch snowflake sets

   - Peano maps: the Sierpinski and Hilbert maps

   Author: José Ramírez Labrador.

   For questions, suggestions and bugs, please feel free to contact me
at

   pepe DOT ramirez AAATTT uca DOT es


File: maxima.info,  Node: Definitions for IFS fractals,  Next: Definitions for complex fractals,  Prev: Introduction to fractals,  Up: Package fractals

63.2 Definitions for IFS fractals
=================================

Some fractals can be generated by iterative applications of contractive
affine transformations in a random way; see

   Hoggar S. G., "Mathematics for computer graphics", Cambridge
University Press 1994.

   We define a list with several contractive affine transformations, and
we randomly select the transformation in a recursive way.  The
probability of the choice of a transformation must be related with the
contraction ratio.

   You can change the transformations and find another fractal

 -- Function: sierpinskiale (<n>)

     Sierpinski Triangle: 3 contractive maps; .5 contraction constant
     and translations; all maps have the same contraction ratio.
     Argument <n> must be great enough, 10000 or greater.

     Example:

          (%i1) load("fractals")$
          (%i2) n: 10000$
          (%i3) plot2d([discrete,sierpinskiale(n)], [style,dots])$

 -- Function: treefale (<n>)

     3 contractive maps all with the same contraction ratio.  Argument
     <n> must be great enough, 10000 or greater.

     Example:

          (%i1) load("fractals")$
          (%i2) n: 10000$
          (%i3) plot2d([discrete,treefale(n)], [style,dots])$

 -- Function: fernfale (<n>)

     4 contractive maps, the probability to choice a transformation must
     be related with the contraction ratio.  Argument <n> must be great
     enough, 10000 or greater.

     Example:

          (%i1) load("fractals")$
          (%i2) n: 10000$
          (%i3) plot2d([discrete,fernfale(n)], [style,dots])$


File: maxima.info,  Node: Definitions for complex fractals,  Next: Definitions for Koch snowflakes,  Prev: Definitions for IFS fractals,  Up: Package fractals

63.3 Definitions for complex fractals
=====================================

 -- Function: mandelbrot_set (<x>, <y>)

     Mandelbrot set.

     Example:

     This program is time consuming because it must make a lot of
     operations; the computing time is also related with the number of
     grid points.

          (%i1) load("fractals")$
          (%i2) plot3d (mandelbrot_set, [x, -2.5, 1], [y, -1.5, 1.5],
                          [gnuplot_preamble, "set view map"],
                          [gnuplot_pm3d, true],
                          [grid, 150, 150])$

 -- Function: julia_set (<x>, <y>)

     Julia sets.

     This program is time consuming because it must make a lot of
     operations; the computing time is also related with the number of
     grid points.

     Example:

          (%i1) load("fractals")$
          (%i2) plot3d (julia_set, [x, -2, 1], [y, -1.5, 1.5],
                          [gnuplot_preamble, "set view map"],
                          [gnuplot_pm3d, true],
                          [grid, 150, 150])$

     See also ‘julia_parameter’.

 -- Optional variable: julia_parameter
     Default value: ‘%i’

     Complex parameter for Julia fractals.  Its default value is ‘%i’;
     we suggest the values ‘-.745+%i*.113002’, ‘-.39054-%i*.58679’,
     ‘-.15652+%i*1.03225’, ‘-.194+%i*.6557’ and ‘.011031-%i*.67037’.

 -- Function: julia_sin (<x>, <y>)

     While function ‘julia_set’ implements the transformation
     ‘julia_parameter+z^2’, function ‘julia_sin’ implements
     ‘julia_parameter*sin(z)’.  See source code for more details.

     This program runs slowly because it calculates a lot of sines.

     Example:

     This program is time consuming because it must make a lot of
     operations; the computing time is also related with the number of
     grid points.

          (%i1) load("fractals")$
          (%i2) julia_parameter:1+.1*%i$
          (%i3) plot3d (julia_sin, [x, -2, 2], [y, -3, 3],
                          [gnuplot_preamble, "set view map"],
                          [gnuplot_pm3d, true],
                          [grid, 150, 150])$

     See also ‘julia_parameter’.


File: maxima.info,  Node: Definitions for Koch snowflakes,  Next: Definitions for Peano maps,  Prev: Definitions for complex fractals,  Up: Package fractals

63.4 Definitions for Koch snowflakes
====================================

 -- Function: snowmap (<ent>, <nn>)

     Koch snowflake sets.  Function ‘snowmap’ plots the snow Koch map
     over the vertex of an initial closed polygonal, in the complex
     plane.  Here the orientation of the polygon is important.  Argument
     <nn> is the number of recursive applications of Koch
     transformation; <nn> must be small (5 or 6).

     Examples:

          (%i1) load("fractals")$
          (%i2) plot2d([discrete,
                        snowmap([1,exp(%i*%pi*2/3),exp(-%i*%pi*2/3),1],4)])$
          (%i3) plot2d([discrete,
                        snowmap([1,exp(-%i*%pi*2/3),exp(%i*%pi*2/3),1],4)])$
          (%i4) plot2d([discrete, snowmap([0,1,1+%i,%i,0],4)])$
          (%i5) plot2d([discrete, snowmap([0,%i,1+%i,1,0],4)])$


File: maxima.info,  Node: Definitions for Peano maps,  Prev: Definitions for Koch snowflakes,  Up: Package fractals

63.5 Definitions for Peano maps
===============================

Continuous curves that cover an area.  Warning: the number of points
exponentially grows with <n>.

 -- Function: hilbertmap (<nn>)

     Hilbert map.  Argument <nn> must be small (5, for example).  Maxima
     can crash if <nn> is 7 or greater.

     Example:

          (%i1) load("fractals")$
          (%i2) plot2d([discrete,hilbertmap(6)])$

 -- Function: sierpinskimap (<nn>)

     Sierpinski map.  Argument <nn> must be small (5, for example).
     Maxima can crash if <nn> is 7 or greater.

     Example:

          (%i1) load("fractals")$
          (%i2) plot2d([discrete,sierpinskimap(6)])$


File: maxima.info,  Node: Package gentran,  Next: Package ggf,  Prev: Package fractals,  Up: Top

64 Package gentran
******************

* Menu:

* Introduction to Gentran::
* Functions for Gentran::
* Gentran Mode Switches::
* Gentran Option Variables::
* Gentran Evaluation Forms::


File: maxima.info,  Node: Introduction to Gentran,  Next: Functions for Gentran,  Prev: Package gentran,  Up: Package gentran

64.1 Introduction to Gentran
============================

Original Authors Barbara Gates and Paul Wang

   Gentran is a powerful generator of foreign language code.  Currently
it can generate FORTRAN, 'C', and RATFOR code from Maxima language code.
Gentran can translate mathematical expressions, iteration loops,
conditional branching statements, data type information, function
definitions, matrtices and arrays, and more.


File: maxima.info,  Node: Functions for Gentran,  Next: Gentran Mode Switches,  Prev: Introduction to Gentran,  Up: Package gentran

64.2 Functions for Gentran
==========================

 -- Function: gentran (<stmt1>, <stmt2>, ... , <stmtn> , <[f1, f2, ... ,
          fm]>)
     Translates each stmt into formatted code in the target language.  A
     substantial subset of expressions and statements in the Maxima
     programming language can be translated directly into numerical
     code.  The *gentran* command translates Maxima statements or
     procedure definitions into code in the target language
     (*gentranlang:* fortran, c, or ratfor).  Expressions may optionally
     be given to Maxima for evaluation prior to translation.

     _stmt1, stmt2, ...  , stmtn_ is a sequence of one or more
     statements, each of which is any Maxima user level expression,
     (simple, group, or block) statement, or procedure definition that
     can be translated into the target language.

     _[f1, f2, ...  , fm]_ is an optional list of output files to which
     translated output will be written.  They can be any of the
     following:

     _*string*_ = the name of an output file in quotes

     *true* (no quotes) = the terminal

     *false* = the current output file(s)

     *all* = all files currently open for output by gentran

     If the files are not open they will be opened; if they are open,
     output will be appended to them.  Filenames are given as quoted
     strings.  If the optional variable *genoutpath* (string, including
     the final /) default *false* is set, it will be prepended to the
     output file names.  If the output file list is omitted, output will
     be written to the current output, generally the terminal.
     *gentran* returns (a list of) the name(s) of file(s) to which code
     was written.

 -- Function: gentranout (<f1>, <f2>, ... , <fn>)

     Gentran maintains a list of files currently open for output by
     gentran commands only.  gentranout inserts each file name
     represented by _f1, f2,...  , fn_ into that list and opens each one
     for output.  It also resets the current output file(s) to include
     all files in _f1, f2, ...  , fn_.  gentranout returns the list of
     files represented by _f1, f2, ...  , fn_; i.e., the current output
     file(s) after the command has been executed.

 -- Function: gentranshut (<f1>, <f2>, ... , <fn>)

     gentranshut creates a list of file names from _f1, f2, ...  , fn_,
     deletes each from the output file list, and closes the
     corresponding files.  If (all of) the current output file(s) are
     closed, then the current output file is reset to the terminal.
     gentranshut returns (a list of) the current output file(s) after
     the command has been executed.  *gentranshut*(*all*) will close all
     gentran output files.

 -- Function: gentranpush (<f1>, <f2>, ... , <fn>)

     gentranpush pushes the file list onto the output stack.  Each file
     in the list that is not already open for output is opened at this
     time.  The current output file is reset to this new element on the
     top of the stack.

 -- Function: gentranpop (<f1>, <f2>, ... , <fn>)

     gentranpop deletes the top-most occurrence of the single element
     containing the file name(s) represented by _f1, f2, ...  , fn_ from
     the output stack.  Files whose names have been completely removed
     from the output stack are closed.  The current output file is reset
     to the (new) element on the top of the output stack.  gentranpop
     returns the current output file(s) after this command has been
     executed.

 -- Function: gentranin (<f1>, <f2>, ... , <fn>, [<f1>,<f2>, ... ,
          <fm>])

     gentranin processes mixed-language template files consisting of
     active parts (delimited by <<...>>) containing Maxima statements,
     including calls to gentran, and passive parts, assumed to contain
     statements in the target language (including comments), which are
     transcribed verbatim.  Input files are processed sequentially and
     the results appended to the output.  The presence of >> in passive
     parts of the file (except for in comments) is interpreted as an
     end-of-file and terminates processing of that file.  The optional
     list of output files _[f1,f2, ...  , fm]_ each receive a copy of
     the entire output.  All filespecs are quoted strings.  Input files
     may be given as (quoted string) filenames, which will be located by
     Maxima *file_search*.  The optional variable *geninpath* (default
     *false* ) must be a _list_ of quoted strings describing the paths
     to be searched for the input files.  If it is set, that list
     replaces the standard Maxima search paths.

     Active parts may contain any number of Maxima expressions and
     statements.  They are not copied directly to the output.  Instead,
     they are given to Maxima for evaluation.  All output generated by
     each evaluation is sent to the output file(s).  Returned values are
     only printed on the terminal.  Active parts will most likely
     contain calls to gentran to generate code.  This means that the
     result of processing a template file will be the original template
     file with all active parts replaced by generated code.  If _[f1,
     f2, ...  , fm]_ is not supplied, then generated code is simply
     written to the current output file(s).  However, if it is given,
     then the current output file is temporarily overridden.  Generated
     code is written to each file represented by _f1, f2, ...  , fn_ for
     this command only.  Files which were open prior to the call to
     gentranin will remain open after the call, and files which did not
     exist prior to the call will be created, opened, written to, and
     closed.  The output file stack will be exactly the same both before
     and after the call.  gentranin returns (to the terminal) the
     name(s) of (all) file(s) written to by this command.

 -- Function: gentraninshut ()

     A cleanup function to close input files in case where gentranin
     hung due to error in template.

 -- Function: tempvar (<type>)

     Generates temporary variable names by concatenating *tempvarname*
     (default *'t*) with sequence numbers.  If _type_ is non-false,
     _e.g._  "real*8" the corresponding type is assigned to the variable
     in the gentran symbol table, which may be used to generate
     declarations depending on the setting of the *gendecs* flag.  It is
     the users responsibility to make sure temporary variable names do
     not conflict with the main program.

 -- Function: markvar (<vname>)

     markvar "marks" variable name _vname_ to indicate that it currently
     holds a significant value.

 -- Function: unmarkvar (<vname>)

     unmarkvar "unmarks" variable name _vname_ to indicate that it no
     longer holds a significant value.

 -- Function: markedvarp (<vname>)

     markedvarp tests whether the variable name _vname_ is currently
     marked.

 -- Function: gendecs (<name>)

     The gendecs command can be called any time the gendecs flag is
     switched off to retrieve all type declarations from Gentran's
     symbol table for the given subprogram name (or the "current"
     subprogram if false is given as its argument).

 -- Function: gentran_on (<sw>)

     Turns on the mode switch _sw_.

 -- Function: gentran_off (<sw>)

     Turns the given switch, _sw_, off.


File: maxima.info,  Node: Gentran Mode Switches,  Next: Gentran Option Variables,  Prev: Functions for Gentran,  Up: Package gentran

64.3 Gentran Mode Switches
==========================

 -- Option variable: fortran
 -- Option variable: ratfor
 -- Option variable: c
     Default: off

     These mode switches change the default mode of Maxima from
     evaluation to translation.  They can be turned on and off with the
     gentran commands gentran_on and gentran_off.  Each time a new
     Maxima session is started up, the system is in evaluation mode.  It
     prints a prompt on the user's terminal screen and waits for an
     expression or statement to be entered.  It then proceeds to
     evaluate the expression, prints a new prompt, and waits for the
     user to enter another expression or statement.  This mode can be
     changed to translation mode by turning on either the fortran,
     ratfor or c switches.  After one of these switches is turned on and
     until it is turned off, every expression or statement entered by
     the user is translated into the corresponding language just as if
     it had been given as an argument to the gentran command.  Each of
     the special functions that can be used from within a call to
     gentran can be used at the top level until the switch is turned
     off.

 -- Option variable: gendecs
     Default: on

     When the gendecs switch is turned on, gentran generates type
     declarations whenever possible.  When gendecs is switched off, type
     declarations are not generated.  Instead, type information is
     stored in gentran's symbol table but is not retrieved in the form
     of declarations unless and until either the gendecs command is
     called or the gendecs flag is switched back.  *Note*: Generated
     declarations may often be placed in an inappropriate place (_e.g._
     in the middle of executable fortran code).  Therefore the gendecs
     flag is turned off during processing of templates by *gentranin*.


File: maxima.info,  Node: Gentran Option Variables,  Next: Gentran Evaluation Forms,  Prev: Gentran Mode Switches,  Up: Package gentran

64.4 Gentran Option Variables
=============================

 -- Option variable: gentranlang
     Default: fortran

     Selects the target numerical language.  Currently, gentranlang must
     be fortran, ratfor, or c.  Note that symbols entered in Maxima are
     case-sensitive.  gentranlang should not be set to FORTRAN, RATFOR
     or C.

 -- Option variable: fortlinelen
     default: 72

     Maximum number of characters printed on each line of generated
     FORTRAN code.

 -- Option variable: minfortlinelen
     Default: 40

     Minimum number of characters printed on each line of generated
     FORTRAN code.

 -- Option variable: fortcurrind
     Default: 0

     Number of blank spaces printed at the beginning of each line of
     generated FORTRAN code (after column 6).

 -- Option variable: ratlinelen
     Default: 80

     Maximum number of characters printed on each line of generated
     Ratfor code.

 -- Option variable: clinelen
     Default: 80

     Maximum number of characters printed on each line of generated 'C'
     code.

 -- Option variable: minclinelen
     Default: 40

     Minimum number of characters printed on each line of generated 'C'
     code.

 -- Option variable: ccurind
     Default: 0

     Number of blank spaces printed at the beginning of each line of
     generated'C' code.

 -- Option variable: tablen
     Default: 4

     Number of blank spaces printed for each new level of indentation.
     (Automatic indentation can be turned off by setting this variable
     to 0.)

 -- Option variable: genfloat
     Default: false

     When set to true (or any non-false value), causes integers in
     generated numerical code to be converted to floating point numbers,
     except in the following places: array subscripts, exponents, and
     initial, final, and step values in do-loops.  An exception (for
     compatibility with Macsyma 2.4) is that numbers in exponentials
     (with base %e only) are double-floated even when genfloat is false.

 -- Option variable: dblfloat
     Default: *false* If dblfloat is set to true, floating point numbers
     in gentran output in implementations (such as Windows Maxima under
     CLISP) in which float and double-float are the same will be printed
     as *.d0.  In implementations in which float and double-float are
     different, floats will be coerced to double-float before being
     printed.

 -- Option variable: gentranseg
     Default: *true*

 -- Option variable: maxexpprintlen
     Default: 800

     When *gentranseg* is true (or any non-false value), causes Gentran
     to "segment" large expressions into subexpressions of manageable
     size.  The segmentation facility generates a sequence of assignment
     statements, each of which assigns a subexpression to an
     automatically generated temporary variable name.  This sequence is
     generated in such a way that temporary variables are re-used as
     soon as possible, thereby keeping the number of automatically
     generated variables to a minimum.  The maximum allowable expression
     size can be controlled by setting the *maxexpprintlen* variable to
     the maximum number of characters allowed in an expression printed
     in the target numerical language (excluding spaces and other
     whitespace characters automatically printed by the formatter).
     When the segmentation routine generates temporary variables, it
     places type declarations in the symbol table for those variables if
     possible.  It uses the following rules to determine their type:

     1.  If the type of the variable to which the large expression is
     being assigned is already known (i.e., has been declared by the
     user via a TYPE form), then the temporary variables will be
     declared to be of that same type.  2.  If the global variable
     *tempvartype* has a non-false value, then the temporary variables
     are declared to be of that type.  3.  Otherwise, the variables are
     not declared unless *implicit* has been set to *true*.

 -- Option variable: gentranopt
     Default: *false*

     When set to true (or any non-false value), causes Gentran to
     replace each block of straightline code by an optimized sequence of
     assignments obtained from the Maxima optimize command.  (The
     optimize command takes an expression and replaces common
     subexpressions by temporary variable names.  It returns the
     resulting assignment statement, preceded by
     common-subexpression-to-temporary-variable assignments.

 -- Option variable: tempvarname
     Default: *'t*

     Name used as the prefix when generating temporary variable names.

 -- Option variable: optimvarname
     default: *'u*

     is the preface used to generate temporary file names produced by
     the optimizer when *gentranopt* is *true*.  When both gentranseg
     and gentranopt are true, the optimizer generates temporary file
     names using *optimvarname* while the segmentation routine uses
     *tempvarname* preventing conflict.

 -- Option variable: tempvarnum
     Default: 0

     Number appended onto tempvarname to create a temporary variable
     name.  If the temporary variable name resulting from appending
     tempvarnum onto the end of tempvarname has already been generated
     and still holds a useful value or has a different type than
     requested, then the number is incremented until one is found that
     was not previously generated or does not still hold a significant
     value or a different type.

 -- Option variable: tempvartype
     Default: *false*

     Target language variable type (e.g., INTEGER, REAL*8, FLOAT, etc.)
     used as a default for automatically generated variables whose type
     cannot be determined otherwise.  If tempvartype is false, then
     generated temporary variables whose type cannot be determined are
     not automatically declared.

 -- Option variable: implicit
     Default: *false*

     If implicit is set to *true* temporary variables are assigned their
     implicit type according to Fortran rules based on the initial
     letter of the name.  If gendecs is on, this results in printed type
     declarations.

 -- Option variable: gentranparser
     Default: *false*

     If gentranparser is set to *true* Maxima forms input to gentran
     will be parsed and an error will be produced if an expression
     cannot be translated.  Otherwise, untranslatable expressions may
     generate anomalous output, sometimes containing explicit calls to
     Maxima functions.

 -- Option variable: genstmtno
     Default: 25000

     Number used when a statement number must be generated.  Note: it is
     the user's responsibility to make sure this number will not clash
     with statement numbers in template files.

 -- Option variable: genstmtincr
     Default: 1

     number by which genstmtno is incremented each time a new statement
     number is generated.

 -- Option variable: usefortcomplex
     Default: *false*

     If usefortcomplex is true, real numbers in expressions declared to
     be complex by _type(complex,...)_ will be printed in Fortran
     complex number format _(realpart,0.0)_.  This is a purely syntactic
     device and does not carry out any complex calculations.


File: maxima.info,  Node: Gentran Evaluation Forms,  Prev: Gentran Option Variables,  Up: Package gentran

64.5 Gentran Evaluation Forms
=============================

The following special functions can be included in Maxima statements
which are to be translated by the gentran command to indicate that they
are to be partially or fully evaluated by Maxima before being translated
into numerical code.  Note that these functions have the described
effect only when supplied in arguments to the gentran command.

 -- Function: eval (<exp>)

     Where _exp_ is any Maxima expression or statement which, after
     evaluation by Maxima, results in an expression that can be
     translated by gentran into the target language.  When eval is
     called from an argument that is to be translated, it tells gentran
     to give the expression to Maxima for evaluation first, and then to
     translate the result of that evaluation.

 -- Function: rsetq (<var>, <exp>)

     Where _var_ is any Maxima variable, matrix or array element, and
     _exp_ is any Maxima expression which, after evaluation by Maxima
     results in an expression that can be translated by Gentran into the
     target language.  This is equivalent to VAR : EVAL(EXP) ;

 -- Function: lsetq (_var_, _exp_)

     Where _var_ is any Maxima user level matrix or array element with
     indices which, after evaluation by Maxima, will result in
     expressions that can be translated by Gentran, and _exp_ is any
     Maxima user level expression that can be translated into the target
     language.  This is equivalent to ‘var[eval(s1), eval(s2), ...]:
     exp’ where <s1>, <s2>, ...  are indices.

 -- Function: lrsetq (_var_, _exp_)

     Where _var_ is any Maxima matrix or array element with indices
     which, after evaluation by Maxima, will result in expressions that
     can be translated by Gentran; and _exp_ is any user level
     expression which, after evaluation, will result in an expression
     that can be translated by Gentran into the target language.  This
     is equivalent to ‘var[eval(s1), eval(s2), ...]: eval(exp);’.

 -- Function: type (_type,v1...vn_)

     Places information in the gentran symbol table to assign _type_ to
     variables _v1...vn_.  This may result in type declarations printed
     by gentran depending on the setting of gendecs.  *type* must be
     called from within gentran and does not evaluate its arguments
     unless *eval*() is used.

 -- Function: literal (_arg1, arg2, ... , argn_)

     where arg1, arg2, ...  , argn is an argument list containing one or
     more arg's, each of which either is, or evaluates to, an atom.  The
     atoms _tab_ and _cr_ have special meanings.  arg's are not
     evaluated unless given as arguments to eval.  This function call is
     replaced by the character sequence resulting from concatenation of
     the given atoms.  Double quotes are stripped from all string type
     arg's, and each occurrence of the reserved atom _tab_ or _cr_ is
     replaced by a tab to the current level of indentation, or an
     end-of-line character.


File: maxima.info,  Node: Package ggf,  Next: Package graphs,  Prev: Package gentran,  Up: Top

65 Package ggf
**************

* Menu:

* Functions and Variables for ggf::


File: maxima.info,  Node: Functions and Variables for ggf,  Prev: Package ggf,  Up: Package ggf

65.1 Functions and Variables for ggf
====================================

 -- Option variable: GGFINFINITY
     Default value: 3

     This is an option variable for function ‘ggf’.

     When computing the continued fraction of the generating function, a
     partial quotient having a degree (strictly) greater than
     <GGFINFINITY> will be discarded and the current convergent will be
     considered as the exact value of the generating function; most
     often the degree of all partial quotients will be 0 or 1; if you
     use a greater value, then you should give enough terms in order to
     make the computation accurate enough.

     See also ‘ggf’.

 -- Option variable: GGFCFMAX
     Default value: 3

     This is an option variable for function ‘ggf’.

     When computing the continued fraction of the generating function,
     if no good result has been found (see the <GGFINFINITY> flag) after
     having computed <GGFCFMAX> partial quotients, the generating
     function will be considered as not being a fraction of two
     polynomials and the function will exit.  Put freely a greater value
     for more complicated generating functions.

     See also ‘ggf’.

 -- Function: ggf (<l>)
     Compute the generating function (if it is a fraction of two
     polynomials) of a sequence, its first terms being given.  <l> is a
     list of numbers.

     The solution is returned as a fraction of two polynomials.  If no
     solution has been found, it returns with ‘done’.

     This function is controlled by global variables <GGFINFINITY> and
     <GGFCFMAX>.  See also <GGFINFINITY> and <GGFCFMAX>.

     To use this function write first ‘load("ggf")’.

          (%i1) load("ggf")$
          (%i2) makelist(fib(n),n,0,10);
          (%o2)                [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
          (%i3) ggf(%);
                                                 x
          (%o3)                            - ----------
                                              2
                                             x  + x - 1
          (%i4) taylor(%,x,0,10);
                        2      3      4      5      6       7       8       9       10
          (%o4)/T/ x + x  + 2 x  + 3 x  + 5 x  + 8 x  + 13 x  + 21 x  + 34 x  + 55 x
                                                                                  + . . .
          (%i5) makelist(2*fib(n+1)-fib(n),n,0,10);
          (%o5)              [2, 1, 3, 4, 7, 11, 18, 29, 47, 76, 123]
          (%i6) ggf(%);
                                              x - 2
          (%o6)                             ----------
                                             2
                                            x  + x - 1
          (%i7) taylor(%,x,0,10);
                              2      3      4       5       6       7       8       9
          (%o7)/T/ 2 + x + 3 x  + 4 x  + 7 x  + 11 x  + 18 x  + 29 x  + 47 x  + 76 x
                                                                               10
                                                                        + 123 x   + . . .

     As these examples show, the generating function does create a
     function whose Taylor series has coefficients that are the elements
     of the original list.


File: maxima.info,  Node: Package graphs,  Next: Package grobner,  Prev: Package ggf,  Up: Top

66 Package graphs
*****************

* Menu:

* Introduction to graphs::
* Functions and Variables for graphs::


File: maxima.info,  Node: Introduction to graphs,  Next: Functions and Variables for graphs,  Prev: Package graphs,  Up: Package graphs

66.1 Introduction to graphs
===========================

The ‘graphs’ package provides graph and digraph data structure for
Maxima.  Graphs and digraphs are simple (have no multiple edges nor
loops), although digraphs can have a directed edge from <u> to <v> and a
directed edge from <v> to <u>.

   Internally graphs are represented by adjacency lists and implemented
as a lisp structures.  Vertices are identified by their ids (an id is an
integer).  Edges/arcs are represented by lists of length 2.  Labels can
be assigned to vertices of graphs/digraphs and weights can be assigned
to edges/arcs of graphs/digraphs.

   There is a ‘draw_graph’ function for drawing graphs.  Graphs are
drawn using a force based vertex positioning algorithm.  ‘draw_graph’
can also use graphviz programs available from
<https://www.graphviz.org>.  ‘draw_graph’ is based on the maxima ‘draw’
package.

   To use the ‘graphs’ package, first load it with ‘load("graphs")’.


File: maxima.info,  Node: Functions and Variables for graphs,  Prev: Introduction to graphs,  Up: Package graphs

66.2 Functions and Variables for graphs
=======================================

66.2.1 Building graphs
----------------------

 -- Function: create_graph
          create_graph (<v_list>, <e_list>)
          create_graph (<n>, <e_list>)
          create_graph (<v_list>, <e_list>, <directed>)

     Creates a new graph on the set of vertices <v_list> and with edges
     <e_list>.

     <v_list> is a list of vertices ‘[v1, v2, ..., vn]’ or a list of
     vertices together with vertex labels ‘[[v1, l1], [v2 ,l2], ...,
     [vn, ln]]’.  A vertex may be any integer, and <v_list> may contain
     vertices in any order.  A label may be any Maxima expression, and
     two or more vertices may have the same label.

     <n> is the number of vertices.  Vertices will be identified by
     integers from 0 to n-1.

     <e_list> is a list of edges ‘[e1, e2,..., em]’ or a list of edges
     together with edge-weights ‘[[e1, w1], ..., [em, wm]]’.

     If <directed> is not ‘false’, a directed graph will be returned.

     Example 1: create a cycle on 3 vertices:
          (%i1) load ("graphs")$
          (%i2) g : create_graph([1,2,3], [[1,2], [2,3], [1,3]])$
          (%i3) print_graph(g)$
          Graph on 3 vertices with 3 edges.
          Adjacencies:
            3 :  1  2
            2 :  3  1
            1 :  3  2

     Example 2: create a cycle on 3 vertices with edge weights:
          (%i1) load ("graphs")$
          (%i2) g : create_graph([1,2,3], [[[1,2], 1.0], [[2,3], 2.0],
                                    [[1,3], 3.0]])$
          (%i3) print_graph(g)$
          Graph on 3 vertices with 3 edges.
          Adjacencies:
            3 :  1  2
            2 :  3  1
            1 :  3  2

     Example 3: create a directed graph:
          (%i1) load ("graphs")$
          (%i2) d : create_graph(
                  [1,2,3,4],
                  [
                   [1,3], [1,4],
                   [2,3], [2,4]
                  ],
                  'directed = true)$
          (%i3) print_graph(d)$
          Digraph on 4 vertices with 4 arcs.
          Adjacencies:
            4 :
            3 :
            2 :  4  3
            1 :  4  3

 -- Function: copy_graph (<g>)
     Returns a copy of the graph <g>.

 -- Function: circulant_graph (<n>, <d>)
     Returns the circulant graph with parameters <n> and <d>.

     Example:
          (%i1) load ("graphs")$
          (%i2) g : circulant_graph(10, [1,3])$
          (%i3) print_graph(g)$
          Graph on 10 vertices with 20 edges.
          Adjacencies:
            9 :  2  6  0  8
            8 :  1  5  9  7
            7 :  0  4  8  6
            6 :  9  3  7  5
            5 :  8  2  6  4
            4 :  7  1  5  3
            3 :  6  0  4  2
            2 :  9  5  3  1
            1 :  8  4  2  0
            0 :  7  3  9  1

 -- Function: clebsch_graph ()
     Returns the Clebsch graph.

 -- Function: complement_graph (<g>)
     Returns the complement of the graph <g>.

 -- Function: complete_bipartite_graph (<n>, <m>)
     Returns the complete bipartite graph on <n+m> vertices.

 -- Function: complete_graph (<n>)
     Returns the complete graph on <n> vertices.

 -- Function: cycle_digraph (<n>)
     Returns the directed cycle on <n> vertices.

 -- Function: cycle_graph (<n>)
     Returns the cycle on <n> vertices.

 -- Function: cuboctahedron_graph (<n>)
     Returns the cuboctahedron graph.

 -- Function: cube_graph (<n>)
     Returns the <n>-dimensional cube.

 -- Function: dodecahedron_graph ()
     Returns the dodecahedron graph.

 -- Function: empty_graph (<n>)
     Returns the empty graph on <n> vertices.

 -- Function: flower_snark (<n>)
     Returns the flower graph on <4n> vertices.

     Example:
          (%i1) load ("graphs")$
          (%i2) f5 : flower_snark(5)$
          (%i3) chromatic_index(f5);
          (%o3)                           4

 -- Function: from_adjacency_matrix (<A>)
     Returns the graph represented by its adjacency matrix <A>.

 -- Function: frucht_graph ()
     Returns the Frucht graph.

 -- Function: graph_product (<g1>, <g1>)
     Returns the direct product of graphs <g1> and <g2>.

     Example:
          (%i1) load ("graphs")$
          (%i2) grid : graph_product(path_graph(3), path_graph(4))$
          (%i3) draw_graph(grid)$


     (Figure graphs01: Direct product of two graphs)

 -- Function: graph_union (<g1>, <g1>)
     Returns the union (sum) of graphs <g1> and <g2>.

 -- Function: grid_graph (<n>, <m>)
     Returns the <n x m> grid.

 -- Function: great_rhombicosidodecahedron_graph ()
     Returns the great rhombicosidodecahedron graph.

 -- Function: great_rhombicuboctahedron_graph ()
     Returns the great rhombicuboctahedron graph.

 -- Function: grotzch_graph ()
     Returns the Grotzch graph.

 -- Function: heawood_graph ()
     Returns the Heawood graph.

 -- Function: icosahedron_graph ()
     Returns the icosahedron graph.

 -- Function: icosidodecahedron_graph ()
     Returns the icosidodecahedron graph.

 -- Function: induced_subgraph (<V>, <g>)
     Returns the graph induced on the subset <V> of vertices of the
     graph <g>.

     Example:
          (%i1) load ("graphs")$
          (%i2) p : petersen_graph()$
          (%i3) V : [0,1,2,3,4]$
          (%i4) g : induced_subgraph(V, p)$
          (%i5) print_graph(g)$
          Graph on 5 vertices with 5 edges.
          Adjacencies:
            4 :  3  0
            3 :  2  4
            2 :  1  3
            1 :  0  2
            0 :  1  4

 -- Function: line_graph (<g>)
     Returns the line graph of the graph <g>.

 -- Function: make_graph
          make_graph (<vrt>, <f>)
          make_graph (<vrt>, <f>, <oriented>)

     Creates a graph using a predicate function <f>.

     <vrt> is a list or set of vertices, or an integer.

     When <vrt> is a list or set, its elements may be any integers, and,
     if a list, may be listed in any order.

     When <vrt> is an integer, vertices of the graph will be integers
     from 1 to <vrt>.

     <f> is a predicate function.  Two vertices <a> and <b> will be
     connected if ‘f(a,b)=true’.

     If <directed> is not <false>, then the graph will be directed.

     Example 1:
          (%i1) load("graphs")$
          (%i2) g : make_graph(powerset({1,2,3,4,5}, 2), disjointp)$
          (%i3) is_isomorphic(g, petersen_graph());
          (%o3)                         true
          (%i4) get_vertex_label(1, g);
          (%o4)                        {1, 2}

     Example 2:
          (%i1) load("graphs")$
          (%i2) f(i, j) := is (mod(j, i)=0)$
          (%i3) g : make_graph(20, f, directed=true)$
          (%i4) out_neighbors(4, g);
          (%o4)                    [8, 12, 16, 20]
          (%i5) in_neighbors(18, g);
          (%o5)                    [1, 2, 3, 6, 9]

 -- Function: mycielski_graph (<g>)
     Returns the mycielskian graph of the graph <g>.

 -- Function: new_graph ()
     Returns the graph with no vertices and no edges.

 -- Function: path_digraph (<n>)
     Returns the directed path on <n> vertices.

 -- Function: path_graph (<n>)
     Returns the path on <n> vertices.

 -- Function: petersen_graph
          petersen_graph ()
          petersen_graph (<n>, <d>)

     Returns the petersen graph <P_{n,d}>.  The default values for <n>
     and <d> are ‘n=5’ and ‘d=2’.

 -- Function: random_bipartite_graph (<a>, <b>, <p>)
     Returns a random bipartite graph on ‘a+b’ vertices.  Each edge is
     present with probability <p>.

 -- Function: random_digraph (<n>, <p>)
     Returns a random directed graph on <n> vertices.  Each arc is
     present with probability <p>.

 -- Function: random_regular_graph
          random_regular_graph (<n>)
          random_regular_graph (<n>, <d>)

     Returns a random <d>-regular graph on <n> vertices.  The default
     value for <d> is ‘d=3’.

 -- Function: random_graph (<n>, <p>)
     Returns a random graph on <n> vertices.  Each edge is present with
     probability <p>.

 -- Function: random_graph1 (<n>, <m>)
     Returns a random graph on <n> vertices and random <m> edges.

 -- Function: random_network (<n>, <p>, <w>)
     Returns a random network on <n> vertices.  Each arc is present with
     probability <p> and has a weight in the range ‘[0,w]’.  The
     function returns a list ‘[network, source, sink]’.

     Example:
          (%i1) load ("graphs")$
          (%i2) [net, s, t] : random_network(50, 0.2, 10.0);
          (%o2)                   [DIGRAPH, 50, 51]
          (%i3) max_flow(net, s, t)$
          (%i4) first(%);
          (%o4)                   27.65981397932507

 -- Function: random_tournament (<n>)
     Returns a random tournament on <n> vertices.

 -- Function: random_tree (<n>)
     Returns a random tree on <n> vertices.

 -- Function: small_rhombicosidodecahedron_graph ()
     Returns the small rhombicosidodecahedron graph.

 -- Function: small_rhombicuboctahedron_graph ()
     Returns the small rhombicuboctahedron graph.

 -- Function: snub_cube_graph ()
     Returns the snub cube graph.

 -- Function: snub_dodecahedron_graph ()
     Returns the snub dodecahedron graph.

 -- Function: truncated_cube_graph ()
     Returns the truncated cube graph.

 -- Function: truncated_dodecahedron_graph ()
     Returns the truncated dodecahedron graph.

 -- Function: truncated_icosahedron_graph ()
     Returns the truncated icosahedron graph.

 -- Function: truncated_tetrahedron_graph ()
     Returns the truncated tetrahedron graph.

 -- Function: tutte_graph ()
     Returns the Tutte graph.

 -- Function: underlying_graph (<g>)
     Returns the underlying graph of the directed graph <g>.

 -- Function: wheel_graph (<n>)
     Returns the wheel graph on <n+1> vertices.

66.2.2 Graph properties
-----------------------

 -- Function: adjacency_matrix (<gr>)
     Returns the adjacency matrix of the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) c5 : cycle_graph(4)$
          (%i3) adjacency_matrix(c5);
                                   [ 0  1  0  1 ]
                                   [            ]
                                   [ 1  0  1  0 ]
          (%o3)                    [            ]
                                   [ 0  1  0  1 ]
                                   [            ]
                                   [ 1  0  1  0 ]

 -- Function: average_degree (<gr>)
     Returns the average degree of vertices in the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) average_degree(grotzch_graph());
                                         40
          (%o2)                          --
                                         11

 -- Function: biconnected_components (<gr>)
     Returns the (vertex sets of) 2-connected components of the graph
     <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) g : create_graph(
                      [1,2,3,4,5,6,7],
                      [
                       [1,2],[2,3],[2,4],[3,4],
                       [4,5],[5,6],[4,6],[6,7]
                      ])$
          (%i3) biconnected_components(g);
          (%o3)        [[6, 7], [4, 5, 6], [1, 2], [2, 3, 4]]


     (Figure graphs13: Graph with 2-connected vertices)

 -- Function: bipartition (<gr>)
     Returns a bipartition of the vertices of the graph <gr> or an empty
     list if <gr> is not bipartite.

     Example:

          (%i1) load ("graphs")$
          (%i2) h : heawood_graph()$
          (%i3) [A,B]:bipartition(h);
          (%o3)  [[8, 12, 6, 10, 0, 2, 4], [13, 5, 11, 7, 9, 1, 3]]
          (%i4) draw_graph(h, show_vertices=A, program=circular)$


     (Figure graphs02: Bipartition of the vertices in a Heawood graph)

 -- Function: chromatic_index (<gr>)
     Returns the chromatic index of the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) p : petersen_graph()$
          (%i3) chromatic_index(p);
          (%o3)                           4

 -- Function: chromatic_number (<gr>)
     Returns the chromatic number of the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) chromatic_number(cycle_graph(5));
          (%o2)                           3
          (%i3) chromatic_number(cycle_graph(6));
          (%o3)                           2

 -- Function: clear_edge_weight (<e>, <gr>)
     Removes the weight of the edge <e> in the graph <gr>.

     Example:

          (%i1) load ("graphs")$
          (%i2) g : create_graph(3, [[[0,1], 1.5], [[1,2], 1.3]])$
          (%i3) get_edge_weight([0,1], g);
          (%o3)                          1.5
          (%i4) clear_edge_weight([0,1], g)$
          (%i5) get_edge_weight([0,1], g);
          (%o5)                           1

 -- Function: clear_vertex_label (<v>, <gr>)
     Removes the label of the vertex <v> in the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) g : create_graph([[0,"Zero"], [1, "One"]], [[0,1]])$
          (%i3) get_vertex_label(0, g);
          (%o3)                         Zero
          (%i4) clear_vertex_label(0, g);
          (%o4)                         done
          (%i5) get_vertex_label(0, g);
          (%o5)                         false

 -- Function: connected_components (<gr>)
     Returns the (vertex sets of) connected components of the graph
     <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) g: graph_union(cycle_graph(5), path_graph(4))$
          (%i3) connected_components(g);
          (%o3)            [[1, 2, 3, 4, 0], [8, 7, 6, 5]]

 -- Function: diameter (<gr>)
     Returns the diameter of the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) diameter(dodecahedron_graph());
          (%o2)                           5

 -- Function: edge_coloring (<gr>)
     Returns an optimal coloring of the edges of the graph <gr>.

     The function returns the chromatic index and a list representing
     the coloring of the edges of <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) p : petersen_graph()$
          (%i3) [ch_index, col] : edge_coloring(p);
          (%o3) [4, [[[0, 5], 3], [[5, 7], 1], [[0, 1], 1], [[1, 6], 2],
          [[6, 8], 1], [[1, 2], 3], [[2, 7], 4], [[7, 9], 2], [[2, 3], 2],
          [[3, 8], 3], [[5, 8], 2], [[3, 4], 1], [[4, 9], 4], [[6, 9], 3],
          [[0, 4], 2]]]
          (%i4) assoc([0,1], col);
          (%o4)                           1
          (%i5) assoc([0,5], col);
          (%o5)                           3

 -- Function: degree_sequence (<gr>)
     Returns the list of vertex degrees of the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) degree_sequence(random_graph(10, 0.4));
          (%o2)            [2, 2, 2, 2, 2, 2, 3, 3, 3, 3]

 -- Function: edge_connectivity (<gr>)
     Returns the edge-connectivity of the graph <gr>.

     See also ‘min_edge_cut’.

 -- Function: edges (<gr>)
     Returns the list of edges (arcs) in a (directed) graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) edges(complete_graph(4));
          (%o2)   [[2, 3], [1, 3], [1, 2], [0, 3], [0, 2], [0, 1]]

 -- Function: get_edge_weight
          get_edge_weight (<e>, <gr>)
          get_edge_weight (<e>, <gr>, <ifnot>)

     Returns the weight of the edge <e> in the graph <gr>.

     If there is no weight assigned to the edge, the function returns 1.
     If the edge is not present in the graph, the function signals an
     error or returns the optional argument <ifnot>.

     Example:
          (%i1) load ("graphs")$
          (%i2) c5 : cycle_graph(5)$
          (%i3) get_edge_weight([1,2], c5);
          (%o3)                           1
          (%i4) set_edge_weight([1,2], 2.0, c5);
          (%o4)                         done
          (%i5) get_edge_weight([1,2], c5);
          (%o5)                          2.0

 -- Function: get_vertex_label (<v>, <gr>)
     Returns the label of the vertex <v> in the graph <gr>.

     If no label is assigned to vertex <v>, ‘get_vertex_label’ returns
     ‘false’.

     Example:
          (%i1) load("graphs")$
          (%i2) g: create_graph([[0, "Zero"], [1, "One"], 2, 3], [])$
          (%i3) get_vertex_label(0, g);
          (%o3)                         Zero
          (%i4) get_vertex_label(2, g);
          (%o4)                         false

 -- Function: get_unique_vertex_by_label (<l>, <gr>)
     Returns the unique vertex which has the label <l> in graph <gr>.

     If there is no such vertex, ‘get_unique_vertex_by_label’ returns
     ‘false’.

     If there are two or more vertices with label <l>,
     ‘get_unique_vertex_by_label’ reports an error.

     Example:
          (%i1) load ("graphs")$
          (%i2) g: create_graph ([[0, "Zero"], [1, "One"], [2, "Other"], [3, "Other"]], []) $
          (%i3) get_unique_vertex_by_label ("Zero", g);
          (%o3)                           0
          (%i4) get_unique_vertex_by_label ("Two", g);
          (%o4)                         false
          (%i5) errcatch (get_unique_vertex_by_label ("Other", g));
          get_unique_vertex_by_label: two or more vertices have the same label "Other"
          (%o5)                          []

 -- Function: get_all_vertices_by_label (<l>, <gr>)
     Returns all vertices, if any, which have the label <l> in graph
     <gr>.

     If there are no such vertices, ‘get_all_vertices_by_label’ returns
     an empty list ‘[]’.

     Example:
          (%i1) load ("graphs")$
          (%i2) g: create_graph ([[0, "Zero"], [1, "One"], [2, "Other"], [3, "Other"]], []) $
          (%i3) get_all_vertices_by_label ("Zero", g);
          (%o3)                          [0]
          (%i4) get_all_vertices_by_label ("Two", g);
          (%o4)                          []
          (%i5) get_all_vertices_by_label ("Other", g);
          (%o5)                        [2, 3]

 -- Function: graph_charpoly (<gr>, <x>)
     Returns the characteristic polynomial (in variable <x>) of the
     graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) p : petersen_graph()$
          (%i3) graph_charpoly(p, x), factor;
                                             5        4
          (%o3)               (x - 3) (x - 1)  (x + 2)

 -- Function: graph_center (<gr>)
     Returns the center of the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) g : grid_graph(5,5)$
          (%i3) graph_center(g);
          (%o3)                         [12]

 -- Function: graph_eigenvalues (<gr>)
     Returns the eigenvalues of the graph <gr>.  The function returns
     eigenvalues in the same format as maxima ‘eigenvalues’ function.

     Example:
          (%i1) load ("graphs")$
          (%i2) p : petersen_graph()$
          (%i3) graph_eigenvalues(p);
          (%o3)               [[3, - 2, 1], [1, 4, 5]]

 -- Function: graph_periphery (<gr>)
     Returns the periphery of the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) g : grid_graph(5,5)$
          (%i3) graph_periphery(g);
          (%o3)                    [24, 20, 4, 0]

 -- Function: graph_size (<gr>)
     Returns the number of edges in the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) p : petersen_graph()$
          (%i3) graph_size(p);
          (%o3)                          15

 -- Function: graph_order (<gr>)
     Returns the number of vertices in the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) p : petersen_graph()$
          (%i3) graph_order(p);
          (%o3)                          10

 -- Function: girth (<gr>)
     Returns the length of the shortest cycle in <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) g : heawood_graph()$
          (%i3) girth(g);
          (%o3)                           6

 -- Function: hamilton_cycle (<gr>)
     Returns the Hamilton cycle of the graph <gr> or an empty list if
     <gr> is not hamiltonian.

     Example:
          (%i1) load ("graphs")$
          (%i2) c : cube_graph(3)$
          (%i3) hc : hamilton_cycle(c);
          (%o3)              [7, 3, 2, 6, 4, 0, 1, 5, 7]
          (%i4) draw_graph(c, show_edges=vertices_to_cycle(hc))$


     (Figure graphs03: Hamilton cycle of a cubic graph)

 -- Function: hamilton_path (<gr>)
     Returns the Hamilton path of the graph <gr> or an empty list if
     <gr> does not have a Hamilton path.

     Example:
          (%i1) load ("graphs")$
          (%i2) p : petersen_graph()$
          (%i3) hp : hamilton_path(p);
          (%o3)            [0, 5, 7, 2, 1, 6, 8, 3, 4, 9]
          (%i4) draw_graph(p, show_edges=vertices_to_path(hp))$


     (Figure graphs04: Hamilton path of a Petersen graph)

 -- Function: isomorphism (<gr1>, <gr2>)

     Returns a an isomorphism between graphs/digraphs <gr1> and <gr2>.
     If <gr1> and <gr2> are not isomorphic, it returns an empty list.

     Example:
          (%i1) load ("graphs")$
          (%i2) clk5:complement_graph(line_graph(complete_graph(5)))$
          (%i3) isomorphism(clk5, petersen_graph());
          (%o3) [9 -> 0, 2 -> 1, 6 -> 2, 5 -> 3, 0 -> 4, 1 -> 5, 3 -> 6,
                                                    4 -> 7, 7 -> 8, 8 -> 9]

 -- Function: in_neighbors (<v>, <gr>)
     Returns the list of in-neighbors of the vertex <v> in the directed
     graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) p : path_digraph(3)$
          (%i3) in_neighbors(2, p);
          (%o3)                          [1]
          (%i4) out_neighbors(2, p);
          (%o4)                          []

 -- Function: is_biconnected (<gr>)
     Returns ‘true’ if <gr> is 2-connected and ‘false’ otherwise.

     Example:
          (%i1) load ("graphs")$
          (%i2) is_biconnected(cycle_graph(5));
          (%o2)                         true
          (%i3) is_biconnected(path_graph(5));
          (%o3)                         false

 -- Function: is_bipartite (<gr>)
     Returns ‘true’ if <gr> is bipartite (2-colorable) and ‘false’
     otherwise.

     Example:
          (%i1) load ("graphs")$
          (%i2) is_bipartite(petersen_graph());
          (%o2)                         false
          (%i3) is_bipartite(heawood_graph());
          (%o3)                         true

 -- Function: is_connected (<gr>)
     Returns ‘true’ if the graph <gr> is connected and ‘false’
     otherwise.

     Example:
          (%i1) load ("graphs")$
          (%i2) is_connected(graph_union(cycle_graph(4), path_graph(3)));
          (%o2)                         false

 -- Function: is_digraph (<gr>)
     Returns ‘true’ if <gr> is a directed graph and ‘false’ otherwise.

     Example:
          (%i1) load ("graphs")$
          (%i2) is_digraph(path_graph(5));
          (%o2)                         false
          (%i3) is_digraph(path_digraph(5));
          (%o3)                         true

 -- Function: is_edge_in_graph (<e>, <gr>)
     Returns ‘true’ if <e> is an edge (arc) in the (directed) graph <g>
     and ‘false’ otherwise.

     Example:
          (%i1) load ("graphs")$
          (%i2) c4 : cycle_graph(4)$
          (%i3) is_edge_in_graph([2,3], c4);
          (%o3)                         true
          (%i4) is_edge_in_graph([3,2], c4);
          (%o4)                         true
          (%i5) is_edge_in_graph([2,4], c4);
          (%o5)                         false
          (%i6) is_edge_in_graph([3,2], cycle_digraph(4));
          (%o6)                         false

 -- Function: is_graph (<gr>)
     Returns ‘true’ if <gr> is a graph and ‘false’ otherwise.

     Example:
          (%i1) load ("graphs")$
          (%i2) is_graph(path_graph(5));
          (%o2)                         true
          (%i3) is_graph(path_digraph(5));
          (%o3)                         false

 -- Function: is_graph_or_digraph (<gr>)
     Returns ‘true’ if <gr> is a graph or a directed graph and ‘false’
     otherwise.

     Example:
          (%i1) load ("graphs")$
          (%i2) is_graph_or_digraph(path_graph(5));
          (%o2)                         true
          (%i3) is_graph_or_digraph(path_digraph(5));
          (%o3)                         true

 -- Function: is_isomorphic (<gr1>, <gr2>)

     Returns ‘true’ if graphs/digraphs <gr1> and <gr2> are isomorphic
     and ‘false’ otherwise.

     See also *note isomorphism::.

     Example:
          (%i1) load ("graphs")$
          (%i2) clk5:complement_graph(line_graph(complete_graph(5)))$
          (%i3) is_isomorphic(clk5, petersen_graph());
          (%o3)                         true

 -- Function: is_planar (<gr>)

     Returns ‘true’ if <gr> is a planar graph and ‘false’ otherwise.

     The algorithm used is the Demoucron's algorithm, which is a
     quadratic time algorithm.

     Example:
          (%i1) load ("graphs")$
          (%i2) is_planar(dodecahedron_graph());
          (%o2)                         true
          (%i3) is_planar(petersen_graph());
          (%o3)                         false
          (%i4) is_planar(petersen_graph(10,2));
          (%o4)                         true

 -- Function: is_sconnected (<gr>)
     Returns ‘true’ if the directed graph <gr> is strongly connected and
     ‘false’ otherwise.

     Example:
          (%i1) load ("graphs")$
          (%i2) is_sconnected(cycle_digraph(5));
          (%o2)                         true
          (%i3) is_sconnected(path_digraph(5));
          (%o3)                         false

 -- Function: is_vertex_in_graph (<v>, <gr>)
     Returns ‘true’ if <v> is a vertex in the graph <g> and ‘false’
     otherwise.

     Example:
          (%i1) load ("graphs")$
          (%i2) c4 : cycle_graph(4)$
          (%i3) is_vertex_in_graph(0, c4);
          (%o3)                         true
          (%i4) is_vertex_in_graph(6, c4);
          (%o4)                         false

 -- Function: is_tree (<gr>)
     Returns ‘true’ if <gr> is a tree and ‘false’ otherwise.

     Example:
          (%i1) load ("graphs")$
          (%i2) is_tree(random_tree(4));
          (%o2)                         true
          (%i3) is_tree(graph_union(random_tree(4), random_tree(5)));
          (%o3)                         false

 -- Function: laplacian_matrix (<gr>)
     Returns the laplacian matrix of the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) laplacian_matrix(cycle_graph(5));
                             [  2   - 1   0    0   - 1 ]
                             [                         ]
                             [ - 1   2   - 1   0    0  ]
                             [                         ]
          (%o2)              [  0   - 1   2   - 1   0  ]
                             [                         ]
                             [  0    0   - 1   2   - 1 ]
                             [                         ]
                             [ - 1   0    0   - 1   2  ]

 -- Function: max_clique (<gr>)
     Returns a maximum clique of the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) g : random_graph(100, 0.5)$
          (%i3) max_clique(g);
          (%o3)          [6, 12, 31, 36, 52, 59, 62, 63, 80]

 -- Function: max_degree (<gr>)
     Returns the maximal degree of vertices of the graph <gr> and a
     vertex of maximal degree.

     Example:
          (%i1) load ("graphs")$
          (%i2) g : random_graph(100, 0.02)$
          (%i3) max_degree(g);
          (%o3)                        [6, 79]
          (%i4) vertex_degree(95, g);
          (%o4)                           2

 -- Function: max_flow (<net>, <s>, <t>)
     Returns a maximum flow through the network <net> with the source
     <s> and the sink <t>.

     The function returns the value of the maximal flow and a list
     representing the weights of the arcs in the optimal flow.

     Example:
          (%i1) load ("graphs")$
          (%i2) net : create_graph(
            [1,2,3,4,5,6],
            [[[1,2], 1.0],
             [[1,3], 0.3],
             [[2,4], 0.2],
             [[2,5], 0.3],
             [[3,4], 0.1],
             [[3,5], 0.1],
             [[4,6], 1.0],
             [[5,6], 1.0]],
            directed=true)$
          (%i3) [flow_value, flow] : max_flow(net, 1, 6);
          (%o3) [0.7, [[[1, 2], 0.5], [[1, 3], 0.2], [[2, 4], 0.2],
          [[2, 5], 0.3], [[3, 4], 0.1], [[3, 5], 0.1], [[4, 6], 0.3],
          [[5, 6], 0.4]]]
          (%i4) fl : 0$
          (%i5) for u in out_neighbors(1, net)
               do fl : fl + assoc([1, u], flow)$
          (%i6) fl;
          (%o6)                          0.7

 -- Function: max_independent_set (<gr>)
     Returns a maximum independent set of the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) d : dodecahedron_graph()$
          (%i3) mi : max_independent_set(d);
          (%o3)             [0, 3, 5, 9, 10, 11, 18, 19]
          (%i4) draw_graph(d, show_vertices=mi)$


     (Figure graphs05: Maximum independent set of a dodecahedral graph)

 -- Function: max_matching (<gr>)
     Returns a maximum matching of the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) d : dodecahedron_graph()$
          (%i3) m : max_matching(d);
          (%o3) [[5, 7], [8, 9], [6, 10], [14, 19], [13, 18], [12, 17],
                                         [11, 16], [0, 15], [3, 4], [1, 2]]
          (%i4) draw_graph(d, show_edges=m)$


     (Figure graphs06: Maximum matching of a dodecahedral graph)

 -- Function: min_degree (<gr>)
     Returns the minimum degree of vertices of the graph <gr> and a
     vertex of minimum degree.

     Example:
          (%i1) load ("graphs")$
          (%i2) g : random_graph(100, 0.1)$
          (%i3) min_degree(g);
          (%o3)                        [3, 49]
          (%i4) vertex_degree(21, g);
          (%o4)                           9

 -- Function: min_edge_cut (<gr>)
     Returns the minimum edge cut in the graph <gr>.

     See also *note edge_connectivity::.

 -- Function: min_vertex_cover (<gr>)
     Returns the minimum vertex cover of the graph <gr>.

 -- Function: min_vertex_cut (<gr>)
     Returns the minimum vertex cut in the graph <gr>.

     See also *note vertex_connectivity::.

 -- Function: minimum_spanning_tree (<gr>)
     Returns the minimum spanning tree of the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) g : graph_product(path_graph(10), path_graph(10))$
          (%i3) t : minimum_spanning_tree(g)$
          (%i4) draw_graph(g, show_edges=edges(t))$


     (Figure graphs07: Minimum spanning of rectangular graph)

 -- Function: neighbors (<v>, <gr>)
     Returns the list of neighbors of the vertex <v> in the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) p : petersen_graph()$
          (%i3) neighbors(3, p);
          (%o3)                       [4, 8, 2]

 -- Function: odd_girth (<gr>)
     Returns the length of the shortest odd cycle in the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) g : graph_product(cycle_graph(4), cycle_graph(7))$
          (%i3) girth(g);
          (%o3)                           4
          (%i4) odd_girth(g);
          (%o4)                           7

 -- Function: out_neighbors (<v>, <gr>)
     Returns the list of out-neighbors of the vertex <v> in the directed
     graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) p : path_digraph(3)$
          (%i3) in_neighbors(2, p);
          (%o3)                          [1]
          (%i4) out_neighbors(2, p);
          (%o4)                          []

 -- Function: planar_embedding (<gr>)

     Returns the list of facial walks in a planar embedding of <gr> and
     ‘false’ if <gr> is not a planar graph.

     The graph <gr> must be biconnected.

     The algorithm used is the Demoucron's algorithm, which is a
     quadratic time algorithm.

     Example:
          (%i1) load ("graphs")$
          (%i2) planar_embedding(grid_graph(3,3));
          (%o2) [[3, 6, 7, 8, 5, 2, 1, 0], [4, 3, 0, 1], [3, 4, 7, 6],
                                                [8, 7, 4, 5], [1, 2, 5, 4]]

 -- Function: print_graph (<gr>)
     Prints some information about the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) c5 : cycle_graph(5)$
          (%i3) print_graph(c5)$
          Graph on 5 vertices with 5 edges.
          Adjacencies:
            4 :  0  3
            3 :  4  2
            2 :  3  1
            1 :  2  0
            0 :  4  1
          (%i4) dc5 : cycle_digraph(5)$
          (%i5) print_graph(dc5)$
          Digraph on 5 vertices with 5 arcs.
          Adjacencies:
            4 :  0
            3 :  4
            2 :  3
            1 :  2
            0 :  1
          (%i6) out_neighbors(0, dc5);
          (%o6)                          [1]

 -- Function: radius (<gr>)
     Returns the radius of the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) radius(dodecahedron_graph());
          (%o2)                           5

 -- Function: set_edge_weight (<e>, <w>, <gr>)
     Assigns the weight <w> to the edge <e> in the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) g : create_graph([1, 2], [[[1,2], 1.2]])$
          (%i3) get_edge_weight([1,2], g);
          (%o3)                          1.2
          (%i4) set_edge_weight([1,2], 2.1, g);
          (%o4)                         done
          (%i5) get_edge_weight([1,2], g);
          (%o5)                          2.1

 -- Function: set_vertex_label (<v>, <l>, <gr>)
     Assigns the label <l> to the vertex <v> in the graph <gr>.

     A label may be any Maxima expression, and two or more vertices may
     have the same label.

     Example:
          (%i1) load ("graphs")$
          (%i2) g : create_graph([[1, "One"], [2, "Two"]], [[1, 2]])$
          (%i3) get_vertex_label(1, g);
          (%o3)                          One
          (%i4) set_vertex_label(1, "oNE", g);
          (%o4)                         done
          (%i5) get_vertex_label(1, g);
          (%o5)                          oNE
          (%i6) h : create_graph([[11, x], [22, y], [33, x + y]], [[11, 33], [22, 33]]) $
          (%i7) get_vertex_label (33, h);
          (%o7)                         y + x

 -- Function: shortest_path (<u>, <v>, <gr>)
     Returns the shortest path from <u> to <v> in the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) d : dodecahedron_graph()$
          (%i3) path : shortest_path(0, 7, d);
          (%o3)                   [0, 1, 19, 13, 7]
          (%i4) draw_graph(d, show_edges=vertices_to_path(path))$


     (Figure graphs08: Shortest path between two vertices in a
     dodecahedral graph)

 -- Function: shortest_weighted_path (<u>, <v>, <gr>)
     Returns the length of the shortest weighted path and the shortest
     weighted path from <u> to <v> in the graph <gr>.

     The length of a weighted path is the sum of edge weights of edges
     in the path.  If an edge has no weight, then it has a default
     weight 1.

     Example:

          (%i1) load ("graphs")$
          (%i2) g: petersen_graph(20, 2)$
          (%i3) for e in edges(g) do set_edge_weight(e, random(1.0), g)$
          (%i4) shortest_weighted_path(0, 10, g);
          (%o4) [2.575143920268482, [0, 20, 38, 36, 34, 32, 30, 10]]

 -- Function: strong_components (<gr>)
     Returns the strong components of a directed graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) t : random_tournament(4)$
          (%i3) strong_components(t);
          (%o3)                 [[1], [0], [2], [3]]
          (%i4) vertex_out_degree(3, t);
          (%o4)                           3

 -- Function: topological_sort (<dag>)

     Returns a topological sorting of the vertices of a directed graph
     <dag> or an empty list if <dag> is not a directed acyclic graph.

     Example:
          (%i1) load ("graphs")$
          (%i2) g:create_graph(
                   [1,2,3,4,5],
                   [
                    [1,2], [2,5], [5,3],
                    [5,4], [3,4], [1,3]
                   ],
                   directed=true)$
          (%i3) topological_sort(g);
          (%o3)                    [1, 2, 5, 3, 4]

 -- Function: vertex_connectivity (<g>)
     Returns the vertex connectivity of the graph <g>.

     See also *note min_vertex_cut::.

 -- Function: vertex_degree (<v>, <gr>)
     Returns the degree of the vertex <v> in the graph <gr>.

 -- Function: vertex_distance (<u>, <v>, <gr>)
     Returns the length of the shortest path between <u> and <v> in the
     (directed) graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) d : dodecahedron_graph()$
          (%i3) vertex_distance(0, 7, d);
          (%o3)                           4
          (%i4) shortest_path(0, 7, d);
          (%o4)                   [0, 1, 19, 13, 7]

 -- Function: vertex_eccentricity (<v>, <gr>)

     Returns the eccentricity of the vertex <v> in the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) g:cycle_graph(7)$
          (%i3) vertex_eccentricity(0, g);
          (%o3)                           3

 -- Function: vertex_in_degree (<v>, <gr>)
     Returns the in-degree of the vertex <v> in the directed graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) p5 : path_digraph(5)$
          (%i3) print_graph(p5)$
          Digraph on 5 vertices with 4 arcs.
          Adjacencies:
            4 :
            3 :  4
            2 :  3
            1 :  2
            0 :  1
          (%i4) vertex_in_degree(4, p5);
          (%o4)                           1
          (%i5) in_neighbors(4, p5);
          (%o5)                          [3]

 -- Function: vertex_out_degree (<v>, <gr>)
     Returns the out-degree of the vertex <v> in the directed graph
     <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) t : random_tournament(10)$
          (%i3) vertex_out_degree(0, t);
          (%o3)                           2
          (%i4) out_neighbors(0, t);
          (%o4)                        [7, 1]

 -- Function: vertices (<gr>)
     Returns the list of vertices in the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) vertices(complete_graph(4));
          (%o2)                     [3, 2, 1, 0]

 -- Function: vertex_coloring (<gr>)
     Returns an optimal coloring of the vertices of the graph <gr>.

     The function returns the chromatic number and a list representing
     the coloring of the vertices of <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) p:petersen_graph()$
          (%i3) vertex_coloring(p);
          (%o3) [3, [[0, 2], [1, 3], [2, 2], [3, 3], [4, 1], [5, 3],
                                           [6, 1], [7, 1], [8, 2], [9, 2]]]

 -- Function: wiener_index (<gr>)
     Returns the Wiener index of the graph <gr>.

     Example:
          (%i2) wiener_index(dodecahedron_graph());
          (%o2)                          500

66.2.3 Modifying graphs
-----------------------

 -- Function: add_edge (<e>, <gr>)
     Adds the edge <e> to the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) p : path_graph(4)$
          (%i3) neighbors(0, p);
          (%o3)                          [1]
          (%i4) add_edge([0,3], p);
          (%o4)                         done
          (%i5) neighbors(0, p);
          (%o5)                        [3, 1]

 -- Function: add_edges (<e_list>, <gr>)
     Adds all edges in the list <e_list> to the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) g : empty_graph(3)$
          (%i3) add_edges([[0,1],[1,2]], g)$
          (%i4) print_graph(g)$
          Graph on 3 vertices with 2 edges.
          Adjacencies:
            2 :  1
            1 :  2  0
            0 :  1

 -- Function: add_vertex (<v>, <gr>)
     Adds the vertex <v> to the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) g : path_graph(2)$
          (%i3) add_vertex(2, g)$
          (%i4) print_graph(g)$
          Graph on 3 vertices with 1 edges.
          Adjacencies:
            2 :
            1 :  0
            0 :  1

 -- Function: add_vertices (<v_list>, <gr>)
     Adds all vertices in the list <v_list> to the graph <gr>.  A vertex
     may be any integer, and <v_list> may contain vertices in any order.

 -- Function: connect_vertices (<v_list>, <u_list>, <gr>)
     Connects all vertices from the list <v_list> with the vertices in
     the list <u_list> in the graph <gr>.

     <v_list> and <u_list> can be single vertices or lists of vertices.

     Example:
          (%i1) load ("graphs")$
          (%i2) g : empty_graph(4)$
          (%i3) connect_vertices(0, [1,2,3], g)$
          (%i4) print_graph(g)$
          Graph on 4 vertices with 3 edges.
          Adjacencies:
            3 :  0
            2 :  0
            1 :  0
            0 :  3  2  1

 -- Function: contract_edge (<e>, <gr>)
     Contracts the edge <e> in the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) g: create_graph(
                8, [[0,3],[1,3],[2,3],[3,4],[4,5],[4,6],[4,7]])$
          (%i3) print_graph(g)$
          Graph on 8 vertices with 7 edges.
          Adjacencies:
            7 :  4
            6 :  4
            5 :  4
            4 :  7  6  5  3
            3 :  4  2  1  0
            2 :  3
            1 :  3
            0 :  3
          (%i4) contract_edge([3,4], g)$
          (%i5) print_graph(g)$
          Graph on 7 vertices with 6 edges.
          Adjacencies:
            7 :  3
            6 :  3
            5 :  3
            3 :  5  6  7  2  1  0
            2 :  3
            1 :  3
            0 :  3

 -- Function: remove_edge (<e>, <gr>)
     Removes the edge <e> from the graph <gr>.

     Example:
          (%i1) load ("graphs")$
          (%i2) c3 : cycle_graph(3)$
          (%i3) remove_edge([0,1], c3)$
          (%i4) print_graph(c3)$
          Graph on 3 vertices with 2 edges.
          Adjacencies:
            2 :  0  1
            1 :  2
            0 :  2

 -- Function: remove_vertex (<v>, <gr>)
     Removes the vertex <v> from the graph <gr>.

66.2.4 Reading and writing to files
-----------------------------------

 -- Function: dimacs_export
          dimacs_export (<gr>, <fl>)
          dimacs_export (<gr>, <fl>, <comment1>, ..., <commentn>)

     Exports the graph into the file <fl> in the DIMACS format.
     Optional comments will be added to the top of the file.

 -- Function: dimacs_import (<fl>)

     Returns the graph from file <fl> in the DIMACS format.

 -- Function: graph6_decode (<str>)

     Returns the graph encoded in the graph6 format in the string <str>.

 -- Function: graph6_encode (<gr>)

     Returns a string which encodes the graph <gr> in the graph6 format.

 -- Function: graph6_export (<gr_list>, <fl>)

     Exports graphs in the list <gr_list> to the file <fl> in the graph6
     format.

 -- Function: graph6_import (<fl>)

     Returns a list of graphs from the file <fl> in the graph6 format.

 -- Function: sparse6_decode (<str>)

     Returns the graph encoded in the sparse6 format in the string
     <str>.

 -- Function: sparse6_encode (<gr>)

     Returns a string which encodes the graph <gr> in the sparse6
     format.

 -- Function: sparse6_export (<gr_list>, <fl>)

     Exports graphs in the list <gr_list> to the file <fl> in the
     sparse6 format.

 -- Function: sparse6_import (<fl>)

     Returns a list of graphs from the file <fl> in the sparse6 format.

66.2.5 Visualization
--------------------

 -- Function: draw_graph
          draw_graph (<graph>)
          draw_graph (<graph>, <option1>, ..., <optionk>)

     Draws the graph using the *note Package draw:: package.

     The algorithm used to position vertices is specified by the
     optional argument <program>.  The default value is
     ‘program=spring_embedding’.  <draw_graph> can also use the graphviz
     programs for positioning vertices, but graphviz must be installed
     separately.

     Example 1:

          (%i1) load ("graphs")$
          (%i2) g:grid_graph(10,10)$
          (%i3) m:max_matching(g)$
          (%i4) draw_graph(g,
             spring_embedding_depth=100,
             show_edges=m, edge_type=dots,
             vertex_size=0)$


     (Figure graphs09: Example of the use of draw_graph to draw a graph)

     Example 2:

          (%i1) load ("graphs")$
          (%i2) g:create_graph(16,
              [
               [0,1],[1,3],[2,3],[0,2],[3,4],[2,4],
               [5,6],[6,4],[4,7],[6,7],[7,8],[7,10],[7,11],
               [8,10],[11,10],[8,9],[11,12],[9,15],[12,13],
               [10,14],[15,14],[13,14]
              ])$
          (%i3) t:minimum_spanning_tree(g)$
          (%i4) draw_graph(
              g,
              show_edges=edges(t),
              show_edge_width=4,
              show_edge_color=green,
              vertex_type=filled_square,
              vertex_size=2
              )$


     (Figure graphs10: Example of the use of draw_graph to draw a graph)

     Example 3:

          (%i1) load ("graphs")$
          (%i2) g:create_graph(16,
              [
               [0,1],[1,3],[2,3],[0,2],[3,4],[2,4],
               [5,6],[6,4],[4,7],[6,7],[7,8],[7,10],[7,11],
               [8,10],[11,10],[8,9],[11,12],[9,15],[12,13],
               [10,14],[15,14],[13,14]
              ])$
          (%i3) mi : max_independent_set(g)$
          (%i4) draw_graph(
              g,
              show_vertices=mi,
              show_vertex_type=filled_up_triangle,
              show_vertex_size=2,
              edge_color=cyan,
              edge_width=3,
              show_id=true,
              text_color=brown
              )$


     (Figure graphs11: Example of the use of draw_graph to draw a graph)

     Example 4:

          (%i1) load ("graphs")$
          (%i2) net : create_graph(
              [0,1,2,3,4,5],
              [
               [[0,1], 3], [[0,2], 2],
               [[1,3], 1], [[1,4], 3],
               [[2,3], 2], [[2,4], 2],
               [[4,5], 2], [[3,5], 2]
              ],
              directed=true
              )$
          (%i3) draw_graph(
              net,
              show_weight=true,
              vertex_size=0,
              show_vertices=[0,5],
              show_vertex_type=filled_square,
              head_length=0.2,
              head_angle=10,
              edge_color="dark-green",
              text_color=blue
              )$


     (Figure graphs12: Example of the use of draw_graph to draw a graph)

     Example 5:

          (%i1) load("graphs")$
          (%i2) g: petersen_graph(20, 2);
          (%o2)                         GRAPH
          (%i3) draw_graph(g, redraw=true, program=planar_embedding);
          (%o3)                         done


     (Figure graphs14: Example of the use of draw_graph to draw a graph)

     Example 6:

          (%i1) load("graphs")$
          (%i2) t: tutte_graph();
          (%o2)                         GRAPH
          (%i3) draw_graph(t, redraw=true,
                              fixed_vertices=[1,2,3,4,5,6,7,8,9]);
          (%o3)                         done


     (Figure graphs15: Example of the use of draw_graph to draw a graph)

 -- Option variable: draw_graph_program
     Default value: <spring_embedding>

     The default value for the program used to position vertices in
     ‘draw_graph’ program.

 -- draw_graph option: show_id
     Default value: <false>

     If <true> then ids of the vertices are displayed.

 -- draw_graph option: show_label
     Default value: <false>

     If <true> then labels of the vertices are displayed.

 -- draw_graph option: label_alignment
     Default value: <center>

     Determines how to align the labels/ids of the vertices.  Can be
     ‘left’, ‘center’ or ‘right’.

 -- draw_graph option: show_weight
     Default value: <false>

     If <true> then weights of the edges are displayed.

 -- draw_graph option: vertex_type
     Default value: <circle>

     Defines how vertices are displayed.  See the <point_type> option
     for the ‘draw’ package for possible values.

 -- draw_graph option: vertex_size
     The size of vertices.

 -- draw_graph option: vertex_color
     The color used for displaying vertices.

 -- draw_graph option: show_vertices
     Default value: []

     Display selected vertices in the using a different color.

 -- draw_graph option: show_vertex_type
     Defines how vertices specified in <show_vertices> are displayed.
     See the <point_type> option for the ‘draw’ package for possible
     values.

 -- draw_graph option: show_vertex_size
     The size of vertices in <show_vertices>.

 -- draw_graph option: show_vertex_color
     The color used for displaying vertices in the <show_vertices> list.

 -- draw_graph option: vertex_partition
     Default value: []

     A partition ‘[[v1,v2,...],...,[vk,...,vn]]’ of the vertices of the
     graph.  The vertices of each list in the partition will be drawn in
     a different color.

 -- draw_graph option: vertex_coloring
     Specifies coloring of the vertices.  The coloring <col> must be
     specified in the format as returned by <vertex_coloring>.

 -- draw_graph option: edge_color
     The color used for displaying edges.

 -- draw_graph option: edge_width
     The width of edges.

 -- draw_graph option: edge_type
     Defines how edges are displayed.  See the <line_type> option for
     the ‘draw’ package.

 -- draw_graph option: show_edges
     Display edges specified in the list <e_list> using a different
     color.

 -- draw_graph option: show_edge_color
     The color used for displaying edges in the <show_edges> list.

 -- draw_graph option: show_edge_width
     The width of edges in <show_edges>.

 -- draw_graph option: show_edge_type
     Defines how edges in <show_edges> are displayed.  See the
     <line_type> option for the ‘draw’ package.

 -- draw_graph option: edge_partition
     A partition ‘[[e1,e2,...],...,[ek,...,em]]’ of edges of the graph.
     The edges of each list in the partition will be drawn using a
     different color.

 -- draw_graph option: edge_coloring
     The coloring of edges.  The coloring must be specified in the
     format as returned by the function <edge_coloring>.

 -- draw_graph option: redraw
     Default value: <false>

     If ‘true’, vertex positions are recomputed even if the positions
     have been saved from a previous drawing of the graph.

 -- draw_graph option: head_angle
     Default value: 15

     The angle for the arrows displayed on arcs (in directed graphs).

 -- draw_graph option: head_length
     Default value: 0.1

     The length for the arrows displayed on arcs (in directed graphs).

 -- draw_graph option: spring_embedding_depth
     Default value: 50

     The number of iterations in the spring embedding graph drawing
     algorithm.

 -- draw_graph option: terminal
     The terminal used for drawing (see the <terminal> option in the
     ‘draw’ package).

 -- draw_graph option: file_name
     The filename of the drawing if terminal is not screen.

 -- draw_graph option: program
     Defines the program used for positioning vertices of the graph.
     Can be one of the graphviz programs (dot, neato, twopi, circ, fdp),
     <circular>, <spring_embedding> or <planar_embedding>.
     <planar_embedding> is only available for 2-connected planar graphs.
     When ‘program=spring_embedding’, a set of vertices with fixed
     position can be specified with the <fixed_vertices> option.

 -- draw_graph option: fixed_vertices
     Specifies a list of vertices which will have positions fixed along
     a regular polygon.  Can be used when ‘program=spring_embedding’.

 -- Function: vertices_to_path (<v_list>)
     Converts a list <v_list> of vertices to a list of edges of the path
     defined by <v_list>.

 -- Function: vertices_to_cycle (<v_list>)
     Converts a list <v_list> of vertices to a list of edges of the
     cycle defined by <v_list>.


File: maxima.info,  Node: Package grobner,  Next: Package hompack,  Prev: Package graphs,  Up: Top

67 Package grobner
******************

* Menu:

* Introduction to grobner ::
* Functions and Variables for grobner ::


File: maxima.info,  Node: Introduction to grobner,  Next: Functions and Variables for grobner,  Prev: Package grobner,  Up: Package grobner

67.1 Introduction to grobner
============================

‘grobner’ is a package for working with Groebner bases in Maxima.

To use the following functions you must load the ‘grobner.lisp’ package.

     load("grobner");

A demo can be started by
     demo("grobner.demo");

or
     batch("grobner.demo")

Some of the calculation in the demo will take a lot of time therefore
the output ‘grobner-demo.output’ of the demo can be found in the same
directory as the demo file.

67.1.1 Notes on the grobner package
-----------------------------------

The package was written by

Marek Rychlik

<http://alamos.math.arizona.edu>

and is released 2002-05-24 under the terms of the General Public
License(GPL) (see file ‘grobner.lisp’).  This documentation was
extracted from the files
‘README’, ‘grobner.lisp’, ‘grobner.demo’, ‘grobner-demo.output’

by Günter Nowak.  Suggestions for improvement of the documentation can
be discussed at the _maxima_-mailing-list <maxima@math.utexas.edu>.  The
code is a little bit out of date now.  Modern implementation use the
fast _F4_ algorithm described in
A new efficient algorithm for computing Gröbner bases (F4)
Jean-Charles Faugère
LIP6/CNRS Université Paris VI
January 20, 1999

67.1.2 Implementations of admissible monomial orders in grobner
---------------------------------------------------------------

   • ‘lex’

     pure lexicographic, default order for monomial comparisons
   • ‘grlex’

     total degree order, ties broken by lexicographic

   • ‘grevlex’

     total degree, ties broken by reverse lexicographic

   • ‘invlex’

     inverse lexicographic order


File: maxima.info,  Node: Functions and Variables for grobner,  Prev: Introduction to grobner,  Up: Package grobner

67.2 Functions and Variables for grobner
========================================

67.2.1 Global switches for grobner
----------------------------------

 -- Option variable: poly_monomial_order
     Default value: ‘lex’

     This global switch controls which monomial order is used in
     polynomial and Groebner Bases calculations.  If not set, ‘lex’ will
     be used.

 -- Option variable: poly_coefficient_ring
     Default value: ‘expression_ring’

     This switch indicates the coefficient ring of the polynomials that
     will be used in grobner calculations.  If not set, _maxima's_
     general expression ring will be used.  This variable may be set to
     ‘ring_of_integers’ if desired.

 -- Option variable: poly_primary_elimination_order
     Default value: ‘false’

     Name of the default order for eliminated variables in
     elimination-based functions.  If not set, ‘lex’ will be used.

 -- Option variable: poly_secondary_elimination_order
     Default value: ‘false’

     Name of the default order for kept variables in elimination-based
     functions.  If not set, ‘lex’ will be used.

 -- Option variable: poly_elimination_order
     Default value: ‘false’

     Name of the default elimination order used in elimination
     calculations.  If set, it overrides the settings in variables
     ‘poly_primary_elimination_order’ and
     ‘poly_secondary_elimination_order’.  The user must ensure that this
     is a true elimination order valid for the number of eliminated
     variables.

 -- Option variable: poly_return_term_list
     Default value: ‘false’

     If set to ‘true’, all functions in this package will return each
     polynomial as a list of terms in the current monomial order rather
     than a _maxima_ general expression.

 -- Option variable: poly_grobner_debug
     Default value: ‘false’

     If set to ‘true’, produce debugging and tracing output.

 -- Option variable: poly_grobner_algorithm
     Default value: ‘buchberger’

     Possible values:
        • ‘buchberger’
        • ‘parallel_buchberger’
        • ‘gebauer_moeller’

     The name of the algorithm used to find the Groebner Bases.

 -- Option variable: poly_top_reduction_only
     Default value: ‘false’

     If not ‘false’, use top reduction only whenever possible.  Top
     reduction means that division algorithm stops after the first
     reduction.

67.2.2 Simple operators in grobner
----------------------------------

‘poly_add’, ‘poly_subtract’, ‘poly_multiply’ and ‘poly_expt’ are the
arithmetical operations on polynomials.  These are performed using the
internal representation, but the results are converted back to the
_maxima_ general form.

 -- Function: poly_add (<poly1>, <poly2>, <varlist>)
     Adds two polynomials <poly1> and <poly2>.

          (%i1) poly_add(z+x^2*y,x-z,[x,y,z]);
                                              2
          (%o1)                              x  y + x

 -- Function: poly_subtract (<poly1>, <poly2>, <varlist>)
     Subtracts a polynomial <poly2> from <poly1>.

          (%i1) poly_subtract(z+x^2*y,x-z,[x,y,z]);
                                                2
          (%o1)                          2 z + x  y - x

 -- Function: poly_multiply (<poly1>, <poly2>, <varlist>)
     Returns the product of polynomials <poly1> and <poly2>.

          (%i2) poly_multiply(z+x^2*y,x-z,[x,y,z])-(z+x^2*y)*(x-z),expand;
          (%o1)                                  0

 -- Function: poly_s_polynomial (<poly1>, <poly2>, <varlist>)
     Returns the _syzygy polynomial_ (_S-polynomial_) of two polynomials
     <poly1> and <poly2>.

 -- Function: poly_primitive_part (<poly1>, <varlist>)
     Returns the polynomial <poly> divided by the GCD of its
     coefficients.

          (%i1) poly_primitive_part(35*y+21*x,[x,y]);
          (%o1)                              5 y + 3 x

 -- Function: poly_normalize (<poly>, <varlist>)
     Returns the polynomial <poly> divided by the leading coefficient.
     It assumes that the division is possible, which may not always be
     the case in rings which are not fields.

67.2.3 Other functions in grobner
---------------------------------

 -- Function: poly_expand (<poly>, <varlist>)
     This function parses polynomials to internal form and back.  It is
     equivalent to ‘expand(<poly>)’ if <poly> parses correctly to a
     polynomial.  If the representation is not compatible with a
     polynomial in variables <varlist>, the result is an error.  It can
     be used to test whether an expression correctly parses to the
     internal representation.  The following examples illustrate that
     indexed and transcendental function variables are allowed.

          (%i1) poly_expand((x-y)*(y+x),[x,y]);
                                               2    2
          (%o1)                               x  - y
          (%i2) poly_expand((y+x)^2,[x,y]);
                                          2            2
          (%o2)                          y  + 2 x y + x
          (%i3) poly_expand((y+x)^5,[x,y]);
                            5      4         2  3       3  2      4      5
          (%o3)            y  + 5 x y  + 10 x  y  + 10 x  y  + 5 x  y + x
          (%i4) poly_expand(-1-x*exp(y)+x^2/sqrt(y),[x]);
                                                    2
                                            y      x
          (%o4)                       - x %e  + ------- - 1
                                                 sqrt(y)

          (%i5) poly_expand(-1-sin(x)^2+sin(x),[sin(x)]);
                                          2
          (%o5)                      - sin (x) + sin(x) - 1

 -- Function: poly_expt (<poly>, <number>, <varlist>)
     exponentitates <poly> by a positive integer <number>.  If <number>
     is not a positive integer number an error will be raised.

          (%i1) poly_expt(x-y,3,[x,y])-(x-y)^3,expand;
          (%o1)                                  0

 -- Function: poly_content (<poly>. <varlist>)
     ‘poly_content’ extracts the GCD of its coefficients

          (%i1) poly_content(35*y+21*x,[x,y]);
          (%o1)                                  7

 -- Function: poly_pseudo_divide (<poly>, <polylist>, <varlist>)
     Pseudo-divide a polynomial <poly> by the list of n polynomials
     <polylist>.  Return multiple values.  The first value is a list of
     quotients a.  The second value is the remainder r.  The third
     argument is a scalar coefficient c, such that c*poly can be divided
     by <polylist> within the ring of coefficients, which is not
     necessarily a field.  Finally, the fourth value is an integer count
     of the number of reductions performed.  The resulting objects
     satisfy the equation:

     c*poly=sum(a[i]*polylist[i],i=1...n)+r.

 -- Function: poly_exact_divide (<poly1>, <poly2>, <varlist>)
     Divide a polynomial <poly1> by another polynomial <poly2>.  Assumes
     that exact division with no remainder is possible.  Returns the
     quotient.

 -- Function: poly_normal_form (<poly>, <polylist>, <varlist>)
     ‘poly_normal_form’ finds the normal form of a polynomial <poly>
     with respect to a set of polynomials <polylist>.

 -- Function: poly_buchberger_criterion (<polylist>, <varlist>)
     Returns ‘true’ if <polylist> is a Groebner basis with respect to
     the current term order, by using the Buchberger criterion: for
     every two polynomials h1 and h2 in <polylist> the S-polynomial
     S(h1,h2) reduces to 0 modulo <polylist>.

 -- Function: poly_buchberger (<polylist_fl> <varlist>)
     ‘poly_buchberger’ performs the Buchberger algorithm on a list of
     polynomials and returns the resulting Groebner basis.

67.2.4 Standard postprocessing of Groebner Bases
------------------------------------------------

The _k-th elimination Ideal_ I_k of an Ideal I over K[ x[1],...,x[n] ]
is the ideal intersect(I, K[ x[k+1],...,x[n] ]).

The _colon ideal_ I:J is the ideal {h|for all w in J: w*h in I}.

The ideal I:p^inf is the ideal {h| there is a n in N: p^n*h in I}.

The ideal I:J^inf is the ideal {h| there is a n in N and a p in J: p^n*h
in I}.

The _radical ideal_ sqrt(I) is the ideal {h| there is a n in N : h^n in
I }.

 -- Function: poly_reduction (<polylist>, <varlist>)
     ‘poly_reduction’ reduces a list of polynomials <polylist>, so that
     each polynomial is fully reduced with respect to the other
     polynomials.

 -- Function: poly_minimization (<polylist>, <varlist>)
     Returns a sublist of the polynomial list <polylist> spanning the
     same monomial ideal as <polylist> but minimal, i.e.  no leading
     monomial of a polynomial in the sublist divides the leading
     monomial of another polynomial.

 -- Function: poly_normalize_list (<polylist>, <varlist>)
     ‘poly_normalize_list’ applies ‘poly_normalize’ to each polynomial
     in the list.  That means it divides every polynomial in a list
     <polylist> by its leading coefficient.

 -- Function: poly_grobner (<polylist>, <varlist>)
     Returns a Groebner basis of the ideal span by the polynomials
     <polylist>.  Affected by the global flags.

 -- Function: poly_reduced_grobner (<polylist>, <varlist>)
     Returns a reduced Groebner basis of the ideal span by the
     polynomials <polylist>.  Affected by the global flags.

 -- Function: poly_depends_p (<poly>, <var>, <varlist>)
     ‘poly_depends’ tests whether a polynomial depends on a variable
     <var>.

 -- Function: poly_elimination_ideal (<polylist>, <number>, <varlist>)

     ‘poly_elimination_ideal’ returns the grobner basis of the number-th
     elimination ideal of an ideal specified as a list of generating
     polynomials (not necessarily Groebner basis).

 -- Function: poly_colon_ideal (<polylist1>, <polylist2>, <varlist>)

     Returns the reduced Groebner basis of the colon ideal

     I(polylist1):I(polylist2)

     where polylist1 and polylist2 are two lists of polynomials.

 -- Function: poly_ideal_intersection (<polylist1>, <polylist2>,
          <varlist>)

     ‘poly_ideal_intersection’ returns the intersection of two ideals.

 -- Function: poly_lcm (<poly1>, <poly2>, <varlist>)
     Returns the lowest common multiple of <poly1> and <poly2>.

 -- Function: poly_gcd (<poly1>, <poly2>, <varlist>)

     Returns the greatest common divisor of <poly1> and <poly2>.

     See also ‘ezgcd’, ‘gcd’, ‘gcdex’, and *note gcdivide::.

     Example:

          (%i1) p1:6*x^3+19*x^2+19*x+6;
                                  3       2
          (%o1)                6 x  + 19 x  + 19 x + 6
          (%i2) p2:6*x^5+13*x^4+12*x^3+13*x^2+6*x;
                            5       4       3       2
          (%o2)          6 x  + 13 x  + 12 x  + 13 x  + 6 x
          (%i3) poly_gcd(p1, p2, [x]);
                                      2
          (%o3)                    6 x  + 13 x + 6

 -- Function: poly_grobner_equal (<polylist1>, <polylist2>, <varlist>)
     ‘poly_grobner_equal’ tests whether two Groebner Bases generate the
     same ideal.  Returns ‘true’ if two lists of polynomials <polylist1>
     and <polylist2>, assumed to be Groebner Bases, generate the same
     ideal, and ‘false’ otherwise.  This is equivalent to checking that
     every polynomial of the first basis reduces to 0 modulo the second
     basis and vice versa.  Note that in the example below the first
     list is not a Groebner basis, and thus the result is ‘false’.

          (%i1) poly_grobner_equal([y+x,x-y],[x,y],[x,y]);
          (%o1)                         false

 -- Function: poly_grobner_subsetp (<polylist1>, <polylist2>, <varlist>)

     ‘poly_grobner_subsetp’ tests whether an ideal generated by
     <polylist1> is contained in the ideal generated by <polylist2>.
     For this test to always succeed, <polylist2> must be a Groebner
     basis.

 -- Function: poly_grobner_member (<poly>, <polylist>, <varlist>)

     Returns ‘true’ if a polynomial <poly> belongs to the ideal
     generated by the polynomial list <polylist>, which is assumed to be
     a Groebner basis.  Returns ‘false’ otherwise.

     ‘poly_grobner_member’ tests whether a polynomial belongs to an
     ideal generated by a list of polynomials, which is assumed to be a
     Groebner basis.  Equivalent to ‘normal_form’ being 0.

 -- Function: poly_ideal_saturation1 (<polylist>, <poly>, <varlist>)
     Returns the reduced Groebner basis of the saturation of the ideal

     I(polylist):poly^inf

     Geometrically, over an algebraically closed field, this is the set
     of polynomials in the ideal generated by <polylist> which do not
     identically vanish on the variety of <poly>.

 -- Function: poly_ideal_saturation (<polylist1>, <polylist2>,
          <varlist>)
     Returns the reduced Groebner basis of the saturation of the ideal

     I(polylist1):I(polylist2)^inf

     Geometrically, over an algebraically closed field, this is the set
     of polynomials in the ideal generated by <polylist1> which do not
     identically vanish on the variety of <polylist2>.

 -- Function: poly_ideal_polysaturation1 (<polylist1>, <polylist2>,
          <varlist>)
     <polylist2> is a list of n polynomials ‘[poly1,...,polyn]’.
     Returns the reduced Groebner basis of the ideal

     I(polylist):poly1^inf:...:polyn^inf

     obtained by a sequence of successive saturations in the polynomials
     of the polynomial list <polylist2> of the ideal generated by the
     polynomial list <polylist1>.

 -- Function: poly_ideal_polysaturation (<polylist>, <polylistlist>,
          <varlist>)
     <polylistlist> is a list of n list of polynomials
     ‘[polylist1,...,polylistn]’.  Returns the reduced Groebner basis of
     the saturation of the ideal

     I(polylist):I(polylist_1)^inf:...:I(polylist_n)^inf

 -- Function: poly_saturation_extension (<poly>, <polylist>, <varlist1>,
          <varlist2>)

     ‘poly_saturation_extension’ implements the famous Rabinowitz trick.

 -- Function: poly_polysaturation_extension (<poly>, <polylist>,
          <varlist1>, <varlist2>)


File: maxima.info,  Node: Package hompack,  Next: Package impdiff,  Prev: Package grobner,  Up: Top

68 Package hompack
******************

* Menu:

* Introduction to hompack::
* Functions and Variables for hompack::


File: maxima.info,  Node: Introduction to hompack,  Next: Functions and Variables for hompack,  Up: Package hompack

68.1 Introduction to hompack
============================

‘Hompack’ is a Common Lisp translation (via ‘f2cl’) of the Fortran
library HOMPACK, as obtained from Netlib.


File: maxima.info,  Node: Functions and Variables for hompack,  Prev: Introduction to hompack,  Up: Package hompack

68.2 Functions and Variables for hompack
========================================

 -- Function: hompack_polsys (<eqnlist>, <varlist> [, <iflg1>, <epsbig>,
          <epssml>, <numrr>])
     Finds the roots of the system of polynomials in the variables
     <varlist> in the system of equations in <eqnlist>.  The number of
     equations must match number of variables.  Each equation must be a
     polynomial with variables in <varlist>.  The coefficients must be
     real numbers.

     The optional keyword arguments provide some control over the
     algorithm.

     ‘epsbig’
          is the local error tolerance allowed by the path tracker,
          defaulting to 1e-4.
     ‘epssml’
          is the accuracy desired for the final solution, defaulting to
          1d-14.
     ‘numrr’
          is the number of multiples of 1000 steps that will be tried
          before abandoning a path, defaulting to 10.
     ‘iflg1’
          defaulting to 0, controls the algorithm as follows:
          ‘0’
               If the problem is to be solved without calling ‘polsys’'
               scaling routine, ‘sclgnp’, and without using the
               projective transformation.
          ‘1’
               If scaling but no projective transformation is to be
               used.
          ‘10’
               If no scaling but projective transformation is to be
               used.
          ‘11’
               If both scaling and projective transformation are to be
               used.

     ‘hompack_polsys’ returns a list.  The elements of the list are:
     ‘retcode’
          Indicates whether the solution is valid or not.
          ‘0’
               Solution found without problems
          ‘1’
               Solution succeeded but ‘iflg2’ indicates some issues with
               a root.  (That is, ‘iflg2’ is not all ones.)
          ‘-1’
               ‘NN’, the declared dimension of the number of terms in
               the polynomials, is too small.  (This should not happen.)
          ‘-2’
               ‘MMAXT’, the declared dimension for the internal
               coefficient and degree arrays, is too small.  (This
               should not happen.)
          ‘-3’
               ‘TTOTDG’, the total degree of the equations, is too
               small.  (This should not happen.)
          ‘-4’
               ‘LENWK’, the length of the internal real work array, is
               too small.  (This should not happen.)
          ‘-5’
               ‘LENIWK’, the length of the internal integer work array,
               is too small.  (This should not happen.)
          ‘-6’
               <iflg1> is not 0 or 1, or 10 or 11.  (This should not
               happen; an error should be thrown before ‘polsys’ is
               called.)
     ‘roots’
          The roots of the system of equations.  This is in the same
          format as ‘solve’ would return.
     ‘iflg2’
          A list containing information on how the path for the m'th
          root terminated:
          ‘1’
               Normal return
          ‘2’
               Specified error tolerance cannot be met.  Increase
               <epsbig> and <epssml> and rerun.
          ‘3’
               Maximum number of steps exceeded.  To track the path
               further, increase <numrr> and rerun the path.  However,
               the path may be diverging, if the lambda value is near 1
               and the roots values are large.
          ‘4’
               Jacobian matrix does not have full rank.  The algorithm
               has failed (the zero curve of the homotopy map cannot be
               followed any further).
          ‘5’
               The tracking algorithm has lost the zero curve of the
               homotopy map and is not making progress.  The error
               tolerances <epsbig> and <epssml> were too lenient.  The
               problem should be restarted with smaller error
               tolerances.
          ‘6’
               The normal flow newton iteration in ‘stepnf’ or ‘rootnf’
               failed to converge.  The error tolerance <epsbig> may be
               too stringent.
          ‘7’
               Illegal input parameters, a fatal error.
     ‘lambda’
          A list of the final lambda value for the m-th root, where
          lambda is the continuation parameter.
     ‘arclen’
          A list of the arc length of the m-th root.
     ‘nfe’
          A list of the number of jacobian matrix evaluations required
          to track the m-th root.

     Here are some examples of using ‘hompack_polsys’.
          (%i1) load(hompack)$
          (%i2) hompack_polsys([x1^2-1, x2^2-2],[x1,x2]);
          (%o2) [0, [[x1 = 7.493410174972965e-17 %i - 1.0,
          x2 = - 2.1199276810167172e-16 %i - 1.4142135623730951],
          [x1 = 1.0 - 1.7812202259088373e-17 %i,
          x2 = - 9.892128000334418e-17 %i - 1.4142135623730951],
          [x1 = - 8.745710933584358e-17 %i - 1.0,
          x2 = 1.4142135623730951 - 3.1543521174128613e-17 %i],
          [x1 = 1.0 - 5.5487454344135625e-18 %i,
          x2 = 9.617653810456737e-17 %i + 1.4142135623730951]],
          [1, 1, 1, 1], [1.0, 1.0, 0.9999999999999999,
          0.9999999999999999], [4.6126237693413445, 4.6126230108601,
          4.612623872939582, 4.6126231144843475], [40, 40, 40, 40]]

     The analytical solution can be obtained with solve:
          (%i1) solve([x1^2-1, x2^2-2],[x1,x2]);
          (%o1) [[x1 = 1, x2 = - sqrt(2)], [x1 = 1, x2 = sqrt(2)],
                      [x1 = - 1, x2 = - sqrt(2)], [x1 = - 1, x2 = sqrt(2)]]
     We see that ‘hompack_polsys’ returned the correct answer except
     that the roots are in a different order and there is a small
     imaginary part.

     Another example, with corresponding solution from solve:
          (%i1) load(hompack)$
          (%i2) hompack_polsys([x1^2 + 2*x2^2 + x1*x2 - 5, 2*x1^2 + x2^2 + x2-4],[x1,x2]);
          (%o2) [0, [[x1 = 1.2015573017007832 - 6.51849608628558e-16 %i,
          x2 = - 2.2667444298167825e-16 %i - 1.6672703634801431],
          [x1 = - 5.901956169878514e-17 %i - 1.4285291895653132,
          x2 = - 6.670215053038164e-17 %i - 0.9106199083334114],
          [x1 = 1.942890293094024e-16 %i + 0.5920619420732687,
          x2 = 1.383859154368197 - 1.942890293094024e-16 %i],
          [x1 = 0.08945540033671631 - 8.534583737796769e-16 %i,
          x2 = 2.415141536592239e-16 %i + 1.5576674810817213]],
          [1, 1, 1, 1], [1.0000000000000004, 1.0000000000000002, 1.0,
          0.9999999999999999], [6.205795654034981, 7.7222132593900525,
          7.228287079174324, 5.6114742835849105], [35, 41, 48, 40]]
          (%i3) solve([x1^2+2*x2^2+x1*x2 - 5, 2*x1^2+x2^2+x2-4],[x1,x2]);
          (%o3) [[x1 = 0.08945540336850383, x2 = 1.5576673866090713],
          [x1 = 0.5920619554695062, x2 = 1.3838592860838075],
          [x1 = 1.2015573525007488, x2 = - 1.66727025803531],
          [x1 = - 1.428529150636283, x2 = - 0.9106198942815954]]

     Note that ‘hompack_polsys’ can sometimes be very slow.  Perhaps
     ‘solve’ can be used.  Or perhaps ‘eliminate’ can be used to convert
     the system of polynomials into one polynomial for which ‘allroots’
     can find all the roots.


File: maxima.info,  Node: Package impdiff,  Next: Package interpol,  Prev: Package hompack,  Up: Top

69 Package impdiff
******************

* Menu:

* Functions and Variables for impdiff::


File: maxima.info,  Node: Functions and Variables for impdiff,  Prev: Package impdiff,  Up: Package impdiff

69.1 Functions and Variables for impdiff
========================================

 -- Function: implicit_derivative
          (<f>,<indvarlist>,<orderlist>,<depvar>)
     This subroutine computes implicit derivatives of multivariable
     functions.  <f> is an array function, the indexes are the
     derivative degree in the <indvarlist> order; <indvarlist> is the
     independent variable list; <orderlist> is the order desired; and
     <depvar> is the dependent variable.

     To use this function write first ‘load("impdiff")’.


File: maxima.info,  Node: Package interpol,  Next: Package itensor,  Prev: Package impdiff,  Up: Top

70 Package interpol
*******************

* Menu:

* Introduction to interpol::
* Functions and Variables for interpol::


File: maxima.info,  Node: Introduction to interpol,  Next: Functions and Variables for interpol,  Prev: Package interpol,  Up: Package interpol

70.1 Introduction to interpol
=============================

Package ‘interpol’ defines the Lagrangian, the linear and the cubic
splines methods for polynomial interpolation.

   For comments, bugs or suggestions, please contact me at <'mario AT
edu DOT xunta DOT es'>.


File: maxima.info,  Node: Functions and Variables for interpol,  Prev: Introduction to interpol,  Up: Package interpol

70.2 Functions and Variables for interpol
=========================================

 -- Function: lagrange
          lagrange (<points>)
          lagrange (<points>, <option>)

     Computes the polynomial interpolation by the Lagrangian method.
     Argument <points> must be either:

        • a two column matrix, ‘p:matrix([2,4],[5,6],[9,3])’,
        • a list of pairs, ‘p: [[2,4],[5,6],[9,3]]’,
        • a list of numbers, ‘p: [4,6,3]’, in which case the abscissas
          will be assigned automatically to 1, 2, 3, etc.

     In the first two cases the pairs are ordered with respect to the
     first coordinate before making computations.

     With the <option> argument it is possible to select the name for
     the independent variable, which is ‘'x’ by default; to define
     another one, write something like ‘varname='z’.

     Note that when working with high degree polynomials, floating point
     evaluations are unstable.

     See also ‘linearinterpol’, ‘cspline’, and *note ratinterpol::.

     Examples:

          (%i1) load("interpol")$
          (%i2) p:[[7,2],[8,2],[1,5],[3,2],[6,7]]$
          (%i3) lagrange(p);
                 (x - 7) (x - 6) (x - 3) (x - 1)
          (%o3)  -------------------------------
                               35
             (x - 8) (x - 6) (x - 3) (x - 1)
           - -------------------------------
                           12
             7 (x - 8) (x - 7) (x - 3) (x - 1)
           + ---------------------------------
                            30
             (x - 8) (x - 7) (x - 6) (x - 1)
           - -------------------------------
                           60
             (x - 8) (x - 7) (x - 6) (x - 3)
           + -------------------------------
                           84
          (%i4) f(x):=''%;
                         (x - 7) (x - 6) (x - 3) (x - 1)
          (%o4)  f(x) := -------------------------------
                                       35
             (x - 8) (x - 6) (x - 3) (x - 1)
           - -------------------------------
                           12
             7 (x - 8) (x - 7) (x - 3) (x - 1)
           + ---------------------------------
                            30
             (x - 8) (x - 7) (x - 6) (x - 1)
           - -------------------------------
                           60
             (x - 8) (x - 7) (x - 6) (x - 3)
           + -------------------------------
                           84
          (%i5) /* Evaluate the polynomial at some points */
                expand(map(f,[2.3,5/7,%pi]));
                                            4          3           2
                              919062  73 %pi    701 %pi    8957 %pi
          (%o5)  [- 1.567535, ------, ------- - -------- + ---------
                              84035     420       210         420
                                                       5288 %pi   186
                                                     - -------- + ---]
                                                         105       5
          (%i6) %,numer;
          (%o6) [- 1.567535, 10.9366573451538, 2.89319655125692]
          (%i7) load("draw")$  /* load draw package */
          (%i8) /* Plot the polynomial together with points */
                draw2d(
                  color      = red,
                  key        = "Lagrange polynomial",
                  explicit(f(x),x,0,10),
                  point_size = 3,
                  color      = blue,
                  key        = "Sample points",
                  points(p))$
          (%i9) /* Change variable name */
                lagrange(p, varname=w);
                 (w - 7) (w - 6) (w - 3) (w - 1)
          (%o9)  -------------------------------
                               35
             (w - 8) (w - 6) (w - 3) (w - 1)
           - -------------------------------
                           12
             7 (w - 8) (w - 7) (w - 3) (w - 1)
           + ---------------------------------
                            30
             (w - 8) (w - 7) (w - 6) (w - 1)
           - -------------------------------
                           60
             (w - 8) (w - 7) (w - 6) (w - 3)
           + -------------------------------
                           84

 -- Function: charfun2 (<x>, <a>, <b>)

     The characteristic or indicator function on the half-open interval
     [<a>, <b>), that is, including <a> and excluding <b>.

     When <x> >= <a> and <x> < <b> evaluates to ‘true’ or ‘false’,
     ‘charfun2’ returns 1 or 0, respectively.

     Otherwise, ‘charfun2’ returns a partially-evaluated result in terms
     of ‘charfun’.

     Package ‘interpol’ loads this function.

     See also *note charfun::.

     Examples:

     When <x> >= <a> and <x> < <b> evaluates to ‘true’ or ‘false’,
     ‘charfun2’ returns 1 or 0, respectively.

          (%i1) load ("interpol") $
          (%i2) charfun2 (5, 0, 100);
          (%o2)                           1
          (%i3) charfun2 (-5, 0, 100);
          (%o3)                           0

     Otherwise, ‘charfun2’ returns a partially-evaluated result in terms
     of ‘charfun’.

          (%i1) load ("interpol") $
          (%i2) charfun2 (t, 0, 100);
          (%o2)            charfun((0 <= t) and (t < 100))
          (%i3) charfun2 (5, u, v);
          (%o3)             charfun((u <= 5) and (5 < v))
          (%i4) assume (v > u, u > 5);
          (%o4)                    [v > u, u > 5]
          (%i5) charfun2 (5, u, v);
          (%o5)                           0

 -- Function: linearinterpol
          linearinterpol (<points>)
          linearinterpol (<points>, <option>)

     Computes the polynomial interpolation by the linear method.
     Argument <points> must be either:

        • a two column matrix, ‘p:matrix([2,4],[5,6],[9,3])’,
        • a list of pairs, ‘p: [[2,4],[5,6],[9,3]]’,
        • a list of numbers, ‘p: [4,6,3]’, in which case the abscissas
          will be assigned automatically to 1, 2, 3, etc.

     In the first two cases the pairs are ordered with respect to the
     first coordinate before making computations.

     With the <option> argument it is possible to select the name for
     the independent variable, which is ‘'x’ by default; to define
     another one, write something like ‘varname='z’.

     See also ‘lagrange’, ‘cspline’, and *note ratinterpol::.

     Examples:

          (%i1) load("interpol")$
          (%i2) p: matrix([7,2],[8,3],[1,5],[3,2],[6,7])$
          (%i3) linearinterpol(p);
                  13   3 x
          (%o3)  (-- - ---) charfun2(x, minf, 3)
                  2     2
           + (x - 5) charfun2(x, 7, inf) + (37 - 5 x) charfun2(x, 6, 7)
              5 x
           + (--- - 3) charfun2(x, 3, 6)
               3

          (%i4) f(x):=''%;
                          13   3 x
          (%o4)  f(x) := (-- - ---) charfun2(x, minf, 3)
                          2     2
           + (x - 5) charfun2(x, 7, inf) + (37 - 5 x) charfun2(x, 6, 7)
              5 x
           + (--- - 3) charfun2(x, 3, 6)
               3
          (%i5)  /* Evaluate the polynomial at some points */
                 map(f,[7.3,25/7,%pi]);
                                      62  5 %pi
          (%o5)                 [2.3, --, ----- - 3]
                                      21    3
          (%i6) %,numer;
          (%o6)  [2.3, 2.952380952380953, 2.235987755982989]
          (%i7) load("draw")$  /* load draw package */
          (%i8)  /* Plot the polynomial together with points */
                 draw2d(
                   color      = red,
                   key        = "Linear interpolator",
                   explicit(f(x),x,-5,20),
                   point_size = 3,
                   color      = blue,
                   key        = "Sample points",
                   points(args(p)))$
          (%i9)  /* Change variable name */
                 linearinterpol(p, varname='s);
                 13   3 s
          (%o9) (-- - ---) charfun2(s, minf, 3)
                 2     2
           + (s - 5) charfun2(s, 7, inf) + (37 - 5 s) charfun2(s, 6, 7)
              5 s
           + (--- - 3) charfun2(s, 3, 6)
               3

 -- Function: cspline
          cspline (<points>)
          cspline (<points>, <option1>, <option2>, ...)

     Computes the polynomial interpolation by the cubic splines method.
     Argument <points> must be either:

        • a two column matrix, ‘p:matrix([2,4],[5,6],[9,3])’,
        • a list of pairs, ‘p: [[2,4],[5,6],[9,3]]’,
        • a list of numbers, ‘p: [4,6,3]’, in which case the abscissas
          will be assigned automatically to 1, 2, 3, etc.

     In the first two cases the pairs are ordered with respect to the
     first coordinate before making computations.

     There are three options to fit specific needs:
        • ‘'d1’, default ‘'unknown’, is the first derivative at x_1; if
          it is ‘'unknown’, the second derivative at x_1 is made equal
          to 0 (natural cubic spline); if it is equal to a number, the
          second derivative is calculated based on this number.

        • ‘'dn’, default ‘'unknown’, is the first derivative at x_n; if
          it is ‘'unknown’, the second derivative at x_n is made equal
          to 0 (natural cubic spline); if it is equal to a number, the
          second derivative is calculated based on this number.

        • ‘'varname’, default ‘'x’, is the name of the independent
          variable.

     See also ‘lagrange’, ‘linearinterpol’, and *note ratinterpol::.

     Examples:
          (%i1) load("interpol")$
          (%i2) p:[[7,2],[8,2],[1,5],[3,2],[6,7]]$
          (%i3) /* Unknown first derivatives at the extremes
                   is equivalent to natural cubic splines */
                cspline(p);
                        3         2
                  1159 x    1159 x    6091 x   8283
          (%o3)  (------- - ------- - ------ + ----) charfun2(x, minf, 3)
                   3288      1096      3288    1096
                      3         2
                2587 x    5174 x    494117 x   108928
           + (- ------- + ------- - -------- + ------) charfun2(x, 7, inf)
                 1644       137       1644      137
                    3          2
              4715 x    15209 x    579277 x   199575
           + (------- - -------- + -------- - ------) charfun2(x, 6, 7)
               1644       274        1644      274
                      3         2
                3287 x    2223 x    48275 x   9609
           + (- ------- + ------- - ------- + ----) charfun2(x, 3, 6)
                 4932       274      1644     274

          (%i4) f(x):=''%$
          (%i5) /* Some evaluations */
                map(f,[2.3,5/7,%pi]), numer;
          (%o5) [1.991460766423356, 5.823200187269903, 2.227405312429507]
          (%i6) load("draw")$  /* load draw package */
          (%i7) /* Plotting interpolating function */
                draw2d(
                  color      = red,
                  key        = "Cubic splines",
                  explicit(f(x),x,0,10),
                  point_size = 3,
                  color      = blue,
                  key        = "Sample points",
                  points(p))$
          (%i8) /* New call, but giving values at the derivatives */
                cspline(p,d1=0,dn=0);
                        3          2
                  1949 x    11437 x    17027 x   1247
          (%o8)  (------- - -------- + ------- + ----) charfun2(x, minf, 3)
                   2256       2256      2256     752
                      3          2
                1547 x    35581 x    68068 x   173546
           + (- ------- + -------- - ------- + ------) charfun2(x, 7, inf)
                  564       564        141      141
                   3          2
              607 x    35147 x    55706 x   38420
           + (------ - -------- + ------- - -----) charfun2(x, 6, 7)
               188       564        141      47
                      3         2
                3895 x    1807 x    5146 x   2148
           + (- ------- + ------- - ------ + ----) charfun2(x, 3, 6)
                 5076       188      141      47
          (%i8) /* Defining new interpolating function */
                g(x):=''%$
          (%i9) /* Plotting both functions together */
                draw2d(
                  color      = black,
                  key        = "Cubic splines (default)",
                  explicit(f(x),x,0,10),
                  color      = red,
                  key        = "Cubic splines (d1=0,dn=0)",
                  explicit(g(x),x,0,10),
                  point_size = 3,
                  color      = blue,
                  key        = "Sample points",
                  points(p))$

 -- Function: ratinterpol
          ratinterpol (<points>, <numdeg>)
          ratinterpol (<points>, <numdeg>, <option1>)

     Generates a rational interpolator for data given by <points> and
     the degree of the numerator being equal to <numdeg>; the degree of
     the denominator is calculated automatically.  Argument <points>
     must be either:

        • a two column matrix, ‘p:matrix([2,4],[5,6],[9,3])’,
        • a list of pairs, ‘p: [[2,4],[5,6],[9,3]]’,
        • a list of numbers, ‘p: [4,6,3]’, in which case the abscissas
          will be assigned automatically to 1, 2, 3, etc.

     In the first two cases the pairs are ordered with respect to the
     first coordinate before making computations.

     There is one option to fit specific needs:
        • ‘'varname’, default ‘'x’, is the name of the independent
          variable.

     See also ‘lagrange’, ‘linearinterpol’, ‘cspline’,
     ‘minpack_lsquares’, and *note Package lbfgs::

     Examples:

          (%i1) load("interpol")$
          (%i2) load("draw")$
          (%i3) p:[[7.2,2.5],[8.5,2.1],[1.6,5.1],[3.4,2.4],[6.7,7.9]]$
          (%i4) for k:0 thru length(p)-1 do
                  draw2d(
                    explicit(ratinterpol(p,k),x,0,9),
                    point_size = 3,
                    points(p),
                    title = concat("Degree of numerator = ",k),
                    yrange=[0,10])$


File: maxima.info,  Node: Package itensor,  Next: Package lapack,  Prev: Package interpol,  Up: Top

71 Package itensor
******************

* Menu:

* Introduction to itensor::
* Functions and Variables for itensor::


File: maxima.info,  Node: Introduction to itensor,  Next: Functions and Variables for itensor,  Prev: Package itensor,  Up: Package itensor

71.1 Introduction to itensor
============================

Maxima implements symbolic tensor manipulation of two distinct types:
component tensor manipulation (*note Package ctensor::) and indicial
tensor manipulation (*note Package itensor::).

   Nota bene: Please see the note on 'new tensor notation' below.

   Component tensor manipulation means that geometrical tensor objects
are represented as arrays or matrices.  Tensor operations such as
contraction or covariant differentiation are carried out by actually
summing over repeated (dummy) indices with ‘do’ statements.  That is,
one explicitly performs operations on the appropriate tensor components
stored in an array or matrix.

   Indicial tensor manipulation is implemented by representing tensors
as functions of their covariant, contravariant and derivative indices.
Tensor operations such as contraction or covariant differentiation are
performed by manipulating the indices themselves rather than the
components to which they correspond.

   These two approaches to the treatment of differential, algebraic and
analytic processes in the context of Riemannian geometry have various
advantages and disadvantages which reveal themselves only through the
particular nature and difficulty of the user's problem.  However, one
should keep in mind the following characteristics of the two
implementations:

   The representation of tensors and tensor operations explicitly in
terms of their components makes ‘ctensor’ easy to use.  Specification of
the metric and the computation of the induced tensors and invariants is
straightforward.  Although all of Maxima's powerful simplification
capacity is at hand, a complex metric with intricate functional and
coordinate dependencies can easily lead to expressions whose size is
excessive and whose structure is hidden.  In addition, many calculations
involve intermediate expressions which swell causing programs to
terminate before completion.  Through experience, a user can avoid many
of these difficulties.

   Because of the special way in which tensors and tensor operations are
represented in terms of symbolic operations on their indices,
expressions which in the component representation would be unmanageable
can sometimes be greatly simplified by using the special routines for
symmetrical objects in ‘itensor’.  In this way the structure of a large
expression may be more transparent.  On the other hand, because of the
special indicial representation in ‘itensor’, in some cases the user may
find difficulty with the specification of the metric, function
definition, and the evaluation of differentiated "indexed" objects.

   The ‘itensor’ package can carry out differentiation with respect to
an indexed variable, which allows one to use the package when dealing
with Lagrangian and Hamiltonian formalisms.  As it is possible to
differentiate a field Lagrangian with respect to an (indexed) field
variable, one can use Maxima to derive the corresponding Euler-Lagrange
equations in indicial form.  These equations can be translated into
component tensor (‘ctensor’) programs using the ‘ic_convert’ function,
allowing us to solve the field equations in a particular coordinate
representation, or to recast the equations of motion in Hamiltonian
form.  See ‘einhil.dem’ and ‘bradic.dem’ for two comprehensive examples.
The first, ‘einhil.dem’, uses the Einstein-Hilbert action to derive the
Einstein field tensor in the homogeneous and isotropic case (Friedmann
equations) and the spherically symmetric, static case (Schwarzschild
solution.)  The second, ‘bradic.dem’, demonstrates how to compute the
Friedmann equations from the action of Brans-Dicke gravity theory, and
also derives the Hamiltonian associated with the theory's scalar field.

71.1.1 New tensor notation
--------------------------

Earlier versions of the ‘itensor’ package in Maxima used a notation that
sometimes led to incorrect index ordering.  Consider the following, for
instance:

     (%i2) imetric(g);
     (%o2)                                done
     (%i3) ishow(g([],[j,k])*g([],[i,l])*a([i,j],[]))$
                                      i l  j k
     (%t3)                           g    g    a
                                                i j
     (%i4) ishow(contract(%))$
                                           k l
     (%t4)                                a

   This result is incorrect unless ‘a’ happens to be a symmetric tensor.
The reason why this happens is that although ‘itensor’ correctly
maintains the order within the set of covariant and contravariant
indices, once an index is raised or lowered, its position relative to
the other set of indices is lost.

   To avoid this problem, a new notation has been developed that remains
fully compatible with the existing notation and can be used
interchangeably.  In this notation, contravariant indices are inserted
in the appropriate positions in the covariant index list, but with a
minus sign prepended.  Functions like ‘contract_Itensor’ and ‘ishow’ are
now aware of this new index notation and can process tensors
appropriately.

   In this new notation, the previous example yields a correct result:

     (%i5) ishow(g([-j,-k],[])*g([-i,-l],[])*a([i,j],[]))$
                                      i l       j k
     (%t5)                           g    a    g
                                           i j
     (%i6) ishow(contract(%))$
                                           l k
     (%t6)                                a

   Presently, the only code that makes use of this notation is the
‘lc2kdt’ function.  Through this notation, it achieves consistent
results as it applies the metric tensor to resolve Levi-Civita symbols
without resorting to numeric indices.

   Since this code is brand new, it probably contains bugs.  While it
has been tested to make sure that it doesn't break anything using the
"old" tensor notation, there is a considerable chance that "new" tensors
will fail to interoperate with certain functions or features.  These
bugs will be fixed as they are encountered...  until then, caveat
emptor!

71.1.2 Indicial tensor manipulation
-----------------------------------

The indicial tensor manipulation package may be loaded by
‘load("itensor")’.  Demos are also available: try ‘demo("tensor")’.

   In ‘itensor’ a tensor is represented as an "indexed object" .  This
is a function of 3 groups of indices which represent the covariant,
contravariant and derivative indices.  The covariant indices are
specified by a list as the first argument to the indexed object, and the
contravariant indices by a list as the second argument.  If the indexed
object lacks either of these groups of indices then the empty list ‘[]’
is given as the corresponding argument.  Thus, ‘g([a,b],[c])’ represents
an indexed object called ‘g’ which has two covariant indices ‘(a,b)’,
one contravariant index (‘c’) and no derivative indices.

   The derivative indices, if they are present, are appended as
additional arguments to the symbolic function representing the tensor.
They can be explicitly specified by the user or be created in the
process of differentiation with respect to some coordinate variable.
Since ordinary differentiation is commutative, the derivative indices
are sorted alphanumerically, unless ‘iframe_flag’ is set to ‘true’,
indicating that a frame metric is being used.  This canonical ordering
makes it possible for Maxima to recognize that, for example,
‘t([a],[b],i,j)’ is the same as ‘t([a],[b],j,i)’.  Differentiation of an
indexed object with respect to some coordinate whose index does not
appear as an argument to the indexed object would normally yield zero.
This is because Maxima would not know that the tensor represented by the
indexed object might depend implicitly on the corresponding coordinate.
By modifying the existing Maxima function ‘diff’ in ‘itensor’, Maxima
now assumes that all indexed objects depend on any variable of
differentiation unless otherwise stated.  This makes it possible for the
summation convention to be extended to derivative indices.  It should be
noted that ‘itensor’ does not possess the capabilities of raising
derivative indices, and so they are always treated as covariant.

   The following functions are available in the tensor package for
manipulating indexed objects.  At present, with respect to the
simplification routines, it is assumed that indexed objects do not by
default possess symmetry properties.  This can be overridden by setting
the variable ‘allsym[false]’ to ‘true’, which will result in treating
all indexed objects completely symmetric in their lists of covariant
indices and symmetric in their lists of contravariant indices.

   The ‘itensor’ package generally treats tensors as opaque objects.
Tensorial equations are manipulated based on algebraic rules,
specifically symmetry and contraction rules.  In addition, the ‘itensor’
package understands covariant differentiation, curvature, and torsion.
Calculations can be performed relative to a metric of moving frame,
depending on the setting of the ‘iframe_flag’ variable.

   A sample session below demonstrates how to load the ‘itensor’
package, specify the name of the metric, and perform some simple
calculations.

     (%i1) load("itensor");
     (%o1)      /share/tensor/itensor.lisp
     (%i2) imetric(g);
     (%o2)                                done
     (%i3) components(g([i,j],[]),p([i,j],[])*e([],[]))$
     (%i4) ishow(g([k,l],[]))$
     (%t4)                               e p
                                            k l
     (%i5) ishow(diff(v([i],[]),t))$
     (%t5)                                  0
     (%i6) depends(v,t);
     (%o6)                               [v(t)]
     (%i7) ishow(diff(v([i],[]),t))$
                                         d
     (%t7)                               -- (v )
                                         dt   i
     (%i8) ishow(idiff(v([i],[]),j))$
     (%t8)                                v
                                           i,j
     (%i9) ishow(extdiff(v([i],[]),j))$
     (%t9)                             v    - v
                                        j,i    i,j
                                       -----------
                                            2
     (%i10) ishow(liediff(v,w([i],[])))$
                                    %3          %3
     (%t10)                        v   w     + v   w
                                        i,%3    ,i  %3
     (%i11) ishow(covdiff(v([i],[]),j))$
                                                   %4
     (%t11)                        v    - v   ichr2
                                    i,j    %4      i j
     (%i12) ishow(ev(%,ichr2))$
                     %4 %5
     (%t12) v    - (g      v   (e p       + e   p     - e p       - e    p
             i,j            %4     j %5,i    ,i  j %5      i j,%5    ,%5  i j

                                              + e p       + e   p    ))/2
                                                   i %5,j    ,j  i %5
     (%i13) iframe_flag:true;
     (%o13)                               true
     (%i14) ishow(covdiff(v([i],[]),j))$
                                                  %6
     (%t14)                        v    - v   icc2
                                    i,j    %6     i j
     (%i15) ishow(ev(%,icc2))$
                                                  %6
     (%t15)                        v    - v   ifc2
                                    i,j    %6     i j
     (%i16) ishow(radcan(ev(%,ifc2,ifc1)))$
                  %6 %7                    %6 %7
     (%t16) - (ifg      v   ifb       + ifg      v   ifb       - 2 v
                         %6    j %7 i             %6    i j %7      i,j

                                                  %6 %7
                                             - ifg      v   ifb      )/2
                                                         %6    %7 i j
     (%i17) ishow(canform(s([i,j],[])-s([j,i])))$
     (%t17)                            s    - s
                                        i j    j i
     (%i18) decsym(s,2,0,[sym(all)],[]);
     (%o18)                               done
     (%i19) ishow(canform(s([i,j],[])-s([j,i])))$
     (%t19)                                 0
     (%i20) ishow(canform(a([i,j],[])+a([j,i])))$
     (%t20)                            a    + a
                                        j i    i j
     (%i21) decsym(a,2,0,[anti(all)],[]);
     (%o21)                               done
     (%i22) ishow(canform(a([i,j],[])+a([j,i])))$
     (%t22)                                 0


File: maxima.info,  Node: Functions and Variables for itensor,  Prev: Introduction to itensor,  Up: Package itensor

71.2 Functions and Variables for itensor
========================================

71.2.1 Managing indexed objects
-------------------------------

 -- Function: dispcon
          dispcon (<tensor_1>, <tensor_2>, ...)
          dispcon (all)

     Displays the contraction properties of its arguments as were given
     to ‘defcon’.  ‘dispcon (all)’ displays all the contraction
     properties which were defined.

 -- Function: entertensor (<name>)

     is a function which, by prompting, allows one to create an indexed
     object called <name> with any number of tensorial and derivative
     indices.  Either a single index or a list of indices (which may be
     null) is acceptable input (see the example under ‘covdiff’).

 -- Function: changename (<old>, <new>, <expr>)

     will change the name of all indexed objects called <old> to <new>
     in <expr>.  <old> may be either a symbol or a list of the form
     ‘[<name>, <m>, <n>]’ in which case only those indexed objects
     called <name> with <m> covariant and <n> contravariant indices will
     be renamed to <new>.

 -- Function: listoftens

     Lists all tensors in a tensorial expression, complete with their
     indices.  E.g.,


          (%i6) ishow(a([i,j],[k])*b([u],[],v)+c([x,y],[])*d([],[])*e)$
                                                   k
          (%t6)                        d e c    + a    b
                                            x y    i j  u,v
          (%i7) ishow(listoftens(%))$
                                         k
          (%t7)                        [a   , b   , c   , d]
                                         i j   u,v   x y

 -- Function: ishow (<expr>)

     displays <expr> with the indexed objects in it shown having their
     covariant indices as subscripts and contravariant indices as
     superscripts.  The derivative indices are displayed as subscripts,
     separated from the covariant indices by a comma (see the examples
     throughout this document).

 -- Function: indices (<expr>)

     Returns a list of two elements.  The first is a list of the free
     indices in <expr> (those that occur only once).  The second is the
     list of the dummy indices in <expr> (those that occur exactly
     twice) as the following example demonstrates.


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) ishow(a([i,j],[k,l],m,n)*b([k,o],[j,m,p],q,r))$
                                          k l      j m p
          (%t2)                          a        b
                                          i j,m n  k o,q r
          (%i3) indices(%);
          (%o3)                 [[l, p, i, n, o, q, r], [k, j, m]]

     A tensor product containing the same index more than twice is
     syntactically illegal.  ‘indices’ attempts to deal with these
     expressions in a reasonable manner; however, when it is called to
     operate upon such an illegal expression, its behavior should be
     considered undefined.

 -- Function: rename
          rename (<expr>)
          rename (<expr>, <count>)

     Returns an expression equivalent to <expr> but with the dummy
     indices in each term chosen from the set ‘[%1, %2,...]’, if the
     optional second argument is omitted.  Otherwise, the dummy indices
     are indexed beginning at the value of <count>.  Each dummy index in
     a product will be different.  For a sum, ‘rename’ will operate upon
     each term in the sum resetting the counter with each term.  In this
     way ‘rename’ can serve as a tensorial simplifier.  In addition, the
     indices will be sorted alphanumerically (if ‘allsym’ is ‘true’)
     with respect to covariant or contravariant indices depending upon
     the value of ‘flipflag’.  If ‘flipflag’ is ‘false’ then the indices
     will be renamed according to the order of the contravariant
     indices.  If ‘flipflag’ is ‘true’ the renaming will occur according
     to the order of the covariant indices.  It often happens that the
     combined effect of the two renamings will reduce an expression more
     than either one by itself.


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) allsym:true;
          (%o2)                                true
          (%i3) g([],[%4,%5])*g([],[%6,%7])*ichr2([%1,%4],[%3])*
          ichr2([%2,%3],[u])*ichr2([%5,%6],[%1])*ichr2([%7,r],[%2])-
          g([],[%4,%5])*g([],[%6,%7])*ichr2([%1,%2],[u])*
          ichr2([%3,%5],[%1])*ichr2([%4,%6],[%3])*ichr2([%7,r],[%2]),noeval$
          (%i4) expr:ishow(%)$
                 %4 %5  %6 %7      %3         u          %1         %2
          (%t4) g      g      ichr2      ichr2      ichr2      ichr2
                                   %1 %4      %2 %3      %5 %6      %7 r

                  %4 %5  %6 %7      u          %1         %3         %2
               - g      g      ichr2      ichr2      ichr2      ichr2
                                    %1 %2      %3 %5      %4 %6      %7 r
          (%i5) flipflag:true;
          (%o5)                                true
          (%i6) ishow(rename(expr))$
                 %2 %5  %6 %7      %4         u          %1         %3
          (%t6) g      g      ichr2      ichr2      ichr2      ichr2
                                   %1 %2      %3 %4      %5 %6      %7 r

                  %4 %5  %6 %7      u          %1         %3         %2
               - g      g      ichr2      ichr2      ichr2      ichr2
                                    %1 %2      %3 %4      %5 %6      %7 r
          (%i7) flipflag:false;
          (%o7)                                false
          (%i8) rename(%th(2));
          (%o8)                                  0
          (%i9) ishow(rename(expr))$
                 %1 %2  %3 %4      %5         %6         %7        u
          (%t9) g      g      ichr2      ichr2      ichr2     ichr2
                                   %1 %6      %2 %3      %4 r      %5 %7

                  %1 %2  %3 %4      %6         %5         %7        u
               - g      g      ichr2      ichr2      ichr2     ichr2
                                    %1 %3      %2 %6      %4 r      %5 %7

 -- Option variable: flipflag
     Default value: ‘false’

     If ‘false’ then the indices will be renamed according to the order
     of the contravariant indices, otherwise according to the order of
     the covariant indices.

     If ‘flipflag’ is ‘false’ then ‘rename’ forms a list of the
     contravariant indices as they are encountered from left to right
     (if ‘true’ then of the covariant indices).  The first dummy index
     in the list is renamed to ‘%1’, the next to ‘%2’, etc.  Then
     sorting occurs after the ‘rename’-ing (see the example under
     ‘rename’).

 -- Function: defcon
          defcon (<tensor_1>)
          defcon (<tensor_1>, <tensor_2>, <tensor_3>)

     gives <tensor_1> the property that the contraction of a product of
     <tensor_1> and <tensor_2> results in <tensor_3> with the
     appropriate indices.  If only one argument, <tensor_1>, is given,
     then the contraction of the product of <tensor_1> with any indexed
     object having the appropriate indices (say ‘my_tensor’) will yield
     an indexed object with that name, i.e.  ‘my_tensor’, and with a new
     set of indices reflecting the contractions performed.  For example,
     if ‘imetric:g’, then ‘defcon(g)’ will implement the raising and
     lowering of indices through contraction with the metric tensor.
     More than one ‘defcon’ can be given for the same indexed object;
     the latest one given which applies in a particular contraction will
     be used.  ‘contractions’ is a list of those indexed objects which
     have been given contraction properties with ‘defcon’.

 -- Function: remcon
          remcon (<tensor_1>, ..., <tensor_n>)
          remcon (all)

     Removes all the contraction properties from the (<tensor_1>, ...,
     <tensor_n>).  ‘remcon(all)’ removes all contraction properties from
     all indexed objects.

 -- Function: contract (<expr>)

     Carries out the tensorial contractions in <expr> which may be any
     combination of sums and products.  This function uses the
     information given to the ‘defcon’ function.  For best results,
     ‘expr’ should be fully expanded.  ‘ratexpand’ is the fastest way to
     expand products and powers of sums if there are no variables in the
     denominators of the terms.  The ‘gcd’ switch should be ‘false’ if
     GCD cancellations are unnecessary.

 -- Function: indexed_tensor (<tensor>)

     Must be executed before assigning components to a <tensor> for
     which a built in value already exists as with ‘ichr1’, ‘ichr2’,
     ‘icurvature’.  See the example under ‘icurvature’.

 -- Function: components (<tensor>, <expr>)

     permits one to assign an indicial value to an expression <expr>
     giving the values of the components of <tensor>.  These are
     automatically substituted for the tensor whenever it occurs with
     all of its indices.  The tensor must be of the form
     ‘t([...],[...])’ where either list may be empty.  <expr> can be any
     indexed expression involving other objects with the same free
     indices as <tensor>.  When used to assign values to the metric
     tensor wherein the components contain dummy indices one must be
     careful to define these indices to avoid the generation of multiple
     dummy indices.  Removal of this assignment is given to the function
     ‘remcomps’.

     It is important to keep in mind that ‘components’ cares only about
     the valence of a tensor, not about any particular index ordering.
     Thus assigning components to, say, ‘x([i,-j],[])’, ‘x([-j,i],[])’,
     or ‘x([i],[j])’ all produce the same result, namely components
     being assigned to a tensor named ‘x’ with valence ‘(1,1)’.

     Components can be assigned to an indexed expression in four ways,
     two of which involve the use of the ‘components’ command:

     1) As an indexed expression.  For instance:

          (%i2) components(g([],[i,j]),e([],[i])*p([],[j]))$
          (%i3) ishow(g([],[i,j]))$
                                                i  j
          (%t3)                                e  p

     2) As a matrix:


          (%i5) lg:-ident(4)$lg[1,1]:1$lg;
                                      [ 1   0    0    0  ]
                                      [                  ]
                                      [ 0  - 1   0    0  ]
          (%o5)                       [                  ]
                                      [ 0   0   - 1   0  ]
                                      [                  ]
                                      [ 0   0    0   - 1 ]
          (%i6) components(g([i,j],[]),lg);
          (%o6)                                done
          (%i7) ishow(g([i,j],[]))$
          (%t7)                                g
                                                i j
          (%i8) g([1,1],[]);
          (%o8)                                  1
          (%i9) g([4,4],[]);
          (%o9)                                 - 1

     3) As a function.  You can use a Maxima function to specify the
     components of a tensor based on its indices.  For instance, the
     following code assigns ‘kdelta’ to ‘h’ if ‘h’ has the same number
     of covariant and contravariant indices and no derivative indices,
     and ‘g’ otherwise:


          (%i4) h(l1,l2,[l3]):=if length(l1)=length(l2) and length(l3)=0
            then kdelta(l1,l2) else apply(g,append([l1,l2], l3))$
          (%i5) ishow(h([i],[j]))$
                                                    j
          (%t5)                               kdelta
                                                    i
          (%i6) ishow(h([i,j],[k],l))$
                                               k
          (%t6)                               g
                                               i j,l

     4) Using Maxima's pattern matching capabilities, specifically the
     ‘defrule’ and ‘applyb1’ commands:


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) matchdeclare(l1,listp);
          (%o2)                                done
          (%i3) defrule(r1,m(l1,[]),(i1:idummy(),
                g([l1[1],l1[2]],[])*q([i1],[])*e([],[i1])))$

          (%i4) defrule(r2,m([],l1),(i1:idummy(),
                w([],[l1[1],l1[2]])*e([i1],[])*q([],[i1])))$

          (%i5) ishow(m([i,n],[])*m([],[i,m]))$
                                              i m
          (%t5)                              m    m
                                                   i n
          (%i6) ishow(rename(applyb1(%,r1,r2)))$
                                     %1  %2  %3 m
          (%t6)                     e   q   w     q   e   g
                                                   %1  %2  %3 n

 -- Function: remcomps (<tensor>)

     Unbinds all values from <tensor> which were assigned with the
     ‘components’ function.

 -- Function: showcomps (<tensor>)

     Shows component assignments of a tensor, as made using the
     ‘components’ command.  This function can be particularly useful
     when a matrix is assigned to an indicial tensor using ‘components’,
     as demonstrated by the following example:


          (%i1) load("ctensor");
          (%o1)       /share/tensor/ctensor.mac
          (%i2) load("itensor");
          (%o2)      /share/tensor/itensor.lisp
          (%i3) lg:matrix([sqrt(r/(r-2*m)),0,0,0],[0,r,0,0],
                          [0,0,sin(theta)*r,0],[0,0,0,sqrt((r-2*m)/r)]);
                  [         r                                     ]
                  [ sqrt(-------)  0       0              0       ]
                  [      r - 2 m                                  ]
                  [                                               ]
                  [       0        r       0              0       ]
          (%o3)   [                                               ]
                  [       0        0  r sin(theta)        0       ]
                  [                                               ]
                  [                                      r - 2 m  ]
                  [       0        0       0        sqrt(-------) ]
                  [                                         r     ]
          (%i4) components(g([i,j],[]),lg);
          (%o4)                                done
          (%i5) showcomps(g([i,j],[]));
                       [         r                                     ]
                       [ sqrt(-------)  0       0              0       ]
                       [      r - 2 m                                  ]
                       [                                               ]
                       [       0        r       0              0       ]
          (%t5) g    = [                                               ]
                 i j   [       0        0  r sin(theta)        0       ]
                       [                                               ]
                       [                                      r - 2 m  ]
                       [       0        0       0        sqrt(-------) ]
                       [                                         r     ]
          (%o5)                                false

     The ‘showcomps’ command can also display components of a tensor of
     rank higher than 2.

 -- Function: idummy ()

     Increments ‘icounter’ and returns as its value an index of the form
     ‘%n’ where n is a positive integer.  This guarantees that dummy
     indices which are needed in forming expressions will not conflict
     with indices already in use (see the example under ‘indices’).

 -- Option variable: idummyx
     Default value: ‘%’

     Is the prefix for dummy indices (see the example under ‘indices’).

 -- Option variable: icounter
     Default value: ‘1’

     Determines the numerical suffix to be used in generating the next
     dummy index in the tensor package.  The prefix is determined by the
     option ‘idummy’ (default: ‘%’).

 -- Function: kdelta (<L1>, <L2>)
     is the generalized Kronecker delta function defined in the
     ‘itensor’ package with <L1> the list of covariant indices and <L2>
     the list of contravariant indices.  ‘kdelta([i],[j])’ returns the
     ordinary Kronecker delta.  The command ‘ev(<expr>,kdelta)’ causes
     the evaluation of an expression containing ‘kdelta([],[])’ to the
     dimension of the manifold.

     In what amounts to an abuse of this notation, ‘itensor’ also allows
     ‘kdelta’ to have 2 covariant and no contravariant, or 2
     contravariant and no covariant indices, in effect providing a
     co(ntra)variant "unit matrix" capability.  This is strictly
     considered a programming aid and not meant to imply that
     ‘kdelta([i,j],[])’ is a valid tensorial object.

 -- Function: kdels (<L1>, <L2>)

     Symmetrized Kronecker delta, used in some calculations.  For
     instance:


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) kdelta([1,2],[2,1]);
          (%o2)                                 - 1
          (%i3) kdels([1,2],[2,1]);
          (%o3)                                  1
          (%i4) ishow(kdelta([a,b],[c,d]))$
                                       c       d         d       c
          (%t4)                  kdelta  kdelta  - kdelta  kdelta
                                       a       b         a       b
          (%i4) ishow(kdels([a,b],[c,d]))$
                                       c       d         d       c
          (%t4)                  kdelta  kdelta  + kdelta  kdelta
                                       a       b         a       b

 -- Function: levi_civita (<L>)
     is the permutation (or Levi-Civita) tensor which yields 1 if the
     list <L> consists of an even permutation of integers, -1 if it
     consists of an odd permutation, and 0 if some indices in <L> are
     repeated.

 -- Function: lc2kdt (<expr>)
     Simplifies expressions containing the Levi-Civita symbol,
     converting these to Kronecker-delta expressions when possible.  The
     main difference between this function and simply evaluating the
     Levi-Civita symbol is that direct evaluation often results in
     Kronecker expressions containing numerical indices.  This is often
     undesirable as it prevents further simplification.  The ‘lc2kdt’
     function avoids this problem, yielding expressions that are more
     easily simplified with ‘rename’ or ‘contract’.


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) expr:ishow('levi_civita([],[i,j])
                           *'levi_civita([k,l],[])*a([j],[k]))$
                                            i j  k
          (%t2)                  levi_civita    a  levi_civita
                                                 j            k l
          (%i3) ishow(ev(expr,levi_civita))$
                                            i j  k       1 2
          (%t3)                       kdelta    a  kdelta
                                            1 2  j       k l
          (%i4) ishow(ev(%,kdelta))$
                       i       j         j       i   k
          (%t4) (kdelta  kdelta  - kdelta  kdelta ) a
                       1       2         1       2   j

                                         1       2         2       1
                                  (kdelta  kdelta  - kdelta  kdelta )
                                         k       l         k       l
          (%i5) ishow(lc2kdt(expr))$
                               k       i       j    k       j       i
          (%t5)               a  kdelta  kdelta  - a  kdelta  kdelta
                               j       k       l    j       k       l
          (%i6) ishow(contract(expand(%)))$
                                           i           i
          (%t6)                           a  - a kdelta
                                           l           l

     The ‘lc2kdt’ function sometimes makes use of the metric tensor.  If
     the metric tensor was not defined previously with ‘imetric’, this
     results in an error.


          (%i7) expr:ishow('levi_civita([],[i,j])
                           *'levi_civita([],[k,l])*a([j,k],[]))$
                                           i j            k l
          (%t7)                 levi_civita    levi_civita    a
                                                               j k
          (%i8) ishow(lc2kdt(expr))$
          Maxima encountered a Lisp error:

           Error in $IMETRIC [or a callee]:
           $IMETRIC [or a callee] requires less than two arguments.

          Automatically continuing.
          To re-enable the Lisp debugger set *debugger-hook* to nil.
          (%i9) imetric(g);
          (%o9)                                done
          (%i10) ishow(lc2kdt(expr))$
                   %3 i       k   %4 j       l     %3 i       l   %4 j
          (%t10) (g     kdelta   g     kdelta   - g     kdelta   g
                              %3             %4               %3
                        k
                  kdelta  ) a
                        %4   j k
          (%i11) ishow(contract(expand(%)))$
                                            l i    l i  j
          (%t11)                           a    - g    a
                                                        j

 -- Function: lc_l
     Simplification rule used for expressions containing the unevaluated
     Levi-Civita symbol (‘levi_civita’).  Along with ‘lc_u’, it can be
     used to simplify many expressions more efficiently than the
     evaluation of ‘levi_civita’.  For example:


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) el1:ishow('levi_civita([i,j,k],[])*a([],[i])*a([],[j]))$
                                       i  j
          (%t2)                       a  a  levi_civita
                                                       i j k
          (%i3) el2:ishow('levi_civita([],[i,j,k])*a([i])*a([j]))$
                                                 i j k
          (%t3)                       levi_civita      a  a
                                                        i  j
          (%i4) canform(contract(expand(applyb1(el1,lc_l,lc_u))));
          (%t4)                                  0
          (%i5) canform(contract(expand(applyb1(el2,lc_l,lc_u))));
          (%t5)                                  0

 -- Function: lc_u

     Simplification rule used for expressions containing the unevaluated
     Levi-Civita symbol (‘levi_civita’).  Along with ‘lc_u’, it can be
     used to simplify many expressions more efficiently than the
     evaluation of ‘levi_civita’.  For details, see ‘lc_l’.

 -- Function: canten (<expr>)
     Simplifies <expr> by renaming (see ‘rename’) and permuting dummy
     indices.  ‘rename’ is restricted to sums of tensor products in
     which no derivatives are present.  As such it is limited and should
     only be used if ‘canform’ is not capable of carrying out the
     required simplification.

     The ‘canten’ function returns a mathematically correct result only
     if its argument is an expression that is fully symmetric in its
     indices.  For this reason, ‘canten’ returns an error if ‘allsym’ is
     not set to ‘true’.

 -- Function: concan (<expr>)
     Similar to ‘canten’ but also performs index contraction.

71.2.2 Tensor symmetries
------------------------

 -- Option variable: allsym
     Default value: ‘false’

     If ‘true’ then all indexed objects are assumed symmetric in all of
     their covariant and contravariant indices.  If ‘false’ then no
     symmetries of any kind are assumed in these indices.  Derivative
     indices are always taken to be symmetric unless ‘iframe_flag’ is
     set to ‘true’.

 -- Function: decsym (<tensor>, <m>, <n>, [<cov_1>, <cov_2>, ...],
          [<contr_1>, <contr_2>, ...])

     Declares symmetry properties for <tensor> of <m> covariant and <n>
     contravariant indices.  The <cov_i> and <contr_i> are
     pseudofunctions expressing symmetry relations among the covariant
     and contravariant indices respectively.  These are of the form
     ‘symoper(<index_1>, <index_2>,...)’ where ‘symoper’ is one of
     ‘sym’, ‘anti’ or ‘cyc’ and the <index_i> are integers indicating
     the position of the index in the <tensor>.  This will declare
     <tensor> to be symmetric, antisymmetric or cyclic respectively in
     the <index_i>.  ‘symoper(all)’ is also an allowable form which
     indicates all indices obey the symmetry condition.  For example,
     given an object ‘b’ with 5 covariant indices,
     ‘decsym(b,5,3,[sym(1,2),anti(3,4)],[cyc(all)])’ declares ‘b’
     symmetric in its first and second and antisymmetric in its third
     and fourth covariant indices, and cyclic in all of its
     contravariant indices.  Either list of symmetry declarations may be
     null.  The function which performs the simplifications is ‘canform’
     as the example below illustrates.


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) expr:contract( expand( a([i1, j1, k1], [])
                     *kdels([i, j, k], [i1, j1, k1])))$
          (%i3) ishow(expr)$
          (%t3)         a      + a      + a      + a      + a      + a
                         k j i    k i j    j k i    j i k    i k j    i j k
          (%i4) decsym(a,3,0,[sym(all)],[]);
          (%o4)                                done
          (%i5) ishow(canform(expr))$
          (%t5)                              6 a
                                                i j k
          (%i6) remsym(a,3,0);
          (%o6)                                done
          (%i7) decsym(a,3,0,[anti(all)],[]);
          (%o7)                                done
          (%i8) ishow(canform(expr))$
          (%t8)                                  0
          (%i9) remsym(a,3,0);
          (%o9)                                done
          (%i10) decsym(a,3,0,[cyc(all)],[]);
          (%o10)                               done
          (%i11) ishow(canform(expr))$
          (%t11)                        3 a      + 3 a
                                           i k j      i j k
          (%i12) dispsym(a,3,0);
          (%o12)                     [[cyc, [[1, 2, 3]], []]]

 -- Function: remsym (<tensor>, <m>, <n>)
     Removes all symmetry properties from <tensor> which has <m>
     covariant indices and <n> contravariant indices.

 -- Function: dispsym (<tensor>, <m>, <n>)
     Displays all of the defined symmetries from <tensor> which has <m>
     covariant indices and <n> contravariant indices.  See ‘decsym’ for
     an example.

 -- Function: canform
          canform (<expr>)
          canform (<expr>, <rename>)

     Simplifies <expr> by renaming dummy indices and reordering all
     indices as dictated by symmetry conditions imposed on them.  If
     ‘allsym’ is ‘true’ then all indices are assumed symmetric,
     otherwise symmetry information provided by ‘decsym’ declarations
     will be used.  The dummy indices are renamed in the same manner as
     in the ‘rename’ function.  When ‘canform’ is applied to a large
     expression the calculation may take a considerable amount of time.
     This time can be shortened by calling ‘rename’ on the expression
     first.  Also see the example under ‘decsym’.  Note: ‘canform’ may
     not be able to reduce an expression completely to its simplest form
     although it will always return a mathematically correct result.

     The optional second parameter <rename>, if set to ‘false’,
     suppresses renaming.

71.2.3 Indicial tensor calculus
-------------------------------

 -- Function: diff (<expr>, <v_1>, [<n_1>, [<v_2>, <n_2>] ...])

     is the usual Maxima differentiation function which has been
     expanded in its abilities for ‘itensor’.  It takes the derivative
     of <expr> with respect to <v_1> <n_1> times, with respect to <v_2>
     <n_2> times, etc.  For the tensor package, the function has been
     modified so that the <v_i> may be integers from 1 up to the value
     of the variable ‘dim’.  This will cause the differentiation to be
     carried out with respect to the <v_i>th member of the list
     ‘vect_coords’.  If ‘vect_coords’ is bound to an atomic variable,
     then that variable subscripted by <v_i> will be used for the
     variable of differentiation.  This permits an array of coordinate
     names or subscripted names like ‘x[1]’, ‘x[2]’, ...  to be used.

     A further extension adds the ability to ‘diff’ to compute
     derivatives with respect to an indexed variable.  In particular,
     the tensor package knows how to differentiate expressions
     containing combinations of the metric tensor and its derivatives
     with respect to the metric tensor and its first and second
     derivatives.  This capability is particularly useful when
     considering Lagrangian formulations of a gravitational theory,
     allowing one to derive the Einstein tensor and field equations from
     the action principle.

 -- Function: idiff (<expr>, <v_1>, [<n_1>, [<v_2>, <n_2>] ...])
     Indicial differentiation.  Unlike ‘diff’, which differentiates with
     respect to an independent variable, ‘idiff)’ can be used to
     differentiate with respect to a coordinate.  For an indexed object,
     this amounts to appending the <v_i> as derivative indices.
     Subsequently, derivative indices will be sorted, unless
     ‘iframe_flag’ is set to ‘true’.

     ‘idiff’ can also differentiate the determinant of the metric
     tensor.  Thus, if ‘imetric’ has been bound to ‘G’ then
     ‘idiff(determinant(g),k)’ will return ‘2 * determinant(g) *
     ichr2([%i,k],[%i])’ where the dummy index ‘%i’ is chosen
     appropriately.

 -- Function: liediff (<v>, <ten>)

     Computes the Lie-derivative of the tensorial expression <ten> with
     respect to the vector field <v>.  <ten> should be any indexed
     tensor expression; <v> should be the name (without indices) of a
     vector field.  For example:


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) ishow(liediff(v,a([i,j],[])*b([],[k],l)))$
                 k    %2            %2          %2
          (%t2) b   (v   a       + v   a     + v   a    )
                 ,l       i j,%2    ,j  i %2    ,i  %2 j

                                    %1  k        %1  k      %1  k
                                + (v   b      - b   v    + v   b   ) a
                                        ,%1 l    ,l  ,%1    ,l  ,%1   i j

 -- Function: rediff (<ten>)

     Evaluates all occurrences of the ‘idiff’ command in the tensorial
     expression <ten>.

 -- Function: undiff (<expr>)

     Returns an expression equivalent to <expr> but with all derivatives
     of indexed objects replaced by the noun form of the ‘idiff’
     function.  Its arguments would yield that indexed object if the
     differentiation were carried out.  This is useful when it is
     desired to replace a differentiated indexed object with some
     function definition resulting in <expr> and then carry out the
     differentiation by saying ‘ev(<expr>, idiff)’.

 -- Function: evundiff (<expr>)

     Equivalent to the execution of ‘undiff’, followed by ‘ev’ and
     ‘rediff’.

     The point of this operation is to easily evaluate expressions that
     cannot be directly evaluated in derivative form.  For instance, the
     following causes an error:

          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) icurvature([i,j,k],[l],m);
          Maxima encountered a Lisp error:

           Error in $ICURVATURE [or a callee]:
           $ICURVATURE [or a callee] requires less than three arguments.

          Automatically continuing.
          To re-enable the Lisp debugger set *debugger-hook* to nil.

     However, if ‘icurvature’ is entered in noun form, it can be
     evaluated using ‘evundiff’:

          (%i3) ishow('icurvature([i,j,k],[l],m))$
                                                   l
          (%t3)                          icurvature
                                                   i j k,m
          (%i4) ishow(evundiff(%))$
                       l              l         %1           l           %1
          (%t4) - ichr2        - ichr2     ichr2      - ichr2       ichr2
                       i k,j m        %1 j      i k,m        %1 j,m      i k

                       l              l         %1           l           %1
                + ichr2        + ichr2     ichr2      + ichr2       ichr2
                       i j,k m        %1 k      i j,m        %1 k,m      i j

     Note: In earlier versions of Maxima, derivative forms of the
     Christoffel-symbols also could not be evaluated.  This has been
     fixed now, so ‘evundiff’ is no longer necessary for expressions
     like this:

          (%i5) imetric(g);
          (%o5)                                done
          (%i6) ishow(ichr2([i,j],[k],l))$
                 k %3
                g     (g         - g         + g        )
                        j %3,i l    i j,%3 l    i %3,j l
          (%t6) -----------------------------------------
                                    2

                                   k %3
                                  g     (g       - g       + g      )
                                   ,l     j %3,i    i j,%3    i %3,j
                                + -----------------------------------
                                                   2

 -- Function: flush (<expr>, <tensor_1>, <tensor_2>, ...)
     Set to zero, in <expr>, all occurrences of the <tensor_i> that have
     no derivative indices.

 -- Function: flushd (<expr>, <tensor_1>, <tensor_2>, ...)
     Set to zero, in <expr>, all occurrences of the <tensor_i> that have
     derivative indices.

 -- Function: flushnd (<expr>, <tensor>, <n>)
     Set to zero, in <expr>, all occurrences of the differentiated
     object <tensor> that have <n> or more derivative indices as the
     following example demonstrates.

          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) ishow(a([i],[J,r],k,r)+a([i],[j,r,s],k,r,s))$
                                          J r      j r s
          (%t2)                          a      + a
                                          i,k r    i,k r s
          (%i3) ishow(flushnd(%,a,3))$
                                               J r
          (%t3)                               a
                                               i,k r

 -- Function: coord (<tensor_1>, <tensor_2>, ...)

     Gives <tensor_i> the coordinate differentiation property that the
     derivative of contravariant vector whose name is one of the
     <tensor_i> yields a Kronecker delta.  For example, if ‘coord(x)’
     has been done then ‘idiff(x([],[i]),j)’ gives ‘kdelta([i],[j])’.
     ‘coord’ is a list of all indexed objects having this property.

 -- Function: remcoord
          remcoord (<tensor_1>, <tensor_2>, ...)
          remcoord (all)

     Removes the coordinate differentiation property from the ‘tensor_i’
     that was established by the function ‘coord’.  ‘remcoord(all)’
     removes this property from all indexed objects.

 -- Function: makebox (<expr>,<g>)
     Display <expr> using the metric <g> such that any tensor
     d'Alembertian occurring in <expr> will be indicated using the
     symbol ‘[]’.  For example, ‘[]p([m],[n])’ represents
     ‘g([],[i,j])*p([m],[n],i,j)’.

 -- Function: conmetderiv (<expr>, <tensor>)

     Simplifies expressions containing ordinary derivatives of both
     covariant and contravariant forms of the metric tensor (the current
     restriction).  For example, ‘conmetderiv’ can relate the derivative
     of the contravariant metric tensor with the Christoffel symbols as
     seen from the following:


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) ishow(g([],[a,b],c))$
                                                a b
          (%t2)                                g
                                                ,c
          (%i3) ishow(conmetderiv(%,g))$
                                   %1 b      a       %1 a      b
          (%t3)                 - g     ichr2     - g     ichr2
                                             %1 c              %1 c

 -- Function: simpmetderiv
          simpmetderiv (<expr>)
          simpmetderiv (<expr>[, <stop>])

     Simplifies expressions containing products of the derivatives of
     the metric tensor.  Specifically, ‘simpmetderiv’ recognizes two
     identities:


             ab        ab           ab                 a
            g   g   + g   g     = (g   g  )   = (kdelta )   = 0
             ,d  bc        bc,d         bc ,d          c ,d

     hence


             ab          ab
            g   g   = - g   g
             ,d  bc          bc,d

     and


            ab          ab
           g   g     = g   g
            ,j  ab,i    ,i  ab,j

     which follows from the symmetries of the Christoffel symbols.

     The ‘simpmetderiv’ function takes one optional parameter which,
     when present, causes the function to stop after the first
     successful substitution in a product expression.  The
     ‘simpmetderiv’ function also makes use of the global variable
     ‘flipflag’ which determines how to apply a "canonical" ordering to
     the product indices.

     Put together, these capabilities can be used to achieve powerful
     simplifications that are difficult or impossible to accomplish
     otherwise.  This is demonstrated through the following example that
     explicitly uses the partial simplification features of
     ‘simpmetderiv’ to obtain a contractible expression:


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) imetric(g);
          (%o2)                                done
          (%i3) ishow(g([],[a,b])*g([],[b,c])*g([a,b],[],d)*g([b,c],[],e))$
                                       a b  b c
          (%t3)                       g    g    g      g
                                                 a b,d  b c,e
          (%i4) ishow(canform(%))$

          errexp1 has improper indices
           -- an error.  Quitting.  To debug this try debugmode(true);
          (%i5) ishow(simpmetderiv(%))$
                                       a b  b c
          (%t5)                       g    g    g      g
                                                 a b,d  b c,e
          (%i6) flipflag:not flipflag;
          (%o6)                                true
          (%i7) ishow(simpmetderiv(%th(2)))$
                                         a b  b c
          (%t7)                         g    g    g    g
                                         ,d   ,e   a b  b c
          (%i8) flipflag:not flipflag;
          (%o8)                                false
          (%i9) ishow(simpmetderiv(%th(2),stop))$
                                         a b  b c
          (%t9)                       - g    g    g      g
                                              ,e   a b,d  b c
          (%i10) ishow(contract(%))$
                                              b c
          (%t10)                           - g    g
                                              ,e   c b,d

     See also ‘weyl.dem’ for an example that uses ‘simpmetderiv’ and
     ‘conmetderiv’ together to simplify contractions of the Weyl tensor.

 -- Function: flush1deriv (<expr>, <tensor>)

     Set to zero, in ‘expr’, all occurrences of ‘tensor’ that have
     exactly one derivative index.

71.2.4 Tensors in curved spaces
-------------------------------

 -- Function: imetric (<g>)
 -- System variable: imetric

     Specifies the metric by assigning the variable ‘imetric:<g>’ in
     addition, the contraction properties of the metric <g> are set up
     by executing the commands ‘defcon(<g>), defcon(<g>, <g>, kdelta)’.
     The variable ‘imetric’ (unbound by default), is bound to the
     metric, assigned by the ‘imetric(<g>)’ command.

 -- Function: idim (<n>)
     Sets the dimensions of the metric.  Also initializes the
     antisymmetry properties of the Levi-Civita symbols for the given
     dimension.

 -- Function: ichr1 ([<i>, <j>, <k>])
     Yields the Christoffel symbol of the first kind via the definition
                 (g      + g      - g     )/2 .
                   ik,j     jk,i     ij,k
     To evaluate the Christoffel symbols for a particular metric, the
     variable ‘imetric’ must be assigned a name as in the example under
     ‘chr2’.

 -- Function: ichr2 ([<i>, <j>], [<k>])
     Yields the Christoffel symbol of the second kind defined by the
     relation
                                 ks
             ichr2([i,j],[k]) = g    (g      + g      - g     )/2
                                       is,j     js,i     ij,s

 -- Function: icurvature ([<i>, <j>, <k>], [<h>])
     Yields the Riemann curvature tensor in terms of the Christoffel
     symbols of the second kind (‘ichr2’).  The following notation is
     used:
                      h             h            h         %1         h
            icurvature     = - ichr2      - ichr2     ichr2    + ichr2
                      i j k         i k,j        %1 j      i k        i j,k
                                      h          %1
                               + ichr2      ichr2
                                      %1 k       i j

 -- Function: covdiff (<expr>, <v_1>, <v_2>, ...)
     Yields the covariant derivative of <expr> with respect to the
     variables <v_i> in terms of the Christoffel symbols of the second
     kind (‘ichr2’).  In order to evaluate these, one should use
     ‘ev(<expr>,ichr2)’.


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) entertensor()$
          Enter tensor name: a;
          Enter a list of the covariant indices: [i,j];
          Enter a list of the contravariant indices: [k];
          Enter a list of the derivative indices: [];
                                                k
          (%t2)                                a
                                                i j
          (%i3) ishow(covdiff(%,s))$
                       k         %1     k         %1     k
          (%t3)     - a     ichr2    - a     ichr2    + a
                       i %1      j s    %1 j      i s    i j,s

                       k     %1
                + ichr2     a
                       %1 s  i j
          (%i4) imetric:g;
          (%o4)                                  g
          (%i5) ishow(ev(%th(2),ichr2))$
                   %1 %4  k
                  g      a     (g       - g       + g      )
                          i %1   s %4,j    j s,%4    j %4,s
          (%t5) - ------------------------------------------
                                      2
              %1 %3  k
             g      a     (g       - g       + g      )
                     %1 j   s %3,i    i s,%3    i %3,s
           - ------------------------------------------
                                 2
              k %2  %1
             g     a    (g        - g        + g       )
                    i j   s %2,%1    %1 s,%2    %1 %2,s     k
           + ------------------------------------------- + a
                                  2                         i j,s
          (%i6)

 -- Function: lorentz_gauge (<expr>)
     Imposes the Lorentz condition by substituting 0 for all indexed
     objects in <expr> that have a derivative index identical to a
     contravariant index.

 -- Function: igeodesic_coords (<expr>, <name>)

     Causes undifferentiated Christoffel symbols and first derivatives
     of the metric tensor vanish in <expr>.  The <name> in the
     ‘igeodesic_coords’ function refers to the metric <name> (if it
     appears in <expr>) while the connection coefficients must be called
     with the names ‘ichr1’ and/or ‘ichr2’.  The following example
     demonstrates the verification of the cyclic identity satisfied by
     the Riemann curvature tensor using the ‘igeodesic_coords’ function.


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) ishow(icurvature([r,s,t],[u]))$
                       u            u         %1         u
          (%t2) - ichr2      - ichr2     ichr2    + ichr2
                       r t,s        %1 s      r t        r s,t

                                                        u         %1
                                                 + ichr2     ichr2
                                                        %1 t      r s
          (%i3) ishow(igeodesic_coords(%,ichr2))$
                                           u            u
          (%t3)                       ichr2      - ichr2
                                           r s,t        r t,s
          (%i4) ishow(igeodesic_coords(icurvature([r,s,t],[u]),ichr2)+
                      igeodesic_coords(icurvature([s,t,r],[u]),ichr2)+
                      igeodesic_coords(icurvature([t,r,s],[u]),ichr2))$
                       u            u            u            u
          (%t4) - ichr2      + ichr2      + ichr2      - ichr2
                       t s,r        t r,s        s t,r        s r,t

                                                       u            u
                                                - ichr2      + ichr2
                                                       r t,s        r s,t
          (%i5) canform(%);
          (%o5)                                  0

71.2.5 Moving frames
--------------------

Maxima now has the ability to perform calculations using moving frames.
These can be orthonormal frames (tetrads, vielbeins) or an arbitrary
frame.

   To use frames, you must first set ‘iframe_flag’ to ‘true’.  This
causes the Christoffel-symbols, ‘ichr1’ and ‘ichr2’, to be replaced by
the more general frame connection coefficients ‘icc1’ and ‘icc2’ in
calculations.  Specifically, the behavior of ‘covdiff’ and ‘icurvature’
is changed.

   The frame is defined by two tensors: the inverse frame field (‘ifri’,
the dual basis tetrad), and the frame metric ‘ifg’.  The frame metric is
the identity matrix for orthonormal frames, or the Lorentz metric for
orthonormal frames in Minkowski spacetime.  The inverse frame field
defines the frame base (unit vectors).  Contraction properties are
defined for the frame field and the frame metric.

   When ‘iframe_flag’ is true, many ‘itensor’ expressions use the frame
metric ‘ifg’ instead of the metric defined by ‘imetric’ for raising and
lowerind indices.

   IMPORTANT: Setting the variable ‘iframe_flag’ to ‘true’ does NOT
undefine the contraction properties of a metric defined by a call to
‘defcon’ or ‘imetric’.  If a frame field is used, it is best to define
the metric by assigning its name to the variable ‘imetric’ and NOT
invoke the ‘imetric’ function.

   Maxima uses these two tensors to define the frame coefficients
(‘ifc1’ and ‘ifc2’) which form part of the connection coefficients
(‘icc1’ and ‘icc2’), as the following example demonstrates:


     (%i1) load("itensor");
     (%o1)      /share/tensor/itensor.lisp
     (%i2) iframe_flag:true;
     (%o2)                                true
     (%i3) ishow(covdiff(v([],[i]),j))$
                                    i        i     %1
     (%t3)                         v   + icc2     v
                                    ,j       %1 j
     (%i4) ishow(ev(%,icc2))$
                                    %1     i       i
     (%t4)                         v   ifc2     + v
                                           %1 j    ,j
     (%i5) ishow(ev(%,ifc2))$
                               %1    i %2                i
     (%t5)                    v   ifg     ifc1        + v
                                              %1 j %2    ,j
     (%i6) ishow(ev(%,ifc1))$
                 %1    i %2
                v   ifg     (ifb        - ifb        + ifb       )
                                j %2 %1      %2 %1 j      %1 j %2     i
     (%t6)      -------------------------------------------------- + v
                                        2                             ,j
     (%i7) ishow(ifb([a,b,c]))$
                                                        %3    %4
     (%t7)               (ifri        - ifri       ) ifr   ifr
                              a %3,%4       a %4,%3     b     c

   An alternate method is used to compute the frame bracket (‘ifb’) if
the ‘iframe_bracket_form’ flag is set to ‘false’:


     (%i8) block([iframe_bracket_form:false],ishow(ifb([a,b,c])))$
                                     %6    %5        %5      %6
     (%t8)              ifri     (ifr   ifr     - ifr     ifr  )
                            a %5     b     c,%6      b,%6    c

 -- Function: iframes ()

     Since in this version of Maxima, contraction identities for ‘ifr’
     and ‘ifri’ are always defined, as is the frame bracket (‘ifb’),
     this function does nothing.

 -- Variable: ifb

     The frame bracket.  The contribution of the frame metric to the
     connection coefficients is expressed using the frame bracket:


                    - ifb      + ifb      + ifb
                         c a b      b c a      a b c
          ifc1    = --------------------------------
              abc                  2

     The frame bracket itself is defined in terms of the frame field and
     frame metric.  Two alternate methods of computation are used
     depending on the value of ‘frame_bracket_form’.  If true (the
     default) or if the ‘itorsion_flag’ is ‘true’:


                    d      e                                      f
          ifb =  ifr    ifr   (ifri      - ifri      - ifri    itr   )
             abc    b      c       a d,e       a e,d       a f    d e


     Otherwise:


                       e      d        d      e
          ifb    = (ifr    ifr    - ifr    ifr   ) ifri
             abc       b      c,e      b,e    c        a d

 -- Variable: icc1

     Connection coefficients of the first kind.  In ‘itensor’, defined
     as


          icc1    = ichr1    - ikt1    - inmc1
              abc        abc       abc        abc

     In this expression, if ‘iframe_flag’ is true, the
     Christoffel-symbol ‘ichr1’ is replaced with the frame connection
     coefficient ‘ifc1’.  If ‘itorsion_flag’ is ‘false’, ‘ikt1’ will be
     omitted.  It is also omitted if a frame base is used, as the
     torsion is already calculated as part of the frame bracket.
     Lastly, of ‘inonmet_flag’ is ‘false’, ‘inmc1’ will not be present.

 -- Variable: icc2

     Connection coefficients of the second kind.  In ‘itensor’, defined
     as


              c         c        c         c
          icc2   = ichr2   - ikt2   - inmc2
              ab        ab       ab        ab

     In this expression, if ‘iframe_flag’ is true, the
     Christoffel-symbol ‘ichr2’ is replaced with the frame connection
     coefficient ‘ifc2’.  If ‘itorsion_flag’ is ‘false’, ‘ikt2’ will be
     omitted.  It is also omitted if a frame base is used, as the
     torsion is already calculated as part of the frame bracket.
     Lastly, of ‘inonmet_flag’ is ‘false’, ‘inmc2’ will not be present.

 -- Variable: ifc1

     Frame coefficient of the first kind (also known as Ricci-rotation
     coefficients.)  This tensor represents the contribution of the
     frame metric to the connection coefficient of the first kind.
     Defined as:


                    - ifb      + ifb      + ifb
                         c a b      b c a      a b c
          ifc1    = --------------------------------
              abc                   2


 -- Variable: ifc2

     Frame coefficient of the second kind.  This tensor represents the
     contribution of the frame metric to the connection coefficient of
     the second kind.  Defined as a permutation of the frame bracket
     (‘ifb’) with the appropriate indices raised and lowered as
     necessary:


              c       cd
          ifc2   = ifg   ifc1
              ab             abd

 -- Variable: ifr

     The frame field.  Contracts with the inverse frame field (‘ifri’)
     to form the frame metric (‘ifg’).

 -- Variable: ifri

     The inverse frame field.  Specifies the frame base (dual basis
     vectors).  Along with the frame metric, it forms the basis of all
     calculations based on frames.

 -- Variable: ifg

     The frame metric.  Defaults to ‘kdelta’, but can be changed using
     ‘components’.

 -- Variable: ifgi

     The inverse frame metric.  Contracts with the frame metric (‘ifg’)
     to ‘kdelta’.

 -- Option variable: iframe_bracket_form
     Default value: ‘true’

     Specifies how the frame bracket (‘ifb’) is computed.

71.2.6 Torsion and nonmetricity
-------------------------------

Maxima can now take into account torsion and nonmetricity.  When the
flag ‘itorsion_flag’ is set to ‘true’, the contribution of torsion is
added to the connection coefficients.  Similarly, when the flag
‘inonmet_flag’ is true, nonmetricity components are included.

 -- Variable: inm

     The nonmetricity vector.  Conformal nonmetricity is defined through
     the covariant derivative of the metric tensor.  Normally zero, the
     metric tensor's covariant derivative will evaluate to the following
     when ‘inonmet_flag’ is set to ‘true’:


          g     =- g  inm
           ij;k     ij   k

 -- Variable: inmc1

     Covariant permutation of the nonmetricity vector components.
     Defined as


                     g   inm  - inm  g   - g   inm
                      ab    c      a  bc    ac    b
          inmc1    = ------------------------------
               abc                 2

     (Substitute ‘ifg’ in place of ‘g’ if a frame metric is used.)

 -- Variable: inmc2

     Contravariant permutation of the nonmetricity vector components.
     Used in the connection coefficients if ‘inonmet_flag’ is ‘true’.
     Defined as:


                                c         c         cd
                    -inm  kdelta  - kdelta  inm  + g   inm  g
               c        a       b         a    b          d  ab
          inmc2   = -------------------------------------------
               ab                        2

     (Substitute ‘ifg’ in place of ‘g’ if a frame metric is used.)

 -- Variable: ikt1

     Covariant permutation of the torsion tensor (also known as
     contorsion).  Defined as:


                            d           d       d
                    -g   itr  - g    itr   - itr   g
                      ad    cb    bd    ca      ab  cd
          ikt1    = ----------------------------------
              abc                   2

     (Substitute ‘ifg’ in place of ‘g’ if a frame metric is used.)

 -- Variable: ikt2

     Contravariant permutation of the torsion tensor (also known as
     contorsion).  Defined as:


              c     cd
          ikt2   = g   ikt1
              ab           abd

     (Substitute ‘ifg’ in place of ‘g’ if a frame metric is used.)

 -- Variable: itr

     The torsion tensor.  For a metric with torsion, repeated covariant
     differentiation on a scalar function will not commute, as
     demonstrated by the following example:


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) imetric:g;
          (%o2)                                  g
          (%i3) covdiff( covdiff( f( [], []), i), j)
                                - covdiff( covdiff( f( [], []), j), i)$
          (%i4) ishow(%)$
                                             %4              %2
          (%t4)                    f    ichr2    - f    ichr2
                                    ,%4      j i    ,%2      i j
          (%i5) canform(%);
          (%o5)                                  0
          (%i6) itorsion_flag:true;
          (%o6)                                true
          (%i7) covdiff( covdiff( f( [], []), i), j)
                                - covdiff( covdiff( f( [], []), j), i)$
          (%i8) ishow(%)$
                                     %8             %6
          (%t8)             f    icc2    - f    icc2    - f     + f
                             ,%8     j i    ,%6     i j    ,j i    ,i j
          (%i9) ishow(canform(%))$
                                             %1             %1
          (%t9)                     f    icc2    - f    icc2
                                     ,%1     j i    ,%1     i j
          (%i10) ishow(canform(ev(%,icc2)))$
                                             %1             %1
          (%t10)                    f    ikt2    - f    ikt2
                                     ,%1     i j    ,%1     j i
          (%i11) ishow(canform(ev(%,ikt2)))$
                                %2 %1                    %2 %1
          (%t11)          f    g      ikt1       - f    g      ikt1
                           ,%2            i j %1    ,%2            j i %1
          (%i12) ishow(factor(canform(rename(expand(ev(%,ikt1))))))$
                                     %3 %2            %1       %1
                               f    g      g      (itr    - itr   )
                                ,%3         %2 %1     j i      i j
          (%t12)               ------------------------------------
                                                2
          (%i13) decsym(itr,2,1,[anti(all)],[]);
          (%o13)                               done
          (%i14) defcon(g,g,kdelta);
          (%o14)                               done
          (%i15) subst(g,nounify(g),%th(3))$
          (%i16) ishow(canform(contract(%)))$
                                                     %1
          (%t16)                           - f    itr
                                              ,%1    i j

71.2.7 Exterior algebra
-----------------------

The ‘itensor’ package can perform operations on totally antisymmetric
covariant tensor fields.  A totally antisymmetric tensor field of rank
(0,L) corresponds with a differential L-form.  On these objects, a
multiplication operation known as the exterior product, or wedge
product, is defined.

   Unfortunately, not all authors agree on the definition of the wedge
product.  Some authors prefer a definition that corresponds with the
notion of antisymmetrization: in these works, the wedge product of two
vector fields, for instance, would be defined as

                 a a  - a a
                  i j    j i
      a  /\ a  = -----------
       i     j        2

   More generally, the product of a p-form and a q-form would be defined
as

                            1     k1..kp l1..lq
     A       /\ B       = ------ D              A       B
      i1..ip     j1..jq   (p+q)!  i1..ip j1..jq  k1..kp  l1..lq

   where ‘D’ stands for the Kronecker-delta.

   Other authors, however, prefer a "geometric" definition that
corresponds with the notion of the volume element:

     a  /\ a  = a a  - a a
      i     j    i j    j i

   and, in the general case

                            1    k1..kp l1..lq
     A       /\ B       = ----- D              A       B
      i1..ip     j1..jq   p! q!  i1..ip j1..jq  k1..kp  l1..lq

   Since ‘itensor’ is a tensor algebra package, the first of these two
definitions appears to be the more natural one.  Many applications,
however, utilize the second definition.  To resolve this dilemma, a flag
has been implemented that controls the behavior of the wedge product: if
‘igeowedge_flag’ is ‘false’ (the default), the first, "tensorial"
definition is used, otherwise the second, "geometric" definition will be
applied.

 -- Operator: ~

     The wedge product operator is denoted by the tilde ‘~’.  This is a
     binary operator.  Its arguments should be expressions involving
     scalars, covariant tensors of rank one, or covariant tensors of
     rank ‘l’ that have been declared antisymmetric in all covariant
     indices.

     The behavior of the wedge product operator is controlled by the
     ‘igeowedge_flag’ flag, as in the following example:

          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) ishow(a([i])~b([j]))$
                                           a  b  - b  a
                                            i  j    i  j
          (%t2)                            -------------
                                                 2
          (%i3) decsym(a,2,0,[anti(all)],[]);
          (%o3)                                done
          (%i4) ishow(a([i,j])~b([k]))$
                                    a    b  + b  a    - a    b
                                     i j  k    i  j k    i k  j
          (%t4)                     ---------------------------
                                                 3
          (%i5) igeowedge_flag:true;
          (%o5)                                true
          (%i6) ishow(a([i])~b([j]))$
          (%t6)                            a  b  - b  a
                                            i  j    i  j
          (%i7) ishow(a([i,j])~b([k]))$
          (%t7)                     a    b  + b  a    - a    b
                                     i j  k    i  j k    i k  j

 -- Operator: |

     The vertical bar ‘|’ denotes the "contraction with a vector" binary
     operation.  When a totally antisymmetric covariant tensor is
     contracted with a contravariant vector, the result is the same
     regardless which index was used for the contraction.  Thus, it is
     possible to define the contraction operation in an index-free
     manner.

     In the ‘itensor’ package, contraction with a vector is always
     carried out with respect to the first index in the literal sorting
     order.  This ensures better simplification of expressions involving
     the ‘|’ operator.  For instance:

          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) decsym(a,2,0,[anti(all)],[]);
          (%o2)                                done
          (%i3) ishow(a([i,j],[])|v)$
                                              %1
          (%t3)                              v   a
                                                  %1 j
          (%i4) ishow(a([j,i],[])|v)$
                                               %1
          (%t4)                             - v   a
                                                   %1 j

     Note that it is essential that the tensors used with the ‘|’
     operator be declared totally antisymmetric in their covariant
     indices.  Otherwise, the results will be incorrect.

 -- Function: extdiff (<expr>, <i>)

     Computes the exterior derivative of <expr> with respect to the
     index <i>.  The exterior derivative is formally defined as the
     wedge product of the partial derivative operator and a differential
     form.  As such, this operation is also controlled by the setting of
     ‘igeowedge_flag’.  For instance:

          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) ishow(extdiff(v([i]),j))$
                                            v    - v
                                             j,i    i,j
          (%t2)                             -----------
                                                 2
          (%i3) decsym(a,2,0,[anti(all)],[]);
          (%o3)                                done
          (%i4) ishow(extdiff(a([i,j]),k))$
                                     a      - a      + a
                                      j k,i    i k,j    i j,k
          (%t4)                      ------------------------
                                                3
          (%i5) igeowedge_flag:true;
          (%o5)                                true
          (%i6) ishow(extdiff(v([i]),j))$
          (%t6)                             v    - v
                                             j,i    i,j
          (%i7) ishow(extdiff(a([i,j]),k))$
          (%t7)                    - (a      - a      + a     )
                                       k j,i    k i,j    j i,k

 -- Function: hodge (<expr>)

     Compute the Hodge-dual of <expr>.  For instance:


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) imetric(g);
          (%o2)                            done
          (%i3) idim(4);
          (%o3)                            done
          (%i4) icounter:100;
          (%o4)                             100
          (%i5) decsym(A,3,0,[anti(all)],[])$

          (%i6) ishow(A([i,j,k],[]))$
          (%t6)                           A
                                           i j k
          (%i7) ishow(canform(hodge(%)))$
                                    %1 %2 %3 %4
                         levi_civita            g        A
                                                 %1 %102  %2 %3 %4
          (%t7)          -----------------------------------------
                                             6
          (%i8) ishow(canform(hodge(%)))$
                           %1 %2 %3 %8            %4 %5 %6 %7
          (%t8) levi_civita            levi_civita            g
                                                               %1 %106
                                       g        g        g      A         /6
                                        %2 %107  %3 %108  %4 %8  %5 %6 %7
          (%i9) lc2kdt(%)$

          (%i10) %,kdelta$

          (%i11) ishow(canform(contract(expand(%))))$
          (%t11)                     - A
                                        %106 %107 %108

 -- Option variable: igeowedge_flag
     Default value: ‘false’

     Controls the behavior of the wedge product and exterior derivative.
     When set to ‘false’ (the default), the notion of differential forms
     will correspond with that of a totally antisymmetric covariant
     tensor field.  When set to ‘true’, differential forms will agree
     with the notion of the volume element.

71.2.8 Exporting TeX expressions
--------------------------------

The ‘itensor’ package provides limited support for exporting tensor
expressions to TeX. Since ‘itensor’ expressions appear as function
calls, the regular Maxima ‘tex’ command will not produce the expected
output.  You can try instead the ‘tentex’ command, which attempts to
translate tensor expressions into appropriately indexed TeX objects.

 -- Function: tentex (<expr>)

     To use the ‘tentex’ function, you must first load ‘tentex’, as in
     the following example:

          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) load("tentex");
          (%o2)       /share/tensor/tentex.lisp
          (%i3) idummyx:m;
          (%o3)                                  m
          (%i4) ishow(icurvature([j,k,l],[i]))$
                      m1       i           m1       i           i
          (%t4)  ichr2    ichr2     - ichr2    ichr2     - ichr2
                      j k      m1 l        j l      m1 k        j l,k

                                                                i
                                                         + ichr2
                                                                j k,l
          (%i5) tentex(%)$
          $$\Gamma_{j\,k}^{m_1}\,\Gamma_{l\,m_1}^{i}-\Gamma_{j\,l}^{m_1}\,
           \Gamma_{k\,m_1}^{i}-\Gamma_{j\,l,k}^{i}+\Gamma_{j\,k,l}^{i}$$

     Note the use of the ‘idummyx’ assignment, to avoid the appearance
     of the percent sign in the TeX expression, which may lead to
     compile errors.

     NB: This version of the ‘tentex’ function is somewhat experimental.

71.2.9 Interfacing with ctensor
-------------------------------

The ‘itensor’ package has the ability to generate Maxima code that can
then be executed in the context of the ‘ctensor’ package.  The function
that performs this task is ‘ic_convert’.

 -- Function: ic_convert (<eqn>)

     Converts the ‘itensor’ equation <eqn> to a ‘ctensor’ assignment
     statement.  Implied sums over dummy indices are made explicit while
     indexed objects are transformed into arrays (the array subscripts
     are in the order of covariant followed by contravariant indices of
     the indexed objects).  The derivative of an indexed object will be
     replaced by the noun form of ‘diff’ taken with respect to
     ‘ct_coords’ subscripted by the derivative index.  The Christoffel
     symbols ‘ichr1’ and ‘ichr2’ will be translated to ‘lcs’ and ‘mcs’,
     respectively and if ‘metricconvert’ is ‘true’ then all occurrences
     of the metric with two covariant (contravariant) indices will be
     renamed to ‘lg’ (‘ug’).  In addition, ‘do’ loops will be introduced
     summing over all free indices so that the transformed assignment
     statement can be evaluated by just doing ‘ev’.  The following
     examples demonstrate the features of this function.

          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) eqn:ishow(t([i,j],[k])=f([],[])*g([l,m],[])*a([],[m],j)
                *b([i],[l,k]))$
                                       k        m   l k
          (%t2)                       t    = f a   b    g
                                       i j      ,j  i    l m
          (%i3) ic_convert(eqn);
          (%o3) for i thru dim do (for j thru dim do (
                 for k thru dim do
                  t        : f sum(sum(diff(a , ct_coords ) b
                   i, j, k                   m           j   i, l, k

           g    , l, 1, dim), m, 1, dim)))
            l, m
          (%i4) imetric(g);
          (%o4)                                done
          (%i5) metricconvert:true;
          (%o5)                                true
          (%i6) ic_convert(eqn);
          (%o6) for i thru dim do (for j thru dim do (
                 for k thru dim do
                  t        : f sum(sum(diff(a , ct_coords ) b
                   i, j, k                   m           j   i, l, k

           lg    , l, 1, dim), m, 1, dim)))
             l, m

71.2.10 Reserved words
----------------------

The following Maxima words are used by the ‘itensor’ package internally
and should not be redefined:

       Keyword    Comments
       ------------------------------------------
       indices2() Internal version of indices()
       conti      Lists contravariant indices
       covi       Lists covariant indices of an indexed object
       deri       Lists derivative indices of an indexed object
       name       Returns the name of an indexed object
       concan
       irpmon
       lc0
       _lc2kdt0
       _lcprod
       _extlc


File: maxima.info,  Node: Package lapack,  Next: Package lbfgs,  Prev: Package itensor,  Up: Top

72 Package lapack
*****************

* Menu:

* Introduction to lapack::
* Functions and Variables for lapack::


File: maxima.info,  Node: Introduction to lapack,  Next: Functions and Variables for lapack,  Prev: Package lapack,  Up: Package lapack

72.1 Introduction to lapack
===========================

‘lapack’ is a Common Lisp translation (via the program ‘f2cl’) of the
Fortran library LAPACK, as obtained from the SLATEC project.


File: maxima.info,  Node: Functions and Variables for lapack,  Prev: Introduction to lapack,  Up: Package lapack

72.2 Functions and Variables for lapack
=======================================

 -- Function: dgeev
          dgeev (<A>)
          dgeev (<A>, <right_p>, <left_p>)

     Computes the eigenvalues and, optionally, the eigenvectors of a
     matrix <A>.  All elements of <A> must be integer or floating point
     numbers.  <A> must be square (same number of rows and columns).
     <A> might or might not be symmetric.

     To make use of this function, you must load the LaPack package via
     ‘load("lapack")’.

     ‘dgeev(<A>)’ computes only the eigenvalues of <A>.  ‘dgeev(<A>,
     <right_p>, <left_p>)’ computes the eigenvalues of <A> and the right
     eigenvectors when <right_p> = ‘true’ and the left eigenvectors when
     <left_p> = ‘true’.

     A list of three items is returned.  The first item is a list of the
     eigenvalues.  The second item is ‘false’ or the matrix of right
     eigenvectors.  The third item is ‘false’ or the matrix of left
     eigenvectors.

     The right eigenvector v_j (the j-th column of the right eigenvector
     matrix) satisfies

     A . v_j = lambda_j . v_j

     where lambda_j is the corresponding eigenvalue.  The left
     eigenvector u_j (the j-th column of the left eigenvector matrix)
     satisfies

     u_j^H . A = lambda_j . u_j^H

     where u_j^H denotes the conjugate transpose of u_j. For a Maxima
     function to compute the conjugate transpose, *note ctranspose::.

     The computed eigenvectors are normalized to have Euclidean norm
     equal to 1, and largest component has imaginary part equal to zero.

     Example:

          (%i1) load ("lapack")$
          (%i2) fpprintprec : 6;
          (%o2)                           6
          (%i3) M : matrix ([9.5, 1.75], [3.25, 10.45]);
                                   [ 9.5   1.75  ]
          (%o3)                    [             ]
                                   [ 3.25  10.45 ]
          (%i4) dgeev (M);
          (%o4)          [[7.54331, 12.4067], false, false]
          (%i5) [L, v, u] : dgeev (M, true, true);
                                     [ - 0.666642  - 0.515792 ]
          (%o5) [[7.54331, 12.4067], [                        ],
                                     [  0.745378   - 0.856714 ]
                                                [ - 0.856714  - 0.745378 ]
                                                [                        ]]
                                                [  0.515792   - 0.666642 ]
          (%i6) D : apply (diag_matrix, L);
                                [ 7.54331     0    ]
          (%o6)                 [                  ]
                                [    0     12.4067 ]
          (%i7) M . v - v . D;
                          [      0.0       - 8.88178e-16 ]
          (%o7)           [                              ]
                          [ - 8.88178e-16       0.0      ]
          (%i8) transpose (u) . M - D . transpose (u);
                               [ 0.0  - 4.44089e-16 ]
          (%o8)                [                    ]
                               [ 0.0       0.0      ]

 -- Function: dgeqrf (<A>)

     Computes the QR decomposition of the matrix <A>.  All elements of
     <A> must be integer or floating point numbers.  <A> may or may not
     have the same number of rows and columns.

     To make use of this function, you must load the LaPack package via
     ‘load("lapack")’.

     The real square matrix A can be decomposed as

     A = QR

     where Q is a square orthogonal matrix with the same number of rows
     as A and R is an upper triangular matrix and is the same size as A.

     A list of two items is returned.  The first item is the matrix Q.
     The second item is the matrix R, The product Q . R, where "."  is
     the noncommutative multiplication operator, is equal to <A>
     (ignoring floating point round-off errors).

          (%i1) load ("lapack")$
          (%i2) fpprintprec : 6;
          (%o2)                           6
          (%i3) M : matrix ([1, -3.2, 8], [-11, 2.7, 5.9]);
                                [  1    - 3.2   8  ]
          (%o3)                 [                  ]
                                [ - 11   2.7   5.9 ]
          (%i4) [q, r] : dgeqrf (M);
                 [ - 0.0905357  0.995893  ]
          (%o4) [[                        ],
                 [  0.995893    0.0905357 ]
                                         [ - 11.0454   2.97863   5.15148 ]
                                         [                               ]]
                                         [    0.0     - 2.94241  8.50131 ]
          (%i5) q . r - M;
                   [ - 7.77156e-16   1.77636e-15   - 8.88178e-16 ]
          (%o5)    [                                             ]
                   [      0.0       - 1.33227e-15   8.88178e-16  ]
          (%i6) mat_norm (%, 1);
          (%o6)                      3.10862e-15

 -- Function: dgesv (<A>, <b>)

     Computes the solution <x> of the linear equation <A> <x> = <b>,
     where <A> is a square matrix, and b is a matrix of the same number
     of rows as <A> and any number of columns.  The return value x is
     the same size as b.

     To make use of this function, you must load the LaPack package via
     ‘load("lapack")’.

     The elements of <A> and <b> must evaluate to real floating point
     numbers via ‘float’; thus elements may be any numeric type,
     symbolic numerical constants, or expressions which evaluate to
     floats.  The elements of <x> are always floating point numbers.
     All arithmetic is carried out as floating point operations.

     ‘dgesv’ computes the solution via the LU decomposition of <A>.

     Examples:

     ‘dgesv’ computes the solution of the linear equation <A> <x> = <b>.

          (%i1) load("lapack")$
          (%i2) A : matrix ([1, -2.5], [0.375, 5]);
                                  [   1    - 2.5 ]
          (%o2)                   [              ]
                                  [ 0.375    5   ]
          (%i3) b : matrix ([1.75], [-0.625]);
                                     [  1.75   ]
          (%o3)                      [         ]
                                     [ - 0.625 ]
          (%i4) x : dgesv (A, b);
                              [  1.2105263157894737   ]
          (%o4)               [                       ]
                              [ - 0.21578947368421053 ]
          (%i5) dlange (inf_norm, b - A . x);
          (%o5)                          0.0

     <b> is a matrix with the same number of rows as <A> and any number
     of columns.  <x> is the same size as <b>.

          (%i1) load ("lapack")$
          (%i2) A : matrix ([1, -0.15], [1.82, 2]);
                                  [  1    - 0.15 ]
          (%o2)                   [              ]
                                  [ 1.82    2    ]
          (%i3) b : matrix ([3.7, 1, 8], [-2.3, 5, -3.9]);
                                 [  3.7   1    8   ]
          (%o3)                  [                 ]
                                 [ - 2.3  5  - 3.9 ]
          (%i4) x : dgesv (A, b);
          (%o4)
           [ 3.1038275406951175   1.2098548174219095  6.7817861856577215  ]
           [                                                              ]
           [ - 3.974483062032557  1.3990321161460624  - 8.121425428948527 ]
          (%i5) dlange (inf_norm, b - A . x);
          (%o5)                1.1102230246251565e-15

     The elements of <A> and <b> must evaluate to real floating point
     numbers.

          (%i1) load ("lapack")$
          (%i2) A : matrix ([5, -%pi], [1b0, 11/17]);
                                  [   5    - %pi ]
                                  [              ]
          (%o2)                   [         11   ]
                                  [ 1.0b0   --   ]
                                  [         17   ]
          (%i3) b : matrix ([%e], [sin(1)]);
                                     [   %e   ]
          (%o3)                      [        ]
                                     [ sin(1) ]
          (%i4) x : dgesv (A, b);
                               [ 0.6903756431559864  ]
          (%o4)                [                     ]
                               [ 0.23351098255295172 ]
          (%i5) dlange (inf_norm, b - A . x);
          (%o5)                 2.220446049250313e-16

 -- Function: dgesvd
          dgesvd (<A>)
          dgesvd (<A>, <left_p>, <right_p>)

     Computes the singular value decomposition (SVD) of a matrix <A>,
     comprising the singular values and, optionally, the left and right
     singular vectors.  All elements of <A> must be integer or floating
     point numbers.  <A> might or might not be square (same number of
     rows and columns).

     To make use of this function, you must load the LaPack package via
     ‘load("lapack")’.

     Let m be the number of rows, and n the number of columns of <A>.
     The singular value decomposition of A comprises three matrices, U,
     Sigma, and V, such that

     {A} = {U} . {Sigma} . {V}^T

     where U is an m-by-m unitary matrix, Sigma is an m-by-n diagonal
     matrix, and V is an n-by-n unitary matrix.

     Let sigma[i] be a diagonal element of Sigma, that is, <Sigma>[i, i]
     = <sigma>[i]. The elements sigma[i] are the so-called singular
     values of A; these are real and nonnegative, and returned in
     descending order.  The first min(m, n) columns of U and V are the
     left and right singular vectors of A. Note that ‘dgesvd’ returns
     the transpose of V, not V itself.

     ‘dgesvd(<A>)’ computes only the singular values of <A>.
     ‘dgesvd(<A>, <left_p>, <right_p>)’ computes the singular values of
     <A> and the left singular vectors when <left_p> = ‘true’ and the
     right singular vectors when <right_p> = ‘true’.

     A list of three items is returned.  The first item is a list of the
     singular values.  The second item is ‘false’ or the matrix of left
     singular vectors.  The third item is ‘false’ or the matrix of right
     singular vectors.

     Example:

          (%i1) load ("lapack")$
          (%i2) fpprintprec : 6;
          (%o2)                           6
          (%i3) M: matrix([1, 2, 3], [3.5, 0.5, 8], [-1, 2, -3], [4, 9, 7]);
                                  [  1    2    3  ]
                                  [               ]
                                  [ 3.5  0.5   8  ]
          (%o3)                   [               ]
                                  [ - 1   2   - 3 ]
                                  [               ]
                                  [  4    9    7  ]
          (%i4) dgesvd (M);
          (%o4)     [[14.4744, 6.38637, 0.452547], false, false]
          (%i5) [sigma, U, VT] : dgesvd (M, true, true);
          (%o5) [[14.4744, 6.38637, 0.452547],
          [ - 0.256731  0.00816168   0.959029    - 0.119523 ]
          [                                                 ]
          [ - 0.526456   0.672116   - 0.206236   - 0.478091 ]
          [                                                 ],
          [  0.107997   - 0.532278  - 0.0708315  - 0.83666  ]
          [                                                 ]
          [ - 0.803287  - 0.514659  - 0.180867    0.239046  ]
          [ - 0.374486  - 0.538209  - 0.755044 ]
          [                                    ]
          [  0.130623   - 0.836799    0.5317   ]]
          [                                    ]
          [ - 0.917986   0.100488    0.383672  ]
          (%i6) m : length (U);
          (%o6)                           4
          (%i7) n : length (VT);
          (%o7)                           3
          (%i8) Sigma:
            genmatrix(lambda ([i, j], if i=j then sigma[i] else 0),
                      m, n);
                           [ 14.4744     0        0     ]
                           [                            ]
                           [    0     6.38637     0     ]
          (%o8)            [                            ]
                           [    0        0     0.452547 ]
                           [                            ]
                           [    0        0        0     ]
          (%i9) U . Sigma . VT - M;
                    [  1.11022e-15        0.0       1.77636e-15 ]
                    [                                           ]
                    [  1.33227e-15    1.66533e-15       0.0     ]
          (%o9)     [                                           ]
                    [ - 4.44089e-16  - 8.88178e-16  4.44089e-16 ]
                    [                                           ]
                    [  8.88178e-16    1.77636e-15   8.88178e-16 ]
          (%i10) transpose (U) . U;
                 [     1.0      5.55112e-17    2.498e-16     2.77556e-17  ]
                 [                                                        ]
                 [ 5.55112e-17      1.0       5.55112e-17    4.16334e-17  ]
          (%o10) [                                                        ]
                 [  2.498e-16   5.55112e-17       1.0       - 2.08167e-16 ]
                 [                                                        ]
                 [ 2.77556e-17  4.16334e-17  - 2.08167e-16       1.0      ]
          (%i11) VT . transpose (VT);
                    [      1.0           0.0      - 5.55112e-17 ]
                    [                                           ]
          (%o11)    [      0.0           1.0       5.55112e-17  ]
                    [                                           ]
                    [ - 5.55112e-17  5.55112e-17       1.0      ]

 -- Function: dlange (<norm>, <A>)
 -- Function: zlange (<norm>, <A>)

     Computes a norm or norm-like function of the matrix <A>.  If <A> is
     a real matrix, use ‘dlange’.  For a matrix with complex elements,
     use ‘zlange’.

     To make use of this function, you must load the LaPack package via
     ‘load("lapack")’.

     ‘norm’ specifies the kind of norm to be computed:
     ‘max’
          Compute max(abs(A(i, j))) where i and j range over the rows
          and columns, respectively, of A. Note that this function is
          not a proper matrix norm.
     ‘one_norm’
          Compute the L[1] norm of A, that is, the maximum of the sum of
          the absolute value of elements in each column.
     ‘inf_norm’
          Compute the L[inf] norm of A, that is, the maximum of the sum
          of the absolute value of elements in each row.
     ‘frobenius’
          Compute the Frobenius norm of A, that is, the square root of
          the sum of squares of the matrix elements.

 -- Function: dgemm
          dgemm (<A>, <B>)
          dgemm (<A>, <B>, <options>)
     Compute the product of two matrices and optionally add the product
     to a third matrix.

     In the simplest form, ‘dgemm(<A>, <B>)’ computes the product of the
     two real matrices, <A> and <B>.

     To make use of this function, you must load the LaPack package via
     ‘load("lapack")’.

     In the second form, ‘dgemm’ computes <alpha> * <A> * <B> + <beta> *
     <C> where <A>, <B>, and <C> are real matrices of the appropriate
     sizes and alpha and beta are real numbers.  Optionally, <A> and/or
     <B> can be transposed before computing the product.  The extra
     parameters are specified by optional keyword arguments: The keyword
     arguments are optional and may be specified in any order.  They all
     take the form ‘key=val’.  The keyword arguments are:

     ‘C’
          The matrix <C> that should be added.  The default is ‘false’,
          which means no matrix is added.
     ‘alpha’
          The product of <A> and <B> is multiplied by this value.  The
          default is 1.
     ‘beta’
          If a matrix <C> is given, this value multiplies <C> before it
          is added.  The default value is 0, which implies that <C> is
          not added, even if <C> is given.  Hence, be sure to specify a
          non-zero value for beta.
     ‘transpose_a’
          If ‘true’, the transpose of <A> is used instead of <A> for the
          product.  The default is ‘false’.
     ‘transpose_b’
          If ‘true’, the transpose of <B> is used instead of <B> for the
          product.  The default is ‘false’.

          (%i1) load ("lapack")$
          (%i2) A : matrix([1,2,3],[4,5,6],[7,8,9]);
                                     [ 1  2  3 ]
                                     [         ]
          (%o2)                      [ 4  5  6 ]
                                     [         ]
                                     [ 7  8  9 ]
          (%i3) B : matrix([-1,-2,-3],[-4,-5,-6],[-7,-8,-9]);
                                  [ - 1  - 2  - 3 ]
                                  [               ]
          (%o3)                   [ - 4  - 5  - 6 ]
                                  [               ]
                                  [ - 7  - 8  - 9 ]
          (%i4) C : matrix([3,2,1],[6,5,4],[9,8,7]);
                                     [ 3  2  1 ]
                                     [         ]
          (%o4)                      [ 6  5  4 ]
                                     [         ]
                                     [ 9  8  7 ]
          (%i5) dgemm(A,B);
                            [ - 30.0   - 36.0   - 42.0  ]
                            [                           ]
          (%o5)             [ - 66.0   - 81.0   - 96.0  ]
                            [                           ]
                            [ - 102.0  - 126.0  - 150.0 ]
          (%i6) A . B;
                               [ - 30   - 36   - 42  ]
                               [                     ]
          (%o6)                [ - 66   - 81   - 96  ]
                               [                     ]
                               [ - 102  - 126  - 150 ]
          (%i7) dgemm(A,B,transpose_a=true);
                            [ - 66.0  - 78.0   - 90.0  ]
                            [                          ]
          (%o7)             [ - 78.0  - 93.0   - 108.0 ]
                            [                          ]
                            [ - 90.0  - 108.0  - 126.0 ]
          (%i8) transpose(A) . B;
                               [ - 66  - 78   - 90  ]
                               [                    ]
          (%o8)                [ - 78  - 93   - 108 ]
                               [                    ]
                               [ - 90  - 108  - 126 ]
          (%i9) dgemm(A,B,c=C,beta=1);
                            [ - 27.0  - 34.0   - 41.0  ]
                            [                          ]
          (%o9)             [ - 60.0  - 76.0   - 92.0  ]
                            [                          ]
                            [ - 93.0  - 118.0  - 143.0 ]
          (%i10) A . B + C;
                               [ - 27  - 34   - 41  ]
                               [                    ]
          (%o10)               [ - 60  - 76   - 92  ]
                               [                    ]
                               [ - 93  - 118  - 143 ]
          (%i11) dgemm(A,B,c=C,beta=1, alpha=-1);
                               [ 33.0   38.0   43.0  ]
                               [                     ]
          (%o11)               [ 72.0   86.0   100.0 ]
                               [                     ]
                               [ 111.0  134.0  157.0 ]
          (%i12) -A . B + C;
                                  [ 33   38   43  ]
                                  [               ]
          (%o12)                  [ 72   86   100 ]
                                  [               ]
                                  [ 111  134  157 ]

 -- Function: zgeev
          zgeev (<A>)
          zgeev (<A>, <right_p>, <left_p>)

     Like ‘dgeev’, but the matrix <A> is complex.

     To make use of this function, you must load the LaPack package via
     ‘load("lapack")’.

 -- Function: zheev
          zheev (<A>)
          zheev (<A>, <eigvec_p>)

     Like ‘dgeev’, but the matrix <A> is assumed to be a square complex
     Hermitian matrix.  If <eigvec_p> is ‘true’, then the eigenvectors
     of the matrix are also computed.

     To make use of this function, you must load the LaPack package via
     ‘load("lapack")’.

     No check is made that the matrix <A> is, in fact, Hermitian.

     A list of two items is returned, as in ‘dgeev’: a list of
     eigenvalues, and ‘false’ or the matrix of the eigenvectors.

          (%i1) load("lapack")$
          (%i2) M: matrix(
               [9.14 +%i*0.00 ,   -4.37 -%i*9.22 ,  -1.98 -%i*1.72 ,  -8.96 -%i*9.50],
               [-4.37 +%i*9.22 ,  -3.35 +%i*0.00 ,   2.25 -%i*9.51 ,   2.57 +%i*2.40],
               [-1.98 +%i*1.72 ,   2.25 +%i*9.51 ,  -4.82 +%i*0.00 ,  -3.24 +%i*2.04],
               [-8.96 +%i*9.50 ,   2.57 -%i*2.40 ,  -3.24 -%i*2.04 ,   8.44 +%i*0.00]);
                         [      9.14      ]         [ - 9.22 %i - 4.37 ]
                         [                ]         [                  ]
                         [ 9.22 %i - 4.37 ]         [      - 3.35      ]
          (%o2)  Col 1 = [                ] Col 2 = [                  ]
                         [ 1.72 %i - 1.98 ]         [  9.51 %i + 2.25  ]
                         [                ]         [                  ]
                         [ 9.5 %i - 8.96  ]         [  2.57 - 2.4 %i   ]
                           [ - 1.72 %i - 1.98 ]         [ - 9.5 %i - 8.96 ]
                           [                  ]         [                 ]
                           [  2.25 - 9.51 %i  ]         [  2.4 %i + 2.57  ]
                   Col 3 = [                  ] Col 4 = [                 ]
                           [      - 4.82      ]         [ 2.04 %i - 3.24  ]
                           [                  ]         [                 ]
                           [ - 2.04 %i - 3.24 ]         [      8.44       ]
          (%i3) zheev(M);
          (%o3) [[- 16.004746472094734, - 6.764970154793324,
                             6.6657114535070985, 25.51400517338097], false]
          (%i4) E: zheev(M,true)$
          (%i5) E[1];
          (%o5) [- 16.004746472094737, - 6.764970154793325,
                                     6.665711453507101, 25.514005173380962]
          (%i6) E[2];
                         [  0.26746505331727455 %i + 0.21754535866650165  ]
                         [                                                ]
                         [  0.002696730886619885 %i + 0.6968836773391712  ]
          (%o6)  Col 1 = [                                                ]
                         [ - 0.6082406376714117 %i - 0.012106142926979313 ]
                         [                                                ]
                         [              0.15930818580950368               ]
                   [  0.26449374706674444 %i + 0.4773693349937472   ]
                   [                                                ]
                   [ - 0.28523890360316206 %i - 0.14143627420116733 ]
           Col 2 = [                                                ]
                   [  0.2654607680986639 %i + 0.44678181171841735   ]
                   [                                                ]
                   [               0.5750762708542709               ]
                   [  0.28106497673059216 %i - 0.13352639282451817  ]
                   [                                                ]
                   [  0.28663101328695556 %i - 0.4536971347853274   ]
           Col 3 = [                                                ]
                   [ - 0.29336843237542953 %i - 0.49549724255410565 ]
                   [                                                ]
                   [               0.5325337537576771               ]
                   [ - 0.5737316575503476 %i - 0.39661467994277055 ]
                   [                                               ]
                   [ 0.018265026190214573 %i + 0.35305577043870173 ]
           Col 4 = [                                               ]
                   [ 0.16737009000854253 %i + 0.01476684746229564  ]
                   [                                               ]
                   [              0.6002632636961784               ]


File: maxima.info,  Node: Package lbfgs,  Next: Package levin,  Prev: Package lapack,  Up: Top

73 Package lbfgs
****************

* Menu:

* Introduction to lbfgs::
* Functions and Variables for lbfgs::


File: maxima.info,  Node: Introduction to lbfgs,  Next: Functions and Variables for lbfgs,  Up: Package lbfgs

73.1 Introduction to lbfgs
==========================

‘lbfgs’ is an implementation of the L-BFGS algorithm [1] to solve
unconstrained minimization problems via a limited-memory quasi-Newton
(BFGS) algorithm.  It is called a limited-memory method because a
low-rank approximation of the Hessian matrix inverse is stored instead
of the entire Hessian inverse.  The program was originally written in
Fortran [2] by Jorge Nocedal, incorporating some functions originally
written by Jorge J. Moré and David J. Thuente, and translated into Lisp
automatically via the program ‘f2cl’.  The Maxima package ‘lbfgs’
comprises the translated code plus an interface function which manages
some details.

   References:

   [1] D. Liu and J. Nocedal.  "On the limited memory BFGS method for
large scale optimization".  Mathematical Programming B 45:503-528 (1989)

   [2] <https://www.netlib.org/opt/lbfgs_um.shar>


File: maxima.info,  Node: Functions and Variables for lbfgs,  Prev: Introduction to lbfgs,  Up: Package lbfgs

73.2 Functions and Variables for lbfgs
======================================

 -- Function: lbfgs
          lbfgs (<FOM>, <X>, <X0>, <epsilon>, <iprint>)
          lbfgs ([<FOM>, <grad>] <X>, <X0>, <epsilon>, <iprint>)

     Finds an approximate solution of the unconstrained minimization of
     the figure of merit <FOM> over the list of variables <X>, starting
     from initial estimates <X0>, such that norm(grad(FOM)) <
     epsilon*max(1, norm(X)).

     <grad>, if present, is the gradient of <FOM> with respect to the
     variables <X>.  <grad> may be a list or a function that returns a
     list, with one element for each element of <X>.  If not present,
     the gradient is computed automatically by symbolic differentiation.
     If <FOM> is a function, the gradient <grad> must be supplied by the
     user.

     The algorithm applied is a limited-memory quasi-Newton (BFGS)
     algorithm [1].  It is called a limited-memory method because a
     low-rank approximation of the Hessian matrix inverse is stored
     instead of the entire Hessian inverse.  Each iteration of the
     algorithm is a line search, that is, a search along a ray in the
     variables <X>, with the search direction computed from the
     approximate Hessian inverse.  The FOM is always decreased by a
     successful line search.  Usually (but not always) the norm of the
     gradient of FOM also decreases.

     <iprint> controls progress messages printed by ‘lbfgs’.

     ‘iprint[1]’
          ‘<iprint>[1]’ controls the frequency of progress messages.
          ‘iprint[1] < 0’
               No progress messages.
          ‘iprint[1] = 0’
               Messages at the first and last iterations.
          ‘iprint[1] > 0’
               Print a message every ‘<iprint>[1]’ iterations.
     ‘iprint[2]’
          ‘<iprint>[2]’ controls the verbosity of progress messages.
          ‘iprint[2] = 0’
               Print out iteration count, number of evaluations of
               <FOM>, value of <FOM>, norm of the gradient of <FOM>, and
               step length.
          ‘iprint[2] = 1’
               Same as ‘<iprint>[2] = 0’, plus <X0> and the gradient of
               <FOM> evaluated at <X0>.
          ‘iprint[2] = 2’
               Same as ‘<iprint>[2] = 1’, plus values of <X> at each
               iteration.
          ‘iprint[2] = 3’
               Same as ‘<iprint>[2] = 2’, plus the gradient of <FOM> at
               each iteration.

     The columns printed by ‘lbfgs’ are the following.

     ‘I’
          Number of iterations.  It is incremented for each line search.
     ‘NFN’
          Number of evaluations of the figure of merit.
     ‘FUNC’
          Value of the figure of merit at the end of the most recent
          line search.
     ‘GNORM’
          Norm of the gradient of the figure of merit at the end of the
          most recent line search.
     ‘STEPLENGTH’
          An internal parameter of the search algorithm.

     Additional information concerning details of the algorithm are
     found in the comments of the original Fortran code [2].

     See also ‘lbfgs_nfeval_max’ and *note lbfgs_ncorrections::.

     References:

     [1] D. Liu and J. Nocedal.  "On the limited memory BFGS method for
     large scale optimization".  Mathematical Programming B 45:503-528
     (1989)

     [2] <https://www.netlib.org/opt/lbfgs_um.shar>

     Examples:

     The same FOM as computed by FGCOMPUTE in the program sdrive.f in
     the LBFGS package from Netlib.  Note that the variables in question
     are subscripted variables.  The FOM has an exact minimum equal to
     zero at u[k] = 1 for k = 1, ..., 8.

          (%i1) load ("lbfgs")$
          (%i2) t1[j] := 1 - u[j];
          (%o2)                     t1  := 1 - u
                                      j         j
          (%i3) t2[j] := 10*(u[j + 1] - u[j]^2);
                                                    2
          (%o3)                t2  := 10 (u      - u )
                                 j         j + 1    j
          (%i4) n : 8;
          (%o4)                           8
          (%i5) FOM : sum (t1[2*j - 1]^2 + t2[2*j - 1]^2, j, 1, n/2);
                           2 2           2              2 2           2
          (%o5) 100 (u  - u )  + (1 - u )  + 100 (u  - u )  + (1 - u )
                      8    7           7           6    5           5
                               2 2           2              2 2           2
                  + 100 (u  - u )  + (1 - u )  + 100 (u  - u )  + (1 - u )
                          4    3           3           2    1           1
          (%i6) lbfgs (FOM, '[u[1],u[2],u[3],u[4],u[5],u[6],u[7],u[8]],
                 [-1.2, 1, -1.2, 1, -1.2, 1, -1.2, 1], 1e-3, [1, 0]);
          *************************************************
            N=    8   NUMBER OF CORRECTIONS=25
                 INITIAL VALUES
           F=  9.680000000000000D+01   GNORM=  4.657353755084533D+02
          *************************************************
           I NFN   FUNC                    GNORM                   STEPLENGTH

           1   3   1.651479526340304D+01   4.324359291335977D+00   7.926153934390631D-04
           2   4   1.650209316638371D+01   3.575788161060007D+00   1.000000000000000D+00
           3   5   1.645461701312851D+01   6.230869903601577D+00   1.000000000000000D+00
           4   6   1.636867301275588D+01   1.177589920974980D+01   1.000000000000000D+00
           5   7   1.612153014409201D+01   2.292797147151288D+01   1.000000000000000D+00
           6   8   1.569118407390628D+01   3.687447158775571D+01   1.000000000000000D+00
           7   9   1.510361958398942D+01   4.501931728123679D+01   1.000000000000000D+00
           8  10   1.391077875774293D+01   4.526061463810630D+01   1.000000000000000D+00
           9  11   1.165625686278198D+01   2.748348965356907D+01   1.000000000000000D+00
          10  12   9.859422687859144D+00   2.111494974231706D+01   1.000000000000000D+00
          11  13   7.815442521732282D+00   6.110762325764183D+00   1.000000000000000D+00
          12  15   7.346380905773044D+00   2.165281166715009D+01   1.285316401779678D-01
          13  16   6.330460634066464D+00   1.401220851761508D+01   1.000000000000000D+00
          14  17   5.238763939854303D+00   1.702473787619218D+01   1.000000000000000D+00
          15  18   3.754016790406625D+00   7.981845727632704D+00   1.000000000000000D+00
          16  20   3.001238402313225D+00   3.925482944745832D+00   2.333129631316462D-01
          17  22   2.794390709722064D+00   8.243329982586480D+00   2.503577283802312D-01
          18  23   2.563783562920545D+00   1.035413426522664D+01   1.000000000000000D+00
          19  24   2.019429976373283D+00   1.065187312340952D+01   1.000000000000000D+00
          20  25   1.428003167668592D+00   2.475962450735100D+00   1.000000000000000D+00
          21  27   1.197874264859232D+00   8.441707983339661D+00   4.303451060697367D-01
          22  28   9.023848942003913D-01   1.113189216665625D+01   1.000000000000000D+00
          23  29   5.508226405855795D-01   2.380830599637816D+00   1.000000000000000D+00
          24  31   3.902893258879521D-01   5.625595817143044D+00   4.834988416747262D-01
          25  32   3.207542206881058D-01   1.149444645298493D+01   1.000000000000000D+00
          26  33   1.874468266118200D-01   3.632482152347445D+00   1.000000000000000D+00
          27  34   9.575763380282112D-02   4.816497449000391D+00   1.000000000000000D+00
          28  35   4.085145106760390D-02   2.087009347116811D+00   1.000000000000000D+00
          29  36   1.931106005512628D-02   3.886818624052740D+00   1.000000000000000D+00
          30  37   6.894000636920714D-03   3.198505769992936D+00   1.000000000000000D+00
          31  38   1.443296008850287D-03   1.590265460381961D+00   1.000000000000000D+00
          32  39   1.571766574930155D-04   3.098257002223532D-01   1.000000000000000D+00
          33  40   1.288011779655132D-05   1.207784334505595D-02   1.000000000000000D+00
          34  41   1.806140190993455D-06   4.587890258846915D-02   1.000000000000000D+00
          35  42   1.769004612050548D-07   1.790537363138099D-02   1.000000000000000D+00
          36  43   3.312164244118216D-10   6.782068546986653D-04   1.000000000000000D+00

           THE MINIMIZATION TERMINATED WITHOUT DETECTING ERRORS.
           IFLAG = 0
          (%o6) [u  = 1.000005339816132, u  = 1.000009942840108,
                  1                       2
          u  = 1.000005339816132, u  = 1.000009942840108,
           3                       4
          u  = 1.000005339816132, u  = 1.000009942840108,
           5                       6
          u  = 1.000005339816132, u  = 1.000009942840108]
           7                       8

     A regression problem.  The FOM is the mean square difference
     between the predicted value F(X[i]) and the observed value Y[i].
     The function F is a bounded monotone function (a so-called
     "sigmoidal" function).  In this example, ‘lbfgs’ computes
     approximate values for the parameters of F and ‘plot2d’ displays a
     comparison of F with the observed data.

          (%i1) load ("lbfgs")$
          (%i2) FOM : '((1/length(X))*sum((F(X[i]) - Y[i])^2, i, 1,
                                                          length(X)));
                                         2
                         sum((F(X ) - Y ) , i, 1, length(X))
                                 i     i
          (%o2)          -----------------------------------
                                      length(X)
          (%i3) X : [1, 2, 3, 4, 5];
          (%o3)                    [1, 2, 3, 4, 5]
          (%i4) Y : [0, 0.5, 1, 1.25, 1.5];
          (%o4)                [0, 0.5, 1, 1.25, 1.5]
          (%i5) F(x) := A/(1 + exp(-B*(x - C)));
                                             A
          (%o5)            F(x) := ----------------------
                                   1 + exp((- B) (x - C))
          (%i6) ''FOM;
                          A               2            A                2
          (%o6) ((----------------- - 1.5)  + (----------------- - 1.25)
                    - B (5 - C)                  - B (4 - C)
                  %e            + 1            %e            + 1
                      A             2            A               2
           + (----------------- - 1)  + (----------------- - 0.5)
                - B (3 - C)                - B (2 - C)
              %e            + 1          %e            + 1
                       2
                      A
           + --------------------)/5
                - B (1 - C)     2
             (%e            + 1)
          (%i7) estimates : lbfgs (FOM, '[A, B, C], [1, 1, 1], 1e-4, [1, 0]);
          *************************************************
            N=    3   NUMBER OF CORRECTIONS=25
                 INITIAL VALUES
           F=  1.348738534246918D-01   GNORM=  2.000215531936760D-01
          *************************************************

          I  NFN  FUNC                    GNORM                   STEPLENGTH
          1    3  1.177820636622582D-01   9.893138394953992D-02   8.554435968992371D-01
          2    6  2.302653892214013D-02   1.180098521565904D-01   2.100000000000000D+01
          3    8  1.496348495303004D-02   9.611201567691624D-02   5.257340567840710D-01
          4    9  7.900460841091138D-03   1.325041647391314D-02   1.000000000000000D+00
          5   10  7.314495451266914D-03   1.510670810312226D-02   1.000000000000000D+00
          6   11  6.750147275936668D-03   1.914964958023037D-02   1.000000000000000D+00
          7   12  5.850716021108202D-03   1.028089194579382D-02   1.000000000000000D+00
          8   13  5.778664230657800D-03   3.676866074532179D-04   1.000000000000000D+00
          9   14  5.777818823650780D-03   3.010740179797108D-04   1.000000000000000D+00

           THE MINIMIZATION TERMINATED WITHOUT DETECTING ERRORS.
           IFLAG = 0
          (%o7) [A = 1.461933911464101, B = 1.601593973254801,
                                                     C = 2.528933072164855]
          (%i8) plot2d ([F(x), [discrete, X, Y]], [x, -1, 6]), ''estimates;
          (%o8)

     Gradient of FOM is specified (instead of computing it
     automatically).  Both the FOM and its gradient are passed as
     functions to ‘lbfgs’.

          (%i1) load ("lbfgs")$
          (%i2) F(a, b, c) := (a - 5)^2 + (b - 3)^4 + (c - 2)^6$
          (%i3) define(F_grad(a, b, c),
                       map (lambda ([x], diff (F(a, b, c), x)), [a, b, c]))$
          (%i4) estimates : lbfgs ([F, F_grad],
                             [a, b, c], [0, 0, 0], 1e-4, [1, 0]);
          *************************************************
            N=    3   NUMBER OF CORRECTIONS=25
                 INITIAL VALUES
           F=  1.700000000000000D+02   GNORM=  2.205175729958953D+02
          *************************************************

             I  NFN     FUNC                    GNORM                   STEPLENGTH

             1    2     6.632967565917637D+01   6.498411132518770D+01   4.534785987412505D-03
             2    3     4.368890936228036D+01   3.784147651974131D+01   1.000000000000000D+00
             3    4     2.685298972775191D+01   1.640262125898520D+01   1.000000000000000D+00
             4    5     1.909064767659852D+01   9.733664001790506D+00   1.000000000000000D+00
             5    6     1.006493272061515D+01   6.344808151880209D+00   1.000000000000000D+00
             6    7     1.215263596054292D+00   2.204727876126877D+00   1.000000000000000D+00
             7    8     1.080252896385329D-02   1.431637116951845D-01   1.000000000000000D+00
             8    9     8.407195124830860D-03   1.126344579730008D-01   1.000000000000000D+00
             9   10     5.022091686198525D-03   7.750731829225275D-02   1.000000000000000D+00
            10   11     2.277152808939775D-03   5.032810859286796D-02   1.000000000000000D+00
            11   12     6.489384688303218D-04   1.932007150271009D-02   1.000000000000000D+00
            12   13     2.075791943844547D-04   6.964319310814365D-03   1.000000000000000D+00
            13   14     7.349472666162258D-05   4.017449067849554D-03   1.000000000000000D+00
            14   15     2.293617477985238D-05   1.334590390856715D-03   1.000000000000000D+00
            15   16     7.683645404048675D-06   6.011057038099202D-04   1.000000000000000D+00

           THE MINIMIZATION TERMINATED WITHOUT DETECTING ERRORS.
           IFLAG = 0
          (%o4) [a = 5.000086823042934, b = 3.052395429705181,
                                                     c = 1.927980629919583]

 -- Variable: lbfgs_nfeval_max
     Default value: 100

     ‘lbfgs_nfeval_max’ is the maximum number of evaluations of the
     figure of merit (FOM) in ‘lbfgs’.  When ‘lbfgs_nfeval_max’ is
     reached, ‘lbfgs’ returns the result of the last successful line
     search.

 -- Variable: lbfgs_ncorrections
     Default value: 25

     ‘lbfgs_ncorrections’ is the number of corrections applied to the
     approximate inverse Hessian matrix which is maintained by ‘lbfgs’.


File: maxima.info,  Node: Package levin,  Next: Package lindstedt,  Prev: Package lbfgs,  Up: Top

74 Package levin
****************

* Menu:

* Introduction to levin::
* Functions and Variables for levin::
* Examples for levin::
* References for levin::


File: maxima.info,  Node: Introduction to levin,  Next: Functions and Variables for levin,  Prev: Package levin,  Up: Package levin

74.1 Introduction to levin
==========================

Package levin provides functions that implement the Levin
u-transformation (*note Levin 1973: levin-1973.).  This transformation
may accelerate convergence of the sum of infinite sequences using a
small number of terms.

   Methods to accelerate the convergence of infinite series do not
usually return the exact sum.  There are two major sources of error:
truncation error, due to the finite number of terms used; and, rounding
error, due to the finite precision arithmetic used in the calculations.
Truncation error dominates for a small number of terms (perhaps 5 to 10
terms).  Rounding error dominates as the number of terms increases
(perhaps above 10 to 20 terms for IEEE-754 double precision arithmetic).

   This package has two functions that address these sources of error.

   Function ‘levin_u_sum’ (by default) uses rational arithmetic with a
fixed number of terms.  This eliminates rounding error if the terms are
known exactly.

   Function ‘bflevin_u_sum’ uses bigfloat precision.  It uses error
estimates to increase the number of terms and the bigfloat arithmetic
precision to meet an accuracy target.

   See ‘Examples for levin’ for examples.  See ‘References for levin’
for further information.


File: maxima.info,  Node: Functions and Variables for levin,  Next: Examples for levin,  Prev: Introduction to levin,  Up: Package levin

74.2 Functions and Variables for levin
======================================

 -- Function: levin_u_sum
          levin_u_sum (<a>, <n>, <n_0>, <nterms>, <mode>)
          levin_u_sum (<a>, <n>, <n_0>, <nterms>)

     Estimate ‘sum(<a>(<n>), <n>, <n_0>, inf)’ using at most <nterms>
     terms using the Levin u-transform *note Levin 1973: levin-1973.

     The following values are recognized for the optional argument
     <mode>.  If <mode> is not supplied, it is assumed to be
     ‘levin_algebraic’.

     ‘levin_algebraic’
          The calculation is performed in exact arithmetic.
          ‘levin_u_sum’ returns the result.

     ‘levin_numeric’
          The calculation is performed in bigfloat arithmetic.  The
          return value is a list ‘[<result>, <variance>]’ where <result>
          is the result of the bigfloat calculation, and <variance> is
          in units of ‘10^(-2*fpprec)’.

     ‘load("levin")’ loads this function.

     See ‘Examples for levin’ for examples.

 -- Function: bflevin_u_sum (<a>, <n>, <n_0>)

     Estimate ‘sum(<a>(<n>), <n>, <n_0>, inf)’ using the Levin
     u-transform in bigfloat arithmetic.

     ‘bflevin_u_sum’ attempts to return the sum of the infinite series
     with a precision given by the global variable ‘fpprec’ using
     bigfloat arithmetic.

     See ‘levin_options’ for options to control this function.
     ‘bflevin_u_sum’ uses an adaptive algorithm to increase both the
     number of terms and the bigfloat precision used for internal
     calculations until the estimated error is acceptable.

     ‘load("levin")’ loads this function.

     See ‘Examples for levin’ for examples.

 -- Variable: levin_options

     Function ‘bflevin_u_sum’ attempts to return the sum of an infinite
     series with a precision given by the global variable ‘fpprec’ using
     bigfloat arithmetic.  ‘bflevin_u_sum’ uses an adaptive algorithm to
     increase both the number of terms used and the bigfloat precision
     used for internal calculations until the estimated error is
     acceptable.

     The undeclared array ‘levin_options’ contains options for
     controlling ‘bflevin_u_sum’.  Note that the subscript values for
     ‘levin_options’ are strings.

     ‘levin_options["debug"]’
          When ‘true’, ‘bflevin_u_sum’ generates additional output.
          Default: ‘false’

     ‘levin_options["min_terms"]’
          Minimum number of terms used by ‘bflevin_u_sum’.  Default: 5

     ‘levin_options["max_terms"]’
          Maximum number of terms used by ‘bflevin_u_sum’.  Default: 640
          (equal to 5*2^7)

     ‘levin_options["min_precision"]’
          Initial bigfloat precision for ‘bflevin_u_sum’.  Default: 16

     ‘levin_options["max_precision"]’
          Maximum bigfloat precision for ‘bflevin_u_sum’.  Default: 1000


File: maxima.info,  Node: Examples for levin,  Next: References for levin,  Prev: Functions and Variables for levin,  Up: Package levin

74.3 Examples for levin
=======================

74.3.1 Example 1: The Basel problem
-----------------------------------

The Basel problem asks for the precise summation of the reciprocals of
the squares of the natural numbers.  Leonhard Euler found, in 1734,

                     inf
                     ====
                     \      1    pi^2
                      >    --- = ---- = 1.6449340668482262...
                     /     n^2     6
                     ====
                     n = 1

   The sum is evaluated using both: ‘levin_u_sum’ using modes
levin_algebraic and levin_numeric; and ‘bflevin_u_sum’ with two values
of bigfloat precision ‘fpprec’.

     (%i1) (load("levin"), exact: %pi^2/6, done);
     (%o1)                         done
     (%i2) s: levin_u_sum(1/n^2, n, 1, 10);
                                3899836039
     (%o2)                      ----------
                                2370816000
     (%i3) float(s);
     (%o3)                   1.644934081345832
     (%i4) float(s - exact);
     (%o4)                 1.4497605782537448e-8
     (%i5) s: levin_u_sum(1/n^2, n, 1, 10, 'levin_numeric);
     (%o5)     [1.644934081345756b0, 1.882785043290232b-12]
     (%i6) bfloat(s[1] - exact);
     (%o6)                 1.449752928817105b-8
     (%i7) s: bflevin_u_sum(1/n^2, n, 1);
     (%o7)                  1.644934066848226b0
     (%i8) s - bfloat(exact);
     (%o8)                 2.775557561562891b-17
     (%i9) /* Now increase fpprec and try the same example again. */
      fpprec: 32;
     (%o9)                          32
     (%i10) s: bflevin_u_sum(1/n^2, n, 1);
     (%o10)         1.644934066848226436472415166646b0
     (%i11) s - bfloat(exact);
     (%o11)       - 3.0814879110195773648895647081359b-33

   Using 10 terms in the series we were able to extrapolate to the exact
sum with an error of approximately 10^{-8}.  This would require around
10^{8} terms by direct summation.  In this case the two modes of
<levin_u_sum> returned results of similar accuracy.

   The effect of the number of terms <nterms> on the accuracy of
<levin_u_sum> is shown in the following example.  The sum of the series
and the approximation error is evaluated for increasing values of
argument <nterms> for both values of the optional argument <mode>:
<levin_algebraic> and <levin_numeric>.  The numeric calculations are
performed with bigfloat precision <fpprec> of 16.  Errors are calculated
with <fpprec> equal to 64.

   The results are reported in three columns: <nterms>, the number of
terms used; <errora>, the difference between the algebraic result and
the exact sum; and <errorn>, the difference between numeric result and
the exact sum.  For small values of <nterms> the two modes return
similar results.  As <nterms> increases above 12, the error for mode
<levin_algebraic> continues to decrease.  However, for mode
<levin_numeric> the error increases with <nterms> to due to roundoff.
This behavior is commonly encountered, and can be addressed by
increasing <fpprec>.

     (%i1) (load("levin"), fpprec: 32, fpprintprec: 3, exact: %pi^2/6, done);
     (%o1)                         done
     (%i2) for nterms: 6 step 2 thru 24 do (
          sa: levin_u_sum(1/n^2, n, 1, nterms),
          sn: block([fpprec: 16], levin_u_sum(1/n^2, n, 1, nterms, 'levin_numeric)),
          errora: abs(bfloat(sa - exact)),
          errorn: abs(bfloat(sn[1] - exact)),
          print(nterms, "     ", errora, "   ", errorn));
     6       2.58b-4     2.58b-4
     8       3.51b-6     3.51b-6
     10       1.45b-8     1.45b-8
     12       2.44b-10     2.44b-10
     14       5.16b-12     3.78b-11
     16       3.54b-14     4.5b-10
     18       3.75b-16     3.21b-11
     20       1.36b-17     8.66b-9
     22       1.73b-19     4.48b-7
     24       4.45b-22     4.25b-6
     (%o2)                         done

74.3.2 Example 2: Divergent Taylor series for log(1+x) when x=2
---------------------------------------------------------------

The Levin u-transformation can find the anti-limit of certain divergent
series.  In this example we calculate the anti-limit of the divergent
Taylor series for log(1+x) when x=2.

                     n
                     ====      m
                     \     (-2)
             A  =  -  >    -----
              n      /       m
                     ====
                     m = 1

   with anti-limit equal to log(3) = 1.0986122886681098...

     (%i1) (load("levin"), done);
     (%o1)                         done
     (%i2) levin_u_sum(-(-2)^n/n, n, 1, 10);
                                3641179708
     (%o2)                      ----------
                                3314344635
     (%i3) s: float(%);
     (%o3)                  1.0986122775370342
     (%i4) exact: log(3.0);
     (%o4)                  1.0986122886681096
     (%i5) s - exact;
     (%o5)                - 1.1131075394743561e-8


File: maxima.info,  Node: References for levin,  Prev: Examples for levin,  Up: Package levin

74.4 References for levin
=========================

The t, u and v Levin transformations are introduced in:

   • (Levin 1973) Levin, David.  Development of Non-Linear
     Transformations for Improving Convergence of Sequences,
     International Journal of Computer Mathematics 3 (1973): 371–88.
     doi:10.1080/00207167308803075
     (https://doi.org/10.1080/00207167308803075)

   • Levin, David, and Avram Sidi.  Two New Classes of Nonlinear
     Transformations for Accelerating the Convergence of Infinite
     Integrals and Series, Applied Mathematics and Computation 9, no.  3
     (October 1981): 175–215.  doi:10.1016/0096-3003(81)90028-X
     (https://doi.org/10.1016/0096-3003(81)90028-X)

   Smith and Ford compared the performance of series acceleration
algorithms in a series of papers.  In conjunction with Fessler they
published algorithms and code that implement the u-transformation with
estimates of truncation and round-off errors.

   • (Smith and Ford 1979) Smith, David A., and William F. Ford.
     Acceleration of Linear and Logarithmic Convergence, SIAM Journal on
     Numerical Analysis 16, no.  2 (1979): 223.  doi:10.1137/0716017
     (https://doi.org/10.1080/00207167308803075)

   • (Smith and Ford 1982) Smith, David A., and William F. Ford.
     Numerical Comparisons of Nonlinear Convergence Accelerators,
     Mathematics of Computation 38, no.  158 (1 May 1982): 481–481.
     doi:10.1090/S0025-5718-1982-0645665-1
     (https://doi.org/10.1090/S0025-5718-1982-0645665-1)

   • Fessler, Theodore, William F. Ford, and David A. Smith.  HURRY: An
     Acceleration Algorithm for Scalar Sequences and Series.  ACM
     Transactions on Mathematical Software 9, no.  3 (1 September 1983):
     346–54.  doi:10.1145/356044.356051
     (https://doi.org/10.1145/356044.356051)

   • Fessler, Theodore, David A. Smith, and William Ford.  Algorithm
     602: HURRY: An Acceleration Algorithm for Scalar Sequences and
     Series.  ACM Transactions on Mathematical Software (TOMS) 9, no.  3
     (September 1983): 355–57.  doi:10.1145/356044.356052
     (https://doi.org/10.1145/356044.356052)

   Sidi (2003) discusses u transformations and more recent extensions.

   • (Sidi 2003) Sidi, Avram.  Practical Extrapolation Methods: Theory
     and Applications, Cambridge University Press, 2003, ISBN
     9780521661591 (https://doi.org/10.1017/CBO9780511546815)

   Bender and Orszag (1978), Chapter 8 Summation of Series, provides
general background on motivation and methods, but does not cover Levin
transformations.

   • (Bender and Orszag, 1978) Bender, Carl, and Steven Orszag.
     Advanced Mathematical Methods for Scientists and Engineers,
     McGraw-Hill, 1978, ISBN 978-0-07-004452-4


File: maxima.info,  Node: Package lindstedt,  Next: Package linearalgebra,  Prev: Package levin,  Up: Top

75 Package lindstedt
********************

* Menu:

* Functions and Variables for lindstedt::


File: maxima.info,  Node: Functions and Variables for lindstedt,  Prev: Package lindstedt,  Up: Package lindstedt

75.1 Functions and Variables for lindstedt
==========================================

 -- Function: Lindstedt (<eq>,<pvar>,<torder>,<ic>)
     This is a first pass at a Lindstedt code.  It can solve problems
     with initial conditions entered, which can be arbitrary constants,
     (just not <%k1> and <%k2>) where the initial conditions on the
     perturbation equations are z[i]=0, z'[i]=0 for i>0.  <ic> is the
     list of initial conditions.

     Problems occur when initial conditions are not given, as the
     constants in the perturbation equations are the same as the zero
     order equation solution.  Also, problems occur when the initial
     conditions for the perturbation equations are not z[i]=0, z'[i]=0
     for i>0, such as the Van der Pol equation.

     Example:
          (%i1) load("makeOrders")$

          (%i2) load("lindstedt")$

          (%i3) Lindstedt('diff(x,t,2)+x-(e*x^3)/6,e,2,[1,0]);
                    2
                   e  (cos(5 T) - 24 cos(3 T) + 23 cos(T))
          (%o3) [[[---------------------------------------
                                    36864
             e (cos(3 T) - cos(T))
           - --------------------- + cos(T)],
                      192
                    2
                 7 e    e
          T = (- ---- - -- + 1) t]]
                 3072   16

     To use this function write first ‘load("makeOrders")’ and
     ‘load("lindstedt")’.


File: maxima.info,  Node: Package linearalgebra,  Next: Package lsquares,  Prev: Package lindstedt,  Up: Top

76 Package linearalgebra
************************

* Menu:

* Introduction to linearalgebra::
* Functions and Variables for linearalgebra::


File: maxima.info,  Node: Introduction to linearalgebra,  Next: Functions and Variables for linearalgebra,  Prev: Package linearalgebra,  Up: Package linearalgebra

76.1 Introduction to linearalgebra
==================================

‘linearalgebra’ is a collection of functions for linear algebra.

   Example:

     (%i1) M : matrix ([1, 2], [1, 2]);
                                 [ 1  2 ]
     (%o1)                       [      ]
                                 [ 1  2 ]
     (%i2) nullspace (M);
                                    [  1  ]
                                    [     ]
     (%o2)                     span([   1 ])
                                    [ - - ]
                                    [   2 ]
     (%i3) columnspace (M);
                                     [ 1 ]
     (%o3)                      span([   ])
                                     [ 1 ]
     (%i4) ptriangularize (M - z*ident(2), z);
                              [ 1   2 - z   ]
     (%o4)                    [             ]
                              [           2 ]
                              [ 0  3 z - z  ]
     (%i5) M : matrix ([1, 2, 3], [4, 5, 6], [7, 8, 9]) - z*ident(3);
                          [ 1 - z    2      3   ]
                          [                     ]
     (%o5)                [   4    5 - z    6   ]
                          [                     ]
                          [   7      8    9 - z ]
     (%i6) MM : ptriangularize (M, z);
                   [ 4  5 - z            6            ]
                   [                                  ]
                   [                2                 ]
                   [     66        z    102 z   132   ]
                   [ 0   --      - -- + ----- + ---   ]
     (%o6)         [     49        7     49     49    ]
                   [                                  ]
                   [               3        2         ]
                   [           49 z    245 z    147 z ]
                   [ 0    0    ----- - ------ - ----- ]
                   [            264      88      44   ]
     (%i7) algebraic : true;
     (%o7)                         true
     (%i8) tellrat (MM [3, 3]);
                              3       2
     (%o8)                  [z  - 15 z  - 18 z]
     (%i9) MM : ratsimp (MM);
                    [ 4  5 - z           6           ]
                    [                                ]
                    [                2               ]
     (%o9)          [     66      7 z  - 102 z - 132 ]
                    [ 0   --    - ------------------ ]
                    [     49              49         ]
                    [                                ]
                    [ 0    0             0           ]
     (%i10) nullspace (MM);
                             [        1         ]
                             [                  ]
                             [   2              ]
                             [  z  - 14 z - 16  ]
                             [  --------------  ]
     (%o10)             span([        8         ])
                             [                  ]
                             [    2             ]
                             [   z  - 18 z - 12 ]
                             [ - -------------- ]
                             [         12       ]
     (%i11) M : matrix ([1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12],
                        [13, 14, 15, 16]);
                            [ 1   2   3   4  ]
                            [                ]
                            [ 5   6   7   8  ]
     (%o11)                 [                ]
                            [ 9   10  11  12 ]
                            [                ]
                            [ 13  14  15  16 ]
     (%i12) columnspace (M);
                                [ 1  ]  [ 2  ]
                                [    ]  [    ]
                                [ 5  ]  [ 6  ]
     (%o12)                span([    ], [    ])
                                [ 9  ]  [ 10 ]
                                [    ]  [    ]
                                [ 13 ]  [ 14 ]
     (%i13) apply ('orthogonal_complement, args (nullspace (transpose (M))));
                                [ 0 ]  [  1  ]
                                [   ]  [     ]
                                [ 1 ]  [  0  ]
     (%o13)                span([   ], [     ])
                                [ 2 ]  [ - 1 ]
                                [   ]  [     ]
                                [ 3 ]  [ - 2 ]


File: maxima.info,  Node: Functions and Variables for linearalgebra,  Prev: Introduction to linearalgebra,  Up: Package linearalgebra

76.2 Functions and Variables for linearalgebra
==============================================

 -- Function: addmatrices (<f>, <M_1>, ..., <M_n>)

     Using the function <f> as the addition function, return the sum of
     the matrices <M_1>, ..., <M_n>.  The function <f> must accept any
     number of arguments (a Maxima nary function).

     Examples:

          (%i1) m1 : matrix([1,2],[3,4])$
          (%i2) m2 : matrix([7,8],[9,10])$
          (%i3) addmatrices('max,m1,m2);
          (%o3) matrix([7,8],[9,10])
          (%i4) addmatrices('max,m1,m2,5*m1);
          (%o4) matrix([7,10],[15,20])

 -- Function: blockmatrixp (<M>)

     Return true if and only if <M> is a matrix and every entry of <M>
     is a matrix.

 -- Function: columnop (<M>, <i>, <j>, <theta>)

     If <M> is a matrix, return the matrix that results from doing the
     column operation ‘C_i <- C_i - <theta> * C_j’.  If <M> doesn't have
     a row <i> or <j>, signal an error.

 -- Function: columnswap (<M>, <i>, <j>)

     If <M> is a matrix, swap columns <i> and <j>.  If <M> doesn't have
     a column <i> or <j>, signal an error.

 -- Function: columnspace (<M>)

     If <M> is a matrix, return ‘span (v_1, ..., v_n)’, where the set
     ‘{v_1, ..., v_n}’ is a basis for the column space of <M>.  The span
     of the empty set is ‘{0}’.  Thus, when the column space has only
     one member, return ‘span ()’.

 -- Function: cholesky
          cholesky (<M>)
          cholesky (<M>, <field>)

     Return the Cholesky factorization of the matrix selfadjoint (or
     hermitian) matrix <M>.  The second argument defaults to
     'generalring.'  For a description of the possible values for
     <field>, see ‘lu_factor’.

 -- Function: ctranspose (<M>)

     Return the complex conjugate transpose of the matrix <M>.  The
     function ‘ctranspose’ uses ‘matrix_element_transpose’ to transpose
     each matrix element.

 -- Function: diag_matrix (<d_1>, <d_2>, ..., <d_n>)

     Return a diagonal matrix with diagonal entries <d_1>, <d_2>, ...,
     <d_n>.  When the diagonal entries are matrices, the zero entries of
     the returned matrix are zero matrices of the appropriate size; for
     example:

          (%i1) diag_matrix(diag_matrix(1,2),diag_matrix(3,4));

                                      [ [ 1  0 ]  [ 0  0 ] ]
                                      [ [      ]  [      ] ]
                                      [ [ 0  2 ]  [ 0  0 ] ]
          (%o1)                       [                    ]
                                      [ [ 0  0 ]  [ 3  0 ] ]
                                      [ [      ]  [      ] ]
                                      [ [ 0  0 ]  [ 0  4 ] ]
          (%i2) diag_matrix(p,q);

                                             [ p  0 ]
          (%o2)                              [      ]
                                             [ 0  q ]

 -- Function: dotproduct (<u>, <v>)

     Return the dotproduct of vectors <u> and <v>.  This is the same as
     ‘conjugate (transpose (<u>)) . <v>’.  The arguments <u> and <v>
     must be column vectors.

 -- Function: eigens_by_jacobi
          eigens_by_jacobi (<A>)
          eigens_by_jacobi (<A>, <field_type>)

     Computes the eigenvalues and eigenvectors of <A> by the method of
     Jacobi rotations.  <A> must be a symmetric matrix (but it need not
     be positive definite nor positive semidefinite).  <field_type>
     indicates the computational field, either ‘floatfield’ or
     ‘bigfloatfield’.  If <field_type> is not specified, it defaults to
     ‘floatfield’.

     The elements of <A> must be numbers or expressions which evaluate
     to numbers via ‘float’ or ‘bfloat’ (depending on <field_type>).

     Examples:

          (%i1) S: matrix([1/sqrt(2), 1/sqrt(2)],[-1/sqrt(2), 1/sqrt(2)]);
                               [     1         1    ]
                               [  -------   ------- ]
                               [  sqrt(2)   sqrt(2) ]
          (%o1)                [                    ]
                               [      1        1    ]
                               [ - -------  ------- ]
                               [   sqrt(2)  sqrt(2) ]
          (%i2) L : matrix ([sqrt(3), 0], [0, sqrt(5)]);
                                [ sqrt(3)     0    ]
          (%o2)                 [                  ]
                                [    0     sqrt(5) ]
          (%i3) M : S . L . transpose (S);
                      [ sqrt(5)   sqrt(3)  sqrt(5)   sqrt(3) ]
                      [ ------- + -------  ------- - ------- ]
                      [    2         2        2         2    ]
          (%o3)       [                                      ]
                      [ sqrt(5)   sqrt(3)  sqrt(5)   sqrt(3) ]
                      [ ------- - -------  ------- + ------- ]
                      [    2         2        2         2    ]
          (%i4) eigens_by_jacobi (M);
          The largest percent change was 0.1454972243679
          The largest percent change was 0.0
          number of sweeps: 2
          number of rotations: 1
          (%o4) [[1.732050807568877, 2.23606797749979],
                                  [  0.70710678118655   0.70710678118655 ]
                                  [                                      ]]
                                  [ - 0.70710678118655  0.70710678118655 ]
          (%i5) float ([[sqrt(3), sqrt(5)], S]);
          (%o5) [[1.732050807568877, 2.23606797749979],
                                  [  0.70710678118655   0.70710678118655 ]
                                  [                                      ]]
                                  [ - 0.70710678118655  0.70710678118655 ]
          (%i6) eigens_by_jacobi (M, bigfloatfield);
          The largest percent change was 1.454972243679028b-1
          The largest percent change was 0.0b0
          number of sweeps: 2
          number of rotations: 1
          (%o6) [[1.732050807568877b0, 2.23606797749979b0],
                          [  7.071067811865475b-1   7.071067811865475b-1 ]
                          [                                              ]]
                          [ - 7.071067811865475b-1  7.071067811865475b-1 ]

 -- Function: get_lu_factors (<x>)

     When ‘<x> = lu_factor (<A>)’, then ‘get_lu_factors’ returns a list
     of the form ‘[P, L, U]’, where <P> is a permutation matrix, <L> is
     lower triangular with ones on the diagonal, and <U> is upper
     triangular, and ‘<A> = <P> <L> <U>’.

 -- Function: hankel
          hankel (<col>)
          hankel (<col>, <row>)

     Return a Hankel matrix <H>.  The first column of <H> is <col>;
     except for the first entry, the last row of <H> is <row>.  The
     default for <row> is the zero vector with the same length as <col>.

 -- Function: hessian (<f>, <x>)

     Returns the Hessian matrix of <f> with respect to the list of
     variables <x>.  The ‘(i, j)’-th element of the Hessian matrix is
     ‘diff(<f>, <x>[i], 1, <x>[j], 1)’.

     Examples:

          (%i1) hessian (x * sin (y), [x, y]);
                               [   0       cos(y)   ]
          (%o1)                [                    ]
                               [ cos(y)  - x sin(y) ]
          (%i2) depends (F, [a, b]);
          (%o2)                       [F(a, b)]
          (%i3) hessian (F, [a, b]);
                                  [   2      2   ]
                                  [  d F    d F  ]
                                  [  ---   ----- ]
                                  [    2   da db ]
                                  [  da          ]
          (%o3)                   [              ]
                                  [   2      2   ]
                                  [  d F    d F  ]
                                  [ -----   ---  ]
                                  [ da db     2  ]
                                  [         db   ]

 -- Function: hilbert_matrix (<n>)

     Return the <n> by <n> Hilbert matrix.  When <n> isn't a positive
     integer, signal an error.

 -- Function: identfor
          identfor (<M>)
          identfor (<M>, <fld>)

     Return an identity matrix that has the same shape as the matrix
     <M>.  The diagonal entries of the identity matrix are the
     multiplicative identity of the field <fld>; the default for <fld>
     is <generalring>.

     The first argument <M> should be a square matrix or a non-matrix.
     When <M> is a matrix, each entry of <M> can be a square matrix -
     thus <M> can be a blocked Maxima matrix.  The matrix can be blocked
     to any (finite) depth.

     See also ‘zerofor’

 -- Function: invert_by_lu (<M>, <(rng generalring)>)

     Invert a matrix <M> by using the LU factorization.  The LU
     factorization is done using the ring <rng>.

 -- Function: jacobian (<f>, <x>)

     Returns the Jacobian matrix of the list of functions <f> with
     respect to the list of variables <x>.  The ‘(i, j)’-th element of
     the Jacobian matrix is ‘diff(<f>[i], <x>[j])’.

     Examples:

          (%i1) jacobian ([sin (u - v), sin (u * v)], [u, v]);
                            [ cos(v - u)  - cos(v - u) ]
          (%o1)             [                          ]
                            [ v cos(u v)   u cos(u v)  ]
          (%i2) depends ([F, G], [y, z]);
          (%o2)                  [F(y, z), G(y, z)]
          (%i3) jacobian ([F, G], [y, z]);
                                     [ dF  dF ]
                                     [ --  -- ]
                                     [ dy  dz ]
          (%o3)                      [        ]
                                     [ dG  dG ]
                                     [ --  -- ]
                                     [ dy  dz ]

 -- Function: kronecker_product (<A>, <B>)

     Return the Kronecker product of the matrices <A> and <B>.

 -- Function: locate_matrix_entry (<M>, <r_1>, <c_1>, <r_2>, <c_2>, <f>,
          <rel>)

     The first argument must be a matrix; the arguments <r_1> through
     <c_2> determine a sub-matrix of <M> that consists of rows <r_1>
     through <r_2> and columns <c_1> through <c_2>.

     Find an entry in the sub-matrix <M> that satisfies some property.
     Three cases:

     (1) ‘<rel> = 'bool’ and <f> a predicate:

     Scan the sub-matrix from left to right then top to bottom, and
     return the index of the first entry that satisfies the predicate
     <f>.  If no matrix entry satisfies <f>, return ‘false’.

     (2) ‘<rel> = 'max’ and <f> real-valued:

     Scan the sub-matrix looking for an entry that maximizes <f>.
     Return the index of a maximizing entry.

     (3) ‘<rel> = 'min’ and <f> real-valued:

     Scan the sub-matrix looking for an entry that minimizes <f>.
     Return the index of a minimizing entry.

 -- Function: lu_backsub (<M>, <b>)

     When ‘<M> = lu_factor (<A>, <field>)’, then ‘lu_backsub (<M>, <b>)’
     solves the linear system ‘<A> <x> = <b>’.

     The <n> by <m> matrix ‘<b>’, with <n> the number of rows of the
     matrix ‘<A>’, contains one right hand side per column.  If there is
     only one right hand side then ‘<b>’ must be a <n> by 1 matrix.

     Each column of the matrix ‘<x>=lu_backsub (<M>, <b>)’ is the
     solution corresponding to the respective column of ‘<b>’.

     Examples:

          (%i1) A : matrix ([1 - z, 3], [3, 8 - z]);
                                         [ 1 - z    3   ]
          (%o1)                          [              ]
                                         [   3    8 - z ]
          (%i2) M : lu_factor (A,generalring);
                         [ 1 - z          3         ]
                         [                          ]
          (%o2)         [[   3              9       ], [1, 2], generalring]
                         [ -----  (- z) - ----- + 8 ]
                         [ 1 - z          1 - z     ]
          (%i3) b : matrix([a],[c]);
                                               [ a ]
          (%o3)                                [   ]
                                               [ c ]
          (%i4) x : lu_backsub(M,b);
                                     [               3 a     ]
                                     [       3 (c - -----)   ]
                                     [              1 - z    ]
                                     [ a - ----------------- ]
                                     [               9       ]
                                     [     (- z) - ----- + 8 ]
                                     [             1 - z     ]
                                     [ --------------------- ]
          (%o4)                      [         1 - z         ]
                                     [                       ]
                                     [            3 a        ]
                                     [       c - -----       ]
                                     [           1 - z       ]
                                     [   -----------------   ]
                                     [             9         ]
                                     [   (- z) - ----- + 8   ]
                                     [           1 - z       ]
          (%i5) ratsimp(A . x - b);
                                               [ 0 ]
          (%o5)                                [   ]
                                               [ 0 ]
          (%i6) B : matrix([a,d],[c,f]);
                                             [ a  d ]
          (%o6)                              [      ]
                                             [ c  f ]
          (%i7) x : lu_backsub(M,B);
                         [               3 a                    3 d     ]
                         [       3 (c - -----)          3 (f - -----)   ]
                         [              1 - z                  1 - z    ]
                         [ a - -----------------  d - ----------------- ]
                         [               9                      9       ]
                         [     (- z) - ----- + 8      (- z) - ----- + 8 ]
                         [             1 - z                  1 - z     ]
                         [ ---------------------  --------------------- ]
          (%o7)          [         1 - z                  1 - z         ]
                         [                                              ]
                         [            3 a                    3 d        ]
                         [       c - -----              f - -----       ]
                         [           1 - z                  1 - z       ]
                         [   -----------------      -----------------   ]
                         [             9                      9         ]
                         [   (- z) - ----- + 8      (- z) - ----- + 8   ]
                         [           1 - z                  1 - z       ]
          (%i8) ratsimp(A . x - B);
                                             [ 0  0 ]
          (%o8)                              [      ]
                                             [ 0  0 ]

 -- Function: lu_factor (<M>, <field>)

     Return a list of the form ‘[<LU>, <perm>, <fld>]’, or ‘[<LU>,
     <perm>, <fld>, <lower-cnd> <upper-cnd>]’, where

     (1) The matrix <LU> contains the factorization of <M> in a packed
     form.  Packed form means three things: First, the rows of <LU> are
     permuted according to the list <perm>.  If, for example, <perm> is
     the list ‘[3,2,1]’, the actual first row of the <LU> factorization
     is the third row of the matrix <LU>.  Second, the lower triangular
     factor of m is the lower triangular part of <LU> with the diagonal
     entries replaced by all ones.  Third, the upper triangular factor
     of <M> is the upper triangular part of <LU>.

     (2) When the field is either ‘floatfield’ or ‘complexfield’, the
     numbers <lower-cnd> and <upper-cnd> are lower and upper bounds for
     the infinity norm condition number of <M>.  For all fields, the
     condition number might not be estimated; for such fields,
     ‘lu_factor’ returns a two item list.  Both the lower and upper
     bounds can differ from their true values by arbitrarily large
     factors.  (See also ‘mat_cond’.)

     The argument <M> must be a square matrix.

     The optional argument <fld> must be a symbol that determines a ring
     or field.  The pre-defined fields and rings are:

     (a) ‘generalring’ - the ring of Maxima expressions,

     (b) ‘floatfield’ - the field of floating point numbers of the type
     double,

     (c) ‘complexfield’ - the field of complex floating point numbers of
     the type double,

     (d) ‘crering’ - the ring of Maxima CRE expressions,

     (e) ‘rationalfield’ - the field of rational numbers,

     (f) ‘runningerror’ - track the all floating point rounding errors,

     (g) ‘noncommutingring’ - the ring of Maxima expressions where
     multiplication is the non-commutative dot operator.

     When the field is ‘floatfield’, ‘complexfield’, or ‘runningerror’,
     the algorithm uses partial pivoting; for all other fields, rows are
     switched only when needed to avoid a zero pivot.

     Floating point addition arithmetic isn't associative, so the
     meaning of 'field' differs from the mathematical definition.

     A member of the field ‘runningerror’ is a two member Maxima list of
     the form ‘[x,n]’,where <x> is a floating point number and ‘n’ is an
     integer.  The relative difference between the 'true' value of ‘x’
     and ‘x’ is approximately bounded by the machine epsilon times ‘n’.
     The running error bound drops some terms that of the order the
     square of the machine epsilon.

     There is no user-interface for defining a new field.  A user that
     is familiar with Common Lisp should be able to define a new field.
     To do this, a user must define functions for the arithmetic
     operations and functions for converting from the field
     representation to Maxima and back.  Additionally, for ordered
     fields (where partial pivoting will be used), a user must define
     functions for the magnitude and for comparing field members.  After
     that all that remains is to define a Common Lisp structure ‘mring’.
     The file ‘mring’ has many examples.

     To compute the factorization, the first task is to convert each
     matrix entry to a member of the indicated field.  When conversion
     isn't possible, the factorization halts with an error message.
     Members of the field needn't be Maxima expressions.  Members of the
     ‘complexfield’, for example, are Common Lisp complex numbers.  Thus
     after computing the factorization, the matrix entries must be
     converted to Maxima expressions.

     See also ‘get_lu_factors’.

     Examples:

          (%i1) w[i,j] := random (1.0) + %i * random (1.0);
          (%o1)          w     := random(1.) + %i random(1.)
                          i, j
          (%i2) showtime : true$
          Evaluation took 0.00 seconds (0.00 elapsed)
          (%i3) M : genmatrix (w, 100, 100)$
          Evaluation took 7.40 seconds (8.23 elapsed)
          (%i4) lu_factor (M, complexfield)$
          Evaluation took 28.71 seconds (35.00 elapsed)
          (%i5) lu_factor (M, generalring)$
          Evaluation took 109.24 seconds (152.10 elapsed)
          (%i6) showtime : false$

          (%i7) M : matrix ([1 - z, 3], [3, 8 - z]);
                                  [ 1 - z    3   ]
          (%o7)                   [              ]
                                  [   3    8 - z ]
          (%i8) lu_factor (M, generalring);
                    [ 1 - z         3        ]
                    [                        ]
          (%o8)    [[   3            9       ], [1, 2], generalring]
                    [ -----  - z - ----- + 8 ]
                    [ 1 - z        1 - z     ]
          (%i9) get_lu_factors (%);
                            [   1    0 ]  [ 1 - z         3        ]
                  [ 1  0 ]  [          ]  [                        ]
          (%o9)  [[      ], [   3      ], [                9       ]]
                  [ 0  1 ]  [ -----  1 ]  [   0    - z - ----- + 8 ]
                            [ 1 - z    ]  [              1 - z     ]
          (%i10) %[1] . %[2] . %[3];
                                  [ 1 - z    3   ]
          (%o10)                  [              ]
                                  [   3    8 - z ]

 -- Function: mat_cond
          mat_cond (<M>, 1)
          mat_cond (<M>, inf)

     Return the <p>-norm matrix condition number of the matrix <m>.  The
     allowed values for <p> are 1 and <inf>.  This function uses the LU
     factorization to invert the matrix <m>.  Thus the running time for
     ‘mat_cond’ is proportional to the cube of the matrix size;
     ‘lu_factor’ determines lower and upper bounds for the infinity norm
     condition number in time proportional to the square of the matrix
     size.

 -- Function: mat_norm
          mat_norm (<M>, 1)
          mat_norm (<M>, inf)
          mat_norm (<M>, frobenius)

     Return the matrix <p>-norm of the matrix <M>.  The allowed values
     for <p> are 1, ‘inf’, and ‘frobenius’ (the Frobenius matrix norm).
     The matrix <M> should be an unblocked matrix.

 -- Function: matrixp
          matrixp (<e>, <p>)
          matrixp (<e>)

     Given an optional argument <p>, return ‘true’ if <e> is a matrix
     and <p> evaluates to ‘true’ for every matrix element.  When
     ‘matrixp’ is not given an optional argument, return ‘true’ if ‘e’
     is a matrix.  In all other cases, return ‘false’.

     See also ‘blockmatrixp’

 -- Function: matrix_size (<M>)

     Return a two member list that gives the number of rows and columns,
     respectively of the matrix <M>.

 -- Function: mat_fullunblocker (<M>)

     If <M> is a block matrix, unblock the matrix to all levels.  If <M>
     is a matrix, return <M>; otherwise, signal an error.

 -- Function: mat_trace (<M>)

     Return the trace of the matrix <M>.  If <M> isn't a matrix, return
     a noun form.  When <M> is a block matrix, ‘mat_trace(M)’ returns
     the same value as does ‘mat_trace(mat_unblocker(m))’.

 -- Function: mat_unblocker (<M>)

     If <M> is a block matrix, unblock <M> one level.  If <M> is a
     matrix, ‘mat_unblocker (M)’ returns <M>; otherwise, signal an
     error.

     Thus if each entry of <M> is matrix, ‘mat_unblocker (M)’ returns an
     unblocked matrix, but if each entry of <M> is a block matrix,
     ‘mat_unblocker (M)’ returns a block matrix with one less level of
     blocking.

     If you use block matrices, most likely you'll want to set
     ‘matrix_element_mult’ to ‘"."’ and ‘matrix_element_transpose’ to
     ‘'transpose’.  See also ‘mat_fullunblocker’.

     Example:

          (%i1) A : matrix ([1, 2], [3, 4]);
                                      [ 1  2 ]
          (%o1)                       [      ]
                                      [ 3  4 ]
          (%i2) B : matrix ([7, 8], [9, 10]);
                                      [ 7  8  ]
          (%o2)                       [       ]
                                      [ 9  10 ]
          (%i3) matrix ([A, B]);
                               [ [ 1  2 ]  [ 7  8  ] ]
          (%o3)                [ [      ]  [       ] ]
                               [ [ 3  4 ]  [ 9  10 ] ]
          (%i4) mat_unblocker (%);
                                   [ 1  2  7  8  ]
          (%o4)                    [             ]
                                   [ 3  4  9  10 ]

 -- Function: nullspace (<M>)

     If <M> is a matrix, return ‘span (v_1, ..., v_n)’, where the set
     ‘{v_1, ..., v_n}’ is a basis for the nullspace of <M>.  The span of
     the empty set is ‘{0}’.  Thus, when the nullspace has only one
     member, return ‘span ()’.

 -- Function: nullity (<M>)

     If <M> is a matrix, return the dimension of the nullspace of <M>.

 -- Function: orthogonal_complement (<v_1>, ..., <v_n>)

     Return ‘span (u_1, ..., u_m)’, where the set ‘{u_1, ..., u_m}’ is a
     basis for the orthogonal complement of the set ‘(v_1, ..., v_n)’.

     Each vector <v_1> through <v_n> must be a column vector.

 -- Function: polytocompanion (<p>, <x>)

     If <p> is a polynomial in <x>, return the companion matrix of <p>.
     For a monic polynomial <p> of degree <n>, we have ‘<p> = (-1)^<n>
     charpoly (polytocompanion (<p>, <x>))’.

     When <p> isn't a polynomial in <x>, signal an error.

 -- Function: ptriangularize (<M>, <v>)

     If <M> is a matrix with each entry a polynomial in <v>, return a
     matrix <M2> such that

     (1) <M2> is upper triangular,

     (2) ‘<M2> = <E_n> ... <E_1> <M>’, where <E_1> through <E_n> are
     elementary matrices whose entries are polynomials in <v>,

     (3) ‘|det (<M>)| = |det (<M2>)|’,

     Note: This function doesn't check that every entry is a polynomial
     in <v>.

 -- Function: rowop (<M>, <i>, <j>, <theta>)

     If <M> is a matrix, return the matrix that results from doing the
     row operation ‘R_i <- R_i - theta * R_j’.  If <M> doesn't have a
     row <i> or <j>, signal an error.

 -- Function: linalg_rank (<M>)

     Return the rank of the matrix <M>.  This function is equivalent to
     function ‘rank’, but it uses a different algorithm: it finds the
     ‘columnspace’ of the matrix and counts its elements, since the rank
     of a matrix is the dimension of its column space.

          (%i1) linalg_rank(matrix([1,2],[2,4]));
          (%o1)                           1
          (%i2) linalg_rank(matrix([1,b],[c,d]));
          (%o2)                           2

 -- Function: rowswap (<M>, <i>, <j>)

     If <M> is a matrix, swap rows <i> and <j>.  If <M> doesn't have a
     row <i> or <j>, signal an error.

 -- Function: toeplitz
          toeplitz (<col>)
          toeplitz (<col>, <row>)

     Return a Toeplitz matrix <T>.  The first first column of <T> is
     <col>; except for the first entry, the first row of <T> is <row>.
     The default for <row> is complex conjugate of <col>.  Example:

          (%i1)  toeplitz([1,2,3],[x,y,z]);
                                            [ 1  y  z ]
                                            [         ]
          (%o1)                             [ 2  1  y ]
                                            [         ]
                                            [ 3  2  1 ]
          (%i2)  toeplitz([1,1+%i]);

                                        [   1     1 - %I ]
          (%o2)                         [                ]
                                        [ %I + 1    1    ]

 -- Function: vandermonde_matrix ([<x_1>, ..., <x_n>])

     Return a <n> by <n> matrix whose <i>-th row is ‘[1, <x_i>, <x_i>^2,
     ... <x_i>^(<n>-1)]’.

 -- Function: zerofor
          zerofor (<M>)
          zerofor (<M>, <fld>)

     Return a zero matrix that has the same shape as the matrix <M>.
     Every entry of the zero matrix is the additive identity of the
     field <fld>; the default for <fld> is <generalring>.

     The first argument <M> should be a square matrix or a non-matrix.
     When <M> is a matrix, each entry of <M> can be a square matrix -
     thus <M> can be a blocked Maxima matrix.  The matrix can be blocked
     to any (finite) depth.

     See also ‘identfor’

 -- Function: zeromatrixp (<M>)

     If <M> is not a block matrix, return ‘true’ if ‘is (equal (<e>,
     0))’ is true for each element <e> of the matrix <M>.  If <M> is a
     block matrix, return ‘true’ if ‘zeromatrixp’ evaluates to ‘true’
     for each element of <e>.


File: maxima.info,  Node: Package lsquares,  Next: Package minpack,  Prev: Package linearalgebra,  Up: Top

77 Package lsquares
*******************

* Menu:

* Introduction to lsquares::
* Functions and Variables for lsquares::


File: maxima.info,  Node: Introduction to lsquares,  Next: Functions and Variables for lsquares,  Prev: Package lsquares,  Up: Package lsquares

77.1 Introduction to lsquares
=============================

‘lsquares’ is a collection of functions to implement the method of least
squares to estimate parameters for a model from numerical data.


File: maxima.info,  Node: Functions and Variables for lsquares,  Prev: Introduction to lsquares,  Up: Package lsquares

77.2 Functions and Variables for lsquares
=========================================

 -- Function: lsquares_estimates
          lsquares_estimates (<D>, <x>, <e>, <a>)
          lsquares_estimates (<D>, <x>, <e>, <a>, initial = <L>, tol =
          <t>)

     Estimate parameters <a> to best fit the equation <e> in the
     variables <x> and <a> to the data <D>, as determined by the method
     of least squares.  ‘lsquares_estimates’ first seeks an exact
     solution, and if that fails, then seeks an approximate solution.

     The return value is a list of lists of equations of the form ‘[a =
     ..., b = ..., c = ...]’.  Each element of the list is a distinct,
     equivalent minimum of the mean square error.

     The data <D> must be a matrix.  Each row is one datum (which may be
     called a 'record' or 'case' in some contexts), and each column
     contains the values of one variable across all data.  The list of
     variables <x> gives a name for each column of <D>, even the columns
     which do not enter the analysis.  The list of parameters <a> gives
     the names of the parameters for which estimates are sought.  The
     equation <e> is an expression or equation in the variables <x> and
     <a>; if <e> is not an equation, it is treated the same as ‘<e> =
     0’.

     Additional arguments to ‘lsquares_estimates’ are specified as
     equations and passed on verbatim to the function ‘lbfgs’ which is
     called to find estimates by a numerical method when an exact result
     is not found.

     If some exact solution can be found (via ‘solve’), the data <D> may
     contain non-numeric values.  However, if no exact solution is
     found, each element of <D> must have a numeric value.  This
     includes numeric constants such as ‘%pi’ and ‘%e’ as well as
     literal numbers (integers, rationals, ordinary floats, and
     bigfloats).  Numerical calculations are carried out with ordinary
     floating-point arithmetic, so all other kinds of numbers are
     converted to ordinary floats for calculations.

     If ‘lsquares_estimates’ needs excessive amounts of time or runs out
     of memory ‘lsquares_estimates_approximate’, which skips the attempt
     to find an exact solution, might still succeed.

     ‘load("lsquares")’ loads this function.

     See also ‘lsquares_estimates_exact’,
     ‘lsquares_estimates_approximate’,
     ‘lsquares_mse’, ‘lsquares_residuals’, and ‘lsquares_residual_mse’.

     Examples:

     A problem for which an exact solution is found.

          (%i1) load ("lsquares")$
          (%i2) M : matrix (
                  [1,1,1], [3/2,1,2], [9/4,2,1], [3,2,2], [2,2,1]);
                                     [ 1  1  1 ]
                                     [         ]
                                     [ 3       ]
                                     [ -  1  2 ]
                                     [ 2       ]
                                     [         ]
          (%o2)                      [ 9       ]
                                     [ -  2  1 ]
                                     [ 4       ]
                                     [         ]
                                     [ 3  2  2 ]
                                     [         ]
                                     [ 2  2  1 ]
          (%i3) lsquares_estimates (
                   M, [z,x,y], (z+D)^2 = A*x+B*y+C, [A,B,C,D]);
                            59        27      10921        107
          (%o3)     [[A = - --, B = - --, C = -----, D = - ---]]
                            16        16      1024         32

     A problem for which no exact solution is found, so
     ‘lsquares_estimates’ resorts to numerical approximation.

          (%i1) load ("lsquares")$
          (%i2) M : matrix ([1, 1], [2, 7/4], [3, 11/4], [4, 13/4]);
                                      [ 1  1  ]
                                      [       ]
                                      [    7  ]
                                      [ 2  -  ]
                                      [    4  ]
                                      [       ]
          (%o2)                       [    11 ]
                                      [ 3  -- ]
                                      [    4  ]
                                      [       ]
                                      [    13 ]
                                      [ 4  -- ]
                                      [    4  ]
          (%i3) lsquares_estimates (
            M, [x,y], y=a*x^b+c, [a,b,c], initial=[3,3,3], iprint=[-1,0]);
          (%o3) [[a = 1.375751433061394, b = 0.7148891534417651,
                                                 c = - 0.4020908910062951]]

     Exponential functions aren't well-conditioned for least min square
     fitting.  In case that fitting to them fails it might be possible
     to get rid of the exponential function using an logarithm.

          (%i1) load ("lsquares")$
          (%i2) yvalues: [1,3,5,60,200,203,80]$
          (%i3) time: [1,2,4,5,6,8,10]$
          (%i4) f: y=a*exp(b*t);
                                             b t
          (%o4)                      y = a %e
          (%i5) yvalues_log: log(yvalues)$
          (%i6) f_log: log(subst(y=exp(y),f));
                                              b t
          (%o6)                   y = log(a %e   )
          (%i7) lsquares_estimates (transpose(matrix(yvalues_log,time)),
                                    [y,t], f_log, [a,b]);
          *************************************************
            N=    2   NUMBER OF CORRECTIONS=25
                 INITIAL VALUES
           F=  6.802906290754687D+00   GNORM=  2.851243373781393D+01
          *************************************************

          I NFN FUNC                  GNORM                 STEPLENGTH

          1   3 1.141838765593467D+00 1.067358003667488D-01 1.390943719972406D-02
          2   5 1.141118195694385D+00 1.237977833033414D-01 5.000000000000000D+00
          3   6 1.136945723147959D+00 3.806696991691383D-01 1.000000000000000D+00
          4   7 1.133958243220262D+00 3.865103550379243D-01 1.000000000000000D+00
          5   8 1.131725773805499D+00 2.292258231154026D-02 1.000000000000000D+00
          6   9 1.131625585698168D+00 2.664440547017370D-03 1.000000000000000D+00
          7  10 1.131620564856599D+00 2.519366958715444D-04 1.000000000000000D+00

           THE MINIMIZATION TERMINATED WITHOUT DETECTING ERRORS.
           IFLAG = 0
          (%o7)   [[a = 1.155904145765554, b = 0.5772666876959847]]

 -- Function: lsquares_estimates_exact (<MSE>, <a>)

     Estimate parameters <a> to minimize the mean square error <MSE>, by
     constructing a system of equations and attempting to solve them
     symbolically via ‘solve’.  The mean square error is an expression
     in the parameters <a>, such as that returned by ‘lsquares_mse’.

     The return value is a list of lists of equations of the form ‘[a =
     ..., b = ..., c = ...]’.  The return value may contain zero, one,
     or two or more elements.  If two or more elements are returned,
     each represents a distinct, equivalent minimum of the mean square
     error.

     See also ‘lsquares_estimates’, ‘lsquares_estimates_approximate’,
     ‘lsquares_mse’, ‘lsquares_residuals’, and ‘lsquares_residual_mse’.

     Example:

          (%i1) load ("lsquares")$
          (%i2) M : matrix (
                   [1,1,1], [3/2,1,2], [9/4,2,1], [3,2,2], [2,2,1]);
                                     [ 1  1  1 ]
                                     [         ]
                                     [ 3       ]
                                     [ -  1  2 ]
                                     [ 2       ]
                                     [         ]
          (%o2)                      [ 9       ]
                                     [ -  2  1 ]
                                     [ 4       ]
                                     [         ]
                                     [ 3  2  2 ]
                                     [         ]
                                     [ 2  2  1 ]
          (%i3) mse : lsquares_mse (M, [z, x, y], (z + D)^2 = A*x + B*y + C);
                   5
                  ====
                  \                                         2     2
                   >    ((- B M    ) - A M     + (M     + D)  - C)
                  /            i, 3       i, 2     i, 1
                  ====
                  i = 1
          (%o3)   -------------------------------------------------
                                          5
          (%i4) lsquares_estimates_exact (mse, [A, B, C, D]);
                            59        27      10921        107
          (%o4)     [[A = - --, B = - --, C = -----, D = - ---]]
                            16        16      1024         32

 -- Function: lsquares_estimates_approximate (<MSE>, <a>, initial = <L>,
          tol = <t>)

     Estimate parameters <a> to minimize the mean square error <MSE>,
     via the numerical minimization function ‘lbfgs’.  The mean square
     error is an expression in the parameters <a>, such as that returned
     by ‘lsquares_mse’.

     The solution returned by ‘lsquares_estimates_approximate’ is a
     local (perhaps global) minimum of the mean square error.  For
     consistency with ‘lsquares_estimates_exact’, the return value is a
     nested list which contains one element, namely a list of equations
     of the form ‘[a = ..., b = ..., c = ...]’.

     Additional arguments to ‘lsquares_estimates_approximate’ are
     specified as equations and passed on verbatim to the function
     ‘lbfgs’.

     <MSE> must evaluate to a number when the parameters are assigned
     numeric values.  This requires that the data from which <MSE> was
     constructed comprise only numeric constants such as ‘%pi’ and ‘%e’
     and literal numbers (integers, rationals, ordinary floats, and
     bigfloats).  Numerical calculations are carried out with ordinary
     floating-point arithmetic, so all other kinds of numbers are
     converted to ordinary floats for calculations.

     ‘load("lsquares")’ loads this function.

     See also ‘lsquares_estimates’, ‘lsquares_estimates_exact’,
     ‘lsquares_mse’,
     ‘lsquares_residuals’, and ‘lsquares_residual_mse’.

     Example:

          (%i1) load ("lsquares")$
          (%i2) M : matrix (
                   [1,1,1], [3/2,1,2], [9/4,2,1], [3,2,2], [2,2,1]);
                                     [ 1  1  1 ]
                                     [         ]
                                     [ 3       ]
                                     [ -  1  2 ]
                                     [ 2       ]
                                     [         ]
          (%o2)                      [ 9       ]
                                     [ -  2  1 ]
                                     [ 4       ]
                                     [         ]
                                     [ 3  2  2 ]
                                     [         ]
                                     [ 2  2  1 ]
          (%i3) mse : lsquares_mse (M, [z, x, y], (z + D)^2 = A*x + B*y + C);
                   5
                  ====
                  \                                         2     2
                   >    ((- B M    ) - A M     + (M     + D)  - C)
                  /            i, 3       i, 2     i, 1
                  ====
                  i = 1
          (%o3)   -------------------------------------------------
                                          5
          (%i4) lsquares_estimates_approximate (
                  mse, [A, B, C, D], iprint = [-1, 0]);
          (%o4) [[A = - 3.678504947401971, B = - 1.683070351177937,
                           C = 10.63469950148714, D = - 3.340357993175297]]

 -- Function: lsquares_mse (<D>, <x>, <e>)

     Returns the mean square error (MSE), a summation expression, for
     the equation <e> in the variables <x>, with data <D>.

     The MSE is defined as:

                              n
                             ====
                         1   \                        2
                         -    >    (lhs(e ) - rhs(e ))
                         n   /           i         i
                             ====
                             i = 1

     where <n> is the number of data and ‘<e>[i]’ is the equation <e>
     evaluated with the variables in <x> assigned values from the ‘i’-th
     datum, ‘<D>[i]’.

     ‘load("lsquares")’ loads this function.

     Example:

          (%i1) load ("lsquares")$
          (%i2) M : matrix (
                   [1,1,1], [3/2,1,2], [9/4,2,1], [3,2,2], [2,2,1]);
                                     [ 1  1  1 ]
                                     [         ]
                                     [ 3       ]
                                     [ -  1  2 ]
                                     [ 2       ]
                                     [         ]
          (%o2)                      [ 9       ]
                                     [ -  2  1 ]
                                     [ 4       ]
                                     [         ]
                                     [ 3  2  2 ]
                                     [         ]
                                     [ 2  2  1 ]
          (%i3) mse : lsquares_mse (M, [z, x, y], (z + D)^2 = A*x + B*y + C);
                   5
                  ====
                  \                                         2     2
                   >    ((- B M    ) - A M     + (M     + D)  - C)
                  /            i, 3       i, 2     i, 1
                  ====
                  i = 1
          (%o3)   -------------------------------------------------
                                          5
          (%i4) diff (mse, D);
          (%o4)
                5
               ====
               \                                                     2
             4  >    (M     + D) ((- B M    ) - A M     + (M     + D)  - C)
               /       i, 1             i, 3       i, 2     i, 1
               ====
               i = 1
             --------------------------------------------------------------
                                           5
          (%i5) ''mse, nouns;
                         2                 2         9 2               2
          (%o5) (((D + 3)  - C - 2 B - 2 A)  + ((D + -)  - C - B - 2 A)
                                                     4
                     2               2         3 2               2
           + ((D + 2)  - C - B - 2 A)  + ((D + -)  - C - 2 B - A)
                                               2
                     2             2
           + ((D + 1)  - C - B - A) )/5
          (%i3) mse : lsquares_mse (M, [z, x, y], (z + D)^2 = A*x + B*y + C);
                     5
                    ====
                    \                 2                         2
                     >    ((D + M    )  - C - M     B - M     A)
                    /            i, 1          i, 3      i, 2
                    ====
                    i = 1
          (%o3)     ---------------------------------------------
                                          5
          (%i4) diff (mse, D);
                   5
                  ====
                  \                             2
                4  >    (D + M    ) ((D + M    )  - C - M     B - M     A)
                  /           i, 1         i, 1          i, 3      i, 2
                  ====
                  i = 1
          (%o4) ----------------------------------------------------------
                                            5
          (%i5) ''mse, nouns;
                         2                 2         9 2               2
          (%o5) (((D + 3)  - C - 2 B - 2 A)  + ((D + -)  - C - B - 2 A)
                                                     4
                     2               2         3 2               2
           + ((D + 2)  - C - B - 2 A)  + ((D + -)  - C - 2 B - A)
                                               2
                     2             2
           + ((D + 1)  - C - B - A) )/5

 -- Function: lsquares_residuals (<D>, <x>, <e>, <a>)

     Returns the residuals for the equation <e> with specified
     parameters <a> and data <D>.

     <D> is a matrix, <x> is a list of variables, <e> is an equation or
     general expression; if not an equation, <e> is treated as if it
     were ‘<e> = 0’.  <a> is a list of equations which specify values
     for any free parameters in <e> aside from <x>.

     The residuals are defined as:

                                  lhs(e ) - rhs(e )
                                       i         i

     where ‘<e>[i]’ is the equation <e> evaluated with the variables in
     <x> assigned values from the ‘i’-th datum, ‘<D>[i]’, and assigning
     any remaining free variables from <a>.

     ‘load("lsquares")’ loads this function.

     Example:

          (%i1) load ("lsquares")$
          (%i2) M : matrix (
                   [1,1,1], [3/2,1,2], [9/4,2,1], [3,2,2], [2,2,1]);
                                     [ 1  1  1 ]
                                     [         ]
                                     [ 3       ]
                                     [ -  1  2 ]
                                     [ 2       ]
                                     [         ]
          (%o2)                      [ 9       ]
                                     [ -  2  1 ]
                                     [ 4       ]
                                     [         ]
                                     [ 3  2  2 ]
                                     [         ]
                                     [ 2  2  1 ]
          (%i3) a : lsquares_estimates (
                    M, [z,x,y], (z+D)^2 = A*x+B*y+C, [A,B,C,D]);
                            59        27      10921        107
          (%o3)     [[A = - --, B = - --, C = -----, D = - ---]]
                            16        16      1024         32
          (%i4) lsquares_residuals (
                    M, [z,x,y], (z+D)^2 = A*x+B*y+C, first(a));
                               13    13    13  13  13
          (%o4)               [--, - --, - --, --, --]
                               64    64    32  64  64

 -- Function: lsquares_residual_mse (<D>, <x>, <e>, <a>)

     Returns the residual mean square error (MSE) for the equation <e>
     with specified parameters <a> and data <D>.

     The residual MSE is defined as:

                              n
                             ====
                         1   \                        2
                         -    >    (lhs(e ) - rhs(e ))
                         n   /           i         i
                             ====
                             i = 1

     where ‘<e>[i]’ is the equation <e> evaluated with the variables in
     <x> assigned values from the ‘i’-th datum, ‘<D>[i]’, and assigning
     any remaining free variables from <a>.

     ‘load("lsquares")’ loads this function.

     Example:

          (%i1) load ("lsquares")$
          (%i2) M : matrix (
                   [1,1,1], [3/2,1,2], [9/4,2,1], [3,2,2], [2,2,1]);
                                     [ 1  1  1 ]
                                     [         ]
                                     [ 3       ]
                                     [ -  1  2 ]
                                     [ 2       ]
                                     [         ]
          (%o2)                      [ 9       ]
                                     [ -  2  1 ]
                                     [ 4       ]
                                     [         ]
                                     [ 3  2  2 ]
                                     [         ]
                                     [ 2  2  1 ]
          (%i3) a : lsquares_estimates (
                 M, [z,x,y], (z+D)^2 = A*x+B*y+C, [A,B,C,D]);
                            59        27      10921        107
          (%o3)     [[A = - --, B = - --, C = -----, D = - ---]]
                            16        16      1024         32
          (%i4) lsquares_residual_mse (
                 M, [z,x,y], (z + D)^2 = A*x + B*y + C, first (a));
                                        169
          (%o4)                         ----
                                        2560

 -- Function: plsquares
          plsquares (<Mat>,<VarList>,<depvars>)
          plsquares (<Mat>,<VarList>,<depvars>,<maxexpon>)
          plsquares (<Mat>,<VarList>,<depvars>,<maxexpon>,<maxdegree>)
     Multivariable polynomial adjustment of a data table by the "least
     squares" method.  <Mat> is a matrix containing the data, <VarList>
     is a list of variable names (one for each Mat column, but use "-"
     instead of varnames to ignore Mat columns), <depvars> is the name
     of a dependent variable or a list with one or more names of
     dependent variables (which names should be in <VarList>),
     <maxexpon> is the optional maximum exponent for each independent
     variable (1 by default), and <maxdegree> is the optional maximum
     polynomial degree (<maxexpon> by default); note that the sum of
     exponents of each term must be equal or smaller than <maxdegree>,
     and if ‘maxdgree = 0’ then no limit is applied.

     If <depvars> is the name of a dependent variable (not in a list),
     ‘plsquares’ returns the adjusted polynomial.  If <depvars> is a
     list of one or more dependent variables, ‘plsquares’ returns a list
     with the adjusted polynomial(s).  The Coefficients of Determination
     are displayed in order to inform about the goodness of fit, which
     ranges from 0 (no correlation) to 1 (exact correlation).  These
     values are also stored in the global variable <DETCOEF> (a list if
     <depvars> is a list).

     A simple example of multivariable linear adjustment:
          (%i1) load("plsquares")$

          (%i2) plsquares(matrix([1,2,0],[3,5,4],[4,7,9],[5,8,10]),
                          [x,y,z],z);
               Determination Coefficient for z = .9897039897039897
                                 11 y - 9 x - 14
          (%o2)              z = ---------------
                                        3

     The same example without degree restrictions:
          (%i3) plsquares(matrix([1,2,0],[3,5,4],[4,7,9],[5,8,10]),
                          [x,y,z],z,1,0);
               Determination Coefficient for z = 1.0
                              x y + 23 y - 29 x - 19
          (%o3)           z = ----------------------
                                        6

     How many diagonals does a N-sides polygon have?  What polynomial
     degree should be used?
          (%i4) plsquares(matrix([3,0],[4,2],[5,5],[6,9],[7,14],[8,20]),
                          [N,diagonals],diagonals,5);
               Determination Coefficient for diagonals = 1.0
                                          2
                                         N  - 3 N
          (%o4)              diagonals = --------
                                            2
          (%i5) ev(%, N=9);   /* Testing for a 9 sides polygon */
          (%o5)                 diagonals = 27

     How many ways do we have to put two queens without they are
     threatened into a n x n chessboard?
          (%i6) plsquares(matrix([0,0],[1,0],[2,0],[3,8],[4,44]),
                          [n,positions],[positions],4);
               Determination Coefficient for [positions] = [1.0]
                                   4       3      2
                                3 n  - 10 n  + 9 n  - 2 n
          (%o6)    [positions = -------------------------]
                                            6
          (%i7) ev(%[1], n=8); /* Testing for a (8 x 8) chessboard */
          (%o7)                positions = 1288

     An example with six dependent variables:
          (%i8) mtrx:matrix([0,0,0,0,0,1,1,1],[0,1,0,1,1,1,0,0],
                            [1,0,0,1,1,1,0,0],[1,1,1,1,0,0,0,1])$
          (%i8) plsquares(mtrx,[a,b,_And,_Or,_Xor,_Nand,_Nor,_Nxor],
                               [_And,_Or,_Xor,_Nand,_Nor,_Nxor],1,0);
                Determination Coefficient for
          [_And, _Or, _Xor, _Nand, _Nor, _Nxor] =
          [1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
          (%o2) [_And = a b, _Or = - a b + b + a,
          _Xor = - 2 a b + b + a, _Nand = 1 - a b,
          _Nor = a b - b - a + 1, _Nxor = 2 a b - b - a + 1]

     To use this function write first ‘load("lsquares")’.


File: maxima.info,  Node: Package minpack,  Next: Package makeOrders,  Prev: Package lsquares,  Up: Top

78 Package minpack
******************

* Menu:

* Introduction to minpack::
* Functions and Variables for minpack::


File: maxima.info,  Node: Introduction to minpack,  Next: Functions and Variables for minpack,  Prev: Package minpack,  Up: Package minpack

78.1 Introduction to minpack
============================

‘Minpack’ is a Common Lisp translation (via ‘f2cl’) of the Fortran
library MINPACK as obtained from Netlib
(https://www.netlib.org/minpack/).


File: maxima.info,  Node: Functions and Variables for minpack,  Prev: Introduction to minpack,  Up: Package minpack

78.2 Functions and Variables for minpack
========================================

 -- Function: minpack_lsquares (<flist>, <varlist>, <guess>, ['tolerance
          = <tolerance>, 'jacobian = <jacobian>])

     Compute the point that minimizes the sum of the squares of the
     functions in the list <flist>.  The variables are in the list
     <varlist>.  An initial guess of the optimum point must be provided
     in <guess>.

     Let <flist> be a list of m functions, f_i(x_1, x_2, ..., x_n). Then
     this function can be used to find the values of x_1, x_2, ..., x_n
     that solve the least squares problem

                         m
                        ____
                        ╲      2
                         ⟩    f (x_1, x_2,..., x_n)
                        ╱      i
                        ‾‾‾‾
                        i = 1

     The optional keyword arguments, <tolerance> and <jacobian> provide
     some control over the algorithm.

     ‘tolerance’
          the estimated relative error desired in the sum of squares.
          The default value is approximately 1.0537e-8.
     ‘jacobian’
          specifies the Jacobian.  If <jacobian> is not given or is
          ‘true’ (the default), the Jacobian is computed from <flist>.
          If <jacobian> is ‘false’, a numerical approximation is used.
          *Note Jacobian: jacobian.

     ‘minpack_lsquares’ returns a list of three items as follows:
       1. The estimated solution
       2. The sum of squares
       3. The success of the algorithm.  The possible values are
            0. improper input parameters.
            1. algorithm estimates that the relative error in the sum of
               squares is at most ‘tolerance’.
            2. algorithm estimates that the relative error between x and
               the solution is at most ‘tolerance’.
            3. conditions for info = 1 and info = 2 both hold.
            4. fvec is orthogonal to the columns of the jacobian to
               machine precision.
            5. number of calls to fcn with iflag = 1 has reached
               100*(n+1).
            6. tol is too small.  no further reduction in the sum of
               squares is possible.
            7. tol is too small.  no further improvement in the
               approximate solution x is possible.

     Here is an example using Powell's singular function.
          (%i1) load("minpack")$
          (%i2) powell(x1,x2,x3,x4) := [x1+10*x2, sqrt(5)*(x3-x4), (x2-2*x3)^2, sqrt(10)*(x1-x4)^2]$
          (%i3) minpack_lsquares(powell(x1,x2,x3,x4), [x1,x2,x3,x4], [3,-1,0,1]);
          (%o3) [[1.6521175961683935e-17, - 1.6521175961683934e-18,
          2.6433881538694683e-18, 2.6433881538694683e-18],
          6.109327859207777e-34, 4]

     Same problem but use numerical approximation to Jacobian.
          (%i1) load("minpack")$
          (%i2) powell(x1,x2,x3,x4) := [x1+10*x2, sqrt(5)*(x3-x4), (x2-2*x3)^2, sqrt(10)*(x1-x4)^2]$
          (%i3) minpack_lsquares(powell(x1,x2,x3,x4), [x1,x2,x3,x4], [3,-1,0,1], jacobian = false);
          (%o3) [[5.060282149485331e-11, - 5.060282149491206e-12,
          2.1794478435472183e-11, 2.1794478435472183e-11],
          3.534491794847031e-21, 5]

 -- Function: minpack_solve (<flist>, <varlist>, <guess>, ['tolerance =
          <tolerance>, 'jacobian = <jacobian>])

     Solve a system of ‘n’ equations in ‘n’ unknowns.  The ‘n’ equations
     are given in the list <flist>, and the unknowns are in <varlist>.
     An initial guess of the solution must be provided in <guess>.

     Let <flist> be a list of m functions, f_i(x_1, x_2, ..., x_n). Then
     this functions solves the system of m nonlinear equations in n
     variables:

          f_i(x_1, x_2, ..., x_n) = 0

     The optional keyword arguments, <tolerance> and <jacobian> provide
     some control over the algorithm.

     ‘tolerance’
          the estimated relative error desired in the sum of squares.
          The default value is approximately 1.0537e-8.
     ‘jacobian’
          specifies the Jacobian.  If <jacobian> is not given or is
          ‘true’ (the default), the Jacobian is computed from <flist>.
          If <jacobian> is ‘false’, a numerical approximation is used.
          *Note Jacobian: jacobian.

     ‘minpack_solve’ returns a list of three items as follows:
       1. The estimated solution
       2. The sum of squares
       3. The success of the algorithm.  The possible values are
            0. improper input parameters.
            1. algorithm estimates that the relative error in the
               solution is at most ‘tolerance’.
            2. number of calls to fcn with iflag = 1 has reached
               100*(n+1).
            3. tol is too small.  no further reduction in the sum of
               squares is possible.
            4. Iteration is not making good progress.

          (%i1) load("minpack")$
          (%i2) powell(x1,x2,x3,x4) := [x1+10*x2, sqrt(5)*(x3-x4), (x2-2*x3)^2, sqrt(10)*(x1-x4)^2]$
          (%i3) minpack_lsquares(powell(x1,x2,x3,x4), [x1,x2,x3,x4], [3,-1,0,1]);
          (%o3) [[1.6521175961683935e-17, - 1.6521175961683934e-18,
          2.6433881538694683e-18, 2.6433881538694683e-18],
          6.109327859207777e-34, 4]
     In this particular case, we can solve this analytically:
          (%i1) powell(x1,x2,x3,x4) := [x1+10*x2, sqrt(5)*(x3-x4), (x2-2*x3)^2, sqrt(10)*(x1-x4)^2]$
          (%i2) solve(powell(x1,x2,x3,x4),[x1,x2,x3,x4]);
          (%o2)          [[x1 = 0, x2 = 0, x3 = 0, x4 = 0]]
     and we see that the numerical solution is quite close the
     analytical one.


File: maxima.info,  Node: Package makeOrders,  Next: Package mnewton,  Prev: Package minpack,  Up: Top

79 Package makeOrders
*********************

* Menu:

* Functions and Variables for makeOrders::


File: maxima.info,  Node: Functions and Variables for makeOrders,  Prev: Package makeOrders,  Up: Package makeOrders

79.1 Functions and Variables for makeOrders
===========================================

 -- Function: makeOrders (<indvarlist>,<orderlist>)
     Returns a list of all powers for a polynomial up to and including
     the arguments.

          (%i1) load("makeOrders")$

          (%i2) makeOrders([a,b],[2,3]);
          (%o2) [[0, 0], [0, 1], [0, 2], [0, 3], [1, 0], [1, 1],
                      [1, 2], [1, 3], [2, 0], [2, 1], [2, 2], [2, 3]]
          (%i3) expand((1+a+a^2)*(1+b+b^2+b^3));
                 2  3      3    3    2  2      2    2    2
          (%o3) a  b  + a b  + b  + a  b  + a b  + b  + a  b + a b
                                                            2
                                                     + b + a  + a + 1
     where ‘[0, 1]’ is associated with the term b and ‘[2, 3]’ with a^2
     b^3.

     To use this function write first ‘load("makeOrders")’.


File: maxima.info,  Node: Package mnewton,  Next: Package numericalio,  Prev: Package makeOrders,  Up: Top

80 Package mnewton
******************

* Menu:

* Introduction to mnewton::
* Functions and Variables for mnewton::


File: maxima.info,  Node: Introduction to mnewton,  Next: Functions and Variables for mnewton,  Prev: Package mnewton,  Up: Package mnewton

80.1 Introduction to mnewton
============================

‘mnewton’ is an implementation of Newton's method for solving nonlinear
equations in one or more variables.


File: maxima.info,  Node: Functions and Variables for mnewton,  Prev: Introduction to mnewton,  Up: Package mnewton

80.2 Functions and Variables for mnewton
========================================

 -- Option variable: newtonepsilon
     Default value: ‘10.0^(-fpprec/2)’

     Precision to determine when the ‘mnewton’ function has converged
     towards the solution.

     When ‘newtonepsilon’ is a bigfloat, ‘mnewton’ computations are done
     with bigfloats; otherwise, ordinary floats are used.

     See also *note mnewton::.

 -- Option variable: newtonmaxiter
     Default value: ‘50’

     Maximum number of iterations to stop the ‘mnewton’ function if it
     does not converge or if it converges too slowly.

     See also *note mnewton::.

 -- Option variable: newtondebug
     Default value: ‘false’

     When ‘newtondebug’ is ‘true’, ‘mnewton’ prints out debugging
     information while solving a problem.

 -- Function: mnewton
          mnewton (<FuncList>, <VarList>, <GuessList>)
          mnewton (<FuncList>, <VarList>, <GuessList>, <DF>)

     Approximate solution of multiple nonlinear equations by Newton's
     method.

     <FuncList> is a list of functions to solve, <VarList> is a list of
     variable names, and <GuessList> is a list of initial
     approximations.  The optional argument <DF> is the Jacobian matrix
     of the list of functions; if not supplied, it is calculated
     automatically from <FuncList>.

     <FuncList> may be specified as a list of equations, in which case
     the function to be solved is the left-hand side of each equation
     minus the right-hand side.

     If there is only a single function, variable, and initial point,
     they may be specified as a single expression, variable, and initial
     value; they need not be lists of one element.

     A variable may be a simple symbol or a subscripted symbol.

     The solution, if any, is returned as a list of one element, which
     is a list of equations, one for each variable, specifying an
     approximate solution; this is the same format as returned by
     ‘solve’.  If the solution is not found, ‘[]’ is returned.

     Functions and initial points may contain complex numbers, and
     solutions likewise may contain complex numbers.

     ‘mnewton’ is governed by global variables ‘newtonepsilon’ and
     ‘newtonmaxiter’, and the global flag *note newtondebug::.

     ‘load("mnewton")’ loads this function.

     See also ‘realroots’, ‘allroots’, ‘find_root’ and *note newton::.

     Examples:

          (%i1) load("mnewton")$

          (%i2) mnewton([x1+3*log(x1)-x2^2, 2*x1^2-x1*x2-5*x1+1],
                        [x1, x2], [5, 5]);
          (%o2) [[x1 = 3.756834008012769, x2 = 2.779849592817897]]
          (%i3) mnewton([2*a^a-5],[a],[1]);
          (%o3)             [[a = 1.70927556786144]]
          (%i4) mnewton([2*3^u-v/u-5, u+2^v-4], [u, v], [2, 2]);
          (%o4) [[u = 1.066618389595407, v = 1.552564766841786]]

     The variable ‘newtonepsilon’ controls the precision of the
     approximations.  It also controls if computations are performed
     with floats or bigfloats.

          (%i1) load("mnewton")$

          (%i2) (fpprec : 25, newtonepsilon : bfloat(10^(-fpprec+5)))$

          (%i3) mnewton([2*3^u-v/u-5, u+2^v-4], [u, v], [2, 2]);
          (%o3) [[u = 1.066618389595406772591173b0,
                                         v = 1.552564766841786450100418b0]]


File: maxima.info,  Node: Package numericalio,  Next: Package odepack,  Prev: Package mnewton,  Up: Top

81 Package numericalio
**********************

* Menu:

* Introduction to numericalio::
* Functions and Variables for plain-text input and output::
* Functions and Variables for binary input and output::


File: maxima.info,  Node: Introduction to numericalio,  Next: Functions and Variables for plain-text input and output,  Prev: Package numericalio,  Up: Package numericalio

81.1 Introduction to numericalio
================================

‘numericalio’ is a collection of functions to read and write files and
streams.  Functions for plain-text input and output can read and write
numbers (integer, float, or bigfloat), symbols, and strings.  Functions
for binary input and output can read and write only floating-point
numbers.

   If there already exists a list, matrix, or array object to store
input data, ‘numericalio’ input functions can write data into that
object.  Otherwise, ‘numericalio’ can guess, to some degree, the
structure of an object to store the data, and return that object.

81.1.1 Plain-text input and output
----------------------------------

In plain-text input and output, it is assumed that each item to read or
write is an atom: an integer, float, bigfloat, string, or symbol, and
not a rational or complex number or any other kind of nonatomic
expression.  The ‘numericalio’ functions may attempt to do something
sensible faced with nonatomic expressions, but the results are not
specified here and subject to change.

   Atoms in both input and output files have the same format as in
Maxima batch files or the interactive console.  In particular, strings
are enclosed in double quotes, backslash ‘\’ prevents any special
interpretation of the next character, and the question mark ‘?’ is
recognized at the beginning of a symbol to mean a Lisp symbol (as
opposed to a Maxima symbol).  No continuation character (to join broken
lines) is recognized.

81.1.2 Separator flag values for input
--------------------------------------

The functions for plain-text input and output take an optional argument,
<separator_flag>, that tells what character separates data.

   For plain-text input, these values of <separator_flag> are
recognized: ‘comma’ for comma separated values, ‘pipe’ for values
separated by the vertical bar character ‘|’, ‘semicolon’ for values
separated by semicolon ‘;’, and ‘space’ for values separated by space or
tab characters.  Equivalently, the separator may be specified as a
string of one character: ‘","’ (comma), ‘"|"’ (pipe), ‘";"’ (semicolon),
‘" "’ (space), or ‘" "’ (tab).

   If the file name ends in ‘.csv’ and <separator_flag> is not
specified, ‘comma’ is assumed.  If the file name ends in something other
than ‘.csv’ and ‘separator_flag’ is not specified, ‘space’ is assumed.

   In plain-text input, multiple successive space and tab characters
count as a single separator.  However, multiple comma, pipe, or
semicolon characters are significant.  Successive comma, pipe, or
semicolon characters (with or without intervening spaces or tabs) are
considered to have ‘false’ between the separators.  For example,
‘1234,,Foo’ is treated the same as ‘1234,false,Foo’.

81.1.3 Separator flag values for output
---------------------------------------

For plain-text output, ‘tab’, for values separated by the tab character,
is recognized as a value of <separator_flag>, as well as ‘comma’,
‘pipe’, ‘semicolon’, and ‘space’.

   In plain-text output, ‘false’ atoms are written as such; a list
‘[1234, false, Foo]’ is written ‘1234,false,Foo’, and there is no
attempt to collapse the output to ‘1234,,Foo’.

81.1.4 Binary floating-point input and output
---------------------------------------------

‘numericalio’ functions can read and write 8-byte IEEE 754
floating-point numbers.  These numbers can be stored either least
significant byte first or most significant byte first, according to the
global flag set by ‘assume_external_byte_order’.  If not specified,
‘numericalio’ assumes the external byte order is most-significant byte
first.

   Other kinds of numbers are coerced to 8-byte floats; ‘numericalio’
cannot read or write binary non-numeric data.

   Some Lisp implementations do not recognize IEEE 754 special values
(positive and negative infinity, not-a-number values, denormalized
values).  The effect of reading such values with ‘numericalio’ is
undefined.

   ‘numericalio’ includes functions to open a stream for reading or
writing a stream of bytes.


File: maxima.info,  Node: Functions and Variables for plain-text input and output,  Next: Functions and Variables for binary input and output,  Prev: Introduction to numericalio,  Up: Package numericalio

81.2 Functions and Variables for plain-text input and output
============================================================

 -- Function: read_matrix
          read_matrix (<S>)
          read_matrix (<S>, <M>)
          read_matrix (<S>, <separator_flag>)
          read_matrix (<S>, <M>, <separator_flag>)

     ‘read_matrix(<S>)’ reads the source <S> and returns its entire
     content as a matrix.  The size of the matrix is inferred from the
     input data; each line of the file becomes one row of the matrix.
     If some lines have different lengths, ‘read_matrix’ complains.

     ‘read_matrix(<S>, <M>)’ read the source <S> into the matrix <M>,
     until <M> is full or the source is exhausted.  Input data are read
     into the matrix in row-major order; the input need not have the
     same number of rows and columns as <M>.

     The source <S> may be a file name or a stream which for example
     allows skipping the very first line of a file (that may be useful,
     if you read CSV data, where the first line often contains the
     description of the columns):
          s : openr("data.txt");
          readline(s);  /* skip the first line */
          M : read_matrix(s, 'comma);  /* read the following (comma-separated) lines into matrix M */
          close(s);

     The recognized values of <separator_flag> are ‘comma’, ‘pipe’,
     ‘semicolon’, and ‘space’.  Equivalently, the separator may be
     specified as a string of one character: ‘","’ (comma), ‘"|"’
     (pipe), ‘";"’ (semicolon), ‘" "’ (space), or ‘" "’ (tab).  If
     <separator_flag> is not specified, the file is assumed
     space-delimited.

     See also ‘openr’, ‘read_array’, ‘read_hashed_array’, ‘read_list’,
     ‘read_binary_matrix’, ‘write_data’ and *note read_nested_list::.

 -- Function: read_array
          read_array (<S>, <A>)
          read_array (<S>, <A>, <separator_flag>)

     Reads the source <S> into the array <A>, until <A> is full or the
     source is exhausted.  Input data are read into the array in
     row-major order; the input need not conform to the dimensions of
     <A>.

     The source <S> may be a file name or a stream.

     The recognized values of <separator_flag> are ‘comma’, ‘pipe’,
     ‘semicolon’, and ‘space’.  Equivalently, the separator may be
     specified as a string of one character: ‘","’ (comma), ‘"|"’
     (pipe), ‘";"’ (semicolon), ‘" "’ (space), or ‘" "’ (tab).  If
     <separator_flag> is not specified, the file is assumed
     space-delimited.

     See also ‘openr’, ‘read_matrix’, ‘read_hashed_array’, ‘read_list’,
     ‘read_binary_array’ and *note read_nested_list::.

 -- Function: read_hashed_array
          read_hashed_array (<S>, <A>)
          read_hashed_array (<S>, <A>, <separator_flag>)

     Reads the source <S> and returns its entire content as a *note
     hashed array::.  The source <S> may be a file name or a stream.

     ‘read_hashed_array’ treats the first item on each line as a hash
     key, and associates the remainder of the line (as a list) with the
     key.  For example, the line ‘567 12 17 32 55’ is equivalent to
     ‘A[567]: [12, 17, 32, 55]$’.  Lines need not have the same numbers
     of elements.

     The recognized values of <separator_flag> are ‘comma’, ‘pipe’,
     ‘semicolon’, and ‘space’.  Equivalently, the separator may be
     specified as a string of one character: ‘","’ (comma), ‘"|"’
     (pipe), ‘";"’ (semicolon), ‘" "’ (space), or ‘" "’ (tab).  If
     <separator_flag> is not specified, the file is assumed
     space-delimited.

     See also ‘openr’, ‘read_matrix’, ‘read_array’, ‘read_list’ and
     *note read_nested_list::.

 -- Function: read_nested_list
          read_nested_list (<S>)
          read_nested_list (<S>, <separator_flag>)

     Reads the source <S> and returns its entire content as a nested
     list.  The source <S> may be a file name or a stream.

     ‘read_nested_list’ returns a list which has a sublist for each line
     of input.  Lines need not have the same numbers of elements.  Empty
     lines are not ignored: an empty line yields an empty sublist.

     The recognized values of <separator_flag> are ‘comma’, ‘pipe’,
     ‘semicolon’, and ‘space’.  Equivalently, the separator may be
     specified as a string of one character: ‘","’ (comma), ‘"|"’
     (pipe), ‘";"’ (semicolon), ‘" "’ (space), or ‘" "’ (tab).  If
     <separator_flag> is not specified, the file is assumed
     space-delimited.

     See also ‘openr’, ‘read_matrix’, ‘read_array’, ‘read_list’ and
     *note read_hashed_array::.

 -- Function: read_list
          read_list (<S>)
          read_list (<S>, <L>)
          read_list (<S>, <separator_flag>)
          read_list (<S>, <L>, <separator_flag>)

     ‘read_list(<S>)’ reads the source <S> and returns its entire
     content as a flat list.

     ‘read_list(<S>, <L>)’ reads the source <S> into the list <L>, until
     <L> is full or the source is exhausted.

     The source <S> may be a file name or a stream.

     The recognized values of <separator_flag> are ‘comma’, ‘pipe’,
     ‘semicolon’, and ‘space’.  Equivalently, the separator may be
     specified as a string of one character: ‘","’ (comma), ‘"|"’
     (pipe), ‘";"’ (semicolon), ‘" "’ (space), or ‘" "’ (tab).  If
     <separator_flag> is not specified, the file is assumed
     space-delimited.

     See also ‘openr’, ‘read_matrix’, ‘read_array’, ‘read_nested_list’,
     ‘read_binary_list’ and *note read_hashed_array::.

 -- Function: write_data
          write_data (<X>, <D>)
          write_data (<X>, <D>, <separator_flag>)

     Writes the object <X> to the destination <D>.

     ‘write_data’ writes a matrix in row-major order, with one line per
     row.

     ‘write_data’ writes an array created by ‘array’ or ‘make_array’ in
     row-major order, with a new line at the end of every slab.
     Higher-dimensional slabs are separated by additional new lines.

     ‘write_data’ writes a hashed array with each key followed by its
     associated list on one line.

     ‘write_data’ writes a nested list with each sublist on one line.

     ‘write_data’ writes a flat list all on one line.

     The destination <D> may be a file name or a stream.  When the
     destination is a file name, the global variable
     ‘file_output_append’ governs whether the output file is appended or
     truncated.  When the destination is a stream, no special action is
     taken by ‘write_data’ after all the data are written; in
     particular, the stream remains open.

     The recognized values of <separator_flag> are ‘comma’, ‘pipe’,
     ‘semicolon’, ‘space’, and ‘tab’.  Equivalently, the separator may
     be specified as a string of one character: ‘","’ (comma), ‘"|"’
     (pipe), ‘";"’ (semicolon), ‘" "’ (space), or ‘" "’ (tab).  If
     <separator_flag> is not specified, the file is assumed
     space-delimited.

     See also ‘openw’ and *note read_matrix::.


File: maxima.info,  Node: Functions and Variables for binary input and output,  Prev: Functions and Variables for plain-text input and output,  Up: Package numericalio

81.3 Functions and Variables for binary input and output
========================================================

 -- Function: assume_external_byte_order (<byte_order_flag>)
     Tells ‘numericalio’ the byte order for reading and writing binary
     data.  Two values of <byte_order_flag> are recognized: ‘lsb’ which
     indicates least-significant byte first, also called little-endian
     byte order; and ‘msb’ which indicates most-significant byte first,
     also called big-endian byte order.

     If not specified, ‘numericalio’ assumes the external byte order is
     most-significant byte first.

 -- Function: openr_binary (<file_name>)
     Returns an input stream of 8-bit unsigned bytes to read the file
     named by <file_name>.

     See also ‘openw_binary’ and *note openr::.

 -- Function: openw_binary (<file_name>)
     Returns an output stream of 8-bit unsigned bytes to write the file
     named by <file_name>.

     See also ‘openr_binary’, ‘opena_binary’ and *note openw::.

 -- Function: opena_binary (<file_name>)
     Returns an output stream of 8-bit unsigned bytes to append the file
     named by <file_name>.

 -- Function: read_binary_matrix (<S>, <M>)
     Reads binary 8-byte floating point numbers from the source <S> into
     the matrix <M> until <M> is full, or the source is exhausted.
     Elements of <M> are read in row-major order.

     The source <S> may be a file name or a stream.

     The byte order in elements of the source is specified by
     ‘assume_external_byte_order’.

     See also *note read_matrix::.

 -- Function: read_binary_array (<S>, <A>)
     Reads binary 8-byte floating point numbers from the source <S> into
     the array <A> until <A> is full, or the source is exhausted.  <A>
     must be an array created by ‘array’ or ‘make_array’.  Elements of
     <A> are read in row-major order.

     The source <S> may be a file name or a stream.

     The byte order in elements of the source is specified by
     ‘assume_external_byte_order’.

     See also *note read_array::.

 -- Function: read_binary_list
          read_binary_list (<S>)
          read_binary_list (<S>, <L>)

     ‘read_binary_list(<S>)’ reads the entire content of the source <S>
     as a sequence of binary 8-byte floating point numbers, and returns
     it as a list.  The source <S> may be a file name or a stream.

     ‘read_binary_list(<S>, <L>)’ reads 8-byte binary floating point
     numbers from the source <S> until the list <L> is full, or the
     source is exhausted.

     The byte order in elements of the source is specified by
     ‘assume_external_byte_order’.

     See also *note read_list::.

 -- Function: write_binary_data (<X>, <D>)

     Writes the object <X>, comprising binary 8-byte IEEE 754
     floating-point numbers, to the destination <D>.  Other kinds of
     numbers are coerced to 8-byte floats.  ‘write_binary_data’ cannot
     write non-numeric data.

     The object <X> may be a list, a nested list, a matrix, or an array
     created by ‘array’ or ‘make_array’; <X> cannot be a hashed array or
     any other type of object.  ‘write_binary_data’ writes nested lists,
     matrices, and arrays in row-major order.

     The destination <D> may be a file name or a stream.  When the
     destination is a file name, the global variable
     ‘file_output_append’ governs whether the output file is appended or
     truncated.  When the destination is a stream, no special action is
     taken by ‘write_binary_data’ after all the data are written; in
     particular, the stream remains open.

     The byte order in elements of the destination is specified by
     ‘assume_external_byte_order’.

     See also *note write_data::.


File: maxima.info,  Node: Package odepack,  Next: Package operatingsystem,  Prev: Package numericalio,  Up: Top

82 Package odepack
******************

* Menu:

* Introduction to ODEPACK::
* Getting Started with ODEPACK::
* Functions and Variables for odepack::


File: maxima.info,  Node: Introduction to ODEPACK,  Next: Getting Started with ODEPACK,  Prev: Package numericalio,  Up: Package odepack

82.1 Introduction to ODEPACK
============================

     ODEPACK is a collection of Fortran solvers for the initial value
     problem for ordinary differential equation systems.  It consists of
     nine solvers, namely a basic solver called LSODE and eight variants
     of it - LSODES, LSODA, LSODAR, LSODPK, LSODKR, LSODI, LSOIBT, and
     LSODIS. The collection is suitable for both stiff and nonstiff
     systems.  It includes solvers for systems given in explicit form,
     dy/dt = f(t,y), and also solvers for systems given in linearly
     implicit form, A(t,y) dy/dt = g(t,y).  Two of the solvers use
     general sparse matrix solvers for the linear systems that arise.
     Two others use iterative (preconditioned Krylov) methods instead of
     direct methods for these linear systems.  The most recent addition
     is LSODIS, which solves implicit problems with general sparse
     treatment of all matrices involved.
   (1)

   References: [1] Fortran Code is from
<https://www.netlib.org/odepack/>

   ---------- Footnotes ----------

   (1) From <https://www.netlib.org/odepack/opkd-sum>


File: maxima.info,  Node: Getting Started with ODEPACK,  Next: Functions and Variables for odepack,  Prev: Introduction to ODEPACK,  Up: Package odepack

82.1.1 Getting Started with ODEPACK
-----------------------------------

Of the eight variants of the solver, Maxima currently only has an
interface to ‘dlsode’.

   Let's say we have this system of equations to solve:

       f1 = -.04d0*y1 + 1d4*y2*y3
       f3 = 3d7*y2*y2
       dy1/dt = f1
       dy2/dt = -f1 - f3
       dy3/dt = f3

   The independent variable is t; the dependent variables are , , and .

   To start the solution, set up the differential equations to solved:
     (%i1) load("dlsode")$
     (%i2) f1: -.04d0*y1 + 1d4*y2*y3$
     (%i3) f3: 3d7*y2*y2$
     (%i4) f2: -f1 - f3$
     (%i5) fex: [f1, f2, f3];
     (%o5) [10000.0 y2 y3 - 0.04 y1,
                                               2                    2
                     - 10000.0 y2 y3 - 3.0e7 y2  + 0.04 y1, 3.0e7 y2 ]

   Initialize the solver, where we have selected method 21:
     (%i1) load("dlsode")$
     (%i2) f1: -.04d0*y1 + 1d4*y2*y3$
     (%i3) f3: 3d7*y2*y2$
     (%i4) f2: -f1 - f3$
     (%i5) fex: [f1, f2, f3];
     (%o5) [10000.0 y2 y3 - 0.04 y1,
                                               2                    2
                     - 10000.0 y2 y3 - 3.0e7 y2  + 0.04 y1, 3.0e7 y2 ]
     (%i6) state : dlsode_init(fex, ['t,y1,y2,y3], 21);
     (%o6) [[f, #<Function "LAMBDA ($T $Y1 $Y2 $Y3)" {6177C099}>],
     [vars, [t, y1, y2, y3]], [mf, 21], [neq, 3], [lrw, 58],
     [liw, 23], [rwork, {Lisp Array: #(0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.\
     0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
                    0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0\
     .0 0.0 0.0 0.0
                    0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0\
     .0 0.0 0.0 0.0
                    0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0)}],
     [iwork,
     {Lisp Array: #(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)}],
     [fjac, #<Function "LAMBDA ($T $Y1 $Y2 $Y3)" {616B2099}>]]
   The arrays rwork and iwork carry state between calls to
‘dlsode_step’, so they should not be modified by the user.  In fact,
this <state> returned from ‘dlsode_init’ should not be modified by the
user at all.

   Now that the algorithm has been initialized we can compute solutions
to the differential equation, using the <state> returned above.

   For this example, we want to compute the solution at times ‘0.4*10^k’
for k from 0 to 11, with the initial values of 1, 0, 0 for the dependent
variables and with a relative tolerance of 1e-4 and absolute tolerances
of 1e-6, 1e-10, and 1e-6 for the dependent variables.

   Then, putting everything together
     (%i1) load("dlsode")$
     (%i2) f1: -.04d0*y1 + 1d4*y2*y3$
     (%i3) f3: 3d7*y2*y2$
     (%i4) f2: -f1 - f3$
     (%i5) fex: [f1, f2, f3];
     (%o5) [10000.0 y2 y3 - 0.04 y1,
                                               2                    2
                     - 10000.0 y2 y3 - 3.0e7 y2  + 0.04 y1, 3.0e7 y2 ]
     (%i6) state : dlsode_init(fex, ['t,y1,y2,y3], 21)$
     (%i7) y: [1d0, 0d0, 0d0]$
     (%i8) t: 0d0$
     (%i9) rtol : 1d-4$
     (%i10) atol: [1d-6, 1d-10, 1d-6]$
     (%i11) istate: 1$
     (%i12) t:0d0$
     (%i13) tout:.4d0$

     (%i14) for k : 1 thru 12 do
       block([],
         result: dlsode_step(y, t, tout, rtol, atol, istate, state),
         printf(true, "At t = ~12,4,2e   y = ~{~14,6,2e~}~%", result[1], result[2]),
         istate : result[3],
         tout : tout * 10);
     At t =   4.0000e-01   y =   9.851726e-01  3.386406e-05  1.479357e-02
     At t =   4.0000e+00   y =   9.055142e-01  2.240418e-05  9.446344e-02
     At t =   4.0000e+01   y =   7.158050e-01  9.184616e-06  2.841858e-01
     At t =   4.0000e+02   y =   4.504846e-01  3.222434e-06  5.495122e-01
     At t =   4.0000e+03   y =   1.831701e-01  8.940379e-07  8.168290e-01
     At t =   4.0000e+04   y =   3.897016e-02  1.621193e-07  9.610297e-01
     At t =   4.0000e+05   y =   4.935213e-03  1.983756e-08  9.950648e-01
     At t =   4.0000e+06   y =   5.159269e-04  2.064759e-09  9.994841e-01
     At t =   4.0000e+07   y =   5.306413e-05  2.122677e-10  9.999469e-01
     At t =   4.0000e+08   y =   5.494530e-06  2.197824e-11  9.999945e-01
     At t =   4.0000e+09   y =   5.129458e-07  2.051784e-12  9.999995e-01
     At t =   4.0000e+10   y =  -7.170563e-08 -2.868225e-13  1.000000e+00
     (%o14)                        done
     (%i15) result;
     (%o15) [4.0e10, [- 7.170562924983933e-8,
     - 2.868224674710487e-13, 1.000000071705913], 2,
     [[n_steps, 330], [n_f_eval, 405], [n_j_eval, 69],
     [method_order, 1], [len_rwork, 58], [len_iwork, 23]]]


File: maxima.info,  Node: Functions and Variables for odepack,  Prev: Getting Started with ODEPACK,  Up: Package odepack

82.2 Functions and Variables for odepack
========================================

 -- Function: dlsode_init (<fex>, <vars>, <method>)

     This must be called before running the solver.  This function
     returns a state object for use in the solver.  The user must not
     modify the state.

     The ODE to be solved is given in <fex>, which is a list of the
     equations.  <vars> is a list of independent variable and the
     dependent variables.  The list of dependent variables must be in
     the same order as the equations if <fex>.  Finally, <method>
     indicates the method to be used by the solver:

          ‘10’
               Nonstiff (Adams) method, no Jacobian used.
          ‘21’
               Stiff (BDF) method, user-supplied full Jacobian.
          ‘22’
               Stiff method, internally generated full Jacobian.

     The returned state object is a list of lists.  The sublist is a
     list of two elements:
          ‘f’
               The compiled function for the ODE.
          ‘vars’
               The list independent and dependent variables (<vars>).
          ‘mf’
               The method to be used (<method>).
          ‘neq’
               The number of equations.
          ‘lrw’
               Length of the work vector for real values.
          ‘liw’
               Length of the work vector for integer values.
          ‘rwork’
               Lisp array holding the real-valued work vector.
          ‘iwork’
               Lisp array holding the integer-valued work vector.
          ‘fjac’
               Compiled analytical Jacobian of the equations

     See also *note dlsode_step::.  *Note Getting Started with ODEPACK::
     for an example of usage.

 -- Function: dlsode_step (<inity>, <t>, <tout>, <rtol>, <atol>,
          <istate>, <state>)

     Performs one step of the solver, returning the values of the
     independent and dependent variables, a success or error code.

     The parameters for ‘dlsode_step’ are:
          ‘inity’
               For the first call (when istate = 1), the initial values
          ‘t’
               Current value of the independent value
          ‘tout’
               Next point where output is desired which must not be
               equal to <t>.
          ‘rtol’
               relative tolerance parameter
          ‘atol’
               Absolute tolerance parameter, scalar of vector.  If
               scalar, it applies to all dependent variables.  Otherwise
               it must be the tolerance for each dependent variable.

               Use <rtol> = 0 for pure absolute error and use <atol> = 0
               for pure relative error.

          ‘istate’
               1 for the first call to dlsode, 2 for subsequent calls.
          ‘state’
               state returned by dlsode_init.

     The output is a list of the following items:
          ‘t’
               independent variable value
          ‘y’
               list of values of the dependent variables at time t.
          ‘istate’
               Integration status:
                    ‘1’
                         no work because tout = tt
                    ‘2’
                         successful result
                    ‘-1’
                         Excess work done on this call
                    ‘-2’
                         Excess accuracy requested
                    ‘-3’
                         Illegal input detected
                    ‘-4’
                         Repeated error test failures
                    ‘-5’
                         Repeated convergence failures (perhaps bad
                         Jacobian or wrong choice of mf or tolerances)
                    ‘-6’
                         Error weight because zero during problem
                         (solution component is vanished and atol(i) =
                         0.
          ‘info’
               association list of various bits of information:
                    ‘n_steps’
                         total steps taken thus far
                    ‘n_f_eval’
                         total number of function evals
                    ‘n_j_eval’
                         total number of Jacobian evals
                    ‘method_order’
                         method order
                    ‘len_rwork’
                         Actual length used for real work array
                    ‘len_iwork’
                         Actual length used for integer work array

     See also *note dlsode_init::.  *Note Getting Started with ODEPACK::
     for an example of usage.


File: maxima.info,  Node: Package operatingsystem,  Next: Package opsubst,  Prev: Package odepack,  Up: Top

83 Package operatingsystem
**************************

* Menu:

* Introduction to operatingsystem::
* Directory operations::
* File operations::
* Environment operations::


File: maxima.info,  Node: Introduction to operatingsystem,  Next: Directory operations,  Prev: Package operatingsystem,  Up: Package operatingsystem

83.1 Introduction to operatingsystem
====================================

Package ‘operatingsystem’ contains functions for operatingsystem-tasks,
like file system operations.


File: maxima.info,  Node: Directory operations,  Next: File operations,  Prev: Introduction to operatingsystem,  Up: Package operatingsystem

83.2 Directory operations
=========================

 -- Function: chdir (<dir>)
     Change to directory <dir>

 -- Function: mkdir (<dir>)
     Create directory <dir>

 -- Function: rmdir (<dir>)
     remove directory <dir>

 -- Function: getcurrentdirectory ()
     returns the current working directory.

     See also *note directory::.

   Examples:

     (%i1) load("operatingsystem")$
     (%i2) mkdir("testdirectory")$
     (%i3) chdir("testdirectory")$
     (%i4) chdir("..")$
     (%i5) rmdir("testdirectory")$


File: maxima.info,  Node: File operations,  Next: Environment operations,  Prev: Directory operations,  Up: Package operatingsystem

83.3 File operations
====================

 -- Function: copy_file (<file1>, <file2>)
     copies file <file1> to <file2>

 -- Function: rename_file (<file1>, <file2>)
     renames file <file1> to <file2>

 -- Function: delete_file (<file1>)
     deletes file <file1>


File: maxima.info,  Node: Environment operations,  Prev: File operations,  Up: Package operatingsystem

83.4 Environment operations
===========================

 -- Function: getenv (<env>)
     Get the value of the environment variable <env>

     Example:

          (%i1) load("operatingsystem")$
          (%i2) getenv("PATH");
          (%o2) /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin


File: maxima.info,  Node: Package opsubst,  Next: Package orthopoly,  Prev: Package operatingsystem,  Up: Top

84 Package opsubst
******************

* Menu:

* Functions and Variables for opsubst::


File: maxima.info,  Node: Functions and Variables for opsubst,  Prev: Package opsubst,  Up: Package opsubst

84.1 Functions and Variables for opsubst
========================================

 -- Function: opsubst
          opsubst (<f>,<g>,<e>)
          opsubst (<g>=<f>,<e>)
          opsubst ([<g1>=<f1>,<g2>=<f2>,..., <gn>=<fn>],<e>)
     The function ‘opsubst’ is similar to the function ‘subst’, except
     that ‘opsubst’ only makes substitutions for the operators in an
     expression.  In general, When <f> is an operator in the expression
     <e>, substitute <g> for <f> in the expression <e>.

     To determine the operator, ‘opsubst’ sets ‘inflag’ to true.  This
     means ‘opsubst’ substitutes for the internal, not the displayed,
     operator in the expression.

     Examples:
          (%i1) load ("opsubst")$

          (%i2) opsubst(f,g,g(g(x)));
          (%o2)                     f(f(x))
          (%i3) opsubst(f,g,g(g));
          (%o3)                       f(g)
          (%i4) opsubst(f,g[x],g[x](z));
          (%o4)                       f(z)
          (%i5) opsubst(g[x],f, f(z));
          (%o5)                      g (z)
                                      x
          (%i6) opsubst(tan, sin, sin(sin));
          (%o6)                     tan(sin)
          (%i7) opsubst([f=g,g=h],f(x));
          (%o7)                       h(x)

     Internally, Maxima does not use the unary negation, division, or
     the subtraction operators; thus:
          (%i8) opsubst("+","-",a-b);
          (%o8)                     a - b
          (%i9) opsubst("f","-",-a);
          (%o9)                      - a
          (%i10) opsubst("^^","/",a/b);
                                       a
          (%o10)                       -
                                       b

     The internal representation of -a*b is *(-1,a,b); thus
          (%i11) opsubst("[","*", -a*b);
          (%o11)                  [- 1, a, b]

     When either operator isn't a Maxima symbol, generally some other
     function will signal an error:
          (%i12) opsubst(a+b,f, f(x));

          Improper name or value in functional position:
          b + a
           -- an error.  Quitting.  To debug this try debugmode(true);

     However, subscripted operators are allowed:
          (%i13) opsubst(g[5],f, f(x));
          (%o13)                     g (x)
                                      5

     To use this function write first ‘load("opsubst")’.


File: maxima.info,  Node: Package orthopoly,  Next: Package pslq,  Prev: Package opsubst,  Up: Top

85 Package orthopoly
********************

* Menu:

* Introduction to orthogonal polynomials::
* Functions and Variables for orthogonal polynomials::


File: maxima.info,  Node: Introduction to orthogonal polynomials,  Next: Functions and Variables for orthogonal polynomials,  Prev: Package orthopoly,  Up: Package orthopoly

85.1 Introduction to orthogonal polynomials
===========================================

‘orthopoly’ is a package for symbolic and numerical evaluation of
several kinds of orthogonal polynomials, including Chebyshev, Laguerre,
Hermite, Jacobi, Legendre, and ultraspherical (Gegenbauer) polynomials.
Additionally, ‘orthopoly’ includes support for the spherical Bessel,
spherical Hankel, and spherical harmonic functions.

   For the most part, ‘orthopoly’ follows the conventions of Abramowitz
and Stegun Handbook of Mathematical Functions, Chapter 22 (10th
printing, December 1972); additionally, we use Gradshteyn and Ryzhik,
Table of Integrals, Series, and Products (1980 corrected and enlarged
edition), and Eugen Merzbacher Quantum Mechanics (2nd edition, 1970).

   Barton Willis of the University of Nebraska at Kearney (UNK) wrote
the ‘orthopoly’ package and its documentation.  The package is released
under the GNU General Public License (GPL).

85.1.1 Getting Started with orthopoly
-------------------------------------

‘load ("orthopoly")’ loads the ‘orthopoly’ package.

   To find the third-order Legendre polynomial,

     (%i1) legendre_p (3, x);
                           3             2
                  5 (1 - x)    15 (1 - x)
     (%o1)      - ---------- + ----------- - 6 (1 - x) + 1
                      2             2

   To express this as a sum of powers of <x>, apply <ratsimp> or <rat>
to the result.

     (%i2) [ratsimp (%), rat (%)];
                             3           3
                          5 x  - 3 x  5 x  - 3 x
     (%o2)/R/            [----------, ----------]
                              2           2

   Alternatively, make the second argument to ‘legendre_p’ (its "main"
variable) a canonical rational expression (CRE).

     (%i1) legendre_p (3, rat (x));
                                   3
                                5 x  - 3 x
     (%o1)/R/                   ----------
                                    2

   For floating point evaluation, ‘orthopoly’ uses a running error
analysis to estimate an upper bound for the error.  For example,

     (%i1) jacobi_p (150, 2, 3, 0.2);
     (%o1) interval(- 0.062017037936715, 1.533267919277521E-11)

   Intervals have the form ‘interval (<c>, <r>)’, where <c> is the
center and <r> is the radius of the interval.  Since Maxima does not
support arithmetic on intervals, in some situations, such as graphics,
you want to suppress the error and output only the center of the
interval.  To do this, set the option variable
‘orthopoly_returns_intervals’ to ‘false’.

     (%i1) orthopoly_returns_intervals : false;
     (%o1)                         false
     (%i2) jacobi_p (150, 2, 3, 0.2);
     (%o2)                  - 0.062017037936715

   Refer to the section *note Floating point Evaluation:: for more
information.

   Most functions in ‘orthopoly’ have a ‘gradef’ property; thus

     (%i1) diff (hermite (n, x), x);
     (%o1)                     2 n H     (x)
                                    n - 1
     (%i2) diff (gen_laguerre (n, a, x), x);
                   (a)               (a)
                n L   (x) - (n + a) L     (x) unit_step(n)
                   n                 n - 1
     (%o2)      ------------------------------------------
                                    x

   The unit step function in the second example prevents an error that
would otherwise arise by evaluating with <n> equal to 0.

     (%i3) ev (%, n = 0);
     (%o3)                           0

   The ‘gradef’ property only applies to the "main" variable;
derivatives with respect other arguments usually result in an error
message; for example

     (%i1) diff (hermite (n, x), x);
     (%o1)                     2 n H     (x)
                                    n - 1
     (%i2) diff (hermite (n, x), n);

     Maxima doesn't know the derivative of hermite with respect the first
     argument
      -- an error.  Quitting.  To debug this try debugmode(true);

   Generally, functions in ‘orthopoly’ map over lists and matrices.  For
the mapping to fully evaluate, the option variables ‘doallmxops’ and
‘listarith’ must both be ‘true’ (the defaults).  To illustrate the
mapping over matrices, consider

     (%i1) hermite (2, x);
                                          2
     (%o1)                    - 2 (1 - 2 x )
     (%i2) m : matrix ([0, x], [y, 0]);
                                 [ 0  x ]
     (%o2)                       [      ]
                                 [ y  0 ]
     (%i3) hermite (2, m);
                    [                             2  ]
                    [      - 2        - 2 (1 - 2 x ) ]
     (%o3)          [                                ]
                    [             2                  ]
                    [ - 2 (1 - 2 y )       - 2       ]

   In the second example, the ‘i, j’ element of the value is ‘hermite
(2, m[i,j])’; this is not the same as computing ‘-2 + 4 m . m’, as seen
in the next example.

     (%i4) -2 * matrix ([1, 0], [0, 1]) + 4 * m . m;
                         [ 4 x y - 2      0     ]
     (%o4)               [                      ]
                         [     0      4 x y - 2 ]

   If you evaluate a function at a point outside its domain, generally
‘orthopoly’ returns the function unevaluated.  For example,

     (%i1) legendre_p (2/3, x);
     (%o1)                        P   (x)
                                   2/3

   ‘orthopoly’ supports translation into TeX; it also does
two-dimensional output on a terminal.

     (%i1) spherical_harmonic (l, m, theta, phi);
                               m
     (%o1)                    Y (theta, phi)
                               l
     (%i2) tex (%);
     $$Y_{l}^{m}\left(\vartheta,\varphi\right)$$
     (%o2)                         false
     (%i3) jacobi_p (n, a, a - b, x/2);
                               (a, a - b) x
     (%o3)                    P          (-)
                               n          2
     (%i4) tex (%);
     $$P_{n}^{\left(a,a-b\right)}\left({{x}\over{2}}\right)$$
     (%o4)                         false

85.1.2 Limitations
------------------

When an expression involves several orthogonal polynomials with symbolic
orders, it's possible that the expression actually vanishes, yet Maxima
is unable to simplify it to zero.  If you divide by such a quantity,
you'll be in trouble.  For example, the following expression vanishes
for integers <n> greater than 1, yet Maxima is unable to simplify it to
zero.

     (%i1) (2*n - 1) * legendre_p (n - 1, x) * x - n * legendre_p (n, x)
           + (1 - n) * legendre_p (n - 2, x);
     (%o1)  (2 n - 1) P     (x) x - n P (x) + (1 - n) P     (x)
                       n - 1           n               n - 2

   For a specific <n>, we can reduce the expression to zero.

     (%i2) ev (% ,n = 10, ratsimp);
     (%o2)                           0

   Generally, the polynomial form of an orthogonal polynomial is
ill-suited for floating point evaluation.  Here's an example.

     (%i1) p : jacobi_p (100, 2, 3, x)$

     (%i2) subst (0.2, x, p);
     (%o2)                3.4442767023833592E+35
     (%i3) jacobi_p (100, 2, 3, 0.2);
     (%o3)  interval(0.18413609135169, 6.8990300925815987E-12)
     (%i4) float(jacobi_p (100, 2, 3, 2/10));
     (%o4)                   0.18413609135169

   The true value is about 0.184; this calculation suffers from extreme
subtractive cancellation error.  Expanding the polynomial and then
evaluating, gives a better result.
     (%i5) p : expand(p)$
     (%i6) subst (0.2, x, p);
     (%o6) 0.18413609766122982

   This isn't a general rule; expanding the polynomial does not always
result in an expression that is better suited for numerical evaluation.
By far, the best way to do numerical evaluation is to make one or more
of the function arguments floating point numbers.  By doing that,
specialized floating point algorithms are used for evaluation.

   Maxima's ‘float’ function is somewhat indiscriminate; if you apply
‘float’ to an expression involving an orthogonal polynomial with a
symbolic degree or order parameter, these parameters may be converted
into floats; after that, the expression will not evaluate fully.
Consider

     (%i1) assoc_legendre_p (n, 1, x);
                                    1
     (%o1)                         P (x)
                                    n
     (%i2) float (%);
                                   1.0
     (%o2)                        P   (x)
                                   n
     (%i3) ev (%, n=2, x=0.9);
                                  1.0
     (%o3)                       P   (0.9)
                                  2

   The expression in (%o3) will not evaluate to a float; ‘orthopoly’
doesn't recognize floating point values where it requires an integer.
Similarly, numerical evaluation of the ‘pochhammer’ function for orders
that exceed ‘pochhammer_max_index’ can be troublesome; consider

     (%i1) x :  pochhammer (1, 10), pochhammer_max_index : 5;
     (%o1)                         (1)
                                      10

   Applying ‘float’ doesn't evaluate <x> to a float

     (%i2) float (x);
     (%o2)                       (1.0)
                                      10.0

   To evaluate <x> to a float, you'll need to bind
‘pochhammer_max_index’ to 11 or greater and apply ‘float’ to <x>.

     (%i3) float (x), pochhammer_max_index : 11;
     (%o3)                       3628800.0

   The default value of ‘pochhammer_max_index’ is 100; change its value
after loading ‘orthopoly’.

   Finally, be aware that reference books vary on the definitions of the
orthogonal polynomials; we've generally used the conventions of
Abramowitz and Stegun.

   Before you suspect a bug in orthopoly, check some special cases to
determine if your definitions match those used by ‘orthopoly’.
Definitions often differ by a normalization; occasionally, authors use
"shifted" versions of the functions that makes the family orthogonal on
an interval other than (-1, 1).  To define, for example, a Legendre
polynomial that is orthogonal on (0, 1), define

     (%i1) shifted_legendre_p (n, x) := legendre_p (n, 2*x - 1)$

     (%i2) shifted_legendre_p (2, rat (x));
                                 2
     (%o2)/R/                 6 x  - 6 x + 1
     (%i3) legendre_p (2, rat (x));
                                    2
                                 3 x  - 1
     (%o3)/R/                    --------
                                    2

85.1.3 Floating point Evaluation
--------------------------------

Most functions in ‘orthopoly’ use a running error analysis to estimate
the error in floating point evaluation; the exceptions are the spherical
Bessel functions and the associated Legendre polynomials of the second
kind.  For numerical evaluation, the spherical Bessel functions call
SLATEC functions.  No specialized method is used for numerical
evaluation of the associated Legendre polynomials of the second kind.

   The running error analysis ignores errors that are second or higher
order in the machine epsilon (also known as unit roundoff).  It also
ignores a few other errors.  It's possible (although unlikely) that the
actual error exceeds the estimate.

   Intervals have the form ‘interval (<c>, <r>)’, where <c> is the
center of the interval and <r> is its radius.  The center of an interval
can be a complex number, and the radius is always a positive real
number.

   Here is an example.

     (%i1) fpprec : 50$

     (%i2) y0 : jacobi_p (100, 2, 3, 0.2);
     (%o2) interval(0.1841360913516871, 6.8990300925815987E-12)
     (%i3) y1 : bfloat (jacobi_p (100, 2, 3, 1/5));
     (%o3) 1.8413609135168563091370224958913493690868904463668b-1

   Let's test that the actual error is smaller than the error estimate

     (%i4) is (abs (part (y0, 1) - y1) < part (y0, 2));
     (%o4)                         true

   Indeed, for this example the error estimate is an upper bound for the
true error.

   Maxima does not support arithmetic on intervals.

     (%i1) legendre_p (7, 0.1) + legendre_p (8, 0.1);
     (%o1) interval(0.18032072148437508, 3.1477135311021797E-15)
             + interval(- 0.19949294375000004, 3.3769353084291579E-15)

   A user could define arithmetic operators that do interval math.  To
define interval addition, we can define

     (%i1) infix ("@+")$

     (%i2) "@+"(x,y) := interval (part (x, 1) + part (y, 1), part (x, 2)
           + part (y, 2))$

     (%i3) legendre_p (7, 0.1) @+ legendre_p (8, 0.1);
     (%o3) interval(- 0.019172222265624955, 6.5246488395313372E-15)

   The special floating point routines get called when the arguments are
complex.  For example,

     (%i1) legendre_p (10, 2 + 3.0*%i);
     (%o1) interval(- 3.876378825E+7 %i - 6.0787748E+7,
                                                1.2089173052721777E-6)

   Let's compare this to the true value.

     (%i1) float (expand (legendre_p (10, 2 + 3*%i)));
     (%o1)          - 3.876378825E+7 %i - 6.0787748E+7

   Additionally, when the arguments are big floats, the special floating
point routines get called; however, the big floats are converted into
double floats and the final result is a double.

     (%i1) ultraspherical (150, 0.5b0, 0.9b0);
     (%o1) interval(- 0.043009481257265, 3.3750051301228864E-14)

85.1.4 Graphics and ‘orthopoly’
-------------------------------

To plot expressions that involve the orthogonal polynomials, you must do
two things:
  1. Set the option variable ‘orthopoly_returns_intervals’ to ‘false’,
  2. Quote any calls to ‘orthopoly’ functions.
   If function calls aren't quoted, Maxima evaluates them to polynomials
before plotting; consequently, the specialized floating point code
doesn't get called.  Here is an example of how to plot an expression
that involves a Legendre polynomial.

     (%i1) plot2d ('(legendre_p (5, x)), [x, 0, 1]),
                             orthopoly_returns_intervals : false;
     (%o1)


   (Figure orthopoly1: Plot of the Legrende polynomial of order 5)

   The entire expression ‘legendre_p (5, x)’ is quoted; this is
different than just quoting the function name using ‘'legendre_p (5,
<x>)’.

85.1.5 Miscellaneous Functions
------------------------------

The ‘orthopoly’ package defines the Pochhammer symbol and a unit step
function.  ‘orthopoly’ uses the Kronecker delta function and the unit
step function in ‘gradef’ statements.

   To convert Pochhammer symbols into quotients of gamma functions, use
‘makegamma’.

     (%i1) makegamma (pochhammer (x, n));
                               gamma(x + n)
     (%o1)                     ------------
                                 gamma(x)
     (%i2) makegamma (pochhammer (1/2, 1/2));
                                     1
     (%o2)                       ---------
                                 sqrt(%pi)

   Derivatives of the Pochhammer symbol are given in terms of the ‘psi’
function.

     (%i1) diff (pochhammer (x, n), x);
     (%o1)             (x)  (psi (x + n) - psi (x))
                          n     0             0
     (%i2) diff (pochhammer (x, n), n);
     (%o2)                   (x)  psi (x + n)
                                n    0

   You need to be careful with the expression in (%o1); the difference
of the ‘psi’ functions has polynomials when ‘<x> = -1, -2, .., -<n>’.
These polynomials cancel with factors in ‘pochhammer (<x>, <n>)’ making
the derivative a degree ‘<n> - 1’ polynomial when <n> is a positive
integer.

   The Pochhammer symbol is defined for negative orders through its
representation as a quotient of gamma functions.  Consider

     (%i1) q : makegamma (pochhammer (x, n));
                               gamma(x + n)
     (%o1)                     ------------
                                 gamma(x)
     (%i2) sublis ([x=11/3, n= -6], q);
                                    729
     (%o2)                        - ----
                                    2240

   Alternatively, we can get this result directly.

     (%i1) pochhammer (11/3, -6);
                                    729
     (%o1)                        - ----
                                    2240

   The unit step function is left-continuous; thus

     (%i1) [unit_step (-1/10), unit_step (0), unit_step (1/10)];
     (%o1)                       [0, 0, 1]

   If you need a unit step function that is neither left or right
continuous at zero, define your own using ‘signum’; for example,

     (%i1) xunit_step (x) := (1 + signum (x))/2$

     (%i2) [xunit_step (-1/10), xunit_step (0), xunit_step (1/10)];
                                     1
     (%o2)                       [0, -, 1]
                                     2

   Do not redefine ‘unit_step’ itself; some code in ‘orthopoly’ requires
that the unit step function be left-continuous.

85.1.6 Algorithms
-----------------

Generally, ‘orthopoly’ does symbolic evaluation by using a hypergeometic
representation of the orthogonal polynomials.  The hypergeometic
functions are evaluated using the (undocumented) functions ‘hypergeo11’
and ‘hypergeo21’.  The exceptions are the half-integer Bessel functions
and the associated Legendre function of the second kind.  The
half-integer Bessel functions are evaluated using an explicit
representation, and the associated Legendre function of the second kind
is evaluated using recursion.

   For floating point evaluation, we again convert most functions into a
hypergeometic form; we evaluate the hypergeometic functions using
forward recursion.  Again, the exceptions are the half-integer Bessel
functions and the associated Legendre function of the second kind.
Numerically, the half-integer Bessel functions are evaluated using the
SLATEC code.


File: maxima.info,  Node: Functions and Variables for orthogonal polynomials,  Prev: Introduction to orthogonal polynomials,  Up: Package orthopoly

85.2 Functions and Variables for orthogonal polynomials
=======================================================

 -- Function: assoc_legendre_p (<n>, <m>, <x>)
     The associated Legendre function of the first kind of degree n and
     order m, assoc_legendre_p(n,m,z), is a solution of the differential
     equation:

     (1-z^2)*diff(w,z,2) - 2*z*diff(w,z) + (n*(n+1)-m^2/(1-z^2))*w = 0

     This is related to the Legendre polynomial, legendre_p(n,x) via

     assoc_legendre_p(n,m,x) = (-1)^m*(1-x^2)^(m/2)
     diff(legendre_p(n,x),x,m)

     Reference: A&S eqn 22.5.37
     (https://personal.math.ubc.ca/~cbm/aands/page_779.htm), A&S eqn
     8.6.6 (https://personal.math.ubc.ca/~cbm/aands/page_334.htm), and
     A&S eqn 8.2.5
     (https://personal.math.ubc.ca/~cbm/aands/page_333.htm).

     Some examples:
          (%i1) assoc_legendre_p(2,0,x);
                                                           2
                                                  3 (1 - x)
          (%o1)                   (- 3 (1 - x)) + ---------- + 1
                                                      2
          (%i2) factor(%);
                                                2
                                             3 x  - 1
          (%o2)                              --------
                                                2
          (%i3) factor(assoc_legendre_p(2,1,x));
                                                        2
          (%o3)                         - 3 x sqrt(1 - x )

          (%i4) (-1)^1*(1-x^2)^(1/2)*diff(legendre_p(2,x),x);
                                                              2
          (%o4)                   - (3 - 3 (1 - x)) sqrt(1 - x )

          (%i5) factor(%);
                                                        2
          (%o5)                         - 3 x sqrt(1 - x )

 -- Function: assoc_legendre_q (<n>, <m>, <x>)
     The associated Legendre function of the second kind of degree n and
     order m, assoc_legendre_q(n,m,z), is a solution of the differential
     equation:

     (1-z^2)*diff(w,z,2) - 2*z*diff(w,z) + (n*(n+1)-m^2/(1-z^2))*w = 0

     Reference: Abramowitz and Stegun, equation 8.5.3 and 8.1.8.

     Some examples:
          (%i1) assoc_legendre_q(0,0,x);
                                                 x + 1
                                           log(- -----)
                                                 x - 1
          (%o1)                            ------------
                                                2
          (%i2) assoc_legendre_q(1,0,x);
                                              x + 1
                                        log(- -----) x - 2
                                              x - 1
          (%o2)/R/                      ------------------
                                                2
          (%i3) assoc_legendre_q(1,1,x);
          (%o3)/R/
                    x + 1            2   2               2            x + 1            2
              log(- -----) sqrt(1 - x ) x  - 2 sqrt(1 - x ) x - log(- -----) sqrt(1 - x )
                    x - 1                                             x - 1
            - ---------------------------------------------------------------------------
                                                  2
                                               2 x  - 2

 -- Function: chebyshev_t (<n>, <x>)
     The Chebyshev polynomial of the first kind of degree n,
     chebyshev_t(n,x).

     Reference: A&S eqn 22.5.47
     (https://personal.math.ubc.ca/~cbm/aands/page_779.htm).

     The polynomials chebyshev_t(n,x) can be written in terms of a
     hypergeometric function:

     hypergeometric([-n,n],[1/2],(1-x)/2)

     The polynomials can also be defined in terms of the sum

     chebyshev_t(n,x) =
     n/2*sum((-1)^r/(n-r)*binomial(n-r,r)*(2*x)^(n-2*r), r, 0,
     floor(n/2))

     or the Rodrigues formula

     chebyshev_t(n,x) = 1/(k(n)*w(x))*diff(w(x)*(1-x^2)^n, x, n)

     where

     w(x) = 1/sqrt(1-x^2)

     k_n = (-2)^n*pochhammer(1/2,n)

     Some examples:
          (%i1) chebyshev_t(2,x);
                                                           2
          (%o1)                   (- 4 (1 - x)) + 2 (1 - x)  + 1
          (%i2) factor(%);
                                                2
          (%o2)                              2 x  - 1
          (%i3) factor(chebyshev_t(3,x));
                                                 2
          (%o3)                            x (4 x  - 3)
          (%i4) factor(hgfred([-3,3],[1/2],(1-x)/2));
                                                 2
          (%o4)                            x (4 x  - 3)

 -- Function: chebyshev_u (<n>, <x>)
     The Chebyshev polynomial of the second kind of degree n,
     chebyshev_u(n,x).

     Reference: A&S eqn 22.5.48
     (https://personal.math.ubc.ca/~cbm/aands/page_779.htm).

     The polynomials chebyshev_u(n,x) can be written in terms of a
     hypergeometric function:

     chebyshev_u(n,x) = (n+1)*hypergeometric([-n,n+1],[3/2],(1-x)/2)

     The polynomials can also be defined in terms of the sum

     chebyshev_u(n,x) = sum((-1)^r*binomial(n-r,r)*(2*x)^(n-2*r), r, 0,
     floor(n/2))

     or the Rodrigues formula

     chebyshev_u(n,x) = 1/(k(n)*w(x))*diff(w(x)*(1-x^2)^n, x, n)

     where

     w(x) = sqrt(1-x^2)

     k(n) = (-2)^n*pochhammer(3/2,n)/(n+1) .

          (%i1) chebyshev_u(2,x);
                                                            2
                                      8 (1 - x)    4 (1 - x)
          (%o1)                 3 ((- ---------) + ---------- + 1)
                                          3            3
          (%i2) expand(%);
                                                2
          (%o2)                              4 x  - 1
          (%i3) expand(chebyshev_u(3,x));
                                               3
          (%o3)                             8 x  - 4 x
          (%i4) expand(4*hgfred([-3,5],[3/2],(1-x)/2));
                                               3
          (%o4)                             8 x  - 4 x

 -- Function: gen_laguerre (<n>, <a>, <x>)
     The generalized Laguerre polynomial of degree n,
     gen_laguerre(n,a,x).

     These can be defined by

     gen_laguerre(n, a, x) = binomial(n+a,n)*hypergeometric([-n], [a+1],
     x)

     The polynomials can also be defined by the sum

     gen_laguerre(n, a, x) =
     sum(pochhammer(a+k+1,n-k)/((n-k)!*k!)*(-x)^k, k, 0, n)

     or the Rodrigues formula

     gen_laguerre(n, a, x) = 1/(k(n)*w(x))*diff(w(x)*x^n, x, n)

     where

     w(x) = %e^(-x)*x^a

     k(n) = n!

     Reference: A&S eqn 22.5.54
     (https://personal.math.ubc.ca/~cbm/aands/page_780.htm).

     Some examples:
          (%i1) gen_laguerre(1,k,x);
                                                       x
          (%o1)                         (k + 1) (1 - -----)
                                                     k + 1
          (%i2) gen_laguerre(2,k,x);
                                                   2
                                                  x            2 x
                           (k + 1) (k + 2) (--------------- - ----- + 1)
                                            (k + 1) (k + 2)   k + 1
          (%o2)            ---------------------------------------------
                                                 2
          (%i3) binomial(2+k,2)*hgfred([-2],[1+k],x);
                                                   2
                                                  x            2 x
                           (k + 1) (k + 2) (--------------- - ----- + 1)
                                            (k + 1) (k + 2)   k + 1
          (%o3)            ---------------------------------------------
                                                 2

 -- Function: hermite (<n>, <x>)
     The Hermite polynomial of degree n, hermite(n,x).

     These polynomials may be defined by a hypergeometric function

     hermite(n,x) = (2*x)^n * hypergeometric([-n/2, -n/2+1/2],[],
     -1/x^2)

     or by the series

     hermite(n,x) = n!*sum((-1)^k*(2*x)^(n-2*k)/(k!*(n-2*k)!), k, 0,
     floor(n/2))

     or the Rodrigues formula

     hermite(n,x) = 1/(k(n)*w(x))*diff(w(x), x, n)

     where

     w(x) = %e(-x^2/2)

     k(n) = (-1)^n

     Reference: A&S eqn 22.5.55
     (https://personal.math.ubc.ca/~cbm/aands/page_780.htm).

     Some examples:
          (%i1) hermite(3,x);
                                                        2
                                                     2 x
          (%o1)                          - 12 x (1 - ----)
                                                      3
          (%i2) expand(%);
                                               3
          (%o2)                             8 x  - 12 x
          (%i3) expand(hermite(4,x));
                                            4       2
          (%o3)                         16 x  - 48 x  + 12
          (%i4) expand((2*x)^4*hgfred([-2,-2+1/2],[],-1/x^2));
                                            4       2
          (%o4)                         16 x  - 48 x  + 12
          (%i5) expand(4!*sum((-1)^k*(2*x)^(4-2*k)/(k!*(4-2*k)!),k,0,floor(4/2)));
                                            4       2
          (%o5)                         16 x  - 48 x  + 12

 -- Function: intervalp (<e>)
     Return ‘true’ if the input is an interval and return false if it
     isn't.

 -- Function: jacobi_p (<n>, <a>, <b>, <x>)
     The Jacobi polynomial, jacobi_p(n,a,b,x).

     The Jacobi polynomials are actually defined for all a and b;
     however, the Jacobi polynomial weight (1 - x)^a (1 + x)^b isn't
     integrable for a <= -1 or b <= -1.

     Reference: A&S eqn 22.5.42
     (https://personal.math.ubc.ca/~cbm/aands/page_779.htm).

     The polynomial may be defined in terms of hypergeometric functions:

     jacobi_p(n,a,b,x) =
     binomial(n+a,n)*hypergeometric([-n,n+a+b+1],[a+1],(1-x)/2)

     or the Rodrigues formula

     jacobi_p(n,a,b,x) = 1/(k(n)*w(x))*diff(w(x)*(1-x^2)^n, x, n)

     where

     w(x) = (1-x)^a*(1-x)^b

     k(n) = (-2)^n*n!

     Some examples:
          (%i1) jacobi_p(0,a,b,x);
          (%o1)                                  1
          (%i2) jacobi_p(1,a,b,x);
                                              (b + a + 2) (1 - x)
          (%o2)                  (a + 1) (1 - -------------------)
                                                   2 (a + 1)

 -- Function: laguerre (<n>, <x>)
     The Laguerre polynomial, laguerre(n,x) of degree n.

     Reference: A&S eqn 22.5.16
     (https://personal.math.ubc.ca/~cbm/aands/page_778.htm) and A&S eqn
     22.5.54 (https://personal.math.ubc.ca/~cbm/aands/page_780.htm).

     These are related to the generalized Laguerre polynomial by

     laguerre(n,x) = gen_laguerre(n,0,x)

     The polynomials are given by the sum

     laguerre(n,x) = sum((-1)^k/k!*binomial(n,k)*x^k,k,0,n)

     Some examples:
          (%i1) laguerre(1,x);
          (%o1)                                1 - x
          (%i2) laguerre(2,x);
                                            2
                                           x
          (%o2)                            -- - 2 x + 1
                                           2
          (%i3) gen_laguerre(2,0,x);
                                            2
                                           x
          (%o3)                            -- - 2 x + 1
                                           2
          (%i4) sum((-1)^k/k!*binomial(2,k)*x^k,k,0,2);
                                            2
                                           x
          (%o4)                            -- - 2 x + 1
                                           2

 -- Function: legendre_p (<n>, <x>)
     The Legendre polynomial of the first kind, legendre(n,x), of degree
     n.

     Reference: A&S eqn 22.5.50
     (https://personal.math.ubc.ca/~cbm/aands/page_779.htm) and A&S eqn
     22.5.51 (https://personal.math.ubc.ca/~cbm/aands/page_779.htm).

     The Legendre polynomial is related to the Jacobi polynomials by

     legendre_p(n,x) = jacobi_p(n,0,0,x)

     or the Rodrigues formula

     legendre_p(n,x) = 1/(k(n)*w(x))*diff(w(x)*(1-x^2)^n, x, n)

     where

     w(x) = 1

     k(n) = (-2)^n*n!

     Some examples:
          (%i1) legendre_p(1,x);
          (%o1)                                  x
          (%i2) legendre_p(2,x);
                                                           2
                                                  3 (1 - x)
          (%o2)                   (- 3 (1 - x)) + ---------- + 1
                                                      2
          (%i3) expand(%);
                                                2
                                             3 x    1
          (%o3)                              ---- - -
                                              2     2
          (%i4) expand(legendre_p(3,x));
                                               3
                                            5 x    3 x
          (%o4)                             ---- - ---
                                             2      2
          (%i5) expand(jacobi_p(3,0,0,x));
                                               3
                                            5 x    3 x
          (%o5)                             ---- - ---
                                             2      2

 -- Function: legendre_q (<n>, <x>)
     The Legendre function of the second kind, legendre_q(n,x) of degree
     n.

     Reference: Abramowitz and Stegun, equations 8.5.3 and 8.1.8.

     These are related to assoc_legendre_q(n,m,x) by

     legendre_q(n,x) = assoc_legendre_q(n,0,x)

     Some examples:
          (%i1) legendre_q(0,x);
                                                 x + 1
                                           log(- -----)
                                                 x - 1
          (%o1)                            ------------
                                                2
          (%i2) legendre_q(1,x);
                                              x + 1
                                        log(- -----) x - 2
                                              x - 1
          (%o2)/R/                      ------------------
                                                2
          (%i3) assoc_legendre_q(1,0,x);
                                              x + 1
                                        log(- -----) x - 2
                                              x - 1
          (%o3)/R/                      ------------------
                                                2

 -- Function: orthopoly_recur (<f>, <args>)
     Returns a recursion relation for the orthogonal function family <f>
     with arguments <args>.  The recursion is with respect to the
     polynomial degree.

          (%i1) orthopoly_recur (legendre_p, [n, x]);
                              (2 n + 1) P (x) x - n P     (x)
                                         n           n - 1
          (%o1)   P     (x) = -------------------------------
                   n + 1                   n + 1

     The second argument to ‘orthopoly_recur’ must be a list with the
     correct number of arguments for the function <f>; if it isn't,
     Maxima signals an error.

          (%i1) orthopoly_recur (jacobi_p, [n, x]);

          Function jacobi_p needs 4 arguments, instead it received 2
           -- an error.  Quitting.  To debug this try debugmode(true);

     Additionally, when <f> isn't the name of one of the families of
     orthogonal polynomials, an error is signalled.

          (%i1) orthopoly_recur (foo, [n, x]);

          A recursion relation for foo isn't known to Maxima
           -- an error.  Quitting.  To debug this try debugmode(true);

 -- Variable: orthopoly_returns_intervals
     Default value: ‘true’

     When ‘orthopoly_returns_intervals’ is ‘true’, floating point
     results are returned in the form ‘interval (<c>, <r>)’, where <c>
     is the center of an interval and <r> is its radius.  The center can
     be a complex number; in that case, the interval is a disk in the
     complex plane.

 -- Function: orthopoly_weight (<f>, <args>)

     Returns a three element list; the first element is the formula of
     the weight for the orthogonal polynomial family <f> with arguments
     given by the list <args>; the second and third elements give the
     lower and upper endpoints of the interval of orthogonality.  For
     example,

          (%i1) w : orthopoly_weight (hermite, [n, x]);
                                      2
                                   - x
          (%o1)                 [%e    , - inf, inf]
          (%i2) integrate(w[1]*hermite(3, x)*hermite(2, x), x, w[2], w[3]);
          (%o2)                           0

     The main variable of <f> must be a symbol; if it isn't, Maxima
     signals an error.

 -- Function: pochhammer (<x>, <n>)
     The Pochhammer symbol, pochhammer(x,n). (See A&S eqn 6.1.22
     (https://personal.math.ubc.ca/~cbm/aands/page_256.htm) and DLMF
     5.2.iii (https://dlmf.nist.gov/5.2.iii)).

     For nonnegative integers <n> with ‘<n> <= pochhammer_max_index’,
     the expression pochhammer(x, n) evaluates to the product x (x + 1)
     (x + 2) ... (x + n - 1) when n > 0 and to 1 when n = 0.  For
     negative n, pochhammer (x, n) is defined as (-1)^n / pochhammer (1
     - x, -n). Thus

          (%i1) pochhammer (x, 3);
          (%o1)                   x (x + 1) (x + 2)
          (%i2) pochhammer (x, -3);
                                           1
          (%o2)               - -----------------------
                                (1 - x) (2 - x) (3 - x)

     To convert a Pochhammer symbol into a quotient of gamma functions,
     (see A&S eqn 6.1.22
     (https://personal.math.ubc.ca/~cbm/aands/page_256.htm)) use
     ‘makegamma’; for example

          (%i1) makegamma (pochhammer (x, n));
                                    gamma(x + n)
          (%o1)                     ------------
                                      gamma(x)

     When <n> exceeds ‘pochhammer_max_index’ or when <n> is symbolic,
     ‘pochhammer’ returns a noun form.

          (%i1) pochhammer (x, n);
          (%o1)                         (x)
                                           n

 -- Variable: pochhammer_max_index
     Default value: 100

     ‘pochhammer (<n>, <x>)’ expands to a product if and only if ‘<n> <=
     pochhammer_max_index’.

     Examples:

          (%i1) pochhammer (x, 3), pochhammer_max_index : 3;
          (%o1)                   x (x + 1) (x + 2)
          (%i2) pochhammer (x, 4), pochhammer_max_index : 3;
          (%o2)                         (x)
                                           4

     Reference: A&S eqn 6.1.16
     (https://personal.math.ubc.ca/~cbm/aands/page_256.htm).

 -- Function: spherical_bessel_j (<n>, <x>)
     The spherical Bessel function of the first kind,
     spherical_bessel_j(n,x).

     Reference: A&S eqn 10.1.8
     (https://personal.math.ubc.ca/~cbm/aands/page_437.htm) and A&S eqn
     10.1.15 (https://personal.math.ubc.ca/~cbm/aands/page_439.htm).

     It is related to the Bessel function by

     spherical_bessel_j(n,x) = sqrt(%pi/(2*x))*bessel_j(n+1/2,x)

     Some examples:
          (%i1) spherical_bessel_j(1,x);
                                          sin(x)
                                          ------ - cos(x)
                                            x
          (%o1)                           ---------------
                                                 x
          (%i2) spherical_bessel_j(2,x);
                                          3             3 cos(x)
                                  (- (1 - --) sin(x)) - --------
                                           2               x
                                          x
          (%o2)                   ------------------------------
                                                x
          (%i3) expand(%);
                                    sin(x)    3 sin(x)   3 cos(x)
          (%o3)                  (- ------) + -------- - --------
                                      x           3          2
                                                 x          x
          (%i4) expand(sqrt(%pi/(2*x))*bessel_j(2+1/2,x)),besselexpand:true;
                                    sin(x)    3 sin(x)   3 cos(x)
          (%o4)                  (- ------) + -------- - --------
                                      x           3          2
                                                 x          x

 -- Function: spherical_bessel_y (<n>, <x>)
     The spherical Bessel function of the second kind,
     <spherical_bessel_y(n,x).

     Reference: A&S eqn 10.1.9
     (https://personal.math.ubc.ca/~cbm/aands/page_437.htm) and A&S eqn
     10.1.15 (https://personal.math.ubc.ca/~cbm/aands/page_439.htm).

     It is related to the Bessel function by

     spherical_bessel_y(n,x) = sqrt(%pi/(2*x))*bessel_y(n+1/2,x)

          (%i1) spherical_bessel_y(1,x);
                                                     cos(x)
                                        (- sin(x)) - ------
                                                       x
          (%o1)                         -------------------
                                                 x
          (%i2) spherical_bessel_y(2,x);
                                     3 sin(x)        3
                                     -------- - (1 - --) cos(x)
                                        x             2
                                                     x
          (%o2)                    - --------------------------
                                                 x
          (%i3) expand(%);
                                    3 sin(x)    cos(x)   3 cos(x)
          (%o3)                  (- --------) + ------ - --------
                                        2         x          3
                                       x                    x
          (%i4) expand(sqrt(%pi/(2*x))*bessel_y(2+1/2,x)),besselexpand:true;
                                    3 sin(x)    cos(x)   3 cos(x)
          (%o4)                  (- --------) + ------ - --------
                                        2         x          3
                                       x                    x

 -- Function: spherical_hankel1 (<n>, <x>)
     The spherical Hankel function of the first kind,
     spherical_hankel1(n,x).

     Reference: A&S eqn 10.1.36
     (https://personal.math.ubc.ca/~cbm/aands/page_439.htm).

     This is defined by

     spherical_hankel1(n,x) = spherical_bessel_j(n,x) +
     %i*spherical_bessel_y(n,x)

 -- Function: spherical_hankel2 (<n>, <x>)
     The spherical Hankel function of the second kind,
     spherical_hankel2(n,x).

     Reference: A&S eqn 10.1.17
     (https://personal.math.ubc.ca/~cbm/aands/page_439.htm).

     This is defined by

     spherical_hankel2(n,x) = spherical_bessel_j(n,x) -
     %i*spherical_bessel_y(n,x)

 -- Function: spherical_harmonic (<n>, <m>, <theta>, <phi>)
     The spherical harmonic function, spherical_harmonic(n,m,theta,phi).

     Spherical harmonics satisfy the angular part of Laplace's equation
     in spherical coordinates.

     For integers n and m such that n <= abs(m) and for theta in [0,
     %pi]. Maxima’s spherical harmonic function can be defined by

     spherical_harmonic(n, m, theta, phi) := (-1)^m *
     (((n-m)!*(2*n+1))/(4*%pi*(n+m)!))^(1/2)*
     exp(%i*m*phi)*assoc_legendre_p(n,m,cos(theta))

     Further, when n < abs(m), the spherical harmonic function vanishes.

     The factor (-1)^m, frequently used in Quantum mechanics, is called
     the Condon-Shortely phase
     (https://en.wikipedia.org/wiki/Spherical_harmonics#Condon%E2%80%93Shortley_phase).
     Some references, including _NIST Digital Library of Mathematical
     Functions_ omit this factor; see <http://dlmf.nist.gov/14.30.E1>.

     Reference: Merzbacher 9.64.

     Some examples:
          (%i1) spherical_harmonic(1,0,theta,phi);
                                        sqrt(3) cos(theta)
          (%o1)                         ------------------
                                           2 sqrt(%pi)
          (%i2) spherical_harmonic(1,1,theta,phi);
                                              %i phi
                                    sqrt(3) %e       sin(theta)
          (%o2)                     ---------------------------
                                           3/2
                                          2    sqrt(%pi)
          (%i3) spherical_harmonic(1,-1,theta,phi);
                                              - %i phi
                                    sqrt(3) %e         sin(theta)
          (%o3)                   - -----------------------------
                                            3/2
                                           2    sqrt(%pi)
          (%i4) spherical_harmonic(2,0,theta,phi);
                                                                        2
                                                      3 (1 - cos(theta))
                    sqrt(5) ((- 3 (1 - cos(theta))) + ------------------- + 1)
                                                               2
          (%o4)     ----------------------------------------------------------
                                           2 sqrt(%pi)
          (%i5) factor(%);
                                                  2
                                    sqrt(5) (3 cos (theta) - 1)
          (%o5)                     ---------------------------
                                            4 sqrt(%pi)

 -- Function: unit_step (<x>)
     The left-continuous unit step function; thus ‘unit_step (<x>)’
     vanishes for ‘<x> <= 0’ and equals 1 for ‘<x> > 0’.

     If you want a unit step function that takes on the value 1/2 at
     zero, use *note hstep::.

 -- Function: ultraspherical (<n>, <a>, <x>)
     The ultraspherical polynomial, ultraspherical(n,a,x) (also known as
     the Gegenbauer polynomial).

     Reference: A&S eqn 22.5.46
     (https://personal.math.ubc.ca/~cbm/aands/page_779.htm).

     These polynomials can be given in terms of Jacobi polynomials:

     ultraspherical(n,a,x) =
     gamma(a+1/2)/gamma(2*a)*gamma(n+2*a)/gamma(n+a+1/2)*jacobi_p(n,a-1/2,a-1/2,x)

     or the series

     ultraspherical(n,a,x) =
     sum((-1)^k*pochhammer(a,n-k)/k!/(n-2*k)!*(2*x)^(n-2*k),k, 0,
     floor(n/2))

     or the Rodrigues formula

     ultraspherical(n,x) = 1/(k(n)*w(x))*diff(w(x)*(1-x^2)^n, x, n)

     where

     w(x) = (1-x^2)^(a-1/2)

     k(n) = (-2)^n*pochhammer(a+1/2,n)*n!/pochhammer(2*a,n)

     Some examples:
          (%i1) ultraspherical(1,a,x);
                                             (2 a + 1) (1 - x)
          (%o1)                     2 a (1 - -----------------)
                                                        1
                                                 2 (a + -)
                                                        2
          (%i2) factor(%);
          (%o2)                                2 a x
          (%i3) factor(ultraspherical(2,a,x));
                                               2      2
          (%o3)                        a (2 a x  + 2 x  - 1)


File: maxima.info,  Node: Package pslq,  Next: Package pytranslate,  Prev: Package orthopoly,  Up: Top

86 Package pslq
***************

* Menu:

* Introduction to pslq::
* Functions and Variables for pslq::


File: maxima.info,  Node: Introduction to pslq,  Next: Functions and Variables for pslq,  Prev: Package pslq,  Up: Package pslq

86.1 Introduction to pslq
=========================

Package ‘pslq’ contains two functions.

   (1) ‘guess_exact_value’ tries to find an exact equivalent for an
inexact number (float or bigfloat).

   (2) ‘pslq_integer_relation’ tries to find integer coefficients such
that a linear combination of inexact numbers is approximately zero.


File: maxima.info,  Node: Functions and Variables for pslq,  Prev: Introduction to pslq,  Up: Package pslq

86.2 Functions and Variables for pslq
=====================================

 -- Function: guess_exact_value (<x>)

     When <x> is a floating point number or bigfloat,
     ‘guess_exact_value’ tries to find an exact expression (in terms of
     radicals, logarithms, exponentials, and the constant ‘%pi’) which
     is nearly equal to the given number.  If ‘guess_exact_value’ cannot
     find such an expression, <x> is returned unchanged.

     When <x> is rational number or other mapatom (other than a float or
     bigfloat), <x> is returned unchanged.

     Otherwise, <x> is a nonatomic expression, and ‘guess_exact_value’
     is applied to each of the arguments of <x>.

     Example:

          (%i1) load ("pslq.mac");
          (%o1)                       pslq.mac
          (%i2) root: float (sin (%pi/12));
          (%o2)                  0.2588190451025207
          (%i3) guess_exact_value (root);
                                  sqrt(2 - sqrt(3))
          (%o3)                   -----------------
                                          2
          (%i4) L: makelist (root^i, i, 0, 4);
          (%o4) [1.0, 0.2588190451025207, 0.06698729810778066,
                                 0.01733758853025369, 0.004487298107780675]
          (%i5) m: pslq_integer_relation(%);
          (%o5)                 [- 1, 0, 16, 0, - 16]
          (%i6) makelist (x^i, i, 0, 4) . m;
                                       4        2
          (%o6)                 (- 16 x ) + 16 x  - 1
          (%i7) solve(%);
                       sqrt(sqrt(3) + 2)      sqrt(sqrt(3) + 2)
          (%o7) [x = - -----------------, x = -----------------,
                               2                      2
                                  sqrt(2 - sqrt(3))      sqrt(2 - sqrt(3))
                            x = - -----------------, x = -----------------]
                                          2                      2

 -- Function: pslq_integer_relation (<L>)

     Implements the PSLQ algorithm [1] to find integer relations between
     bigfloat numbers.

     For a given list <L> of floating point numbers,
     ‘pslq_integer_relation’ returns a list of integers <m> such that
     ‘<m> . <L> = 0’ (with absolute residual error less than
     ‘pslq_threshold’).

     [1] D.H.Bailey: Integer Relation Detection and Lattice Reduction.

     Example:

          (%i1) load ("pslq.mac");
          (%o1)                       pslq.mac
          (%i2) root: float (sin (%pi/12));
          (%o2)                  0.2588190451025207
          (%i3) L: makelist (root^i, i, 0, 4);
          (%o3) [1.0, 0.2588190451025207, 0.06698729810778066,
                                 0.01733758853025369, 0.004487298107780675]
          (%i4) m: pslq_integer_relation(%);
          (%o4)                 [- 1, 0, 16, 0, - 16]
          (%i5) m . L;
          (%o5)                - 2.359223927328458E-16
          (%i6) float (10^(2 - fpprec));
          (%o6)                        1.0E-14
          (%i7) is (abs (m . L) < 10^(2 - fpprec));
          (%o7)                         true

 -- Variable: pslq_precision
     Default value: ‘10^(fpprec - 2)’

     Maximum magnitude of some intermediate results in
     ‘pslq_integer_relation’.  The search fails if one of the
     intermediate results has elements larger than ‘pslq_precision’.

 -- Variable: pslq_threshold
     Default value: ‘10^(2 - fpprec)’

     Threshold for absolute residual error of integer relation found by
     ‘pslq_integer_relation’.

 -- Variable: pslq_depth
     Default value: ‘20 * <n>’

     Number of iterations of the PSLQ algorithm.

     The default value is 20 times <n>, where <n> is the length of the
     list of numbers supplied to ‘pslq_integer_relation’.

 -- Variable: pslq_status

     Indicates success or failure for an integer relation search by
     ‘pslq_integer_relation’.

     When ‘pslq_status’ is 1, it indicates an integer relation was
     found, and the absolute residual error is less than
     ‘pslq_threshold’.

     When ‘pslq_status’ is 2, it indicates an integer relation was not
     found because some intermediate results are larger than
     ‘pslq_precision’.

     When ‘pslq_status’ is 3, it indicates an integer relation was not
     found because the number of iterations ‘pslq_depth’ was reached.


File: maxima.info,  Node: Package pytranslate,  Next: Package quantum_computing,  Prev: Package pslq,  Up: Top

87 Package pytranslate
**********************

* Menu:

* Introduction to pytranslate::
* Functions in pytranslate::
* Extending pytranslate::


File: maxima.info,  Node: Introduction to pytranslate,  Next: Functions in pytranslate,  Up: Package pytranslate

87.1 Introduction to pytranslate
================================

‘pytranslate’ package provides Maxima to Python translation
functionality.  The package is experimental, and the specifications of
the functions in this package might change.  It was written as a Google
Summer of Code project by Lakshya A Agrawal (Undergraduate Student,
IIIT-Delhi) in 2019.  A detailed project report is available as a GitHub
Gist
(https://gist.github.com/LakshyAAAgrawal/33eee2d33c4788764087eef1fa67269e).

   The package needs to be loaded in a Maxima instance for use, by
executing ‘load("pytranslate");’
The statements are converted to python3 syntax.  The file pytranslate.py
must be imported for all translations to run, as shown in example.

   Example:
     (%i1) load ("pytranslate")$
     /* Define an example function to calculate factorial */
     (%i2) pytranslate(my_factorial(x) := if (x = 1 or x = 0) then 1
                       else x * my_factorial(x - 1));
     (%o2)
     def my_factorial(x, v = v):
         v = Stack({}, v)
         v.ins({"x" : x})
         return((1 if ((v["x"] == 1) or (v["x"] == 0)) \
                   else (v["x"] * my_factorial((v["x"] + (-1))))))
     m["my_factorial"] = my_factorial
     (%i3) my_factorial(5);
     (%o3)                          120
     >>> from pytranslate import *
     >>> def my_factorial(x, v = v):
     ...     v = Stack({}, v)
     ...     v.ins({"x" : x})
     ...     return((1 if ((v["x"] == 1) or (v["x"] == 0)) \
     ...     else (v["x"] * my_factorial((v["x"] + (-1))))))
     ...
     >>> my_factorial(5)
     120

   The Maxima to Python Translator works in two stages:
1.  Conversion of the internal Maxima representation to a defined
Intermediate Representation, henceforth referred as IR(mapping is
present in ‘share/pytranslate/maxima-to-ir.html’)
2.  The conversion of IR to Python.

   Supported Maxima forms:
1.  ‘Numbers’(including complex numbers)
2.  ‘Assignment operators’
3.  ‘Arithmetic operators’(+, -, *, ^, /, !)
4.  ‘Logical operators’(and, or, not)
5.  ‘Relational operators’(‘>’, ‘<’, ‘>=’, ‘<=’, ‘!=’, ‘==’)
6.  ‘Lists’
7.  ‘Arrays’
8.  ‘block’
9.  ‘Function’ and function calls
10.  ‘if’-else converted to Python conditionals
11.  ‘for’ loops
12.  ‘lambda’ form

87.1.1 Tests for pytranslate
----------------------------

The tests for ‘pytranslate’ are present at
‘share/pytranslate/rtest_pytranslate.mac’ and can be run by executing
‘batch(rtest_pytranslate, test);’


File: maxima.info,  Node: Functions in pytranslate,  Next: Extending pytranslate,  Prev: Introduction to pytranslate,  Up: Package pytranslate

87.2 Functions in pytranslate
=============================

 -- Function: pytranslate (<expr>, [print-ir])
     Translates the expression <expr> to equivalent python3 statements.
     Output is printed in the stdout.

     Example:
          (%i1) load ("pytranslate")$
          (%i2) pytranslate('(for i:8 step -1 unless i<3 do (print(i))));
          (%o2)
          v["i"] = 8
          while not((v["i"] < 3)):
              m["print"](v["i"])
              v["i"] = (v["i"] + -1)
          del v["i"]

     <expr> is evaluated, and the return value is used for translation.
     Hence, for statements like assignment, it might be useful to quote
     the statement:
          (%i1) load ("pytranslate")$
          (%i2) pytranslate(x:20);
          (%o2)
          20
          (%i3) pytranslate('(x:20));
          (%o3)
          v["x"] = 20

     Passing the optional parameter (<print-ir>) to ‘pytranslate’ as t,
     will print the internal IR representation of ‘expr’ and return the
     translated python3 code.

          (%i1) load("pytranslate");
          (%o1) pytranslate
          (%i2) pytranslate('(plot3d(lambda([x, y], x^2+y^(-1)), [x, 1, 10],
                             [y, 1, 10])), t);
          (body
           (funcall (element-array "m" (string "plot3d"))
                    (lambda
                        ((symbol "x") (symbol "y")
                         (op-no-bracket
                          =
                          (symbol "v")
                          (funcall (symbol "stack") (dictionary) (symbol "v"))))
                      (op +
                          (funcall (element-array (symbol "m") (string "pow"))
                                   (symbol "x") (num 2 0))
                          (funcall (element-array (symbol "m") (string "pow"))
                                   (symbol "y") (unary-op - (num 1 0)))))
                    (struct-list (string "x") (num 1 0) (num 10 0))
                    (struct-list (string "y") (num 1 0) (num 10 0))))
          (%o2)
          m["plot3d"](lambda x, y, v = Stack({}, v): (m["pow"](x, 2) + m["\
          pow"](y, (-1))), ["x", 1, 10], ["y", 1, 10])

 -- Function: show_form (<expr>)
     Displays the internal maxima form of ‘expr’
          (%i4) show_form(a^b);
          ((mexpt) $a $b)
          (%o4) a^b


File: maxima.info,  Node: Extending pytranslate,  Prev: Functions in pytranslate,  Up: Package pytranslate

87.3 Extending pytranslate
==========================

Working of pytranslate:
   • The entry point for pytranslate is the function ‘$pytranslate’
     defined in ‘share/pytranslate/pytranslate.lisp’.
   • ‘$pytranslate’ calls the function ‘maxima-to-ir’ with the Maxima
     expression as an argument(henceforth referred as ‘expr’).
   • ‘maxima-to-ir’ determines if ‘expr’ is atomic or non-atomic(lisp
     cons form).  If atomic, ‘atom-to-ir’ is called with ‘expr’ which
     returns the IR for the atomic expression.
     To define/modify translation for atomic expressions, make changes
     to the definition of ‘atom-to-ir’ in accordance with the IR.
   • If ‘expr’ is non-atomic, the function ‘cons-to-ir’ is called with
     ‘expr’ as an argument.
        • ‘cons-to-ir’ looks for ‘(caar expr)’ which specifies the type
          of ‘expr’, in hash-table <*maxima-direct-ir-map*> and if the
          type is found, then appends the retrieved IR with the result
          of lisp call ‘(mapcar #'maxima-to-ir (cdr expr))’, which
          applies maxima-to-ir function to all the elements present in
          the list.  Effectively, recursively generate IR for all the
          elements present in ‘expr’ and append them to the IR map for
          the type.
          Example:
               (%i9) show_form(a+b);
               ((MPLUS) $B $A)
               (%i10) pytranslate(a+b, t);
               (body (op + (element-array (symbol "v") (string "b")) \
               (element-array (symbol "v") (string "a"))))
               (%o10)
               (v["b"] + v["a"])
          Here, operator + with internal maxima representation,
          ‘(mplus)’ is present in <*maxima-direct-ir-map*> and mapped to
          ‘(op +)’ to which the result of generating IR for all other
          elements of the list (a b), i.e.  ‘(ELEMENT-ARRAY (SYMBOL "v")
          (STRING "b")) (ELEMENT-ARRAY (SYMBOL "v") (STRING "a"))’ is
          appended.

        • If ‘(caar expr)’ is not found in <*maxima-direct-ir-map*>,
          then ‘cons-to-ir’ looks for the type in
          <*maxima-special-ir-map*> which returns the function to handle
          the translation of the type of ‘expr’.  ‘cons-to-ir’ then
          calls the returned function with argument ‘expr’ as an
          argument.
          Example:
               (%i11) show_form(g(x) := x^2);
               ((mdefine simp) (($g) $x) ((mexpt) $x 2))
               (%i12) pytranslate(g(x):=x^2, t);
               (body
                (body
                 (func-def (symbol "g")
                           ((symbol "x") (op-no-bracket = (symbol "v") (symbol "v")))
                           (body-indented
                               (op-no-bracket = (symbol "v") (funcall (symbol "stack") \
                               (dictionary) (symbol "v")))
                               (obj-funcall (symbol "v") (symbol "ins") (dictionary \
                               ((string "x") (symbol "x"))))
                               (funcall (symbol "return")
                                   (funcall (element-array (symbol "f") (string "pow"))
                                        (element-array (symbol "v") (string "x"))
                                                 (num 2 0)))))
                 (op-no-bracket = (element-array (symbol "f") (string "g")) \
                 (symbol "g"))))
               (%o12)
               def g(x, v = v):
                   v = Stack({}, v)
                   v.ins({"x" : x})
                   return(f["pow"](v["x"], 2))
               f["g"] = g

          Here, ‘mdefine’, which is the type of ‘expr’ is present in
          <*maxima-special-ir-map*> which returns ‘func-def-to-ir’ as
          handler function, which is then called with ‘expr’ to generate
          the IR.
          To define/modify translation for a type, add an entry to
          <*maxima-direct-ir-map*> if only a part of the IR needs to be
          generated and the rest can be appended, otherwise, for
          complete handling of ‘expr’, add an entry to
          <*maxima-special-ir-map*> and define a function with the name
          defined in <*maxima-special-ir-map*> which returns the IR for
          the form.  The function naming convention for ir generators is
          (type)-to-ir, where type is the ‘(caar expr)’ for
          expression(‘mdefine -> func-def-to-ir’).  The function must
          return a valid IR for the specific type.
   • After the generation of IR, the function ‘ir-to-python’ is called
     with the generated ‘ir’ as an argument, which performs the codegen
     in a recursive manner.
        • ‘ir-to-python’ looks for lisp ‘(car ir)’ in the hash-table
          <*ir-python-direct-templates*>, which maps IR type to function
          handlers and calls the function returned with ‘ir’ as an
          argument.
   • To extend the IR of pytranslate, define a function with the naming
     convention (type)-to-python and add the name to
     <*ir-python-direct-templates*>.


File: maxima.info,  Node: Package quantum_computing,  Next: Package ratpow,  Prev: Package pytranslate,  Up: Top

88 Package quantum_computing
****************************

* Menu:

* Introduction to quantum_computing::
* Functions and Variables for Quantum_Computing::


File: maxima.info,  Node: Introduction to quantum_computing,  Next: Functions and Variables for Quantum_Computing,  Prev: Package quantum_computing,  Up: Package quantum_computing

88.1 Package quantum_computing
==============================

The ‘quantum_computing’ package provides several functions to simulate
quantum computing circuits.  The state of a system of <n> qubits is
represented by a list of 2^<n> complex numbers and an operator acting on
<m> qubits is represented by a 2^<m> by 2^<m> matrix.  A hash array
<qmatrix> is defined with 6 common one-qubit matrices: the identity, the
Pauli matrices, the Hadamard matrix and the phase matrix.

   The major disadvantage compared to a real quantum computer is very
slow computing times even with a few qubits.  An advantage is that,
unlike a quantum computer, in this simulator a quantum state can be
cloned using *note copylist::.

   This is an additional package that must be loaded with
‘load("quantum_computing")’ in order to use it.


File: maxima.info,  Node: Functions and Variables for Quantum_Computing,  Prev: Introduction to quantum_computing,  Up: Package quantum_computing

88.2 Functions and Variables for Quantum_Computing
==================================================

 -- Function: binlist
          binlist (<k>)
          binlist (<k>, <n>)

     ‘binlist’(<k>), where <k> must be a natural number, returns a list
     of binary digits 0 or 1 corresponding to the digits of <k> in
     binary representation.  ‘binlist’(<k>, <n>) does the same but
     returns a list of length <n>, with leading zeros as necessary.
     Notice that for the result to represent a possible state of <m>
     qubits, <n> should be equal to 2^<m> and <k> should be between 0
     and 2^<m>-1.

 -- Function: binlist2dec (<lst>)

     Given a list <lst> with <n> binary digits, it returns the decimal
     number it represents.

 -- Function: CNOT (<q>, <i>, <j>)

     Changes the value of the <j>'th qubit, in a state <q> of <m>
     qubits, when the value of the <i>'th qubit equals 1.  It modifies
     the list <q> and returns its modified value.

 -- Function: controlled (<U>, <q>, <c>, <i>)

     Applies a matrix <U>, acting on <m> qubits, on qubits <i> through
     <i>+<m>-1 of the state <q> of <n> qubits (<n> > <m>), when the
     value of the <c>'th qubit in <q> equals 1.  <i> should be an
     integer between 1 and <n>+1-<m> and <c> should be an integer
     between 1 and <n>, excluding the qubits to be modified (<i> through
     <i>+<m>-1).

     <U> can be one of the indices of the array of common matrices
     <qmatrix> (see ‘qmatrix’).  The state <q> is modified and shown in
     the output.

 -- Function: gate
          gate (<U>, <q>)
          gate (<U>, <q>, <i>)
          gate (<U>, <q>, <i1>, ..., <im>)

     <U> must be a matrix acting on states of <m> qubits; <q> a list
     corresponding to a state of <n> qubits (<n> >= <m>); <i> and the
     <m> numbers <i1>, ..., <im> must be different integers between 1
     and <n>.

     ‘gate’(<U>, <q>) applies matrix <U> to each qubit of <q>, when <m>
     equals 1, or to the first <m> qubits of <q> when <m> is bigger than
     1.

     ‘gate’(<U>, <q>, <i>) applies matrix <U> to the qubits <i> through
     <i>+<m>-1 of <q>.

     ‘gate’(<U>, <q>, <i1>, ..., <in>) applies matrix <U> to the in the
     positions <i1>, ..., <im>.

     <U> can be one of the indices of the array of common matrices
     <qmatrix> (see ‘qmatrix’).  The state <q> is modified and shown in
     the output.

 -- Function: gate_matrix
          gate_matrix (<U>, <n>)
          gate_matrix (<U>, <n>, <i1>, ..., <im>)

     <U> must be a 2 by 2 matrix or one of the indices of the array of
     common matrices <qmatrix> (see ‘qmatrix’).  ‘gate_matrix’(<U>, <n>)
     returns the matrix corresponding to the action of <U> on each qubit
     in a state of <n> qubits.

     ‘gate_matrix’ (<U>, <n>, <i1>, ..., <im>) returns the matrix
     corresponding to the action of <U> on qubits <i1>, ..., <im> of a
     state of <n> qubits, where <i1>, ..., <im> are different integers
     between 1 and <n>.

 -- Function: linsert (<e>, <lst>, <p>)

     Inserts the expression or list <e> into the list <lst> at position
     <p>.  The list can be empty and <p> must be an integer between 1
     and the length of <lst> plus 1.

 -- Function: lreplace (<e>, <lst>, <p>)

     If <e> is a list of length <n>, the elements in the positions <p>,
     <p>+1, ..., <p>+<n>-1 of the list <lst> are replaced by <e>, or the
     first elements of <e> if the end of <lst> is reached.  If <e> is an
     expression, the element in position <p> of list <lst> is replaced
     by that expression.  <p> must be an integer between 1 and the
     length of <lst>.

 -- Function: normalize (<q>)

     Returns the normalized version of a quantum state given as a list
     <q>.

 -- Function: qdisplay (<q>)

     Represents the state <q> of a system of <n> qubits as a linear
     combination of the computational states with <n> binary digits.  It
     returns an expression including strings and symbols.

 -- System variable: qmatrix

     This variable is a predefined hash array of two by two matrices
     with the standard matrices: identity, Pauli matrices, Hadamard
     matrix and the phase matrix.  The six possible indices are I, X, Y,
     Z, H, S. <qmatrix>[I] is the identity matrix, <qmatrix>[X] the
     Pauli x matrix, <qmatrix>[Y] the Pauli y matrix, <qmatrix>[Z] the
     Pauli z matrix, <qmatrix>[H] the Hadamard matrix and <qmatrix>[S]
     the phase matrix.

 -- Function: qmeasure
          qmeasure (<q>)
          qmeasure (<q>, <i1>, ..., <im>)

     Measures the value of one or more qubits in a system of <n> qubits
     with state <q>.  The <m> positive integers <i1>, ..., <im> are the
     positions of the qubits to be measured It requires 1 or more
     arguments.  The first argument must be the state q.  If the only
     argument given is <q>, all the n qubits will be measured.

     It returns a list with the values of the qubits measured (either 0
     or 1), in the same order they were requested or in ascending order
     if the only argument given was <q>.  It modifies the list <q>,
     reflecting the collapse of the quantum state after the measurement.

 -- Function: qubits
          qubits (<n>)
          qubits (<i1>, ..., <in>)

     ‘qubits’(<n>) returns a list representing the ground state of a
     system of <n> qubits.

     ‘qubits’(<i1>, ..., <in>) returns a list with representing the
     state of <n> qubits with values <i1>, ..., <in>.

 -- Function: qswap (<q>, <i>, <j>)

     Interchanges the states of qubits <i> and <j> in the state <q> of a
     system of several qubits.  It modifies the list <q> and returns its
     modified value.

 -- Function: Rx (<a>)

     Returns the 2 by two matrix (acting on one qubit) corresponding to
     a rotation of with an angle of <a> radians around the x axis.

 -- Function: Ry (<a>)

     Returns the 2 by two matrix (acting on one qubit) corresponding to
     a rotation of with an angle of <a> radians around the y axis.

 -- Function: Rz (<a>)

     Returns the 2 by two matrix (acting on one qubit) corresponding to
     a rotation of with an angle of <a> radians around the z axis.

 -- Function: tprod (<o1>, ..., <on>)

     Returns the tensor product of the <n> matrices or lists <o1>, ...,
     <on>.

 -- Function: toffoli (<q>, (<i>, (<j>, (<k>)

     Changes the value of the <k>'th qubit, in the state <q> of <n>
     qubits, if the values of the <i>'th anf <j>'th qubits are equal to
     1.  It modifies the list <q> and returns its new value.


File: maxima.info,  Node: Package ratpow,  Next: Package rk_adaptive,  Prev: Package quantum_computing,  Up: Top

89 Package ratpow
*****************

The package ‘ratpow’ provides functions that return the coefficients of
the numerator of a CRE polynomial in a given variable.

   For example,
   • ‘ratp_coeffs(5*x^7-3*x^2+4,x)’ returns ‘[[7,5],[2,-3],[0,4]]’,
     which omits zero terms;
   • ‘ratp_dense_coeffs(5*x^7-y*x^2+4,x)’ returns ‘[5,0,0,0,0,-y,0,4]’,
     which includes zero terms;
   • ‘ratp_dense_coeffs((x^4-y^4)/(x-y),x)’ returns ‘[1,y,y^2,y^3]’,
     because CRE simplifies the expression to ‘x^3+y*x^2+y^2*x+y^3’;
   • ‘ratp_dense_coeffs(x+sqrt(x),x)’ returns ‘[1,sqrt(x)]’ while
     ‘ratp_dense_coeffs(x+sqrt(x),sqrt(x))’ returns ‘[1,x]’: in CRE
     form, ‘x’ and ‘sqrt(x)’ are treated as independent variables.

   The returned coefficients are in CRE form except for numbers.

   For the list of vars of a CRE polynomial, use ‘showratvars’.  For the
denominator of a CRE polynomial, use ‘ratdenom’.

   For information about CREs see also ‘rat’, ‘ratdisrep’ and *note
showratvars::.
* Menu:

* Functions and Variables for ratpow::


File: maxima.info,  Node: Functions and Variables for ratpow,  Up: Package ratpow

89.1 Functions and Variables for ratpow
=======================================

 -- Function: ratp_hipow (<expr>, <x>)

     Returns the highest power of <x> in ‘ratnumer(expr)’

          (%i1) load("ratpow")$
          (%i2) ratp_hipow( x^(5/2) + x^2 , x);
          (%o2)                           2
          (%i3) ratp_hipow( x^(5/2) + x^2 , sqrt(x));
          (%o3)                           5

 -- Function: ratp_lopow (<expr>, <x>)

     Returns the lowest power of <x> in ‘ratnumer(expr)’

          (%i1) load("ratpow")$
          (%i2) ratp_lopow( x^5 + x^2 , x);
          (%o2)                           2

     The following example returns 0 since ‘1’ equals ‘x^0’:
          (%i1) load("ratpow")$
          (%i2) ratp_lopow( x^5 + x^2 + 1, x);
          (%o2)                           0

     The CRE form of the following equation contains ‘sqrt(x)’ and ‘x’.
     Since they are interpreted as independent variables, ‘ratp_lopow’
     returns ‘0’:
          (%i1) load("ratpow")$
          (%i2) g:sqrt(x)^5 + sqrt(x)^2;
                                       5/2
          (%o2)                       x    + x
          (%i3) showratvars(g);
                                        1/2
          (%o3)                       [x   , x]
          (%i4) ratp_lopow( g, x);
          (%o4)                           0
          (%i5) ratp_lopow( g, sqrt(x));
          (%o5)                           0

 -- Function: ratp_coeffs (<expr>, <x>)

     Returns the powers and coefficients of <x> in ‘ratnumer(expr)’ as a
     list of length-2 lists; returned coefficients are in CRE form
     except for numbers.

     ‘ratnumer(expr)’.
          (%i1) load("ratpow")$
          (%i2) ratp_coeffs( 4*x^3 + x + sqrt(x), x);
          (%o2)/R/         [[3, 4], [1, 1], [0, sqrt(x)]]

 -- Function: ratp_dense_coeffs (<expr>, <x>)

     Returns the coefficients of powers of <x> in ‘ratnumer(expr)’ from
     highest to lowest; returned coefficients are in CRE form except for
     numbers.

          (%i1) load("ratpow")$
          (%i2) ratp_dense_coeffs( 4*x^3 + x + sqrt(x), x);
          (%o2)/R/               [4, 0, 1, sqrt(x)]


File: maxima.info,  Node: Package rk_adaptive,  Next: Package romberg,  Prev: Package ratpow,  Up: Top

90 Package rk_adaptive
**********************

* Menu:

* Introduction to rk_adaptive::
* Functions and Variables for rk_adaptive::


File: maxima.info,  Node: Introduction to rk_adaptive,  Next: Functions and Variables for rk_adaptive,  Prev: Package rk_adaptive,  Up: Package rk_adaptive

90.1 Introduction to rk_adaptive
================================

‘rk_adaptive’ employs the runge-kutta method for numberically solving
differential equations, but other than ‘rk’ it tries to find a sensible
step size, which reduces both runtime and amount of data produced.


File: maxima.info,  Node: Functions and Variables for rk_adaptive,  Prev: Introduction to rk_adaptive,  Up: Package rk_adaptive

90.2 Functions and Variables for rk_adaptive
============================================

 -- Function: rk_adaptive (<expr>, <vars>, <vars_initval>, <var>,
     <startval>, <endval>, <params1...>)

     Tries to solve the ODE whose derivates are defined by ‘expr’ to the
     variables ‘vars’, starting at their initial values ‘vars_initval’.
     The independent variable (in physics: normally time) is ‘var’,
     being stepped from ‘startval’ to ‘endval’.

     Sometimes it speeds up the calculation to use a floating-point
     number as ‘startval’, as using floars will prevent all results from
     becoming endless rational numbers.

     The following optional parameters are accepted:

        • ‘maxstep=num’: The maximum step size to be used.
        • ‘minstep=num’: The minimum step size to be used.
        • ‘timestep_initial=num’: The initial guess for the optimum time
          step to start with.
        • ‘maxabserr=num’: The maximum absolute error of the resulting
          curves.
        • ‘maxrelerr=num’: The maximum relative error of the resulting
          curves as a fallback for variables with big values for which
          ‘maxabserr’ might be too sensitive.

     See also *note rk::.

     Example:
          (%i1) pnts:rk_adaptive(-1/10*x,x,1,t,0,100)  $


File: maxima.info,  Node: Package romberg,  Next: Package simplex,  Prev: Package rk_adaptive,  Up: Top

91 Package romberg
******************

* Menu:

* Functions and Variables for romberg::


File: maxima.info,  Node: Functions and Variables for romberg,  Prev: Package romberg,  Up: Package romberg

91.1 Functions and Variables for romberg
========================================

 -- Function: romberg
          romberg (<expr>, <x>, <a>, <b>)
          romberg (<F>, <a>, <b>)

     Computes a numerical integration by Romberg's method.

     ‘romberg(<expr>, <x>, <a>, <b>)’ returns an estimate of the
     integral ‘integrate(<expr>, <x>, <a>, <b>)’.  <expr> must be an
     expression which evaluates to a floating point value when <x> is
     bound to a floating point value.

     ‘romberg(<F>, <a>, <b>)’ returns an estimate of the integral
     ‘integrate(<F>(x), x, <a>, <b>)’ where ‘x’ represents the unnamed,
     sole argument of <F>; the actual argument is not named ‘x’.  <F>
     must be a Maxima or Lisp function which returns a floating point
     value when the argument is a floating point value.  <F> may name a
     translated or compiled Maxima function.

     The accuracy of ‘romberg’ is governed by the global variables
     ‘rombergabs’ and ‘rombergtol’.  ‘romberg’ terminates successfully
     when the absolute difference between successive approximations is
     less than ‘rombergabs’, or the relative difference in successive
     approximations is less than ‘rombergtol’.  Thus when ‘rombergabs’
     is 0.0 (the default) only the relative error test has any effect on
     ‘romberg’.

     ‘romberg’ halves the stepsize at most ‘rombergit’ times before it
     gives up; the maximum number of function evaluations is therefore
     ‘2^rombergit’.  If the error criterion established by ‘rombergabs’
     and ‘rombergtol’ is not satisfied, ‘romberg’ prints an error
     message.  ‘romberg’ always makes at least ‘rombergmin’ iterations;
     this is a heuristic intended to prevent spurious termination when
     the integrand is oscillatory.

     ‘romberg’ repeatedly evaluates the integrand after binding the
     variable of integration to a specific value (and not before).  This
     evaluation policy makes it possible to nest calls to ‘romberg’, to
     compute multidimensional integrals.  However, the error
     calculations do not take the errors of nested integrations into
     account, so errors may be underestimated.  Also, methods devised
     especially for multidimensional problems may yield the same
     accuracy with fewer function evaluations.

     See also ‘Introduction to QUADPACK’, a collection of numerical
     integration functions.

     Examples:

     A 1-dimensional integration.
          (%i1) f(x) := 1/((x - 1)^2 + 1/100) + 1/((x - 2)^2 + 1/1000)
                        + 1/((x - 3)^2 + 1/200);
                              1                 1                1
          (%o1) f(x) := -------------- + --------------- + --------------
                               2    1           2    1            2    1
                        (x - 1)  + ---   (x - 2)  + ----   (x - 3)  + ---
                                   100              1000              200
          (%i2) rombergtol : 1e-6;
          (%o2)                 9.999999999999999e-7
          (%i3) rombergit : 15;
          (%o3)                          15
          (%i4) estimate : romberg (f(x), x, -5, 5);
          (%o4)                   173.6730736617464
          (%i5) exact : integrate (f(x), x, -5, 5);
                  3/2          3/2      3/2          3/2
          (%o5) 10    atan(7 10   ) + 10    atan(3 10   )
                3/2         9/2       3/2         5/2
           + 5 2    atan(5 2   ) + 5 2    atan(5 2   ) + 10 atan(60)
           + 10 atan(40)
          (%i6) abs (estimate - exact) / exact, numer;
          (%o6)                 7.552722451569877e-11

     A 2-dimensional integration, implemented by nested calls to
     ‘romberg’.
          (%i1) g(x, y) := x*y / (x + y);
                                              x y
          (%o1)                   g(x, y) := -----
                                             x + y
          (%i2) rombergtol : 1e-6;
          (%o2)                 9.999999999999999e-7
          (%i3) estimate : romberg (romberg (g(x, y), y, 0, x/2), x, 1, 3);
          (%o3)                  0.8193023962835647
          (%i4) assume (x > 0);
          (%o4)                        [x > 0]
          (%i5) integrate (integrate (g(x, y), y, 0, x/2), x, 1, 3);
                                                     3
                                               2 log(-) - 1
                              9                      2        9
          (%o5)      (- 9 log(-)) + 9 log(3) + ------------ + -
                              2                     6         2
          (%i6) exact : radcan (%);
                              26 log(3) - 26 log(2) - 13
          (%o6)             - --------------------------
                                          3
          (%i7) abs (estimate - exact) / exact, numer;
          (%o7)                 1.371197987185102e-10

 -- Option variable: rombergabs
     Default value: 0.0

     The accuracy of ‘romberg’ is governed by the global variables
     ‘rombergabs’ and ‘rombergtol’.  ‘romberg’ terminates successfully
     when the absolute difference between successive approximations is
     less than ‘rombergabs’, or the relative difference in successive
     approximations is less than ‘rombergtol’.  Thus when ‘rombergabs’
     is 0.0 (the default) only the relative error test has any effect on
     ‘romberg’.

     See also ‘rombergit’ and ‘rombergmin’.

 -- Option variable: rombergit
     Default value: 11

     ‘romberg’ halves the stepsize at most ‘rombergit’ times before it
     gives up; the maximum number of function evaluations is therefore
     ‘2^rombergit’.  ‘romberg’ always makes at least ‘rombergmin’
     iterations; this is a heuristic intended to prevent spurious
     termination when the integrand is oscillatory.

     See also ‘rombergabs’ and ‘rombergtol’.

 -- Option variable: rombergmin
     Default value: 0

     ‘romberg’ always makes at least ‘rombergmin’ iterations; this is a
     heuristic intended to prevent spurious termination when the
     integrand is oscillatory.

     See also ‘rombergit’, ‘rombergabs’, and ‘rombergtol’.

 -- Option variable: rombergtol
     Default value: 1e-4

     The accuracy of ‘romberg’ is governed by the global variables
     ‘rombergabs’ and ‘rombergtol’.  ‘romberg’ terminates successfully
     when the absolute difference between successive approximations is
     less than ‘rombergabs’, or the relative difference in successive
     approximations is less than ‘rombergtol’.  Thus when ‘rombergabs’
     is 0.0 (the default) only the relative error test has any effect on
     ‘romberg’.

     See also ‘rombergit’ and ‘rombergmin’.


File: maxima.info,  Node: Package simplex,  Next: Package simplification,  Prev: Package romberg,  Up: Top

92 Package simplex
******************

* Menu:

* Introduction to simplex::
* Functions and Variables for simplex::


File: maxima.info,  Node: Introduction to simplex,  Next: Functions and Variables for simplex,  Prev: Package simplex,  Up: Package simplex

92.1 Introduction to simplex
============================

‘simplex’ is a package for linear optimization using the simplex
algorithm.

   Example:

     (%i1) load("simplex")$
     (%i2) minimize_lp(x+y, [3*x+2*y>2, x+4*y>3]);
                       9        7       1
     (%o2)            [--, [y = --, x = -]]
                       10       10      5

92.1.1 Tests for simplex
------------------------

There are some tests in the directory ‘share/simplex/Tests’.

92.1.1.1 klee_minty
...................

The function ‘klee_minty’ produces input for ‘linear_program’, for which
exponential time for solving is required without scaling.

   Example:

     load("klee_minty")$
     apply(linear_program, klee_minty(6));

   A better approach:

     epsilon_sx : 0$
     scale_sx : true$
     apply(linear_program, klee_minty(10));

92.1.1.2 NETLIB
...............

Some smaller problems from netlib (<https://www.netlib.org/lp/data/>)
test suite are converted to a format, readable by Maxima.  Problems are
‘adlittle’, ‘afiro’, ‘kb2’, ‘sc50a’ and ‘share2b’.  Each problem has
three input files in CSV format for matrix <A> and vectors <b> and <c>.

   Example:

     A : read_matrix("adlittle_A.csv", 'csv)$
     b : read_list("adlittle_b.csv", 'csv)$
     c : read_list("adlittle_c.csv", 'csv)$
     linear_program(A, b, c)$
     %[2];
     => 225494.9631623802

   Results:

     PROBLEM        MINIMUM                  SCALING
     adlittle       +2.2549496316E+05        false
     afiro          -4.6475314286E+02        false
     kb2            -1.7499001299E+03        true
     sc50a          -6.4575077059E+01        false
     share2b        -4.1573518187E+02        false

   The Netlib website <https://www.netlib.org/lp/data/readme> lists the
values as

     PROBLEM        MINIMUM
     adlittle       +2.2549496316E+05
     afiro          -4.6475314286E+02
     kb2            -1.7499001299E+03
     sc50a          -6.4575077059E+01
     share2b        -4.1573224074E+02


File: maxima.info,  Node: Functions and Variables for simplex,  Prev: Introduction to simplex,  Up: Package simplex

92.2 Functions and Variables for simplex
========================================

 -- Option variable: epsilon_lp
     Default value: ‘10^-8’

     Epsilon used for numerical computations in ‘linear_program’; it is
     set to 0 in ‘linear_program’ when all inputs are rational.

     Example:

          (%i1) load("simplex")$

          (%i2) minimize_lp(-x, [1e-9*x + y <= 1], [x,y]);
          Warning: linear_program(A,b,c): non-rat inputs found, epsilon_lp= 1.0e-8
          Warning: Solution may be incorrect.
          (%o2)                        Problem not bounded!
          (%i3) minimize_lp(-x, [10^-9*x + y <= 1], [x,y]);
          (%o3)               [- 1000000000, [y = 0, x = 1000000000]]
          (%i4) minimize_lp(-x, [1e-9*x + y <= 1], [x,y]), epsilon_lp=0;
          (%o4)     [- 9.999999999999999e+8, [y = 0, x = 9.999999999999999e+8]]

     See also: ‘linear_program’, ‘ratnump’.

 -- Function: linear_program (<A>, <b>, <c>)

     ‘linear_program’ is an implementation of the simplex algorithm.
     ‘linear_program(A, b, c)’ computes a vector <x> for which ‘c.x’ is
     minimum possible among vectors for which ‘A.x = b’ and ‘x >= 0’.
     Argument <A> is a matrix and arguments <b> and <c> are lists.

     ‘linear_program’ returns a list which contains the minimizing
     vector <x> and the minimum value ‘c.x’.  If the problem is not
     bounded, it returns "Problem not bounded!"  and if the problem is
     not feasible, it returns "Problem not feasible!".

     To use this function first load the ‘simplex’ package with
     ‘load("simplex");’.

     Example:

          (%i2) A: matrix([1,1,-1,0], [2,-3,0,-1], [4,-5,0,0])$
          (%i3) b: [1,1,6]$
          (%i4) c: [1,-2,0,0]$
          (%i5) linear_program(A, b, c);
                             13     19        3
          (%o5)            [[--, 4, --, 0], - -]
                             2      2         2

     See also: ‘minimize_lp’, ‘scale_lp’, and ‘epsilon_lp’.

 -- Function: maximize_lp (<obj>, <cond>, [<pos>])

     Maximizes linear objective function <obj> subject to some linear
     constraints <cond>.  See ‘minimize_lp’ for detailed description of
     arguments and return value.

     See also: ‘minimize_lp’.

 -- Function: minimize_lp (<obj>, <cond>, [<pos>])

     Minimizes a linear objective function <obj> subject to some linear
     constraints <cond>.  <cond> a list of linear equations or
     inequalities.  In strict inequalities ‘>’ is replaced by ‘>=’ and
     ‘<’ by ‘<=’.  The optional argument <pos> is a list of decision
     variables which are assumed to be positive.

     If the minimum exists, ‘minimize_lp’ returns a list which contains
     the minimum value of the objective function and a list of decision
     variable values for which the minimum is attained.  If the problem
     is not bounded, ‘minimize_lp’ returns "Problem not bounded!"  and
     if the problem is not feasible, it returns "Problem not feasible!".

     The decision variables are not assumed to be non-negative by
     default.  If all decision variables are non-negative, set
     ‘nonnegative_lp’ to ‘true’ or include ‘all’ in the optional
     argument <pos>.  If only some of decision variables are positive,
     list them in the optional argument <pos> (note that this is more
     efficient than adding constraints).

     ‘minimize_lp’ uses the simplex algorithm which is implemented in
     maxima ‘linear_program’ function.

     To use this function first load the ‘simplex’ package with
     ‘load("simplex");’.

     Examples:

          (%i1) minimize_lp(x+y, [3*x+y=0, x+2*y>2]);
                                4       6        2
          (%o1)                [-, [y = -, x = - -]]
                                5       5        5
          (%i2) minimize_lp(x+y, [3*x+y>0, x+2*y>2]), nonnegative_lp=true;
          (%o2)                [1, [y = 1, x = 0]]
          (%i3) minimize_lp(x+y, [3*x+y>0, x+2*y>2], all);
          (%o3)                         [1, [y = 1, x = 0]]
          (%i4) minimize_lp(x+y, [3*x+y=0, x+2*y>2]), nonnegative_lp=true;
          (%o4)                Problem not feasible!
          (%i5) minimize_lp(x+y, [3*x+y>0]);
          (%o5)                Problem not bounded!

     There is also a limited ability to solve linear programs with
     symbolic constants.

          (%i1) declare(c,constant)$
          (%i2) maximize_lp(x+y, [y<=-x/c+3, y<=-x+4], [x, y]), epsilon_lp=0;
          Is (c-1)*c positive, negative or zero?
          p;
          Is c*(2*c-1) positive, negative or zero?
          p;
          Is c positive or negative?
          p;
          Is c-1 positive, negative or zero?
          p;
          Is 2*c-1 positive, negative or zero?
          p;
          Is 3*c-4 positive, negative or zero?
          p;
                                           1                1
          (%o2)                 [4, [x = -----, y = 3 - ---------]]
                                             1               1
                                         1 - -          (1 - -) c
                                             c               c

          (%i1) (assume(c>4/3), declare(c,constant))$
          (%i2) maximize_lp(x+y, [y<=-x/c+3, y<=-x+4], [x, y]), epsilon_lp=0;
                                           1                1
          (%o2)                 [4, [x = -----, y = 3 - ---------]]
                                             1               1
                                         1 - -          (1 - -) c
                                             c               c

     See also: ‘maximize_lp’, ‘nonnegative_lp’, ‘epsilon_lp’.

 -- Option variable: nonnegative_lp
 -- Option variable: nonegative_lp
     Default value: ‘false’

     If ‘nonnegative_lp’ is true all decision variables to ‘minimize_lp’
     and ‘maximize_lp’ are assumed to be non-negative.  ‘nonegative_lp’
     is a deprecated alias.

     See also: ‘minimize_lp’.

 -- Option variable: scale_lp
     Default value: ‘false’

     When ‘scale_lp’ is ‘true’, ‘linear_program’ scales its input so
     that the maximum absolute value in each row or column is 1.

 -- Variable: pivot_count_sx

     After ‘linear_program’ returns, ‘pivot_count_sx’ is the number of
     pivots in last computation.

 -- Variable: pivot_max_sx

     ‘pivot_max_sx’ is the maximum number of pivots allowed by
     ‘linear_program’.


File: maxima.info,  Node: Package simplification,  Next: Package solve_rec,  Prev: Package simplex,  Up: Top

93 Package simplification
*************************

* Menu:

* Introduction to simplification::
* Package absimp::
* Package facexp::
* Package functs::
* Package ineq::
* Package rducon::
* Package scifac::


File: maxima.info,  Node: Introduction to simplification,  Next: Package absimp,  Prev: Package simplification,  Up: Package simplification

93.1 Introduction to simplification
===================================

The directory ‘maxima/share/simplification’ contains several scripts
which implement simplification rules and functions, and also some
functions not related to simplification.


File: maxima.info,  Node: Package absimp,  Next: Package facexp,  Prev: Introduction to simplification,  Up: Package simplification

93.2 Package absimp
===================

The ‘absimp’ package contains pattern-matching rules that extend the
built-in simplification rules for the ‘abs’ and ‘signum’ functions.
‘absimp’ respects relations established with the built-in ‘assume’
function and by declarations such as ‘mode_declare (m, even, n, odd)’
for even or odd integers.

   ‘absimp’ defines ‘unitramp’ and ‘unitstep’ functions in terms of
‘abs’ and ‘signum’.

   ‘load ("absimp")’ loads this package.  ‘demo ("absimp")’ shows a
demonstration of this package.

   Examples:

     (%i1) load ("absimp")$
     (%i2) (abs (x))^2;
                                     2
     (%o2)                          x
     (%i3) diff (abs (x), x);
                                    x
     (%o3)                        ------
                                  abs(x)
     (%i4) cosh (abs (x));
     (%o4)                        cosh(x)


File: maxima.info,  Node: Package facexp,  Next: Package functs,  Prev: Package absimp,  Up: Package simplification

93.3 Package facexp
===================

The ‘facexp’ package contains several related functions that provide the
user with the ability to structure expressions by controlled expansion.
This capability is especially useful when the expression contains
variables that have physical meaning, because it is often true that the
most economical form of such an expression can be obtained by fully
expanding the expression with respect to those variables, and then
factoring their coefficients.  While it is true that this procedure is
not difficult to carry out using standard Maxima functions, additional
fine-tuning may also be desirable, and these finishing touches can be
more difficult to apply.

   The function ‘facsum’ and its related forms provide a convenient
means for controlling the structure of expressions in this way.  Another
function, ‘collectterms’, can be used to add two or more expressions
that have already been simplified to this form, without resimplifying
the whole expression again.  This function may be useful when the
expressions are very large.

   ‘load ("facexp")’ loads this package.  ‘demo ("facexp")’ shows a
demonstration of this package.

 -- Function: facsum (<expr>, <arg_1>, ..., <arg_n>)
     Returns a form of <expr> which depends on the arguments <arg_1>,
     ..., <arg_n>.  The arguments can be any form suitable for
     ‘ratvars’, or they can be lists of such forms.  If the arguments
     are not lists, then the form returned is fully expanded with
     respect to the arguments, and the coefficients of the arguments are
     factored.  These coefficients are free of the arguments, except
     perhaps in a non-rational sense.

     If any of the arguments are lists, then all such lists are combined
     into a single list, and instead of calling ‘factor’ on the
     coefficients of the arguments, ‘facsum’ calls itself on these
     coefficients, using this newly constructed single list as the new
     argument list for this recursive call.  This process can be
     repeated to arbitrary depth by nesting the desired elements in
     lists.

     It is possible that one may wish to ‘facsum’ with respect to more
     complicated subexpressions, such as ‘log (x + y)’.  Such arguments
     are also permissible.

     Occasionally the user may wish to obtain any of the above forms for
     expressions which are specified only by their leading operators.
     For example, one may wish to ‘facsum’ with respect to all ‘log’'s.
     In this situation, one may include among the arguments either the
     specific ‘log’'s which are to be treated in this way, or
     alternatively, either the expression ‘operator (log)’ or ‘'operator
     (log)’.  If one wished to ‘facsum’ the expression <expr> with
     respect to the operators <op_1>, ..., <op_n>, one would evaluate
     ‘facsum (<expr>, operator (<op_1>, ..., <op_n>))’.  The ‘operator’
     form may also appear inside list arguments.

     In addition, the setting of the switches ‘facsum_combine’ and
     ‘nextlayerfactor’ may affect the result of ‘facsum’.

 -- Global variable: nextlayerfactor
     Default value: ‘false’

     When ‘nextlayerfactor’ is ‘true’, recursive calls of ‘facsum’ are
     applied to the factors of the factored form of the coefficients of
     the arguments.

     When ‘false’, ‘facsum’ is applied to each coefficient as a whole
     whenever recursive calls to ‘facsum’ occur.

     Inclusion of the atom ‘nextlayerfactor’ in the argument list of
     ‘facsum’ has the effect of ‘nextlayerfactor: true’, but for the
     next level of the expression only.  Since ‘nextlayerfactor’ is
     always bound to either ‘true’ or ‘false’, it must be presented
     single-quoted whenever it appears in the argument list of ‘facsum’.

 -- Global variable: facsum_combine
     Default value: ‘true’

     ‘facsum_combine’ controls the form of the final result returned by
     ‘facsum’ when its argument is a quotient of polynomials.  If
     ‘facsum_combine’ is ‘false’ then the form will be returned as a
     fully expanded sum as described above, but if ‘true’, then the
     expression returned is a ratio of polynomials, with each polynomial
     in the form described above.

     The ‘true’ setting of this switch is useful when one wants to
     ‘facsum’ both the numerator and denominator of a rational
     expression, but does not want the denominator to be multiplied
     through the terms of the numerator.

 -- Function: factorfacsum (<expr>, <arg_1>, ... <arg_n>)
     Returns a form of <expr> which is obtained by calling ‘facsum’ on
     the factors of <expr> with <arg_1>, ...  <arg_n> as arguments.  If
     any of the factors of <expr> is raised to a power, both the factor
     and the exponent will be processed in this way.

 -- Function: collectterms (<expr>, <arg_1>, ..., <arg_n>)

     Collects all terms that contain <arg_1> ...  <arg_n>.  If several
     expressions have been simplified with the following functions
     ‘facsum’, ‘factorfacsum’, ‘factenexpand’, ‘facexpten’ or
     ‘factorfacexpten’, and they are to be added together, it may be
     desirable to combine them using the function ‘collecterms’.
     ‘collecterms’ can take as arguments all of the arguments that can
     be given to these other associated functions with the exception of
     ‘nextlayerfactor’, which has no effect on ‘collectterms’.  The
     advantage of ‘collectterms’ is that it returns a form similar to
     ‘facsum’, but since it is adding forms that have already been
     processed by ‘facsum’, it does not need to repeat that effort.
     This capability is especially useful when the expressions to be
     summed are very large.

     See also *note factor::.

     Example:

          (%i1) (exp(x)+2)*x+exp(x);
                                       x          x
          (%o1)                   x (%e  + 2) + %e
          (%i2) collectterms(expand(%),exp(x));
                                            x
          (%o2)                   (x + 1) %e  + 2 x


File: maxima.info,  Node: Package functs,  Next: Package ineq,  Prev: Package facexp,  Up: Package simplification

93.4 Package functs
===================

 -- Function: rempart (<expr>, <n>)
     Removes part <n> from the expression <expr>.

     If <n> is a list of the form ‘[<l>, <m>]’ then parts <l> thru <m>
     are removed.

     To use this function write first ‘load("functs")’.

 -- Function: wronskian ([<f_1>, ..., <f_n>], <x>)
     Returns the Wronskian matrix of the list of expressions [<f_1>,
     ..., <f_n>] in the variable <x>.  The determinant of the Wronskian
     matrix is the Wronskian determinant of the list of expressions.

     To use ‘wronskian’, first ‘load("functs")’.  Example:

          (%i1) load ("functs")$
          (%i2) wronskian([f(x), g(x)],x);
                              [   f(x)       g(x)    ]
                              [                      ]
          (%o2)               [ d          d         ]
                              [ -- (f(x))  -- (g(x)) ]
                              [ dx         dx        ]

 -- Function: tracematrix (<M>)
     Returns the trace (sum of the diagonal elements) of matrix <M>.

     To use this function write first ‘load("functs")’.

 -- Function: rational (<z>)
     Multiplies numerator and denominator of <z> by the complex
     conjugate of denominator, thus rationalizing the denominator.
     Returns canonical rational expression (CRE) form if given one, else
     returns general form.

     To use this function write first ‘load("functs")’.

 -- Function: nonzeroandfreeof (<x>, <expr>)
     Returns ‘true’ if <expr> is nonzero and ‘freeof (<x>, <expr>)’
     returns ‘true’.  Returns ‘false’ otherwise.

     To use this function write first ‘load("functs")’.

 -- Function: linear (<expr>, <x>)
     When <expr> is an expression of the form ‘<a>*<x> + <b>’ where <a>
     is nonzero, and <a> and <b> are free of <x>, ‘linear’ returns a
     list of three equations, one for each of the three formal variables
     <b>, <a>, and <x>.  Otherwise, ‘linear’ returns ‘false’.

     ‘load("antid")’ loads this function.

     Example:

          (%i1) load ("antid");
          (%o1)  /maxima/share/integration/antid.mac
          (%i2) linear ((1 - w)*(1 - x)*z, z);
          (%o2) [bargumentb = 0, aargumenta = (w - 1) x - w + 1,
                                                            xargumentx = z]
          (%i3) linear (cos(u - v) + cos(u + v), u);
          (%o3)                         false

 -- Function: gcdivide (<p>, <q>)

     When the option variable ‘takegcd’ is ‘true’ which is the default,
     ‘gcdivide’ divides the polynomials <p> and <q> by their greatest
     common divisor and returns the ratio of the results.  ‘gcdivde’
     calls the function ‘ezgcd’ to divide the polynomials by the
     greatest common divisor.

     When ‘takegcd’ is ‘false’, ‘gcdivide’ returns the ratio ‘<p>/<q>’.

     To use this function write first ‘load("functs")’.

     See also ‘ezgcd’, ‘gcd’, ‘gcdex’, and *note poly_gcd::.

     Example:

          (%i1) load("functs")$

          (%i2) p1:6*x^3+19*x^2+19*x+6;
                                  3       2
          (%o2)                6 x  + 19 x  + 19 x + 6
          (%i3) p2:6*x^5+13*x^4+12*x^3+13*x^2+6*x;
                            5       4       3       2
          (%o3)          6 x  + 13 x  + 12 x  + 13 x  + 6 x
          (%i4) gcdivide(p1, p2);
                                       x + 1
          (%o4)                        ------
                                        3
                                       x  + x
          (%i5) takegcd:false;
          (%o5)                         false
          (%i6) gcdivide(p1, p2);
                                 3       2
                              6 x  + 19 x  + 19 x + 6
          (%o6)          ----------------------------------
                            5       4       3       2
                         6 x  + 13 x  + 12 x  + 13 x  + 6 x
          (%i7) ratsimp(%);
                                       x + 1
          (%o7)                        ------
                                        3
                                       x  + x

 -- Function: arithmetic (<a>, <d>, <n>)
     Returns the <n>-th term of the arithmetic series ‘<a>, <a> + <d>,
     <a> + 2*<d>, ..., <a> + (<n> - 1)*<d>’.

     To use this function write first ‘load("functs")’.

 -- Function: geometric (<a>, <r>, <n>)
     Returns the <n>-th term of the geometric series ‘<a>, <a>*<r>,
     <a>*<r>^2, ..., <a>*<r>^(<n> - 1)’.

     To use this function write first ‘load("functs")’.

 -- Function: harmonic (<a>, <b>, <c>, <n>)
     Returns the <n>-th term of the harmonic series ‘<a>/<b>, <a>/(<b> +
     <c>), <a>/(<b> + 2*<c>), ..., <a>/(<b> + (<n> - 1)*<c>)’.

     To use this function write first ‘load("functs")’.

 -- Function: arithsum (<a>, <d>, <n>)
     Returns the sum of the arithmetic series from 1 to <n>.

     To use this function write first ‘load("functs")’.

 -- Function: geosum (<a>, <r>, <n>)
     Returns the sum of the geometric series from 1 to <n>.  If <n> is
     infinity (‘inf’) then a sum is finite only if the absolute value of
     <r> is less than 1.

     To use this function write first ‘load("functs")’.

 -- Function: gaussprob (<x>)
     Returns the Gaussian probability function ‘%e^(-<x>^2/2) /
     sqrt(2*%pi)’.

     To use this function write first ‘load("functs")’.

 -- Function: gd (<x>)
     Returns the Gudermannian function ‘2*atan(%e^x)-%pi/2’.

     To use this function write first ‘load("functs")’.

 -- Function: agd (<x>)
     Returns the inverse Gudermannian function ‘log (tan (%pi/4 +
     x/2))’.

     To use this function write first ‘load("functs")’.

 -- Function: vers (<x>)
     Returns the versed sine ‘1 - cos (x)’.

     To use this function write first ‘load("functs")’.

 -- Function: covers (<x>)
     Returns the coversed sine ‘1 - sin (<x>)’.

     To use this function write first ‘load("functs")’.

 -- Function: exsec (<x>)
     Returns the exsecant ‘sec (<x>) - 1’.

     To use this function write first ‘load("functs")’.

 -- Function: hav (<x>)
     Returns the haversine ‘(1 - cos(x))/2’.

     To use this function write first ‘load("functs")’.

 -- Function: combination (<n>, <r>)
     Returns the number of combinations of <n> objects taken <r> at a
     time.

     To use this function write first ‘load("functs")’.

 -- Function: permutation (<n>, <r>)
     Returns the number of permutations of <r> objects selected from a
     set of <n> objects.

     To use this function write first ‘load("functs")’.


File: maxima.info,  Node: Package ineq,  Next: Package rducon,  Prev: Package functs,  Up: Package simplification

93.5 Package ineq
=================

The ‘ineq’ package contains simplification rules for inequalities.

   Example session:

     (%i1) load("ineq")$
     tellsimp: warning: rule will treat '+
                               ' as noncommutative and nonassociative.
     tellsimp: warning: rule will treat '+
                               ' as noncommutative and nonassociative.
     tellsimp: warning: rule will treat '+
                               ' as noncommutative and nonassociative.
     tellsimp: warning: rule will treat '+
                               ' as noncommutative and nonassociative.
     tellsimp: warning: rule will treat '+
                               ' as noncommutative and nonassociative.
     tellsimp: warning: rule will treat '+
                               ' as noncommutative and nonassociative.
     tellsimp: warning: rule will treat '+
                               ' as noncommutative and nonassociative.
     tellsimp: warning: rule will treat '+
                               ' as noncommutative and nonassociative.
     (%i2) a>=4;  /* a sample inequality */
     (%o2)                        a >= 4
     (%o3)                     b + a > c + 4
     (%o4)                       7 x < 7 y
     (%o5)                    - 2 x <= - 6 z
                                      2
     (%o6)                      1 <= a  + 1
     (%o8)                       2 x < 3 x
     (%o9)                        a >= b
     (%o10)                   a + 3 >= b + 3
     (%o11)                       a >= b
     (%o12)                     a >= c - b
     (%o13)                     b + a >= c
     (%o14)                 (- c) + b + a >= 0
     (%o15)                   c - b - a <= 0
                                    2
     (%o16)                  (z - 1)  > - 2 z
                                 2
     (%o17)                     z  + 1 > 0
     (%o18)                        true
     (%i19) (b>c)+%; /* add a second, strict inequality */

   Be careful about using parentheses around the inequalities: when the
user types in ‘(A > B) + (C = 5)’ the result is ‘A + C > B + 5’, but ‘A
> B + C = 5’ is a syntax error, and ‘(A > B + C) = 5’ is something else
entirely.

   Do ‘disprule (all)’ to see a complete listing of the rule
definitions.

   The user will be queried if Maxima is unable to decide the sign of a
quantity multiplying an inequality.

   The most common mis-feature is illustrated by:

     (%i1) eq: a > b;
     (%o1)                         a > b
     (%i2) 2*eq;
     (%o2)                       2 (a > b)
     (%i3) % - eq;
     (%o3)                         a > b

   Another problem is 0 times an inequality; the default to have this
turn into 0 has been left alone.  However, if you type
‘X*<some_inequality>’ and Maxima asks about the sign of ‘X’ and you
respond ‘zero’ (or ‘z’), the program returns ‘X*<some_inequality>’ and
not use the information that ‘X’ is 0.  You should do ‘ev (%, x: 0)’ in
such a case, as the database will only be used for comparison purposes
in decisions, and not for the purpose of evaluating ‘X’.

   The user may note a slower response when this package is loaded, as
the simplifier is forced to examine more rules than without the package,
so you might wish to remove the rules after making use of them.  Do
‘kill (rules)’ to eliminate all of the rules (including any that you
might have defined); or you may be more selective by killing only some
of them; or use ‘remrule’ on a specific rule.

   Note that if you load this package after defining your own rules you
will clobber your rules that have the same name.  The rules in this
package are: ‘*rule1’, ..., ‘*rule8’, ‘+rule1’, ..., ‘+rule18’, and you
must enclose the rulename in quotes to refer to it, as in ‘remrule ("+",
"+rule1")’ to specifically remove the first rule on ‘"+"’ or ‘disprule
("*rule2")’ to display the definition of the second multiplicative rule.


File: maxima.info,  Node: Package rducon,  Next: Package scifac,  Prev: Package ineq,  Up: Package simplification

93.6 Package rducon
===================

 -- Function: reduce_consts (<expr>)
     Replaces constant subexpressions of <expr> with constructed
     constant atoms, saving the definition of all these constructed
     constants in the list of equations ‘const_eqns’, and returning the
     modified <expr>.  Those parts of <expr> are constant which return
     ‘true’ when operated on by the function ‘constantp’.  Hence, before
     invoking ‘reduce_consts’, one should do

          declare ([<objects to be given the constant property>], constant)$

     to set up a database of the constant quantities occurring in your
     expressions.

     If you are planning to generate Fortran output after these symbolic
     calculations, one of the first code sections should be the
     calculation of all constants.  To generate this code segment, do

          map ('fortran, const_eqns)$

     Variables besides ‘const_eqns’ which affect ‘reduce_consts’ are:

     ‘const_prefix’ (default value: ‘xx’) is the string of characters
     used to prefix all symbols generated by ‘reduce_consts’ to
     represent constant subexpressions.

     ‘const_counter’ (default value: 1) is the integer index used to
     generate unique symbols to represent each constant subexpression
     found by ‘reduce_consts’.

     ‘load ("rducon")’ loads this function.  ‘demo ("rducon")’ shows a
     demonstration of this function.


File: maxima.info,  Node: Package scifac,  Prev: Package rducon,  Up: Package simplification

93.7 Package scifac
===================

 -- Function: gcfac (<expr>)
     ‘gcfac’ is a factoring function that attempts to apply the same
     heuristics which scientists apply in trying to make expressions
     simpler.  ‘gcfac’ is limited to monomial-type factoring.  For a
     sum, ‘gcfac’ does the following:

       1. Factors over the integers.
       2. Factors out the largest powers of terms occurring as
          coefficients, regardless of the complexity of the terms.
       3. Uses (1) and (2) in factoring adjacent pairs of terms.
       4. Repeatedly and recursively applies these techniques until the
          expression no longer changes.

     Item (3) does not necessarily do an optimal job of pairwise
     factoring because of the combinatorially-difficult nature of
     finding which of all possible rearrangements of the pairs yields
     the most compact pair-factored result.

     ‘load ("scifac")’ loads this function.  ‘demo ("scifac")’ shows a
     demonstration of this function.


File: maxima.info,  Node: Package solve_rec,  Next: Package stats,  Prev: Package simplification,  Up: Top

94 Package solve_rec
********************

* Menu:

* Introduction to solve_rec::
* Functions and Variables for solve_rec::


File: maxima.info,  Node: Introduction to solve_rec,  Next: Functions and Variables for solve_rec,  Prev: Package solve_rec,  Up: Package solve_rec

94.1 Introduction to solve_rec
==============================

‘solve_rec’ is a package for solving linear recurrences with polynomial
coefficients.

   A demo is available with ‘demo("solve_rec");’.

   Example:

     (%i1) load("solve_rec")$
     (%i2) solve_rec((n+4)*s[n+2] + s[n+1] - (n+1)*s[n], s[n]);
                                         n
                      %k  (2 n + 3) (- 1)          %k
                        1                            2
     (%o2)       s  = -------------------- + ---------------
                  n     (n + 1) (n + 2)      (n + 1) (n + 2)


File: maxima.info,  Node: Functions and Variables for solve_rec,  Prev: Introduction to solve_rec,  Up: Package solve_rec

94.2 Functions and Variables for solve_rec
==========================================

 -- Function: harmonic_number (<x>)
     When <x> is positive integer n, ‘harmonic_number’ is the n'th
     harmonic number.  More generally, ‘harmonic_number(x) = psi[0](x+1)
     + %gamma’.  (See *note polygamma::).

          (%i1) load("simplify_sum")$
          (%i2) harmonic_number(5);
                                         137
          (%o2)                          ---
                                         60
          (%i3) sum(1/k, k, 1, 5);
                                         137
          (%o3)                          ---
                                         60
          (%i4) float(harmonic_number(sqrt(2)));
          (%o4)              %gamma + 0.6601971549171388
          (%i5) float(psi[0](1+sqrt(2)))+%gamma;
          (%o5)              %gamma + 0.6601971549171388

 -- Function: harmonic_to_psi (<x>)
     Converts expressions with ‘harmonic_number’ to the equivalent
     expression involving ‘psi[0]’ (see *note polygamma::).

          (%i1) load("simplify_sum")$
          (%i2) harmonic_to_psi(harmonic_number(sqrt(2)));
          (%o2)              psi (sqrt(2) + 1) + %gamma
                                0

 -- Function: reduce_order (<rec>, <sol>, <var>)

     Reduces the order of linear recurrence <rec> when a particular
     solution <sol> is known.  The reduced recurrence can be used to get
     other solutions.

     Example:

          (%i3) rec: x[n+2] = x[n+1] + x[n]/n;
                                                x
                                                 n
          (%o3)               x      = x      + --
                               n + 2    n + 1   n
          (%i4) solve_rec(rec, x[n]);
          WARNING: found some hypergeometrical solutions!
          (%o4)                    x  = %k  n
                                    n     1
          (%i5) reduce_order(rec, n, x[n]);
          (%t5)                    x  = n %z
                                    n       n

                                     n - 1
                                     ====
                                     \
          (%t6)                %z  =  >     %u
                                 n   /        %j
                                     ====
                                     %j = 0

          (%o6)             (- n - 2) %u     - %u
                                        n + 1     n
          (%i6) solve_rec((n+2)*%u[n+1] + %u[n], %u[n]);
                                               n
                                      %k  (- 1)
                                        1
          (%o6)                 %u  = ----------
                                  n    (n + 1)!

          So the general solution is

                       n - 1
                       ====        j
                       \      (- 1)
                 %k  n  >    -------- + %k  n
                   2   /     (j + 1)!     1
                       ====
                       j = 0

 -- Option variable: simplify_products
     Default value: ‘true’

     If ‘simplify_products’ is ‘true’, ‘solve_rec’ will try to simplify
     products in result.

     See also: *note solve_rec::.

 -- Function: simplify_sum (<expr>)

     Tries to simplify all sums appearing in <expr> to a closed form.

     To use this function first load the ‘simplify_sum’ package with
     ‘load("simplify_sum")’.

     Example:

          (%i1) load("simplify_sum")$
          (%i2) sum(binomial(n+k,k)/2^k, k, 1, n) + sum(binomial(2*n, 2*k), k, 1,n);
                  n                          n
                 ====                       ====
                 \     binomial(n + k, k)   \
          (%o2)   >    ------------------ +  >    binomial(2 n, 2 k)
                 /              k           /
                 ====          2            ====
                 k = 1                      k = 1
          (%i3) simplify_sum(%);
                                   2 n - 1    n
          (%o3)                   2        + 2  - 2

 -- Function: solve_rec (<eqn>, <var>, [<init>])
     Solves for hypergeometrical solutions to linear recurrence <eqn>
     with polynomials coefficient in variable <var>.  Optional arguments
     <init> are initial conditions.

     ‘solve_rec’ can solve linear recurrences with constant
     coefficients, finds hypergeometrical solutions to homogeneous
     linear recurrences with polynomial coefficients, rational solutions
     to linear recurrences with polynomial coefficients and can solve
     Ricatti type recurrences.

     Note that the running time of the algorithm used to find
     hypergeometrical solutions is exponential in the degree of the
     leading and trailing coefficient.

     To use this function first load the ‘solve_rec’ package with
     ‘load("solve_rec");’.

     Example of linear recurrence with constant coefficients:

          (%i2) solve_rec(a[n]=a[n-1]+a[n-2]+n/2^n, a[n]);
                                  n          n
                     (sqrt(5) - 1)  %k  (- 1)
                                      1           n
          (%o2) a  = ------------------------- - ----
                 n               n                  n
                                2                5 2
                                                          n
                                             (sqrt(5) + 1)  %k
                                                              2    2
                                           + ------------------ - ----
                                                      n              n
                                                     2            5 2

     Example of linear recurrence with polynomial coefficients:

          (%i7) 2*x*(x+1)*y[x] - (x^2+3*x-2)*y[x+1] + (x-1)*y[x+2];
                                   2
          (%o7) (x - 1) y      - (x  + 3 x - 2) y      + 2 x (x + 1) y
                         x + 2                   x + 1                x
          (%i8) solve_rec(%, y[x], y[1]=1, y[3]=3);
                                        x
                                     3 2    x!
          (%o9)                 y  = ---- - --
                                 x    4     2

     Example of Ricatti type recurrence:

          (%i2) x*y[x+1]*y[x] - y[x+1]/(x+2) + y[x]/(x-1) = 0;
                                      y         y
                                       x + 1     x
          (%o2)         x y  y      - ------ + ----- = 0
                           x  x + 1   x + 2    x - 1
          (%i3) solve_rec(%, y[x], y[3]=5)$
          (%i4) ratsimp(minfactorial(factcomb(%)));
                                             3
                                         30 x  - 30 x
          (%o4) y  = - -------------------------------------------------
                 x        6      5       4       3       2
                       5 x  - 3 x  - 25 x  + 15 x  + 20 x  - 12 x - 1584

     See also: ‘solve_rec_rat’, ‘simplify_products’ and *note
     product_use_gamma::.

 -- Function: solve_rec_rat (<eqn>, <var>, [<init>])

     Solves for rational solutions to linear recurrences.  See solve_rec
     for description of arguments.

     To use this function first load the ‘solve_rec’ package with
     ‘load("solve_rec");’.

     Example:

          (%i1) (x+4)*a[x+3] + (x+3)*a[x+2] - x*a[x+1] + (x^2-1)*a[x];
          (%o1)  (x + 4) a      + (x + 3) a      - x a
                          x + 3            x + 2      x + 1
                                                             2
                                                         + (x  - 1) a
                                                                      x
          (%i2) solve_rec_rat(% = (x+2)/(x+1), a[x]);
                                 1
          (%o2)      a  = ---------------
                      x   (x - 1) (x + 1)

     See also: *note solve_rec::.

 -- Option variable: product_use_gamma
     Default value: ‘true’

     When simplifying products, ‘solve_rec’ introduces gamma function
     into the expression if ‘product_use_gamma’ is ‘true’.

     See also: ‘simplify_products’, *note solve_rec::.

 -- Function: summand_to_rec
          summand_to_rec (<summand>, <k>, <n>)
          summand_to_rec (<summand>, [<k>, <lo>, <hi>], <n>)

     Returns the recurrence satisfied by the sum

               hi
              ====
              \
               >     summand
              /
              ====
            k = lo

     where summand is hypergeometrical in <k> and <n>.  If <lo> and <hi>
     are omitted, they are assumed to be ‘lo = -inf’ and ‘hi = inf’.

     To use this function first load the ‘simplify_sum’ package with
     ‘load("simplify_sum")’.

     Example:

          (%i1) load("simplify_sum")$
          (%i2) summand: binom(n,k);
          (%o2)                           binomial(n, k)
          (%i3) summand_to_rec(summand,k,n);
          (%o3)                      2 sm  - sm      = 0
                                         n     n + 1
          (%i7) summand: binom(n, k)/(k+1);
                                          binomial(n, k)
          (%o7)                           --------------
                                              k + 1
          (%i8) summand_to_rec(summand, [k, 0, n], n);
          (%o8)               2 (n + 1) sm  - (n + 2) sm      = - 1
                                          n             n + 1


File: maxima.info,  Node: Package stats,  Next: Package stirling,  Prev: Package solve_rec,  Up: Top

95 Package stats
****************

* Menu:

* Introduction to stats::
* Functions and Variables for inference_result::
* Functions and Variables for stats::
* Functions and Variables for special distributions::


File: maxima.info,  Node: Introduction to stats,  Next: Functions and Variables for inference_result,  Up: Package stats

95.1 Introduction to stats
==========================

Package ‘stats’ contains a set of classical statistical inference and
hypothesis testing procedures.

   All these functions return an ‘inference_result’ Maxima object which
contains the necessary results for population inferences and decision
making.

   Global variable ‘stats_numer’ controls whether results are given in
floating point or symbolic and rational format; its default value is
‘true’ and results are returned in floating point format.

   Package ‘descriptive’ contains some utilities to manipulate data
structures (lists and matrices); for example, to extract subsamples.  It
also contains some examples on how to use package ‘numericalio’ to read
data from plain text files.  See ‘descriptive’ and ‘numericalio’ for
more details.

   Package ‘stats’ loads packages ‘descriptive’, ‘distrib’ and
‘inference_result’.

   For comments, bugs or suggestions, please contact the author at

   <'mario AT edu DOT xunta DOT es'>.


File: maxima.info,  Node: Functions and Variables for inference_result,  Next: Functions and Variables for stats,  Prev: Introduction to stats,  Up: Package stats

95.2 Functions and Variables for inference_result
=================================================

 -- Function: inference_result (<title>, <values>, <numbers>)

     Constructs an ‘inference_result’ object of the type returned by the
     stats functions.  Argument <title> is a string with the name of the
     procedure; <values> is a list with elements of the form ‘symbol =
     value’ and <numbers> is a list with positive integer numbers
     ranging from one to ‘length(<values>)’, indicating which values
     will be shown by default.

     Example:

     This is a simple example showing results concerning a rectangle.
     The title of this object is the string ‘"Rectangle"’, it stores
     five results, named ‘'base’, ‘'height’, ‘'diagonal’, ‘'area’, and
     ‘'perimeter’, but only the first, second, fifth, and fourth will be
     displayed.  The ‘'diagonal’ is stored in this object, but it is not
     displayed; to access its value, make use of function
     ‘take_inference’.

          (%i1) load("inference_result")$
          (%i2) b: 3$ h: 2$
          (%i3) inference_result("Rectangle",
                                  ['base=b,
                                   'height=h,
                                   'diagonal=sqrt(b^2+h^2),
                                   'area=b*h,
                                   'perimeter=2*(b+h)],
                                  [1,2,5,4] );
                                  |   Rectangle
                                  |
                                  |    base = 3
                                  |
          (%o3)                   |   height = 2
                                  |
                                  | perimeter = 10
                                  |
                                  |    area = 6
          (%i4) take_inference('diagonal,%);
          (%o4)                        sqrt(13)

     See also *note take_inference::.

 -- Function: inferencep (<obj>)

     Returns ‘true’ or ‘false’, depending on whether <obj> is an
     ‘inference_result’ object or not.

 -- Function: items_inference (<obj>)

     Returns a list with the names of the items stored in <obj>, which
     must be an ‘inference_result’ object.

     Example:

     The ‘inference_result’ object stores two values, named ‘'pi’ and
     ‘'e’, but only the second is displayed.  The ‘items_inference’
     function returns the names of all items, no matter they are
     displayed or not.

          (%i1) load("inference_result")$
          (%i2) inference_result("Hi", ['pi=%pi,'e=%e],[2]);
                                      |   Hi
          (%o2)                       |
                                      | e = %e
          (%i3) items_inference(%);
          (%o3)                        [pi, e]

 -- Function: take_inference
          take_inference (<n>, <obj>)
          take_inference (<name>, <obj>)
          take_inference (<list>, <obj>)

     Returns the <n>-th value stored in <obj> if <n> is a positive
     integer, or the item named <name> if this is the name of an item.
     If the first argument is a list of numbers and/or symbols, function
     ‘take_inference’ returns a list with the corresponding results.

     Example:

     Given an ‘inference_result’ object, function ‘take_inference’ is
     called in order to extract some information stored in it.

          (%i1) load("inference_result")$
          (%i2) b: 3$ h: 2$
          (%i3) sol: inference_result("Rectangle",
                                      ['base=b,
                                       'height=h,
                                       'diagonal=sqrt(b^2+h^2),
                                       'area=b*h,
                                       'perimeter=2*(b+h)],
                                      [1,2,5,4] );
                                  |   Rectangle
                                  |
                                  |    base = 3
                                  |
          (%o3)                   |   height = 2
                                  |
                                  | perimeter = 10
                                  |
                                  |    area = 6
          (%i4) take_inference('base,sol);
          (%o4)                           3
          (%i5) take_inference(5,sol);
          (%o5)                          10
          (%i6) take_inference([1,'diagonal],sol);
          (%o6)                     [3, sqrt(13)]
          (%i7) take_inference(items_inference(sol),sol);
          (%o7)                [3, 2, sqrt(13), 6, 10]

     See also ‘inference_result’, and *note take_inference::.


File: maxima.info,  Node: Functions and Variables for stats,  Next: Functions and Variables for special distributions,  Prev: Functions and Variables for inference_result,  Up: Package stats

95.3 Functions and Variables for stats
======================================

 -- Option variable: stats_numer
     Default value: ‘true’

     If ‘stats_numer’ is ‘true’, inference statistical functions return
     their results in floating point numbers.  If it is ‘false’, results
     are given in symbolic and rational format.

 -- Function: test_mean
          test_mean (<x>)
          test_mean (<x>, <options> ...)

     This is the mean <t>-test.  Argument <x> is a list or a column
     matrix containing an one dimensional sample.  It also performs an
     asymptotic test based on the Central Limit Theorem if option
     ‘'asymptotic’ is ‘true’.

     Options:

        • ‘'mean’, default ‘0’, is the mean value to be checked.

        • ‘'alternative’, default ‘'twosided’, is the alternative
          hypothesis; valid values are: ‘'twosided’, ‘'greater’ and
          ‘'less’.

        • ‘'dev’, default ‘'unknown’, this is the value of the standard
          deviation when it is known; valid values are: ‘'unknown’ or a
          positive expression.

        • ‘'conflevel’, default ‘95/100’, confidence level for the
          confidence interval; it must be an expression which takes a
          value in (0,1).

        • ‘'asymptotic’, default ‘false’, indicates whether it performs
          an exact <t>-test or an asymptotic one based on the Central
          Limit Theorem; valid values are ‘true’ and ‘false’.

     The output of function ‘test_mean’ is an ‘inference_result’ Maxima
     object showing the following results:

       1. ‘'mean_estimate’: the sample mean.

       2. ‘'conf_level’: confidence level selected by the user.

       3. ‘'conf_interval’: confidence interval for the population mean.

       4. ‘'method’: inference procedure.

       5. ‘'hypotheses’: null and alternative hypotheses to be tested.

       6. ‘'statistic’: value of the sample statistic used for testing
          the null hypothesis.

       7. ‘'distribution’: distribution of the sample statistic,
          together with its parameter(s).

       8. ‘'p_value’: p-value of the test.

     Examples:

     Performs an exact <t>-test with unknown variance.  The null
     hypothesis is H_0: mean=50 against the one sided alternative H_1:
     mean<50; according to the results, the p-value is too great, there
     are no evidence for rejecting H_0.

          (%i1) load("stats")$
          (%i2) data: [78,64,35,45,45,75,43,74,42,42]$
          (%i3) test_mean(data,'conflevel=0.9,'alternative='less,'mean=50);
                    |                 MEAN TEST
                    |
                    |            mean_estimate = 54.3
                    |
                    |              conf_level = 0.9
                    |
                    | conf_interval = [minf, 61.51314273502712]
                    |
          (%o3)     |  method = Exact t-test. Unknown variance.
                    |
                    | hypotheses = H0: mean = 50 , H1: mean < 50
                    |
                    |       statistic = .8244705235071678
                    |
                    |       distribution = [student_t, 9]
                    |
                    |        p_value = .7845100411786889

     This time Maxima performs an asymptotic test, based on the Central
     Limit Theorem.  The null hypothesis is H_0: equal(mean, 50) against
     the two sided alternative H_1: not equal(mean, 50); according to
     the results, the p-value is very small, H_0 should be rejected in
     favor of the alternative H_1.  Note that, as indicated by the
     ‘Method’ component, this procedure should be applied to large
     samples.

          (%i1) load("stats")$
          (%i2) test_mean([36,118,52,87,35,256,56,178,57,57,89,34,25,98,35,
                        98,41,45,198,54,79,63,35,45,44,75,42,75,45,45,
                        45,51,123,54,151],
                        'asymptotic=true,'mean=50);
                    |                       MEAN TEST
                    |
                    |           mean_estimate = 74.88571428571429
                    |
                    |                   conf_level = 0.95
                    |
                    | conf_interval = [57.72848600856194, 92.04294256286663]
                    |
          (%o2)     |    method = Large sample z-test. Unknown variance.
                    |
                    |       hypotheses = H0: mean = 50 , H1: mean # 50
                    |
                    |             statistic = 2.842831192874313
                    |
                    |             distribution = [normal, 0, 1]
                    |
                    |             p_value = .004471474652002261

 -- Function: test_means_difference
          test_means_difference (<x1>, <x2>)
          test_means_difference (<x1>, <x2>, <options> ...)

     This is the difference of means <t>-test for two samples.
     Arguments <x1> and <x2> are lists or column matrices containing two
     independent samples.  In case of different unknown variances (see
     options ‘'dev1’, ‘'dev2’ and ‘'varequal’ below), the degrees of
     freedom are computed by means of the Welch approximation.  It also
     performs an asymptotic test based on the Central Limit Theorem if
     option ‘'asymptotic’ is set to ‘true’.

     Options:

        • 
        • ‘'alternative’, default ‘'twosided’, is the alternative
          hypothesis; valid values are: ‘'twosided’, ‘'greater’ and
          ‘'less’.

        • ‘'dev1’, default ‘'unknown’, this is the value of the standard
          deviation of the <x1> sample when it is known; valid values
          are: ‘'unknown’ or a positive expression.

        • ‘'dev2’, default ‘'unknown’, this is the value of the standard
          deviation of the <x2> sample when it is known; valid values
          are: ‘'unknown’ or a positive expression.

        • ‘'varequal’, default ‘false’, whether variances should be
          considered to be equal or not; this option takes effect only
          when ‘'dev1’ and/or ‘'dev2’ are ‘'unknown’.

        • ‘'conflevel’, default ‘95/100’, confidence level for the
          confidence interval; it must be an expression which takes a
          value in (0,1).

        • ‘'asymptotic’, default ‘false’, indicates whether it performs
          an exact <t>-test or an asymptotic one based on the Central
          Limit Theorem; valid values are ‘true’ and ‘false’.

     The output of function ‘test_means_difference’ is an
     ‘inference_result’ Maxima object showing the following results:

       1. ‘'diff_estimate’: the difference of means estimate.

       2. ‘'conf_level’: confidence level selected by the user.

       3. ‘'conf_interval’: confidence interval for the difference of
          means.

       4. ‘'method’: inference procedure.

       5. ‘'hypotheses’: null and alternative hypotheses to be tested.

       6. ‘'statistic’: value of the sample statistic used for testing
          the null hypothesis.

       7. ‘'distribution’: distribution of the sample statistic,
          together with its parameter(s).

       8. ‘'p_value’: p-value of the test.

     Examples:

     The equality of means is tested with two small samples <x> and <y>,
     against the alternative H_1: m_1>m_2, being m_1 and m_2 the
     populations means; variances are unknown and supposed to be
     different.

          (%i1) load("stats")$
          (%i2) x: [20.4,62.5,61.3,44.2,11.1,23.7]$
          (%i3) y: [1.2,6.9,38.7,20.4,17.2]$
          (%i4) test_means_difference(x,y,'alternative='greater);
                      |              DIFFERENCE OF MEANS TEST
                      |
                      |         diff_estimate = 20.31999999999999
                      |
                      |                 conf_level = 0.95
                      |
                      |    conf_interval = [- .04597417812882298, inf]
                      |
          (%o4)       |        method = Exact t-test. Welch approx.
                      |
                      | hypotheses = H0: mean1 = mean2 , H1: mean1 > mean2
                      |
                      |           statistic = 1.838004300728477
                      |
                      |    distribution = [student_t, 8.62758740184604]
                      |
                      |            p_value = .05032746527991905

     The same test as before, but now variances are supposed to be
     equal.

          (%i1) load("stats")$
          (%i2) x: [20.4,62.5,61.3,44.2,11.1,23.7]$
          (%i3) y: matrix([1.2],[6.9],[38.7],[20.4],[17.2])$
          (%i4) test_means_difference(x,y,'alternative='greater,
                                                           'varequal=true);
                      |              DIFFERENCE OF MEANS TEST
                      |
                      |         diff_estimate = 20.31999999999999
                      |
                      |                 conf_level = 0.95
                      |
                      |     conf_interval = [- .7722627696897568, inf]
                      |
          (%o4)       |   method = Exact t-test. Unknown equal variances
                      |
                      | hypotheses = H0: mean1 = mean2 , H1: mean1 > mean2
                      |
                      |           statistic = 1.765996124515009
                      |
                      |           distribution = [student_t, 9]
                      |
                      |            p_value = .05560320992529344

 -- Function: test_variance
          test_variance (<x>)
          test_variance (<x>, <options>, ...)

     This is the variance <chi^2>-test.  Argument <x> is a list or a
     column matrix containing an one dimensional sample taken from a
     normal population.

     Options:

        • ‘'mean’, default ‘'unknown’, is the population's mean, when it
          is known.

        • ‘'alternative’, default ‘'twosided’, is the alternative
          hypothesis; valid values are: ‘'twosided’, ‘'greater’ and
          ‘'less’.

        • ‘'variance’, default ‘1’, this is the variance value
          (positive) to be checked.

        • ‘'conflevel’, default ‘95/100’, confidence level for the
          confidence interval; it must be an expression which takes a
          value in (0,1).

     The output of function ‘test_variance’ is an ‘inference_result’
     Maxima object showing the following results:

       1. ‘'var_estimate’: the sample variance.

       2. ‘'conf_level’: confidence level selected by the user.

       3. ‘'conf_interval’: confidence interval for the population
          variance.

       4. ‘'method’: inference procedure.

       5. ‘'hypotheses’: null and alternative hypotheses to be tested.

       6. ‘'statistic’: value of the sample statistic used for testing
          the null hypothesis.

       7. ‘'distribution’: distribution of the sample statistic,
          together with its parameter.

       8. ‘'p_value’: p-value of the test.

     Examples:

     It is tested whether the variance of a population with unknown mean
     is equal to or greater than 200.

          (%i1) load("stats")$
          (%i2) x: [203,229,215,220,223,233,208,228,209]$
          (%i3) test_variance(x,'alternative='greater,'variance=200);
                       |                  VARIANCE TEST
                       |
                       |              var_estimate = 110.75
                       |
                       |                conf_level = 0.95
                       |
                       |     conf_interval = [57.13433376937479, inf]
                       |
          (%o3)        | method = Variance Chi-square test. Unknown mean.
                       |
                       |    hypotheses = H0: var = 200 , H1: var > 200
                       |
                       |                 statistic = 4.43
                       |
                       |             distribution = [chi2, 8]
                       |
                       |           p_value = .8163948512777689

 -- Function: test_variance_ratio
          test_variance_ratio (<x1>, <x2>)
          test_variance_ratio (<x1>, <x2>, <options> ...)

     This is the variance ratio <F>-test for two normal populations.
     Arguments <x1> and <x2> are lists or column matrices containing two
     independent samples.

     Options:

        • ‘'alternative’, default ‘'twosided’, is the alternative
          hypothesis; valid values are: ‘'twosided’, ‘'greater’ and
          ‘'less’.

        • ‘'mean1’, default ‘'unknown’, when it is known, this is the
          mean of the population from which <x1> was taken.

        • ‘'mean2’, default ‘'unknown’, when it is known, this is the
          mean of the population from which <x2> was taken.

        • ‘'conflevel’, default ‘95/100’, confidence level for the
          confidence interval of the ratio; it must be an expression
          which takes a value in (0,1).

     The output of function ‘test_variance_ratio’ is an
     ‘inference_result’ Maxima object showing the following results:

       1. ‘'ratio_estimate’: the sample variance ratio.

       2. ‘'conf_level’: confidence level selected by the user.

       3. ‘'conf_interval’: confidence interval for the variance ratio.

       4. ‘'method’: inference procedure.

       5. ‘'hypotheses’: null and alternative hypotheses to be tested.

       6. ‘'statistic’: value of the sample statistic used for testing
          the null hypothesis.

       7. ‘'distribution’: distribution of the sample statistic,
          together with its parameters.

       8. ‘'p_value’: p-value of the test.

     Examples:

     The equality of the variances of two normal populations is checked
     against the alternative that the first is greater than the second.

          (%i1) load("stats")$
          (%i2) x: [20.4,62.5,61.3,44.2,11.1,23.7]$
          (%i3) y: [1.2,6.9,38.7,20.4,17.2]$
          (%i4) test_variance_ratio(x,y,'alternative='greater);
                        |              VARIANCE RATIO TEST
                        |
                        |       ratio_estimate = 2.316933391522034
                        |
                        |               conf_level = 0.95
                        |
                        |    conf_interval = [.3703504689507268, inf]
                        |
          (%o4)         | method = Variance ratio F-test. Unknown means.
                        |
                        | hypotheses = H0: var1 = var2 , H1: var1 > var2
                        |
                        |         statistic = 2.316933391522034
                        |
                        |            distribution = [f, 5, 4]
                        |
                        |          p_value = .2179269692254457

 -- Function: test_proportion
          test_proportion (<x>, <n>)
          test_proportion (<x>, <n>, <options> ...)

     Inferences on a proportion.  Argument <x> is the number of
     successes in <n> trials in a Bernoulli experiment with unknown
     probability.

     Options:

        • ‘'proportion’, default ‘1/2’, is the value of the proportion
          to be checked.

        • ‘'alternative’, default ‘'twosided’, is the alternative
          hypothesis; valid values are: ‘'twosided’, ‘'greater’ and
          ‘'less’.

        • ‘'conflevel’, default ‘95/100’, confidence level for the
          confidence interval; it must be an expression which takes a
          value in (0,1).

        • ‘'asymptotic’, default ‘false’, indicates whether it performs
          an exact test based on the binomial distribution, or an
          asymptotic one based on the Central Limit Theorem; valid
          values are ‘true’ and ‘false’.

        • ‘'correct’, default ‘true’, indicates whether Yates correction
          is applied or not.

     The output of function ‘test_proportion’ is an ‘inference_result’
     Maxima object showing the following results:

       1. ‘'sample_proportion’: the sample proportion.

       2. ‘'conf_level’: confidence level selected by the user.

       3. ‘'conf_interval’: Wilson confidence interval for the
          proportion.

       4. ‘'method’: inference procedure.

       5. ‘'hypotheses’: null and alternative hypotheses to be tested.

       6. ‘'statistic’: value of the sample statistic used for testing
          the null hypothesis.

       7. ‘'distribution’: distribution of the sample statistic,
          together with its parameters.

       8. ‘'p_value’: p-value of the test.

     Examples:

     Performs an exact test.  The null hypothesis is H_0: p=1/2 against
     the one sided alternative H_1: p<1/2.

          (%i1) load("stats")$
          (%i2) test_proportion(45, 103, alternative = less);
                   |            PROPORTION TEST
                   |
                   | sample_proportion = .4368932038834951
                   |
                   |           conf_level = 0.95
                   |
                   | conf_interval = [0, 0.522714149150231]
                   |
          (%o2)    |     method = Exact binomial test.
                   |
                   | hypotheses = H0: p = 0.5 , H1: p < 0.5
                   |
                   |             statistic = 45
                   |
                   |  distribution = [binomial, 103, 0.5]
                   |
                   |      p_value = .1184509388901454

     A two sided asymptotic test.  Confidence level is 99/100.

          (%i1) load("stats")$
          (%i2) fpprintprec:7$
          (%i3) test_proportion(45, 103,
                            conflevel = 99/100, asymptotic=true);
                |                 PROPORTION TEST
                |
                |           sample_proportion = .43689
                |
                |                conf_level = 0.99
                |
                |        conf_interval = [.31422, .56749]
                |
          (%o3) | method = Asympthotic test with Yates correction.
                |
                |     hypotheses = H0: p = 0.5 , H1: p # 0.5
                |
                |               statistic = .43689
                |
                |      distribution = [normal, 0.5, .048872]
                |
                |                p_value = .19662

 -- Function: test_proportions_difference
          test_proportions_difference (<x1>, <n1>, <x2>, <n2>)
          test_proportions_difference (<x1>, <n1>, <x2>, <n2>, <options>
          ...)

     Inferences on the difference of two proportions.  Argument <x1> is
     the number of successes in <n1> trials in a Bernoulli experiment in
     the first population, and <x2> and <n2> are the corresponding
     values in the second population.  Samples are independent and the
     test is asymptotic.

     Options:

        • ‘'alternative’, default ‘'twosided’, is the alternative
          hypothesis; valid values are: ‘'twosided’ (‘p1 # p2’),
          ‘'greater’ (‘p1 > p2’) and ‘'less’ (‘p1 < p2’).

        • ‘'conflevel’, default ‘95/100’, confidence level for the
          confidence interval; it must be an expression which takes a
          value in (0,1).

        • ‘'correct’, default ‘true’, indicates whether Yates correction
          is applied or not.

     The output of function ‘test_proportions_difference’ is an
     ‘inference_result’ Maxima object showing the following results:

       1. ‘'proportions’: list with the two sample proportions.

       2. ‘'conf_level’: confidence level selected by the user.

       3. ‘'conf_interval’: Confidence interval for the difference of
          proportions ‘p1 - p2’.

       4. ‘'method’: inference procedure and warning message in case of
          any of the samples sizes is less than 10.

       5. ‘'hypotheses’: null and alternative hypotheses to be tested.

       6. ‘'statistic’: value of the sample statistic used for testing
          the null hypothesis.

       7. ‘'distribution’: distribution of the sample statistic,
          together with its parameters.

       8. ‘'p_value’: p-value of the test.

     Examples:

     A machine produced 10 defective articles in a batch of 250.  After
     some maintenance work, it produces 4 defective in a batch of 150.
     In order to know if the machine has improved, we test the null
     hypothesis ‘H0:p1=p2’, against the alternative ‘H0:p1>p2’, where
     ‘p1’ and ‘p2’ are the probabilities for one produced article to be
     defective before and after maintenance.  According to the p value,
     there is not enough evidence to accept the alternative.

          (%i1) load("stats")$
          (%i2) fpprintprec:7$
          (%i3) test_proportions_difference(10, 250, 4, 150,
                                          alternative = greater);
                |       DIFFERENCE OF PROPORTIONS TEST
                |
                |       proportions = [0.04, .02666667]
                |
                |              conf_level = 0.95
                |
                |      conf_interval = [- .02172761, 1]
                |
          (%o3) | method = Asymptotic test. Yates correction.
                |
                |   hypotheses = H0: p1 = p2 , H1: p1 > p2
                |
                |            statistic = .01333333
                |
                |    distribution = [normal, 0, .01898069]
                |
                |             p_value = .2411936

     Exact standard deviation of the asymptotic normal distribution when
     the data are unknown.

          (%i1) load("stats")$
          (%i2) stats_numer: false$
          (%i3) sol: test_proportions_difference(x1,n1,x2,n2)$
          (%i4) last(take_inference('distribution,sol));
                         1    1                  x2 + x1
                        (-- + --) (x2 + x1) (1 - -------)
                         n2   n1                 n2 + n1
          (%o4)    sqrt(---------------------------------)
                                     n2 + n1

 -- Function: test_sign
          test_sign (<x>)
          test_sign (<x>, <options> ...)

     This is the non parametric sign test for the median of a continuous
     population.  Argument <x> is a list or a column matrix containing
     an one dimensional sample.

     Options:

        • ‘'alternative’, default ‘'twosided’, is the alternative
          hypothesis; valid values are: ‘'twosided’, ‘'greater’ and
          ‘'less’.

        • ‘'median’, default ‘0’, is the median value to be checked.

     The output of function ‘test_sign’ is an ‘inference_result’ Maxima
     object showing the following results:

       1. ‘'med_estimate’: the sample median.

       2. ‘'method’: inference procedure.

       3. ‘'hypotheses’: null and alternative hypotheses to be tested.

       4. ‘'statistic’: value of the sample statistic used for testing
          the null hypothesis.

       5. ‘'distribution’: distribution of the sample statistic,
          together with its parameter(s).

       6. ‘'p_value’: p-value of the test.

     Examples:

     Checks whether the population from which the sample was taken has
     median 6, against the alternative H_1: median > 6.

          (%i1) load("stats")$
          (%i2) x: [2,0.1,7,1.8,4,2.3,5.6,7.4,5.1,6.1,6]$
          (%i3) test_sign(x,'median=6,'alternative='greater);
                         |                  SIGN TEST
                         |
                         |              med_estimate = 5.1
                         |
                         |      method = Non parametric sign test.
                         |
          (%o3)          | hypotheses = H0: median = 6 , H1: median > 6
                         |
                         |                statistic = 7
                         |
                         |      distribution = [binomial, 10, 0.5]
                         |
                         |         p_value = .05468749999999989

 -- Function: test_signed_rank
          test_signed_rank (<x>)
          test_signed_rank (<x>, <options> ...)

     This is the Wilcoxon signed rank test to make inferences about the
     median of a continuous population.  Argument <x> is a list or a
     column matrix containing an one dimensional sample.  Performs
     normal approximation if the sample size is greater than 20, or if
     there are zeroes or ties.

     See also ‘pdf_rank_test’ and ‘cdf_rank_test’

     Options:

        • ‘'median’, default ‘0’, is the median value to be checked.

        • ‘'alternative’, default ‘'twosided’, is the alternative
          hypothesis; valid values are: ‘'twosided’, ‘'greater’ and
          ‘'less’.

     The output of function ‘test_signed_rank’ is an ‘inference_result’
     Maxima object with the following results:

       1. ‘'med_estimate’: the sample median.

       2. ‘'method’: inference procedure.

       3. ‘'hypotheses’: null and alternative hypotheses to be tested.

       4. ‘'statistic’: value of the sample statistic used for testing
          the null hypothesis.

       5. ‘'distribution’: distribution of the sample statistic,
          together with its parameter(s).

       6. ‘'p_value’: p-value of the test.

     Examples:

     Checks the null hypothesis H_0: median = 15 against the alternative
     H_1: median > 15.  This is an exact test, since there are no ties.

          (%i1) load("stats")$
          (%i2) x: [17.1,15.9,13.7,13.4,15.5,17.6]$
          (%i3) test_signed_rank(x,median=15,alternative=greater);
                           |             SIGNED RANK TEST
                           |
                           |           med_estimate = 15.7
                           |
                           |           method = Exact test
                           |
          (%o3)            | hypotheses = H0: med = 15 , H1: med > 15
                           |
                           |              statistic = 14
                           |
                           |     distribution = [signed_rank, 6]
                           |
                           |            p_value = 0.28125

     Checks the null hypothesis H_0: equal(median, 2.5) against the
     alternative H_1: not equal(median, 2.5).  This is an approximated
     test, since there are ties.

          (%i1) load("stats")$
          (%i2) y:[1.9,2.3,2.6,1.9,1.6,3.3,4.2,4,2.4,2.9,1.5,3,2.9,4.2,3.1]$
          (%i3) test_signed_rank(y,median=2.5);
                       |                 SIGNED RANK TEST
                       |
                       |                med_estimate = 2.9
                       |
                       |          method = Asymptotic test. Ties
                       |
          (%o3)        |    hypotheses = H0: med = 2.5 , H1: med # 2.5
                       |
                       |                 statistic = 76.5
                       |
                       | distribution = [normal, 60.5, 17.58195097251724]
                       |
                       |           p_value = .3628097734643669

 -- Function: test_rank_sum
          test_rank_sum (<x1>, <x2>)
          test_rank_sum (<x1>, <x2>, <option>)

     This is the Wilcoxon-Mann-Whitney test for comparing the medians of
     two continuous populations.  The first two arguments <x1> and <x2>
     are lists or column matrices with the data of two independent
     samples.  Performs normal approximation if any of the sample sizes
     is greater than 10, or if there are ties.

     Option:

        • ‘'alternative’, default ‘'twosided’, is the alternative
          hypothesis; valid values are: ‘'twosided’, ‘'greater’ and
          ‘'less’.

     The output of function ‘test_rank_sum’ is an ‘inference_result’
     Maxima object with the following results:

       1. ‘'method’: inference procedure.

       2. ‘'hypotheses’: null and alternative hypotheses to be tested.

       3. ‘'statistic’: value of the sample statistic used for testing
          the null hypothesis.

       4. ‘'distribution’: distribution of the sample statistic,
          together with its parameters.

       5. ‘'p_value’: p-value of the test.

     Examples:

     Checks whether populations have similar medians.  Samples sizes are
     small and an exact test is made.

          (%i1) load("stats")$
          (%i2) x:[12,15,17,38,42,10,23,35,28]$
          (%i3) y:[21,18,25,14,52,65,40,43]$
          (%i4) test_rank_sum(x,y);
                        |                 RANK SUM TEST
                        |
                        |              method = Exact test
                        |
                        | hypotheses = H0: med1 = med2 , H1: med1 # med2
          (%o4)         |
                        |                 statistic = 22
                        |
                        |        distribution = [rank_sum, 9, 8]
                        |
                        |          p_value = .1995886466474702

     Now, with greater samples and ties, the procedure makes normal
     approximation.  The alternative hypothesis is H_1: median1 <
     median2.

          (%i1) load("stats")$
          (%i2) x: [39,42,35,13,10,23,15,20,17,27]$
          (%i3) y: [20,52,66,19,41,32,44,25,14,39,43,35,19,56,27,15]$
          (%i4) test_rank_sum(x,y,'alternative='less);
                       |                  RANK SUM TEST
                       |
                       |          method = Asymptotic test. Ties
                       |
                       |  hypotheses = H0: med1 = med2 , H1: med1 < med2
          (%o4)        |
                       |                 statistic = 48.5
                       |
                       | distribution = [normal, 79.5, 18.95419580097078]
                       |
                       |           p_value = .05096985666598441

 -- Function: test_normality (<x>)

     Shapiro-Wilk test for normality.  Argument <x> is a list of
     numbers, and sample size must be greater than 2 and less or equal
     than 5000, otherwise, function ‘test_normality’ signals an error
     message.

     Reference:

     [1] Algorithm AS R94, Applied Statistics (1995), vol.44, no.4,
     547-551

     The output of function ‘test_normality’ is an ‘inference_result’
     Maxima object with the following results:

       1. ‘'statistic’: value of the <W> statistic.

       2. ‘'p_value’: p-value under normal assumption.

     Examples:

     Checks for the normality of a population, based on a sample of size
     9.

          (%i1) load("stats")$
          (%i2) x:[12,15,17,38,42,10,23,35,28]$
          (%i3) test_normality(x);
                                 |      SHAPIRO - WILK TEST
                                 |
          (%o3)                  | statistic = .9251055695162436
                                 |
                                 |  p_value = .4361763918860381

 -- Function: linear_regression
          linear_regression (<x>)
          linear_regression (<x> <option>)

     Multivariate linear regression, y_i = b0 + b1*x_1i + b2*x_2i + ...
     + bk*x_ki + u_i, where u_i are N(0,sigma) independent random
     variables.  Argument <x> must be a matrix with more than one
     column.  The last column is considered as the responses (y_i).

     Option:

        • ‘'conflevel’, default ‘95/100’, confidence level for the
          confidence intervals; it must be an expression which takes a
          value in (0,1).

     The output of function ‘linear_regression’ is an ‘inference_result’
     Maxima object with the following results:

       1. ‘'b_estimation’: regression coefficients estimates.

       2. ‘'b_covariances’: covariance matrix of the regression
          coefficients estimates.

       3. ‘b_conf_int’: confidence intervals of the regression
          coefficients.

       4. ‘b_statistics’: statistics for testing coefficient.

       5. ‘b_p_values’: p-values for coefficient tests.

       6. ‘b_distribution’: probability distribution for coefficient
          tests.

       7. ‘v_estimation’: unbiased variance estimator.

       8. ‘v_conf_int’: variance confidence interval.

       9. ‘v_distribution’: probability distribution for variance test.

       10. ‘residuals’: residuals.

       11. ‘adc’: adjusted determination coefficient.

       12. ‘aic’: Akaike's information criterion.

       13. ‘bic’: Bayes's information criterion.

     Only items 1, 4, 5, 6, 7, 8, 9 and 11 above, in this order, are
     shown by default.  The rest remain hidden until the user makes use
     of functions ‘items_inference’ and ‘take_inference’.

     Example:

     Fitting a linear model to a trivariate sample.  The last column is
     considered as the responses (y_i).

          (%i2) load("stats")$
          (%i3) X:matrix(
              [58,111,64],[84,131,78],[78,158,83],
              [81,147,88],[82,121,89],[102,165,99],
              [85,174,101],[102,169,102])$
          (%i4) fpprintprec: 4$
          (%i5) res: linear_regression(X);
                       |       LINEAR REGRESSION MODEL
                       |
                       | b_estimation = [9.054, .5203, .2397]
                       |
                       | b_statistics = [.6051, 2.246, 1.74]
                       |
                       | b_p_values = [.5715, .07466, .1423]
                       |
          (%o5)        |   b_distribution = [student_t, 5]
                       |
                       |         v_estimation = 35.27
                       |
                       |     v_conf_int = [13.74, 212.2]
                       |
                       |      v_distribution = [chi2, 5]
                       |
                       |             adc = .7922
          (%i6) items_inference(res);
          (%o6) [b_estimation, b_covariances, b_conf_int, b_statistics,
          b_p_values, b_distribution, v_estimation, v_conf_int,
          v_distribution, residuals, adc, aic, bic]
          (%i7) take_inference('b_covariances, res);
                            [  223.9    - 1.12   - .8532  ]
                            [                             ]
          (%o7)             [ - 1.12    .05367   - .02305 ]
                            [                             ]
                            [ - .8532  - .02305   .01898  ]
          (%i8) take_inference('bic, res);
          (%o8)                          30.98
          (%i9) load("draw")$
          (%i10) draw2d(
              points_joined = true,
              grid = true,
              points(take_inference('residuals, res)) )$


File: maxima.info,  Node: Functions and Variables for special distributions,  Prev: Functions and Variables for stats,  Up: Package stats

95.4 Functions and Variables for special distributions
======================================================

 -- Function: pdf_signed_rank (<x>, <n>)
     Probability density function of the exact distribution of the
     signed rank statistic.  Argument <x> is a real number and <n> a
     positive integer.

     See also *note test_signed_rank::.

 -- Function: cdf_signed_rank (<x>, <n>)
     Cumulative distribution function of the exact distribution of the
     signed rank statistic.  Argument <x> is a real number and <n> a
     positive integer.

     See also *note test_signed_rank::.

 -- Function: pdf_rank_sum (<x>, <n>, <m>)
     Probability density function of the exact distribution of the rank
     sum statistic.  Argument <x> is a real number and <n> and <m> are
     both positive integers.

     See also *note test_rank_sum::.

 -- Function: cdf_rank_sum (<x>, <n>, <m>)
     Cumulative distribution function of the exact distribution of the
     rank sum statistic.  Argument <x> is a real number and <n> and <m>
     are both positive integers.

     See also *note test_rank_sum::.


File: maxima.info,  Node: Package stirling,  Next: Package stringproc,  Prev: Package stats,  Up: Top

96 Package stirling
*******************

* Menu:

* Functions and Variables for stirling::


File: maxima.info,  Node: Functions and Variables for stirling,  Prev: Package stirling,  Up: Package stirling

96.1 Functions and Variables for stirling
=========================================

 -- Function: stirling
          stirling (<z>,<n>)
          stirling (<z>,<n>,<pred>)

     Replace ‘gamma(x)’ with the O(1/x^{2n-1}) Stirling formula.  when
     <n> isn't a nonnegative integer, signal an error.  With the
     optional third argument ‘pred’, the Stirling formula is applied
     only when ‘pred’ is true.

     Reference: Abramowitz & Stegun, " Handbook of mathematical
     functions", 6.1.40.

     Examples:
          (%i1) load ("stirling")$

          (%i2) stirling(gamma(%alpha+x)/gamma(x),1);
                 1/2 - x             x + %alpha - 1/2
          (%o2) x        (x + %alpha)
                                             1           1
                                      --------------- - ---- - %alpha
                                      12 (x + %alpha)   12 x
                                    %e
          (%i3) taylor(%,x,inf,1);
                              %alpha       2    %alpha
                    %alpha   x       %alpha  - x       %alpha
          (%o3)/T/ x       + -------------------------------- + . . .
                                           2 x
          (%i4) map('factor,%);
                                                 %alpha - 1
                   %alpha   (%alpha - 1) %alpha x
          (%o4)   x       + -------------------------------
                                            2

     The function ‘stirling’ knows the difference between the variable
     'gamma' and the function gamma:

          (%i5) stirling(gamma + gamma(x),0);
                                              x - 1/2   - x
          (%o5)    gamma + sqrt(2) sqrt(%pi) x        %e
          (%i6) stirling(gamma(y) + gamma(x),0);
                                   y - 1/2   - y
          (%o6) sqrt(2) sqrt(%pi) y        %e
                                                        x - 1/2   - x
                                   + sqrt(2) sqrt(%pi) x        %e

     To apply the Stirling formula only to terms that involve the
     variable ‘k’, use an optional third argument; for example
          (%i7) makegamma(pochhammer(a,k)/pochhammer(b,k));
          (%o7) (gamma(b)*gamma(k+a))/(gamma(a)*gamma(k+b))
          (%i8) stirling(%,1, lambda([s], not(freeof(k,s))));
          (%o8) (%e^(b-a)*gamma(b)*(k+a)^(k+a-1/2)*(k+b)^(-k-b+1/2))/gamma(a)
     The terms ‘gamma(a)’ and ‘gamma(b)’ are free of ‘k’, so the
     Stirling formula was not applied to these two terms.

     To use this function write first ‘load("stirling")’.


File: maxima.info,  Node: Package stringproc,  Next: Package sym,  Prev: Package stirling,  Up: Top

97 Package stringproc
*********************

* Menu:

* Introduction to String Processing::
* String Input and Output::
* Characters::
* String Processing::
* Octets and Utilities for Cryptography::
* Regular Expressions::


File: maxima.info,  Node: Introduction to String Processing,  Next: String Input and Output,  Prev: Package stringproc,  Up: Package stringproc

97.1 Introduction to String Processing
======================================

The package ‘stringproc’ contains functions for processing strings and
characters including formatting, encoding and data streams.  This
package is completed by some tools for cryptography, e.g.  base64 and
hash functions.

   It can be directly loaded via ‘load("stringproc")’ or automatically
by using one of its functions.

   For questions and bug reports please contact the author.  The
following command prints his e-mail-address.

   ‘printf(true, "~{~a~}@gmail.com", split(sdowncase("Volker van
Nek")))$’

   A string is constructed by typing e.g.  ‘"Text"’.  When the option
variable ‘stringdisp’ is set to ‘false’, which is the default, the
double quotes won't be printed.  *note stringp:: is a test, if an object
is a string.

     (%i1) str: "Text";
     (%o1)                         Text
     (%i2) stringp(str);
     (%o2)                         true

   Characters are represented by a string of length 1.  *note charp:: is
the corresponding test.

     (%i1) char: "e";
     (%o1)                           e
     (%i2) charp(char);
     (%o2)                         true

   In Maxima position indices in strings are like in list 1-indexed
which results to the following consistency.

     (%i1) is(charat("Lisp",1) = charlist("Lisp")[1]);
     (%o1)                         true

   A string may contain Maxima expressions.  These can be parsed with
*note parse_string::.

     (%i1) map(parse_string, ["42" ,"sqrt(2)", "%pi"]);
     (%o1)                   [42, sqrt(2), %pi]
     (%i2) map('float, %);
     (%o2)        [42.0, 1.414213562373095, 3.141592653589793]

   Strings can be processed as characters or in binary form as octets.
Functions for conversions are *note string_to_octets:: and *note
octets_to_string::.  Usable encodings depend on the platform, the
application and the underlying Lisp.  (The following shows Maxima in
GNU/Linux, compiled with SBCL.)

     (%i1) obase: 16.$
     (%i2) string_to_octets("$£€", "cp1252");
     (%o2)                     [24, 0A3, 80]
     (%i3) string_to_octets("$£€", "utf-8");
     (%o3)               [24, 0C2, 0A3, 0E2, 82, 0AC]

   Strings may be written to character streams or as octets to binary
streams.  The following example demonstrates file in and output of
characters.

   *note openw:: returns an output stream to a file, *note printf::
writes formatted to that file and by e.g.  *note close:: all characters
contained in the stream are written to the file.

     (%i1) s: openw("file.txt");
     (%o1)                #<output stream file.txt>
     (%i2) printf(s, "~%~d ~f ~a ~a ~f ~e ~a~%",
     42, 1.234, sqrt(2), %pi, 1.0e-2, 1.0e-2, 1.0b-2)$
     (%i3) close(s)$

   *note openr:: then returns an input stream from the previously used
file and *note readline:: returns the line read as a string.  The string
may be tokenized by e.g.  *note split:: or *note tokens:: and finally
parsed by *note parse_string::.

     (%i4) s: openr("file.txt");
     (%o4)                 #<input stream file.txt>
     (%i5) readline(s);
     (%o5)          42 1.234 sqrt(2) %pi 0.01 1.0E-2 1.0b-2
     (%i6) map(parse_string, split(%));
     (%o6)       [42, 1.234, sqrt(2), %pi, 0.01, 0.01, 1.0b-2]
     (%i7) close(s)$


File: maxima.info,  Node: String Input and Output,  Next: Characters,  Prev: Introduction to String Processing,  Up: Package stringproc

97.2 String Input and Output
============================

Example: Formatted printing to a file.

     (%i1) s: openw("file.txt");
     (%o1)                      #<output stream file.txt>
     (%i2) control:
     "~2tAn atom: ~20t~a~%~2tand a list: ~20t~{~r ~}~%~2t\
     and an integer: ~20t~d~%"$
     (%i3) printf( s,control, 'true,[1,2,3],42 )$
     (%o3)                                false
     (%i4) close(s);
     (%o4)                                true
     (%i5) s: openr("file.txt");
     (%o5)                      #<input stream file.txt>
     (%i6) while stringp( tmp:readline(s) ) do print(tmp)$
       An atom:          true
       and a list:       one two three
       and an integer:   42
     (%i7) close(s)$

 -- Function: close (<stream>)

     Closes <stream> and returns ‘true’ if <stream> had been open.

 -- Function: flength (<stream>)

     <stream> has to be an open stream from or to a file.  ‘flength’
     then returns the number of bytes which are currently present in
     this file.

     Example: See *note writebyte:: .

 -- Function: flush_output (<stream>)

     Flushes <stream> where <stream> has to be an output stream to a
     file.

     Example: See *note writebyte:: .

 -- Function: fposition
          fposition (<stream>)
          fposition (<stream>, <pos>)

     Returns the current position in <stream>, if <pos> is not used.  If
     <pos> is used, ‘fposition’ sets the position in <stream>.  <stream>
     has to be a stream from or to a file and <pos> has to be a positive
     number.

     Positions in data streams are like in strings or lists 1-indexed,
     i.e.  the first element in <stream> is in position 1.

 -- Function: freshline
          freshline ()
          freshline (<stream>)

     Writes a new line to the standard output stream if the position is
     not at the beginning of a line and returns ‘true’.  Using the
     optional argument <stream> the new line is written to that stream.
     There are some cases, where ‘freshline()’ does not work as
     expected.

     See also *note newline::.

 -- Function: get_output_stream_string (<stream>)

     Returns a string containing all the characters currently present in
     <stream> which must be an open string-output stream.  The returned
     characters are removed from <stream>.

     Example: See *note make_string_output_stream:: .

 -- Function: make_string_input_stream
          make_string_input_stream (<string>)
          make_string_input_stream (<string>, <start>)
          make_string_input_stream (<string>, <start>, <end>)

     Returns an input stream which contains parts of <string> and an end
     of file.  Without optional arguments the stream contains the entire
     string and is positioned in front of the first character.  <start>
     and <end> define the substring contained in the stream.  The first
     character is available at position 1.

          (%i1) istream : make_string_input_stream("text", 1, 4);
          (%o1)              #<string-input stream from "text">
          (%i2) (while (c : readchar(istream)) # false do sprint(c), newline())$
          t e x
          (%i3) close(istream)$

 -- Function: make_string_output_stream ()

     Returns an output stream that accepts characters.  Characters
     currently present in this stream can be retrieved by *note
     get_output_stream_string::.

          (%i1) ostream : make_string_output_stream();
          (%o1)               #<string-output stream 09622ea0>
          (%i2) printf(ostream, "foo")$

          (%i3) printf(ostream, "bar")$

          (%i4) string : get_output_stream_string(ostream);
          (%o4)                            foobar
          (%i5) printf(ostream, "baz")$

          (%i6) string : get_output_stream_string(ostream);
          (%o6)                              baz
          (%i7) close(ostream)$

 -- Function: newline
          newline ()
          newline (<stream>)

     Writes a new line to the standard output stream.  Using the
     optional argument <stream> the new line is written to that stream.
     There are some cases, where ‘newline()’ does not work as expected.

     See *note sprint:: for an example of using ‘newline()’.

 -- Function: opena (<file>)

     Returns a character output stream to <file>.  If an existing file
     is opened, ‘opena’ appends elements at the end of <file>.

     For binary output see *note opena_binary: Functions and Variables
     for binary input and output. .

 -- Function: openr
          openr (<file>)
          openr (<file>, <encoding>)

     Returns a character input stream to <file>.  ‘openr’ assumes that
     <file> already exists.  If reading the file results in a lisp error
     about its encoding passing the correct string as the argument
     <encoding> might help.  The available encodings and their names
     depend on the lisp being used.  For sbcl a list of suitable strings
     can be found at <http://www.sbcl.org/manual/#External-Formats>.

     For binary input see *note openr_binary: Functions and Variables
     for binary input and output. .  See also ‘close’ and *note openw::.

          (%i1) istream : openr("data.txt","EUC-JP");
          (%o1)     #<FD-STREAM for "file /home/gunter/data.txt" {10099A3AE3}>
          (%i2) close(istream);
          (%o2)                                true

 -- Function: openw (<file>)

     Returns a character output stream to <file>.  If <file> does not
     exist, it will be created.  If an existing file is opened, ‘openw’
     destructively modifies <file>.

     For binary output see *note openw_binary: Functions and Variables
     for binary input and output. .

     See also ‘close’ and *note openr::.

 -- Function: printf
          printf (<dest>, <string>)
          printf (<dest>, <string>, <expr_1>, ..., <expr_n>)

     Produces formatted output by outputting the characters of
     control-string <string> and observing that a tilde introduces a
     directive.  The character after the tilde, possibly preceded by
     prefix parameters and modifiers, specifies what kind of formatting
     is desired.  Most directives use one or more elements of the
     arguments <expr_1>, ..., <expr_n> to create their output.

     If <dest> is a stream or ‘true’, then ‘printf’ returns ‘false’.
     Otherwise, ‘printf’ returns a string containing the output.  By
     default the streams <stdin>, <stdout> and <stderr> are defined.  If
     Maxima is running as a network client (which is the normal case if
     Maxima is communicating with a graphical user interface, which must
     be the server) ‘setup-client’ will define <old_stdout> and
     <old_stderr>, too.

     ‘printf’ provides the Common Lisp function ‘format’ in Maxima.  The
     following example illustrates the general relation between these
     two functions.

          (%i1) printf(true, "R~dD~d~%", 2, 2);
          R2D2
          (%o1)                                false
          (%i2) :lisp (format t "R~dD~d~%" 2 2)
          R2D2
          NIL

     The following description is limited to a rough sketch of the
     possibilities of ‘printf’.  The Lisp function ‘format’ is described
     in detail in many reference books.  Of good help is e.g.  the free
     available online-manual "Common Lisp the Language" by Guy L.
     Steele.  See chapter 22.3.3 there.

     In addition, ‘printf’ recognizes two format directives which are
     not known to Lisp ‘format’.  The format directive ‘~m’ indicates
     Maxima pretty printer output.  The format directive ‘~h’ indicates
     a bigfloat number.

             ~%       new line
             ~&       fresh line
             ~t       tab
             ~$       monetary
             ~d       decimal integer
             ~b       binary integer
             ~o       octal integer
             ~x       hexadecimal integer
             ~br      base-b integer
             ~r       spell an integer
             ~p       plural
             ~f       floating point
             ~e       scientific notation
             ~g       ~f or ~e, depending upon magnitude
             ~h       bigfloat
             ~a       uses Maxima function string
             ~m       Maxima pretty printer output
             ~s       like ~a, but output enclosed in "double quotes"
             ~~       ~
             ~<       justification, ~> terminates
             ~(       case conversion, ~) terminates
             ~[       selection, ~] terminates
             ~{       iteration, ~} terminates

     Note that the directive ~* is not supported.

     If <dest> is a stream or ‘true’, then ‘printf’ returns ‘false’.
     Otherwise, ‘printf’ returns a string containing the output.

          (%i1) printf( false, "~a ~a ~4f ~a ~@r",
                        "String",sym,bound,sqrt(12),144), bound = 1.234;
          (%o1)                 String sym 1.23 2*sqrt(3) CXLIV
          (%i2) printf( false,"~{~a ~}",["one",2,"THREE"] );
          (%o2)                          one 2 THREE
          (%i3) printf(true,"~{~{~9,1f ~}~%~}",mat ),
                    mat = args(matrix([1.1,2,3.33],[4,5,6],[7,8.88,9]))$
                1.1       2.0       3.3
                4.0       5.0       6.0
                7.0       8.9       9.0
          (%i4) control: "~:(~r~) bird~p ~[is~;are~] singing."$
          (%i5) printf( false,control, n,n,if n=1 then 1 else 2 ), n=2;
          (%o5)                    Two birds are singing.

     The directive ~h has been introduced to handle bigfloats.

          ~w,d,e,x,o,p@H
           w : width
           d : decimal digits behind floating point
           e : minimal exponent digits
           x : preferred exponent
           o : overflow character
           p : padding character
           @ : display sign for positive numbers

          (%i1) fpprec : 1000$
          (%i2) printf(true, "|~h|~%", 2.b0^-64)$
          |0.0000000000000000000542101086242752217003726400434970855712890625|
          (%i3) fpprec : 26$
          (%i4) printf(true, "|~h|~%", sqrt(2))$
          |1.4142135623730950488016887|
          (%i5) fpprec : 24$
          (%i6) printf(true, "|~h|~%", sqrt(2))$
          |1.41421356237309504880169|
          (%i7) printf(true, "|~28h|~%", sqrt(2))$
          |   1.41421356237309504880169|
          (%i8) printf(true, "|~28,,,,,'*h|~%", sqrt(2))$
          |***1.41421356237309504880169|
          (%i9) printf(true, "|~,18h|~%", sqrt(2))$
          |1.414213562373095049|
          (%i10) printf(true, "|~,,,-3h|~%", sqrt(2))$
          |1414.21356237309504880169b-3|
          (%i11) printf(true, "|~,,2,-3h|~%", sqrt(2))$
          |1414.21356237309504880169b-03|
          (%i12) printf(true, "|~20h|~%", sqrt(2))$
          |1.41421356237309504880169|
          (%i13) printf(true, "|~20,,,,'+h|~%", sqrt(2))$
          |++++++++++++++++++++|

     For conversion of objects to strings also see ‘concat’, ‘sconcat’,
     ‘string’ and *note simplode::.

 -- Function: readbyte (<stream>)

     Removes and returns the first byte in <stream> which must be a
     binary input stream.  If the end of file is encountered ‘readbyte’
     returns ‘false’.

     Example: Read the first 16 bytes from a file encrypted with AES in
     OpenSSL.

          (%i1) ibase: obase: 16.$

          (%i2) in: openr_binary("msg.bin");
          (%o2)                       #<input stream msg.bin>
          (%i3) (L:[],  thru 16. do push(readbyte(in), L),  L:reverse(L));
          (%o3) [53, 61, 6C, 74, 65, 64, 5F, 5F, 88, 56, 0DE, 8A, 74, 0FD,
                 0AD, 0F0]
          (%i4) close(in);
          (%o4)                                true
          (%i5) map(ascii, rest(L,-8));
          (%o5)                      [S, a, l, t, e, d, _, _]
          (%i6) salt: octets_to_number(rest(L,8));
          (%o6)                          8856de8a74fdadf0

 -- Function: readchar (<stream>)

     Removes and returns the first character in <stream>.  If the end of
     file is encountered ‘readchar’ returns ‘false’.

     Example: See *note make_string_input_stream::.

 -- Function: readline (<stream>)

     Returns a string containing all characters starting at the current
     position in <stream> up to the end of the line or ‘false’ if the
     end of the file is encountered.

 -- Function: sprint (<expr_1>, ..., <expr_n>)

     Evaluates and displays its arguments one after the other 'on a
     line' starting at the leftmost position.  The expressions are
     printed with a space character right next to the number, and it
     disregards line length.  ‘newline()’ might be used for line
     breaking.

     Example: Sequential printing with ‘sprint’.  Creating a new line
     with ‘newline()’.

          (%i1) for n:0 thru 19 do sprint(fib(n))$
          0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
          (%i2) for n:0 thru 22 do (
                   sprint(fib(n)),
                   if mod(n,10) = 9 then newline() )$
          0 1 1 2 3 5 8 13 21 34
          55 89 144 233 377 610 987 1597 2584 4181
          6765 10946 17711

 -- Function: writebyte (<byte>, <stream>)

     Writes <byte> to <stream> which must be a binary output stream.
     ‘writebyte’ returns ‘byte’.

     Example: Write some bytes to a binary file output stream.  In this
     example all bytes correspond to printable characters and are
     printed by ‘printfile’.  The bytes remain in the stream until
     ‘flush_output’ or ‘close’ have been called.

          (%i1) ibase: obase: 16.$

          (%i2) bytes: map(cint, charlist("GNU/Linux"));
          (%o2)                [47, 4E, 55, 2F, 4C, 69, 6E, 75, 78]
          (%i3) out: openw_binary("test.bin");
          (%o3)                      #<output stream test.bin>
          (%i4) for i thru 3 do writebyte(bytes[i], out);
          (%o4)                                done
          (%i5) printfile("test.bin")$

          (%i6) flength(out);
          (%o6)                                  0
          (%i7) flush_output(out);
          (%o7)                                true
          (%i8) flength(out);
          (%o8)                                  3
          (%i9) printfile("test.bin")$
          GNU
          (%i0A) for b in rest(bytes,3) do writebyte(b, out);
          (%o0A)                               done
          (%i0B) close(out);
          (%o0B)                               true
          (%i0C) printfile("test.bin")$
          GNU/Linux


File: maxima.info,  Node: Characters,  Next: String Processing,  Prev: String Input and Output,  Up: Package stringproc

97.3 Characters
===============

Characters are strings of length 1.

 -- Function: adjust_external_format ()

     Prints information about the current external format of the Lisp
     reader and in case the external format encoding differs from the
     encoding of the application which runs Maxima
     ‘adjust_external_format’ tries to adjust the encoding or prints
     some help or instruction.  ‘adjust_external_format’ returns ‘true’
     when the external format has been changed and ‘false’ otherwise.

     Functions like *note cint::, *note unicode::, *note
     octets_to_string:: and *note string_to_octets:: need UTF-8 as the
     external format of the Lisp reader to work properly over the full
     range of Unicode characters.

     Examples (Maxima on Windows, March 2016): Using
     ‘adjust_external_format’ when the default external format is not
     equal to the encoding provided by the application.

     1.  Command line Maxima

     In case a terminal session is preferred it is recommended to use
     Maxima compiled with SBCL. Here Unicode support is provided by
     default and calls to ‘adjust_external_format’ are unnecessary.

     If Maxima is compiled with CLISP or GCL it is recommended to change
     the terminal encoding from CP850 to CP1252.
     ‘adjust_external_format’ prints some help.

     CCL reads UTF-8 while the terminal input is CP850 by default.
     CP1252 is not supported by CCL. ‘adjust_external_format’ prints
     instructions for changing the terminal encoding and external format
     both to iso-8859-1.

     2.  wxMaxima

     In wxMaxima SBCL reads CP1252 by default but the input from the
     application is UTF-8 encoded.  Adjustment is needed.

     Calling ‘adjust_external_format’ and restarting Maxima permanently
     changes the default external format to UTF-8.

          (%i1)adjust_external_format();
          The line
          (setf sb-impl::*default-external-format* :utf-8)
          has been appended to the init file
          C:/Users/Username/.sbclrc
          Please restart Maxima to set the external format to UTF-8.
          (%i1) false

     Restarting Maxima.

          (%i1) adjust_external_format();
          The external format is currently UTF-8
          and has not been changed.
          (%i1) false

 -- Function: alphacharp (<char>)

     Returns ‘true’ if <char> is an alphabetic character.

     To identify a non-US-ASCII character as an alphabetic character the
     underlying Lisp must provide full Unicode support.  E.g.  a German
     umlaut is detected as an alphabetic character with SBCL in
     GNU/Linux but not with GCL. (In Windows Maxima, when compiled with
     SBCL, must be set to UTF-8.  See *note adjust_external_format:: for
     more.)

     Example: Examination of non-US-ASCII characters.

     The underlying Lisp (SBCL, GNU/Linux) is able to convert the typed
     character into a Lisp character and to examine.

          (%i1) alphacharp("ü");
          (%o1)                          true

     In GCL this is not possible.  An error break occurs.

          (%i1) alphacharp("u");
          (%o1)                          true
          (%i2) alphacharp("ü");

          package stringproc: ü cannot be converted into a Lisp character.
           -- an error.

 -- Function: alphanumericp (<char>)

     Returns ‘true’ if <char> is an alphabetic character or a digit
     (only corresponding US-ASCII characters are regarded as digits).

     Note: See remarks on *note alphacharp::.

 -- Function: ascii (<int>)

     Returns the US-ASCII character corresponding to the integer <int>
     which has to be less than ‘128’.

     See *note unicode:: for converting code points larger than ‘127’.

     Examples:

          (%i1) for n from 0 thru 127 do (
                  ch: ascii(n),
                  if alphacharp(ch) then sprint(ch),
                  if n = 96 then newline() )$
          A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
          a b c d e f g h i j k l m n o p q r s t u v w x y z

 -- Function: cequal (<char_1>, <char_2>)

     Returns ‘true’ if <char_1> and <char_2> are the same character.

 -- Function: cequalignore (<char_1>, <char_2>)

     Like ‘cequal’ but ignores case which is only possible for
     non-US-ASCII characters when the underlying Lisp is able to
     recognize a character as an alphabetic character.  See remarks on
     *note alphacharp::.

 -- Function: cgreaterp (<char_1>, <char_2>)

     Returns ‘true’ if the code point of <char_1> is greater than the
     code point of <char_2>.

 -- Function: cgreaterpignore (<char_1>, <char_2>)

     Like ‘cgreaterp’ but ignores case which is only possible for
     non-US-ASCII characters when the underlying Lisp is able to
     recognize a character as an alphabetic character.  See remarks on
     *note alphacharp::.

 -- Function: charp (<obj>)

     Returns ‘true’ if <obj> is a Maxima-character.  See introduction
     for example.

 -- Function: cint (<char>)

     Returns the Unicode code point of <char> which must be a Maxima
     character, i.e.  a string of length ‘1’.

     Examples: The hexadecimal code point of some characters (Maxima
     with SBCL on GNU/Linux).

          (%i1) obase: 16.$
          (%i2) map(cint, ["$","£","€"]);
          (%o2)                           [24, 0A3, 20AC]

     Warning: It is not possible to enter characters corresponding to
     code points larger than 16 bit in wxMaxima with SBCL on Windows
     when the external format has not been set to UTF-8.  See *note
     adjust_external_format::.

     CMUCL doesn't process these characters as one character.  ‘cint’
     then returns ‘false’.  Converting a character to a code point via
     UTF-8-octets may serve as a workaround:

     ‘utf8_to_unicode(string_to_octets(character));’

     See *note utf8_to_unicode::, *note string_to_octets::.

 -- Function: clessp (<char_1>, <char_2>)

     Returns ‘true’ if the code point of <char_1> is less than the code
     point of <char_2>.

 -- Function: clesspignore (<char_1>, <char_2>)

     Like ‘clessp’ but ignores case which is only possible for
     non-US-ASCII characters when the underlying Lisp is able to
     recognize a character as an alphabetic character.  See remarks on
     *note alphacharp::.

 -- Function: constituent (<char>)

     Returns ‘true’ if <char> is a graphic character but not a space
     character.  A graphic character is a character one can see, plus
     the space character.  (‘constituent’ is defined by Paul Graham.
     See Paul Graham, ANSI Common Lisp, 1996, page 67.)

          (%i1) for n from 0 thru 255 do (
          tmp: ascii(n), if constituent(tmp) then sprint(tmp) )$
          ! " #  %  ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B
          C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c
          d e f g h i j k l m n o p q r s t u v w x y z { | } ~

 -- Function: digitcharp (<char>)

     Returns ‘true’ if <char> is a digit where only the corresponding
     US-ASCII-character is regarded as a digit.

 -- Function: lowercasep (<char>)

     Returns ‘true’ if <char> is a lowercase character.

     Note: See remarks on *note alphacharp::.

 -- Variable: newline

     The newline character (ASCII-character 10).

 -- Variable: space

     The space character.

 -- Variable: tab

     The tab character.

 -- Function: unicode (<arg>)

     Returns the character defined by <arg> which might be a Unicode
     code point or a name string if the underlying Lisp provides full
     Unicode support.

     Example: Characters defined by hexadecimal code points (Maxima with
     SBCL on GNU/Linux).

          (%i1) ibase: 16.$
          (%i2) map(unicode, [24, 0A3, 20AC]);
          (%o2)                            [$, £, €]

     Warning: In wxMaxima with SBCL on Windows it is not possible to
     convert code points larger than 16 bit to characters when the
     external format has not been set to UTF-8.  See *note
     adjust_external_format:: for more information.

     CMUCL doesn't process code points larger than 16 bit.  In these
     cases ‘unicode’ returns ‘false’.  Converting a code point to a
     character via UTF-8 octets may serve as a workaround:

     ‘octets_to_string(unicode_to_utf8(code_point));’

     See *note octets_to_string::, *note unicode_to_utf8::.

     In case the underlying Lisp provides full Unicode support the
     character might be specified by its name.  The following is
     possible in ECL, CLISP and SBCL, where in SBCL on Windows the
     external format has to be set to UTF-8.  ‘unicode(name)’ is
     supported by CMUCL too but again limited to 16 bit characters.

     The string argument to ‘unicode’ is basically the same string
     returned by ‘printf’ using the "~@c" specifier.  But as shown below
     the prefix "#\" must be omitted.  Underlines might be replaced by
     spaces and uppercase letters by lowercase ones.

     Example (continued): Characters defined by names (Maxima with SBCL
     on GNU/Linux).

          (%i3) printf(false, "~@c", unicode(0DF));
          (%o3)                    #\LATIN_SMALL_LETTER_SHARP_S
          (%i4) unicode("LATIN_SMALL_LETTER_SHARP_S");
          (%o4)                                  ß
          (%i5) unicode("Latin small letter sharp s");
          (%o5)                                  ß

 -- Function: unicode_to_utf8 (<code_point>)

     Returns a list containing the UTF-8 code corresponding to the
     Unicode <code_point>.

     Examples: Converting Unicode code points to UTF-8 and vice versa.

          (%i1) ibase: obase: 16.$
          (%i2) map(cint, ["$","£","€"]);
          (%o2)                           [24, 0A3, 20AC]
          (%i3) map(unicode_to_utf8, %);
          (%o3)                 [[24], [0C2, 0A3], [0E2, 82, 0AC]]
          (%i4) map(utf8_to_unicode, %);
          (%o4)                           [24, 0A3, 20AC]

 -- Function: uppercasep (<char>)

     Returns ‘true’ if <char> is an uppercase character.

     Note: See remarks on *note alphacharp::.

 -- Variable: us_ascii_only

     This option variable affects Maxima when the character encoding
     provided by the application which runs Maxima is UTF-8 but the
     external format of the Lisp reader is not equal to UTF-8.

     On GNU/Linux this is true when Maxima is built with GCL and on
     Windows in wxMaxima with GCL- and SBCL-builds.  With SBCL it is
     recommended to change the external format to UTF-8.  Setting
     ‘us_ascii_only’ is unnecessary then.  See *note
     adjust_external_format:: for details.

     ‘us_ascii_only’ is ‘false’ by default.  Maxima itself then (i.e.
     in the above described situation) parses the UTF-8 encoding.

     When ‘us_ascii_only’ is set to ‘true’ it is assumed that all
     strings used as arguments to string processing functions do not
     contain Non-US-ASCII characters.  Given that promise, Maxima avoids
     parsing UTF-8 and strings can be processed more efficiently.

 -- Function: utf8_to_unicode (<list>)

     Returns a Unicode code point corresponding to the <list> which must
     contain the UTF-8 encoding of a single character.

     Examples: See *note unicode_to_utf8::.


File: maxima.info,  Node: String Processing,  Next: Octets and Utilities for Cryptography,  Prev: Characters

97.4 String Processing
======================

Position indices in strings are 1-indexed like in Maxima lists.  See
example in *note charat::.

 -- Function: charat (<string>, <n>)

     Returns the <n>-th character of <string>.  The first character in
     <string> is returned with <n> = 1.

          (%i1) charat("Lisp",1);
          (%o1)                           L
          (%i2) charlist("Lisp")[1];
          (%o2)                           L

 -- Function: charlist (<string>)

     Returns the list of all characters in <string>.

          (%i1) charlist("Lisp");
          (%o1)                     [L, i, s, p]

 -- Function: eval_string (<str>)

     Parse the string <str> as a Maxima expression and evaluate it.  The
     string <str> may or may not have a terminator (dollar sign ‘$’ or
     semicolon ‘;’).  Only the first expression is parsed and evaluated,
     if there is more than one.

     Complain if <str> is not a string.

     Examples:

          (%i1) eval_string ("foo: 42; bar: foo^2 + baz");
          (%o1)                       42
          (%i2) eval_string ("(foo: 42, bar: foo^2 + baz)");
          (%o2)                   baz + 1764

     See also *note parse_string:: and *note eval_string_lisp::.

 -- Function: parse_string (<str>)

     Parse the string <str> as a Maxima expression (do not evaluate it).
     The string <str> may or may not have a terminator (dollar sign ‘$’
     or semicolon ‘;’).  Only the first expression is parsed, if there
     is more than one.

     Complain if <str> is not a string.

     Examples:

          (%i1) parse_string ("foo: 42; bar: foo^2 + baz");
          (%o1)                    foo : 42
          (%i2) parse_string ("(foo: 42, bar: foo^2 + baz)");
                                             2
          (%o2)          (foo : 42, bar : foo  + baz)

     See also *note eval_string::.

 -- Function: scopy (<string>)

     Returns a copy of <string> as a new string.

 -- Function: sdowncase
          sdowncase (<string>)
          sdowncase (<string>, <start>)
          sdowncase (<string>, <start>, <end>)

     Like *note supcase:: but uppercase characters are converted to
     lowercase.

 -- Function: sequal (<string_1>, <string_2>)

     Returns ‘true’ if <string_1> and <string_2> contain the same
     sequence of characters.

 -- Function: sequalignore (<string_1>, <string_2>)

     Like ‘sequal’ but ignores case which is only possible for
     non-US-ASCII characters when the underlying Lisp is able to
     recognize a character as an alphabetic character.  See remarks on
     *note alphacharp::.

 -- Function: sexplode (<string>)

     ‘sexplode’ is an alias for function ‘charlist’.

 -- Function: simplode
          simplode (<list>)
          simplode (<list>, <delim>)

     ‘simplode’ takes a list of expressions and concatenates them into a
     string.  If no delimiter <delim> is specified, ‘simplode’ uses no
     delimiter.  <delim> can be any string.

     See also ‘concat’, ‘sconcat’, ‘string’ and *note printf::.

     Examples:

          (%i1) simplode(["xx[",3,"]:",expand((x+y)^3)]);
          (%o1)             xx[3]:y^3+3*x*y^2+3*x^2*y+x^3
          (%i2) simplode( sexplode("stars")," * " );
          (%o2)                   s * t * a * r * s
          (%i3) simplode( ["One","more","coffee."]," " );
          (%o3)                   One more coffee.

 -- Function: sinsert (<seq>, <string>, <pos>)
     Returns a string that is a concatenation of ‘substring(<string>, 1,
     <pos>-1)’, the string <seq> and ‘substring (<string>, <pos>)’.
     Note that the first character in <string> is in position 1.

     Examples:

          (%i1) s: "A submarine."$
          (%i2) concat( substring(s,1,3),"yellow ",substring(s,3) );
          (%o2)                  A yellow submarine.
          (%i3) sinsert("hollow ",s,3);
          (%o3)                  A hollow submarine.

 -- Function: sinvertcase
          sinvertcase (<string>)
          sinvertcase (<string>, <start>)
          sinvertcase (<string>, <start>, <end>)

     Returns <string> except that each character from position <start>
     to <end> is inverted.  If <end> is not given, all characters from
     <start> to the end of <string> are replaced.

     Examples:

          (%i1) sinvertcase("sInvertCase");
          (%o1)                      SiNVERTcASE

 -- Function: slength (<string>)

     Returns the number of characters in <string>.

 -- Function: smake (<num>, <char>)

     Returns a new string with a number of <num> characters <char>.

     Example:

          (%i1) smake(3,"w");
          (%o1)                          www

 -- Function: smismatch
          smismatch (<string_1>, <string_2>)
          smismatch (<string_1>, <string_2>, <test>)

     Returns the position of the first character of <string_1> at which
     <string_1> and <string_2> differ or ‘false’.  Default test function
     for matching is ‘sequal’.  If ‘smismatch’ should ignore case, use
     ‘sequalignore’ as test.

     Example:

          (%i1) smismatch("seven","seventh");
          (%o1)                           6

 -- Function: split
          split (<string>)
          split (<string>, <delim>)
          split (<string>, <delim>, <multiple>)

     Returns the list of all tokens in <string>.  Each token is an
     unparsed string.  ‘split’ uses <delim> as delimiter.  If <delim> is
     not given, the space character is the default delimiter.
     <multiple> is a boolean variable with ‘true’ by default.  Multiple
     delimiters are read as one.  This is useful if tabs are saved as
     multiple space characters.  If <multiple> is set to ‘false’, each
     delimiter is noted.

     Examples:

          (%i1) split("1.2   2.3   3.4   4.5");
          (%o1)                 [1.2, 2.3, 3.4, 4.5]
          (%i2) split("first;;third;fourth",";",false);
          (%o2)               [first, , third, fourth]

 -- Function: sposition (<char>, <string>)
     Returns the position of the first character in <string> which
     matches <char>.  The first character in <string> is in position 1.
     For matching characters ignoring case see *note ssearch::.

 -- Function: sremove
          sremove (<seq>, <string>)
          sremove (<seq>, <string>, <test>)
          sremove (<seq>, <string>, <test>, <start>)
          sremove (<seq>, <string>, <test>, <start>, <end>)

     Returns a string like <string> but without all substrings matching
     <seq>.  Default test function for matching is ‘sequal’.  If
     ‘sremove’ should ignore case while searching for <seq>, use
     ‘sequalignore’ as test.  Use <start> and <end> to limit searching.
     Note that the first character in <string> is in position 1.

     Examples:

          (%i1) sremove("n't","I don't like coffee.");
          (%o1)                   I do like coffee.
          (%i2) sremove ("DO ",%,'sequalignore);
          (%o2)                    I like coffee.

 -- Function: sremovefirst
          sremovefirst (<seq>, <string>)
          sremovefirst (<seq>, <string>, <test>)
          sremovefirst (<seq>, <string>, <test>, <start>)
          sremovefirst (<seq>, <string>, <test>, <start>, <end>)

     Like ‘sremove’ except that only the first substring that matches
     <seq> is removed.

 -- Function: sreverse (<string>)

     Returns a string with all the characters of <string> in reverse
     order.

     See also *note reverse::.

 -- Function: ssearch
          ssearch (<seq>, <string>)
          ssearch (<seq>, <string>, <test>)
          ssearch (<seq>, <string>, <test>, <start>)
          ssearch (<seq>, <string>, <test>, <start>, <end>)

     Returns the position of the first substring of <string> that
     matches the string <seq>.  Default test function for matching is
     ‘sequal’.  If ‘ssearch’ should ignore case, use ‘sequalignore’ as
     test.  Use <start> and <end> to limit searching.  Note that the
     first character in <string> is in position 1.

     Example:

          (%i1) ssearch("~s","~{~S ~}~%",'sequalignore);
          (%o1)                                  4

 -- Function: ssort
          ssort (<string>)
          ssort (<string>, <test>)

     Returns a string that contains all characters from <string> in an
     order such there are no two successive characters <c> and <d> such
     that ‘test (<c>, <d>)’ is ‘false’ and ‘test (<d>, <c>)’ is ‘true’.
     Default test function for sorting is <clessp>.  The set of test
     functions is ‘{clessp, clesspignore, cgreaterp, cgreaterpignore,
     cequal, cequalignore}’.

     Examples:

          (%i1) ssort("I don't like Mondays.");
          (%o1)                    '.IMaddeiklnnoosty
          (%i2) ssort("I don't like Mondays.",'cgreaterpignore);
          (%o2)                 ytsoonnMlkIiedda.'

 -- Function: ssubst
          ssubst (<new>, <old>, <string>)
          ssubst (<new>, <old>, <string>, <test>)
          ssubst (<new>, <old>, <string>, <test>, <start>)
          ssubst (<new>, <old>, <string>, <test>, <start>, <end>)

     Returns a string like <string> except that all substrings matching
     <old> are replaced by <new>.  <old> and <new> need not to be of the
     same length.  Default test function for matching is ‘sequal’.  If
     ‘ssubst’ should ignore case while searching for old, use
     ‘sequalignore’ as test.  Use <start> and <end> to limit searching.
     Note that the first character in <string> is in position 1.

     Examples:

          (%i1) ssubst("like","hate","I hate Thai food. I hate green tea.");
          (%o1)          I like Thai food. I like green tea.
          (%i2) ssubst("Indian","thai",%,'sequalignore,8,12);
          (%o2)         I like Indian food. I like green tea.

 -- Function: ssubstfirst
          ssubstfirst (<new>, <old>, <string>)
          ssubstfirst (<new>, <old>, <string>, <test>)
          ssubstfirst (<new>, <old>, <string>, <test>, <start>)
          ssubstfirst (<new>, <old>, <string>, <test>, <start>, <end>)

     Like ‘subst’ except that only the first substring that matches
     <old> is replaced.

 -- Function: strim (<seq>,<string>)

     Returns a string like <string>, but with all characters that appear
     in <seq> removed from both ends.

     Examples:

          (%i1) "/* comment */"$
          (%i2) strim(" /*",%);
          (%o2)                        comment
          (%i3) slength(%);
          (%o3)                           7

 -- Function: striml (<seq>, <string>)

     Like ‘strim’ except that only the left end of <string> is trimmed.

 -- Function: strimr (<seq>, <string>)

     Like ‘strim’ except that only the right end of <string> is trimmed.

 -- Function: stringp (<obj>)

     Returns ‘true’ if <obj> is a string.  See introduction for example.

 -- Function: substring
          substring (<string>, <start>)
          substring (<string>, <start>, <end>)

     Returns the substring of <string> beginning at position <start> and
     ending at position <end>.  The character at position <end> is not
     included.  If <end> is not given, the substring contains the rest
     of the string.  Note that the first character in <string> is in
     position 1.

     Examples:

          (%i1) substring("substring",4);
          (%o1)                        string
          (%i2) substring(%,4,6);
          (%o2)                          in

 -- Function: supcase
          supcase (<string>)
          supcase (<string>, <start>)
          supcase (<string>, <start>, <end>)

     Returns <string> except that lowercase characters from position
     <start> to <end> are replaced by the corresponding uppercase ones.
     If <end> is not given, all lowercase characters from <start> to the
     end of <string> are replaced.

     Example:

          (%i1) supcase("english",1,2);
          (%o1)                        English

 -- Function: tokens
          tokens (<string>)
          tokens (<string>, <test>)

     Returns a list of tokens, which have been extracted from <string>.
     The tokens are substrings whose characters satisfy a certain test
     function.  If test is not given, <constituent> is used as the
     default test.  ‘{constituent, alphacharp, digitcharp, lowercasep,
     uppercasep, charp, characterp, alphanumericp}’ is the set of test
     functions.  (The Lisp-version of ‘tokens’ is written by Paul
     Graham.  ANSI Common Lisp, 1996, page 67.)

     Examples:

          (%i1) tokens("24 October 2005");
          (%o1)                  [24, October, 2005]
          (%i2) tokens("05-10-24",'digitcharp);
          (%o2)                     [05, 10, 24]
          (%i3) map(parse_string,%);
          (%o3)                      [5, 10, 24]


File: maxima.info,  Node: Octets and Utilities for Cryptography,  Next: Regular Expressions,  Prev: String Processing

97.5 Octets and Utilities for Cryptography
==========================================

 -- Function: base64 (<arg>)

     Returns the base64-representation of <arg> as a string.  The
     argument <arg> may be a string, a non-negative integer or a list of
     octets.

     Examples:

          (%i1) base64: base64("foo bar baz");
          (%o1)                          Zm9vIGJhciBiYXo=
          (%i2) string: base64_decode(base64);
          (%o2)                            foo bar baz
          (%i3) obase: 16.$
          (%i4) integer: base64_decode(base64, 'number);
          (%o4)                       666f6f206261722062617a
          (%i5) octets: base64_decode(base64, 'list);
          (%o5)            [66, 6F, 6F, 20, 62, 61, 72, 20, 62, 61, 7A]
          (%i6) ibase: 16.$
          (%i7) base64(octets);
          (%o7)                          Zm9vIGJhciBiYXo=

     Note that if <arg> contains umlauts (resp.  octets larger than 127)
     the resulting base64-string is platform dependent.  However the
     decoded string will be equal to the original.

 -- Function: base64_decode
          base64_decode (<base64-string>)
          base64_decode (<base64-string>, <return-type>)

     By default ‘base64_decode’ decodes the <base64-string> back to the
     original string.

     The optional argument <return-type> allows ‘base64_decode’ to
     alternatively return the corresponding number or list of octets.
     <return-type> may be ‘string’, ‘number’ or ‘list’.

     Example: See *note base64::.

 -- Function: crc24sum
          crc24sum (<octets>)
          crc24sum (<octets>, <return-type>)

     By default ‘crc24sum’ returns the ‘CRC24’ checksum of an octet-list
     as a string.

     The optional argument <return-type> allows ‘crc24sum’ to
     alternatively return the corresponding number or list of octets.
     <return-type> may be ‘string’, ‘number’ or ‘list’.

     Example:

          -----BEGIN PGP SIGNATURE-----
          Version: GnuPG v2.0.22 (GNU/Linux)

          iQEcBAEBAgAGBQJVdCTzAAoJEG/1Mgf2DWAqCSYH/AhVFwhu1D89C3/QFcgVvZTM
          wnOYzBUURJAL/cT+IngkLEpp3hEbREcugWp+Tm6aw3R4CdJ7G3FLxExBH/5KnDHi
          rBQu+I7+3ySK2hpryQ6Wx5J9uZSa4YmfsNteR8up0zGkaulJeWkS4pjiRM+auWVe
          vajlKZCIK52P080DG7Q2dpshh4fgTeNwqCuCiBhQ73t8g1IaLdhDN6EzJVjGIzam
          /spqT/sTo6sw8yDOJjvU+Qvn6/mSMjC/YxjhRMaQt9EMrR1AZ4ukBF5uG1S7mXOH
          WdiwkSPZ3gnIBhM9SuC076gLWZUNs6NqTeE3UzMjDAFhH3jYk1T7mysCvdtIkms=
          =WmeC
          -----END PGP SIGNATURE-----

          (%i1) ibase : obase : 16.$
          (%i2) sig64 : sconcat(
           "iQEcBAEBAgAGBQJVdCTzAAoJEG/1Mgf2DWAqCSYH/AhVFwhu1D89C3/QFcgVvZTM",
           "wnOYzBUURJAL/cT+IngkLEpp3hEbREcugWp+Tm6aw3R4CdJ7G3FLxExBH/5KnDHi",
           "rBQu+I7+3ySK2hpryQ6Wx5J9uZSa4YmfsNteR8up0zGkaulJeWkS4pjiRM+auWVe",
           "vajlKZCIK52P080DG7Q2dpshh4fgTeNwqCuCiBhQ73t8g1IaLdhDN6EzJVjGIzam",
           "/spqT/sTo6sw8yDOJjvU+Qvn6/mSMjC/YxjhRMaQt9EMrR1AZ4ukBF5uG1S7mXOH",
           "WdiwkSPZ3gnIBhM9SuC076gLWZUNs6NqTeE3UzMjDAFhH3jYk1T7mysCvdtIkms=" )$
          (%i3) octets: base64_decode(sig64, 'list)$
          (%i4) crc24: crc24sum(octets, 'list);
          (%o4)                          [5A, 67, 82]
          (%i5) base64(crc24);
          (%o5)                              WmeC

 -- Function: md5sum
          md5sum (<arg>)
          md5sum (<arg>, <return-type>)

     Returns the ‘MD5’ checksum of a string, non-negative integer, list
     of octets, or binary (not character) input stream.  A file for
     which an input stream is opened may be an ordinary text file; it is
     the stream which needs to be binary, not the file itself.

     When the argument is an input stream, ‘md5sum’ reads the entire
     content of the stream, but does not close the stream.

     The default return value is a string containing 32 hex characters.
     The optional argument <return-type> allows ‘md5sum’ to
     alternatively return the corresponding number or list of octets.
     <return-type> may be ‘string’, ‘number’ or ‘list’.

     Note that in case <arg> contains German umlauts or other non-ASCII
     characters (resp.  octets larger than 127) the ‘MD5’ checksum is
     platform dependent.

     Examples:

          (%i1) ibase: obase: 16.$
          (%i2) msg: "foo bar baz"$
          (%i3) string: md5sum(msg);
          (%o3)                  ab07acbb1e496801937adfa772424bf7
          (%i4) integer: md5sum(msg, 'number);
          (%o4)                 0ab07acbb1e496801937adfa772424bf7
          (%i5) octets: md5sum(msg, 'list);
          (%o5)        [0AB,7,0AC,0BB,1E,49,68,1,93,7A,0DF,0A7,72,42,4B,0F7]
          (%i6) sdowncase( printf(false, "~{~2,'0x~^:~}", octets) );
          (%o6)           ab:07:ac:bb:1e:49:68:01:93:7a:df:a7:72:42:4b:f7

     The argument may be a binary input stream.

          (%i1) S: openr_binary (file_search ("md5.lisp"));
          (%o1) #<INPUT BUFFERED FILE-STREAM (UNSIGNED-BYTE 8)
            /home/robert/maxima/maxima-code/share/stringproc/md5.lisp>
          (%i2) md5sum (S);
          (%o2)           31a512ed53daf5b99495c9d05559355f
          (%i3) close (S);
          (%o3)                         true

 -- Function: mgf1_sha1
          mgf1_sha1 (<seed>, <len>)
          mgf1_sha1 (<seed>, <len>, <return-type>)

     Returns a pseudo random number of variable length.  By default the
     returned value is a number with a length of <len> octets.

     The optional argument <return-type> allows ‘mgf1_sha1’ to
     alternatively return the corresponding list of <len> octets.
     <return-type> may be ‘number’ or ‘list’.

     The computation of the returned value is described in ‘RFC 3447’,
     appendix ‘B.2.1 MGF1’.  ‘SHA1’ is used as hash function, i.e.  the
     randomness of the computed number relies on the randomness of
     ‘SHA1’ hashes.

     Example:

          (%i1) ibase: obase: 16.$
          (%i2) number: mgf1_sha1(4711., 8);
          (%o2)                        0e0252e5a2a42fea1
          (%i3) octets: mgf1_sha1(4711., 8, 'list);
          (%o3)                  [0E0,25,2E,5A,2A,42,0FE,0A1]

 -- Function: number_to_octets (<number>)

     Returns an octet-representation of <number> as a list of octets.
     The <number> must be a non-negative integer.

     Example:

          (%i1) ibase : obase : 16.$
          (%i2) octets: [0ca,0fe,0ba,0be]$
          (%i3) number: octets_to_number(octets);
          (%o3)                            0cafebabe
          (%i4) number_to_octets(number);
          (%o4)                      [0CA, 0FE, 0BA, 0BE]

 -- Function: octets_to_number (<octets>)

     Returns a number by concatenating the octets in the list of
     <octets>.

     Example: See *note number_to_octets::.

 -- Function: octets_to_oid (<octets>)

     Computes an object identifier (OID) from the list of <octets>.

     Example: RSA encryption OID

          (%i1) ibase : obase : 16.$
          (%i2) oid: octets_to_oid([2A,86,48,86,0F7,0D,1,1,1]);
          (%o2)                      1.2.840.113549.1.1.1
          (%i3) oid_to_octets(oid);
          (%o3)               [2A, 86, 48, 86, 0F7, 0D, 1, 1, 1]

 -- Function: octets_to_string
          octets_to_string (<octets>)
          octets_to_string (<octets>, <encoding>)

     Decodes the list of <octets> into a string according to current
     system defaults.  When decoding octets corresponding to
     Non-US-ASCII characters the result depends on the platform,
     application and underlying Lisp.

     Example: Using system defaults (Maxima compiled with GCL, which
     uses no format definition and simply passes through the
     UTF-8-octets encoded by the GNU/Linux terminal).

          (%i1) octets: string_to_octets("abc");
          (%o1)                            [61, 62, 63]
          (%i2) octets_to_string(octets);
          (%o2)                                 abc
          (%i3) ibase: obase: 16.$
          (%i4) unicode(20AC);
          (%o4)                                  €
          (%i5) octets: string_to_octets(%);
          (%o5)                           [0E2, 82, 0AC]
          (%i6) octets_to_string(octets);
          (%o6)                                  €
          (%i7) utf8_to_unicode(octets);
          (%o7)                                20AC

     In case the external format of the Lisp reader is equal to UTF-8
     the optional argument <encoding> allows to set the encoding for the
     octet to string conversion.  If necessary see *note
     adjust_external_format:: for changing the external format.

     Some names of supported encodings (see corresponding Lisp manual
     for more):
     CCL, CLISP, SBCL: ‘utf-8, ucs-2be, ucs-4be, iso-8859-1, cp1252,
     cp850’
     CMUCL: ‘utf-8, utf-16-be, utf-32-be, iso8859-1, cp1252’
     ECL: ‘utf-8, ucs-2be, ucs-4be, iso-8859-1, windows-cp1252,
     dos-cp850’

     Example (continued): Using the optional encoding argument (Maxima
     compiled with SBCL, GNU/Linux terminal).

          (%i8) string_to_octets("€", "ucs-2be");
          (%o8)                              [20, 0AC]

 -- Function: oid_to_octets (<oid-string>)

     Converts an object identifier (OID) to a list of <octets>.

     Example: See *note octets_to_oid::.

 -- Function: sha1sum
          sha1sum (<arg>)
          sha1sum (<arg>, <return-type>)

     Returns the ‘SHA1’ fingerprint of a string, a non-negative integer
     or a list of octets.  The default return value is a string
     containing 40 hex characters.

     The optional argument <return-type> allows ‘sha1sum’ to
     alternatively return the corresponding number or list of octets.
     <return-type> may be ‘string’, ‘number’ or ‘list’.

     Example:

          (%i1) ibase: obase: 16.$
          (%i2) msg: "foo bar baz"$
          (%i3) string: sha1sum(msg);
          (%o3)              c7567e8b39e2428e38bf9c9226ac68de4c67dc39
          (%i4) integer: sha1sum(msg, 'number);
          (%o4)             0c7567e8b39e2428e38bf9c9226ac68de4c67dc39
          (%i5) octets: sha1sum(msg, 'list);
          (%o5)  [0C7,56,7E,8B,39,0E2,42,8E,38,0BF,9C,92,26,0AC,68,0DE,4C,67,0DC,39]
          (%i6) sdowncase( printf(false, "~{~2,'0x~^:~}", octets) );
          (%o6)     c7:56:7e:8b:39:e2:42:8e:38:bf:9c:92:26:ac:68:de:4c:67:dc:39

     Note that in case <arg> contains German umlauts or other non-ASCII
     characters (resp.  octets larger than 127) the ‘SHA1’ fingerprint
     is platform dependent.

 -- Function: sha256sum
          sha256sum (<arg>)
          sha256sum (<arg>, <return-type>)

     Returns the ‘SHA256’ fingerprint of a string, a non-negative
     integer or a list of octets.  The default return value is a string
     containing 64 hex characters.

     The optional argument <return-type> allows ‘sha256sum’ to
     alternatively return the corresponding number or list of octets
     (see *note sha1sum::).

     Example:

          (%i1) string: sha256sum("foo bar baz");
          (%o1)  dbd318c1c462aee872f41109a4dfd3048871a03dedd0fe0e757ced57dad6f2d7

     Note that in case <arg> contains German umlauts or other non-ASCII
     characters (resp.  octets larger than 127) the ‘SHA256’ fingerprint
     is platform dependent.

 -- Function: string_to_octets
          string_to_octets (<string>)
          string_to_octets (<string>, <encoding>)

     Encodes a <string> into a list of octets according to current
     system defaults.  When encoding strings containing Non-US-ASCII
     characters the result depends on the platform, application and
     underlying Lisp.

     In case the external format of the Lisp reader is equal to UTF-8
     the optional argument <encoding> allows to set the encoding for the
     string to octet conversion.  If necessary see *note
     adjust_external_format:: for changing the external format.

     See *note octets_to_string:: for examples and some more
     information.


File: maxima.info,  Node: Regular Expressions,  Prev: Octets and Utilities for Cryptography

97.6 Regular Expressions
========================

* Menu:

* Introduction to Regular Expressions::
* Functions and Variables::


File: maxima.info,  Node: Introduction to Regular Expressions,  Next: Functions and Variables,  Prev: Regular Expressions,  Up: Regular Expressions

97.6.1 Introduction to Regular Expressions
------------------------------------------

‘sregex’ is an interface to the portable regex engine by Dorai Sitaram.
The syntax of the regular expressions is described in detail in the
pregexp manual (http://ds26gte.github.io/pregexp/index.html) by Dorai
Sitaram.  See the manual for full details.

   While ‘sregex’ supports Unicode, the support for Unicode characters
in strings is dependent on the support for Unicode characters in the
Lisp used to run Maxima.


File: maxima.info,  Node: Functions and Variables,  Prev: Introduction to Regular Expressions,  Up: Regular Expressions

97.6.2 Functions and Variables
------------------------------

 -- Function: regex_compile (<pattern>)
     Compile regex string in <pattern> to an internal form that is
     easier for the regex engine to process.  This is not required,
     however.  All the regex functions accept this compiled regex or a
     string.  If the pattern is used many times, compiling the pattern
     will speed up matching.

          (%i1) regex_compile("c.r");
          (%o1)         Structure [COMPILED-REGEX for "c.r"]

 -- Function: regex_match_pos (<regex>, <str>)
 -- Function: regex_match_pos (<regex>, <str>, <start>)
 -- Function: regex_match_pos (<regex>, <str>, <start>, <end>)
     Return a list consisting of a list of the start and end positions
     of <str> where the first match of <regex> occurred.  If no match is
     found, returns ‘false’.

     If a third argument, <start>, is supplied, it is the starting index
     of the text string <str>.  The fourth argument, <end>, is the
     ending index of text string <str>.

          (%i1) str : "his hay needle stack -- my hay needle stack -- her hay needle stack"$
          (%i2) regex : regex_compile("ne{2}dle")$
          (%i3) regex_match_pos(regex, str);
          (%o3)                       [[9, 15]]
          (%i4) regex_match_pos("ne{2}dle", str);
          (%o4)                       [[9, 15]]
          (%i5) regex_match_pos("ne{2}dle", str, 25, 44);
          (%o5)                      [[32, 38]]

     Here is an example where ‘regex_match_pos’ returns a list of more
     than one element:
          (%i1) str : "jan 1, 1970";
          (%o1)                      jan 1, 1970
          (%i2) match: regex_match_pos("([a-z]+) ([0-9]+), ([0-9]+)", "jan 1, 1970");
          (%o2)          [[1, 12], [1, 4], [5, 6], [8, 12]]
          (%i3) map(lambda([posn], substring(str, posn[1], posn[2])), match);
          (%o3)              [jan 1, 1970, jan, 1, 1970]

     The first element is for the full match.  Each subsequent element
     of the list is the substring that matches the _cluster_ enclosed in
     parenthesis in the given regular expression.

 -- Function: regex_match (<regex>, <str>)
 -- Function: regex_match (<regex>, <str>, <start>)
 -- Function: regex_match (<regex>, <str>, <start>, <end>)
     ‘regex_match’ is very similar to ‘regex_match_pos’ except that it
     returns the matching substrings instead of the indices of the
     match.  If no match is found, returns ‘false’.

          (%i1) regex_match("ne{2}dle", "hay needle stack");
          (%o1)                       [needle]
          (%i2) regex_match("ne{2}dle", "hay needle stack", 10);
          (%o2)                         false

     Here is examples using POSIX character classes.  ‘[:alpha:]’
     matches any letter.  The pattern matches any letter or underscore:
          (%i1) regex_match("[[:alpha:]_]", "--x--");
          (%o1)                          [x]
          (%i2) regex_match("[[:alpha:]_]", "--_--");
          (%o2)                          [_]
          (%i3) regex_match("[[:alpha:]_]", "--:--");
          (%o3)                         false

     ‘sregex’ supports _clusters_ (see pregexp clusters
     (https://ds26gte.github.io/pregexp/index.html#TAG:__tex2page_toc_TAG:__tex2page_sec_3.4))
     which are subpatterns denoted by being enclosed within parentheses.
     These cause the matcher to return the submatch along with the
     overall match.

     Here we are looking for any number of letters followed by a space,
     any number of digits, a comma and space, then any number of digits.
          (%i1) regex_match("([a-z]+) ([0-9]+), ([0-9]+)", "jan 1, 1970");
          (%o1)              [jan 1, 1970, jan, 1, 1970]
     The result is a list of strings.  The first element is the full
     match.  The second matches ‘"([a-z]+)"’, which is a cluster of any
     number of letters.  Hence, ‘"jan"’ matches this cluster.  Likewise
     for the other clusters.

     A more complicated example illustrates how a subpattern fails to
     match, but the overall pattern matches.  In this case, ‘false’
     represents to failed match.

     The regex pattern matches "month year" or "month day, year".  The
     subpattern matches the day, if present.
          (%i1) date_re : regex_compile("([a-z]+) +([0-9]+,)? *([0-9]+)");
          (%o1)
            Structure [COMPILED-REGEX for "([a-z]+) +([0-9]+,)? *([0-9]+)"]
          (%i2) regex_match(date_re, "jan 1, 1970");
          (%o2)             [jan 1, 1970, jan, 1,, 1970]
          (%i3) regex_match(date_re, "jan 1970");
          (%o3)             [jan 1970, jan, false, 1970]

     You can also do case-insensitive matches by using a _cloister_ (see
     pregexp cloisters
     (https://ds26gte.github.io/pregexp/index.html#TAG:__tex2page_toc_TAG:__tex2page_sec_3.4.3))
     with the ‘i’ modifier:

          (%i1) regex_match("hearth", "HeartH");
          (%o1)                         false
          (%i2) regex_match("(?i:hearth)", "HeartH");
          (%o2)                       [HeartH]

     Alternate subpatterns can be separated by ‘|’.
          (%i1) regex_match("f(ee|i|o|um)", "a small, final fee");
          (%o1)                        [fi, i]
     The first element is the full match ‘"fi"’; the second shows that
     we matched ‘"i"’ for the cluster.

 -- Function: regex_split (<regex>, <str>)
     Returns a list of strings where <str> has been split into
     substrings where the <regex> identifies the delimiters to use for
     separating the substrings.

          (%i1) regex_split("[,;]+", "split,pea;;;soup");
          (%o1)                  [split, pea, soup]

 -- Function: regex_subst_first (<replacement>, <pattern>, <str>)
     Returns a string where the first occurrence of <pattern> in <str>
     with <replacement>.

          (%i1) regex_subst_first("ty", "t.", "liberte egalite fraternite");
          (%o1)              liberty egalite fraternite

     This example shows how to use back references.  The replacement
     specifies that the first submatch is used as the replacement text.
          (%i1) regex_match("_(.+?)_", "the _nina_, the _pinta_, and the _santa maria_");
          (%o1)                    [_nina_, nina]
          (%i2) regex_subst_first("*\\1*", "_(.+?)_", "the _nina_, the _pinta_, and the _santa maria_");
          (%o2)    the *nina*, the _pinta_, and the _santa maria_

 -- Function: regex_subst (<replacement>, <pattern>, <str>)
     Returns a string where every occurrence of <pattern> has been
     replaced by <replacement> in the string <str>.

          (%i1) regex_subst("ty", "t.\\b", "liberte egalite fraternite");
          (%o1)              liberty egality fraternity

 -- Function: string_to_regex (<str>)
     Returns a regex string where any special reqex characters in <str>
     are quoted to remove the specialness of the character.

          (%i1) re : string_to_regex(". :");
          (%o1)                         \. :
          (%i2) regex_match(re, "z :");
          (%o2)                         false
          (%i3) regex_match(re, ". :");
          (%o3)                         [. :]
          (%i4) regex_match(". :", "z :");
          (%o4)                         [z :]

     In this example, the regex will only match a substring consisting
     of a period, followed by a space and a colon.  Without the quoting,
     the ‘"."’ would match any single character.


File: maxima.info,  Node: Package sym,  Next: Package to_poly_solve,  Prev: Package stringproc,  Up: Top

98 Package sym
**************

* Menu:

* Introduction to Symmetries::
* Functions and Variables for Symmetries::


File: maxima.info,  Node: Introduction to Symmetries,  Next: Functions and Variables for Symmetries,  Prev: Package sym,  Up: Package sym

98.1 Introduction to Symmetries
===============================

‘sym’ is a package for working with symmetric groups of polynomials.

   It was written for Macsyma-Symbolics by Annick Valibouze
(<https://web.archive.org/web/20061125035035/http://www-calfor.lip6.fr/~avb/>).
The algorithms are described in the following papers:

  1. Fonctions symétriques et changements de bases.  Annick Valibouze.
     EUROCAL'87 (Leipzig, 1987), 323-332, Lecture Notes in Comput.  Sci
     378.  Springer, Berlin, 1989.
     <http://www.stix.polytechnique.fr/publications/1984-1994.html>

  2. Résolvantes et fonctions symétriques.  Annick Valibouze.
     Proceedings of the ACM-SIGSAM 1989 International Symposium on
     Symbolic and Algebraic Computation, ISSAC'89 (Portland, Oregon).
     ACM Press, 390-399, 1989.
     <https://web.archive.org/web/20061125035035/http://www-calfor.lip6.fr/~avb/DonneesTelechargeables/MesArticles/issac89ACMValibouze.pdf>

  3. Symbolic computation with symmetric polynomials, an extension to
     Macsyma.  Annick Valibouze.  Computers and Mathematics (MIT, USA,
     June 13-17, 1989), Springer-Verlag, New York Berlin, 308-320, 1989.
     <http://www.stix.polytechnique.fr/publications/1984-1994.html>

  4. Théorie de Galois Constructive.  Annick Valibouze.  Mémoire
     d'habilitation à diriger les recherches (HDR), Université P. et M.
     Curie (Paris VI), 1994.


File: maxima.info,  Node: Functions and Variables for Symmetries,  Prev: Introduction to Symmetries,  Up: Package sym

98.2 Functions and Variables for Symmetries
===========================================

98.2.1 Changing bases
---------------------

 -- Function: comp2pui (<n>, <L>)
     implements passing from the complete symmetric functions given in
     the list <L> to the elementary symmetric functions from 0 to <n>.
     If the list <L> contains fewer than <n+1> elements, it will be
     completed with formal values of the type <h1>, <h2>, etc.  If the
     first element of the list <L> exists, it specifies the size of the
     alphabet, otherwise the size is set to <n>.

          (%i1) comp2pui (3, [4, g]);
                                  2                    2
          (%o1)    [4, g, 2 h2 - g , 3 h3 - g h2 + g (g  - 2 h2)]

 -- Function: ele2pui (<m>, <L>)
     goes from the elementary symmetric functions to the complete
     functions.  Similar to ‘comp2ele’ and ‘comp2pui’.

     Other functions for changing bases: ‘comp2ele’.

 -- Function: ele2comp (<m>, <L>)
     Goes from the elementary symmetric functions to the compete
     functions.  Similar to ‘comp2ele’ and ‘comp2pui’.

     Other functions for changing bases: ‘comp2ele’.

 -- Function: elem (<ele>, <sym>, <lvar>)
     decomposes the symmetric polynomial <sym>, in the variables
     contained in the list <lvar>, in terms of the elementary symmetric
     functions given in the list <ele>.  If the first element of <ele>
     is given, it will be the size of the alphabet, otherwise the size
     will be the degree of the polynomial <sym>.  If values are missing
     in the list <ele>, formal values of the type <e1>, <e2>, etc.  will
     be added.  The polynomial <sym> may be given in three different
     forms: contracted (‘elem’ should then be 1, its default value),
     partitioned (‘elem’ should be 3), or extended (i.e.  the entire
     polynomial, and ‘elem’ should then be 2).  The function ‘pui’ is
     used in the same way.

     On an alphabet of size 3 with <e1>, the first elementary symmetric
     function, with value 7, the symmetric polynomial in 3 variables
     whose contracted form (which here depends on only two of its
     variables) is <x^4-2*x*y> decomposes as follows in elementary
     symmetric functions:

          (%i1) elem ([3, 7], x^4 - 2*x*y, [x, y]);
          (%o1) 7 (e3 - 7 e2 + 7 (49 - e2)) + 21 e3

                                                   + (- 2 (49 - e2) - 2) e2
          (%i2) ratsimp (%);
                                        2
          (%o2)             28 e3 + 2 e2  - 198 e2 + 2401

     Other functions for changing bases: ‘comp2ele’.

 -- Function: mon2schur (<L>)
     The list <L> represents the Schur function S_L: we have L = [i_1,
     i_2, ..., i_q], with i_1 <= i_2 <= ... <= i_q.  The Schur function
     S_[i_1, i_2, ..., i_q] is the minor of the infinite matrix h_[i-j],
     i <= 1, j <= 1, consisting of the q first rows and the columns 1 +
     i_1, 2 + i_2, ..., q + i_q.

     This Schur function can be written in terms of monomials by using
     ‘treinat’ and *note kostka::.  The form returned is a symmetric
     polynomial in a contracted representation in the variables
     x_1,x_2,...

          (%i1) mon2schur ([1, 1, 1]);
          (%o1)                       x1 x2 x3
          (%i2) mon2schur ([3]);
                                            2        3
          (%o2)                x1 x2 x3 + x1  x2 + x1
          (%i3) mon2schur ([1, 2]);
                                                2
          (%o3)                  2 x1 x2 x3 + x1  x2

     which means that for 3 variables this gives:

             2 x1 x2 x3 + x1^2 x2 + x2^2 x1 + x1^2 x3 + x3^2 x1
              + x2^2 x3 + x3^2 x2
     Other functions for changing bases: ‘comp2ele’.

 -- Function: multi_elem (<l_elem>, <multi_pc>, <l_var>)
     decomposes a multi-symmetric polynomial in the multi-contracted
     form <multi_pc> in the groups of variables contained in the list of
     lists <l_var> in terms of the elementary symmetric functions
     contained in <l_elem>.

          (%i1) multi_elem ([[2, e1, e2], [2, f1, f2]], a*x + a^2 + x^3,
                [[x, y], [a, b]]);
                                                            3
          (%o1)         - 2 f2 + f1 (f1 + e1) - 3 e1 e2 + e1
          (%i2) ratsimp (%);
                                   2                       3
          (%o2)         - 2 f2 + f1  + e1 f1 - 3 e1 e2 + e1

     Other functions for changing bases: ‘comp2ele’.

 -- Function: multi_pui
     is to the function ‘pui’ what the function ‘multi_elem’ is to the
     function ‘elem’.

          (%i1) multi_pui ([[2, p1, p2], [2, t1, t2]], a*x + a^2 + x^3,
                [[x, y], [a, b]]);
                                                      3
                                          3 p1 p2   p1
          (%o1)              t2 + p1 t1 + ------- - ---
                                             2       2

 -- Function: pui (<L>, <sym>, <lvar>)
     decomposes the symmetric polynomial <sym>, in the variables in the
     list <lvar>, in terms of the power functions in the list <L>.  If
     the first element of <L> is given, it will be the size of the
     alphabet, otherwise the size will be the degree of the polynomial
     <sym>.  If values are missing in the list <L>, formal values of the
     type <p1>, <p2> , etc.  will be added.  The polynomial <sym> may be
     given in three different forms: contracted (‘elem’ should then be
     1, its default value), partitioned (‘elem’ should be 3), or
     extended (i.e.  the entire polynomial, and ‘elem’ should then be
     2).  The function ‘pui’ is used in the same way.

          (%i1) pui;
          (%o1)                           1
          (%i2) pui ([3, a, b], u*x*y*z, [x, y, z]);
                                 2
                             a (a  - b) u   (a b - p3) u
          (%o2)              ------------ - ------------
                                  6              3
          (%i3) ratsimp (%);
                                                 3
                                (2 p3 - 3 a b + a ) u
          (%o3)                 ---------------------
                                          6
     Other functions for changing bases: ‘comp2ele’.

 -- Function: pui2comp (<n>, <lpui>)
     renders the list of the first <n> complete functions (with the
     length first) in terms of the power functions given in the list
     <lpui>.  If the list <lpui> is empty, the cardinal is <n>,
     otherwise it is its first element (as in ‘comp2ele’ and
     ‘comp2pui’).

          (%i1) pui2comp (2, []);
                                                 2
                                          p2 + p1
          (%o1)                   [2, p1, --------]
                                             2
          (%i2) pui2comp (3, [2, a1]);
                                                      2
                                           a1 (p2 + a1 )
                                   2  p3 + ------------- + a1 p2
                            p2 + a1              2
          (%o2)     [2, a1, --------, --------------------------]
                               2                  3
          (%i3) ratsimp (%);
                                      2                     3
                               p2 + a1   2 p3 + 3 a1 p2 + a1
          (%o3)        [2, a1, --------, --------------------]
                                  2               6
     Other functions for changing bases: ‘comp2ele’.

 -- Function: pui2ele (<n>, <lpui>)
     effects the passage from power functions to the elementary
     symmetric functions.  If the flag ‘pui2ele’ is ‘girard’, it will
     return the list of elementary symmetric functions from 1 to <n>,
     and if the flag is ‘close’, it will return the <n>-th elementary
     symmetric function.

     Other functions for changing bases: ‘comp2ele’.

 -- Function: puireduc (<n>, <lpui>)
     <lpui> is a list whose first element is an integer <m>.  ‘puireduc’
     gives the first <n> power functions in terms of the first <m>.

          (%i1) puireduc (3, [2]);
                                                   2
                                             p1 (p1  - p2)
          (%o1)          [2, p1, p2, p1 p2 - -------------]
                                                   2
          (%i2) ratsimp (%);
                                                     3
                                         3 p1 p2 - p1
          (%o2)              [2, p1, p2, -------------]
                                               2

 -- Function: schur2comp (<P>, <l_var>)
     <P> is a polynomial in the variables of the list <l_var>.  Each of
     these variables represents a complete symmetric function.  In
     <l_var> the <i>-th complete symmetric function is represented by
     the concatenation of the letter ‘h’ and the integer <i>: ‘h<i>’.
     This function expresses <P> in terms of Schur functions.

          (%i1) schur2comp (h1*h2 - h3, [h1, h2, h3]);
          (%o1)                         s
                                         1, 2
          (%i2) schur2comp (a*h3, [h3]);
          (%o2)                         s  a
                                         3

98.2.2 Changing representations
-------------------------------

 -- Function: cont2part (<pc>, <lvar>)
     returns the partitioned polynomial associated to the contracted
     form <pc> whose variables are in <lvar>.

          (%i1) pc: 2*a^3*b*x^4*y + x^5;
                                     3    4      5
          (%o1)                   2 a  b x  y + x
          (%i2) cont2part (pc, [x, y]);
                                             3
          (%o2)              [[1, 5, 0], [2 a  b, 4, 1]]

 -- Function: contract (<psym>, <lvar>)
     returns a contracted form (i.e.  a monomial orbit under the action
     of the symmetric group) of the polynomial <psym> in the variables
     contained in the list <lvar>.  The function ‘explose’ performs the
     inverse operation.  The function ‘tcontract’ tests the symmetry of
     the polynomial.

          (%i1) psym: explose (2*a^3*b*x^4*y, [x, y, z]);
                   3      4      3      4      3    4        3    4
          (%o1) 2 a  b y z  + 2 a  b x z  + 2 a  b y  z + 2 a  b x  z

                                                     3      4      3    4
                                                + 2 a  b x y  + 2 a  b x  y
          (%i2) contract (psym, [x, y, z]);
                                        3    4
          (%o2)                      2 a  b x  y

 -- Function: explose (<pc>, <lvar>)
     returns the symmetric polynomial associated with the contracted
     form <pc>.  The list <lvar> contains the variables.

          (%i1) explose (a*x + 1, [x, y, z]);
          (%o1)                  a z + a y + a x + 1

 -- Function: part2cont (<ppart>, <lvar>)
     goes from the partitioned form to the contracted form of a
     symmetric polynomial.  The contracted form is rendered with the
     variables in <lvar>.

          (%i1) part2cont ([[2*a^3*b, 4, 1]], [x, y]);
                                        3    4
          (%o1)                      2 a  b x  y

 -- Function: partpol (<psym>, <lvar>)
     <psym> is a symmetric polynomial in the variables of the list
     <lvar>.  This function returns its partitioned representation.

          (%i1) partpol (-a*(x + y) + 3*x*y, [x, y]);
          (%o1)               [[3, 1, 1], [- a, 1, 0]]

 -- Function: tcontract (<pol>, <lvar>)
     tests if the polynomial <pol> is symmetric in the variables of the
     list <lvar>.  If so, it returns a contracted representation like
     the function ‘contract’.

 -- Function: tpartpol (<pol>, <lvar>)
     tests if the polynomial <pol> is symmetric in the variables of the
     list <lvar>.  If so, it returns its partitioned representation like
     the function ‘partpol’.

98.2.3 Groups and orbits
------------------------

 -- Function: direct ([<p_1>, ..., <p_n>], <y>, <f>, [<lvar_1>, ...,
          <lvar_n>])
     calculates the direct image (see M. Giusti, D. Lazard et A.
     Valibouze, ISSAC 1988, Rome) associated to the function <f>, in the
     lists of variables <lvar_1>, ..., <lvar_n>, and in the polynomials
     <p_1>, ..., <p_n> in a variable <y>.  The arity of the function <f>
     is important for the calculation.  Thus, if the expression for <f>
     does not depend on some variable, it is useless to include this
     variable, and not including it will also considerably reduce the
     amount of computation.

          (%i1) direct ([z^2  - e1* z + e2, z^2  - f1* z + f2],
                        z, b*v + a*u, [[u, v], [a, b]]);
                 2
          (%o1) y  - e1 f1 y

                                           2            2             2   2
                            - 4 e2 f2 - (e1  - 2 e2) (f1  - 2 f2) + e1  f1
                          + -----------------------------------------------
                                                   2
          (%i2) ratsimp (%);
                        2                2                   2
          (%o2)        y  - e1 f1 y + (e1  - 4 e2) f2 + e2 f1
          (%i3) ratsimp (direct ([z^3-e1*z^2+e2*z-e3,z^2  - f1* z + f2],
                        z, b*v + a*u, [[u, v], [a, b]]));
                 6            5         2                        2    2   4
          (%o3) y  - 2 e1 f1 y  + ((2 e1  - 6 e2) f2 + (2 e2 + e1 ) f1 ) y

                                    3                               3   3
           + ((9 e3 + 5 e1 e2 - 2 e1 ) f1 f2 + (- 2 e3 - 2 e1 e2) f1 ) y

                   2       2        4    2
           + ((9 e2  - 6 e1  e2 + e1 ) f2

                              2       2       2                   2    4
           + (- 9 e1 e3 - 6 e2  + 3 e1  e2) f1  f2 + (2 e1 e3 + e2 ) f1 )

            2          2                      2     3          2
           y  + (((9 e1  - 27 e2) e3 + 3 e1 e2  - e1  e2) f1 f2

                           2            2    3                5
           + ((15 e2 - 2 e1 ) e3 - e1 e2 ) f1  f2 - 2 e2 e3 f1 ) y

                     2                   3           3     2   2    3
           + (- 27 e3  + (18 e1 e2 - 4 e1 ) e3 - 4 e2  + e1  e2 ) f2

                   2      3                   3    2   2
           + (27 e3  + (e1  - 9 e1 e2) e3 + e2 ) f1  f2

                             2    4        2   6
           + (e1 e2 e3 - 9 e3 ) f1  f2 + e3  f1

     Finding the polynomial whose roots are the sums a+u where a is a
     root of z^2 - e_1 z + e_2 and u is a root of z^2 - f_1 z + f_2.

          (%i1) ratsimp (direct ([z^2 - e1* z + e2, z^2 - f1* z + f2],
                                    z, a + u, [[u], [a]]));
                 4                    3             2
          (%o1) y  + (- 2 f1 - 2 e1) y  + (2 f2 + f1  + 3 e1 f1 + 2 e2

               2   2                              2               2
           + e1 ) y  + ((- 2 f1 - 2 e1) f2 - e1 f1  + (- 2 e2 - e1 ) f1

                            2                     2            2
           - 2 e1 e2) y + f2  + (e1 f1 - 2 e2 + e1 ) f2 + e2 f1  + e1 e2 f1

               2
           + e2

     ‘direct’ accepts two flags: ‘elementaires’ and ‘puissances’
     (default) which allow decomposing the symmetric polynomials
     appearing in the calculation into elementary symmetric functions,
     or power functions, respectively.

     Functions of ‘sym’ used in this function:

     ‘multi_orbit’ (so ‘orbit’), ‘pui_direct’, ‘multi_elem’ (so ‘elem’),
     ‘multi_pui’ (so ‘pui’), ‘pui2ele’, ‘ele2pui’ (if the flag ‘direct’
     is in ‘puissances’).

 -- Function: multi_orbit (<P>, [<lvar_1>, <lvar_2>,..., <lvar_p>])

     <P> is a polynomial in the set of variables contained in the lists
     <lvar_1>, <lvar_2>, ..., <lvar_p>.  This function returns the orbit
     of the polynomial <P> under the action of the product of the
     symmetric groups of the sets of variables represented in these <p>
     lists.

          (%i1) multi_orbit (a*x + b*y, [[x, y], [a, b]]);
          (%o1)                [b y + a x, a y + b x]
          (%i2) multi_orbit (x + y + 2*a, [[x, y], [a, b, c]]);
          (%o2)        [y + x + 2 c, y + x + 2 b, y + x + 2 a]
     Also see: ‘orbit’ for the action of a single symmetric group.

 -- Function: multsym (<ppart_1>, <ppart_2>, <n>)
     returns the product of the two symmetric polynomials in <n>
     variables by working only modulo the action of the symmetric group
     of order <n>.  The polynomials are in their partitioned form.

     Given the 2 symmetric polynomials in <x>, <y>: ‘3*(x + y) + 2*x*y’
     and ‘5*(x^2 + y^2)’ whose partitioned forms are ‘[[3, 1], [2, 1,
     1]]’ and ‘[[5, 2]]’, their product will be

          (%i1) multsym ([[3, 1], [2, 1, 1]], [[5, 2]], 2);
          (%o1)         [[10, 3, 1], [15, 3, 0], [15, 2, 1]]
     that is ‘10*(x^3*y + y^3*x) + 15*(x^2*y + y^2*x) + 15*(x^3 + y^3)’.

     Functions for changing the representations of a symmetric
     polynomial:

     ‘contract’, ‘cont2part’, ‘explose’, ‘part2cont’, ‘partpol’,
     ‘tcontract’, ‘tpartpol’.

 -- Function: orbit (<P>, <lvar>)
     computes the orbit of the polynomial <P> in the variables in the
     list <lvar> under the action of the symmetric group of the set of
     variables in the list <lvar>.

          (%i1) orbit (a*x + b*y, [x, y]);
          (%o1)                [a y + b x, b y + a x]
          (%i2) orbit (2*x + x^2, [x, y]);
                                  2         2
          (%o2)                 [y  + 2 y, x  + 2 x]
     See also ‘multi_orbit’ for the action of a product of symmetric
     groups on a polynomial.

 -- Function: pui_direct (<orbite>, [<lvar_1>, ..., <lvar_n>], [<d_1>,
          <d_2>, ..., <d_n>])

     Let <f> be a polynomial in <n> blocks of variables <lvar_1>, ...,
     <lvar_n>.  Let <c_i> be the number of variables in <lvar_i>, and
     <SC> be the product of <n> symmetric groups of degree <c_1>, ...,
     <c_n>.  This group acts naturally on <f>.  The list <orbite> is the
     orbit, denoted ‘<SC>(<f>)’, of the function <f> under the action of
     <SC>.  (This list may be obtained by the function ‘multi_orbit’.)
     The <di> are integers s.t.  c_1 <= d_1, c_2 <= d_2, ..., c_n <=
     d_n.

     Let <SD> be the product of the symmetric groups S_[d_1] x S_[d_2] x
     ... x S_[d_n].  The function ‘pui_direct’ returns the first <n>
     power functions of ‘<SD>(<f>)’ deduced from the power functions of
     ‘<SC>(<f>)’, where <n> is the size of ‘<SD>(<f>)’.

     The result is in multi-contracted form w.r.t.  <SD>, i.e.  only one
     element is kept per orbit, under the action of <SD>.

          (%i1) l: [[x, y], [a, b]];
          (%o1)                   [[x, y], [a, b]]
          (%i2) pui_direct (multi_orbit (a*x + b*y, l), l, [2, 2]);
                                                 2  2
          (%o2)               [a x, 4 a b x y + a  x ]
          (%i3) pui_direct (multi_orbit (a*x + b*y, l), l, [3, 2]);
                                       2  2     2    2        3  3
          (%o3) [2 a x, 4 a b x y + 2 a  x , 3 a  b x  y + 2 a  x ,

              2  2  2  2      3    3        4  4
          12 a  b  x  y  + 4 a  b x  y + 2 a  x ,

              3  2  3  2      4    4        5  5
          10 a  b  x  y  + 5 a  b x  y + 2 a  x ,

              3  3  3  3       4  2  4  2      5    5        6  6
          40 a  b  x  y  + 15 a  b  x  y  + 6 a  b x  y + 2 a  x ]
          (%i4) pui_direct ([y + x + 2*c, y + x + 2*b, y + x + 2*a],
                [[x, y], [a, b, c]], [2, 3]);
                                       2              2
          (%o4) [3 x + 2 a, 6 x y + 3 x  + 4 a x + 4 a ,

                           2                   3        2       2        3
                        9 x  y + 12 a x y + 3 x  + 6 a x  + 12 a  x + 8 a ]

98.2.4 Partitions
-----------------

 -- Function: kostka (<part_1>, <part_2>)
     written by P. Esperet, calculates the Kostka number of the
     partition <part_1> and <part_2>.

          (%i1) kostka ([3, 3, 3], [2, 2, 2, 1, 1, 1]);
          (%o1)                           6

 -- Function: lgtreillis (<n>, <m>)
     returns the list of partitions of weight <n> and length <m>.

          (%i1) lgtreillis (4, 2);
          (%o1)                   [[3, 1], [2, 2]]
     Also see: ‘ltreillis’, ‘treillis’ and *note treinat::.

 -- Function: ltreillis (<n>, <m>)
     returns the list of partitions of weight <n> and length less than
     or equal to <m>.

          (%i1) ltreillis (4, 2);
          (%o1)               [[4, 0], [3, 1], [2, 2]]
     Also see: ‘lgtreillis’, ‘treillis’ and *note treinat::.

 -- Function: treillis (<n>)
     returns all partitions of weight <n>.

          (%i1) treillis (4);
          (%o1)    [[4], [3, 1], [2, 2], [2, 1, 1], [1, 1, 1, 1]]

     See also: ‘lgtreillis’, ‘ltreillis’ and *note treinat::.

 -- Function: treinat (<part>)
     returns the list of partitions inferior to the partition <part>
     w.r.t.  the natural order.

          (%i1) treinat ([5]);
          (%o1)                         [[5]]
          (%i2) treinat ([1, 1, 1, 1, 1]);
          (%o2) [[5], [4, 1], [3, 2], [3, 1, 1], [2, 2, 1], [2, 1, 1, 1],

                                                           [1, 1, 1, 1, 1]]
          (%i3) treinat ([3, 2]);
          (%o3)                 [[5], [4, 1], [3, 2]]

     See also: ‘lgtreillis’, ‘ltreillis’ and *note treillis::.

98.2.5 Polynomials and their roots
----------------------------------

 -- Function: ele2polynome (<L>, <z>)
     returns the polynomial in <z> s.t.  the elementary symmetric
     functions of its roots are in the list ‘<L> = [<n>, <e_1>, ...,
     <e_n>]’, where <n> is the degree of the polynomial and <e_i> the
     <i>-th elementary symmetric function.

          (%i1) ele2polynome ([2, e1, e2], z);
                                    2
          (%o1)                    z  - e1 z + e2
          (%i2) polynome2ele (x^7 - 14*x^5 + 56*x^3  - 56*x + 22, x);
          (%o2)          [7, 0, - 14, 0, 56, 0, - 56, - 22]
          (%i3) ele2polynome ([7, 0, -14, 0, 56, 0, -56, -22], x);
                            7       5       3
          (%o3)            x  - 14 x  + 56 x  - 56 x + 22
     The inverse: ‘polynome2ele (<P>, <z>)’.

     Also see: ‘polynome2ele’, ‘pui2polynome’.

 -- Function: polynome2ele (<P>, <x>)
     gives the list ‘<l> = [<n>, <e_1>, ..., <e_n>]’ where <n> is the
     degree of the polynomial <P> in the variable <x> and <e_i> is the
     <i>-the elementary symmetric function of the roots of <P>.

          (%i1) polynome2ele (x^7 - 14*x^5 + 56*x^3 - 56*x + 22, x);
          (%o1)          [7, 0, - 14, 0, 56, 0, - 56, - 22]
          (%i2) ele2polynome ([7, 0, -14, 0, 56, 0, -56, -22], x);
                            7       5       3
          (%o2)            x  - 14 x  + 56 x  - 56 x + 22
     The inverse: ‘ele2polynome (<l>, <x>)’

 -- Function: prodrac (<L>, <k>)
     <L> is a list containing the elementary symmetric functions on a
     set <A>.  ‘prodrac’ returns the polynomial whose roots are the <k>
     by <k> products of the elements of <A>.

     Also see ‘somrac’.

 -- Function: pui2polynome (<x>, <lpui>)
     calculates the polynomial in <x> whose power functions of the roots
     are given in the list <lpui>.

          (%i1) pui;
          (%o1)                           1
          (%i2) kill(labels);
          (%o0)                         done
          (%i1) polynome2ele (x^3 - 4*x^2 + 5*x - 1, x);
          (%o1)                     [3, 4, 5, 1]
          (%i2) ele2pui (3, %);
          (%o2)                     [3, 4, 6, 7]
          (%i3) pui2polynome (x, %);
                                  3      2
          (%o3)                  x  - 4 x  + 5 x - 1
     See also: ‘polynome2ele’, *note ele2polynome::.

 -- Function: somrac (<L>, <k>)
     The list <L> contains elementary symmetric functions of a
     polynomial <P> .  The function computes the polynomial whose roots
     are the <k> by <k> distinct sums of the roots of <P>.

     Also see ‘prodrac’.

98.2.6 Resolvents
-----------------

 -- Function: resolvante (<P>, <x>, <f>, [<x_1>,..., <x_d>])
     calculates the resolvent of the polynomial <P> in <x> of degree ‘n
     >= d’ by the function <f> expressed in the variables <x_1>, ...,
     <x_d>.  For efficiency of computation it is important to not
     include in the list ‘[<x_1>, ..., <x_d>]’ variables which do not
     appear in the transformation function <f>.

     To increase the efficiency of the computation one may set flags in
     ‘resolvante’ so as to use appropriate algorithms:

     If the function <f> is unitary:
        • A polynomial in a single variable,
        • linear,
        • alternating,
        • a sum,
        • symmetric,
        • a product,
        • the function of the Cayley resolvent (usable up to degree 5)

               (x1*x2 + x2*x3 + x3*x4 + x4*x5 + x5*x1 -
                    (x1*x3 + x3*x5 + x5*x2 + x2*x4 + x4*x1))^2

          general,
     the flag of ‘resolvante’ may be, respectively:
        • unitaire,
        • lineaire,
        • alternee,
        • somme,
        • produit,
        • cayley,
        • generale.

          (%i1) resolvante: unitaire$
          (%i2) resolvante (x^7 - 14*x^5 + 56*x^3 - 56*x + 22, x, x^3 - 1,
                [x]);

          " resolvante unitaire " [7, 0, 28, 0, 168, 0, 1120, - 154, 7840,
                                   - 2772, 56448, - 33880,

          413952, - 352352, 3076668, - 3363360, 23114112, - 30494464,

          175230832, - 267412992, 1338886528, - 2292126760]
            3       6      3       9      6      3
          [x  - 1, x  - 2 x  + 1, x  - 3 x  + 3 x  - 1,

           12      9      6      3       15      12       9       6      3
          x   - 4 x  + 6 x  - 4 x  + 1, x   - 5 x   + 10 x  - 10 x  + 5 x

                 18      15       12       9       6      3
           - 1, x   - 6 x   + 15 x   - 20 x  + 15 x  - 6 x  + 1,

           21      18       15       12       9       6      3
          x   - 7 x   + 21 x   - 35 x   + 35 x  - 21 x  + 7 x  - 1]
          [- 7, 1127, - 6139, 431767, - 5472047, 201692519, - 3603982011]
                 7      6        5         4          3           2
          (%o2) y  + 7 y  - 539 y  - 1841 y  + 51443 y  + 315133 y

                                                        + 376999 y + 125253
          (%i3) resolvante: lineaire$
          (%i4) resolvante (x^4 - 1, x, x1 + 2*x2 + 3*x3, [x1, x2, x3]);

          " resolvante lineaire "
                 24       20         16            12             8
          (%o4) y   + 80 y   + 7520 y   + 1107200 y   + 49475840 y

                                                              4
                                                 + 344489984 y  + 655360000
          (%i5) resolvante: general$
          (%i6) resolvante (x^4 - 1, x, x1 + 2*x2 + 3*x3, [x1, x2, x3]);

          " resolvante generale "
                 24       20         16            12             8
          (%o6) y   + 80 y   + 7520 y   + 1107200 y   + 49475840 y

                                                              4
                                                 + 344489984 y  + 655360000
          (%i7) resolvante (x^4 - 1, x, x1 + 2*x2 + 3*x3, [x1, x2, x3, x4]);

          " resolvante generale "
                 24       20         16            12             8
          (%o7) y   + 80 y   + 7520 y   + 1107200 y   + 49475840 y

                                                              4
                                                 + 344489984 y  + 655360000
          (%i8) direct ([x^4 - 1], x, x1 + 2*x2 + 3*x3, [[x1, x2, x3]]);
                 24       20         16            12             8
          (%o8) y   + 80 y   + 7520 y   + 1107200 y   + 49475840 y

                                                              4
                                                 + 344489984 y  + 655360000
          (%i9) resolvante :lineaire$
          (%i10) resolvante (x^4 - 1, x, x1 + x2 + x3, [x1, x2, x3]);

          " resolvante lineaire "
                                        4
          (%o10)                       y  - 1
          (%i11) resolvante: symetrique$
          (%i12) resolvante (x^4 - 1, x, x1 + x2 + x3, [x1, x2, x3]);

          " resolvante symetrique "
                                        4
          (%o12)                       y  - 1
          (%i13) resolvante (x^4 + x + 1, x, x1 - x2, [x1, x2]);

          " resolvante symetrique "
                                     6      2
          (%o13)                    y  - 4 y  - 1
          (%i14) resolvante: alternee$
          (%i15) resolvante (x^4 + x + 1, x, x1 - x2, [x1, x2]);

          " resolvante alternee "
                      12      8       6        4        2
          (%o15)     y   + 8 y  + 26 y  - 112 y  + 216 y  + 229
          (%i16) resolvante: produit$
          (%i17) resolvante (x^7 - 7*x + 3, x, x1*x2*x3, [x1, x2, x3]);

          " resolvante produit "
                  35      33         29        28         27        26
          (%o17) y   - 7 y   - 1029 y   + 135 y   + 7203 y   - 756 y

                   24           23          22            21           20
           + 1323 y   + 352947 y   - 46305 y   - 2463339 y   + 324135 y

                    19           18             17              15
           - 30618 y   - 453789 y   - 40246444 y   + 282225202 y

                       14              12             11            10
           - 44274492 y   + 155098503 y   + 12252303 y   + 2893401 y

                        9            8            7             6
           - 171532242 y  + 6751269 y  + 2657205 y  - 94517766 y

                      5             3
           - 3720087 y  + 26040609 y  + 14348907
          (%i18) resolvante: symetrique$
          (%i19) resolvante (x^7 - 7*x + 3, x, x1*x2*x3, [x1, x2, x3]);

          " resolvante symetrique "
                  35      33         29        28         27        26
          (%o19) y   - 7 y   - 1029 y   + 135 y   + 7203 y   - 756 y

                   24           23          22            21           20
           + 1323 y   + 352947 y   - 46305 y   - 2463339 y   + 324135 y

                    19           18             17              15
           - 30618 y   - 453789 y   - 40246444 y   + 282225202 y

                       14              12             11            10
           - 44274492 y   + 155098503 y   + 12252303 y   + 2893401 y

                        9            8            7             6
           - 171532242 y  + 6751269 y  + 2657205 y  - 94517766 y

                      5             3
           - 3720087 y  + 26040609 y  + 14348907
          (%i20) resolvante: cayley$
          (%i21) resolvante (x^5 - 4*x^2 + x + 1, x, a, []);

          " resolvante de Cayley "
                  6       5         4          3            2
          (%o21) x  - 40 x  + 4080 x  - 92928 x  + 3772160 x  + 37880832 x

                                                                 + 93392896

     For the Cayley resolvent, the 2 last arguments are neutral and the
     input polynomial must necessarily be of degree 5.

     See also:
     ‘resolvante_bipartite’, ‘resolvante_produit_sym’,
     ‘resolvante_unitaire’, ‘resolvante_alternee1’, ‘resolvante_klein’,
     ‘resolvante_klein3’, ‘resolvante_vierer’, *note resolvante_diedrale::.

 -- Function: resolvante_alternee1 (<P>, <x>)
     calculates the transformation ‘<P>(<x>)’ of degree <n> by the
     function product(x_i - x_j, 1 <= i < j <= n - 1).

     See also:
     ‘resolvante_produit_sym’, ‘resolvante_unitaire’,
     ‘resolvante’, ‘resolvante_klein’, ‘resolvante_klein3’,
     ‘resolvante_vierer’, ‘resolvante_diedrale’, *note resolvante_bipartite::.

 -- Function: resolvante_bipartite (<P>, <x>)
     calculates the transformation of ‘<P>(<x>)’ of even degree <n> by
     the function x_1 x_2 ... x_[n/2] + x_[n/2 + 1] ... x_n.

          (%i1) resolvante_bipartite (x^6 + 108, x);
                        10        8           6             4
          (%o1)        y   - 972 y  + 314928 y  - 34012224 y

     See also:
     ‘resolvante_produit_sym’, ‘resolvante_unitaire’,
     ‘resolvante’, ‘resolvante_klein’, ‘resolvante_klein3’,
     ‘resolvante_vierer’, ‘resolvante_diedrale’, *note resolvante_alternee1::.

 -- Function: resolvante_diedrale (<P>, <x>)
     calculates the transformation of ‘<P>(<x>)’ by the function ‘<x_1>
     <x_2> + <x_3> <x_4>’.

          (%i1) resolvante_diedrale (x^5 - 3*x^4 + 1, x);
                 15       12       11       10        9         8         7
          (%o1) x   - 21 x   - 81 x   - 21 x   + 207 x  + 1134 x  + 2331 x

                  6         5          4          3          2
           - 945 x  - 4970 x  - 18333 x  - 29079 x  - 20745 x  - 25326 x

           - 697

     See also:
     ‘resolvante_produit_sym’, ‘resolvante_unitaire’,
     ‘resolvante_alternee1’, ‘resolvante_klein’, ‘resolvante_klein3’,
     ‘resolvante_vierer’, *note resolvante::.

 -- Function: resolvante_klein (<P>, <x>)
     calculates the transformation of ‘<P>(<x>)’ by the function ‘<x_1>
     <x_2> <x_4> + <x_4>’.

     See also:
     ‘resolvante_produit_sym’, ‘resolvante_unitaire’,
     ‘resolvante_alternee1’, ‘resolvante’, ‘resolvante_klein3’,
     ‘resolvante_vierer’, *note resolvante_diedrale::.

 -- Function: resolvante_klein3 (<P>, <x>)
     calculates the transformation of ‘<P>(<x>)’ by the function ‘<x_1>
     <x_2> <x_4> + <x_4>’.

     See also:
     ‘resolvante_produit_sym’, ‘resolvante_unitaire’,
     ‘resolvante_alternee1’, ‘resolvante_klein’, ‘resolvante’,
     ‘resolvante_vierer’, *note resolvante_diedrale::.

 -- Function: resolvante_produit_sym (<P>, <x>)
     calculates the list of all product resolvents of the polynomial
     ‘<P>(<x>)’.

          (%i1) resolvante_produit_sym (x^5 + 3*x^4 + 2*x - 1, x);
                  5      4             10      8       7       6       5
          (%o1) [y  + 3 y  + 2 y - 1, y   - 2 y  - 21 y  - 31 y  - 14 y

              4       3      2       10      8       7    6       5       4
           - y  + 14 y  + 3 y  + 1, y   + 3 y  + 14 y  - y  - 14 y  - 31 y

                 3      2       5      4
           - 21 y  - 2 y  + 1, y  - 2 y  - 3 y - 1, y - 1]
          (%i2) resolvante: produit$
          (%i3) resolvante (x^5 + 3*x^4 + 2*x - 1, x, a*b*c, [a, b, c]);

          " resolvante produit "
                 10      8       7    6        5       4       3     2
          (%o3) y   + 3 y  + 14 y  - y  - 14 y  - 31 y  - 21 y  - 2 y  + 1

     See also:
     ‘resolvante’, ‘resolvante_unitaire’,
     ‘resolvante_alternee1’, ‘resolvante_klein’,
     ‘resolvante_klein3’, ‘resolvante_vierer’,
     *note resolvante_diedrale::.

 -- Function: resolvante_unitaire (<P>, <Q>, <x>)
     computes the resolvent of the polynomial ‘<P>(<x>)’ by the
     polynomial ‘<Q>(<x>)’.

     See also:
     ‘resolvante_produit_sym’, ‘resolvante’,
     ‘resolvante_alternee1’, ‘resolvante_klein’, ‘resolvante_klein3’,
     ‘resolvante_vierer’, *note resolvante_diedrale::.

 -- Function: resolvante_vierer (<P>, <x>)
     computes the transformation of ‘<P>(<x>)’ by the function ‘<x_1>
     <x_2> - <x_3> <x_4>’.

     See also:
     ‘resolvante_produit_sym’, ‘resolvante_unitaire’,
     ‘resolvante_alternee1’, ‘resolvante_klein’, ‘resolvante_klein3’,
     ‘resolvante’, *note resolvante_diedrale::.

98.2.7 Miscellaneous
--------------------

 -- Function: multinomial (<r>, <part>)
     where <r> is the weight of the partition <part>.  This function
     returns the associate multinomial coefficient: if the parts of
     <part> are <i_1>, <i_2>, ..., <i_k>, the result is ‘<r>!/(<i_1>!
     <i_2>! ... <i_k>!)’.

 -- Function: permut (<L>)
     returns the list of permutations of the list <L>.


File: maxima.info,  Node: Package to_poly_solve,  Next: Package trigtools,  Prev: Package sym,  Up: Top

99 Package to_poly_solve
************************

* Menu:

* Functions and Variables for to_poly_solve::


File: maxima.info,  Node: Functions and Variables for to_poly_solve,  Prev: Package to_poly_solve,  Up: Package to_poly_solve

99.1 Functions and Variables for to_poly_solve
==============================================

The packages ‘to_poly’ and ‘to_poly_solve’ are experimental; the
specifications of the functions in these packages might change or the
some of the functions in these packages might be merged into other
Maxima functions.

   Barton Willis (Professor of Mathematics, University of Nebraska at
Kearney) wrote the ‘to_poly’ and ‘to_poly_solve’ packages and the
English language user documentation for these packages.

 -- Operator: %and

     The operator ‘%and’ is a simplifying nonshort-circuited logical
     conjunction.  Maxima simplifies an ‘%and’ expression to either
     true, false, or a logically equivalent, but simplified, expression.
     The operator ‘%and’ is associative, commutative, and idempotent.
     Thus when ‘%and’ returns a noun form, the arguments of ‘%and’ form
     a non-redundant sorted list; for example

          (%i1) a %and (a %and b);
          (%o1)                       a %and b

     If one argument to a conjunction is the explicit the negation of
     another argument, ‘%and’ returns false:

          (%i2) a %and (not a);
          (%o2)                         false

     If any member of the conjunction is false, the conjunction
     simplifies to false even if other members are manifestly
     non-boolean; for example

          (%i3) 42 %and false;
          (%o3)                         false

     Any argument of an ‘%and’ expression that is an inequation (that
     is, an inequality or equation), is simplified using the Fourier
     elimination package.  The Fourier elimination simplifier has a
     pre-processor that converts some, but not all, nonlinear
     inequations into linear inequations; for example the Fourier
     elimination code simplifies ‘abs(x) + 1 > 0’ to true, so

          (%i4) (x < 1) %and (abs(x) + 1 > 0);
          (%o4)                         x < 1

     Notes
        • The option variable ‘prederror’ does not alter the
          simplification ‘%and’ expressions.

        • To avoid operator precedence errors, compound expressions
          involving the operators ‘%and, %or’, and ‘not’ should be fully
          parenthesized.

        • The Maxima operators ‘and’ and ‘or’ are both short-circuited.
          Thus ‘and’ isn't associative or commutative.

     Limitations The conjunction ‘%and’ simplifies inequations locally,
     not globally.  This means that conjunctions such as

          (%i5) (x < 1) %and (x > 1);
          (%o5)                 (x > 1) %and (x < 1)

     do not simplify to false.  Also, the Fourier elimination code
     ignores the fact database;

          (%i6) assume(x > 5);
          (%o6)                        [x > 5]
          (%i7) (x > 1) %and (x > 2);
          (%o7)                 (x > 1) %and (x > 2)

     Finally, nonlinear inequations that aren't easily converted into an
     equivalent linear inequation aren't simplified.

     There is no support for distributing ‘%and’ over ‘%or’; neither is
     there support for distributing a logical negation over ‘%and’.

     To use ‘load("to_poly_solve")’

     Related functions ‘%or, %if, and, or, not’

     Status The operator ‘%and’ is experimental; the specifications of
     this function might change and its functionality might be merged
     into other Maxima functions.

 -- Operator: %if (<bool>, <a>, <b>)

     The operator ‘%if’ is a simplifying conditional.  The conditional
     <bool> should be boolean-valued.  When the conditional is true,
     return the second argument; when the conditional is false, return
     the third; in all other cases, return a noun form.

     Maxima inequations (either an inequality or an equality) are not
     boolean-valued; for example, Maxima does not simplify 5 < 6 to
     true, and it does not simplify 5 = 6 to false; however, in the
     context of a conditional to an ‘%if’ statement, Maxima
     automatically attempts to determine the truth value of an
     inequation.  Examples:

          (%i1) f : %if(x # 1, 2, 8);
          (%o1)                 %if(x - 1 # 0, 2, 8)
          (%i2) [subst(x = -1,f), subst(x=1,f)];
          (%o2)                        [2, 8]

     If the conditional involves an inequation, Maxima simplifies it
     using the Fourier elimination package.

     Notes

        • If the conditional is manifestly non-boolean, Maxima returns a
          noun form:

          (%i3) %if(42,1,2);
          (%o3)                     %if(42, 1, 2)

        • The Maxima operator ‘if’ is nary, the operator ‘%if’ isn't
          nary.

     Limitations The Fourier elimination code only simplifies nonlinear
     inequations that are readily convertible to an equivalent linear
     inequation.

     To use: ‘load("to_poly_solve")’

     Status: The operator ‘%if’ is experimental; its specifications
     might change and its functionality might be merged into other
     Maxima functions.

 -- Operator: %or

     The operator ‘%or’ is a simplifying nonshort-circuited logical
     disjunction.  Maxima simplifies an ‘%or’ expression to either true,
     false, or a logically equivalent, but simplified, expression.  The
     operator ‘%or’ is associative, commutative, and idempotent.  Thus
     when ‘%or’ returns a noun form, the arguments of ‘%or’ form a
     non-redundant sorted list; for example

          (%i1) a %or (a %or b);
          (%o1)                        a %or b

     If one member of the disjunction is the explicit the negation of
     another member, ‘%or’ returns true:

          (%i2) a %or (not a);
          (%o2)                         true

     If any member of the disjunction is true, the disjunction
     simplifies to true even if other members of the disjunction are
     manifestly non-boolean; for example

          (%i3) 42 %or true;
          (%o3)                         true

     Any argument of an ‘%or’ expression that is an inequation (that is,
     an inequality or equation), is simplified using the Fourier
     elimination package.  The Fourier elimination code simplifies
     ‘abs(x) + 1 > 0’ to true, so we have

          (%i4) (x < 1) %or (abs(x) + 1 > 0);
          (%o4)                         true

     Notes
        • The option variable ‘prederror’ does not alter the
          simplification of ‘%or’ expressions.

        • You should parenthesize compound expressions involving the
          operators ‘%and, %or’, and ‘not’; the binding powers of these
          operators might not match your expectations.

        • The Maxima operators ‘and’ and ‘or’ are both short-circuited.
          Thus ‘or’ isn't associative or commutative.

     Limitations The conjunction ‘%or’ simplifies inequations locally,
     not globally.  This means that conjunctions such as

          (%i1) (x < 1) %or (x >= 1);
          (%o1) (x > 1) %or (x >= 1)

     do not simplify to true.  Further, the Fourier elimination code
     ignores the fact database;

          (%i2) assume(x > 5);
          (%o2)                        [x > 5]
          (%i3) (x > 1) %and (x > 2);
          (%o3)                 (x > 1) %and (x > 2)

     Finally, nonlinear inequations that aren't easily converted into an
     equivalent linear inequation aren't simplified.

     The algorithm that looks for terms that cannot both be false is
     weak; also there is no support for distributing ‘%or’ over ‘%and’;
     neither is there support for distributing a logical negation over
     ‘%or’.

     To use ‘load("to_poly_solve")’

     Related functions ‘%or, %if, and, or, not’

     Status The operator ‘%or’ is experimental; the specifications of
     this function might change and its functionality might be merged
     into other Maxima functions.

 -- Function: complex_number_p (<x>)

     The predicate ‘complex_number_p’ returns true if its argument is
     either ‘a + %i * b’, ‘a’, ‘%i b’, or ‘%i’, where ‘a’ and ‘b’ are
     either rational or floating point numbers (including big floating
     point); for all other inputs, ‘complex_number_p’ returns false; for
     example

          (%i1) map('complex_number_p,[2/3, 2 + 1.5 * %i, %i]);
          (%o1)                  [true, true, true]
          (%i2) complex_number_p((2+%i)/(5-%i));
          (%o2)                         false
          (%i3) complex_number_p(cos(5 - 2 * %i));
          (%o3)                         false

     Related functions ‘isreal_p’

     To use ‘load("to_poly_solve")’

     Status The operator ‘complex_number_p’ is experimental; its
     specifications might change and its functionality might be merged
     into other Maxima functions.

 -- Function: compose_functions (<l>)

     The function call ‘compose_functions(l)’ returns a lambda form that
     is the composition of the functions in the list <l>.  The functions
     are applied from right to left; for example

          (%i1) compose_functions([cos, exp]);
                                                  %g151
          (%o1)             lambda([%g151], cos(%e     ))
          (%i2) %(x);
                                            x
          (%o2)                       cos(%e )

     When the function list is empty, return the identity function:

          (%i3) compose_functions([]);
          (%o3)                lambda([%g152], %g152)
          (%i4)  %(x);
          (%o4)                           x

     Notes
        • When Maxima determines that a list member isn't a symbol or a
          lambda form, ‘funmake’ (not ‘compose_functions’) signals an
          error:

          (%i5) compose_functions([a < b]);

          funmake: first argument must be a symbol, subscripted symbol,
          string, or lambda expression; found: a < b
          #0: compose_functions(l=[a < b])(to_poly_solve.mac line 40)
           -- an error. To debug this try: debugmode(true);

        • To avoid name conflicts, the independent variable is
          determined by the function ‘new_variable’.

               (%i6) compose_functions([%g0]);
               (%o6)              lambda([%g154], %g0(%g154))
               (%i7) compose_functions([%g0]);
               (%o7)              lambda([%g155], %g0(%g155))

          Although the independent variables are different, Maxima is
          able to to deduce that these lambda forms are semantically
          equal:

               (%i8) is(equal(%o6,%o7));
               (%o8)                         true

     To use ‘load("to_poly_solve")’

     Status The function ‘compose_functions’ is experimental; its
     specifications might change and its functionality might be merged
     into other Maxima functions.

 -- Function: dfloat (<x>)

     The function ‘dfloat’ is a similar to ‘float’, but the function
     ‘dfloat’ applies ‘rectform’ when ‘float’ fails to evaluate to an
     IEEE double floating point number; thus

          (%i1) float(4.5^(1 + %i));
                                         %i + 1
          (%o1)                       4.5
          (%i2) dfloat(4.5^(1 + %i));
          (%o2)        4.48998802962884 %i + .3000124893895671

     Notes

        • The rectangular form of an expression might be poorly suited
          for numerical evaluation-for example, the rectangular form
          might needlessly involve the difference of floating point
          numbers (subtractive cancellation).

        • The identifier ‘float’ is both an option variable (default
          value false) and a function name.

     Related functions ‘float, bfloat’

     To use ‘load("to_poly_solve")’

     Status The function ‘dfloat’ is experimental; its specifications
     might change and its functionality might be merged into other
     Maxima functions.

 -- Function: elim (<l>, <x>)

     The function ‘elim’ eliminates the variables in the set or list ‘x’
     from the equations in the set or list ‘l’.  Each member of ‘x’ must
     be a symbol; the members of ‘l’ can either be equations, or
     expressions that are assumed to equal zero.

     The function ‘elim’ returns a list of two lists; the first is the
     list of expressions with the variables eliminated; the second is
     the list of pivots; thus, the second list is a list of expressions
     that ‘elim’ used to eliminate the variables.

     Here is an example of eliminating between linear equations:

          (%i1) elim(set(x + y + z = 1, x - y  - z = 8, x - z = 1),
                     set(x,y));
          (%o1)            [[2 z - 7], [y + 7, z - x + 1]]

     Eliminating ‘x’ and ‘y’ yields the single equation ‘2 z - 7 = 0’;
     the equations ‘y + 7 = 0’ and ‘z - z + 1 = 1’ were used as pivots.
     Eliminating all three variables from these equations,
     triangularizes the linear system:

          (%i2) elim(set(x + y + z = 1, x - y  - z = 8, x - z = 1),
                     set(x,y,z));
          (%o2)           [[], [2 z - 7, y + 7, z - x + 1]]

     Of course, the equations needn't be linear:

          (%i3) elim(set(x^2 - 2 * y^3 = 1,  x - y = 5), [x,y]);
                               3    2
          (%o3)       [[], [2 y  - y  - 10 y - 24, y - x + 5]]

     The user doesn't control the order the variables are eliminated.
     Instead, the algorithm uses a heuristic to attempt to choose the
     best pivot and the best elimination order.

     Notes

        • Unlike the related function ‘eliminate’, the function ‘elim’
          does not invoke ‘solve’ when the number of equations equals
          the number of variables.

        • The function ‘elim’ works by applying resultants; the option
          variable ‘resultant’ determines which algorithm Maxima uses.
          Using ‘sqfr’, Maxima factors each resultant and suppresses
          multiple zeros.

        • The ‘elim’ will triangularize a nonlinear set of polynomial
          equations; the solution set of the triangularized set can be
          larger than that solution set of the untriangularized set.
          Thus, the triangularized equations can have spurious
          solutions.

     Related functions elim_allbut, eliminate_using, eliminate

     Option variables resultant

     To use ‘load("to_poly")’

     Status The function ‘elim’ is experimental; its specifications
     might change and its functionality might be merged into other
     Maxima functions.

 -- Function: elim_allbut (<l>, <x>)

     This function is similar to ‘elim’, except that it eliminates all
     the variables in the list of equations ‘l’ except for those
     variables that in in the list ‘x’

          (%i1) elim_allbut([x+y = 1, x - 5*y = 1],[]);
          (%o1)                 [[], [y, y + x - 1]]
          (%i2) elim_allbut([x+y = 1, x - 5*y = 1],[x]);
          (%o2)                [[x - 1], [y + x - 1]]

     To use ‘load("to_poly")’

     Option variables resultant

     Related functions elim, eliminate_using, eliminate

     Status The function ‘elim_allbut’ is experimental; its
     specifications might change and its functionality might be merged
     into other Maxima functions.

 -- Function: eliminate_using (<l>, <e>, <x>)

     Using ‘e’ as the pivot, eliminate the symbol ‘x’ from the list or
     set of equations in ‘l’.  The function ‘eliminate_using’ returns a
     set.

          (%i1) eq : [x^2 - y^2 - z^3 , x*y - z^2 - 5, x - y + z];
                         3    2    2     2
          (%o1)      [- z  - y  + x , - z  + x y - 5, z - y + x]
          (%i2) eliminate_using(eq,first(eq),z);
                  3              2      2      3    2
          (%o2) {y  + (1 - 3 x) y  + 3 x  y - x  - x ,
                                  4    3  3       2  2             4
                                 y  - x  y  + 13 x  y  - 75 x y + x  + 125}
          (%i3) eliminate_using(eq,second(eq),z);
                  2            2       4    3  3       2  2             4
          (%o3) {y  - 3 x y + x  + 5, y  - x  y  + 13 x  y  - 75 x y + x
                                                                     + 125}
          (%i4) eliminate_using(eq, third(eq),z);
                  2            2       3              2      2      3    2
          (%o4) {y  - 3 x y + x  + 5, y  + (1 - 3 x) y  + 3 x  y - x  - x }

     Option variables resultant

     Related functions elim, eliminate, elim_allbut

     To use ‘load("to_poly")’

     Status The function ‘eliminate_using’ is experimental; its
     specifications might change and its functionality might be merged
     into other Maxima functions.

 -- Function: fourier_elim ([<eq1>, <eq2>, ...], [<var1>, <var>, ...])

     Fourier elimination is the analog of Gauss elimination for linear
     inequations (equations or inequalities).  The function call
     ‘fourier_elim([eq1, eq2, ...], [var1, var2, ...])’ does Fourier
     elimination on a list of linear inequations ‘[eq1, eq2, ...]’ with
     respect to the variables ‘[var1, var2, ...]’; for example

          (%i1) fourier_elim([y-x < 5, x - y < 7, 10 < y],[x,y]);
          (%o1)            [y - 5 < x, x < y + 7, 10 < y]
          (%i2) fourier_elim([y-x < 5, x - y < 7, 10 < y],[y,x]);
          (%o2)        [max(10, x - 7) < y, y < x + 5, 5 < x]

     Eliminating first with respect to x and second with respect to y
     yields lower and upper bounds for x that depend on y, and lower and
     upper bounds for y that are numbers.  Eliminating in the other
     order gives x dependent lower and upper bounds for y, and numerical
     lower and upper bounds for x.

     When necessary, ‘fourier_elim’ returns a _disjunction_ of lists of
     inequations:

          (%i3) fourier_elim([x # 6],[x]);
          (%o3)                  [x < 6] or [6 < x]

     When the solution set is empty, ‘fourier_elim’ returns ‘emptyset’,
     and when the solution set is all reals, ‘fourier_elim’ returns
     ‘universalset’; for example

          (%i4) fourier_elim([x < 1, x > 1],[x]);
          (%o4)                       emptyset
          (%i5) fourier_elim([minf < x, x < inf],[x]);
          (%o5)                     universalset

     For nonlinear inequations, ‘fourier_elim’ returns a (somewhat)
     simplified list of inequations:

          (%i6) fourier_elim([x^3 - 1 > 0],[x]);
                         2                             2
          (%o6) [1 < x, x  + x + 1 > 0] or [x < 1, - (x  + x + 1) > 0]
          (%i7) fourier_elim([cos(x) < 1/2],[x]);
          (%o7)                  [1 - 2 cos(x) > 0]

     Instead of a list of inequations, the first argument to
     ‘fourier_elim’ may be a logical disjunction or conjunction:

          (%i8) fourier_elim((x + y < 5) and (x - y >8),[x,y]);
                                                        3
          (%o8)            [y + 8 < x, x < 5 - y, y < - -]
                                                        2
          (%i9) fourier_elim(((x + y < 5) and x < 1) or  (x - y >8),[x,y]);
          (%o9)          [y + 8 < x] or [x < min(1, 5 - y)]

     The function ‘fourier_elim’ supports the inequation operators ‘<,
     <=, >, >=, #’, and ‘=’.

     The Fourier elimination code has a preprocessor that converts some
     nonlinear inequations that involve the absolute value, minimum, and
     maximum functions into linear in equations.  Additionally, the
     preprocessor handles some expressions that are the product or
     quotient of linear terms:

          (%i10) fourier_elim([max(x,y) > 6, x # 8, abs(y-1) > 12],[x,y]);
          (%o10) [6 < x, x < 8, y < - 11] or [8 < x, y < - 11]
           or [x < 8, 13 < y] or [x = y, 13 < y] or [8 < x, x < y, 13 < y]
           or [y < x, 13 < y]
          (%i11) fourier_elim([(x+6)/(x-9) <= 6],[x]);
          (%o11)           [x = 12] or [12 < x] or [x < 9]
          (%i12) fourier_elim([x^2 - 1 # 0],[x]);
          (%o12)      [- 1 < x, x < 1] or [1 < x] or [x < - 1]

     To use ‘load("fourier_elim")’

 -- Function: isreal_p (<e>)

     The predicate ‘isreal_p’ returns true when Maxima is able to
     determine that ‘e’ is real-valued on the entire real line; it
     returns false when Maxima is able to determine that ‘e’ isn't
     real-valued on some nonempty subset of the real line; and it
     returns a noun form for all other cases.

          (%i1) map('isreal_p, [-1, 0, %i, %pi]);
          (%o1)               [true, true, false, true]

     Maxima variables are assumed to be real; thus

          (%i2) isreal_p(x);
          (%o2)                         true

     The function ‘isreal_p’ examines the fact database:

          (%i3) declare(z,complex)$

          (%i4) isreal_p(z);
          (%o4)                      isreal_p(z)

     Limitations Too often, ‘isreal_p’ returns a noun form when it
     should be able to return false; a simple example: the logarithm
     function isn't real-valued on the entire real line, so
     ‘isreal_p(log(x))’ should return false; however

          (%i5) isreal_p(log(x));
          (%o5)                   isreal_p(log(x))

     To use ‘load("to_poly_solve")’

     Related functions complex_number_p

     Status The function ‘isreal_p’ is experimental; its specifications
     might change and its functionality might be merged into other
     Maxima functions.

 -- Function: new_variable (type)

     Return a unique symbol of the form ‘%[z,n,r,c,g]k’, where ‘k’ is an
     integer.  The allowed values for type are integer, natural_number,
     real, complex, and general.  (By natural number, we mean the
     nonnegative integers; thus zero is a natural number.  Some, but not
     all, definitions of natural number exclude zero.)

     When type isn't one of the allowed values, type defaults to
     general.  For integers, natural numbers, and complex numbers,
     Maxima automatically appends this information to the fact database.

          (%i1) map('new_variable,
                    ['integer, 'natural_number, 'real, 'complex, 'general]);
          (%o1)          [%z144, %n145, %r146, %c147, %g148]
          (%i2) nicedummies(%);
          (%o2)               [%z0, %n0, %r0, %c0, %g0]
          (%i3) featurep(%z0, 'integer);
          (%o3)                         true
          (%i4) featurep(%n0, 'integer);
          (%o4)                         true
          (%i5) is(%n0 >= 0);
          (%o5)                         true
          (%i6) featurep(%c0, 'complex);
          (%o6)                         true

     Note Generally, the argument to ‘new_variable’ should be quoted.
     The quote will protect against errors similar to

          (%i7) integer : 12$

          (%i8) new_variable(integer);
          (%o8)                         %g149
          (%i9) new_variable('integer);
          (%o9)                         %z150

     Related functions nicedummies

     To use ‘load("to_poly_solve")’

     Status The function ‘new_variable’ is experimental; its
     specifications might change and its functionality might be merged
     into other Maxima functions.

 -- Function: nicedummies

     Starting with zero, the function ‘nicedummies’ re-indexes the
     variables in an expression that were introduced by ‘new_variable’;

          (%i1) new_variable('integer) + 52 * new_variable('integer);
          (%o1)                   52 %z136 + %z135
          (%i2) new_variable('integer) - new_variable('integer);
          (%o2)                     %z137 - %z138
          (%i3) nicedummies(%);
          (%o3)                       %z0 - %z1

     Related functions new_variable

     To use ‘load("to_poly_solve")’

     Status The function ‘nicedummies’ is experimental; its
     specifications might change and its functionality might be merged
     into other Maxima functions.

 -- Function: parg (<x>)

     The function ‘parg’ is a simplifying version of the complex
     argument function ‘carg’; thus

          (%i1) map('parg,[1,1+%i,%i, -1 + %i, -1]);
                                  %pi  %pi  3 %pi
          (%o1)               [0, ---, ---, -----, %pi]
                                   4    2     4

     Generally, for a non-constant input, ‘parg’ returns a noun form;
     thus

          (%i2) parg(x + %i * sqrt(x));
          (%o2)                 parg(x + %i sqrt(x))

     When ‘sign’ can determine that the input is a positive or negative
     real number, ‘parg’ will return a non-noun form for a non-constant
     input.  Here are two examples:

          (%i3) parg(abs(x));
          (%o3) 0
          (%i4) parg(-x^2-1);
          (%o4)                          %pi

     Note The ‘sign’ function mostly ignores the variables that are
     declared to be complex (‘declare(x,complex)’); for variables that
     are declared to be complex, the ‘parg’ can return incorrect values;
     for example

          (%i1) declare(x,complex)$

          (%i2) parg(x^2 + 1);
          (%o2) 0

     Related function carg, isreal_p

     To use ‘load("to_poly_solve")’

     Status The function ‘parg’ is experimental; its specifications
     might change and its functionality might be merged into other
     Maxima functions.

 -- Function: real_imagpart_to_conjugate (<e>)

     The function ‘real_imagpart_to_conjugate’ replaces all occurrences
     of ‘realpart’ and ‘imagpart’ to algebraically equivalent
     expressions involving the ‘conjugate’.

          (%i1) declare(x, complex)$

          (%i2) real_imagpart_to_conjugate(realpart(x) +  imagpart(x) = 3);
                    conjugate(x) + x   %i (x - conjugate(x))
          (%o2)     ---------------- - --------------------- = 3
                           2                     2

     To use ‘load("to_poly_solve")’

     Status The function ‘real_imagpart_to_conjugate’ is experimental;
     its specifications might change and its functionality might be
     merged into other Maxima functions.

 -- Function: rectform_log_if_constant (<e>)

     The function ‘rectform_log_if_constant’ converts all terms of the
     form ‘ log(c)’ to ‘rectform(log(c))’, where ‘c’ is either a
     declared constant expression or explicitly declared constant

          (%i1) rectform_log_if_constant(log(1-%i) - log(x - %i));
                                           log(2)   %i %pi
          (%o1)            - log(x - %i) + ------ - ------
                                             2        4
          (%i2) declare(a,constant, b,constant)$

          (%i3) rectform_log_if_constant(log(a + %i*b));
                                 2    2
                            log(b  + a )
          (%o3)             ------------ + %i atan2(b, a)
                                 2

     To use ‘load("to_poly_solve")’

     Status The function ‘rectform_log_if_constant’ is experimental; the
     specifications of this function might change might change and its
     functionality might be merged into other Maxima functions.

 -- Function: simp_inequality (<e>)

     The function ‘simp_inequality’ applies basic simplifications to
     inequations, returning either a boolean value (true or false) or
     the original inequation.

     The simplification rules used by ‘simp_inequality’ include some
     facts about the ranges of the absolute value, power, and
     exponential functions along with some elementary algebra facts.

     For conjunctions or disjunctions of inequations, ‘simp_inequality’
     is applied to each individual inequation, but no effort is made to
     simplify the entire logical expression.

     Effectively, simp_inequality creates a new empty context, so
     database facts are not used to simplify inequations.

     ‘load("to_poly_solve")’ loads this function.

     Examples:

          (%i2) simp_inequality(1 # 0);
          (%o2) true

          (%i3) simp_inequality(1 < 0);
          (%o3) false

          (%i4) simp_inequality(a=a);
          (%o4) true

          (%i5) simp_inequality(a # a);
          (%o5) false

          (%i6) simp_inequality(a + 1 # a);
          (%o6) true

          (%i7) simp_inequality(a < a+1);
          (%o7) true

          (%i8) simp_inequality(abs(x) >= 0);
          (%o8) true

          (%i9) simp_inequality(exp(x)  > 0);
          (%o9) true

          (%i10) simp_inequality(x^2 >= 0);
          (%o10) true

          (%i11) simp_inequality(2^x  # 0);
          (%o11) true

          (%i12) simp_inequality(2^(x+1) > 2^x);
          (%o12) true

     The fact database is not consulted.  For example:

          (%i13) assume(xx > 0)$
          (%i14) simp_inequality(xx > 0);
          (%o14) xx>0

     And finally, for conjunctions or disjunctions of inequations, each
     inequation is simplified, but no effort is made to simplify the
     entire logical expression; for example:

          (%i15) simp_inequality((1 > 0) and (x < 0) and (x > 0));
          (%o15) x<0 and x>0

 -- Function: standardize_inverse_trig (<e>)

     This function applies the identities ‘cot(x) = atan(1/x), acsc(x) =
     asin(1/x),’ and similarly for ‘asec, acoth, acsch’ and ‘asech’ to
     an expression.  See Abramowitz and Stegun, Eqs.  4.4.6 through
     4.4.8 and 4.6.4 through 4.6.6.

     To use ‘load("to_poly_solve")’

     Status The function ‘standardize_inverse_trig’ is experimental; its
     specifications might change and its functionality might be merged
     into other Maxima functions.

 -- Function: subst_parallel (<l>, <e>)

     When ‘l’ is a single equation or a list of equations, substitute
     the right hand side of each equation for the left hand side.  The
     substitutions are made in parallel; for example

          (%i1) load("to_poly_solve")$

          (%i2) subst_parallel([x=y,y=x], [x,y]);
          (%o2)                        [y, x]

     Compare this to substitutions made serially:

          (%i3) subst([x=y,y=x],[x,y]);
          (%o3)                        [x, x]

     The function ‘subst_parallel’ is similar to ‘sublis’ except that
     ‘subst_parallel’ allows for substitution of nonatoms; for example

          (%i4) subst_parallel([x^2 = a, y = b], x^2 * y);
          (%o4)                          a b
          (%i5) sublis([x^2 = a, y = b], x^2 * y);

                                                                       2
          sublis: left-hand side of equation must be a symbol; found: x
           -- an error. To debug this try: debugmode(true);

     The substitutions made by ‘subst_parallel’ are literal, not
     semantic; thus ‘subst_parallel’ does not recognize that x * y is a
     subexpression of x^2 * y

          (%i6) subst_parallel([x * y = a], x^2 * y);
                                         2
          (%o6)                         x  y

     The function ‘subst_parallel’ completes all substitutions before
     simplifications.  This allows for substitutions into conditional
     expressions where errors might occur if the simplifications were
     made earlier:

          (%i7) subst_parallel([x = 0], %if(x < 1, 5, log(x)));
          (%o7)                           5
          (%i8) subst([x = 0], %if(x < 1, 5, log(x)));

          log: encountered log(0).
           -- an error. To debug this try: debugmode(true);

     Related functions subst, sublis, ratsubst

     To use ‘load("to_poly_solve_extra.lisp")’

     Status The function ‘subst_parallel’ is experimental; the
     specifications of this function might change might change and its
     functionality might be merged into other Maxima functions.

 -- Function: to_poly (<e>, <l>)

     The function ‘to_poly’ attempts to convert the equation ‘e’ into a
     polynomial system along with inequality constraints; the solutions
     to the polynomial system that satisfy the constraints are solutions
     to the equation ‘e’.  Informally, ‘to_poly’ attempts to
     polynomialize the equation <e>; an example might clarify:

          (%i1) load("to_poly_solve")$

          (%i2) to_poly(sqrt(x) = 3, [x]);
                                      2
          (%o2) [[%g130 - 3, x = %g130 ],
                                %pi                               %pi
                             [- --- < parg(%g130), parg(%g130) <= ---], []]
                                 2                                 2

     The conditions ‘-%pi/2<parg(%g130),parg(%g130)<=%pi/2’ tell us that
     ‘%g130’ is in the range of the square root function.  When this is
     true, the solution set to ‘sqrt(x) = 3’ is the same as the solution
     set to ‘%g130-3,x=%g130^2’.

     To polynomialize trigonometric expressions, it is necessary to
     introduce a non algebraic substitution; these non algebraic
     substitutions are returned in the third list returned by ‘to_poly’;
     for example

          (%i3) to_poly(cos(x),[x]);
                          2                                 %i x
          (%o3)    [[%g131  + 1], [2 %g131 # 0], [%g131 = %e    ]]

     Constant terms aren't polynomializied unless the number one is a
     member of the variable list; for example

          (%i4) to_poly(x = sqrt(5),[x]);
          (%o4)                [[x - sqrt(5)], [], []]
          (%i5) to_poly(x = sqrt(5),[1,x]);
                                      2
          (%o5) [[x - %g132, 5 = %g132 ],
                                %pi                               %pi
                             [- --- < parg(%g132), parg(%g132) <= ---], []]
                                 2                                 2

     To generate a polynomial with sqrt(5) + sqrt(7) as one of its
     roots, use the commands

          (%i6) first(elim_allbut(first(to_poly(x = sqrt(5) + sqrt(7),
                                                [1,x])), [x]));
                                    4       2
          (%o6)                   [x  - 24 x  + 4]

     Related functions to_poly_solve

     To use ‘load("to_poly")’

     Status: The function ‘to_poly’ is experimental; its specifications
     might change and its functionality might be merged into other
     Maxima functions.

 -- Function: to_poly_solve (<e>, <l>, [options])

     The function ‘to_poly_solve’ tries to solve the equations e for the
     variables l.  The equation(s) e can either be a single expression
     or a set or list of expressions; similarly, l can either be a
     single symbol or a list of set of symbols.  When a member of e
     isn't explicitly an equation, for example x^2 -1, the solver
     assumes that the expression vanishes.

     The basic strategy of ‘to_poly_solve’ is to convert the input into
     a polynomial form and to call ‘algsys’ on the polynomial system.
     Internally ‘to_poly_solve’ defaults ‘algexact’ to true.  To change
     the default for ‘algexact’, append 'algexact=false to the
     ‘to_poly_solve’ argument list.

     When ‘to_poly_solve’ is able to determine the solution set, each
     member of the solution set is a list in a ‘%union’ object:

          (%i1) load("to_poly_solve")$

          (%i2) to_poly_solve(x*(x-1) = 0, x);
          (%o2)               %union([x = 0], [x = 1])

     When ‘to_poly_solve’ is unable to determine the solution set, a
     ‘%solve’ nounform is returned (in this case, a warning is printed)

          (%i3) to_poly_solve(x^k + 2* x + 1 = 0, x);

          Nonalgebraic argument given to 'to_poly'
          unable to solve
                                    k
          (%o3)            %solve([x  + 2 x + 1 = 0], [x])

     Substitution into a ‘%solve’ nounform can sometimes result in the
     solution

          (%i4) subst(k = 2, %);
          (%o4)                   %union([x = - 1])

     Especially for trigonometric equations, the solver sometimes needs
     to introduce an arbitrary integer.  These arbitrary integers have
     the form ‘%zXXX’, where ‘XXX’ is an integer; for example

          (%i5) to_poly_solve(sin(x) = 0, x);
          (%o5)   %union([x = 2 %pi %z33 + %pi], [x = 2 %pi %z35])

     To re-index these variables to zero, use ‘nicedummies’:

          (%i6) nicedummies(%);
          (%o6)    %union([x = 2 %pi %z0 + %pi], [x = 2 %pi %z1])

     Occasionally, the solver introduces an arbitrary complex number of
     the form ‘%cXXX’ or an arbitrary real number of the form ‘%rXXX’.
     The function ‘nicedummies’ will re-index these identifiers to zero.

     The solution set sometimes involves simplifying versions of various
     of logical operators including ‘%and’, ‘%or’, or ‘%if’ for
     conjunction, disjunction, and implication, respectively; for
     example

          (%i7) sol : to_poly_solve(abs(x) = a, x);
          (%o7) %union(%if(isnonnegative_p(a), [x = - a], %union()),
                                %if(isnonnegative_p(a), [x = a], %union()))
          (%i8) subst(a = 42, sol);
          (%o8)             %union([x = - 42], [x = 42])
          (%i9) subst(a = -42, sol);
          (%o9)                       %union()

     The empty set is represented by ‘%union()’.

     The function ‘to_poly_solve’ is able to solve some, but not all,
     equations involving rational powers, some nonrational powers,
     absolute values, trigonometric functions, and minimum and maximum.
     Also, some it can solve some equations that are solvable in in
     terms of the Lambert W function; some examples:

          (%i1) load("to_poly_solve")$

          (%i2) to_poly_solve(set(max(x,y) = 5, x+y = 2), set(x,y));
          (%o2)      %union([x = - 3, y = 5], [x = 5, y = - 3])
          (%i3) to_poly_solve(abs(1-abs(1-x)) = 10,x);
          (%o3)             %union([x = - 10], [x = 12])
          (%i4) to_poly_solve(set(sqrt(x) + sqrt(y) = 5, x + y = 10),
                              set(x,y));
                               3/2               3/2
                              5    %i - 10      5    %i + 10
          (%o4) %union([x = - ------------, y = ------------],
                                   2                 2
                                          3/2                 3/2
                                         5    %i + 10        5    %i - 10
                                    [x = ------------, y = - ------------])
                                              2                   2
          (%i5) to_poly_solve(cos(x) * sin(x) = 1/2,x,
                              'simpfuncs = ['expand, 'nicedummies]);
                                                   %pi
          (%o5)              %union([x = %pi %z0 + ---])
                                                    4
          (%i6) to_poly_solve(x^(2*a) + x^a + 1,x);
                                                  2 %i %pi %z81
                                                  -------------
                                            1/a         a
                            (sqrt(3) %i - 1)    %e
          (%o6) %union([x = -----------------------------------],
                                            1/a
                                           2
                                                            2 %i %pi %z83
                                                            -------------
                                                      1/a         a
                                    (- sqrt(3) %i - 1)    %e
                               [x = -------------------------------------])
                                                     1/a
                                                    2
          (%i7) to_poly_solve(x * exp(x) = a, x);
          (%o7)              %union([x = lambert_w(a)])

     For linear inequalities, ‘to_poly_solve’ automatically does Fourier
     elimination:

          (%i8) to_poly_solve([x + y < 1, x - y >= 8], [x,y]);
                                         7
          (%o8) %union([x = y + 8, y < - -],
                                         2
                                                                        7
                                           [y + 8 < x, x < 1 - y, y < - -])
                                                                        2

     Each optional argument to ‘to_poly_solve’ must be an equation;
     generally, the order of these options does not matter.

        • ‘simpfuncs = l’, where ‘l’ is a list of functions.  Apply the
          composition of the members of l to each solution.

               (%i1) to_poly_solve(x^2=%i,x);
                                              1/4             1/4
               (%o1)       %union([x = - (- 1)   ], [x = (- 1)   ])
               (%i2) to_poly_solve(x^2= %i,x, 'simpfuncs = ['rectform]);
                                     %i         1             %i         1
               (%o2) %union([x = - ------- - -------], [x = ------- + -------])
                                   sqrt(2)   sqrt(2)        sqrt(2)   sqrt(2)

          Sometimes additional simplification can revert a
          simplification; for example

               (%i3) to_poly_solve(x^2=1,x);
               (%o3)              %union([x = - 1], [x = 1])
               (%i4) to_poly_solve(x^2= 1,x, 'simpfuncs = [polarform]);
                                                       %i %pi
               (%o4)            %union([x = 1], [x = %e      ]

          Maxima doesn't try to check that each member of the function
          list ‘l’ is purely a simplification; thus

               (%i5) to_poly_solve(x^2 = %i,x, 'simpfuncs = [lambda([s],s^2)]);
               (%o5)                   %union([x = %i])

          To convert each solution to a double float, use ‘simpfunc =
          ['dfloat]’:

               (%i6) to_poly_solve(x^3 +x + 1 = 0,x,
                                   'simpfuncs = ['dfloat]), algexact : true;
               (%o6) %union([x = - .6823278038280178],
               [x = .3411639019140089 - 1.161541399997251 %i],
               [x = 1.161541399997251 %i + .3411639019140089])

        • ‘use_grobner = true’ With this option, the function
          ‘poly_reduced_grobner’ is applied to the equations before
          attempting their solution.  Primarily, this option provides a
          workaround for weakness in the function ‘algsys’.  Here is an
          example of such a workaround:

               (%i7) to_poly_solve([x^2+y^2=2^2,(x-1)^2+(y-1)^2=2^2],[x,y],
                                   'use_grobner = true);
                                   sqrt(7) - 1      sqrt(7) + 1
               (%o7) %union([x = - -----------, y = -----------],
                                        2                2
                                                sqrt(7) + 1        sqrt(7) - 1
                                           [x = -----------, y = - -----------])
                                                     2                  2
               (%i8) to_poly_solve([x^2+y^2=2^2,(x-1)^2+(y-1)^2=2^2],[x,y]);
               (%o8)                       %union()

        • ‘maxdepth = k’, where ‘k’ is a positive integer.  This
          function controls the maximum recursion depth for the solver.
          The default value for ‘maxdepth’ is five.  When the recursions
          depth is exceeded, the solver signals an error:

               (%i9) to_poly_solve(cos(x) = x,x, 'maxdepth = 2);

               Unable to solve
               Unable to solve
               (%o9)        %solve([cos(x) = x], [x], maxdepth = 2)

        • ‘parameters = l’, where ‘l’ is a list of symbols.  The solver
          attempts to return a solution that is valid for all members of
          the list ‘l’; for example:

               (%i10) to_poly_solve(a * x = x, x);
               (%o10)                   %union([x = 0])
               (%i11) to_poly_solve(a * x = x, x, 'parameters = [a]);
               (%o11) %union(%if(a - 1 = 0, [x = %c111], %union()),
                                              %if(a - 1 # 0, [x = 0], %union()))

          In ‘(%o2)’, the solver introduced a dummy variable; to
          re-index the these dummy variables, use the function
          ‘nicedummies’:

               (%i12) nicedummies(%);
               (%o12) %union(%if(a - 1 = 0, [x = %c0], %union()),
                                              %if(a - 1 # 0, [x = 0], %union()))

     The ‘to_poly_solve’ uses data stored in the hashed array
     ‘one_to_one_reduce’ to solve equations of the form f(a) = f(b).
     The assignment ‘one_to_one_reduce['f,'f] : lambda([a,b], a=b)’
     tells ‘to_poly_solve’ that the solution set of f(a) = f(b) equals
     the solution set of a=b; for example

          (%i13) one_to_one_reduce['f,'f] : lambda([a,b], a=b)$

          (%i14) to_poly_solve(f(x^2-1) = f(0),x);
          (%o14)             %union([x = - 1], [x = 1])

     More generally, the assignment ‘one_to_one_reduce['f,'g] :
     lambda([a,b], w(a, b) = 0’ tells ‘to_poly_solve’ that the solution
     set of f(a) = f(b) equals the solution set of w(a,b) = 0; for
     example

          (%i15) one_to_one_reduce['f,'g] : lambda([a,b], a = 1 + b/2)$

          (%i16) to_poly_solve(f(x) - g(x),x);
          (%o16)                   %union([x = 2])

     Additionally, the function ‘to_poly_solve’ uses data stored in the
     hashed array ‘function_inverse’ to solve equations of the form f(a)
     = b.  The assignment ‘function_inverse['f] : lambda([s], g(s))’
     informs ‘to_poly_solve’ that the solution set to ‘f(x) = b’ equals
     the solution set to ‘x = g(b)’; two examples:

          (%i17) function_inverse['Q] : lambda([s], P(s))$

          (%i18) to_poly_solve(Q(x-1) = 2009,x);
          (%o18)              %union([x = P(2009) + 1])
          (%i19) function_inverse['G] : lambda([s], s+new_variable(integer));
          (%o19)       lambda([s], s + new_variable(integer))
          (%i20) to_poly_solve(G(x - a) = b,x);
          (%o20)             %union([x = b + a + %z125])

     Notes

        • The solve variables needn't be symbols; when ‘fullratsubst’ is
          able to appropriately make substitutions, the solve variables
          can be nonsymbols:

          (%i1) to_poly_solve([x^2 + y^2 + x * y = 5, x * y = 8],
                              [x^2 + y^2, x * y]);
                                            2    2
          (%o1)           %union([x y = 8, y  + x  = - 3])

        • For equations that involve complex conjugates, the solver
          automatically appends the conjugate equations; for example

          (%i1) declare(x,complex)$

          (%i2) to_poly_solve(x + (5 + %i) * conjugate(x) = 1, x);
                                             %i + 21
          (%o2)              %union([x = - -----------])
                                           25 %i - 125
          (%i3) declare(y,complex)$

          (%i4) to_poly_solve(set(conjugate(x) - y = 42 + %i,
                                  x + conjugate(y) = 0), set(x,y));
                                     %i - 42        %i + 42
          (%o4)        %union([x = - -------, y = - -------])
                                        2              2

        • For an equation that involves the absolute value function, the
          ‘to_poly_solve’ consults the fact database to decide if the
          argument to the absolute value is complex valued.  When

               (%i1) to_poly_solve(abs(x) = 6, x);
               (%o1)              %union([x = - 6], [x = 6])
               (%i2) declare(z,complex)$

               (%i3) to_poly_solve(abs(z) = 6, z);
               (%o3) %union(%if((%c11 # 0) %and (%c11 conjugate(%c11) - 36 =
                                                      0), [z = %c11], %union()))

          This is the only situation that the solver consults the fact
          database.  If a solve variable is declared to be an integer,
          for example, ‘to_poly_solve’ ignores this declaration.

     Relevant option variables algexact, resultant, algebraic

     Related functions to_poly

     To use ‘load("to_poly_solve")’

     Status: The function ‘to_poly_solve’ is experimental; its
     specifications might change and its functionality might be merged
     into other Maxima functions.

 -- Operator: %union (<soln_1>, <soln_2>, <soln_3>, ...)
 -- Operator: %union ()

     ‘%union(<soln_1>, <soln_2>, <soln_3>, ...)’ represents the union of
     its arguments, each of which represents a solution set, as
     determined by ‘to_poly_solve’.  ‘%union()’ represents the empty
     set.

     In many cases, a solution is a list of equations ‘[<x> = ..., <y> =
     ..., <z> = ...]’ where <x>, <y>, and <z> are one or more unknowns.
     In such cases, ‘to_poly_solve’ returns a ‘%union’ expression
     containing one or more such lists.

     The solution set sometimes involves simplifying versions of various
     of logical operators including ‘%and’, ‘%or’, or ‘%if’ for
     conjunction, disjunction, and implication, respectively.

     Examples:

     ‘%union(...)’ represents the union of its arguments, each of which
     represents a solution set, as determined by ‘to_poly_solve’.  In
     many cases, a solution is a list of equations.

          (%i1) load ("to_poly_solve") $
          (%i2) to_poly_solve ([sqrt(x^2 - y^2), x + y], [x, y]);
          (%o2)    %union([x = 0, y = 0], [x = %c13, y = - %c13])

     ‘%union()’ represents the empty set.

          (%i1) load ("to_poly_solve") $
          (%i2) to_poly_solve (abs(x) = -1, x);
          (%o2)                       %union()

     The solution set sometimes involves simplifying versions of various
     of logical operators.

          (%i1) load ("to_poly_solve") $
          (%i2) sol : to_poly_solve (abs(x) = a, x);
          (%o2) %union(%if(isnonnegative_p(a), [x = - a], %union()),
                                %if(isnonnegative_p(a), [x = a], %union()))
          (%i3) subst (a = 42, sol);
          (%o3)             %union([x = - 42], [x = 42])
          (%i4) subst (a = -42, sol);
          (%o4)                       %union()


File: maxima.info,  Node: Package trigtools,  Next: Package unit,  Prev: Package to_poly_solve,  Up: Top

100 Package trigtools
*********************

* Menu:

* Introduction to trigtools::
* Functions and Variables for trigtools::
* References::


File: maxima.info,  Node: Introduction to trigtools,  Next: Functions and Variables for trigtools,  Prev: Package trigtools,  Up: Package trigtools

                           Trigtools Package
                           *****************


                           Aleksas Dormarkas
                        <aleksasd873@gmail.com>
                     <aleksas.domarkas@mif.vu.lt>
                           December 1, 2013

100.1 Introduction to trigtools
===============================

We use open-source computer algebra system(CAS) maxima 5.31.2.  The
trigtools package(1) contains commands that help you work with
trigonometric expressions.  List of functions in trigtools package:

   • ‘c2sin’
   • ‘c2cos’
   • ‘c2trig’
   • ‘c2hyp’
   • ‘trigfactor’
   • ‘trigsolve’
   • ‘trigvalue’
   • ‘trigeval’
   • ‘atan_contract’

   ---------- Footnotes ----------

   (1) This is a conversion by hand of the original "trigtools-doc.pdf"
file in "share/contrib/trigtools", by Raymond Toy.  See the pdf for the
definitive version.


File: maxima.info,  Node: Functions and Variables for trigtools,  Next: References,  Prev: Introduction to trigtools,  Up: Package trigtools

100.2 Functions and Variables for trigtools
===========================================

* Menu:

* Convert to sin and cos::
* Convert to Trigonometric Functions::
* Convert to Hyperbolic Functions::
* Factor Sums of sin and cos Functions::
* Solve Trigonometric Equations::
* Evaluation of Trigonometric Functions::
* Contract atan Functions::


File: maxima.info,  Node: Convert to sin and cos,  Next: Convert to Trigonometric Functions,  Prev: Functions and Variables for trigtools,  Up: Functions and Variables for trigtools

100.2.1 Convert to sin and cos
------------------------------

 -- Function: c2sin (<x>)
 -- Function: c2cos (<x>)
     The function c2sin converts the expression a*cos(x)+b*sin(x) to
     r*sin(x+phi).

     The function c2cos converts the expression a*cos(x)+b*sin(x) to
     r*cos(x-phi).

     ‘load("trigtools")’ loads these functions.

     Examples:
          (%i1) load("trigtools")$
          (%i2) c2sin(3*sin(x)+4*cos(x));
                                                4
          (%o2)                  5 sin(x + atan(-))
                                                3
          (%i3) trigexpand(%),expand;
          (%o3)                  3 sin(x) + 4 cos(x)
          (%i4) c2cos(3*sin(x)-4*cos(x));
                                                 3
          (%o4)                 - 5 cos(x + atan(-))
                                                 4
          (%i5) trigexpand(%),expand;
          (%o5)                  3 sin(x) - 4 cos(x)
          (%i6) c2sin(sin(x)+cos(x));
                                                %pi
          (%o6)                 sqrt(2) sin(x + ---)
                                                 4
          (%i7) trigexpand(%),expand;
          (%o7)                    sin(x) + cos(x)
          (%i8) c2cos(sin(x)+cos(x));
                                                %pi
          (%o8)                 sqrt(2) cos(x - ---)
                                                 4
          (%i9) trigexpand(%),expand;
          (%o9)                    sin(x) + cos(x)

     Example.  Solve trigonometric equation

          (%i1) eq:3*sin(x)+4*cos(x)=2;
          (%o1)                3 sin(x) + 4 cos(x) = 2
          (%i2) plot2d([3*sin(x)+4*cos(x),2],[x,-%pi,%pi]);
          (%o2)                         false

           [image src="figures/trigtools-1.png" alt="plot1"]

          (%i1) load("trigtools")$
          (%i2) eq:3*sin(x)+4*cos(x)=2$
          (%i3) eq1:c2sin(lhs(eq))=2;
                                              4
          (%o3)                5 sin(x + atan(-)) = 2
                                              3
          (%i4) solvetrigwarn:false$
          (%i5) solve(eq1)[1]$ x1:rhs(%);
                                       2         4
          (%o6)                   asin(-) - atan(-)
                                       5         3
          (%i7) float(%), numer;
          (%o7)                 - 0.5157783719341241
          (%i8) eq2:c2cos(lhs(eq))=2;
                                              3
          (%o8)                5 cos(x - atan(-)) = 2
                                              4
          (%i9) solve(eq2,x)[1]$ x2:rhs(%);
                                       3         2
          (%o10)                  atan(-) + acos(-)
                                       4         5
          (%i11) float(%), numer;
          (%o11)                  1.802780589520693
          (%i12) sol:[x1,x2];
                             2         4        3         2
          (%o12)       [asin(-) - atan(-), atan(-) + acos(-)]
                             5         3        4         5

     Answ.: x = x1 + 2*%pi*k, x1 = asin(2/5)-atan(4/3), or x1 =
     atan(3/4)+acos(2/5), for k any integer.


File: maxima.info,  Node: Convert to Trigonometric Functions,  Next: Convert to Hyperbolic Functions,  Prev: Convert to sin and cos,  Up: Functions and Variables for trigtools

100.2.2 Convert to Trigonometric Functions
------------------------------------------

 -- Function: c2trig (<x>)
     The function c2trig (convert to trigonometric) reduce expression
     with hyperbolic functions sinh, cosh, tanh, coth to trigonometric
     expression with sin, cos, tan, cot.

     ‘load("trigtools")’ loads these functions.

     Examples:

       1.  
               (%i1) load(trigtools)$
               (%i2) sinh(x)=c2trig(sinh(x));
               (%o2)               sinh(x) = - %i sin(%i x)
               (%i3) cosh(x)=c2trig(cosh(x));
               (%o3)                  cosh(x) = cos(%i x)
               (%i4) tanh(x)=c2trig(tanh(x));
               (%o4)               tanh(x) = - %i tan(%i x)
               (%i5) coth(x)=c2trig(coth(x));
               (%o5)                coth(x) = %i cot(%i x)

       2. see
          <https://maxima.sourceforge.io/ext/list_archives/2013/msg03230.html>
               (%i1) load("trigtools")$
               (%i2) cos(p+q*%i);
               (%o2)                     cos(%i q + p)
               (%i3) trigexpand(%);
               (%o3)          cos(p) cosh(q) - %i sin(p) sinh(q)
               (%i4) c2trig(%);
               (%o4)                     cos(%i q + p)

       3.  
               (%i1) load("trigtools")$
               (%i2) sin(a+b*%i);
               (%o2)                     sin(%i b + a)
               (%i3) trigexpand(%);
               (%o3)          %i cos(a) sinh(b) + sin(a) cosh(b)
               (%i4) c2trig(%);
               (%o4)                     sin(%i b + a)

       4.  
               (%i1) load("trigtools")$
               (%i2) cos(a*%i+b*%i);
               (%o2)                   cos(%i b + %i a)
               (%i3) trigexpand(%);
               (%o3)           sinh(a) sinh(b) + cosh(a) cosh(b)
               (%i4) c2trig(%);
               (%o4)                   cos(%i b + %i a)

       5.  
               (%i1) load("trigtools")$
               (%i2) tan(a+%i*b);
               (%o2)                     tan(%i b + a)
               (%i3) trigexpand(%);
                                      %i tanh(b) + tan(a)
               (%o3)                 ---------------------
                                     1 - %i tan(a) tanh(b)
               (%i4) c2trig(%);
               (%o4)                     tan(%i b + a)

       6.  

               (%i1) load("trigtools")$
               (%i2) cot(x+%i*y);
               (%o2)                     cot(%i y + x)
               (%i3) trigexpand(%);
                                    - %i cot(x) coth(y) - 1
               (%o3)                -----------------------
                                      cot(x) - %i coth(y)
               (%i4) c2trig(%);
               (%o4)                     cot(%i y + x)


File: maxima.info,  Node: Convert to Hyperbolic Functions,  Next: Factor Sums of sin and cos Functions,  Prev: Convert to Trigonometric Functions,  Up: Functions and Variables for trigtools

100.2.3 Convert to Hyperbolic Functions
---------------------------------------

 -- Function: c2hyp (<x>)
     The function c2hyp (convert to hyperbolic) convert expression with
     exp function to expression with hyperbolic functions sinh, cosh.

     ‘load("trigtools")’ loads this function.

     Examples:

          (%i1) load("trigtools")$
          (%i2) c2hyp(exp(x));
          (%o2)                   sinh(x) + cosh(x)
          (%i3) c2hyp(exp(x)+exp(x^2)+1);
                           2          2
          (%o3)      sinh(x ) + cosh(x ) + sinh(x) + cosh(x) + 1
          (%i4) c2hyp(exp(x)/(2*exp(y)-3*exp(z)));
                                  sinh(x) + cosh(x)
          (%o4)     ---------------------------------------------
                    2 (sinh(y) + cosh(y)) - 3 (sinh(z) + cosh(z))


File: maxima.info,  Node: Factor Sums of sin and cos Functions,  Next: Solve Trigonometric Equations,  Prev: Convert to Hyperbolic Functions,  Up: Functions and Variables for trigtools

100.2.4 Factor Sums of sin and cos Functions
--------------------------------------------

 -- Function: trigfactor (<x>)
     The function trigfactor factors expressions of form
     +-sin(x)+-cos(y).

     ‘load("trigtools")’ loads this function.

     Examples:

       1.  
               (%i1) load("trigtools")$
               (%i2) trigfactor(sin(x)+cos(x));
                                                     %pi
               (%o2)                 sqrt(2) cos(x - ---)
                                                      4
               (%i3) trigrat(%);
               (%o3)                    sin(x) + cos(x)

       2.  
               (%i1) load("trigtools")$
               (%i2) trigfactor(sin(x)+cos(y));
                                    y   x   %pi      y   x   %pi
               (%o2)          2 cos(- - - + ---) cos(- + - - ---)
                                    2   2    4       2   2    4
               (%i3) trigrat(%);
               (%o3)                    cos(y) + sin(x)

       3.  
               (%i1) load("trigtools")$
               (%i2) trigfactor(sin(x)-cos(3*y));
                                  3 y   x   %pi      3 y   x   %pi
               (%o2)        2 sin(--- - - + ---) sin(--- + - - ---)
                                   2    2    4        2    2    4
               (%i3) trigrat(%);
               (%o3)                   sin(x) - cos(3 y)

       4.  
               (%i1) load("trigtools")$
               (%i2) trigfactor(-sin(5*x)-cos(3*y));
                                 3 y   5 x   %pi      3 y   5 x   %pi
               (%o2)     - 2 cos(--- - --- + ---) cos(--- + --- - ---)
                                  2     2     4        2     2     4
               (%i3) trigrat(%);
               (%o3)                 - cos(3 y) - sin(5 x)

       5.  
               (%i1) load("trigtools")$
               (%i2) sin(alpha)+sin(beta)=trigfactor(sin(alpha)+sin(beta));
                                                    beta   alpha
               (%o2) sin(beta) + sin(alpha) = 2 cos(---- - -----)
                                                     2       2
                                                                   beta   alpha
                                                               sin(---- + -----)
                                                                    2       2
               (%i3) trigrat(%);
               (%o3)    sin(beta) + sin(alpha) = sin(beta) + sin(alpha)

       6.  
               (%i1) load("trigtools")$
               (%i2) sin(alpha)-sin(beta)=trigfactor(sin(alpha)-sin(beta));
                                                      beta   alpha
               (%o2) sin(alpha) - sin(beta) = - 2 sin(---- - -----)
                                                       2       2
                                                                   beta   alpha
                                                               cos(---- + -----)
                                                                    2       2

       7.  
               (%i1) load("trigtools")$
               (%i2) cos(alpha)+cos(beta)=trigfactor(cos(alpha)+cos(beta));
                                                    beta   alpha
               (%o2) cos(beta) + cos(alpha) = 2 cos(---- - -----)
                                                     2       2
                                                                   beta   alpha
                                                               cos(---- + -----)
                                                                    2       2

       8.  
               (%i1) load("trigtools")$
               (%i2) cos(alpha)-cos(beta)=trigfactor(cos(alpha)-cos(beta));
                                                    beta   alpha
               (%o2) cos(alpha) - cos(beta) = 2 sin(---- - -----)
                                                     2       2
                                                                   beta   alpha
                                                               sin(---- + -----)
                                                                    2       2

       9.  
               (%i1) load("trigtools")$
               (%i2) trigfactor(3*sin(x)+7*cos(x));
               (%o2)                  3 sin(x) + 7 cos(x)
               (%i3) c2sin(%);
                                                         7
               (%o3)               sqrt(58) sin(x + atan(-))
                                                         3
               (%i4) trigexpand(%),expand;
               (%o4)                  3 sin(x) + 7 cos(x)

       10.  
               (%i1) load("trigtools")$
               (%i2) trigfactor(sin(2*x));
               (%o2)                       sin(2 x)
               (%i3) trigexpand(%);
               (%o3)                    2 cos(x) sin(x)


File: maxima.info,  Node: Solve Trigonometric Equations,  Next: Evaluation of Trigonometric Functions,  Prev: Factor Sums of sin and cos Functions,  Up: Functions and Variables for trigtools

100.2.5 Solve Trigonometric Equations
-------------------------------------

 -- Function: trigsolve (<x>)
     The function trigsolve find solutions of trigonometric equation
     from interval [a, b).

     ‘load("trigtools")’ loads this function.

     Examples:
       1.  
               (%i1) eq:eq:3*sin(x)+4*cos(x)=2;
               (%o1)                3 sin(x) + 4 cos(x) = 2
               (%i2) plot2d([3*sin(x)+4*cos(x),2],[x,-%pi,%pi]);
               (%o2)                         false

           [image src="figures/trigtools-2.png" alt="plot2"]

               (%i1) load("trigtools")$
               (%i2) eq:eq:3*sin(x)+4*cos(x)=2$
               (%i3) sol:trigsolve(eq,-%pi,%pi);
                           2 sqrt(21)   12              2 sqrt(21)   12
               (%o3) {atan(---------- - --), %pi - atan(---------- + --)}
                               5        5                   5        5
               (%i4) float(%), numer;
               (%o4)      {- 0.5157783719341241, 1.8027805895206928}

          Answ.  : x = atan((2*sqrt(21))/5-12/5)+2*%pi*k ;
          x=%pi-atan((2*sqrt(21))/5+12/5)+2*%pi*k, k - any integer.

       2.  
               (%i1) load("trigtools")$
               (%i2) eq:cos(3*x)-sin(x)=sqrt(3)*(cos(x)-sin(3*x));
               (%o2)    cos(3 x) - sin(x) = sqrt(3) (cos(x) - sin(3 x))
               (%i3) plot2d([lhs(eq)-rhs(eq)], [x,0,2*%pi])$

           [image src="figures/trigtools-3.png" alt="plot3"]

          We have 6 solutions from [0, 2*pi].
               (%i1) load("trigtools")$
               (%i2) eq:cos(3*x)-sin(x)=sqrt(3)*(cos(x)-sin(3*x))$
               (%i3) plot2d([lhs(eq)-rhs(eq)], [x,0.2,0.5])$

           [image src="figures/trigtools-4.png" alt="plot4"]

               (%i1) load("trigtools")$
               (%i2) load("trigtools")$
               (%i3) eq:cos(3*x)-sin(x)=sqrt(3)*(cos(x)-sin(3*x))$
               (%i4) plot2d([lhs(eq)-rhs(eq)], [x,3.3,3.6])$

           [image src="figures/trigtools-5.png" alt="plot4"]

               (%i1) load("trigtools")$
               (%i2) eq:cos(3*x)-sin(x)=sqrt(3)*(cos(x)-sin(3*x))$
               (%i3) trigfactor(lhs(eq))=map(trigfactor,rhs(eq));
                                 %pi            %pi
               (%o3) - 2 sin(x + ---) sin(2 x - ---) =
                                  4              4
                                                             %pi            %pi
                                           2 sqrt(3) sin(x - ---) sin(2 x - ---)
                                                              4              4
               (%i4) factor(lhs(%)-rhs(%));
                              4 x + %pi                4 x - %pi
               (%o4) - 2 (sin(---------) + sqrt(3) sin(---------))
                                  4                        4
                                                                      8 x - %pi
                                                                  sin(---------)
                                                                          4

          Equation is equivalent to
               (%i1) load("trigtools")$
               (%i2) eq:cos(3*x)-sin(x)=sqrt(3)*(cos(x)-sin(3*x))$
               (%i3) trigfactor(lhs(eq))=map(trigfactor,rhs(eq));
                                 %pi            %pi
               (%o3) - 2 sin(x + ---) sin(2 x - ---) =
                                  4              4
                                                             %pi            %pi
                                           2 sqrt(3) sin(x - ---) sin(2 x - ---)
                                                              4              4
               (%i4) L:factor(rhs(%)-lhs(%));
                            4 x + %pi                4 x - %pi       8 x - %pi
               (%o4) 2 (sin(---------) + sqrt(3) sin(---------)) sin(---------)
                                4                        4               4
               (%i5) eq1:part(L,2)=0;
                              4 x + %pi                4 x - %pi
               (%o5)      sin(---------) + sqrt(3) sin(---------) = 0
                                  4                        4
               (%i6) eq2:part(L,3)=0;
                                          8 x - %pi
               (%o6)                  sin(---------) = 0
                                              4
               (%i7) S1:trigsolve(eq1,0,2*%pi);
                                          %pi  13 %pi
               (%o7)                     {---, ------}
                                          12     12
               (%i8) S2:trigsolve(eq2,0,2*%pi);
                                   %pi  5 %pi  9 %pi  13 %pi
               (%o8)              {---, -----, -----, ------}
                                    8     8      8      8
               (%i9) S:listify(union(S1,S2));
                            %pi  %pi  5 %pi  13 %pi  9 %pi  13 %pi
               (%o9)       [---, ---, -----, ------, -----, ------]
                            12    8     8      12      8      8
               (%i10) float(%), numer;
               (%o10) [0.2617993877991494, 0.39269908169872414,
               1.9634954084936207, 3.4033920413889422, 3.5342917352885173,
               5.105088062083414]

          Answer: x = a+2*%pi*k, where a any from S, k any integer.

       3.  
               (%i1) load("trigtools")$
               (%i2) eq:8*cos(x)*cos(4*x)*cos(5*x)-1=0;
               (%o2)          8 cos(x) cos(4 x) cos(5 x) - 1 = 0
               (%i3) trigrat(%);
               (%o3)     2 cos(10 x) + 2 cos(8 x) + 2 cos(2 x) + 1 = 0

          Left side is periodic with period T=%pi.

          We have 10 solutions from [0, pi].
               (%i1) load("trigtools")$
               (%i2) eq:8*cos(x)*cos(4*x)*cos(5*x)-1=0$
               (%i3) plot2d([lhs(eq),rhs(eq)],[x,0,%pi]);
               (%o3)                         false

           [image src="figures/trigtools-6.png" alt="plot6"]

               (%i1) load("trigtools")$
               (%i2) eq:8*cos(x)*cos(4*x)*cos(5*x)-1=0$
               (%i3) x4:find_root(eq, x, 1.3, 1.32);
               (%o3)                  1.3089969389957472
               (%i4) x5:find_root(eq, x, 1.32, 1.35);
               (%o4)                  1.3463968515384828
               (%i5) plot2d([lhs(eq),0], [x,1.3,1.35], [gnuplot_preamble, "set grid;"]);
               (%o5)                         false

           [image src="figures/trigtools-7.png" alt="plot7"]

          Equation we multiply by 2*sin(x)*cos(2*x):

               (%i1) load("trigtools")$
               (%i2) eq:8*cos(x)*cos(4*x)*cos(5*x)-1=0$
               (%i3) eq*2*sin(x)*cos(2*x);
               (%o3) 2 sin(x) cos(2 x) (8 cos(x) cos(4 x) cos(5 x) - 1) = 0
               (%i4) eq1:trigreduce(%),expand;
               (%o4)                sin(13 x) + sin(x) = 0
               (%i5) trigfactor(lhs(eq1))=0;
               (%o5)                2 cos(6 x) sin(7 x) = 0
               (%i6) S1:trigsolve(cos(6*x),0,%pi);
                             %pi  %pi  5 %pi  7 %pi  3 %pi  11 %pi
               (%o6)        {---, ---, -----, -----, -----, ------}
                             12    4    12     12      4      12
               (%i7) S2:trigsolve(sin(7*x),0,%pi);
                              %pi  2 %pi  3 %pi  4 %pi  5 %pi  6 %pi
               (%o7)      {0, ---, -----, -----, -----, -----, -----}
                               7     7      7      7      7      7

          We remove solutions of sin(x)=0 and cos(2*x) = 0.

               (%i1) load("trigtools")$
               (%i2) S1:trigsolve(cos(6*x),0,%pi)$
               (%i3) S2:trigsolve(sin(7*x),0,%pi)$
               (%i4) S3:trigsolve(sin(x),0,%pi);
               (%o4)                          {0}
               (%i5) S4:trigsolve(cos(2*x),0,%pi);
                                          %pi  3 %pi
               (%o5)                     {---, -----}
                                           4     4

          We find 10 solutions from [0, %pi]:

               (%i1) load("trigtools")$
               (%i2) S1:trigsolve(cos(6*x),0,%pi)$
               (%i3) S2:trigsolve(sin(7*x),0,%pi)$
               (%i4) S3:trigsolve(sin(x),0,%pi)$
               (%i5) S4:trigsolve(cos(2*x),0,%pi)$
               (%i6) union(S1,S2)$ setdifference(%,S3)$ setdifference(%,S4);
                      %pi  %pi  2 %pi  5 %pi  3 %pi  4 %pi  7 %pi  5 %pi
               (%o8) {---, ---, -----, -----, -----, -----, -----, -----,
                      12    7     7     12      7      7     12      7
                                                                  6 %pi  11 %pi
                                                                  -----, ------}
                                                                    7      12
               (%i9) S:listify(%);
                      %pi  %pi  2 %pi  5 %pi  3 %pi  4 %pi  7 %pi  5 %pi
               (%o9) [---, ---, -----, -----, -----, -----, -----, -----,
                      12    7     7     12      7      7     12      7
                                                                  6 %pi  11 %pi
                                                                  -----, ------]
                                                                    7      12
               (%i10) length(S);
               (%o10)                         10
               (%i11) float(S), numer;
               (%o11) [0.2617993877991494, 0.4487989505128276,
               0.8975979010256552, 1.3089969389957472, 1.3463968515384828,
               1.7951958020513104, 1.8325957145940461, 2.243994752564138,
               2.6927937030769655, 2.8797932657906435]
          Answer: x = a+2*%pi*k, where a any from S, k any integer.


File: maxima.info,  Node: Evaluation of Trigonometric Functions,  Next: Contract atan Functions,  Prev: Solve Trigonometric Equations,  Up: Functions and Variables for trigtools

100.2.6 Evaluation of Trigonometric Functions
---------------------------------------------

 -- Function: trigvalue (<x>)
     The function trigvalue compute values of sin(m*%pi/n),
     cos(m*%pi/n), tan(m*%pi/n), and cot(m*%pi/n) in radicals.

     ‘trigvalue’ is essentially an internal function.  Use function
     ‘trigeval’ in preference.

     ‘load("trigtools")’ loads this function.

 -- Function: trigeval (<x>)
     The function trigeval compute values of expressions with
     sin(m*%pi/n), cos(m*%pi/n), tan(m*%pi/n), and cot(m*%pi/n) in
     radicals.

   ‘load("trigtools")’ loads this function.

   Examples:
  1. Values of trigonometric functions
          (%i1) load("trigtools")$
          (%i2) load(trigtools)$
          (%i3) trigvalue(sin(%pi/10));
                                     sqrt(5) - 1
          (%o3)                      -----------
                                          4
          (%i4) trigvalue(cos(%pi/10));
                                  sqrt(sqrt(5) + 5)
          (%o4)                   -----------------
                                         3/2
                                        2
          (%i5) trigvalue(tan(%pi/10));
                                 sqrt(5 - 2 sqrt(5))
          (%o5)                  -------------------
                                       sqrt(5)
          (%i6) float(%), numer;
          (%o6)                  0.3249196962329063
          (%i7) float(tan(%pi/10)), numer;
          (%o7)                  0.3249196962329063
          (%i8) trigvalue(cot(%pi/10));
          (%o8)                  sqrt(2 sqrt(5) + 5)
          (%i9) float(%), numer;
          (%o9)                  3.0776835371752536
          (%i10) float(cot(%pi/10)), numer;
          (%o10)                  3.077683537175254
          (%i11) trigvalue(sin(%pi/32));
                        sqrt(2 - sqrt(sqrt(sqrt(2) + 2) + 2))
          (%o11)        -------------------------------------
                                          2
          (%i12) trigvalue(cos(%pi/32));
                        sqrt(sqrt(sqrt(sqrt(2) + 2) + 2) + 2)
          (%o12)        -------------------------------------
                                          2
          (%i13) trigvalue(cos(%pi/256));
          (%o13) sqrt(sqrt(sqrt(sqrt(sqrt(sqrt(sqrt(2) + 2) + 2) + 2) + 2)
                                                                + 2) + 2)/2
          (%i14) trigvalue(cos(%pi/60));
          (%o14)
            sqrt(sqrt(sqrt(2) sqrt(3) sqrt(sqrt(5) + 5) + sqrt(5) + 7) + 4)
            ---------------------------------------------------------------
                                          3/2
                                         2
          (%i15) trigvalue(sin(%pi/60));
          (%o15)
            sqrt(4 - sqrt(sqrt(2) sqrt(3) sqrt(sqrt(5) + 5) + sqrt(5) + 7))
            ---------------------------------------------------------------
                                          3/2
                                         2
          (%i16) trigvalue(sin(%pi/18));
                                          %pi
          (%o16)                      sin(---)
                                          18
          (%i17) trigvalue(sin(%pi/20));
                         sqrt(4 - sqrt(2) sqrt(sqrt(5) + 5))
          (%o17)         -----------------------------------
                                         3/2
                                        2

  2. ode example
          (%i1) load("trigtools")$
          (%i2) load(odes)$
          (%i3) eq:'diff(y,x,5)+2*y=0;
                                     5
                                    d y
          (%o3)                     --- + 2 y = 0
                                      5
                                    dx
          (%i4) odeL(eq,y,x);
                         1/5     4 %pi
                      - 2    cos(-----) x
                                   5              1/5     4 %pi
          (%o4) y = %e                    C5 sin(2    sin(-----) x)
                                                            5
                  1/5     4 %pi
               - 2    cos(-----) x
                            5              1/5     4 %pi
           + %e                    C4 cos(2    sin(-----) x)
                                                     5
                  1/5     2 %pi
               - 2    cos(-----) x
                            5              1/5     2 %pi
           + %e                    C3 sin(2    sin(-----) x)
                                                     5
                  1/5     2 %pi
               - 2    cos(-----) x
                            5              1/5     2 %pi
           + %e                    C2 cos(2    sin(-----) x)
                                                     5
                  1/5
               - 2    x
           + %e         C1
          (%i5) sol:trigeval(%);
                        (sqrt(5) - 1) x
                      - ---------------
                              9/5
                             2                 sqrt(sqrt(5) + 5) x
          (%o5) y = %e                  C3 sin(-------------------)
                                                      13/10
                                                     2
                 (sqrt(5) - 1) x
               - ---------------
                       9/5
                      2                 sqrt(sqrt(5) + 5) x
           + %e                  C2 cos(-------------------)
                                               13/10
                                              2
               (sqrt(5) + 1) x
               ---------------
                     9/5
                    2                 sqrt(5 - sqrt(5)) x
           + %e                C5 sin(-------------------)
                                             13/10
                                            2
               (sqrt(5) + 1) x
               ---------------
                     9/5                                          1/5
                    2                 sqrt(5 - sqrt(5)) x      - 2    x
           + %e                C4 cos(-------------------) + %e         C1
                                             13/10
                                            2
          (%i6) subst(sol,eq)$
          (%i7) ev(%, nouns)$
          (%i8) radcan(%);
          (%o8)                         0 = 0

  3. n-th root of complex number

     Example.  Find the 4-th roots of %i
          (%i1) load("trigtools")$
          (%i2) solve(x^4=%i,x);
                          1/8                1/8             1/8
          (%o2) [x = (- 1)    %i, x = - (- 1)   , x = - (- 1)    %i,
                                                                       1/8
                                                              x = (- 1)   ]
          (%i3) rectform(%);
                            %pi        %pi                %pi        %pi
          (%o3) [x = %i cos(---) - sin(---), x = - %i sin(---) - cos(---),
                             8          8                  8          8
                            %pi           %pi              %pi        %pi
                    x = sin(---) - %i cos(---), x = %i sin(---) + cos(---)]
                             8             8                8          8
          (%i4) trigeval(%);
                     sqrt(sqrt(2) + 2) %i   sqrt(2 - sqrt(2))
          (%o4) [x = -------------------- - -----------------,
                              2                     2
                sqrt(2 - sqrt(2)) %i   sqrt(sqrt(2) + 2)
          x = - -------------------- - -----------------,
                         2                     2
              sqrt(2 - sqrt(2))   sqrt(sqrt(2) + 2) %i
          x = ----------------- - --------------------,
                      2                    2
              sqrt(2 - sqrt(2)) %i   sqrt(sqrt(2) + 2)
          x = -------------------- + -----------------]
                       2                     2


File: maxima.info,  Node: Contract atan Functions,  Prev: Evaluation of Trigonometric Functions,  Up: Functions and Variables for trigtools

100.2.7 Contract atan Functions
-------------------------------

 -- Function: atan_contract (<r>)
     The function atan_contract(r) contracts atan functions.  We assume:
     abs(r)<%pi/2.

     ‘load("trigtools")’ loads this function.

     Examples:

       1.  
               (%i1) load("trigtools")$
               (%i2) atan_contract(atan(x)+atan(y));
               (%o2)                   atan(y) + atan(x)
               (%i3) assume(abs(atan(x)+atan(y))<%pi/2)$
               (%i4) atan(x)+atan(y)=atan_contract(atan(x)+atan(y));
                                                         y + x
               (%o4)           atan(y) + atan(x) = atan(-------)
                                                        1 - x y

       2.  
               (%i1) load("trigtools")$
               (%i2) atan(1/3)+atan(1/5)+atan(1/7)+atan(1/8)$ %=atan_contract(%);
                               1         1         1         1    %pi
               (%o3)      atan(-) + atan(-) + atan(-) + atan(-) = ---
                               3         5         7         8     4

       3. Machin's formulae
               (%i1) load("trigtools")$
               (%i2) 4*atan(1/5)-atan(1/239)=atan_contract(4*atan(1/5)-atan(1/239));
                                         1          1     %pi
               (%o2)              4 atan(-) - atan(---) = ---
                                         5         239     4

       4. see <https://en.wikipedia.org/wiki/Machin-like_formula>
               (%i1) load("trigtools")$
               (%i2) 12*atan(1/49)+32*atan(1/57)-5*atan(1/239)+12*atan(1/110443)$
               (%i3) %=atan_contract(%);
                             1             1             1
               (%o3) 12 atan(--) + 32 atan(--) - 5 atan(---)
                             49            57           239
                                                                     1       %pi
                                                         + 12 atan(------) = ---
                                                                   110443     4


File: maxima.info,  Node: References,  Prev: Functions and Variables for trigtools,  Up: Package trigtools

100.3 References
================

  1. <https://maxima.sourceforge.io>


File: maxima.info,  Node: Package unit,  Next: Package wrstcse,  Prev: Package trigtools,  Up: Top

101 Package unit
****************

* Menu:

* Introduction to Units::
* Functions and Variables for Units::


File: maxima.info,  Node: Introduction to Units,  Next: Functions and Variables for Units,  Prev: Package unit,  Up: Package unit

101.1 Introduction to Units
===========================

The _unit_ package enables the user to convert between arbitrary units
and work with dimensions in equations.  The functioning of this package
is radically different from the original Maxima units package - whereas
the original was a basic list of definitions, this package uses rulesets
to allow the user to chose, on a per dimension basis, what unit final
answers should be rendered in.  It will separate units instead of
intermixing them in the display, allowing the user to readily identify
the units associated with a particular answer.  It will allow a user to
simplify an expression to its fundamental Base Units, as well as
providing fine control over simplifying to derived units.  Dimensional
analysis is possible, and a variety of tools are available to manage
conversion and simplification options.  In addition to customizable
automatic conversion, _units_ also provides a traditional manual
conversion option.

   Note - when unit conversions are inexact Maxima will make
approximations resulting in fractions.  This is a consequence of the
techniques used to simplify units.  The messages warning of this type of
substitution are disabled by default in the case of units (normally they
are on) since this situation occurs frequently and the warnings clutter
the output.  (The existing state of ratprint is restored after unit
conversions, so user changes to that setting will be preserved
otherwise.)  If the user needs this information for units, they can set
_unitverbose:on_ to reactivate the printing of warnings from the unit
conversion process.

   _unit_ is included in Maxima in the share/contrib/unit directory.  It
obeys normal Maxima package loading conventions:

     (%i1) load("unit")$
     *******************************************************************
     *                       Units version 0.50                        *
     *          Definitions based on the NIST Reference on             *
     *              Constants, Units, and Uncertainty                  *
     *       Conversion factors from various sources including         *
     *                   NIST and the GNU units package                *
     *******************************************************************

     Redefining necessary functions...
     WARNING: DEFUN/DEFMACRO: redefining function TOPLEVEL-MACSYMA-EVAL ...
     WARNING: DEFUN/DEFMACRO: redefining function MSETCHK ...
     WARNING: DEFUN/DEFMACRO: redefining function KILL1 ...
     WARNING: DEFUN/DEFMACRO: redefining function NFORMAT ...
     Initializing unit arrays...
     Done.

   The WARNING messages are expected and not a cause for concern - they
indicate the _unit_ package is redefining functions already defined in
Maxima proper.  This is necessary in order to properly handle units.
The user should be aware that if other changes have been made to these
functions by other packages those changes will be overwritten by this
loading process.

   The _unit.mac_ file also loads a lisp file _unit-functions.lisp_
which contains the lisp functions needed for the package.

   Clifford Yapp is the primary author.  He has received valuable
assistance from Barton Willis of the University of Nebraska at Kearney
(UNK), Robert Dodier, and other intrepid folk of the Maxima mailing
list.

   There are probably lots of bugs.  Let me know.  ‘float’ and ‘numer’
don't do what is expected.

   TODO : dimension functionality, handling of temperature, showabbr and
friends.  Show examples with addition of quantities containing units.


File: maxima.info,  Node: Functions and Variables for Units,  Prev: Introduction to Units,  Up: Package unit

101.2 Functions and Variables for Units
=======================================

 -- Function: setunits (<list>)
     By default, the _unit_ package does not use any derived dimensions,
     but will convert all units to the seven fundamental dimensions
     using MKS units.
          (%i2) N;
                                               kg m
          (%o2)                                ----
                                                 2
                                                s
          (%i3) dyn;
                                             1      kg m
          (%o3)                           (------) (----)
                                           100000     2
                                                     s
          (%i4) g;
                                              1
          (%o4)                             (----) (kg)
                                             1000
          (%i5) centigram*inch/minutes^2;
                                            127        kg m
          (%o5)                       (-------------) (----)
                                       1800000000000     2
                                                        s

     In some cases this is the desired behavior.  If the user wishes to
     use other units, this is achieved with the ‘setunits’ command:
          (%i6) setunits([centigram,inch,minute]);
          (%o6)                                done
          (%i7) N;
                                      1800000000000   %in cg
          (%o7)                      (-------------) (------)
                                           127            2
                                                      %min
          (%i8) dyn;
                                         18000000   %in cg
          (%o8)                         (--------) (------)
                                           127          2
                                                    %min
          (%i9) g;
          (%o9)                             (100) (cg)
          (%i10) centigram*inch/minutes^2;
                                              %in cg
          (%o10)                              ------
                                                  2
                                              %min

     The setting of units is quite flexible.  For example, if we want to
     get back to kilograms, meters, and seconds as defaults for those
     dimensions we can do:
          (%i11) setunits([kg,m,s]);
          (%o11)                               done
          (%i12) centigram*inch/minutes^2;
                                            127        kg m
          (%o12)                      (-------------) (----)
                                       1800000000000     2
                                                        s

     Derived units are also handled by this command:
          (%i17) setunits(N);
          (%o17)                               done
          (%i18) N;
          (%o18)                                 N
          (%i19) dyn;
                                              1
          (%o19)                           (------) (N)
                                            100000
          (%i20) kg*m/s^2;
          (%o20)                                 N
          (%i21) centigram*inch/minutes^2;
                                              127
          (%o21)                        (-------------) (N)
                                         1800000000000

     Notice that the _unit_ package recognized the non MKS combination
     of mass, length, and inverse time squared as a force, and converted
     it to Newtons.  This is how Maxima works in general.  If, for
     example, we prefer dyne to Newtons, we simply do the following:
          (%i22) setunits(dyn);
          (%o22)                               done
          (%i23) kg*m/s^2;
          (%o23)                          (100000) (dyn)
          (%i24) centigram*inch/minutes^2;
                                            127
          (%o24)                         (--------) (dyn)
                                          18000000

     To discontinue simplifying to any force, we use the uforget
     command:
          (%i26) uforget(dyn);
          (%o26)                               false
          (%i27) kg*m/s^2;
                                               kg m
          (%o27)                               ----
                                                 2
                                                s
          (%i28) centigram*inch/minutes^2;
                                            127        kg m
          (%o28)                      (-------------) (----)
                                       1800000000000     2
                                                        s
     This would have worked equally well with ‘uforget(N)’ or
     ‘uforget(%force)’.

     See also ‘uforget’.  To use this function write first
     ‘load("unit")’.

 -- Function: uforget (<list>)
     By default, the _unit_ package converts all units to the seven
     fundamental dimensions using MKS units.  This behavior can be
     changed with the ‘setunits’ command.  After that, the user can
     restore the default behavior for a particular dimension by means of
     the ‘uforget’ command:
          (%i13) setunits([centigram,inch,minute]);
          (%o13)                               done
          (%i14) centigram*inch/minutes^2;
                                              %in cg
          (%o14)                              ------
                                                  2
                                              %min
          (%i15) uforget([cg,%in,%min]);
          (%o15)                      [false, false, false]
          (%i16) centigram*inch/minutes^2;
                                            127        kg m
          (%o16)                      (-------------) (----)
                                       1800000000000     2
                                                        s

     ‘uforget’ operates on dimensions, not units, so any unit of a
     particular dimension will work.  The dimension itself is also a
     legal argument.

     See also ‘setunits’.  To use this function write first
     ‘load("unit")’.

 -- Function: convert (<expr>, <list>)
     When resetting the global environment is overkill, there is the
     ‘convert’ command, which allows one time conversions.  It can
     accept either a single argument or a list of units to use in
     conversion.  When a convert operation is done, the normal global
     evaluation system is bypassed, in order to avoid the desired result
     being converted again.  As a consequence, for inexact calculations
     "rat" warnings will be visible if the global environment
     controlling this behavior (‘ratprint’) is true.  This is also
     useful for spot-checking the accuracy of a global conversion.
     Another feature is ‘convert’ will allow a user to do Base Dimension
     conversions even if the global environment is set to simplify to a
     Derived Dimension.

          (%i2) kg*m/s^2;
                                               kg m
          (%o2)                                ----
                                                 2
                                                s
          (%i3) convert(kg*m/s^2,[g,km,s]);
                                               g km
          (%o3)                                ----
                                                 2
                                                s
          (%i4) convert(kg*m/s^2,[g,inch,minute]);

          `rat' replaced 39.37007874015748 by 5000/127 = 39.37007874015748
                                        18000000000   %in g
          (%o4)                        (-----------) (-----)
                                            127           2
                                                      %min
          (%i5) convert(kg*m/s^2,[N]);
          (%o5)                                  N
          (%i6) convert(kg*m^2/s^2,[N]);
          (%o6)                                 m N
          (%i7) setunits([N,J]);
          (%o7)                                done
          (%i8) convert(kg*m^2/s^2,[N]);
          (%o8)                                 m N
          (%i9) convert(kg*m^2/s^2,[N,inch]);

          `rat' replaced 39.37007874015748 by 5000/127 = 39.37007874015748
                                           5000
          (%o9)                           (----) (%in N)
                                           127
          (%i10) convert(kg*m^2/s^2,[J]);
          (%o10)                                 J
          (%i11) kg*m^2/s^2;
          (%o11)                                 J
          (%i12) setunits([g,inch,s]);
          (%o12)                               done
          (%i13) kg*m/s^2;
          (%o13)                                 N
          (%i14) uforget(N);
          (%o14)                               false
          (%i15) kg*m/s^2;
                                          5000000   %in g
          (%o15)                         (-------) (-----)
                                            127       2
                                                     s
          (%i16) convert(kg*m/s^2,[g,inch,s]);

          `rat' replaced 39.37007874015748 by 5000/127 = 39.37007874015748
                                          5000000   %in g
          (%o16)                         (-------) (-----)
                                            127       2
                                                     s

     See also ‘setunits’ and ‘uforget’.  To use this function write
     first ‘load("unit")’.

 -- Optional variable: usersetunits
     Default value: none

     If a user wishes to have a default unit behavior other than that
     described, they can make use of _maxima-init.mac_ and the
     _usersetunits_ variable.  The _unit_ package will check on startup
     to see if this variable has been assigned a list.  If it has, it
     will use setunits on that list and take the units from that list to
     be defaults.  ‘uforget’ will revert to the behavior defined by
     usersetunits over its own defaults.  For example, if we have a
     _maxima-init.mac_ file containing:
          usersetunits : [N,J];
     we would see the following behavior:
          (%i1) load("unit")$
          *******************************************************************
          *                       Units version 0.50                        *
          *          Definitions based on the NIST Reference on             *
          *              Constants, Units, and Uncertainty                  *
          *       Conversion factors from various sources including         *
          *                   NIST and the GNU units package                *
          *******************************************************************

          Redefining necessary functions...
          WARNING: DEFUN/DEFMACRO: redefining function
           TOPLEVEL-MACSYMA-EVAL ...
          WARNING: DEFUN/DEFMACRO: redefining function MSETCHK ...
          WARNING: DEFUN/DEFMACRO: redefining function KILL1 ...
          WARNING: DEFUN/DEFMACRO: redefining function NFORMAT ...
          Initializing unit arrays...
          Done.
          User defaults found...
          User defaults initialized.
          (%i2) kg*m/s^2;
          (%o2)                                  N
          (%i3) kg*m^2/s^2;
          (%o3)                                  J
          (%i4) kg*m^3/s^2;
          (%o4)                                 J m
          (%i5) kg*m*km/s^2;
          (%o5)                             (1000) (J)
          (%i6) setunits([dyn,eV]);
          (%o6)                                done
          (%i7) kg*m/s^2;
          (%o7)                           (100000) (dyn)
          (%i8) kg*m^2/s^2;
          (%o8)                     (6241509596477042688) (eV)
          (%i9) kg*m^3/s^2;
          (%o9)                    (6241509596477042688) (eV m)
          (%i10) kg*m*km/s^2;
          (%o10)                   (6241509596477042688000) (eV)
          (%i11) uforget([dyn,eV]);
          (%o11)                           [false, false]
          (%i12) kg*m/s^2;
          (%o12)                                 N
          (%i13) kg*m^2/s^2;
          (%o13)                                 J
          (%i14) kg*m^3/s^2;
          (%o14)                                J m
          (%i15) kg*m*km/s^2;
          (%o15)                            (1000) (J)
     Without ‘usersetunits’, the initial inputs would have been
     converted to MKS, and uforget would have resulted in a return to
     MKS rules.  Instead, the user preferences are respected in both
     cases.  Notice these can still be overridden if desired.  To
     completely eliminate this simplification - i.e.  to have the user
     defaults reset to factory defaults - the ‘dontusedimension’ command
     can be used.  ‘uforget’ can restore user settings again, but only
     if ‘usedimension’ frees it for use.  Alternately,
     ‘kill(usersetunits)’ will completely remove all knowledge of the
     user defaults from the session.  Here are some examples of how
     these various options work.
          (%i2) kg*m/s^2;
          (%o2)                                  N
          (%i3) kg*m^2/s^2;
          (%o3)                                  J
          (%i4) setunits([dyn,eV]);
          (%o4)                                done
          (%i5) kg*m/s^2;
          (%o5)                           (100000) (dyn)
          (%i6) kg*m^2/s^2;
          (%o6)                     (6241509596477042688) (eV)
          (%i7) uforget([dyn,eV]);
          (%o7)                          [false, false]
          (%i8) kg*m/s^2;
          (%o8)                                  N
          (%i9) kg*m^2/s^2;
          (%o9)                                  J
          (%i10) dontusedimension(N);
          (%o10)                             [%force]
          (%i11) dontusedimension(J);
          (%o11)                         [%energy, %force]
          (%i12) kg*m/s^2;
                                               kg m
          (%o12)                               ----
                                                 2
                                                s
          (%i13) kg*m^2/s^2;
                                                   2
                                               kg m
          (%o13)                               -----
                                                 2
                                                s
          (%i14) setunits([dyn,eV]);
          (%o14)                               done
          (%i15) kg*m/s^2;
                                               kg m
          (%o15)                               ----
                                                 2
                                                s
          (%i16) kg*m^2/s^2;
                                                   2
                                               kg m
          (%o16)                               -----
                                                 2
                                                s
          (%i17) uforget([dyn,eV]);
          (%o17)                         [false, false]
          (%i18) kg*m/s^2;
                                               kg m
          (%o18)                               ----
                                                 2
                                                s
          (%i19) kg*m^2/s^2;
                                                   2
                                               kg m
          (%o19)                               -----
                                                 2
                                                s
          (%i20) usedimension(N);
          Done.  To have Maxima simplify to this dimension, use
          setunits([unit]) to select a unit.
          (%o20)                               true
          (%i21) usedimension(J);
          Done.  To have Maxima simplify to this dimension, use
          setunits([unit]) to select a unit.
          (%o21)                               true
          (%i22) kg*m/s^2;
                                               kg m
          (%o22)                               ----
                                                 2
                                                s
          (%i23) kg*m^2/s^2;
                                                   2
                                               kg m
          (%o23)                               -----
                                                 2
                                                s
          (%i24) setunits([dyn,eV]);
          (%o24)                               done
          (%i25) kg*m/s^2;
          (%o25)                          (100000) (dyn)
          (%i26) kg*m^2/s^2;
          (%o26)                    (6241509596477042688) (eV)
          (%i27) uforget([dyn,eV]);
          (%o27)                           [false, false]
          (%i28) kg*m/s^2;
          (%o28)                                 N
          (%i29) kg*m^2/s^2;
          (%o29)                                 J
          (%i30) kill(usersetunits);
          (%o30)                               done
          (%i31) uforget([dyn,eV]);
          (%o31)                          [false, false]
          (%i32) kg*m/s^2;
                                               kg m
          (%o32)                               ----
                                                 2
                                                s
          (%i33) kg*m^2/s^2;
                                                   2
                                               kg m
          (%o33)                               -----
                                                 2
                                                s
     Unfortunately this wide variety of options is a little confusing at
     first, but once the user grows used to them they should find they
     have very full control over their working environment.

 -- Function: metricexpandall (<x>)
     Rebuilds global unit lists automatically creating all desired
     metric units.  <x> is a numerical argument which is used to specify
     how many metric prefixes the user wishes defined.  The arguments
     are as follows, with each higher number defining all lower numbers'
     units:
                     0 - none. Only base units
                     1 - kilo, centi, milli
          (default)  2 - giga, mega, kilo, hecto, deka, deci, centi, milli,
                         micro, nano
                     3 - peta, tera, giga, mega, kilo, hecto, deka, deci,
                         centi, milli, micro, nano, pico, femto
                     4 - all
     Normally, Maxima will not define the full expansion since this
     results in a very large number of units, but ‘metricexpandall’ can
     be used to rebuild the list in a more or less complete fashion.
     The relevant variable in the _unit.mac_ file is <%unitexpand>.

 -- Variable: %unitexpand
     Default value: ‘2’

     This is the value supplied to ‘metricexpandall’ during the initial
     loading of _unit_.


File: maxima.info,  Node: Package wrstcse,  Next: Package zeilberger,  Prev: Package unit,  Up: Top

102 Package wrstcse
*******************

* Menu:

* Introduction to wrstcse::
* Functions and Variables for wrstcse::


File: maxima.info,  Node: Introduction to wrstcse,  Next: Functions and Variables for wrstcse,  Prev: Package wrstcse,  Up: Package wrstcse

102.1 Introduction to wrstcse
=============================

‘wrstcse’ provides a few approaches to worst case calculations that are
powerful enough for most engineering problems, but avoid the problems
that make a true interval arithmetic unfeasible for non-trivial
problems:
   • Extreme worst case calculation by determining which combination of
     extreme input values will yield the most extreme result
     (‘wc_mintypmax’, ‘wc_systematic’).  Its approach isn't guaranteed
     to find local minima and maxima in the middle of the input
     parameter space.  In most real-world problems, though, the
     derivation of the result to each parameter doesn't change its sign
     in the tolerance space, which moves the extreme cases to the edges
     of the tolerance space making them accessible to this method.  Via
     ‘wc_ewc_simplify’ this method can typically be reduced from a
     brute-force approach to being O(n)-complete.
   • The monte carlo approach that assigns each parameter random values
     in the tolerance space and, when repeated n times will yield a view
     of the distribution n samples might have.  The view provided by
     this method is pessimistic, as most real-wprld items are more
     probabible to lie in the middle of the tolerance space than at its
     end.
   • The root mean square approach that knowing an approximation of the
     parameters of the gaussian distribution of the input values one can
     determine how big the tolerances will realistically be if one
     requires a given yield (see ‘wc_mintypmax_rss’).  Note that even
     rectangles tend to quickly add up to approximation of gauss curve,
     if affecting the same tolerance which makes this method applicable
     to most real-world problems.

   Tolerances are applied to parameters by providing each
tolerance-laden parameter with a <tol[n]> that wrstcase will vary
between -1 and 1 looking for extreme results, while <rol[n]>=0 should
yield the typical value of a parameter..  Using the same <n> for two
parameters will make both parameters have coupled tolerances.  Therefore
two 1% resistors that both will change over the temperature range by
another 2% in the same way can be defined as follows:
     (%i1) load("wrstcse")$
     (%i2) vals: [
        R_1= 1000.0*(1+tol[1]*.01)*(1+tol[3]*.02),
        R_2= 2000.0*(1+tol[2]*.01)*(1+tol[3]*.02)
      ];
     (%o2) [R_1 = 1000.0 (0.01 tol  + 1) (0.02 tol  + 1),
                                  1               3
                         R_2 = 2000.0 (0.01 tol  + 1) (0.02 tol  + 1)]
                                               2               3
     (%i3) R_1+R_2=wc_mintypmax(subst(vals,R_1+R_2));
     (%o3) R_2 + R_1 = [min = 2910.6, typ = 3000.0,
                                             max = 3090.6000000000004]
     (%i4) R_1+R_2=wc_mintypmax_percent(subst(vals,R_1+R_2));
     (%o4) R_2 + R_1 = [min = - 2.980000000000005 %, typ = 3000.0,
                                           max = 3.0200000000000227 %]
     (%i5) R_1/R_2=wc_mintypmax(subst(vals,R_1/R_2));
           R_1
     (%o5) --- = [min = 0.4900990099009901, typ = 0.5,
           R_2
                                             max = 0.5101010101010102]
     (%i6) R_1/R_2=wc_mintypmax_percent(subst(vals,R_1/R_2));
           R_1
     (%o6) --- = [min = - 1.980198019801982 %, typ = 0.5,
           R_2
                                            max = 2.020202020202033 %]

   ‘load ("wrstcse")’ loads this package.


File: maxima.info,  Node: Functions and Variables for wrstcse,  Prev: Introduction to wrstcse,  Up: Package wrstcse

102.2 Functions and Variables for wrstcse
=========================================

 -- Function: wc_typicalvalues (<expression>)

     Returns what happens if all <tol[n]> happen to be 0, which moves
     all parameter to the middle of their tolerance range.

     Example:
          (%i1) load("wrstcse")$
          (%i2) vals: [
             R_1= 1000.0*(1+tol[1]*.01),
             R_2= 2000.0*(1+tol[2]*.01)
           ];
          (%o2) [R_1 = 1000.0 (0.01 tol  + 1),
                                       1
                                              R_2 = 2000.0 (0.01 tol  + 1)]
                                                                    2
          (%i3) divider:U_Out=U_In*R_1/(R_1+R_2);
                                          R_1 U_In
          (%o3)                   U_Out = ---------
                                          R_2 + R_1
          (%i4) wc_typicalvalues(vals);
          (%o4)             [R_1 = 1000.0, R_2 = 2000.0]
          (%i5) wc_typicalvalues(subst(vals,divider));
          (%o5)            U_Out = 0.3333333333333333 U_In

 -- Function: wc_inputvalues_min (<listofinputvalues>)

     Sets all the input values contained in <listofinputvalues> to their
     minimum values and returns the result.  Helpful for example when
     trying to determine the minimum result of complicated filters;

     See also *note wc_inputvalues_min::.

     Example:
          (%i1) load("wrstcse")$
          (%i2) vals: [
             R_1= 1000.0*(1+tol["R_1"]*.01+tol["Temp"]*.001),
             R_2= 2000.0*(1+tol["R_2"]*.01+tol["Temp"]*.001),
             R_3= 2000.0*(1+tol["R_3"]*.01)
           ];
          (%o2) [R_1 = 1000.0 (0.001 tol     + 0.01 tol    + 1),
                                        Temp           R_1
          R_2 = 2000.0 (0.001 tol     + 0.01 tol    + 1),
                                 Temp           R_2
          R_3 = 2000.0 (0.01 tol    + 1)]
                                R_3
          (%i3) wc_inputvalueranges(vals);
                     [ R_1  989.0   1000.0  1010.9999999999999 ]
                     [                                         ]
          (%o3)      [ R_2  1978.0  2000.0  2021.9999999999998 ]
                     [                                         ]
                     [ R_3  1980.0  2000.0        2020.0       ]
          (%i4) vals_min:wc_inputvalues_min(vals);
          (%o4)       [R_1 = 989.0, R_2 = 1978.0, R_3 = 1980.0]
          (%i5) wc_inputvalueranges(vals_min);
                           [ R_1  989.0   989.0   989.0  ]
                           [                             ]
          (%o5)            [ R_2  1978.0  1978.0  1978.0 ]
                           [                             ]
                           [ R_3  1980.0  1980.0  1980.0 ]

 -- Function: wc_inputvalues_max (<listofinputvalues>)

     Sets all the input values contained in <listofinputvalues> to their
     maximum values and returns the result.  Helpful for example when
     trying to determine the maximum result of complicated filters;

     See also *note wc_inputvalues_min::.

     Example:
          (%i1) fpprintprec:4;
          (%o1)                           4
          (%i2) load("wrstcse")$
          (%i3) vals: [
             R_1= 1000.0*(1+tol["R_1"]*.01+tol["Temp"]*.001),
             R_2= 2000.0*(1+tol["R_2"]*.01+tol["Temp"]*.001),
             R_3= 2000.0*(1+tol["R_3"]*.01)
           ];
          (%o3) [R_1 = 1000.0 (0.001 tol     + 0.01 tol    + 1),
                                        Temp           R_1
          R_2 = 2.0e+3 (0.001 tol     + 0.01 tol    + 1),
                                 Temp           R_2
          R_3 = 2.0e+3 (0.01 tol    + 1)]
                                R_3
          (%i4) wc_inputvalueranges(vals);
                         [ R_1   989.0    1000.0  1.011e+3 ]
                         [                                 ]
          (%o4)          [ R_2  1.978e+3  2.0e+3  2.022e+3 ]
                         [                                 ]
                         [ R_3  1.98e+3   2.0e+3  2.02e+3  ]
          (%i5) vals_max:wc_inputvalues_max(vals);
          (%o5)    [R_1 = 1.011e+3, R_2 = 2.022e+3, R_3 = 2.02e+3]
          (%i6) wc_inputvalueranges(vals_max);
                        [ R_1  1.011e+3  1.011e+3  1.011e+3 ]
                        [                                   ]
          (%o6)         [ R_2  2.022e+3  2.022e+3  2.022e+3 ]
                        [                                   ]
                        [ R_3  2.02e+3   2.02e+3   2.02e+3  ]

 -- Function: wc_inputvalueranges (<expression>, [<show_tols>])

     Convenience function: Displays a list which parameter can vary
     between which values.

     If <show_tols> is ‘true’ then this function additionally displays
     which <tol[n]> each variable is affected by.

     See also ‘wc_mintypmax2tol’ and *note wc_inputvalueassumptions::.

     Example:
          (%i1) fpprintprec:4;
          (%o1)                           4
          (%i2) load("wrstcse")$
          (%i3) vals: [
             R_1= 1000.0*(1+tol["R_1"]*.01+tol["Temp"]*.001),
             R_2= 2000.0*(1+tol["R_2"]*.01+tol["Temp"]*.001),
             R_3= 2000.0*(1+tol["R_3"]*.01)
           ];
          (%o3) [R_1 = 1000.0 (0.001 tol     + 0.01 tol    + 1),
                                        Temp           R_1
          R_2 = 2.0e+3 (0.001 tol     + 0.01 tol    + 1),
                                 Temp           R_2
          R_3 = 2.0e+3 (0.01 tol    + 1)]
                                R_3
          (%i4) wc_inputvalueranges(vals);
                         [ R_1   989.0    1000.0  1.011e+3 ]
                         [                                 ]
          (%o4)          [ R_2  1.978e+3  2.0e+3  2.022e+3 ]
                         [                                 ]
                         [ R_3  1.98e+3   2.0e+3  2.02e+3  ]
          (%i5) wc_inputvalueranges(vals,true);
                [ R_1   989.0    1000.0  1.011e+3  [tol    , tol   ] ]
                [                                      Temp     R_1  ]
                [                                                    ]
          (%o5) [ R_2  1.978e+3  2.0e+3  2.022e+3  [tol    , tol   ] ]
                [                                      Temp     R_2  ]
                [                                                    ]
                [ R_3  1.98e+3   2.0e+3  2.02e+3       [tol   ]      ]
                [                                          R_3       ]

 -- Function: wc_systematic (<expression>, [<num>])

     Systematically introduces <num> values per parameter into
     <expression> and returns a list of the result.  If no <num> is
     given, <num> defaults to <wc_defaultvaluespertol>.  Negative values
     for <num> make ‘wc_systematic’ use the monte carlo method with
     <num> samples, instead.

     If an equation uses the following values with tolerances:

     ‘vals:[R_1=100+tol[1],R_2=100+tol[2]];’

     ‘num=2’ will cause the following combinations of tolerances to be
     tested:
     (Figure wrstcse_ewc_2) ‘num=3’ will cause the following
     combinations of tolerances to be tested:
     (Figure wrstcse_ewc_3) ‘num=-500’ will cause the following
     combinations of tolerances to be tested, instead:
     (Figure wrstcse_montecarlo)

     See also ‘wc_defaultvaluespertol’, ‘wc_mintypmax’,
     ‘wc_defaultvaluespertol’, ‘wc_ewc_simplify’ and *note
     wc_montecarlo::.

     Example:
          (%i1) load("wrstcse")$
          (%i2) vals: [
             R_1= 1000.0*(1+tol[1]*.01),
             R_2= 2000.0*(1+tol[2]*.01)
           ];
          (%o2) [R_1 = 1000.0 (0.01 tol  + 1),
                                       1
                                              R_2 = 2000.0 (0.01 tol  + 1)]
                                                                    2
          (%i3) divider: U_Out=U_In*(R_1)/(R_1+R_2);
                                          R_1 U_In
          (%o3)                   U_Out = ---------
                                          R_2 + R_1
          (%i4) wc_systematic(subst(vals,rhs(divider)));
          (%o4) [0.33333333333333337 U_In, 0.3311036789297659 U_In,
          0.3289036544850498 U_In, 0.3355704697986577 U_In,
          0.3333333333333333 U_In, 0.33112582781456956 U_In,
          0.3377926421404682 U_In, 0.3355481727574751 U_In,
          0.3333333333333333 U_In]

 -- Function: wc_ewc_simplify (<expression>, <definitions>...)

     Brute-forcing through all combinations of <tol[n]> in order to find
     the worst-case combination is O(m^n)-complete and therefore
     computationally intensive for high numbers of tol[n].

     ‘wc_ewc_simplify’ uses the sign of the derivatives of <expression>
     to combine as many ‘tol[n]’, as possible.  The result is an
     expression that might run much faster through ‘wc_mintypmax’ and
     ‘wc_systematic’, but that, if the derivate of <expression> doesn't
     change sign in the <tol[n]> space, still yields the same results
     for the brute-force approaches to worst-case analysis.

     Note that changing the number of <tol[n]> will change the
     statistical distribution of the results over the <tol[n]> space and
     therefore will change the statistical distribution of the
     montecarlo method and the results of the root sum square functions.

     See also ‘wc_mintypmax’ and *note wc_montecarlo::.

     <definitions> allows to temporarily asssign values to specific
     <tol[n]> during the optimizations (normally optimizagion is done
     with all <tol[n]> being zero) which has the side-effect of
     excempting these <tol[n]> from the optimization.

     Example:
          (%i1) load("wrstcse")$
          (%i2) vals: [
             R_1= 1000.0*(1+tol[1]*.01),
             R_2= 2000.0*(1+tol[2]*.01)
           ];
          (%o2) [R_1 = 1000.0 (0.01 tol  + 1),
                                       1
                                              R_2 = 2000.0 (0.01 tol  + 1)]
                                                                    2
          (%i3) ratprint:false;
          (%o3)                         false
          (%i4) assume(U_In>0);
          (%o4)                      [U_In > 0]
          (%i5) divider: U_Out=U_In*(R_1)/(R_1+R_2);
                                          R_1 U_In
          (%o5)                   U_Out = ---------
                                          R_2 + R_1
          (%i6) divider_vals:subst(vals,divider);
                                  1000.0 (0.01 tol  + 1) U_In
                                                  1
          (%o6) U_Out = -----------------------------------------------
                        2000.0 (0.01 tol  + 1) + 1000.0 (0.01 tol  + 1)
                                        2                        1
          (%i7) divider_vals_simplified:lhs(divider_vals)=wc_ewc_simplify(rhs(divider_vals));
                                  1000.0 (1 - 0.01 tol ) U_In
                                                      2
          (%o7) U_Out = -----------------------------------------------
                        2000.0 (0.01 tol  + 1) + 1000.0 (1 - 0.01 tol )
                                        2                            2
          (%i8) wc_systematic(rhs(divider_vals));
          (%o8) [0.33333333333333337 U_In, 0.3311036789297659 U_In,
          0.3289036544850498 U_In, 0.3355704697986577 U_In,
          0.3333333333333333 U_In, 0.33112582781456956 U_In,
          0.3377926421404682 U_In, 0.3355481727574751 U_In,
          0.3333333333333333 U_In]
          (%i9) wc_systematic(rhs(divider_vals_simplified));
          (%o9) [0.3377926421404682 U_In, 0.3333333333333333 U_In,
                                                   0.3289036544850498 U_In]
          (%i10) lhs(divider_vals)=wc_mintypmax(rhs(divider_vals));
          (%o10) U_Out = [min = 0.3289036544850498 U_In,
              typ = 0.3333333333333333 U_In, max = 0.3377926421404682 U_In]
          (%i11) lhs(divider_vals_simplified)=wc_mintypmax(rhs(divider_vals_simplified));
          (%o11) U_Out = [min = 0.3289036544850498 U_In,
              typ = 0.3333333333333333 U_In, max = 0.3377926421404682 U_In]

     Use case for adding definitions (<tol["E_Gain"]> cannot be
     optimized without knowing the sign of <tol["U_In"]>):
          (%i1) load("wrstcse")$
          (%i2) vals: [
             U_In=1.2*tol["U_In"], /* The input voltage range */
             n_Bits=16,            /* The ADC's number of bits */
             U_Ref=1.2*(1+.01*tol["U_Ref"]), /* The Adc's reference */
             E_Gain=1+1.2e-6*tol["E_Gain"], /* Gain error */
             E_Offset=1.5e-6                /* Offset error */
           ];
          (%o2) [U_In = 1.2 tol    , n_Bits = 16,
                               U_In
          U_Ref = 1.2 (0.01 tol      + 1), E_Gain = 1.2e-6 tol       + 1,
                               U_Ref                          E_Gain
          E_Offset = 1.5e-6]
          (%i3) ratprint:false;
          (%o3)                         false
          (%i4) wc_inputvalueranges(vals);
                     [   U_In      - 1.2      0        1.2    ]
                     [                                        ]
                     [  n_Bits      16        16       16     ]
                     [                                        ]
          (%o4)      [  U_Ref      1.188     1.2      1.212   ]
                     [                                        ]
                     [  E_Gain   0.9999988    1     1.0000012 ]
                     [                                        ]
                     [ E_Offset   1.5e-6    1.5e-6   1.5e-6   ]
          (%i5) ndsadc:n_DSADC=((U_In*E_Gain+E_Offset)/U_Ref+.5)*(2^(n_Bits)-1);
                            n_Bits       E_Gain U_In + E_Offset
          (%o5) n_DSADC = (2       - 1) (---------------------- + 0.5)
                                                 U_Ref
          (%i6) lhs(ndsadc)=wc_ewc_simplify(subst(vals,rhs(ndsadc)));
          (%o6) n_DSADC = 65535 ((0.8333333333333334
           (1.5e-6 - 1.2 (1.2e-6 tol       + 1) tol     ))
                                    E_Gain         U_Ref
          /(0.01 tol      + 1) + 0.5)
                    U_Ref
          (%i7) lhs(ndsadc)=wc_ewc_simplify(subst(vals,rhs(ndsadc)),tol["U_In"]=1);
          (%o7) n_DSADC = 65535 ((0.8333333333333334
           (1.2 tol     (1 - 1.2e-6 tol     ) + 1.5e-6))
                   U_In                U_Ref
          /(0.01 tol      + 1) + 0.5)
                    U_Ref

 -- Function: wc_montecarlo (<expression>, <num>)

     Introduces <num> random values per parameter into <expression> and
     returns a list of the result.

     See also *note wc_systematic::.

     Example:
          (%i1) load("wrstcse")$
          (%i2) vals: [
             R_1= 1000.0*(1+tol[1]*.01),
             R_2= 2000.0*(1+tol[2]*.01)
           ];
          (%o2) [R_1 = 1000.0 (0.01 tol  + 1),
                                       1
                                              R_2 = 2000.0 (0.01 tol  + 1)]
                                                                    2
          (%i3) divider: U_Out=U_In*(R_1)/(R_1+R_2);
                                          R_1 U_In
          (%o3)                   U_Out = ---------
                                          R_2 + R_1
          (%i4) wc_montecarlo(subst(vals,rhs(divider)),10);
          (%o4) [0.3301505377099377 U_In, 0.33276843198354916 U_In,
          0.33406203454153227 U_In, 0.33434833585190965 U_In,
          0.3341006856369802 U_In, 0.3359647531928058 U_In,
          0.32911646313213117 U_In, 0.333158315034511 U_In,
          0.3325173140803672 U_In, 0.3331108406798784 U_In]

 -- Function: wc_mintypmax (<expr>, [<n>])

     Prints the minimum, maximum and typical value of <expr>.  If <n> is
     positive, <n> values for each parameter will be tried
     systematically.  If <n> is negative, <-n> random values are used
     instead.  If no <n> is given, <wc_defaultvaluespertol> is assumed.

     See also ‘wc_mintypmax_percent’, ‘wc_mintypmax_rss’,
     ‘wc_mintypmax_num’, ‘wc_min’, ‘wc_max’, ‘wc_ewc_simplify’ and *note
     wc_systematic::.

     Example:
          (%i1) load("wrstcse")$
          (%i2) ratprint:false$
          (%i3) vals: [
             R_1= 1000.0*(1+tol[1]*.01),
             R_2= 1000.0*(1+tol[2]*.01)
           ];
          (%o3) [R_1 = 1000.0 (0.01 tol  + 1),
                                       1
                                              R_2 = 1000.0 (0.01 tol  + 1)]
                                                                    2
          (%i4) assume(U_In>0);
          (%o4)                      [U_In > 0]
          (%i5) divider:U_Out=U_In*R_1/(R_1+R_2);
                                          R_1 U_In
          (%o5)                   U_Out = ---------
                                          R_2 + R_1
          (%i6) lhs(divider)=wc_mintypmax(subst(vals,rhs(divider)));
          (%o6) U_Out = [min = 0.495 U_In, typ = 0.5 U_In,
                                                          max = 0.505 U_In]

 -- Function: wc_mintypmax_num (<equation>, <var>, <range_min>,
     <range_max>, [<n>])

     For each tolerance calculation in <equation> this tries to
     numerically find the value of <var> that solves <equation>.
     Expects the value of <var> to be in the range
     <range_min>...<range_max>.  Additionally expects
     ‘lhs(equation)-rhs(equation)’ to change sign within that range.

     See also ‘wc_mintypmax’,

     Example:
          (%i1) load("wrstcse")$
          (%i2) ratprint:false$
          (%i3) vals: [
             f=(1+tol["f"]*.2),
             A=(1+tol["A"]*.1)
           ]$
          (%i4) wc_inputvalueranges(vals,true);
                             [ f  0.8  1  1.2  [tol ] ]
                             [                     f  ]
          (%o4)              [                        ]
                             [ A  0.9  1  1.1  [tol ] ]
                             [                     A  ]
          (%i5) assume(U_In>0);
          (%o5)                      [U_In > 0]
          (%i6) eq:cos(2*%pi*f*x)=A*x;
          (%o6)                 cos(2 %pi f x) = A x
          (%i7) x=wc_mintypmax_num(subst(vals,eq),x,0,.3);
          (%o7) x = [min = 0.18165213379777342, typ = 0.21544061525279004,
                                                  max = 0.2646539803703126]

 -- Function: wc_mintypmax_percent (<expr>, <sigmas>)

     Like ‘wc_mintypmax’, but outputs the tolerance range in percent.

     See *note wc_mintypmax::.

     Example:
          (%i1) load("wrstcse")$
          (%i2) ratprint:false$
          (%i3) wc_defaultsigma:6$
          (%i4) vals: [
             R_1= 1000.0*(1+tol[1]*.01),
             R_2= 1000.0*(1+tol[2]*.01)
           ];
          (%o4) [R_1 = 1000.0 (0.01 tol  + 1),
                                       1
                                              R_2 = 1000.0 (0.01 tol  + 1)]
                                                                    2
          (%i5) assume(U_In>0);
          (%o5)                      [U_In > 0]
          (%i6) divider:U_Out=U_In*R_1/(R_1+R_2);
                                          R_1 U_In
          (%o6)                   U_Out = ---------
                                          R_2 + R_1
          (%i7) lhs(divider)=wc_mintypmax(subst(vals,rhs(divider)));
          (%o7) U_Out = [min = 0.495 U_In, typ = 0.5 U_In,
                                                          max = 0.505 U_In]
          (%i8) lhs(divider)=wc_mintypmax_percent(subst(vals,rhs(divider)));
          (%o8) U_Out = [min = - 1.0000000000000009 %, typ = 0.5 U_In,
                                                max = 1.0000000000000009 %]

 -- Function: wc_mintypmax_rss (<expr>, <sigmas>)

     Prints the minimum and maximum of <expr>, as well as how high the
     probability is that <expr> will lie out of that range based on a
     root sum square calculation and assuming all input ranges will be
     gauss-shaped.

     <wc_defaultsigma> defines how many sigma of an input value's
     tolerance distribution the range of <tol[n]>=[-1...1] corresponds
     to.

     The RSS methods has a few advantages a brute-force worst-case
     calculation: It is fast even witput ‘wc_ewc_simplify’.  It prevents
     overengineering resulting from assuming all tolerances to add up in
     a catastrophical way if this only happens in a neglectible number
     of cases.  But it will yield only the correct results if the
     gaussian distribution of the input data is known.

     Due to its nature this method doesn't support tolerances that
     aren't symmetrical.  Therefore in that case the tolerances are
     extended in the direction that is less wide.

     See also ‘wc_defaultsigma’ ‘wc_mintypmax_rss_percent’, and *note
     wc_mintypmax::.

     Example:
          (%i1) load("wrstcse")$
          (%i2) ratprint:false$
          (%i3) wc_defaultsigma:6$
          (%i4) vals: [
             R_1= 1000.0*(1+tol[1]*.01),
             R_2= 1000.0*(1+tol[2]*.01)
           ];
          (%o4) [R_1 = 1000.0 (0.01 tol  + 1),
                                       1
                                              R_2 = 1000.0 (0.01 tol  + 1)]
                                                                    2
          (%i5) assume(U_In>0);
          (%o5)                      [U_In > 0]
          (%i6) divider:U_Out=U_In*R_1/(R_1+R_2);
                                          R_1 U_In
          (%o6)                   U_Out = ---------
                                          R_2 + R_1
          (%i7) lhs(divider)=wc_mintypmax_rss(subst(vals,rhs(divider)),6);
          (%o7) U_Out = [min = 0.49646446609406725 U_In, typ = 0.5 U_In,
           max = 0.5035355339059328 U_In, Fail = 0.0019731752898266564 ppm]

 -- Function: wc_mintypmax_rss_percent (<expr>, <sigmas>)

     Like ‘wc_mintypmax_rss’, but outputs the tolerance range in
     percent.

     See *note wc_mintypmax_rss::.

     Example:
          (%i1) load("wrstcse")$
          (%i2) ratprint:false$
          (%i3) wc_defaultsigma:6$
          (%i4) vals: [
             R_1= 1000.0*(1+tol[1]*.01),
             R_2= 1000.0*(1+tol[2]*.01)
           ];
          (%o4) [R_1 = 1000.0 (0.01 tol  + 1),
                                       1
                                              R_2 = 1000.0 (0.01 tol  + 1)]
                                                                    2
          (%i5) assume(U_In>0);
          (%o5)                      [U_In > 0]
          (%i6) divider:U_Out=U_In*R_1/(R_1+R_2);
                                          R_1 U_In
          (%o6)                   U_Out = ---------
                                          R_2 + R_1
          (%i7) lhs(divider)=wc_mintypmax_rss(subst(vals,rhs(divider)),6);
          (%o7) U_Out = [min = 0.49646446609406725 U_In, typ = 0.5 U_In,
           max = 0.5035355339059328 U_In, Fail = 0.0019731752898266564 ppm]
          (%i8) lhs(divider)=float(wc_mintypmax_rss_percent(subst(vals,rhs(divider)),6));
          (%o8) U_Out = [min = - 0.7071067811865506 %, typ = 0.5 U_In,
              max = 0.7071067811865506 %, Fail = 0.0019731752898266564 ppm]

 -- Option variable: wc_defaultsigma
     Default value: ‘6’

     Defines how many sigmas of the gauss distribution that represents
     the tolerances of a parameter correspond to a <tol[n]> value of
     -1...1.

     See also *note wc_mintypmax_rss::.

     Example:
          (%i1) load("wrstcse")$
          (%i2) ratprint:false$
          (%i3) vals: [
             R_1= 1000.0*(1+tol[1]*.01),
             R_2= 1000.0*(1+tol[2]*.01)
           ];
          (%o3) [R_1 = 1000.0 (0.01 tol  + 1),
                                       1
                                              R_2 = 1000.0 (0.01 tol  + 1)]
                                                                    2
          (%i4) assume(U_In>0);
          (%o4)                      [U_In > 0]
          (%i5) divider:U_Out=U_In*R_1/(R_1+R_2);
                                          R_1 U_In
          (%o5)                   U_Out = ---------
                                          R_2 + R_1
          (%i6) wc_defaultsigma:1$
          (%i7) lhs(divider)=wc_mintypmax_rss(subst(vals,rhs(divider)),6);
          (%o7) U_Out = [min = 0.4787867965644036 U_In, typ = 0.5 U_In,
           max = 0.5212132034355964 U_In, Fail = 0.0019731752898266564 ppm]
          (%i8) wc_defaultsigma:3$
          (%i9) lhs(divider)=wc_mintypmax_rss(subst(vals,rhs(divider)),6);
          (%o9) U_Out = [min = 0.49292893218813455 U_In, typ = 0.5 U_In,
           max = 0.5070710678118655 U_In, Fail = 0.0019731752898266564 ppm]
          (%i10) wc_defaultsigma:6$
          (%i11) lhs(divider)=wc_mintypmax_rss(subst(vals,rhs(divider)),6);
          (%o11) U_Out = [min = 0.49646446609406725 U_In, typ = 0.5 U_In,
           max = 0.5035355339059328 U_In, Fail = 0.0019731752898266564 ppm]

 -- Option variable: wc_defaultvaluespertol
     Default value: ‘3’

     Defines how many samples per <tol[n]> the EWC method of
     ‘wc_systematic’ and ‘wc_mintypmax’ shall use by default.

     See also ‘wc_systematic’ and *note wc_mintypmax::.

     Example:
          (%i1) load("wrstcse")$
          (%i2) ratprint:false$
          (%i3) vals: [
             R_1= 100.0*(1+tol[1]*.01),
             R_2= 1000.0*(1+tol[2]*.01)
           ];
          (%o3) [R_1 = 100.0 (0.01 tol  + 1), R_2 = 1000.0 (0.01 tol  + 1)]
                                      1                             2
          (%i4) wc_defaultvaluespertol:2$
          (%i5) wc_systematic(vals);
          (%o5) [[R_1 = 99.0, R_2 = 990.0], [R_1 = 99.0, R_2 = 1010.0],
                   [R_1 = 101.0, R_2 = 990.0], [R_1 = 101.0, R_2 = 1010.0]]
          (%i6) wc_defaultvaluespertol:3$
          (%i7) wc_systematic(vals);
          (%o7) [[R_1 = 99.0, R_2 = 990.0], [R_1 = 99.0, R_2 = 1000.0],
          [R_1 = 99.0, R_2 = 1010.0], [R_1 = 100.0, R_2 = 990.0],
          [R_1 = 100.0, R_2 = 1000.0], [R_1 = 100.0, R_2 = 1010.0],
          [R_1 = 101.0, R_2 = 990.0], [R_1 = 101.0, R_2 = 1000.0],
          [R_1 = 101.0, R_2 = 1010.0]]
          (%i8) wc_defaultvaluespertol:5$
          (%i9) wc_systematic(vals);
          (%o9) [[R_1 = 99.0, R_2 = 990.0], [R_1 = 99.0, R_2 = 995.0],
          [R_1 = 99.0, R_2 = 1000.0], [R_1 = 99.0,
          R_2 = 1004.9999999999999], [R_1 = 99.0, R_2 = 1010.0],
          [R_1 = 99.5, R_2 = 990.0], [R_1 = 99.5, R_2 = 995.0],
          [R_1 = 99.5, R_2 = 1000.0], [R_1 = 99.5,
          R_2 = 1004.9999999999999], [R_1 = 99.5, R_2 = 1010.0],
          [R_1 = 100.0, R_2 = 990.0], [R_1 = 100.0, R_2 = 995.0],
          [R_1 = 100.0, R_2 = 1000.0], [R_1 = 100.0,
          R_2 = 1004.9999999999999], [R_1 = 100.0, R_2 = 1010.0],
          [R_1 = 100.49999999999999, R_2 = 990.0],
          [R_1 = 100.49999999999999, R_2 = 995.0],
          [R_1 = 100.49999999999999, R_2 = 1000.0],
          [R_1 = 100.49999999999999, R_2 = 1004.9999999999999],
          [R_1 = 100.49999999999999, R_2 = 1010.0],
          [R_1 = 101.0, R_2 = 990.0], [R_1 = 101.0, R_2 = 995.0],
          [R_1 = 101.0, R_2 = 1000.0], [R_1 = 101.0,
          R_2 = 1004.9999999999999], [R_1 = 101.0, R_2 = 1010.0]]

 -- Function: wc_tolappend (<list1>, <list2>,...)

     Appends lists of parameters from independent sources making sure
     that tolerances of all elements in one list will stay independent
     from all elements in the others.

     Works like append() in that it appends all values from all of its
     arguments to make one big list.  But this command, if one list
     happens to contain a <tol[n]> with the same <n> as another list,
     changes one of these <n> to a new value that makes it independent
     from all tolerances from the other list.

     See also *note append::.

     Example:
          (%i1) load("wrstcse")$
          (%i2) val_a: [
             R_1= 1000.0*(1+tol[1]*.01),
             R_2= 1000.0*(1+tol[2]*.01)
           ];
          (%o2) [R_1 = 1000.0 (0.01 tol  + 1),
                                       1
                                              R_2 = 1000.0 (0.01 tol  + 1)]
                                                                    2
          (%i3) val_b: [
             R_3= 1000.0*(1+tol[1]*.01),
             R_4= 1000.0*(1+tol[4]*.01)
           ];
          (%o3) [R_3 = 1000.0 (0.01 tol  + 1),
                                       1
                                              R_4 = 1000.0 (0.01 tol  + 1)]
                                                                    4
          (%i4) append(val_a,val_b);
          (%o4) [R_1 = 1000.0 (0.01 tol  + 1),
                                       1
          R_2 = 1000.0 (0.01 tol  + 1), R_3 = 1000.0 (0.01 tol  + 1),
                                2                             1
          R_4 = 1000.0 (0.01 tol  + 1)]
                                4
          (%i5) wc_tolappend(val_a,val_b);
                                      used = 1

          (%o5) [R_1 = 1000.0 (0.01 tol  + 1),
                                       1
          R_2 = 1000.0 (0.01 tol  + 1), R_3 = 1000.0 (0.01 tol  + 1),
                                2                             5
          R_4 = 1000.0 (0.01 tol  + 1)]
                                4

 -- Function: wc_mintypmax2tol (<tolname>, <minval>, <typval>, <maxval>)

     Generates a parameter that uses the tolerance <tolname> and
     tolerates between the given values.

     Example:
          (%i1) load("wrstcse")$
          (%i2) vals: [U_Diode=wc_mintypmax2tol(tol[1],.5,.75,.82),
                 R=wc_mintypmax2tol(tol[2],1,1.1,1.3),
                 U_In=wc_mintypmax2tol(tol[3],0,0,15)];
          (%o2) [U_Diode = 0.034999999999999976 (|tol | + tol )
                                                 |   1|      1
           + 0.125 (tol  - |tol |) + 0.75,
                       1   |   1|
          R = 0.09999999999999998 (|tol | + tol )
                                   |   2|      2
           + 0.050000000000000044 (tol  - |tol |) + 1.1,
                                      2   |   2|
                 15 (|tol | + tol )
                     |   3|      3
          U_In = ------------------]
                         2
          (%i3) wc_inputvalueranges(vals);
                            [ U_Diode  0.5  0.75  0.82 ]
                            [                          ]
          (%o3)             [    R     1.0  1.1   1.3  ]
                            [                          ]
                            [  U_In     0    0     15  ]

 -- Function: wc_inputvalueassumptions (<expr>)

     Often it is good practice to keep all numeric values with
     tolerances in a list and to introduce them into the equations only
     when needed.

     ‘wc_inputvalueassumptions’ in this case can inform the ‘assume’
     database about the range each variable in that list will be in.

     See also ‘wc_tolassumptions’, ‘wc_inputvalueranges’ and *note
     assume::.

     Example:
          (%i1) load("wrstcse");
          (%o1) /home/gunter/src/maxima-code/share/contrib/wrstcse.mac
          (%i2) vals:[
              R_1=100*(1+1/100*tol["R1"])*(1+1/100*tol["Temp"]),
              R_2=200*(1+1/100*tol["R2"])*(1+1/100*tol["Temp"])];
                            tol         tol
                               R1          Temp
          (%o2) [R_1 = 100 (----- + 1) (------- + 1),
                             100          100
                                                  tol         tol
                                                     R2          Temp
                                       R_2 = 200 (----- + 1) (------- + 1)]
                                                   100          100
          (%i3) float(wc_inputvalueassumptions(%));
          (%o3) [R_2 >= 196.02, R_2 <= 204.02, R_1 >= 98.01, R_1 <= 102.01]
          (%i4) is(R_1>R_2);
          (%o4)                         false
          (%i5) is(R_1>90);
          (%o5)                         true
          (%i6) is(R_1>200);
          (%o6)                         false
          (%i7) is(R_1<200);
          (%o7)                         true
          (%i8) is(R_1>100);
          (%o8)                        unknown

 -- Function: wc_tolassumptions (<expr>)

     Adds the range of the <tol[n]> contained in <expr> to the assume
     database.

     See also ‘wc_inputvalueassumptions’, ‘wc_inputvalueranges’ and
     *note assume::.

     Example:
          (%i1) load("wrstcse");
          (%o1) /home/gunter/src/maxima-code/share/contrib/wrstcse.mac
          (%i2) vals:[
              R_1=100*(1+1/100*tol["R1"])*(1+1/100*tol["Temp"]),
              R_2=200*(1+1/100*tol["R2"])*(1+1/100*tol["Temp"])];
                            tol         tol
                               R1          Temp
          (%o2) [R_1 = 100 (----- + 1) (------- + 1),
                             100          100
                                                  tol         tol
                                                     R2          Temp
                                       R_2 = 200 (----- + 1) (------- + 1)]
                                                   100          100
          (%i3) float(wc_tolassumptions(%));
          (%o3) [tol   >= - 1.0, tol   <= 1.0, tol     >= - 1.0,
                    R1              R1            Temp
                              tol     <= 1.0, tol   >= - 1.0, tol   <= 1.0]
                                 Temp            R2              R2
          (%i4) is(tol[R_1]>tol[R_2]);
          (%o4)                        unknown
          (%i5) is(tol[R_1]>1);
          (%o5)                        unknown
          (%i6) is(tol[R_1]<-1);
          (%o6)                        unknown
          (%i7) is(tol[R_1]<0);
          (%o7)                        unknown
          (%i8) is(tol[R_2]>2);
          (%o8)                        unknown

 -- Function: wc_min (<expr>, [<num>])

     Outputs only the minimum value of <expr>).  If <num> is present it
     tells maxima how many samples to try out of the range of each
     tolerance.

     See also ‘wc_max’, ‘wc_typicalvalues’ and *note wc_mintypmax::.

     Example:
          (%i1) load("wrstcse");
          (%o1) /home/gunter/src/maxima-code/share/contrib/wrstcse.mac
          (%i2) vals:[
              R_1=100*(1+1/100*tol["R1"])*(1+1/100*tol["Temp"]),
              R_2=200*(1+1/100*tol["R2"])*(1+1/100*tol["Temp"])];
                            tol         tol
                               R1          Temp
          (%o2) [R_1 = 100 (----- + 1) (------- + 1),
                             100          100
                                                  tol         tol
                                                     R2          Temp
                                       R_2 = 200 (----- + 1) (------- + 1)]
                                                   100          100
          (%i3) rtotal:R_Total=R_1+R_2;
          (%o3)                  R_Total = R_2 + R_1
          (%i4) wc_mintypmax(subst(vals,rhs(rtotal)));
                               29403                   30603
          (%o4)         [min = -----, typ = 300, max = -----]
                                100                     100
          (%i5) wc_min(subst(vals,rhs(rtotal)));
                                        29403
          (%o5)                         -----
                                         100

 -- Function: wc_max (<expr>, [<num>])

     Outputs only the maximum value of <expr>).  If <num> is present it
     tells maxima how many samples to try out of the range of each
     tolerance.

     See also ‘wc_max’, ‘wc_typicalvalues’ and *note wc_mintypmax::.

     Example:
          (%i1) load("wrstcse");
          (%o1) /home/gunter/src/maxima-code/share/contrib/wrstcse.mac
          (%i2) vals:[
              R_1=100*(1+1/100*tol["R1"])*(1+1/100*tol["Temp"]),
              R_2=200*(1+1/100*tol["R2"])*(1+1/100*tol["Temp"])];
                            tol         tol
                               R1          Temp
          (%o2) [R_1 = 100 (----- + 1) (------- + 1),
                             100          100
                                                  tol         tol
                                                     R2          Temp
                                       R_2 = 200 (----- + 1) (------- + 1)]
                                                   100          100
          (%i3) rtotal:R_Total=R_1+R_2;
          (%o3)                  R_Total = R_2 + R_1
          (%i4) wc_mintypmax(subst(vals,rhs(rtotal)));
                               29403                   30603
          (%o4)         [min = -----, typ = 300, max = -----]
                                100                     100
          (%i5) wc_max(subst(vals,rhs(rtotal)));
                                        30603
          (%o5)                         -----
                                         100

