This is octave.info, produced by makeinfo version 6.5 from octave.texi.

INFO-DIR-SECTION Math
START-INFO-DIR-ENTRY
* Octave: (octave).             Interactive language for numerical computations.
END-INFO-DIR-ENTRY

Copyright © 1996-2018 John W. Eaton.

   Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

   Permission is granted to copy and distribute modified versions of
this manual under the conditions for verbatim copying, provided that the
entire resulting derived work is distributed under the terms of a
permission notice identical to this one.

   Permission is granted to copy and distribute translations of this
manual into another language, under the above conditions for modified
versions.


File: octave.info,  Node: Arithmetic,  Next: Linear Algebra,  Prev: Matrix Manipulation,  Up: Top

17 Arithmetic
*************

Unless otherwise noted, all of the functions described in this chapter
will work for real and complex scalar, vector, or matrix arguments.
Functions described as “mapping functions” apply the given operation
individually to each element when given a matrix argument.  For example:

     sin ([1, 2; 3, 4])
          ⇒  0.84147   0.90930
              0.14112  -0.75680

* Menu:

* Exponents and Logarithms::
* Complex Arithmetic::
* Trigonometry::
* Sums and Products::
* Utility Functions::
* Special Functions::
* Rational Approximations::
* Coordinate Transformations::
* Mathematical Constants::


File: octave.info,  Node: Exponents and Logarithms,  Next: Complex Arithmetic,  Up: Arithmetic

17.1 Exponents and Logarithms
=============================

 -- : exp (X)
     Compute ‘e^x’ for each element of X.

     To compute the matrix exponential, see *note Linear Algebra::.

     See also: *note log: XREFlog.

 -- : expm1 (X)
     Compute ‘exp (X) - 1’ accurately in the neighborhood of zero.

     See also: *note exp: XREFexp.

 -- : log (X)
     Compute the natural logarithm, ‘ln (X)’, for each element of X.

     To compute the matrix logarithm, see *note Linear Algebra::.

     See also: *note exp: XREFexp, *note log1p: XREFlog1p, *note log2:
     XREFlog2, *note log10: XREFlog10, *note logspace: XREFlogspace.

 -- : reallog (X)
     Return the real-valued natural logarithm of each element of X.

     If any element results in a complex return value ‘reallog’ aborts
     and issues an error.

     See also: *note log: XREFlog, *note realpow: XREFrealpow, *note
     realsqrt: XREFrealsqrt.

 -- : log1p (X)
     Compute ‘log (1 + X)’ accurately in the neighborhood of zero.

     See also: *note log: XREFlog, *note exp: XREFexp, *note expm1:
     XREFexpm1.

 -- : log10 (X)
     Compute the base-10 logarithm of each element of X.

     See also: *note log: XREFlog, *note log2: XREFlog2, *note logspace:
     XREFlogspace, *note exp: XREFexp.

 -- : log2 (X)
 -- : [F, E] = log2 (X)
     Compute the base-2 logarithm of each element of X.

     If called with two output arguments, split X into binary mantissa
     and exponent so that ‘1/2 <= abs(f) < 1’ and E is an integer.  If
     ‘x = 0’, ‘f = e = 0’.

     See also: *note pow2: XREFpow2, *note log: XREFlog, *note log10:
     XREFlog10, *note exp: XREFexp.

 -- : pow2 (X)
 -- : pow2 (F, E)
     With one input argument, compute 2 .^ x for each element of X.

     With two input arguments, return f .* (2 .^ e).

     See also: *note log2: XREFlog2, *note nextpow2: XREFnextpow2, *note
     power: XREFpower.

 -- : N = nextpow2 (X)
     Compute the exponent for the smallest power of two larger than the
     input.

     For each element in the input array X, return the first integer N
     such that 2^n ≥ abs (x).

     See also: *note pow2: XREFpow2, *note log2: XREFlog2.

 -- : realpow (X, Y)
     Compute the real-valued, element-by-element power operator.

     This is equivalent to ‘X .^ Y’, except that ‘realpow’ reports an
     error if any return value is complex.

     See also: *note power: XREFpower, *note reallog: XREFreallog, *note
     realsqrt: XREFrealsqrt.

 -- : sqrt (X)
     Compute the square root of each element of X.

     If X is negative, a complex result is returned.

     To compute the matrix square root, see *note Linear Algebra::.

     See also: *note realsqrt: XREFrealsqrt, *note nthroot: XREFnthroot.

 -- : realsqrt (X)
     Return the real-valued square root of each element of X.

     If any element results in a complex return value ‘realsqrt’ aborts
     and issues an error.

     See also: *note sqrt: XREFsqrt, *note realpow: XREFrealpow, *note
     reallog: XREFreallog.

 -- : cbrt (X)
     Compute the real cube root of each element of X.

     Unlike ‘X^(1/3)’, the result will be negative if X is negative.

     See also: *note nthroot: XREFnthroot.

 -- : nthroot (X, N)

     Compute the real (non-complex) N-th root of X.

     X must have all real entries and N must be a scalar.  If N is an
     even integer and X has negative entries then ‘nthroot’ aborts and
     issues an error.

     Example:

          nthroot (-1, 3)
          ⇒ -1
          (-1) ^ (1 / 3)
          ⇒ 0.50000 - 0.86603i

     See also: *note realsqrt: XREFrealsqrt, *note sqrt: XREFsqrt, *note
     cbrt: XREFcbrt.


File: octave.info,  Node: Complex Arithmetic,  Next: Trigonometry,  Prev: Exponents and Logarithms,  Up: Arithmetic

17.2 Complex Arithmetic
=======================

In the descriptions of the following functions, Z is the complex number
X + IY, where I is defined as ‘sqrt (-1)’.

 -- : abs (Z)
     Compute the magnitude of Z.

     The magnitude is defined as |Z| = ‘sqrt (x^2 + y^2)’.

     For example:

          abs (3 + 4i)
               ⇒ 5

     See also: *note arg: XREFarg.

 -- : arg (Z)
 -- : angle (Z)
     Compute the argument, i.e., angle of Z.

     This is defined as, THETA = ‘atan2 (Y, X)’, in radians.

     For example:

          arg (3 + 4i)
               ⇒ 0.92730

     See also: *note abs: XREFabs.

 -- : conj (Z)
     Return the complex conjugate of Z.

     The complex conjugate is defined as ‘conj (Z)’ = X - IY.

     See also: *note real: XREFreal, *note imag: XREFimag.

 -- : cplxpair (Z)
 -- : cplxpair (Z, TOL)
 -- : cplxpair (Z, TOL, DIM)
     Sort the numbers Z into complex conjugate pairs ordered by
     increasing real part.

     The negative imaginary complex numbers are placed first within each
     pair.  All real numbers (those with ‘abs (imag (Z)) / abs (Z) <
     TOL’) are placed after the complex pairs.

     TOL is a weighting factor in the range [0, 1) which determines the
     tolerance of the matching.  The default value is ‘100 * eps’ and
     the resulting tolerance for a given complex pair is ‘TOL * abs
     (Z(i)))’.

     By default the complex pairs are sorted along the first
     non-singleton dimension of Z.  If DIM is specified, then the
     complex pairs are sorted along this dimension.

     Signal an error if some complex numbers could not be paired.
     Signal an error if all complex numbers are not exact conjugates (to
     within TOL).  Note that there is no defined order for pairs with
     identical real parts but differing imaginary parts.

          cplxpair (exp (2i*pi*[0:4]'/5)) == exp (2i*pi*[3; 2; 4; 1; 0]/5)

 -- : imag (Z)
     Return the imaginary part of Z as a real number.

     See also: *note real: XREFreal, *note conj: XREFconj.

 -- : real (Z)
     Return the real part of Z.

     See also: *note imag: XREFimag, *note conj: XREFconj.


File: octave.info,  Node: Trigonometry,  Next: Sums and Products,  Prev: Complex Arithmetic,  Up: Arithmetic

17.3 Trigonometry
=================

Octave provides the following trigonometric functions where angles are
specified in radians.  To convert from degrees to radians multiply by
‘pi/180’ or use the ‘deg2rad’ function.  For example, ‘sin (30 *
pi/180)’ returns the sine of 30 degrees.  As an alternative, Octave
provides a number of trigonometric functions which work directly on an
argument specified in degrees.  These functions are named after the base
trigonometric function with a ‘d’ suffix.  As an example, ‘sin’ expects
an angle in radians while ‘sind’ expects an angle in degrees.

   Octave uses the C library trigonometric functions.  It is expected
that these functions are defined by the ISO/IEC 9899 Standard.  This
Standard is available at:
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf>.  Section
F.9.1 deals with the trigonometric functions.  The behavior of most of
the functions is relatively straightforward.  However, there are some
exceptions to the standard behavior.  Many of the exceptions involve the
behavior for -0.  The most complex case is atan2.  Octave exactly
implements the behavior given in the Standard.  Including ‘atan2(+- 0,
0)’ returns ‘+- pi’.

   It should be noted that MATLAB uses different definitions which
apparently do not distinguish -0.

 -- : RAD = deg2rad (DEG)

     Convert degrees to radians.

     The input DEG must be a scalar, vector, or N-dimensional array of
     double or single floating point values.  DEG may be complex in
     which case the real and imaginary components are converted
     separately.

     The output RAD is the same size and shape as DEG with degrees
     converted to radians using the conversion constant ‘pi/180’.

     Example:

          deg2rad ([0, 90, 180, 270, 360])
            ⇒  0.00000   1.57080   3.14159   4.71239   6.28319

     See also: *note rad2deg: XREFrad2deg.

 -- : DEG = rad2deg (RAD)

     Convert radians to degrees.

     The input RAD must be a scalar, vector, or N-dimensional array of
     double or single floating point values.  RAD may be complex in
     which case the real and imaginary components are converted
     separately.

     The output DEG is the same size and shape as RAD with radians
     converted to degrees using the conversion constant ‘180/pi’.

     Example:

          rad2deg ([0, pi/2, pi, 3/2*pi, 2*pi])
            ⇒  0    90   180   270   360

     See also: *note deg2rad: XREFdeg2rad.

 -- : sin (X)
     Compute the sine for each element of X in radians.

     See also: *note asin: XREFasin, *note sind: XREFsind, *note sinh:
     XREFsinh.

 -- : cos (X)
     Compute the cosine for each element of X in radians.

     See also: *note acos: XREFacos, *note cosd: XREFcosd, *note cosh:
     XREFcosh.

 -- : tan (Z)
     Compute the tangent for each element of X in radians.

     See also: *note atan: XREFatan, *note tand: XREFtand, *note tanh:
     XREFtanh.

 -- : sec (X)
     Compute the secant for each element of X in radians.

     See also: *note asec: XREFasec, *note secd: XREFsecd, *note sech:
     XREFsech.

 -- : csc (X)
     Compute the cosecant for each element of X in radians.

     See also: *note acsc: XREFacsc, *note cscd: XREFcscd, *note csch:
     XREFcsch.

 -- : cot (X)
     Compute the cotangent for each element of X in radians.

     See also: *note acot: XREFacot, *note cotd: XREFcotd, *note coth:
     XREFcoth.

 -- : asin (X)
     Compute the inverse sine in radians for each element of X.

     See also: *note sin: XREFsin, *note asind: XREFasind.

 -- : acos (X)
     Compute the inverse cosine in radians for each element of X.

     See also: *note cos: XREFcos, *note acosd: XREFacosd.

 -- : atan (X)
     Compute the inverse tangent in radians for each element of X.

     See also: *note tan: XREFtan, *note atand: XREFatand.

 -- : asec (X)
     Compute the inverse secant in radians for each element of X.

     See also: *note sec: XREFsec, *note asecd: XREFasecd.

 -- : acsc (X)
     Compute the inverse cosecant in radians for each element of X.

     See also: *note csc: XREFcsc, *note acscd: XREFacscd.

 -- : acot (X)
     Compute the inverse cotangent in radians for each element of X.

     See also: *note cot: XREFcot, *note acotd: XREFacotd.

 -- : sinh (X)
     Compute the hyperbolic sine for each element of X.

     See also: *note asinh: XREFasinh, *note cosh: XREFcosh, *note tanh:
     XREFtanh.

 -- : cosh (X)
     Compute the hyperbolic cosine for each element of X.

     See also: *note acosh: XREFacosh, *note sinh: XREFsinh, *note tanh:
     XREFtanh.

 -- : tanh (X)
     Compute hyperbolic tangent for each element of X.

     See also: *note atanh: XREFatanh, *note sinh: XREFsinh, *note cosh:
     XREFcosh.

 -- : sech (X)
     Compute the hyperbolic secant of each element of X.

     See also: *note asech: XREFasech.

 -- : csch (X)
     Compute the hyperbolic cosecant of each element of X.

     See also: *note acsch: XREFacsch.

 -- : coth (X)
     Compute the hyperbolic cotangent of each element of X.

     See also: *note acoth: XREFacoth.

 -- : asinh (X)
     Compute the inverse hyperbolic sine for each element of X.

     See also: *note sinh: XREFsinh.

 -- : acosh (X)
     Compute the inverse hyperbolic cosine for each element of X.

     See also: *note cosh: XREFcosh.

 -- : atanh (X)
     Compute the inverse hyperbolic tangent for each element of X.

     See also: *note tanh: XREFtanh.

 -- : asech (X)
     Compute the inverse hyperbolic secant of each element of X.

     See also: *note sech: XREFsech.

 -- : acsch (X)
     Compute the inverse hyperbolic cosecant of each element of X.

     See also: *note csch: XREFcsch.

 -- : acoth (X)
     Compute the inverse hyperbolic cotangent of each element of X.

     See also: *note coth: XREFcoth.

 -- : atan2 (Y, X)
     Compute atan (Y / X) for corresponding elements of Y and X.

     Y and X must match in size and orientation.  The signs of elements
     of Y and X are used to determine the quadrants of each resulting
     value.

     This function is equivalent to ‘arg (complex (X, Y))’.

     See also: *note tan: XREFtan, *note tand: XREFtand, *note tanh:
     XREFtanh, *note atanh: XREFatanh.

   Octave provides the following trigonometric functions where angles
are specified in degrees.  These functions produce true zeros at the
appropriate intervals rather than the small round-off error that occurs
when using radians.  For example:

     cosd (90)
          ⇒ 0
     cos (pi/2)
          ⇒ 6.1230e-17

 -- : sind (X)
     Compute the sine for each element of X in degrees.

     Returns zero for elements where ‘X/180’ is an integer.

     See also: *note asind: XREFasind, *note sin: XREFsin.

 -- : cosd (X)
     Compute the cosine for each element of X in degrees.

     Returns zero for elements where ‘(X-90)/180’ is an integer.

     See also: *note acosd: XREFacosd, *note cos: XREFcos.

 -- : tand (X)
     Compute the tangent for each element of X in degrees.

     Returns zero for elements where ‘X/180’ is an integer and ‘Inf’ for
     elements where ‘(X-90)/180’ is an integer.

     See also: *note atand: XREFatand, *note tan: XREFtan.

 -- : secd (X)
     Compute the secant for each element of X in degrees.

     See also: *note asecd: XREFasecd, *note sec: XREFsec.

 -- : cscd (X)
     Compute the cosecant for each element of X in degrees.

     See also: *note acscd: XREFacscd, *note csc: XREFcsc.

 -- : cotd (X)
     Compute the cotangent for each element of X in degrees.

     See also: *note acotd: XREFacotd, *note cot: XREFcot.

 -- : asind (X)
     Compute the inverse sine in degrees for each element of X.

     See also: *note sind: XREFsind, *note asin: XREFasin.

 -- : acosd (X)
     Compute the inverse cosine in degrees for each element of X.

     See also: *note cosd: XREFcosd, *note acos: XREFacos.

 -- : atand (X)
     Compute the inverse tangent in degrees for each element of X.

     See also: *note tand: XREFtand, *note atan: XREFatan.

 -- : atan2d (Y, X)
     Compute atan (Y / X) in degrees for corresponding elements from Y
     and X.

     See also: *note tand: XREFtand, *note atan2: XREFatan2.

 -- : asecd (X)
     Compute the inverse secant in degrees for each element of X.

     See also: *note secd: XREFsecd, *note asec: XREFasec.

 -- : acscd (X)
     Compute the inverse cosecant in degrees for each element of X.

     See also: *note cscd: XREFcscd, *note acsc: XREFacsc.

 -- : acotd (X)
     Compute the inverse cotangent in degrees for each element of X.

     See also: *note cotd: XREFcotd, *note acot: XREFacot.


File: octave.info,  Node: Sums and Products,  Next: Utility Functions,  Prev: Trigonometry,  Up: Arithmetic

17.4 Sums and Products
======================

 -- : sum (X)
 -- : sum (X, DIM)
 -- : sum (..., "native")
 -- : sum (..., "double")
 -- : sum (..., "extra")
     Sum of elements along dimension DIM.

     If DIM is omitted, it defaults to the first non-singleton
     dimension.

     The optional "type" input determines the class of the variable used
     for calculations.  By default, operations on floating point inputs
     (double or single) are performed in their native data type, while
     operations on integer, logical, and character data types are
     performed using doubles.  If the argument "native" is given, then
     the operation is performed in the same type as the original
     argument.

     For example:

          sum ([true, true])
             ⇒ 2
          sum ([true, true], "native")
             ⇒ true

     If "double" is given the sum is performed in double precision even
     for single precision inputs.

     For double precision inputs, the "extra" option will use a more
     accurate algorithm than straightforward summation.  For single
     precision inputs, "extra" is the same as "double".  For all other
     data type "extra" has no effect.

     See also: *note cumsum: XREFcumsum, *note sumsq: XREFsumsq, *note
     prod: XREFprod.

 -- : prod (X)
 -- : prod (X, DIM)
 -- : prod (..., "native")
 -- : prod (..., "double")
     Product of elements along dimension DIM.

     If DIM is omitted, it defaults to the first non-singleton
     dimension.

     The optional "type" input determines the class of the variable used
     for calculations.  If the argument "native" is given, then the
     operation is performed in the same type as the original argument,
     rather than the default double type.

     For example:

          prod ([true, true])
             ⇒ 1
          prod ([true, true], "native")
             ⇒ true

     On the contrary, if "double" is given, the operation is performed
     in double precision even for single precision inputs.

     See also: *note cumprod: XREFcumprod, *note sum: XREFsum.

 -- : cumsum (X)
 -- : cumsum (X, DIM)
 -- : cumsum (..., "native")
 -- : cumsum (..., "double")
     Cumulative sum of elements along dimension DIM.

     If DIM is omitted, it defaults to the first non-singleton
     dimension.  For example:

          cumsum ([1, 2; 3, 4; 5, 6])
             ⇒  1   2
                 4   6
                 9  12

     See ‘sum’ for an explanation of the optional parameters "native"
     and "double".

     See also: *note sum: XREFsum, *note cumprod: XREFcumprod.

 -- : cumprod (X)
 -- : cumprod (X, DIM)
     Cumulative product of elements along dimension DIM.

     If DIM is omitted, it defaults to the first non-singleton
     dimension.  For example:

          cumprod ([1, 2; 3, 4; 5, 6])
             ⇒  1   2
                 3   8
                15  48

     See also: *note prod: XREFprod, *note cumsum: XREFcumsum.

 -- : sumsq (X)
 -- : sumsq (X, DIM)
     Sum of squares of elements along dimension DIM.

     If DIM is omitted, it defaults to the first non-singleton
     dimension.

     This function is conceptually equivalent to computing

          sum (x .* conj (x), dim)

     but it uses less memory and avoids calling ‘conj’ if X is real.

     See also: *note sum: XREFsum, *note prod: XREFprod.


File: octave.info,  Node: Utility Functions,  Next: Special Functions,  Prev: Sums and Products,  Up: Arithmetic

17.5 Utility Functions
======================

 -- : ceil (X)
     Return the smallest integer not less than X.

     This is equivalent to rounding towards positive infinity.

     If X is complex, return ‘ceil (real (X)) + ceil (imag (X)) * I’.

          ceil ([-2.7, 2.7])
              ⇒ -2    3

     See also: *note floor: XREFfloor, *note round: XREFround, *note
     fix: XREFfix.

 -- : fix (X)
     Truncate fractional portion of X and return the integer portion.

     This is equivalent to rounding towards zero.  If X is complex,
     return ‘fix (real (X)) + fix (imag (X)) * I’.

          fix ([-2.7, 2.7])
             ⇒ -2    2

     See also: *note ceil: XREFceil, *note floor: XREFfloor, *note
     round: XREFround.

 -- : floor (X)
     Return the largest integer not greater than X.

     This is equivalent to rounding towards negative infinity.  If X is
     complex, return ‘floor (real (X)) + floor (imag (X)) * I’.

          floor ([-2.7, 2.7])
               ⇒ -3    2

     See also: *note ceil: XREFceil, *note round: XREFround, *note fix:
     XREFfix.

 -- : round (X)
     Return the integer nearest to X.

     If X is complex, return ‘round (real (X)) + round (imag (X)) * I’.
     If there are two nearest integers, return the one further away from
     zero.

          round ([-2.7, 2.7])
               ⇒ -3    3

     See also: *note ceil: XREFceil, *note floor: XREFfloor, *note fix:
     XREFfix, *note roundb: XREFroundb.

 -- : roundb (X)
     Return the integer nearest to X.  If there are two nearest
     integers, return the even one (banker’s rounding).

     If X is complex, return ‘roundb (real (X)) + roundb (imag (X)) *
     I’.

     See also: *note round: XREFround.

 -- : max (X)
 -- : max (X, [], DIM)
 -- : [W, IW] = max (X)
 -- : max (X, Y)
     Find maximum values in the array X.

     For a vector argument, return the maximum value.  For a matrix
     argument, return a row vector with the maximum value of each
     column.  For a multi-dimensional array, ‘max’ operates along the
     first non-singleton dimension.

     If the optional third argument DIM is present then operate along
     this dimension.  In this case the second argument is ignored and
     should be set to the empty matrix.

     For two matrices (or a matrix and a scalar), return the pairwise
     maximum.

     Thus,

          max (max (X))

     returns the largest element of the 2-D matrix X, and

          max (2:5, pi)
              ⇒  3.1416  3.1416  4.0000  5.0000

     compares each element of the range ‘2:5’ with ‘pi’, and returns a
     row vector of the maximum values.

     For complex arguments, the magnitude of the elements are used for
     comparison.  If the magnitudes are identical, then the results are
     ordered by phase angle in the range (-pi, pi].  Hence,

          max ([-1 i 1 -i])
              ⇒ -1

     because all entries have magnitude 1, but -1 has the largest phase
     angle with value pi.

     If called with one input and two output arguments, ‘max’ also
     returns the first index of the maximum value(s).  Thus,

          [x, ix] = max ([1, 3, 5, 2, 5])
              ⇒  x = 5
                  ix = 3

     See also: *note min: XREFmin, *note cummax: XREFcummax, *note
     cummin: XREFcummin.

 -- : min (X)
 -- : min (X, [], DIM)
 -- : [W, IW] = min (X)
 -- : min (X, Y)
     Find minimum values in the array X.

     For a vector argument, return the minimum value.  For a matrix
     argument, return a row vector with the minimum value of each
     column.  For a multi-dimensional array, ‘min’ operates along the
     first non-singleton dimension.

     If the optional third argument DIM is present then operate along
     this dimension.  In this case the second argument is ignored and
     should be set to the empty matrix.

     For two matrices (or a matrix and a scalar), return the pairwise
     minimum.

     Thus,

          min (min (X))

     returns the smallest element of the 2-D matrix X, and

          min (2:5, pi)
              ⇒  2.0000  3.0000  3.1416  3.1416

     compares each element of the range ‘2:5’ with ‘pi’, and returns a
     row vector of the minimum values.

     For complex arguments, the magnitude of the elements are used for
     comparison.  If the magnitudes are identical, then the results are
     ordered by phase angle in the range (-pi, pi].  Hence,

          min ([-1 i 1 -i])
              ⇒ -i

     because all entries have magnitude 1, but -i has the smallest phase
     angle with value -pi/2.

     If called with one input and two output arguments, ‘min’ also
     returns the first index of the minimum value(s).  Thus,

          [x, ix] = min ([1, 3, 0, 2, 0])
              ⇒  x = 0
                  ix = 3

     See also: *note max: XREFmax, *note cummin: XREFcummin, *note
     cummax: XREFcummax.

 -- : cummax (X)
 -- : cummax (X, DIM)
 -- : [W, IW] = cummax (...)
     Return the cumulative maximum values along dimension DIM.

     If DIM is unspecified it defaults to column-wise operation.  For
     example:

          cummax ([1 3 2 6 4 5])
             ⇒  1  3  3  6  6  6

     If called with two output arguments the index of the maximum value
     is also returned.

          [w, iw] = cummax ([1 3 2 6 4 5])
          ⇒
          w =  1  3  3  6  6  6
          iw = 1  2  2  4  4  4

     See also: *note cummin: XREFcummin, *note max: XREFmax, *note min:
     XREFmin.

 -- : cummin (X)
 -- : cummin (X, DIM)
 -- : [W, IW] = cummin (X)
     Return the cumulative minimum values along dimension DIM.

     If DIM is unspecified it defaults to column-wise operation.  For
     example:

          cummin ([5 4 6 2 3 1])
             ⇒  5  4  4  2  2  1

     If called with two output arguments the index of the minimum value
     is also returned.

          [w, iw] = cummin ([5 4 6 2 3 1])
          ⇒
          w =  5  4  4  2  2  1
          iw = 1  2  2  4  4  6

     See also: *note cummax: XREFcummax, *note min: XREFmin, *note max:
     XREFmax.

 -- : hypot (X, Y)
 -- : hypot (X, Y, Z, ...)
     Compute the element-by-element square root of the sum of the
     squares of X and Y.

     This is equivalent to ‘sqrt (X.^2 + Y.^2)’, but is calculated in a
     manner that avoids overflows for large values of X or Y.

     ‘hypot’ can also be called with more than 2 arguments; in this
     case, the arguments are accumulated from left to right:

          hypot (hypot (X, Y), Z)
          hypot (hypot (hypot (X, Y), Z), W), etc.

 -- : DX = gradient (M)
 -- : [DX, DY, DZ, ...] = gradient (M)
 -- : [...] = gradient (M, S)
 -- : [...] = gradient (M, X, Y, Z, ...)
 -- : [...] = gradient (F, X0)
 -- : [...] = gradient (F, X0, S)
 -- : [...] = gradient (F, X0, X, Y, ...)

     Calculate the gradient of sampled data or a function.

     If M is a vector, calculate the one-dimensional gradient of M.  If
     M is a matrix the gradient is calculated for each dimension.

     ‘[DX, DY] = gradient (M)’ calculates the one-dimensional gradient
     for X and Y direction if M is a matrix.  Additional return
     arguments can be use for multi-dimensional matrices.

     A constant spacing between two points can be provided by the S
     parameter.  If S is a scalar, it is assumed to be the spacing for
     all dimensions.  Otherwise, separate values of the spacing can be
     supplied by the X, ... arguments.  Scalar values specify an
     equidistant spacing.  Vector values for the X, ... arguments
     specify the coordinate for that dimension.  The length must match
     their respective dimension of M.

     At boundary points a linear extrapolation is applied.  Interior
     points are calculated with the first approximation of the numerical
     gradient

          y'(i) = 1/(x(i+1)-x(i-1)) * (y(i-1)-y(i+1)).

     If the first argument F is a function handle, the gradient of the
     function at the points in X0 is approximated using central
     difference.  For example, ‘gradient (@cos, 0)’ approximates the
     gradient of the cosine function in the point x0 = 0.  As with
     sampled data, the spacing values between the points from which the
     gradient is estimated can be set via the S or DX, DY, ...
     arguments.  By default a spacing of 1 is used.

     See also: *note diff: XREFdiff, *note del2: XREFdel2.

 -- : dot (X, Y, DIM)
     Compute the dot product of two vectors.

     If X and Y are matrices, calculate the dot products along the first
     non-singleton dimension.

     If the optional argument DIM is given, calculate the dot products
     along this dimension.

     This is equivalent to ‘sum (conj (X) .* Y, DIM)’, but avoids
     forming a temporary array and is faster.  When X and Y are column
     vectors, the result is equivalent to ‘X' * Y’.

     See also: *note cross: XREFcross, *note divergence: XREFdivergence.

 -- : cross (X, Y)
 -- : cross (X, Y, DIM)
     Compute the vector cross product of two 3-dimensional vectors X and
     Y.

     If X and Y are matrices, the cross product is applied along the
     first dimension with three elements.

     The optional argument DIM forces the cross product to be calculated
     along the specified dimension.

     Example Code:

          cross ([1, 1, 0], [0, 1, 1])
            ⇒
                 1   -1   1

     See also: *note dot: XREFdot, *note curl: XREFcurl, *note
     divergence: XREFdivergence.

 -- : DIV = divergence (X, Y, Z, FX, FY, FZ)
 -- : DIV = divergence (FX, FY, FZ)
 -- : DIV = divergence (X, Y, FX, FY)
 -- : DIV = divergence (FX, FY)
     Calculate divergence of a vector field given by the arrays FX, FY,
     and FZ or FX, FY respectively.

                            d               d               d
          div F(x,y,z)  =   -- F(x,y,z)  +  -- F(x,y,z)  +  -- F(x,y,z)
                            dx              dy              dz

     The coordinates of the vector field can be given by the arguments
     X, Y, Z or X, Y respectively.

     See also: *note curl: XREFcurl, *note gradient: XREFgradient, *note
     del2: XREFdel2, *note dot: XREFdot.

 -- : [CX, CY, CZ, V] = curl (X, Y, Z, FX, FY, FZ)
 -- : [CZ, V] = curl (X, Y, FX, FY)
 -- : [...] = curl (FX, FY, FZ)
 -- : [...] = curl (FX, FY)
 -- : V = curl (...)
     Calculate curl of vector field given by the arrays FX, FY, and FZ
     or FX, FY respectively.

                            / d         d       d         d       d         d     \
          curl F(x,y,z)  =  | -- Fz  -  -- Fy,  -- Fx  -  -- Fz,  -- Fy  -  -- Fx |
                            \ dy        dz      dz        dx      dx        dy    /

     The coordinates of the vector field can be given by the arguments
     X, Y, Z or X, Y respectively.  V calculates the scalar component of
     the angular velocity vector in direction of the z-axis for
     two-dimensional input.  For three-dimensional input the scalar
     rotation is calculated at each grid point in direction of the
     vector field at that point.

     See also: *note divergence: XREFdivergence, *note gradient:
     XREFgradient, *note del2: XREFdel2, *note cross: XREFcross.

 -- : L = del2 (M)
 -- : L = del2 (M, H)
 -- : L = del2 (M, DX, DY, ...)

     Calculate the discrete Laplace operator.

     For a 2-dimensional matrix M this is defined as

                1    / d^2            d^2         \
          L  = --- * | ---  M(x,y) +  ---  M(x,y) |
                4    \ dx^2           dy^2        /

     For N-dimensional arrays the sum in parentheses is expanded to
     include second derivatives over the additional higher dimensions.

     The spacing between evaluation points may be defined by H, which is
     a scalar defining the equidistant spacing in all dimensions.
     Alternatively, the spacing in each dimension may be defined
     separately by DX, DY, etc.  A scalar spacing argument defines
     equidistant spacing, whereas a vector argument can be used to
     specify variable spacing.  The length of the spacing vectors must
     match the respective dimension of M.  The default spacing value is
     1.

     Dimensions with fewer than 3 data points are skipped.  Boundary
     points are calculated from the linear extrapolation of interior
     points.

     Example: Second derivative of 2*x^3

          f = @(x) 2*x.^3;
          dd = @(x) 12*x;
          x = 1:6;
          L = 4*del2 (f(x));
          assert (L, dd (x));

     See also: *note gradient: XREFgradient, *note diff: XREFdiff.

 -- : factorial (N)
     Return the factorial of N where N is a real non-negative integer.

     If N is a scalar, this is equivalent to ‘prod (1:N)’.  For vector
     or matrix arguments, return the factorial of each element in the
     array.

     For non-integers see the generalized factorial function ‘gamma’.
     Note that the factorial function grows large quite quickly, and
     even with double precision values overflow will occur if N > 171.
     For such cases consider ‘gammaln’.

     See also: *note prod: XREFprod, *note gamma: XREFgamma, *note
     gammaln: XREFgammaln.

 -- : PF = factor (Q)
 -- : [PF, N] = factor (Q)
     Return the prime factorization of Q.

     The prime factorization is defined as ‘prod (PF) == Q’ where every
     element of PF is a prime number.  If ‘Q == 1’, return 1.  The
     output PF is of the same numeric class as the input.

     With two output arguments, return the unique prime factors PF and
     their multiplicities.  That is, ‘prod (PF .^ N) == Q’.

     Implementation Note: The input Q must be less than ‘flintmax’
     (9.0072e+15) in order to factor correctly.

     See also: *note gcd: XREFgcd, *note lcm: XREFlcm, *note isprime:
     XREFisprime, *note primes: XREFprimes.

 -- : G = gcd (A1, A2, ...)
 -- : [G, V1, ...] = gcd (A1, A2, ...)
     Compute the greatest common divisor of A1, A2, ....

     If more than one argument is given then all arguments must be the
     same size or scalar.  In this case the greatest common divisor is
     calculated for each element individually.  All elements must be
     ordinary or Gaussian (complex) integers.  Note that for Gaussian
     integers, the gcd is only unique up to a phase factor
     (multiplication by 1, -1, i, or -i), so an arbitrary greatest
     common divisor among the four possible is returned.

     Optional return arguments V1, ..., contain integer vectors such
     that,

          G = V1 .* A1 + V2 .* A2 + ...

     Example code:

          gcd ([15, 9], [20, 18])
             ⇒  5  9

     See also: *note lcm: XREFlcm, *note factor: XREFfactor, *note
     isprime: XREFisprime.

 -- : lcm (X, Y)
 -- : lcm (X, Y, ...)
     Compute the least common multiple of X and Y, or of the list of all
     arguments.

     All elements must be numeric and of the same size or scalar.

     See also: *note factor: XREFfactor, *note gcd: XREFgcd, *note
     isprime: XREFisprime.

 -- : rem (X, Y)
     Return the remainder of the division ‘X / Y’.

     The remainder is computed using the expression

          x - y .* fix (x ./ y)

     An error message is printed if the dimensions of the arguments do
     not agree, or if either argument is complex.

     Programming Notes: When calculating with floating point numbers
     (double, single), values within a few eps of an integer will be
     rounded to that integer before computation for compatibility with
     MATLAB.  Any floating point integers greater than ‘flintmax’ (2^53
     for double) will not compute correctly.  For larger integer values
     convert the input to ‘uint64’ before calling this function.

     By convention,

          rem (X, 0) = NaN  if X is a floating point variable
          rem (X, 0) = 0    if X is an integer variable
          rem (X, Y)  returns a value with the signbit from X

     For the opposite conventions see the ‘mod’ function.  In general,
     ‘rem’ is best when computing the remainder after division of two
     _positive_ numbers.  For negative numbers, or when the values are
     periodic, ‘mod’ is a better choice.

     See also: *note mod: XREFmod.

 -- : mod (X, Y)
     Compute the modulo of X and Y.

     Conceptually this is given by

          x - y .* floor (x ./ y)

     and is written such that the correct modulus is returned for
     integer types.  This function handles negative values correctly.
     That is, ‘mod (-1, 3)’ is 2, not -1, as ‘rem (-1, 3)’ returns.

     An error results if the dimensions of the arguments do not agree,
     or if either of the arguments is complex.

     Programming Notes: When calculating with floating point numbers
     (double, single), values within a few eps of an integer will be
     rounded to that integer before computation for compatibility with
     MATLAB.  Any floating point integers greater than ‘flintmax’ (2^53
     for double) will not compute correctly.  For larger integer values
     convert the input to ‘uint64’ before calling this function.

     By convention,

          mod (X, 0) = X
          mod (X, Y)      returns a value with the signbit from Y

     For the opposite conventions see the ‘rem’ function.  In general,
     ‘mod’ is a better choice than ‘rem’ when any of the inputs are
     negative numbers or when the values are periodic.

     See also: *note rem: XREFrem.

 -- : P = primes (N)
     Return all primes up to N.

     The output data class (double, single, uint32, etc.) is the same as
     the input class of N.  The algorithm used is the Sieve of
     Eratosthenes.

     Note: If you need a specific number of primes you can use the fact
     that the distance from one prime to the next is, on average,
     proportional to the logarithm of the prime.  Integrating, one finds
     that there are about k primes less than k*log (5*k).

     See also ‘list_primes’ if you need a specific number N of primes.

     See also: *note list_primes: XREFlist_primes, *note isprime:
     XREFisprime.

 -- : list_primes ()
 -- : list_primes (N)
     List the first N primes.

     If N is unspecified, the first 25 primes are listed.

     See also: *note primes: XREFprimes, *note isprime: XREFisprime.

 -- : sign (X)
     Compute the “signum” function.

     This is defined as

                     -1, x < 0;
          sign (x) =  0, x = 0;
                      1, x > 0.

     For complex arguments, ‘sign’ returns ‘x ./ abs (X)’.

     Note that ‘sign (-0.0)’ is 0.  Although IEEE 754 floating point
     allows zero to be signed, 0.0 and -0.0 compare equal.  If you must
     test whether zero is signed, use the ‘signbit’ function.

     See also: *note signbit: XREFsignbit.

 -- : signbit (X)
     Return logical true if the value of X has its sign bit set and
     false otherwise.

     This behavior is consistent with the other logical functions.  See
     *note Logical Values::.  The behavior differs from the C language
     function which returns nonzero if the sign bit is set.

     This is not the same as ‘x < 0.0’, because IEEE 754 floating point
     allows zero to be signed.  The comparison ‘-0.0 < 0.0’ is false,
     but ‘signbit (-0.0)’ will return a nonzero value.

     See also: *note sign: XREFsign.


File: octave.info,  Node: Special Functions,  Next: Rational Approximations,  Prev: Utility Functions,  Up: Arithmetic

17.6 Special Functions
======================

 -- : [A, IERR] = airy (K, Z, OPT)
     Compute Airy functions of the first and second kind, and their
     derivatives.

           K   Function   Scale factor (if "opt" is supplied)
          ---  --------   ---------------------------------------
           0   Ai (Z)     exp ((2/3) * Z * sqrt (Z))
           1   dAi(Z)/dZ  exp ((2/3) * Z * sqrt (Z))
           2   Bi (Z)     exp (-abs (real ((2/3) * Z * sqrt (Z))))
           3   dBi(Z)/dZ  exp (-abs (real ((2/3) * Z * sqrt (Z))))

     The function call ‘airy (Z)’ is equivalent to ‘airy (0, Z)’.

     The result is the same size as Z.

     If requested, IERR contains the following status information and is
     the same size as the result.

       0. Normal return.

       1. Input error, return ‘NaN’.

       2. Overflow, return ‘Inf’.

       3. Loss of significance by argument reduction results in less
          than half of machine accuracy.

       4. Loss of significance by argument reduction, output may be
          inaccurate.

       5. Error—no computation, algorithm termination condition not met,
          return ‘NaN’.

 -- : J = besselj (ALPHA, X)
 -- : J = besselj (ALPHA, X, OPT)
 -- : [J, IERR] = besselj (...)
     Compute Bessel functions of the first kind.

     The order of the Bessel function ALPHA must be real.  The points
     for evaluation X may be complex.

     If the optional argument OPT is 1 or true, the result J is
     multiplied by ‘exp (-abs (imag (X)))’.

     If ALPHA is a scalar, the result is the same size as X.  If X is a
     scalar, the result is the same size as ALPHA.  If ALPHA is a row
     vector and X is a column vector, the result is a matrix with
     ‘length (X)’ rows and ‘length (ALPHA)’ columns.  Otherwise, ALPHA
     and X must conform and the result will be the same size.

     If requested, IERR contains the following status information and is
     the same size as the result.

       0. Normal return.

       1. Input error, return ‘NaN’.

       2. Overflow, return ‘Inf’.

       3. Loss of significance by argument reduction results in less
          than half of machine accuracy.

       4. Loss of significance by argument reduction, output may be
          inaccurate.

       5. Error—no computation, algorithm termination condition not met,
          return ‘NaN’.

     See also: *note bessely: XREFbessely, *note besseli: XREFbesseli,
     *note besselk: XREFbesselk, *note besselh: XREFbesselh.

 -- : Y = bessely (ALPHA, X)
 -- : Y = bessely (ALPHA, X, OPT)
 -- : [Y, IERR] = bessely (...)
     Compute Bessel functions of the second kind.

     The order of the Bessel function ALPHA must be real.  The points
     for evaluation X may be complex.

     If the optional argument OPT is 1 or true, the result Y is
     multiplied by ‘exp (-abs (imag (X)))’.

     If ALPHA is a scalar, the result is the same size as X.  If X is a
     scalar, the result is the same size as ALPHA.  If ALPHA is a row
     vector and X is a column vector, the result is a matrix with
     ‘length (X)’ rows and ‘length (ALPHA)’ columns.  Otherwise, ALPHA
     and X must conform and the result will be the same size.

     If requested, IERR contains the following status information and is
     the same size as the result.

       0. Normal return.

       1. Input error, return ‘NaN’.

       2. Overflow, return ‘Inf’.

       3. Loss of significance by argument reduction results in less
          than half of machine accuracy.

       4. Complete loss of significance by argument reduction, return
          ‘NaN’.

       5. Error—no computation, algorithm termination condition not met,
          return ‘NaN’.

     See also: *note besselj: XREFbesselj, *note besseli: XREFbesseli,
     *note besselk: XREFbesselk, *note besselh: XREFbesselh.

 -- : I = besseli (ALPHA, X)
 -- : I = besseli (ALPHA, X, OPT)
 -- : [I, IERR] = besseli (...)
     Compute modified Bessel functions of the first kind.

     The order of the Bessel function ALPHA must be real.  The points
     for evaluation X may be complex.

     If the optional argument OPT is 1 or true, the result I is
     multiplied by ‘exp (-abs (real (X)))’.

     If ALPHA is a scalar, the result is the same size as X.  If X is a
     scalar, the result is the same size as ALPHA.  If ALPHA is a row
     vector and X is a column vector, the result is a matrix with
     ‘length (X)’ rows and ‘length (ALPHA)’ columns.  Otherwise, ALPHA
     and X must conform and the result will be the same size.

     If requested, IERR contains the following status information and is
     the same size as the result.

       0. Normal return.

       1. Input error, return ‘NaN’.

       2. Overflow, return ‘Inf’.

       3. Loss of significance by argument reduction results in less
          than half of machine accuracy.

       4. Complete loss of significance by argument reduction, return
          ‘NaN’.

       5. Error—no computation, algorithm termination condition not met,
          return ‘NaN’.

     See also: *note besselk: XREFbesselk, *note besselj: XREFbesselj,
     *note bessely: XREFbessely, *note besselh: XREFbesselh.

 -- : K = besselk (ALPHA, X)
 -- : K = besselk (ALPHA, X, OPT)
 -- : [K, IERR] = besselk (...)

     Compute modified Bessel functions of the second kind.

     The order of the Bessel function ALPHA must be real.  The points
     for evaluation X may be complex.

     If the optional argument OPT is 1 or true, the result K is
     multiplied by ‘exp (X)’.

     If ALPHA is a scalar, the result is the same size as X.  If X is a
     scalar, the result is the same size as ALPHA.  If ALPHA is a row
     vector and X is a column vector, the result is a matrix with
     ‘length (X)’ rows and ‘length (ALPHA)’ columns.  Otherwise, ALPHA
     and X must conform and the result will be the same size.

     If requested, IERR contains the following status information and is
     the same size as the result.

       0. Normal return.

       1. Input error, return ‘NaN’.

       2. Overflow, return ‘Inf’.

       3. Loss of significance by argument reduction results in less
          than half of machine accuracy.

       4. Complete loss of significance by argument reduction, return
          ‘NaN’.

       5. Error—no computation, algorithm termination condition not met,
          return ‘NaN’.

     See also: *note besseli: XREFbesseli, *note besselj: XREFbesselj,
     *note bessely: XREFbessely, *note besselh: XREFbesselh.

 -- : H = besselh (ALPHA, X)
 -- : H = besselh (ALPHA, K, X)
 -- : H = besselh (ALPHA, K, X, OPT)
 -- : [H, IERR] = besselh (...)
     Compute Bessel functions of the third kind (Hankel functions).

     The order of the Bessel function ALPHA must be real.  The kind of
     Hankel function is specified by K and may be either first (K = 1)
     or second (K = 2).  The default is Hankel functions of the first
     kind.  The points for evaluation X may be complex.

     If the optional argument OPT is 1 or true, the result is multiplied
     by ‘exp (-I*X)’ for K = 1 or ‘exp (I*X)’ for K = 2.

     If ALPHA is a scalar, the result is the same size as X.  If X is a
     scalar, the result is the same size as ALPHA.  If ALPHA is a row
     vector and X is a column vector, the result is a matrix with
     ‘length (X)’ rows and ‘length (ALPHA)’ columns.  Otherwise, ALPHA
     and X must conform and the result will be the same size.

     If requested, IERR contains the following status information and is
     the same size as the result.

       0. Normal return.

       1. Input error, return ‘NaN’.

       2. Overflow, return ‘Inf’.

       3. Loss of significance by argument reduction results in less
          than half of machine accuracy.

       4. Complete loss of significance by argument reduction, return
          ‘NaN’.

       5. Error—no computation, algorithm termination condition not met,
          return ‘NaN’.

     See also: *note besselj: XREFbesselj, *note bessely: XREFbessely,
     *note besseli: XREFbesseli, *note besselk: XREFbesselk.

 -- : beta (A, B)
     Compute the Beta function for real inputs A and B.

     The Beta function definition is

          beta (a, b) = gamma (a) * gamma (b) / gamma (a + b).

     The Beta function can grow quite large and it is often more useful
     to work with the logarithm of the output rather than the function
     directly.  *Note betaln: XREFbetaln, for computing the logarithm of
     the Beta function in an efficient manner.

     See also: *note betaln: XREFbetaln, *note betainc: XREFbetainc,
     *note betaincinv: XREFbetaincinv.

 -- : betainc (X, A, B)
 -- : betainc (X, A, B, TAIL)
     Compute the incomplete beta function.

     This is defined as

                         x
                        /
                       |
          I_x (a, b) = | t^(a-1) (1-t)^(b-1) dt
                       |
                       /
                      0

     with real X in the range [0,1].  The inputs A and B must be real
     and strictly positive (> 0).  If one of the inputs is not a scalar
     then the other inputs must be scalar or of compatible dimensions.

     By default, TAIL is "lower" and the incomplete beta function
     integrated from 0 to X is computed.  If TAIL is "upper" then the
     complementary function integrated from X to 1 is calculated.  The
     two choices are related by

     betainc (X, A, B, "upper") = 1 - betainc (X, A, B, "lower").

     ‘betainc’ uses a more sophisticated algorithm than subtraction to
     get numerically accurate results when the "lower" value is small.

     Reference: A. Cuyt, V. Brevik Petersen, B. Verdonk, H. Waadeland,
     W.B. Jones, ‘Handbook of Continued Fractions for Special
     Functions’, ch. 18.

     See also: *note beta: XREFbeta, *note betaincinv: XREFbetaincinv,
     *note betaln: XREFbetaln.

 -- : betaincinv (Y, A, B)
 -- : betaincinv (Y, A, B, "lower")
 -- : betaincinv (Y, A, B, "upper")
     Compute the inverse of the normalized incomplete beta function.

     The normalized incomplete beta function is defined as

                         x
                        /
                       |
          I_x (a, b) = | t^(a-1) (1-t)^(b-1) dt
                       |
                       /
                      0

     If two inputs are scalar, then ‘betaincinv (Y, A, B)’ is returned
     for each of the other inputs.

     If two or more inputs are not scalar, the sizes of them must agree,
     and ‘betaincinv’ is applied element-by-element.

     The variable Y must be in the interval [0,1], while A and B must be
     real and strictly positive.

     By default, TAIL is "lower" and the inverse of the incomplete beta
     function integrated from 0 to X is computed.  If TAIL is "upper"
     then the complementary function integrated from X to 1 is inverted.

     The function is computed by standard Newton’s method, by solving

          Y - betainc (X, A, B) = 0

     See also: *note betainc: XREFbetainc, *note beta: XREFbeta, *note
     betaln: XREFbetaln.

 -- : betaln (A, B)
     Compute the natural logarithm of the Beta function for real inputs
     A and B.

     ‘betaln’ is defined as

          betaln (a, b) = log (beta (a, b))

     and is calculated in a way to reduce the occurrence of underflow.

     The Beta function can grow quite large and it is often more useful
     to work with the logarithm of the output rather than the function
     directly.

     See also: *note beta: XREFbeta, *note betainc: XREFbetainc, *note
     betaincinv: XREFbetaincinv, *note gammaln: XREFgammaln.

 -- : bincoeff (N, K)
     Return the binomial coefficient of N and K.

     The binomial coefficient is defined as

           /   \
           | n |    n (n-1) (n-2) ... (n-k+1)
           |   |  = -------------------------
           | k |               k!
           \   /

     For example:

          bincoeff (5, 2)
             ⇒ 10

     In most cases, the ‘nchoosek’ function is faster for small scalar
     integer arguments.  It also warns about loss of precision for big
     arguments.

     See also: *note nchoosek: XREFnchoosek.

 -- : commutation_matrix (M, N)
     Return the commutation matrix K(m,n) which is the unique M*N by M*N
     matrix such that K(m,n) * vec(A) = vec(A') for all m by n matrices
     A.

     If only one argument M is given, K(m,m) is returned.

     See Magnus and Neudecker (1988), ‘Matrix Differential Calculus with
     Applications in Statistics and Econometrics.’

 -- : cosint (X)
     Compute the cosine integral function:

                      +oo
                     /
          Ci (x) = - | (cos (t)) / t dt
                     /
                    x

     An equivalent definition is

                                       x
                                      /
                                      |  cos (t) - 1
          Ci (x) = gamma + log (x) +  | -------------  dt
                                      |        t
                                      /
                                     0

     Reference:

     M. Abramowitz and I.A. Stegun, ‘Handbook of Mathematical Functions’
     1964.

     See also: *note sinint: XREFsinint, *note expint: XREFexpint, *note
     cos: XREFcos.

 -- : duplication_matrix (N)
     Return the duplication matrix Dn which is the unique n^2 by
     n*(n+1)/2 matrix such that Dn vech (A) = vec (A) for all symmetric
     n by n matrices A.

     See Magnus and Neudecker (1988), ‘Matrix Differential Calculus with
     Applications in Statistics and Econometrics.’

 -- : dawson (Z)
     Compute the Dawson (scaled imaginary error) function.

     The Dawson function is defined as

          (sqrt (pi) / 2) * exp (-z^2) * erfi (z)

     See also: *note erfc: XREFerfc, *note erf: XREFerf, *note erfcx:
     XREFerfcx, *note erfi: XREFerfi, *note erfinv: XREFerfinv, *note
     erfcinv: XREFerfcinv.

 -- : [SN, CN, DN, ERR] = ellipj (U, M)
 -- : [SN, CN, DN, ERR] = ellipj (U, M, TOL)
     Compute the Jacobi elliptic functions SN, CN, and DN of complex
     argument U and real parameter M.

     If M is a scalar, the results are the same size as U.  If U is a
     scalar, the results are the same size as M.  If U is a column
     vector and M is a row vector, the results are matrices with ‘length
     (U)’ rows and ‘length (M)’ columns.  Otherwise, U and M must
     conform in size and the results will be the same size as the
     inputs.

     The value of U may be complex.  The value of M must be 0 ≤ M ≤ 1.

     The optional input TOL is currently ignored (MATLAB uses this to
     allow faster, less accurate approximation).

     If requested, ERR contains the following status information and is
     the same size as the result.

       0. Normal return.

       1. Error—no computation, algorithm termination condition not met,
          return ‘NaN’.

     Reference: Milton Abramowitz and Irene A Stegun, ‘Handbook of
     Mathematical Functions’, Chapter 16 (Sections 16.4, 16.13, and
     16.15), Dover, 1965.

     See also: *note ellipke: XREFellipke.

 -- : K = ellipke (M)
 -- : K = ellipke (M, TOL)
 -- : [K, E] = ellipke (...)
     Compute complete elliptic integrals of the first K(M) and second
     E(M) kind.

     M must be a scalar or real array with -Inf ≤ M ≤ 1.

     The optional input TOL controls the stopping tolerance of the
     algorithm and defaults to ‘eps (class (M))’.  The tolerance can be
     increased to compute a faster, less accurate approximation.

     When called with one output only elliptic integrals of the first
     kind are returned.

     Mathematical Note:

     Elliptic integrals of the first kind are defined as

                   1
                  /               dt
          K (m) = | ------------------------------
                  / sqrt ((1 - t^2)*(1 - m*t^2))
                 0

     Elliptic integrals of the second kind are defined as

                   1
                  /  sqrt (1 - m*t^2)
          E (m) = |  ------------------ dt
                  /  sqrt (1 - t^2)
                 0

     Reference: Milton Abramowitz and Irene A. Stegun, ‘Handbook of
     Mathematical Functions’, Chapter 17, Dover, 1965.

     See also: *note ellipj: XREFellipj.

 -- : erf (Z)
     Compute the error function.

     The error function is defined as

                                  z
                        2        /
          erf (z) = --------- *  | e^(-t^2) dt
                    sqrt (pi)    /
                              t=0

     See also: *note erfc: XREFerfc, *note erfcx: XREFerfcx, *note erfi:
     XREFerfi, *note dawson: XREFdawson, *note erfinv: XREFerfinv, *note
     erfcinv: XREFerfcinv.

 -- : erfc (Z)
     Compute the complementary error function.

     The complementary error function is defined as ‘1 - erf (Z)’.

     See also: *note erfcinv: XREFerfcinv, *note erfcx: XREFerfcx, *note
     erfi: XREFerfi, *note dawson: XREFdawson, *note erf: XREFerf, *note
     erfinv: XREFerfinv.

 -- : erfcx (Z)
     Compute the scaled complementary error function.

     The scaled complementary error function is defined as

          exp (z^2) * erfc (z)

     See also: *note erfc: XREFerfc, *note erf: XREFerf, *note erfi:
     XREFerfi, *note dawson: XREFdawson, *note erfinv: XREFerfinv, *note
     erfcinv: XREFerfcinv.

 -- : erfi (Z)
     Compute the imaginary error function.

     The imaginary error function is defined as

          -i * erf (i*z)

     See also: *note erfc: XREFerfc, *note erf: XREFerf, *note erfcx:
     XREFerfcx, *note dawson: XREFdawson, *note erfinv: XREFerfinv,
     *note erfcinv: XREFerfcinv.

 -- : erfinv (X)
     Compute the inverse error function.

     The inverse error function is defined such that

          erf (Y) == X

     See also: *note erf: XREFerf, *note erfc: XREFerfc, *note erfcx:
     XREFerfcx, *note erfi: XREFerfi, *note dawson: XREFdawson, *note
     erfcinv: XREFerfcinv.

 -- : erfcinv (X)
     Compute the inverse complementary error function.

     The inverse complementary error function is defined such that

          erfc (Y) == X

     See also: *note erfc: XREFerfc, *note erf: XREFerf, *note erfcx:
     XREFerfcx, *note erfi: XREFerfi, *note dawson: XREFdawson, *note
     erfinv: XREFerfinv.

 -- : expint (X)
     Compute the exponential integral.

     The exponential integral is defined as:

                     +oo
                    /
                    | exp (-t)
          E_1 (x) = | -------- dt
                    |    t
                    /
                   x

     Note: For compatibility, this function uses the MATLAB definition
     of the exponential integral.  Most other sources refer to this
     particular value as E_1 (x), and the exponential integral as

                      +oo
                     /
                     | exp (-t)
          Ei (x) = - | -------- dt
                     |    t
                     /
                   -x

     The two definitions are related, for positive real values of X, by
     ‘E_1 (-x) = -Ei (x) - i*pi’.

     References:

     M. Abramowitz and I.A. Stegun, ‘Handbook of Mathematical
     Functions’, 1964.

     N. Bleistein and R.A. Handelsman, ‘Asymptotic expansions of
     integrals’, 1986.

     See also: *note cosint: XREFcosint, *note sinint: XREFsinint, *note
     exp: XREFexp.

 -- : gamma (Z)
     Compute the Gamma function.

     The Gamma function is defined as

                       infinity
                      /
          gamma (z) = | t^(z-1) exp (-t) dt.
                      /
                   t=0

     Programming Note: The gamma function can grow quite large even for
     small input values.  In many cases it may be preferable to use the
     natural logarithm of the gamma function (‘gammaln’) in calculations
     to minimize loss of precision.  The final result is then ‘exp
     (RESULT_USING_GAMMALN).’

     See also: *note gammainc: XREFgammainc, *note gammaln: XREFgammaln,
     *note factorial: XREFfactorial.

 -- : gammainc (X, A)
 -- : gammainc (X, A, TAIL)
     Compute the normalized incomplete gamma function.

     This is defined as

                                          x
                                 1       /
          gammainc (x, a) = ---------    | exp (-t) t^(a-1) dt
                            gamma (a)    /
                                      t=0

     with the limiting value of 1 as X approaches infinity.  The
     standard notation is P(a,x), e.g., Abramowitz and Stegun (6.5.1).

     If A is scalar, then ‘gammainc (X, A)’ is returned for each element
     of X and vice versa.

     If neither X nor A is scalar then the sizes of X and A must agree,
     and ‘gammainc’ is applied element-by-element.  The elements of A
     must be non-negative.

     By default, TAIL is "lower" and the incomplete gamma function
     integrated from 0 to X is computed.  If TAIL is "upper" then the
     complementary function integrated from X to infinity is calculated.

     If TAIL is "scaledlower", then the lower incomplete gamma function
     is multiplied by gamma(a+1)*exp(x)/(x^a).  If TAIL is
     "scaledupper", then the upper incomplete gamma function is
     multiplied by the same quantity.

     References:

     M. Abramowitz and I.A. Stegun, ‘Handbook of mathematical
     functions’, Dover publications, Inc., 1972.

     W. Gautschi, ‘A computational procedure for incomplete gamma
     functions’, ACM Trans.  Math Software, pp.  466–481, Vol 5, No.  4,
     2012.

     W. H. Press, S. A. Teukolsky, W. T. Vetterling, and B. P. Flannery,
     ‘Numerical Recipes in Fortran 77’, ch. 6.2, Vol 1, 1992.

     See also: *note gamma: XREFgamma, *note gammaincinv:
     XREFgammaincinv, *note gammaln: XREFgammaln.

 -- : gammaincinv (Y, A)
 -- : gammaincinv (Y, A, TAIL)
     Compute the inverse of the normalized incomplete gamma function.

     The normalized incomplete gamma function is defined as

                                          x
                                 1       /
          gammainc (x, a) = ---------    | exp (-t) t^(a-1) dt
                            gamma (a)    /
                                      t=0

     and ‘gammaincinv (gammainc (X, A), A) = X’ for each non-negative
     value of X.  If A is scalar then ‘gammaincinv (Y, A)’ is returned
     for each element of Y and vice versa.

     If neither Y nor A is scalar then the sizes of Y and A must agree,
     and ‘gammaincinv’ is applied element-by-element.  The variable Y
     must be in the interval [0,1] while A must be real and positive.

     By default, TAIL is "lower" and the inverse of the incomplete gamma
     function integrated from 0 to X is computed.  If TAIL is "upper",
     then the complementary function integrated from X to infinity is
     inverted.

     The function is computed with Newton’s method by solving

          Y - gammainc (X, A) = 0

     Reference: A. Gil, J. Segura, and N. M. Temme, ‘Efficient and
     accurate algorithms for the computation and inversion of the
     incomplete gamma function ratios’, SIAM J. Sci.  Computing, pp.
     A2965–A2981, Vol 34, 2012.

     See also: *note gammainc: XREFgammainc, *note gamma: XREFgamma,
     *note gammaln: XREFgammaln.

 -- : L = legendre (N, X)
 -- : L = legendre (N, X, NORMALIZATION)
     Compute the associated Legendre function of degree N and order M =
     0 ... N.

     The value N must be a real non-negative integer.

     X is a vector with real-valued elements in the range [-1, 1].

     The optional argument NORMALIZATION may be one of "unnorm", "sch",
     or "norm".  The default if no normalization is given is "unnorm".

     When the optional argument NORMALIZATION is "unnorm", compute the
     associated Legendre function of degree N and order M and return all
     values for M = 0 ... N.  The return value has one dimension more
     than X.

     The associated Legendre function of degree N and order M:

           m         m      2  m/2   d^m
          P(x) = (-1) * (1-x  )    * ----  P(x)
           n                         dx^m   n

     with Legendre polynomial of degree N:

                    1    d^n   2    n
          P(x) = ------ [----(x - 1) ]
           n     2^n n!  dx^n

     ‘legendre (3, [-1.0, -0.9, -0.8])’ returns the matrix:

           x  |   -1.0   |   -0.9   |   -0.8
          ------------------------------------
          m=0 | -1.00000 | -0.47250 | -0.08000
          m=1 |  0.00000 | -1.99420 | -1.98000
          m=2 |  0.00000 | -2.56500 | -4.32000
          m=3 |  0.00000 | -1.24229 | -3.24000

     When the optional argument NORMALIZATION is "sch", compute the
     Schmidt semi-normalized associated Legendre function.  The Schmidt
     semi-normalized associated Legendre function is related to the
     unnormalized Legendre functions by the following:

     For Legendre functions of degree N and order 0:

            0      0
          SP(x) = P(x)
            n      n

     For Legendre functions of degree n and order m:

            m      m         m    2(n-m)! 0.5
          SP(x) = P(x) * (-1)  * [-------]
            n      n              (n+m)!

     When the optional argument NORMALIZATION is "norm", compute the
     fully normalized associated Legendre function.  The fully
     normalized associated Legendre function is related to the
     unnormalized associated Legendre functions by the following:

     For Legendre functions of degree N and order M

            m      m         m    (n+0.5)(n-m)! 0.5
          NP(x) = P(x) * (-1)  * [-------------]
            n      n                  (n+m)!

 -- : gammaln (X)
 -- : lgamma (X)
     Return the natural logarithm of the gamma function of X.

     See also: *note gamma: XREFgamma, *note gammainc: XREFgammainc.

 -- : psi (Z)
 -- : psi (K, Z)
     Compute the psi (polygamma) function.

     The polygamma functions are the Kth derivative of the logarithm of
     the gamma function.  If unspecified, K defaults to zero.  A value
     of zero computes the digamma function, a value of 1, the trigamma
     function, and so on.

     The digamma function is defined:

          psi (z) = d (log (gamma (z))) / dx

     When computing the digamma function (when K equals zero), Z can
     have any value real or complex value.  However, for polygamma
     functions (K higher than 0), Z must be real and non-negative.

     See also: *note gamma: XREFgamma, *note gammainc: XREFgammainc,
     *note gammaln: XREFgammaln.

 -- : sinint (X)
     Compute the sine integral function:

                     x
                    /
          Si (x) =  | sin (t) / t dt
                    /
                   0

     Reference: M. Abramowitz and I.A. Stegun, ‘Handbook of Mathematical
     Functions’, 1964.

     See also: *note cosint: XREFcosint, *note expint: XREFexpint, *note
     sin: XREFsin.


File: octave.info,  Node: Rational Approximations,  Next: Coordinate Transformations,  Prev: Special Functions,  Up: Arithmetic

17.7 Rational Approximations
============================

 -- : S = rat (X)
 -- : S = rat (X, TOL)
 -- : [N, D] = rat (...)

     Find a rational approximation of X to within the tolerance defined
     by TOL.

     If unspecified, the default tolerance is ‘1e-6 * norm (X(:), 1)’.

     When called with one output argument, return a string containing a
     continued fraction expansion (multiple terms).

     When called with two output arguments, return numeric matrices for
     the numerator and denominator of a fractional representation of X
     such that ‘X = N ./ D’.

     For example:

          s = rat (pi)
          ⇒ s = 3 + 1/(7 + 1/16)

          [n, d] = rat (pi)
          ⇒ n =  355
          ⇒ d =  113

          n / d - pi
          ⇒ 0.00000026676

     Programming Note: With one output ‘rat’ produces a string which is
     a continued fraction expansion.  To produce a string which is a
     simple fraction (one numerator, one denominator) use ‘rats’.

     See also: *note rats: XREFrats, *note format: XREFformat.

 -- : rats (X, LEN)
     Convert X into a rational approximation represented as a string.

     The string can be converted back into a matrix as follows:

          r = rats (hilb (4));
          x = str2num (r)

     The optional second argument defines the maximum length of the
     string representing the elements of X.  By default LEN is 9.

     If the length of the smallest possible rational approximation
     exceeds LEN, an asterisk (*) padded with spaces will be returned
     instead.

     See also: *note format: XREFformat, *note rat: XREFrat.


File: octave.info,  Node: Coordinate Transformations,  Next: Mathematical Constants,  Prev: Rational Approximations,  Up: Arithmetic

17.8 Coordinate Transformations
===============================

 -- : [THETA, R] = cart2pol (X, Y)
 -- : [THETA, R, Z] = cart2pol (X, Y, Z)
 -- : [THETA, R] = cart2pol (C)
 -- : [THETA, R, Z] = cart2pol (C)
 -- : P = cart2pol (...)

     Transform Cartesian coordinates to polar or cylindrical
     coordinates.

     The inputs X, Y (, and Z) must be the same shape, or scalar.  If
     called with a single matrix argument then each row of C represents
     the Cartesian coordinate (X, Y (, Z)).

     THETA describes the angle relative to the positive x-axis.

     R is the distance to the z-axis (0, 0, z).

     If only a single return argument is requested then return a matrix
     P where each row represents one polar/(cylindrical) coordinate
     (THETA, PHI (, Z)).

     See also: *note pol2cart: XREFpol2cart, *note cart2sph:
     XREFcart2sph, *note sph2cart: XREFsph2cart.

 -- : [X, Y] = pol2cart (THETA, R)
 -- : [X, Y, Z] = pol2cart (THETA, R, Z)
 -- : [X, Y] = pol2cart (P)
 -- : [X, Y, Z] = pol2cart (P)
 -- : C = pol2cart (...)
     Transform polar or cylindrical coordinates to Cartesian
     coordinates.

     The inputs THETA, R, (and Z) must be the same shape, or scalar.  If
     called with a single matrix argument then each row of P represents
     the polar/(cylindrical) coordinate (THETA, R (, Z)).

     THETA describes the angle relative to the positive x-axis.

     R is the distance to the z-axis (0, 0, z).

     If only a single return argument is requested then return a matrix
     C where each row represents one Cartesian coordinate (X, Y (, Z)).

     See also: *note cart2pol: XREFcart2pol, *note sph2cart:
     XREFsph2cart, *note cart2sph: XREFcart2sph.

 -- : [THETA, PHI, R] = cart2sph (X, Y, Z)
 -- : [THETA, PHI, R] = cart2sph (C)
 -- : S = cart2sph (...)
     Transform Cartesian coordinates to spherical coordinates.

     The inputs X, Y, and Z must be the same shape, or scalar.  If
     called with a single matrix argument then each row of C represents
     the Cartesian coordinate (X, Y, Z).

     THETA describes the angle relative to the positive x-axis.

     PHI is the angle relative to the xy-plane.

     R is the distance to the origin (0, 0, 0).

     If only a single return argument is requested then return a matrix
     S where each row represents one spherical coordinate (THETA, PHI,
     R).

     See also: *note sph2cart: XREFsph2cart, *note cart2pol:
     XREFcart2pol, *note pol2cart: XREFpol2cart.

 -- : [X, Y, Z] = sph2cart (THETA, PHI, R)
 -- : [X, Y, Z] = sph2cart (S)
 -- : C = sph2cart (...)
     Transform spherical coordinates to Cartesian coordinates.

     The inputs THETA, PHI, and R must be the same shape, or scalar.  If
     called with a single matrix argument then each row of S represents
     the spherical coordinate (THETA, PHI, R).

     THETA describes the angle relative to the positive x-axis.

     PHI is the angle relative to the xy-plane.

     R is the distance to the origin (0, 0, 0).

     If only a single return argument is requested then return a matrix
     C where each row represents one Cartesian coordinate (X, Y, Z).

     See also: *note cart2sph: XREFcart2sph, *note pol2cart:
     XREFpol2cart, *note cart2pol: XREFcart2pol.


File: octave.info,  Node: Mathematical Constants,  Prev: Coordinate Transformations,  Up: Arithmetic

17.9 Mathematical Constants
===========================

 -- : e
 -- : e (N)
 -- : e (N, M)
 -- : e (N, M, K, ...)
 -- : e (..., CLASS)
     Return a scalar, matrix, or N-dimensional array whose elements are
     all equal to the base of natural logarithms.

     The constant ‘e’ satisfies the equation ‘log’ (e) = 1.

     When called with no arguments, return a scalar with the value e.

     When called with a single argument, return a square matrix with the
     dimension specified.

     When called with more than one scalar argument the first two
     arguments are taken as the number of rows and columns and any
     further arguments specify additional matrix dimensions.

     The optional argument CLASS specifies the return type and may be
     either "double" or "single".

     See also: *note log: XREFlog, *note exp: XREFexp, *note pi: XREFpi,
     *note I: XREFI.

 -- : pi
 -- : pi (N)
 -- : pi (N, M)
 -- : pi (N, M, K, ...)
 -- : pi (..., CLASS)
     Return a scalar, matrix, or N-dimensional array whose elements are
     all equal to the ratio of the circumference of a circle to its
     diameter.

     Internally, ‘pi’ is computed as ‘4.0 * atan (1.0)’.

     When called with no arguments, return a scalar with the value of
     pi.

     When called with a single argument, return a square matrix with the
     dimension specified.

     When called with more than one scalar argument the first two
     arguments are taken as the number of rows and columns and any
     further arguments specify additional matrix dimensions.

     The optional argument CLASS specifies the return type and may be
     either "double" or "single".

     See also: *note e: XREFe, *note I: XREFI.

 -- : I
 -- : I (N)
 -- : I (N, M)
 -- : I (N, M, K, ...)
 -- : I (..., CLASS)
     Return a scalar, matrix, or N-dimensional array whose elements are
     all equal to the pure imaginary unit, defined as ‘sqrt (-1)’.

     I, and its equivalents i, j, and J, are functions so any of the
     names may be reused for other purposes (such as i for a counter
     variable).

     When called with no arguments, return a scalar with the value i.

     When called with a single argument, return a square matrix with the
     dimension specified.

     When called with more than one scalar argument the first two
     arguments are taken as the number of rows and columns and any
     further arguments specify additional matrix dimensions.

     The optional argument CLASS specifies the return type and may be
     either "double" or "single".

     See also: *note e: XREFe, *note pi: XREFpi, *note log: XREFlog,
     *note exp: XREFexp.

 -- : Inf
 -- : Inf (N)
 -- : Inf (N, M)
 -- : Inf (N, M, K, ...)
 -- : Inf (..., CLASS)
     Return a scalar, matrix or N-dimensional array whose elements are
     all equal to the IEEE representation for positive infinity.

     Infinity is produced when results are too large to be represented
     using the IEEE floating point format for numbers.  Two common
     examples which produce infinity are division by zero and overflow.

          [ 1/0 e^800 ]
          ⇒ Inf   Inf

     When called with no arguments, return a scalar with the value
     ‘Inf’.

     When called with a single argument, return a square matrix with the
     dimension specified.

     When called with more than one scalar argument the first two
     arguments are taken as the number of rows and columns and any
     further arguments specify additional matrix dimensions.

     The optional argument CLASS specifies the return type and may be
     either "double" or "single".

     See also: *note isinf: XREFisinf, *note NaN: XREFNaN.

 -- : NaN
 -- : NaN (N)
 -- : NaN (N, M)
 -- : NaN (N, M, K, ...)
 -- : NaN (..., CLASS)
     Return a scalar, matrix, or N-dimensional array whose elements are
     all equal to the IEEE symbol NaN (Not a Number).

     NaN is the result of operations which do not produce a well defined
     numerical result.  Common operations which produce a NaN are
     arithmetic with infinity (Inf - Inf), zero divided by zero (0/0),
     and any operation involving another NaN value (5 + NaN).

     Note that NaN always compares not equal to NaN (NaN != NaN). This
     behavior is specified by the IEEE standard for floating point
     arithmetic.  To find NaN values, use the ‘isnan’ function.

     When called with no arguments, return a scalar with the value
     ‘NaN’.

     When called with a single argument, return a square matrix with the
     dimension specified.

     When called with more than one scalar argument the first two
     arguments are taken as the number of rows and columns and any
     further arguments specify additional matrix dimensions.

     The optional argument CLASS specifies the return type and may be
     either "double" or "single".

     See also: *note isnan: XREFisnan, *note Inf: XREFInf.

 -- : eps
 -- : eps (X)
 -- : eps (N, M)
 -- : eps (N, M, K, ...)
 -- : eps (..., CLASS)
     Return a scalar, matrix or N-dimensional array whose elements are
     all eps, the machine precision.

     More precisely, ‘eps’ is the relative spacing between any two
     adjacent numbers in the machine’s floating point system.  This
     number is obviously system dependent.  On machines that support
     IEEE floating point arithmetic, ‘eps’ is approximately 2.2204e-16
     for double precision and 1.1921e-07 for single precision.

     When called with no arguments, return a scalar with the value ‘eps
     (1.0)’.

     Given a single argument X, return the distance between X and the
     next largest value.

     When called with more than one argument the first two arguments are
     taken as the number of rows and columns and any further arguments
     specify additional matrix dimensions.  The optional argument CLASS
     specifies the return type and may be either "double" or "single".

     See also: *note realmax: XREFrealmax, *note realmin: XREFrealmin,
     *note intmax: XREFintmax, *note flintmax: XREFflintmax.

 -- : realmax
 -- : realmax (N)
 -- : realmax (N, M)
 -- : realmax (N, M, K, ...)
 -- : realmax (..., CLASS)
     Return a scalar, matrix, or N-dimensional array whose elements are
     all equal to the largest floating point number that is
     representable.

     The actual value is system dependent.  On machines that support
     IEEE floating point arithmetic, ‘realmax’ is approximately
     1.7977e+308 for double precision and 3.4028e+38 for single
     precision.

     When called with no arguments, return a scalar with the value
     ‘realmax ("double")’.

     When called with a single argument, return a square matrix with the
     dimension specified.

     When called with more than one scalar argument the first two
     arguments are taken as the number of rows and columns and any
     further arguments specify additional matrix dimensions.

     The optional argument CLASS specifies the return type and may be
     either "double" or "single".

     See also: *note realmin: XREFrealmin, *note intmax: XREFintmax,
     *note flintmax: XREFflintmax, *note eps: XREFeps.

 -- : realmin
 -- : realmin (N)
 -- : realmin (N, M)
 -- : realmin (N, M, K, ...)
 -- : realmin (..., CLASS)
     Return a scalar, matrix, or N-dimensional array whose elements are
     all equal to the smallest normalized floating point number that is
     representable.

     The actual value is system dependent.  On machines that support
     IEEE floating point arithmetic, ‘realmin’ is approximately
     2.2251e-308 for double precision and 1.1755e-38 for single
     precision.

     When called with no arguments, return a scalar with the value
     ‘realmin ("double")’.

     When called with a single argument, return a square matrix with the
     dimension specified.

     When called with more than one scalar argument the first two
     arguments are taken as the number of rows and columns and any
     further arguments specify additional matrix dimensions.

     The optional argument CLASS specifies the return type and may be
     either "double" or "single".

     See also: *note realmax: XREFrealmax, *note intmin: XREFintmin,
     *note eps: XREFeps.


File: octave.info,  Node: Linear Algebra,  Next: Vectorization and Faster Code Execution,  Prev: Arithmetic,  Up: Top

18 Linear Algebra
*****************

This chapter documents the linear algebra functions provided in Octave.
Reference material for many of these functions may be found in Golub and
Van Loan, ‘Matrix Computations, 2nd Ed.’, Johns Hopkins, 1989, and in
the ‘LAPACK Users’ Guide’, SIAM, 1992.  The ‘LAPACK Users’ Guide’ is
available at: ‘http://www.netlib.org/lapack/lug/’

   A common text for engineering courses is G. Strang, ‘Linear Algebra
and Its Applications, 4th Edition’.  It has become a widespread
reference for linear algebra.  An alternative is P. Lax ‘Linear Algebra
and Its Applications’, and also is a good choice.  It claims to be
suitable for high school students with substantial mathematical
interests as well as first-year undergraduates.

* Menu:

* Techniques Used for Linear Algebra::
* Basic Matrix Functions::
* Matrix Factorizations::
* Functions of a Matrix::
* Specialized Solvers::


File: octave.info,  Node: Techniques Used for Linear Algebra,  Next: Basic Matrix Functions,  Up: Linear Algebra

18.1 Techniques Used for Linear Algebra
=======================================

Octave includes a polymorphic solver that selects an appropriate matrix
factorization depending on the properties of the matrix itself.
Generally, the cost of determining the matrix type is small relative to
the cost of factorizing the matrix itself.  In any case the matrix type
is cached once it is calculated so that it is not re-determined each
time it is used in a linear equation.

   The selection tree for how the linear equation is solved or a matrix
inverse is formed is given by:

  1. If the matrix is upper or lower triangular sparse use a forward or
     backward substitution using the LAPACK xTRTRS function, and goto 4.

  2. If the matrix is square, Hermitian with a real positive diagonal,
     attempt Cholesky factorization using the LAPACK xPOTRF function.

  3. If the Cholesky factorization failed or the matrix is not Hermitian
     with a real positive diagonal, and the matrix is square, factorize
     using the LAPACK xGETRF function.

  4. If the matrix is not square, or any of the previous solvers flags a
     singular or near singular matrix, find a least squares solution
     using the LAPACK xGELSD function.

   The user can force the type of the matrix with the ‘matrix_type’
function.  This overcomes the cost of discovering the type of the
matrix.  However, it should be noted that identifying the type of the
matrix incorrectly will lead to unpredictable results, and so
‘matrix_type’ should be used with care.

   It should be noted that the test for whether a matrix is a candidate
for Cholesky factorization, performed above, and by the ‘matrix_type’
function, does not make certain that the matrix is Hermitian.  However,
the attempt to factorize the matrix will quickly detect a non-Hermitian
matrix.


File: octave.info,  Node: Basic Matrix Functions,  Next: Matrix Factorizations,  Prev: Techniques Used for Linear Algebra,  Up: Linear Algebra

18.2 Basic Matrix Functions
===========================

 -- : AA = balance (A)
 -- : AA = balance (A, OPT)
 -- : [DD, AA] = balance (A, OPT)
 -- : [D, P, AA] = balance (A, OPT)
 -- : [CC, DD, AA, BB] = balance (A, B, OPT)

     Balance the matrix A to reduce numerical errors in future
     calculations.

     Compute ‘AA = DD \ A * DD’ in which AA is a matrix whose row and
     column norms are roughly equal in magnitude, and ‘DD = P * D’, in
     which P is a permutation matrix and D is a diagonal matrix of
     powers of two.  This allows the equilibration to be computed
     without round-off.  Results of eigenvalue calculation are typically
     improved by balancing first.

     If two output values are requested, ‘balance’ returns the diagonal
     D and the permutation P separately as vectors.  In this case, ‘DD =
     eye(n)(:,P) * diag (D)’, where n is the matrix size.

     If four output values are requested, compute ‘AA = CC*A*DD’ and ‘BB
     = CC*B*DD’, in which AA and BB have nonzero elements of
     approximately the same magnitude and CC and DD are permuted
     diagonal matrices as in DD for the algebraic eigenvalue problem.

     The eigenvalue balancing option OPT may be one of:

     "noperm", "S"
          Scale only; do not permute.

     "noscal", "P"
          Permute only; do not scale.

     Algebraic eigenvalue balancing uses standard LAPACK routines.

     Generalized eigenvalue problem balancing uses Ward’s algorithm
     (SIAM Journal on Scientific and Statistical Computing, 1981).

 -- : BW = bandwidth (A, TYPE)
 -- : [LOWER, UPPER] = bandwidth (A)
     Compute the bandwidth of A.

     The TYPE argument is the string "lower" for the lower bandwidth and
     "upper" for the upper bandwidth.  If no TYPE is specified return
     both the lower and upper bandwidth of A.

     The lower/upper bandwidth of a matrix is the number of
     subdiagonals/superdiagonals with nonzero entries.

     See also: *note isbanded: XREFisbanded, *note isdiag: XREFisdiag,
     *note istril: XREFistril, *note istriu: XREFistriu.

 -- : cond (A)
 -- : cond (A, P)
     Compute the P-norm condition number of a matrix with respect to
     inversion.

     ‘cond (A)’ is defined as ‘norm (A, P) * norm (inv (A), P)’.

     By default, ‘P = 2’ is used which implies a (relatively slow)
     singular value decomposition.  Other possible selections are ‘P =
     1, Inf, "fro"’ which are generally faster.  See ‘norm’ for a full
     discussion of possible P values.

     The condition number of a matrix quantifies the sensitivity of the
     matrix inversion operation when small changes are made to matrix
     elements.  Ideally the condition number will be close to 1.  When
     the number is large this indicates small changes (such as underflow
     or round-off error) will produce large changes in the resulting
     output.  In such cases the solution results from numerical
     computing are not likely to be accurate.

     See also: *note condest: XREFcondest, *note rcond: XREFrcond, *note
     condeig: XREFcondeig, *note norm: XREFnorm, *note svd: XREFsvd.

 -- : C = condeig (A)
 -- : [V, LAMBDA, C] = condeig (A)
     Compute condition numbers of a matrix with respect to eigenvalues.

     The condition numbers are the reciprocals of the cosines of the
     angles between the left and right eigenvectors; Large values
     indicate that the matrix has multiple distinct eigenvalues.

     The input A must be a square numeric matrix.

     The outputs are:

        • C is a vector of condition numbers for the eigenvalues of A.

        • V is the matrix of right eigenvectors of A.  The result is
          equivalent to calling ‘[V, LAMBDA] = eig (A)’.

        • LAMBDA is the diagonal matrix of eigenvalues of A.  The result
          is equivalent to calling ‘[V, LAMBDA] = eig (A)’.

     Example

          a = [1, 2; 3, 4];
          c = condeig (a)
            ⇒ c =
                 1.0150
                 1.0150

     See also: *note eig: XREFeig, *note cond: XREFcond, *note balance:
     XREFbalance.

 -- : det (A)
 -- : [D, RCOND] = det (A)
     Compute the determinant of A.

     Return an estimate of the reciprocal condition number if requested.

     Programming Notes: Routines from LAPACK are used for full matrices
     and code from UMFPACK is used for sparse matrices.

     The determinant should not be used to check a matrix for
     singularity.  For that, use any of the condition number functions:
     ‘cond’, ‘condest’, ‘rcond’.

     See also: *note cond: XREFcond, *note condest: XREFcondest, *note
     rcond: XREFrcond.

 -- : LAMBDA = eig (A)
 -- : LAMBDA = eig (A, B)
 -- : [V, LAMBDA] = eig (A)
 -- : [V, LAMBDA] = eig (A, B)
 -- : [V, LAMBDA, W] = eig (A)
 -- : [V, LAMBDA, W] = eig (A, B)
 -- : [...] = eig (A, BALANCEOPTION)
 -- : [...] = eig (A, B, ALGORITHM)
 -- : [...] = eig (..., EIGVALOPTION)
     Compute the eigenvalues (LAMBDA) and optionally the right
     eigenvectors (V) and the left eigenvectors (W) of a matrix or pair
     of matrices.

     The flag BALANCEOPTION can be one of:

     "balance" (default)
          Preliminary balancing is on.

     "nobalance"
          Disables preliminary balancing.

     The flag EIGVALOPTION can be one of:

     "matrix"
          Return the eigenvalues in a diagonal matrix.  (default if 2 or
          3 outputs are requested)

     "vector"
          Return the eigenvalues in a column vector.  (default if only 1
          output is requested, e.g., LAMBDA = eig (A))

     The flag ALGORITHM can be one of:

     "chol"
          Use the Cholesky factorization of B. (default if A is
          symmetric (Hermitian) and B is symmetric (Hermitian) positive
          definite)

     "qz"
          Use the QZ algorithm.  (used whenever A or B are not
          symmetric)

                            no flag           chol              qz
     -----------------------------------------------------------------------------
     both are symmetric     "chol"            "chol"            "qz"
     at least one is not    "qz"              "qz"              "qz"
     symmetric

     The eigenvalues returned by ‘eig’ are not ordered.

     See also: *note eigs: XREFeigs, *note svd: XREFsvd.

 -- : G = givens (X, Y)
 -- : [C, S] = givens (X, Y)
     Compute the Givens rotation matrix G.

     The Givens matrix is a 2-by-2 orthogonal matrix

          G = [ C , S
               -S', C]

     such that

          G * [X; Y] = [*; 0]

     with X and Y scalars.

     If two output arguments are requested, return the factors C and S
     rather than the Givens rotation matrix.

     For example:

          givens (1, 1)
             ⇒   0.70711   0.70711
                 -0.70711   0.70711

     Note: The Givens matrix represents a counterclockwise rotation of a
     2-D plane and can be used to introduce zeros into a matrix prior to
     complete factorization.

     See also: *note planerot: XREFplanerot, *note qr: XREFqr.

 -- : S = gsvd (A, B)
 -- : [U, V, X, C, S] = gsvd (A, B)
 -- : [U, V, X, C, S] = gsvd (A, B, 0)
     Compute the generalized singular value decomposition of (A, B).

     The generalized singular value decomposition is defined by the
     following relations:

          A = U*C*X'
          B = V*S*X'
          C'*C + S'*S = eye (columns (A))

     The function ‘gsvd’ normally returns just the vector of generalized
     singular values ‘sqrt (diag (C'*C) ./ diag (S'*S))’.  If asked for
     five return values, it also computes U, V, X, and C.

     If the optional third input is present, ‘gsvd’ constructs the
     "economy-sized" decomposition where the number of columns of U, V
     and the number of rows of C, S is less than or equal to the number
     of columns of A.  This option is not yet implemented.

     Programming Note: the code is a wrapper to the corresponding LAPACK
     dggsvd and zggsvd routines.

     See also: *note svd: XREFsvd.

 -- : [G, Y] = planerot (X)
     Compute the Givens rotation matrix for the two-element column
     vector X.

     The Givens matrix is a 2-by-2 orthogonal matrix

          G = [ C , S
               -S', C]

     such that

          Y = G * [X(1); X(2)] ≡ [*; 0]

     Note: The Givens matrix represents a counterclockwise rotation of a
     2-D plane and can be used to introduce zeros into a matrix prior to
     complete factorization.

     See also: *note givens: XREFgivens, *note qr: XREFqr.

 -- : X = inv (A)
 -- : [X, RCOND] = inv (A)
     Compute the inverse of the square matrix A.

     Return an estimate of the reciprocal condition number if requested,
     otherwise warn of an ill-conditioned matrix if the reciprocal
     condition number is small.

     In general it is best to avoid calculating the inverse of a matrix
     directly.  For example, it is both faster and more accurate to
     solve systems of equations (A*x = b) with ‘Y = A \ b’, rather than
     ‘Y = inv (A) * b’.

     If called with a sparse matrix, then in general X will be a full
     matrix requiring significantly more storage.  Avoid forming the
     inverse of a sparse matrix if possible.

     See also: *note ldivide: XREFldivide, *note rdivide: XREFrdivide,
     *note pinv: XREFpinv.

 -- : X = linsolve (A, B)
 -- : X = linsolve (A, B, OPTS)
 -- : [X, R] = linsolve (...)
     Solve the linear system ‘A*x = b’.

     With no options, this function is equivalent to the left division
     operator (‘x = A \ b’) or the matrix-left-divide function
     (‘x = mldivide (A, b)’).

     Octave ordinarily examines the properties of the matrix A and
     chooses a solver that best matches the matrix.  By passing a
     structure OPTS to ‘linsolve’ you can inform Octave directly about
     the matrix A.  In this case Octave will skip the matrix examination
     and proceed directly to solving the linear system.

     *Warning:* If the matrix A does not have the properties listed in
     the OPTS structure then the result will not be accurate AND no
     warning will be given.  When in doubt, let Octave examine the
     matrix and choose the appropriate solver as this step takes little
     time and the result is cached so that it is only done once per
     linear system.

     Possible OPTS fields (set value to true/false):

     LT
          A is lower triangular

     UT
          A is upper triangular

     UHESS
          A is upper Hessenberg (currently makes no difference)

     SYM
          A is symmetric or complex Hermitian (currently makes no
          difference)

     POSDEF
          A is positive definite

     RECT
          A is general rectangular (currently makes no difference)

     TRANSA
          Solve ‘A'*x = b’ if true rather than ‘A*x = b’

     The optional second output R is the inverse condition number of A
     (zero if matrix is singular).

     See also: *note mldivide: XREFmldivide, *note matrix_type:
     XREFmatrix_type, *note rcond: XREFrcond.

 -- : TYPE = matrix_type (A)
 -- : TYPE = matrix_type (A, "nocompute")
 -- : A = matrix_type (A, TYPE)
 -- : A = matrix_type (A, "upper", PERM)
 -- : A = matrix_type (A, "lower", PERM)
 -- : A = matrix_type (A, "banded", NL, NU)
     Identify the matrix type or mark a matrix as a particular type.

     This allows more rapid solutions of linear equations involving A to
     be performed.

     Called with a single argument, ‘matrix_type’ returns the type of
     the matrix and caches it for future use.

     Called with more than one argument, ‘matrix_type’ allows the type
     of the matrix to be defined.

     If the option "nocompute" is given, the function will not attempt
     to guess the type if it is still unknown.  This is useful for
     debugging purposes.

     The possible matrix types depend on whether the matrix is full or
     sparse, and can be one of the following

     "unknown"
          Remove any previously cached matrix type, and mark type as
          unknown.

     "full"
          Mark the matrix as full.

     "positive definite"
          Probable full positive definite matrix.

     "diagonal"
          Diagonal matrix.  (Sparse matrices only)

     "permuted diagonal"
          Permuted Diagonal matrix.  The permutation does not need to be
          specifically indicated, as the structure of the matrix
          explicitly gives this.  (Sparse matrices only)

     "upper"
          Upper triangular.  If the optional third argument PERM is
          given, the matrix is assumed to be a permuted upper triangular
          with the permutations defined by the vector PERM.

     "lower"
          Lower triangular.  If the optional third argument PERM is
          given, the matrix is assumed to be a permuted lower triangular
          with the permutations defined by the vector PERM.

     "banded"
     "banded positive definite"
          Banded matrix with the band size of NL below the diagonal and
          NU above it.  If NL and NU are 1, then the matrix is
          tridiagonal and treated with specialized code.  In addition
          the matrix can be marked as probably a positive definite.
          (Sparse matrices only)

     "singular"
          The matrix is assumed to be singular and will be treated with
          a minimum norm solution.

     Note that the matrix type will be discovered automatically on the
     first attempt to solve a linear equation involving A.  Therefore
     ‘matrix_type’ is only useful to give Octave hints of the matrix
     type.  Incorrectly defining the matrix type will result in
     incorrect results from solutions of linear equations; it is
     entirely *the responsibility of the user* to correctly identify the
     matrix type.

     Also, the test for positive definiteness is a low-cost test for a
     Hermitian matrix with a real positive diagonal.  This does not
     guarantee that the matrix is positive definite, but only that it is
     a probable candidate.  When such a matrix is factorized, a
     Cholesky factorization is first attempted, and if that fails the
     matrix is then treated with an LU factorization.  Once the matrix
     has been factorized, ‘matrix_type’ will return the correct
     classification of the matrix.

 -- : norm (A)
 -- : norm (A, P)
 -- : norm (A, P, OPT)
     Compute the p-norm of the matrix A.

     If the second argument is not given, ‘p = 2’ is used.

     If A is a matrix (or sparse matrix):

     P = ‘1’
          1-norm, the largest column sum of the absolute values of A.

     P = ‘2’
          Largest singular value of A.

     P = ‘Inf’ or "inf"
          Infinity norm, the largest row sum of the absolute values of
          A.

     P = "fro"
          Frobenius norm of A, ‘sqrt (sum (diag (A' * A)))’.

     other P, ‘P > 1’
          maximum ‘norm (A*x, p)’ such that ‘norm (x, p) == 1’

     If A is a vector or a scalar:

     P = ‘Inf’ or "inf"
          ‘max (abs (A))’.

     P = ‘-Inf’
          ‘min (abs (A))’.

     P = "fro"
          Frobenius norm of A, ‘sqrt (sumsq (abs (A)))’.

     P = 0
          Hamming norm—the number of nonzero elements.

     other P, ‘P > 1’
          p-norm of A, ‘(sum (abs (A) .^ P)) ^ (1/P)’.

     other P ‘P < 1’
          the p-pseudonorm defined as above.

     If OPT is the value "rows", treat each row as a vector and compute
     its norm.  The result is returned as a column vector.  Similarly,
     if OPT is "columns" or "cols" then compute the norms of each column
     and return a row vector.

     See also: *note normest: XREFnormest, *note normest1: XREFnormest1,
     *note vecnorm: XREFvecnorm, *note cond: XREFcond, *note svd:
     XREFsvd.

 -- : null (A)
 -- : null (A, TOL)
     Return an orthonormal basis of the null space of A.

     The dimension of the null space is taken as the number of singular
     values of A not greater than TOL.  If the argument TOL is missing,
     it is computed as

          max (size (A)) * max (svd (A)) * eps

     See also: *note orth: XREForth.

 -- : orth (A)
 -- : orth (A, TOL)
     Return an orthonormal basis of the range space of A.

     The dimension of the range space is taken as the number of singular
     values of A greater than TOL.  If the argument TOL is missing, it
     is computed as

          max (size (A)) * max (svd (A)) * eps

     See also: *note null: XREFnull.

 -- : [Y, H] = mgorth (X, V)
     Orthogonalize a given column vector X with respect to a set of
     orthonormal vectors comprising the columns of V using the modified
     Gram-Schmidt method.

     On exit, Y is a unit vector such that:

            norm (Y) = 1
            V' * Y = 0
            X = [V, Y]*H'

 -- : pinv (X)
 -- : pinv (X, TOL)
     Return the Moore-Penrose pseudoinverse of X.

     Singular values less than TOL are ignored.

     If the second argument is omitted, it is taken to be

          tol = max ([rows(X), columns(X)]) * norm (X) * eps

     See also: *note inv: XREFinv, *note ldivide: XREFldivide.

 -- : rank (A)
 -- : rank (A, TOL)
     Compute the rank of matrix A, using the singular value
     decomposition.

     The rank is taken to be the number of singular values of A that are
     greater than the specified tolerance TOL.  If the second argument
     is omitted, it is taken to be

          tol = max (size (A)) * sigma(1) * eps;

     where ‘eps’ is machine precision and ‘sigma(1)’ is the largest
     singular value of A.

     The rank of a matrix is the number of linearly independent rows or
     columns and equals the dimension of the row and column space.  The
     function ‘orth’ may be used to compute an orthonormal basis of the
     column space.

     For testing if a system ‘A*X = B’ of linear equations is solvable,
     one can use

          rank (A) == rank ([A B])

     In this case, ‘X = A \ B’ finds a particular solution X.  The
     general solution is X plus the null space of matrix A.  The
     function ‘null’ may be used to compute a basis of the null space.

     Example:

          A = [1 2 3
               4 5 6
               7 8 9];
          rank (A)
            ⇒ 2

     In this example, the number of linearly independent rows is only 2
     because the final row is a linear combination of the first two
     rows:

          A(3,:) == -A(1,:) + 2 * A(2,:)

     See also: *note null: XREFnull, *note orth: XREForth, *note sprank:
     XREFsprank, *note svd: XREFsvd, *note eps: XREFeps.

 -- : C = rcond (A)
     Compute the 1-norm estimate of the reciprocal condition number as
     returned by LAPACK.

     If the matrix is well-conditioned then C will be near 1 and if the
     matrix is poorly conditioned it will be close to 0.

     The matrix A must not be sparse.  If the matrix is sparse then
     ‘condest (A)’ or ‘rcond (full (A))’ should be used instead.

     See also: *note cond: XREFcond, *note condest: XREFcondest.

 -- : trace (A)
     Compute the trace of A, the sum of the elements along the main
     diagonal.

     The implementation is straightforward: ‘sum (diag (A))’.

     See also: *note eig: XREFeig.

 -- : rref (A)
 -- : rref (A, TOL)
 -- : [R, K] = rref (...)
     Return the reduced row echelon form of A.

     TOL defaults to ‘eps * max (size (A)) * norm (A, inf)’.

     The optional return argument K contains the vector of "bound
     variables", which are those columns on which elimination has been
     performed.

 -- : N = vecnorm (A)
 -- : N = vecnorm (A, P)
 -- : N = vecnorm (A, P, DIM)
     Return the p-norm of the elements of A along dimension DIM.

     The p-norm of a vector is defined as

          P-NORM (A, P) = sum (abs (A) .^ P)) ^ (1/P)

     If P is omitted it defaults to 2 (Euclidean norm).  P can be ‘Inf’
     (absolute value of largest element).

     If DIM is omitted the first non-singleton dimension is used.

     See also: *note norm: XREFnorm.


File: octave.info,  Node: Matrix Factorizations,  Next: Functions of a Matrix,  Prev: Basic Matrix Functions,  Up: Linear Algebra

18.3 Matrix Factorizations
==========================

 -- : R = chol (A)
 -- : [R, P] = chol (A)
 -- : [R, P, Q] = chol (A)
 -- : [R, P, Q] = chol (A, "vector")
 -- : [L, ...] = chol (..., "lower")
 -- : [R, ...] = chol (..., "upper")
     Compute the upper Cholesky factor, R, of the real symmetric or
     complex Hermitian positive definite matrix A.

     The upper Cholesky factor R is computed by using the upper
     triangular part of matrix A and is defined by

          R' * R = A.

     Calling ‘chol’ using the optional "upper" flag has the same
     behavior.  In contrast, using the optional "lower" flag, ‘chol’
     returns the lower triangular factorization, computed by using the
     lower triangular part of matrix A, such that

          L * L' = A.

     Called with one output argument ‘chol’ fails if matrix A is not
     positive definite.  Note that if matrix A is not real symmetric or
     complex Hermitian then the lower triangular part is considered to
     be the (complex conjugate) transpose of the upper triangular part,
     or vice versa, given the "lower" flag.

     Called with two or more output arguments P flags whether the matrix
     A was positive definite and ‘chol’ does not fail.  A zero value of
     P indicates that matrix A is positive definite and R gives the
     factorization.  Otherwise, P will have a positive value.

     If called with three output arguments matrix A must be sparse and a
     sparsity preserving row/column permutation is applied to matrix A
     prior to the factorization.  That is R is the factorization of
     ‘A(Q,Q)’ such that

          R' * R = Q' * A * Q.

     The sparsity preserving permutation is generally returned as a
     matrix.  However, given the optional flag "vector", Q will be
     returned as a vector such that

          R' * R = A(Q, Q).

     In general the lower triangular factorization is significantly
     faster for sparse matrices.

     See also: *note hess: XREFhess, *note lu: XREFlu, *note qr: XREFqr,
     *note qz: XREFqz, *note schur: XREFschur, *note svd: XREFsvd, *note
     ichol: XREFichol, *note cholinv: XREFcholinv, *note chol2inv:
     XREFchol2inv, *note cholupdate: XREFcholupdate, *note cholinsert:
     XREFcholinsert, *note choldelete: XREFcholdelete, *note cholshift:
     XREFcholshift.

 -- : cholinv (A)
     Compute the inverse of the symmetric positive definite matrix A
     using the Cholesky factorization.

     See also: *note chol: XREFchol, *note chol2inv: XREFchol2inv, *note
     inv: XREFinv.

 -- : chol2inv (U)
     Invert a symmetric, positive definite square matrix from its
     Cholesky decomposition, U.

     Note that U should be an upper-triangular matrix with positive
     diagonal elements.  ‘chol2inv (U)’ provides ‘inv (U'*U)’ but it is
     much faster than using ‘inv’.

     See also: *note chol: XREFchol, *note cholinv: XREFcholinv, *note
     inv: XREFinv.

 -- : [R1, INFO] = cholupdate (R, U, OP)
     Update or downdate a Cholesky factorization.

     Given an upper triangular matrix R and a column vector U, attempt
     to determine another upper triangular matrix R1 such that

        • R1’*R1 = R’*R + U*U’ if OP is "+"

        • R1’*R1 = R’*R - U*U’ if OP is "-"

     If OP is "-", INFO is set to

        • 0 if the downdate was successful,

        • 1 if R’*R - U*U’ is not positive definite,

        • 2 if R is singular.

     If INFO is not present, an error message is printed in cases 1 and
     2.

     See also: *note chol: XREFchol, *note cholinsert: XREFcholinsert,
     *note choldelete: XREFcholdelete, *note cholshift: XREFcholshift.

 -- : R1 = cholinsert (R, J, U)
 -- : [R1, INFO] = cholinsert (R, J, U)
     Update a Cholesky factorization given a row or column to insert in
     the original factored matrix.

     Given a Cholesky factorization of a real symmetric or complex
     Hermitian positive definite matrix A = R’*R, R upper triangular,
     return the Cholesky factorization of A1, where A1(p,p) = A,
     A1(:,j) = A1(j,:)’ = u and p = [1:j-1,j+1:n+1].  u(j) should be
     positive.

     On return, INFO is set to

        • 0 if the insertion was successful,

        • 1 if A1 is not positive definite,

        • 2 if R is singular.

     If INFO is not present, an error message is printed in cases 1 and
     2.

     See also: *note chol: XREFchol, *note cholupdate: XREFcholupdate,
     *note choldelete: XREFcholdelete, *note cholshift: XREFcholshift.

 -- : R1 = choldelete (R, J)
     Update a Cholesky factorization given a row or column to delete
     from the original factored matrix.

     Given a Cholesky factorization of a real symmetric or complex
     Hermitian positive definite matrix A = R’*R, R upper triangular,
     return the Cholesky factorization of A(p,p), where
     p = [1:j-1,j+1:n+1].

     See also: *note chol: XREFchol, *note cholupdate: XREFcholupdate,
     *note cholinsert: XREFcholinsert, *note cholshift: XREFcholshift.

 -- : R1 = cholshift (R, I, J)
     Update a Cholesky factorization given a range of columns to shift
     in the original factored matrix.

     Given a Cholesky factorization of a real symmetric or complex
     Hermitian positive definite matrix A = R’*R, R upper triangular,
     return the Cholesky factorization of A(p,p), where p is the
     permutation
     ‘p = [1:i-1, shift(i:j, 1), j+1:n]’ if I < J
     or
     ‘p = [1:j-1, shift(j:i,-1), i+1:n]’ if J < I.

     See also: *note chol: XREFchol, *note cholupdate: XREFcholupdate,
     *note cholinsert: XREFcholinsert, *note choldelete: XREFcholdelete.

 -- : H = hess (A)
 -- : [P, H] = hess (A)
     Compute the Hessenberg decomposition of the matrix A.

     The Hessenberg decomposition is ‘P * H * P' = A’ where P is a
     square unitary matrix (‘P' * P = I’, using complex-conjugate
     transposition) and H is upper Hessenberg (‘H(i, j) = 0 forall i >
     j+1)’.

     The Hessenberg decomposition is usually used as the first step in
     an eigenvalue computation, but has other applications as well (see
     Golub, Nash, and Van Loan, IEEE Transactions on Automatic Control,
     1979).

     See also: *note eig: XREFeig, *note chol: XREFchol, *note lu:
     XREFlu, *note qr: XREFqr, *note qz: XREFqz, *note schur: XREFschur,
     *note svd: XREFsvd.

 -- : [L, U] = lu (A)
 -- : [L, U, P] = lu (A)
 -- : [L, U, P, Q] = lu (S)
 -- : [L, U, P, Q, R] = lu (S)
 -- : [...] = lu (S, THRES)
 -- : Y = lu (...)
 -- : [...] = lu (..., "vector")
     Compute the LU decomposition of A.

     If A is full then subroutines from LAPACK are used, and if A is
     sparse then UMFPACK is used.

     The result is returned in a permuted form, according to the
     optional return value P.  For example, given the matrix ‘a = [1, 2;
     3, 4]’,

          [l, u, p] = lu (A)

     returns

          l =

            1.00000  0.00000
            0.33333  1.00000

          u =

            3.00000  4.00000
            0.00000  0.66667

          p =

            0  1
            1  0

     The matrix is not required to be square.

     When called with two or three output arguments and a sparse input
     matrix, ‘lu’ does not attempt to perform sparsity preserving column
     permutations.  Called with a fourth output argument, the sparsity
     preserving column transformation Q is returned, such that ‘P * A *
     Q = L * U’.  This is the *preferred* way to call ‘lu’ with sparse
     input matrices.

     Called with a fifth output argument and a sparse input matrix, ‘lu’
     attempts to use a scaling factor R on the input matrix such that ‘P
     * (R \ A) * Q = L * U’.  This typically leads to a sparser and more
     stable factorization.

     An additional input argument THRES, that defines the pivoting
     threshold can be given.  THRES can be a scalar, in which case it
     defines the UMFPACK pivoting tolerance for both symmetric and
     unsymmetric cases.  If THRES is a 2-element vector, then the first
     element defines the pivoting tolerance for the unsymmetric UMFPACK
     pivoting strategy and the second for the symmetric strategy.  By
     default, the values defined by ‘spparms’ are used ([0.1, 0.001]).

     Given the string argument "vector", ‘lu’ returns the values of P
     and Q as vector values, such that for full matrix, ‘A(P,:) = L *
     U’, and ‘R(P,:) * A(:,Q) = L * U’.

     With two output arguments, returns the permuted forms of the upper
     and lower triangular matrices, such that ‘A = L * U’.  With one
     output argument Y, then the matrix returned by the LAPACK routines
     is returned.  If the input matrix is sparse then the matrix L is
     embedded into U to give a return value similar to the full case.
     For both full and sparse matrices, ‘lu’ loses the permutation
     information.

     See also: *note luupdate: XREFluupdate, *note ilu: XREFilu, *note
     chol: XREFchol, *note hess: XREFhess, *note qr: XREFqr, *note qz:
     XREFqz, *note schur: XREFschur, *note svd: XREFsvd.

 -- : [L, U] = luupdate (L, U, X, Y)
 -- : [L, U, P] = luupdate (L, U, P, X, Y)
     Given an LU factorization of a real or complex matrix A = L*U,
     L lower unit trapezoidal and U upper trapezoidal, return the
     LU factorization of A + X*Y.’, where X and Y are column vectors
     (rank-1 update) or matrices with equal number of columns (rank-k
     update).

     Optionally, row-pivoted updating can be used by supplying a row
     permutation (pivoting) matrix P; in that case, an updated
     permutation matrix is returned.  Note that if L, U, P is a pivoted
     LU factorization as obtained by ‘lu’:

          [L, U, P] = lu (A);

     then a factorization of A+X*Y.’ can be obtained either as

          [L1, U1] = lu (L, U, P*X, Y)

     or

          [L1, U1, P1] = lu (L, U, P, X, Y)

     The first form uses the unpivoted algorithm, which is faster, but
     less stable.  The second form uses a slower pivoted algorithm,
     which is more stable.

     The matrix case is done as a sequence of rank-1 updates; thus, for
     large enough k, it will be both faster and more accurate to
     recompute the factorization from scratch.

     See also: *note lu: XREFlu, *note cholupdate: XREFcholupdate, *note
     qrupdate: XREFqrupdate.

 -- : [Q, R] = qr (A)
 -- : [Q, R, P] = qr (A) # non-sparse A
 -- : X = qr (A) # non-sparse A
 -- : R = qr (A) # sparse A
 -- : [C, R] = qr (A, B)
 -- : [...] = qr (..., 0)
 -- : [...] = qr (..., "vector")
 -- : [...] = qr (..., "matrix")
     Compute the QR factorization of A, using standard LAPACK
     subroutines.

     The QR factorization is

          Q * R = A

     where Q is an orthogonal matrix and R is upper triangular.

     For example, given the matrix ‘A = [1, 2; 3, 4]’,

          [Q, R] = qr (A)

     returns

          Q =

            -0.31623  -0.94868
            -0.94868   0.31623

          R =

            -3.16228  -4.42719
             0.00000  -0.63246

     which multiplied together return the original matrix

          Q * R
            ⇒
               1.0000   2.0000
               3.0000   4.0000

     If just a single return value is requested then it is either R, if
     A is sparse, or X, such that ‘R = triu (X)’ if A is full.  (Note:
     unlike most commands, the single return value is not the first
     return value when multiple values are requested.)

     If the matrix A is full, and a third output P is requested, then
     ‘qr’ calculates the permuted QR factorization

          Q * R = A * P

     where Q is an orthogonal matrix, R is upper triangular, and P is a
     permutation matrix.

     The permuted QR factorization has the additional property that the
     diagonal entries of R are ordered by decreasing magnitude.  In
     other words, ‘abs (diag (R))’ will be ordered from largest to
     smallest.

     For example, given the matrix ‘A = [1, 2; 3, 4]’,

          [Q, R, P] = qr (A)

     returns

          Q =

            -0.44721  -0.89443
            -0.89443   0.44721

          R =

            -4.47214  -3.13050
             0.00000   0.44721

          P =

             0  1
             1  0

     If the input matrix A is sparse then the sparse QR factorization is
     computed using CSPARSE.  Because the matrix Q is, in general, a
     full matrix, it is recommended to request only one return value R.
     In that case, the computation avoids the construction of Q and
     returns R such that ‘R = chol (A' * A)’.

     If an additional matrix B is supplied and two return values are
     requested, then ‘qr’ returns C, where ‘C = Q' * B’.  This allows
     the least squares approximation of ‘A \ B’ to be calculated as

          [C, R] = qr (A, B)
          X = R \ C

     If the final argument is the string "vector" then P is a
     permutation vector (of the columns of A) instead of a permutation
     matrix.  In this case, the defining relationship is

          Q * R = A(:, P)

     The default, however, is to return a permutation matrix and this
     may be explicitly specified by using a final argument of "matrix".

     If the final argument is the scalar 0 an "economy" factorization is
     returned.  When the original matrix A has size MxN and M > N then
     the "economy" factorization will calculate just N rows in R and N
     columns in Q and omit the zeros in R.  If M ≤ N there is no
     difference between the economy and standard factorizations.  When
     calculating an "economy" factorization the output P is always a
     vector rather than a matrix.

     Background: The QR factorization has applications in the solution
     of least squares problems

          min norm (A*x - b)

     for overdetermined systems of equations (i.e., A is a tall, thin
     matrix).

     The permuted QR factorization ‘[Q, R, P] = qr (A)’ allows the
     construction of an orthogonal basis of ‘span (A)’.

     See also: *note chol: XREFchol, *note hess: XREFhess, *note lu:
     XREFlu, *note qz: XREFqz, *note schur: XREFschur, *note svd:
     XREFsvd, *note qrupdate: XREFqrupdate, *note qrinsert:
     XREFqrinsert, *note qrdelete: XREFqrdelete, *note qrshift:
     XREFqrshift.

 -- : [Q1, R1] = qrupdate (Q, R, U, V)
     Update a QR factorization given update vectors or matrices.

     Given a QR factorization of a real or complex matrix A = Q*R,
     Q unitary and R upper trapezoidal, return the QR factorization of
     A + U*V’, where U and V are column vectors (rank-1 update) or
     matrices with equal number of columns (rank-k update).  Notice that
     the latter case is done as a sequence of rank-1 updates; thus, for
     k large enough, it will be both faster and more accurate to
     recompute the factorization from scratch.

     The QR factorization supplied may be either full (Q is square) or
     economized (R is square).

     See also: *note qr: XREFqr, *note qrinsert: XREFqrinsert, *note
     qrdelete: XREFqrdelete, *note qrshift: XREFqrshift.

 -- : [Q1, R1] = qrinsert (Q, R, J, X, ORIENT)
     Update a QR factorization given a row or column to insert in the
     original factored matrix.

     Given a QR factorization of a real or complex matrix A = Q*R,
     Q unitary and R upper trapezoidal, return the QR factorization of
     [A(:,1:j-1) x A(:,j:n)], where U is a column vector to be inserted
     into A (if ORIENT is "col"), or the QR factorization of
     [A(1:j-1,:);x;A(:,j:n)], where X is a row vector to be inserted
     into A (if ORIENT is "row").

     The default value of ORIENT is "col".  If ORIENT is "col", U may be
     a matrix and J an index vector resulting in the QR factorization of
     a matrix B such that B(:,J) gives U and B(:,J) = [] gives A.
     Notice that the latter case is done as a sequence of k insertions;
     thus, for k large enough, it will be both faster and more accurate
     to recompute the factorization from scratch.

     If ORIENT is "col", the QR factorization supplied may be either
     full (Q is square) or economized (R is square).

     If ORIENT is "row", full factorization is needed.

     See also: *note qr: XREFqr, *note qrupdate: XREFqrupdate, *note
     qrdelete: XREFqrdelete, *note qrshift: XREFqrshift.

 -- : [Q1, R1] = qrdelete (Q, R, J, ORIENT)
     Update a QR factorization given a row or column to delete from the
     original factored matrix.

     Given a QR factorization of a real or complex matrix A = Q*R,
     Q unitary and R upper trapezoidal, return the QR factorization of
     [A(:,1:j-1), U, A(:,j:n)], where U is a column vector to be
     inserted into A (if ORIENT is "col"), or the QR factorization of
     [A(1:j-1,:);X;A(:,j:n)], where X is a row ORIENT is "row").  The
     default value of ORIENT is "col".

     If ORIENT is "col", J may be an index vector resulting in the
     QR factorization of a matrix B such that A(:,J) = [] gives B.
     Notice that the latter case is done as a sequence of k deletions;
     thus, for k large enough, it will be both faster and more accurate
     to recompute the factorization from scratch.

     If ORIENT is "col", the QR factorization supplied may be either
     full (Q is square) or economized (R is square).

     If ORIENT is "row", full factorization is needed.

     See also: *note qr: XREFqr, *note qrupdate: XREFqrupdate, *note
     qrinsert: XREFqrinsert, *note qrshift: XREFqrshift.

 -- : [Q1, R1] = qrshift (Q, R, I, J)
     Update a QR factorization given a range of columns to shift in the
     original factored matrix.

     Given a QR factorization of a real or complex matrix A = Q*R,
     Q unitary and R upper trapezoidal, return the QR factorization of
     A(:,p), where p is the permutation
     ‘p = [1:i-1, shift(i:j, 1), j+1:n]’ if I < J
     or
     ‘p = [1:j-1, shift(j:i,-1), i+1:n]’ if J < I.

     See also: *note qr: XREFqr, *note qrupdate: XREFqrupdate, *note
     qrinsert: XREFqrinsert, *note qrdelete: XREFqrdelete.

 -- : LAMBDA = qz (A, B)
 -- : [AA, BB, Q, Z, V, W, LAMBDA] = qz (A, B)
 -- : [AA, BB, Z] = qz (A, B, OPT)
 -- : [AA, BB, Z, LAMBDA] = qz (A, B, OPT)
     Compute the QZ decomposition of a generalized eigenvalue problem.

     The generalized eigenvalue problem is defined as

     A x = LAMBDA B x

     There are three calling forms of the function:

       1. ‘LAMBDA = qz (A, B)’

          Compute the generalized eigenvalues LAMBDA.

       2. ‘[AA, BB, Q, Z, V, W, LAMBDA] = qz (A, B)’

          Compute QZ decomposition, generalized eigenvectors, and
          generalized eigenvalues.


               A * V = B * V * diag (LAMBDA)
               W' * A = diag (LAMBDA) * W' * B
               AA = Q * A * Z, BB = Q * B * Z


          with Q and Z orthogonal (unitary for complex case).

       3. ‘[AA, BB, Z {, LAMBDA}] = qz (A, B, OPT)’

          As in form 2 above, but allows ordering of generalized
          eigenpairs for, e.g., solution of discrete time algebraic
          Riccati equations.  Form 3 is not available for complex
          matrices, and does not compute the generalized eigenvectors V,
          W, nor the orthogonal matrix Q.

          OPT
               for ordering eigenvalues of the GEP pencil.  The leading
               block of the revised pencil contains all eigenvalues that
               satisfy:

               "N"
                    unordered (default)

               "S"
                    small: leading block has all |LAMBDA| < 1

               "B"
                    big: leading block has all |LAMBDA| ≥ 1

               "-"
                    negative real part: leading block has all
                    eigenvalues in the open left half-plane

               "+"
                    non-negative real part: leading block has all
                    eigenvalues in the closed right half-plane

     Note: ‘qz’ performs permutation balancing, but not scaling (*note
     balance: XREFbalance.), which may be lead to less accurate results
     than ‘eig’.  The order of output arguments was selected for
     compatibility with MATLAB.

     See also: *note eig: XREFeig, *note ordeig: XREFordeig, *note
     balance: XREFbalance, *note lu: XREFlu, *note chol: XREFchol, *note
     hess: XREFhess, *note qr: XREFqr, *note qzhess: XREFqzhess, *note
     schur: XREFschur, *note svd: XREFsvd.

 -- : [AA, BB, Q, Z] = qzhess (A, B)
     Compute the Hessenberg-triangular decomposition of the matrix
     pencil ‘(A, B)’, returning ‘AA = Q * A * Z’, ‘BB = Q * B * Z’, with
     Q and Z orthogonal.

     For example:

          [aa, bb, q, z] = qzhess ([1, 2; 3, 4], [5, 6; 7, 8])
            ⇒ aa =
                -3.02244  -4.41741
                 0.92998   0.69749
            ⇒ bb =
                -8.60233  -9.99730
                 0.00000  -0.23250
            ⇒ q =
                -0.58124  -0.81373
                -0.81373   0.58124
            ⇒ z =
               Diagonal Matrix
                 1   0
                 0   1

     The Hessenberg-triangular decomposition is the first step in Moler
     and Stewart’s QZ decomposition algorithm.

     Algorithm taken from Golub and Van Loan, ‘Matrix Computations, 2nd
     edition’.

     See also: *note lu: XREFlu, *note chol: XREFchol, *note hess:
     XREFhess, *note qr: XREFqr, *note qz: XREFqz, *note schur:
     XREFschur, *note svd: XREFsvd.

 -- : S = schur (A)
 -- : S = schur (A, "real")
 -- : S = schur (A, "complex")
 -- : S = schur (A, OPT)
 -- : [U, S] = schur (...)
     Compute the Schur decomposition of A.

     The Schur decomposition is defined as

          S = U' * A * U

     where U is a unitary matrix (‘U'* U’ is identity) and S is upper
     triangular.  The eigenvalues of A (and S) are the diagonal elements
     of S.  If the matrix A is real, then the real Schur decomposition
     is computed, in which the matrix U is orthogonal and S is block
     upper triangular with blocks of size at most ‘2 x 2’ along the
     diagonal.  The diagonal elements of S (or the eigenvalues of the ‘2
     x 2’ blocks, when appropriate) are the eigenvalues of A and S.

     The default for real matrices is a real Schur decomposition.  A
     complex decomposition may be forced by passing the flag "complex".

     The eigenvalues are optionally ordered along the diagonal according
     to the value of OPT.  ‘OPT = "a"’ indicates that all eigenvalues
     with negative real parts should be moved to the leading block of S
     (used in ‘are’), ‘OPT = "d"’ indicates that all eigenvalues with
     magnitude less than one should be moved to the leading block of S
     (used in ‘dare’), and ‘OPT = "u"’, the default, indicates that no
     ordering of eigenvalues should occur.  The leading K columns of U
     always span the A-invariant subspace corresponding to the K leading
     eigenvalues of S.

     The Schur decomposition is used to compute eigenvalues of a square
     matrix, and has applications in the solution of algebraic Riccati
     equations in control (see ‘are’ and ‘dare’).

     See also: *note rsf2csf: XREFrsf2csf, *note ordschur: XREFordschur,
     *note ordeig: XREFordeig, *note lu: XREFlu, *note chol: XREFchol,
     *note hess: XREFhess, *note qr: XREFqr, *note qz: XREFqz, *note
     svd: XREFsvd.

 -- : [U, T] = rsf2csf (UR, TR)
     Convert a real, upper quasi-triangular Schur form TR to a complex,
     upper triangular Schur form T.

     Note that the following relations hold:

     UR * TR * UR’ = U * T * U’ and ‘U' * U’ is the identity matrix I.

     Note also that U and T are not unique.

     See also: *note schur: XREFschur.

 -- : [UR, SR] = ordschur (U, S, SELECT)
     Reorders the real Schur factorization (U,S) obtained with the
     ‘schur’ function, so that selected eigenvalues appear in the upper
     left diagonal blocks of the quasi triangular Schur matrix.

     The logical vector SELECT specifies the selected eigenvalues as
     they appear along S’s diagonal.

     For example, given the matrix ‘A = [1, 2; 3, 4]’, and its Schur
     decomposition

          [U, S] = schur (A)

     which returns

          U =

            -0.82456  -0.56577
             0.56577  -0.82456

          S =

            -0.37228  -1.00000
             0.00000   5.37228


     It is possible to reorder the decomposition so that the positive
     eigenvalue is in the upper left corner, by doing:

          [U, S] = ordschur (U, S, [0,1])

     See also: *note schur: XREFschur, *note ordeig: XREFordeig.

 -- : LAMBDA = ordeig (A)
 -- : LAMBDA = ordeig (A, B)
     Return the eigenvalues of quasi-triangular matrices in their order
     of appearance in the matrix A.

     The quasi-triangular matrix A is usually the result of a Schur
     factorization.  If called with a second input B then the
     generalized eigenvalues of the pair A, B are returned in the order
     of appearance of the matrix ‘A-LAMBDA*B’.  The pair A, B is usually
     the result of a QZ decomposition.

     See also: *note ordschur: XREFordschur, *note eig: XREFeig, *note
     schur: XREFschur, *note qz: XREFqz.

 -- : ANGLE = subspace (A, B)
     Determine the largest principal angle between two subspaces spanned
     by the columns of matrices A and B.

 -- : S = svd (A)
 -- : [U, S, V] = svd (A)
 -- : [U, S, V] = svd (A, "econ")
 -- : [U, S, V] = svd (A, 0)
     Compute the singular value decomposition of A.

     The singular value decomposition is defined by the relation

          A = U*S*V'

     The function ‘svd’ normally returns only the vector of singular
     values.  When called with three return values, it computes U, S,
     and V.  For example,

          svd (hilb (3))

     returns

          ans =

            1.4083189
            0.1223271
            0.0026873

     and

          [u, s, v] = svd (hilb (3))

     returns

          u =

            -0.82704   0.54745   0.12766
            -0.45986  -0.52829  -0.71375
            -0.32330  -0.64901   0.68867

          s =

            1.40832  0.00000  0.00000
            0.00000  0.12233  0.00000
            0.00000  0.00000  0.00269

          v =

            -0.82704   0.54745   0.12766
            -0.45986  -0.52829  -0.71375
            -0.32330  -0.64901   0.68867

     When given a second argument that is not 0, ‘svd’ returns an
     economy-sized decomposition, eliminating the unnecessary rows or
     columns of U or V.

     If the second argument is exactly 0, then the choice of
     decomposition is based on the matrix A.  If A has more rows than
     columns then an economy-sized decomposition is returned, otherwise
     a regular decomposition is calculated.

     Algorithm Notes: When calculating the full decomposition (left and
     right singular matrices in addition to singular values) there is a
     choice of two routines in LAPACK.  The default routine used by
     Octave is ‘gesvd’.  The alternative is ‘gesdd’ which is 5X faster,
     but may use more memory and may be inaccurate for some input
     matrices.  See the documentation for ‘svd_driver’ for more
     information on choosing a driver.

     See also: *note svd_driver: XREFsvd_driver, *note svds: XREFsvds,
     *note eig: XREFeig, *note lu: XREFlu, *note chol: XREFchol, *note
     hess: XREFhess, *note qr: XREFqr, *note qz: XREFqz.

 -- : VAL = svd_driver ()
 -- : OLD_VAL = svd_driver (NEW_VAL)
 -- : svd_driver (NEW_VAL, "local")
     Query or set the underlying LAPACK driver used by ‘svd’.

     Currently recognized values are "gesdd" and "gesvd".  The default
     is "gesvd".

     When called from inside a function with the "local" option, the
     variable is changed locally for the function and any subroutines it
     calls.  The original variable value is restored when exiting the
     function.

     Algorithm Notes: The LAPACK library provides two routines for
     calculating the full singular value decomposition (left and right
     singular matrices as well as singular values).  When calculating
     just the singular values the following discussion is not relevant.

     The newer ‘gesdd’ routine is based on a Divide-and-Conquer
     algorithm that is 5X faster than the alternative ‘gesvd’, which is
     based on QR factorization.  However, the new algorithm can use
     significantly more memory.  For an MxN input matrix the memory
     usage is of order O(min(M,N) ^ 2), whereas the alternative is of
     order O(max(M,N)).

     Beyond speed and memory issues, there have been instances where
     some input matrices were not accurately decomposed by ‘gesdd’.  See
     currently active bug <https://savannah.gnu.org/bugs/?55564>.  Until
     these accuracy issues are resolved in a new version of the LAPACK
     library, the default driver in Octave has been set to "gesvd".

     See also: *note svd: XREFsvd.

 -- : [HOUSV, BETA, ZER] = housh (X, J, Z)
     Compute Householder reflection vector HOUSV to reflect X to be the
     j-th column of identity, i.e.,

          (I - beta*housv*housv')x =  norm (x)*e(j) if x(j) < 0,
          (I - beta*housv*housv')x = -norm (x)*e(j) if x(j) >= 0

     Inputs

     X
          vector

     J
          index into vector

     Z
          threshold for zero (usually should be the number 0)

     Outputs (see Golub and Van Loan):

     BETA
          If beta = 0, then no reflection need be applied (zer set to 0)

     HOUSV
          householder vector

 -- : [U, H, NU] = krylov (A, V, K, EPS1, PFLG)
     Construct an orthogonal basis U of a block Krylov subspace.

     The block Krylov subspace has the following form:

          [v a*v a^2*v ... a^(k+1)*v]

     The construction is made with Householder reflections to guard
     against loss of orthogonality.

     If V is a vector, then H contains the Hessenberg matrix such that
     a*u == u*h+rk*ek’, in which ‘rk = a*u(:,k)-u*h(:,k)’, and ek’ is
     the vector ‘[0, 0, ..., 1]’ of length K.  Otherwise, H is
     meaningless.

     If V is a vector and K is greater than ‘length (A) - 1’, then H
     contains the Hessenberg matrix such that ‘a*u == u*h’.

     The value of NU is the dimension of the span of the Krylov subspace
     (based on EPS1).

     If B is a vector and K is greater than M-1, then H contains the
     Hessenberg decomposition of A.

     The optional parameter EPS1 is the threshold for zero.  The default
     value is 1e-12.

     If the optional parameter PFLG is nonzero, row pivoting is used to
     improve numerical behavior.  The default value is 0.

     Reference: A. Hodel, P. Misra, ‘Partial Pivoting in the Computation
     of Krylov Subspaces of Large Sparse Systems’, Proceedings of the
     42nd IEEE Conference on Decision and Control, December 2003.


File: octave.info,  Node: Functions of a Matrix,  Next: Specialized Solvers,  Prev: Matrix Factorizations,  Up: Linear Algebra

18.4 Functions of a Matrix
==========================

 -- : expm (A)
     Return the exponential of a matrix.

     The matrix exponential is defined as the infinite Taylor series

          expm (A) = I + A + A^2/2! + A^3/3! + ...

     However, the Taylor series is _not_ the way to compute the matrix
     exponential; see Moler and Van Loan, ‘Nineteen Dubious Ways to
     Compute the Exponential of a Matrix’, SIAM Review, 1978.  This
     routine uses Ward’s diagonal Padé approximation method with three
     step preconditioning (SIAM Journal on Numerical Analysis, 1977).
     Diagonal Padé approximations are rational polynomials of matrices

               -1
          D (A)   N (A)

     whose Taylor series matches the first ‘2q+1’ terms of the Taylor
     series above; direct evaluation of the Taylor series (with the same
     preconditioning steps) may be desirable in lieu of the Padé
     approximation when ‘Dq(A)’ is ill-conditioned.

     See also: *note logm: XREFlogm, *note sqrtm: XREFsqrtm.

 -- : S = logm (A)
 -- : S = logm (A, OPT_ITERS)
 -- : [S, ITERS] = logm (...)
     Compute the matrix logarithm of the square matrix A.

     The implementation utilizes a Padé approximant and the identity

          logm (A) = 2^k * logm (A^(1 / 2^k))

     The optional input OPT_ITERS is the maximum number of square roots
     to compute and defaults to 100.

     The optional output ITERS is the number of square roots actually
     computed.

     See also: *note expm: XREFexpm, *note sqrtm: XREFsqrtm.

 -- : S = sqrtm (A)
 -- : [S, ERROR_ESTIMATE] = sqrtm (A)
     Compute the matrix square root of the square matrix A.

     Ref: N.J. Higham.  ‘A New sqrtm for MATLAB’.  Numerical Analysis
     Report No.  336, Manchester Centre for Computational Mathematics,
     Manchester, England, January 1999.

     See also: *note expm: XREFexpm, *note logm: XREFlogm.

 -- : kron (A, B)
 -- : kron (A1, A2, ...)
     Form the Kronecker product of two or more matrices.

     This is defined block by block as

          x = [ a(i,j)*b ]

     For example:

          kron (1:4, ones (3, 1))
               ⇒  1  2  3  4
                   1  2  3  4
                   1  2  3  4

     If there are more than two input arguments A1, A2, ..., AN the
     Kronecker product is computed as

          kron (kron (A1, A2), ..., AN)

     Since the Kronecker product is associative, this is well-defined.

 -- : blkmm (A, B)
     Compute products of matrix blocks.

     The blocks are given as 2-dimensional subarrays of the arrays A, B.
     The size of A must have the form ‘[m,k,...]’ and size of B must be
     ‘[k,n,...]’.  The result is then of size ‘[m,n,...]’ and is
     computed as follows:

          for i = 1:prod (size (A)(3:end))
            C(:,:,i) = A(:,:,i) * B(:,:,i)
          endfor

 -- : X = sylvester (A, B, C)
     Solve the Sylvester equation.

     The Sylvester equation is defined as:

          A X + X B = C

     The solution is computed using standard LAPACK subroutines.

     For example:

          sylvester ([1, 2; 3, 4], [5, 6; 7, 8], [9, 10; 11, 12])
             ⇒ [ 0.50000, 0.66667; 0.66667, 0.50000 ]


File: octave.info,  Node: Specialized Solvers,  Prev: Functions of a Matrix,  Up: Linear Algebra

18.5 Specialized Solvers
========================

 -- : X = bicg (A, B)
 -- : X = bicg (A, B, TOL)
 -- : X = bicg (A, B, TOL, MAXIT)
 -- : X = bicg (A, B, TOL, MAXIT, M)
 -- : X = bicg (A, B, TOL, MAXIT, M1, M2)
 -- : X = bicg (A, B, TOL, MAXIT, M, [], X0)
 -- : X = bicg (A, B, TOL, MAXIT, M1, M2, X0)
 -- : X = bicg (A, B, TOL, MAXIT, M, [], X0, ...)
 -- : X = bicg (A, B, TOL, MAXIT, M1, M2, X0, ...)
 -- : [X, FLAG, RELRES, ITER, RESVEC] = bicg (A, B, ...)
     Solve the linear system of equations ‘A * X = B’ by means of the
     Bi-Conjugate Gradient iterative method.

     The input arguments are:

        • A is the matrix of the linear system and it must be square.  A
          can be passed as a matrix, function handle, or inline function
          ‘Afun’ such that ‘Afun (x, "notransp") = A * x’ and
          ‘Afun (x, "transp") = A' * x’.  Additional parameters to
          ‘Afun’ may be passed after X0.

        • B is the right-hand side vector.  It must be a column vector
          with the same number of rows as A.

        • TOL is the required relative tolerance for the residual error,
          ‘B - A * X’.  The iteration stops if
          ‘norm (B - A * X)’ ≤ ‘TOL * norm (B)’.  If TOL is omitted or
          empty, then a tolerance of 1e-6 is used.

        • MAXIT is the maximum allowed number of iterations; if MAXIT is
          omitted or empty then a value of 20 is used.

        • M1, M2 are the preconditioners.  The preconditioner M is given
          as ‘M = M1 * M2’.  Both M1 and M2 can be passed as a matrix or
          as a function handle or inline function ‘g’ such that
          ‘g (X, "notransp") = M1 \ X’ or ‘g (X, "notransp") = M2 \ X’
          and ‘g (X, "transp") = M1' \ X’ or
          ‘g (X, "transp") = M2' \ X’.  If M1 is omitted or empty, then
          preconditioning is not applied.  The preconditioned system is
          theoretically equivalent to applying the ‘bicg’ method to the
          linear system ‘inv (M1) * A * inv (M2) * Y = inv (M1) * B’ and
          ‘inv (M2') * A' * inv (M1') * Z = inv (M2') * B’ and then
          setting ‘X = inv (M2) * Y’.

        • X0 is the initial guess.  If X0 is omitted or empty then the
          function sets X0 to a zero vector by default.

     Any arguments which follow X0 are treated as parameters, and passed
     in an appropriate manner to any of the functions (AFUN or MFUN) or
     that have been given to ‘bicg’.

     The output parameters are:

        • X is the computed approximation to the solution of
          ‘A * X = B’.  If the algorithm did not converge, then X is the
          iteration which has the minimum residual.

        • FLAG indicates the exit status:

             • 0: The algorithm converged to within the prescribed
               tolerance.

             • 1: The algorithm did not converge and it reached the
               maximum number of iterations.

             • 2: The preconditioner matrix is singular.

             • 3: The algorithm stagnated, i.e., the absolute value of
               the difference between the current iteration X and the
               previous is less than ‘eps * norm (X,2)’.

             • 4: The algorithm could not continue because intermediate
               values became too small or too large for reliable
               computation.

        • RELRES is the ratio of the final residual to its initial
          value, measured in the Euclidean norm.

        • ITER is the iteration which X is computed.

        • RESVEC is a vector containing the residual at each iteration.
          The total number of iterations performed is given by ‘length
          (RESVEC) - 1’.

     Consider a trivial problem with a tridiagonal matrix

          n = 20;
          A = toeplitz (sparse ([1, 1], [1, 2], [2, 1] * n ^ 2, 1, n)) + ...
              toeplitz (sparse (1, 2, -1, 1, n) * n / 2, ...
                        sparse (1, 2, 1, 1, n) * n / 2);
          b = A * ones (n, 1);
          restart = 5;
          [M1, M2] = ilu (A);  # in this tridiag case, it corresponds to lu (A)
          M = M1 * M2;
          Afun = @(x, string) strcmp (string, "notransp") * (A * x) + ...
                               strcmp (string, "transp") * (A' * x);
          Mfun = @(x, string) strcmp (string, "notransp") * (M \ x) + ...
                               strcmp (string, "transp") * (M' \ x);
          M1fun = @(x, string) strcmp (string, "notransp") * (M1 \ x) + ...
                               strcmp (string, "transp") * (M1' \ x);
          M2fun = @(x, string) strcmp (string, "notransp") * (M2 \ x) + ...
                               strcmp (string, "transp") * (M2' \ x);

     EXAMPLE 1: simplest usage of ‘bicg’

          x = bicg (A, b)

     EXAMPLE 2: ‘bicg’ with a function that computes ‘A*X’ and ‘A'*X’

          x = bicg (Afun, b, [], n)

     EXAMPLE 3: ‘bicg’ with a preconditioner matrix M

          x = bicg (A, b, 1e-6, n, M)

     EXAMPLE 4: ‘bicg’ with a function as preconditioner

          x = bicg (Afun, b, 1e-6, n, Mfun)

     EXAMPLE 5: ‘bicg’ with preconditioner matrices M1 and M2

          x = bicg (A, b, 1e-6, n, M1, M2)

     EXAMPLE 6: ‘bicg’ with functions as preconditioners

          x = bicg (Afun, b, 1e-6, n, M1fun, M2fun)

     EXAMPLE 7: ‘bicg’ with as input a function requiring an argument

          function y = Ap (A, x, string, z)
            ## compute A^z * x or (A^z)' * x
            y = x;
            if (strcmp (string, "notransp"))
              for i = 1:z
                y = A * y;
              endfor
            elseif (strcmp (string, "transp"))
              for i = 1:z
                y = A' * y;
              endfor
            endif
          endfunction

          Apfun = @(x, string, p) Ap (A, x, string, p);
          x = bicg (Apfun, b, [], [], [], [], [], 2);

     References:

       1. Y. Saad, ‘Iterative Methods for Sparse Linear Systems’, Second
          edition, 2003, SIAM.

     See also: *note bicgstab: XREFbicgstab, *note cgs: XREFcgs, *note
     gmres: XREFgmres, *note pcg: XREFpcg, *note qmr: XREFqmr, *note
     tfqmr: XREFtfqmr.

 -- : X = bicgstab (A, B, TOL, MAXIT, M1, M2, X0, ...)
 -- : X = bicgstab (A, B, TOL, MAXIT, M, [], X0, ...)
 -- : [X, FLAG, RELRES, ITER, RESVEC] = bicgstab (A, B, ...)
     Solve ‘A x = b’ using the stabilizied Bi-conjugate gradient
     iterative method.

     The input parameters are:

        − A is the matrix of the linear system and it must be square.  A
          can be passed as a matrix, function handle, or inline function
          ‘Afun’ such that ‘Afun(x) = A * x’.  Additional parameters to
          ‘Afun’ are passed after X0.

        − B is the right hand side vector.  It must be a column vector
          with the same number of rows as A.

        − TOL is the required relative tolerance for the residual error,
          ‘B - A * X’.  The iteration stops if
          ‘norm (B - A * X)’ ≤ ‘TOL * norm (B)’.  If TOL is omitted or
          empty, then a tolerance of 1e-6 is used.

        − MAXIT the maximum number of outer iterations, if not given or
          set to [] the default value ‘min (20, numel (b))’ is used.

        − M1, M2 are the preconditioners.  The preconditioner M is given
          as ‘M = M1 * M2’.  Both M1 and M2 can be passed as a matrix or
          as a function handle or inline function ‘g’ such that ‘g(X) =
          M1 \ X’ or ‘g(X) = M2 \ X’.  The technique used is the right
          preconditioning, i.e., it is solved ‘A * inv (M) * Y = B’ and
          then ‘X = inv (M) * Y’.

        − X0 the initial guess, if not given or set to [] the default
          value ‘zeros (size (B))’ is used.

     The arguments which follow X0 are treated as parameters, and passed
     in a proper way to any of the functions (A or M) which are passed
     to ‘bicstab’.

     The output parameters are:

        − X is the approximation computed.  If the method doesn’t
          converge then it is the iterated with the minimum residual.

        − FLAG indicates the exit status:

             − 0: iteration converged to the within the chosen tolerance

             − 1: the maximum number of iterations was reached before
               convergence

             − 2: the preconditioner matrix is singular

             − 3: the algorithm reached stagnation

             − 4: the algorithm can’t continue due to a division by zero

        − RELRES is the relative residual obtained with as ‘(A*X-B) /
          norm(B)’.

        − ITER is the (possibily half) iteration which X is computed.
          If it is an half iteration then it is ‘ITER + 0.5’

        − RESVEC is a vector containing the residual of each half and
          total iteration (There are also the half iterations since X is
          computed in two steps at each iteration).  Doing
          ‘(length(RESVEC) - 1) / 2’ is possible to see the total number
          of (total) iterations performed.

     Let us consider a trivial problem with a tridiagonal matrix

          n = 20;
          A = toeplitz (sparse ([1, 1], [1, 2], [2, 1] * n ^ 2, 1, n))  + ...
              toeplitz (sparse (1, 2, -1, 1, n) * n / 2, ...
              sparse (1, 2, 1, 1, n) * n / 2);
          b = A * ones (n, 1);
          restart = 5;
          [M1, M2] = ilu (A); # in this tridiag case, it corresponds to lu (A)
          M = M1 * M2;
          Afun = @(x) A * x;
          Mfun = @(x) M \ x;
          M1fun = @(x) M1 \ x;
          M2fun = @(x) M2 \ x;

     EXAMPLE 1: simplest usage of ‘bicgstab’

          x = bicgstab (A, b, [], n)

     EXAMPLE 2: ‘bicgstab’ with a function which computes ‘A * X’

          x = bicgstab (Afun, b, [], n)

     EXAMPLE 3: ‘bicgstab’ with a preconditioner matrix M

          x = bicgstab (A, b, [], 1e-06, n, M)

     EXAMPLE 4: ‘bicgstab’ with a function as preconditioner

          x = bicgstab (Afun, b, 1e-6, n, Mfun)

     EXAMPLE 5: ‘bicgstab’ with preconditioner matrices M1 and M2

          x = bicgstab (A, b, [], 1e-6, n, M1, M2)

     EXAMPLE 6: ‘bicgstab’ with functions as preconditioners

          x = bicgstab (Afun, b, 1e-6, n, M1fun, M2fun)

     EXAMPLE 7: ‘bicgstab’ with as input a function requiring an
     argument

          function y = Ap (A, x, z) # compute A^z * x
             y = x;
             for i = 1:z
               y = A * y;
             endfor
           endfunction
          Apfun = @(x, string, p) Ap (A, x, string, p);
          x = bicgstab (Apfun, b, [], [], [], [], [], 2);

     EXAMPLE 8: explicit example to show that ‘bicgstab’ uses a right
     preconditioner

          [M1, M2] = ilu (A + 0.1 * eye (n)); # factorization of A perturbed
          M = M1 * M2;

          ## reference solution computed by bicgstab after one iteration
          [x_ref, fl] = bicgstab (A, b, [], 1, M)

          ## right preconditioning
          [y, fl] = bicgstab (A / M, b, [], 1)
          x = M \ y # compare x and x_ref


     References:

       1. Y. Saad, ‘Iterative Methods for Sparse Linear Systems’, Second
          edition, 2003, SIAM

     See also: *note bicg: XREFbicg, *note cgs: XREFcgs, *note gmres:
     XREFgmres, *note pcg: XREFpcg, *note qmr: XREFqmr, *note tfqmr:
     XREFtfqmr.

 -- : X = cgs (A, B, TOL, MAXIT, M1, M2, X0, ...)
 -- : X = cgs (A, B, TOL, MAXIT, M, [], X0, ...)
 -- : [X, FLAG, RELRES, ITER, RESVEC] = cgs (A, B, ...)
     Solve ‘A x = b’, where A is a square matrix, using the Conjugate
     Gradients Squared method.

     The input arguments are:

        − A is the matrix of the linear system and it must be square.  A
          can be passed as a matrix, function handle, or inline function
          ‘Afun’ such that ‘Afun(x) = A * x’.  Additional parameters to
          ‘Afun’ are passed after X0.

        − B is the right hand side vector.  It must be a column vector
          with same number of rows of A.

        − TOL is the relative tolerance, if not given or set to [] the
          default value 1e-6 is used.

        − MAXIT the maximum number of outer iterations, if not given or
          set to [] the default value ‘min (20, numel (b))’ is used.

        − M1, M2 are the preconditioners.  The preconditioner matrix is
          given as ‘M = M1 * M2’.  Both M1 and M2 can be passed as a
          matrix or as a function handle or inline function ‘g’ such
          that ‘g(x) = M1 \ x’ or ‘g(x) = M2 \ x’.  If M1 is empty or
          not passed then no preconditioners are applied.  The technique
          used is the right preconditioning, i.e., it is solved
          ‘A*inv(M)*y = b’ and then ‘X = inv(M)*y’.

        − X0 the initial guess, if not given or set to [] the default
          value ‘zeros (size (b))’ is used.

     The arguments which follow X0 are treated as parameters, and passed
     in a proper way to any of the functions (A or P) which are passed
     to ‘cgs’.

     The output parameters are:

        − X is the approximation computed.  If the method doesn’t
          converge then it is the iterated with the minimum residual.

        − FLAG indicates the exit status:

             − 0: iteration converged to the within the chosen tolerance

             − 1: the maximum number of iterations was reached before
               convergence

             − 2: the preconditioner matrix is singular

             − 3: the algorithm reached stagnation

             − 4: the algorithm can’t continue due to a division by zero

        − RELRES is the relative residual obtained with as ‘(A*X-B) /
          norm(B)’.

        − ITER is the iteration which X is computed.

        − RESVEC is a vector containing the residual at each iteration.
          Doing ‘length(RESVEC) - 1’ is possible to see the total number
          of iterations performed.

     Let us consider a trivial problem with a tridiagonal matrix

          n = 20;
          A = toeplitz (sparse ([1, 1], [1, 2], [2, 1] * n ^ 2, 1, n))  + ...
              toeplitz (sparse (1, 2, -1, 1, n) * n / 2, ...
              sparse (1, 2, 1, 1, n) * n / 2);
          b = A * ones (n, 1);
          restart = 5;
          [M1, M2] = ilu (A); # in this tridiag case it corresponds to chol (A)'
          M = M1 * M2;
          Afun = @(x) A * x;
          Mfun = @(x) M \ x;
          M1fun = @(x) M1 \ x;
          M2fun = @(x) M2 \ x;

     EXAMPLE 1: simplest usage of ‘cgs’

          x = cgs (A, b, [], n)

     EXAMPLE 2: ‘cgs’ with a function which computes ‘A * X’

          x = cgs (Afun, b, [], n)

     EXAMPLE 3: ‘cgs’ with a preconditioner matrix M

          x = cgs (A, b, [], 1e-06, n, M)

     EXAMPLE 4: ‘cgs’ with a function as preconditioner

          x = cgs (Afun, b, 1e-6, n, Mfun)

     EXAMPLE 5: ‘cgs’ with preconditioner matrices M1 and M2

          x = cgs (A, b, [], 1e-6, n, M1, M2)

     EXAMPLE 6: ‘cgs’ with functions as preconditioners

          x = cgs (Afun, b, 1e-6, n, M1fun, M2fun)

     EXAMPLE 7: ‘cgs’ with as input a function requiring an argument

          function y = Ap (A, x, z) # compute A^z * x
             y = x;
             for i = 1:z
               y = A * y;
             endfor
           endfunction
          Apfun = @(x, string, p) Ap (A, x, string, p);
          x = cgs (Apfun, b, [], [], [], [], [], 2);

     EXAMPLE 8: explicit example to show that ‘cgs’ uses a right
     preconditioner

          [M1, M2] = ilu (A + 0.3 * eye (n)); # factorization of A perturbed
          M = M1 * M2;

          ## reference solution computed by cgs after one iteration
          [x_ref, fl] = cgs (A, b, [], 1, M)

          ## right preconditioning
          [y, fl] = cgs (A / M, b, [], 1)
          x = M \ y # compare x and x_ref


     References:

       1. Y. Saad, ‘Iterative Methods for Sparse Linear Systems’, Second
          edition, 2003, SIAM

     See also: *note pcg: XREFpcg, *note bicgstab: XREFbicgstab, *note
     bicg: XREFbicg, *note gmres: XREFgmres, *note qmr: XREFqmr, *note
     tfqmr: XREFtfqmr.

 -- : X = gmres (A, B, RESTART, TOL, MAXIT, M1, M2, X0, ...)
 -- : X = gmres (A, B, RESTART, TOL, MAXIT, M, [], X0, ...)
 -- : [X, FLAG, RELRES, ITER, RESVEC] = gmres (A, B, ...)
     Solve ‘A x = b’ using the Preconditioned GMRES iterative method
     with restart, a.k.a.  PGMRES(restart).

     The input arguments are:

        − A is the matrix of the linear system and it must be square.  A
          can be passed as a matrix, function handle, or inline function
          ‘Afun’ such that ‘Afun(x) = A * x’.  Additional parameters to
          ‘Afun’ are passed after X0.

        − B is the right hand side vector.  It must be a column vector
          with the same numbers of rows as A.

        − RESTART is the number of iterations before that the method
          restarts.  If it is [] or N = numel (b), then the restart is
          not applied.

        − TOL is the required relative tolerance for the preconditioned
          residual error, ‘inv (M) * (B - A * X)’.  The iteration stops
          if ‘norm (inv (M) * (B - A * X)) ≤ TOL * norm (inv (M) * B)’.
          If TOL is omitted or empty, then a tolerance of 1e-6 is used.

        − MAXIT is the maximum number of outer iterations, if not given
          or set to [], then the default value ‘min (10, N / RESTART)’
          is used.  Note that, if RESTART is empty, then MAXIT is the
          maximum number of iterations.  If RESTART and MAXIT are not
          empty, then the maximum number of iterations is ‘RESTART *
          MAXIT’.  If both RESTART and MAXIT are empty, then the maximum
          number of iterations is set to ‘min (10, N)’.

        − M1, M2 are the preconditioners.  The preconditioner M is given
          as ‘M = M1 * M2’.  Both M1 and M2 can be passed as a matrix,
          function handle, or inline function ‘g’ such that ‘g(x) = M1 \
          x’ or ‘g(x) = M2 \ x’.  If M1 is [] or not given, then the
          preconditioner is not applied.  The technique used is the
          left-preconditioning, i.e., it is solved ‘inv(M) * A * X =
          inv(M) * B’ instead of ‘A * X = B’.

        − X0 is the initial guess, if not given or set to [], then the
          default value ‘zeros (size (B))’ is used.

     The arguments which follow X0 are treated as parameters, and passed
     in a proper way to any of the functions (A or M or M1 or M2) which
     are passed to ‘gmres’.

     The outputs are:

        − X the computed approximation.  If the method does not
          converge, then it is the iterated with minimum residual.

        − FLAG indicates the exit status:

          0 : iteration converged to within the specified tolerance

          1 : maximum number of iterations exceeded

          2 : the preconditioner matrix is singular

          3 : algorithm reached stagnation (the relative difference between two
               consecutive iterations is less than eps)

        − RELRES is the value of the relative preconditioned residual of
          the approximation X.

        − ITER is a vector containing the number of outer iterations and
          inner iterations performed to compute X.  That is:

             • ITER(1): number of outer iterations, i.e., how many times
               the method restarted.  (if RESTART is empty or N, then it
               is 1, if not 1 ≤ ITER(1) ≤ MAXIT).

             • ITER(2): the number of iterations performed before the
               restart, i.e., the method restarts when ‘ITER(2) =
               RESTART’.  If RESTART is empty or N, then 1 ≤ ITER(2) ≤
               MAXIT.

          To be more clear, the approximation X is computed at the
          iteration ‘(ITER(1) - 1) * RESTART + ITER(2)’.  Since the
          output X corresponds to the minimal preconditioned residual
          solution, the total number of iterations that the method
          performed is given by ‘length (resvec) - 1’.

        − RESVEC is a vector containing the preconditioned relative
          residual at each iteration, including the 0-th iteration ‘norm
          (A * X0 - B)’.

     Let us consider a trivial problem with a tridiagonal matrix

          n = 20;
          A = toeplitz (sparse ([1, 1], [1, 2], [2, 1] * n ^ 2, 1, n))  + ...
              toeplitz (sparse (1, 2, -1, 1, n) * n / 2, ...
              sparse (1, 2, 1, 1, n) * n / 2);
          b = A * ones (n, 1);
          restart = 5;
          [M1, M2] = ilu (A); # in this tridiag case, it corresponds to lu (A)
          M = M1 * M2;
          Afun = @(x) A * x;
          Mfun = @(x) M \ x;
          M1fun = @(x) M1 \ x;
          M2fun = @(x) M2 \ x;

     EXAMPLE 1: simplest usage of ‘gmres’

          x = gmres (A, b, [], [], n)

     EXAMPLE 2: ‘gmres’ with a function which computes ‘A * X’

          x = gmres (Afun, b, [], [], n)

     EXAMPLE 3: usage of ‘gmres’ with the restart

          x = gmres (A, b, restart);

     EXAMPLE 4: ‘gmres’ with a preconditioner matrix M with and without
     restart

          x = gmres (A, b, [], 1e-06, n, M)
          x = gmres (A, b, restart, 1e-06, n, M)

     EXAMPLE 5: ‘gmres’ with a function as preconditioner

          x = gmres (Afun, b, [], 1e-6, n, Mfun)

     EXAMPLE 6: ‘gmres’ with preconditioner matrices M1 and M2

          x = gmres (A, b, [], 1e-6, n, M1, M2)

     EXAMPLE 7: ‘gmres’ with functions as preconditioners

          x = gmres (Afun, b, 1e-6, n, M1fun, M2fun)

     EXAMPLE 8: ‘gmres’ with as input a function requiring an argument

            function y = Ap (A, x, p) # compute A^p * x
               y = x;
               for i = 1:p
                 y = A * y;
               endfor
            endfunction
          Apfun = @(x, p) Ap (A, x, p);
          x = gmres (Apfun, b, [], [], [], [], [], [], 2);

     EXAMPLE 9: explicit example to show that ‘gmres’ uses a left
     preconditioner

          [M1, M2] = ilu (A + 0.1 * eye (n)); # factorization of A perturbed
          M = M1 * M2;

          ## reference solution computed by gmres after two iterations
          [x_ref, fl] = gmres (A, b, [], [], 1, M)

          ## left preconditioning
          [x, fl] = gmres (M \ A, M \ b, [], [], 1)
          x # compare x and x_ref


     References:

       1. Y. Saad, ‘Iterative Methods for Sparse Linear Systems’, Second
          edition, 2003, SIAM

     See also: *note bicg: XREFbicg, *note bicgstab: XREFbicgstab, *note
     cgs: XREFcgs, *note pcg: XREFpcg, *note pcr: XREFpcr, *note qmr:
     XREFqmr, *note tfqmr: XREFtfqmr.

 -- : X = qmr (A, B, RTOL, MAXIT, M1, M2, X0)
 -- : X = qmr (A, B, RTOL, MAXIT, P)
 -- : [X, FLAG, RELRES, ITER, RESVEC] = qmr (A, B, ...)
     Solve ‘A x = b’ using the Quasi-Minimal Residual iterative method
     (without look-ahead).

        − RTOL is the relative tolerance, if not given or set to [] the
          default value 1e-6 is used.

        − MAXIT the maximum number of outer iterations, if not given or
          set to [] the default value ‘min (20, numel (b))’ is used.

        − X0 the initial guess, if not given or set to [] the default
          value ‘zeros (size (b))’ is used.

     A can be passed as a matrix or as a function handle or inline
     function ‘f’ such that ‘f(x, "notransp") = A*x’ and ‘f(x, "transp")
     = A'*x’.

     The preconditioner P is given as ‘P = M1 * M2’.  Both M1 and M2 can
     be passed as a matrix or as a function handle or inline function
     ‘g’ such that ‘g(x, "notransp") = M1 \ x’ or ‘g(x, "notransp") = M2
     \ x’ and ‘g(x, "transp") = M1' \ x’ or ‘g(x, "transp") = M2' \ x’.

     If called with more than one output parameter

        − FLAG indicates the exit status:

             − 0: iteration converged to the within the chosen tolerance

             − 1: the maximum number of iterations was reached before
               convergence

             − 3: the algorithm reached stagnation

          (the value 2 is unused but skipped for compatibility).

        − RELRES is the final value of the relative residual.

        − ITER is the number of iterations performed.

        − RESVEC is a vector containing the residual norms at each
          iteration.

     References:

       1. R. Freund and N. Nachtigal, ‘QMR: a quasi-minimal residual
          method for non-Hermitian linear systems’, Numerische
          Mathematik, 1991, 60, pp.  315-339.

       2. R. Barrett, M. Berry, T. Chan, J. Demmel, J. Donato, J.
          Dongarra, V. Eijkhour, R. Pozo, C. Romine, and H. van der
          Vorst, ‘Templates for the solution of linear systems: Building
          blocks for iterative methods’, SIAM, 2nd ed., 1994.

     See also: *note bicg: XREFbicg, *note bicgstab: XREFbicgstab, *note
     cgs: XREFcgs, *note gmres: XREFgmres, *note pcg: XREFpcg.

 -- : X = tfqmr (A, B, TOL, MAXIT, M1, M2, X0, ...)
 -- : X = tfqmr (A, B, TOL, MAXIT, M, [], X0, ...)
 -- : [X, FLAG, RELRES, ITER, RESVEC] = tfqmr (A, B, ...)
     Solve ‘A x = b’ using the Transpose-Tree qmr method, based on the
     cgs.

     The input parameters are:

        − A is the matrix of the linear system and it must be square.  A
          can be passed as a matrix, function handle, or inline function
          ‘Afun’ such that ‘Afun(x) = A * x’.  Additional parameters to
          ‘Afun’ are passed after X0.

        − B is the right hand side vector.  It must be a column vector
          with the same number of rows as A.

        − TOL is the relative tolerance, if not given or set to [] the
          default value 1e-6 is used.

        − MAXIT the maximum number of outer iterations, if not given or
          set to [] the default value ‘min (20, numel (b))’ is used.  To
          be compatible, since the method as different behaviors in the
          iteration number is odd or even, is considered as iteration in
          ‘tfqmr’ the entire odd-even cycle.  That is, to make an entire
          iteration, the algorithm performs two sub-iterations: the odd
          one and the even one.

        − M1, M2 are the preconditioners.  The preconditioner M is given
          as ‘M = M1 * M2’.  Both M1 and M2 can be passed as a matrix or
          as a function handle or inline function ‘g’ such that ‘g(x) =
          M1 \ x’ or ‘g(x) = M2 \ x’.  The technique used is the
          right-preconditioning, i.e., it is solved ‘A*inv(M)*y = b’ and
          then ‘x = inv(M)*y’, instead of ‘A x = b’.

        − X0 the initial guess, if not given or set to [] the default
          value ‘zeros (size (b))’ is used.

     The arguments which follow X0 are treated as parameters, and passed
     in a proper way to any of the functions (A or M) which are passed
     to ‘tfqmr’.

     The output parameters are:

        − X is the approximation computed.  If the method doesn’t
          converge then it is the iterated with the minimum residual.

        − FLAG indicates the exit status:

             − 0: iteration converged to the within the chosen tolerance

             − 1: the maximum number of iterations was reached before
               convergence

             − 2: the preconditioner matrix is singular

             − 3: the algorithm reached stagnation

             − 4: the algorithm can’t continue due to a division by zero

        − RELRES is the relative residual obtained as ‘(A*X-B) / norm
          (B)’.

        − ITER is the iteration which X is computed.

        − RESVEC is a vector containing the residual at each iteration
          (including ‘norm (b - A x0)’).  Doing ‘length (RESVEC) - 1’ is
          possible to see the total number of iterations performed.

     Let us consider a trivial problem with a tridiagonal matrix

          n = 20;
          A = toeplitz (sparse ([1, 1], [1, 2], [2, 1] * n ^ 2, 1, n))  + ...
              toeplitz (sparse (1, 2, -1, 1, n) * n / 2, ...
              sparse (1, 2, 1, 1, n) * n / 2);
          b = A * ones (n, 1);
          restart = 5;
          [M1, M2] = ilu (A); # in this tridiag case it corresponds to chol (A)'
          M = M1 * M2;
          Afun = @(x) A * x;
          Mfun = @(x) M \ x;
          M1fun = @(x) M1 \ x;
          M2fun = @(x) M2 \ x;

     EXAMPLE 1: simplest usage of ‘tfqmr’

          x = tfqmr (A, b, [], n)

     EXAMPLE 2: ‘tfqmr’ with a function which computes ‘A * X’

          x = tfqmr (Afun, b, [], n)

     EXAMPLE 3: ‘tfqmr’ with a preconditioner matrix M

          x = tfqmr (A, b, [], 1e-06, n, M)

     EXAMPLE 4: ‘tfqmr’ with a function as preconditioner

          x = tfqmr (Afun, b, 1e-6, n, Mfun)

     EXAMPLE 5: ‘tfqmr’ with preconditioner matrices M1 and M2

          x = tfqmr (A, b, [], 1e-6, n, M1, M2)

     EXAMPLE 6: ‘tfmqr’ with functions as preconditioners

          x = tfqmr (Afun, b, 1e-6, n, M1fun, M2fun)

     EXAMPLE 7: ‘tfqmr’ with as input a function requiring an argument

          function y = Ap (A, x, z) # compute A^z * x
             y = x;
             for i = 1:z
               y = A * y;
             endfor
           endfunction
          Apfun = @(x, string, p) Ap (A, x, string, p);
          x = tfqmr (Apfun, b, [], [], [], [], [], 2);

     EXAMPLE 8: explicit example to show that ‘tfqmr’ uses a right
     preconditioner

          [M1, M2] = ilu (A + 0.3 * eye (n)); # factorization of A perturbed
          M = M1 * M2;

          ## reference solution computed by tfqmr after one iteration
          [x_ref, fl] = tfqmr (A, b, [], 1, M)

          ## right preconditioning
          [y, fl] = tfqmr (A / M, b, [], 1)
          x = M \ y # compare x and x_ref


     References:

       1. Y. Saad, ‘Iterative Methods for Sparse Linear Systems’, Second
          edition, 2003, SIAM

     See also: *note bicg: XREFbicg, *note bicgstab: XREFbicgstab, *note
     cgs: XREFcgs, *note gmres: XREFgmres, *note pcg: XREFpcg, *note
     qmr: XREFqmr, *note pcr: XREFpcr.


File: octave.info,  Node: Vectorization and Faster Code Execution,  Next: Nonlinear Equations,  Prev: Linear Algebra,  Up: Top

19 Vectorization and Faster Code Execution
******************************************

Vectorization is a programming technique that uses vector operations
instead of element-by-element loop-based operations.  Besides frequently
producing more succinct Octave code, vectorization also allows for
better optimization in the subsequent implementation.  The optimizations
may occur either in Octave’s own Fortran, C, or C++ internal
implementation, or even at a lower level depending on the compiler and
external numerical libraries used to build Octave.  The ultimate goal is
to make use of your hardware’s vector instructions if possible or to
perform other optimizations in software.

   Vectorization is not a concept unique to Octave, but it is
particularly important because Octave is a matrix-oriented language.
Vectorized Octave code will see a dramatic speed up (10X–100X) in most
cases.

   This chapter discusses vectorization and other techniques for writing
faster code.

* Menu:

* Basic Vectorization::        Basic techniques for code optimization
* Broadcasting::               Broadcasting operations
* Function Application::       Applying functions to arrays, cells, and structs
* Accumulation::               Accumulation functions
* JIT Compiler::               Just-In-Time Compiler for loops
* Miscellaneous Techniques::   Other techniques for speeding up code
* Examples::


File: octave.info,  Node: Basic Vectorization,  Next: Broadcasting,  Up: Vectorization and Faster Code Execution

19.1 Basic Vectorization
========================

To a very good first approximation, the goal in vectorization is to
write code that avoids loops and uses whole-array operations.  As a
trivial example, consider

     for i = 1:n
       for j = 1:m
         c(i,j) = a(i,j) + b(i,j);
       endfor
     endfor

compared to the much simpler

     c = a + b;

This isn’t merely easier to write; it is also internally much easier to
optimize.  Octave delegates this operation to an underlying
implementation which, among other optimizations, may use special vector
hardware instructions or could conceivably even perform the additions in
parallel.  In general, if the code is vectorized, the underlying
implementation has more freedom about the assumptions it can make in
order to achieve faster execution.

   This is especially important for loops with "cheap" bodies.  Often it
suffices to vectorize just the innermost loop to get acceptable
performance.  A general rule of thumb is that the "order" of the
vectorized body should be greater or equal to the "order" of the
enclosing loop.

   As a less trivial example, instead of

     for i = 1:n-1
       a(i) = b(i+1) - b(i);
     endfor

write

     a = b(2:n) - b(1:n-1);

   This shows an important general concept about using arrays for
indexing instead of looping over an index variable.  *Note Index
Expressions::.  Also use boolean indexing generously.  If a condition
needs to be tested, this condition can also be written as a boolean
index.  For instance, instead of

     for i = 1:n
       if (a(i) > 5)
         a(i) -= 20
       endif
     endfor

write

     a(a>5) -= 20;

which exploits the fact that ‘a > 5’ produces a boolean index.

   Use elementwise vector operators whenever possible to avoid looping
(operators like ‘.*’ and ‘.^’).  *Note Arithmetic Ops::.  For simple
inline functions, the ‘vectorize’ function can do this automatically.

 -- : vectorize (FUN)
     Create a vectorized version of the inline function FUN by replacing
     all occurrences of ‘*’, ‘/’, etc., with ‘.*’, ‘./’, etc.

     This may be useful, for example, when using inline functions with
     numerical integration or optimization where a vector-valued
     function is expected.

          fcn = vectorize (inline ("x^2 - 1"))
             ⇒ fcn = f(x) = x.^2 - 1
          quadv (fcn, 0, 3)
             ⇒ 6

     See also: *note inline: XREFinline, *note formula: XREFformula,
     *note argnames: XREFargnames.

   Also exploit broadcasting in these elementwise operators both to
avoid looping and unnecessary intermediate memory allocations.  *Note
Broadcasting::.

   Use built-in and library functions if possible.  Built-in and
compiled functions are very fast.  Even with an m-file library function,
chances are good that it is already optimized, or will be optimized more
in a future release.

   For instance, even better than

     a = b(2:n) - b(1:n-1);

is

     a = diff (b);

   Most Octave functions are written with vector and array arguments in
mind.  If you find yourself writing a loop with a very simple operation,
chances are that such a function already exists.  The following
functions occur frequently in vectorized code:

   • Index manipulation

        • find

        • sub2ind

        • ind2sub

        • sort

        • unique

        • lookup

        • ifelse / merge

   • Repetition

        • repmat

        • repelems

   • Vectorized arithmetic

        • sum

        • prod

        • cumsum

        • cumprod

        • sumsq

        • diff

        • dot

        • cummax

        • cummin

   • Shape of higher dimensional arrays

        • reshape

        • resize

        • permute

        • squeeze

        • deal


File: octave.info,  Node: Broadcasting,  Next: Function Application,  Prev: Basic Vectorization,  Up: Vectorization and Faster Code Execution

19.2 Broadcasting
=================

Broadcasting refers to how Octave binary operators and functions behave
when their matrix or array operands or arguments differ in size.  Since
version 3.6.0, Octave now automatically broadcasts vectors, matrices,
and arrays when using elementwise binary operators and functions.
Broadly speaking, smaller arrays are “broadcast” across the larger one,
until they have a compatible shape.  The rule is that corresponding
array dimensions must either

  1. be equal, or

  2. one of them must be 1.

In case all dimensions are equal, no broadcasting occurs and ordinary
element-by-element arithmetic takes place.  For arrays of higher
dimensions, if the number of dimensions isn’t the same, then missing
trailing dimensions are treated as 1.  When one of the dimensions is 1,
the array with that singleton dimension gets copied along that dimension
until it matches the dimension of the other array.  For example,
consider

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

     y = [10 20 30];

     x + y

Without broadcasting, ‘x + y’ would be an error because the dimensions
do not agree.  However, with broadcasting it is as if the following
operation were performed:

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

     y = [10 20 30
          10 20 30
          10 20 30];

     x + y
     ⇒    11   22   33
           14   25   36
           17   28   39

That is, the smaller array of size ‘[1 3]’ gets copied along the
singleton dimension (the number of rows) until it is ‘[3 3]’.  No actual
copying takes place, however.  The internal implementation reuses
elements along the necessary dimension in order to achieve the desired
effect without copying in memory.

   Both arrays can be broadcast across each other, for example, all
pairwise differences of the elements of a vector with itself:

     y - y'
     ⇒    0   10   20
         -10    0   10
         -20  -10    0

Here the vectors of size ‘[1 3]’ and ‘[3 1]’ both get broadcast into
matrices of size ‘[3 3]’ before ordinary matrix subtraction takes place.

   A special case of broadcasting that may be familiar is when all
dimensions of the array being broadcast are 1, i.e., the array is a
scalar.  Thus for example, operations like ‘x - 42’ and ‘max (x, 2)’ are
basic examples of broadcasting.

   For a higher-dimensional example, suppose ‘img’ is an RGB image of
size ‘[m n 3]’ and we wish to multiply each color by a different scalar.
The following code accomplishes this with broadcasting,

     img .*= permute ([0.8, 0.9, 1.2], [1, 3, 2]);

Note the usage of permute to match the dimensions of the ‘[0.8, 0.9,
1.2]’ vector with ‘img’.

   For functions that are not written with broadcasting semantics,
‘bsxfun’ can be useful for coercing them to broadcast.

 -- : bsxfun (F, A, B)
     Apply a binary function F element-by-element to two array arguments
     A and B, expanding singleton dimensions in either input argument as
     necessary.

     F is a function handle, inline function, or string containing the
     name of the function to evaluate.  The function F must be capable
     of accepting two column-vector arguments of equal length, or one
     column vector argument and a scalar.

     The dimensions of A and B must be equal or singleton.  The
     singleton dimensions of the arrays will be expanded to the same
     dimensionality as the other array.

     See also: *note arrayfun: XREFarrayfun, *note cellfun: XREFcellfun.

   Broadcasting is only applied if either of the two broadcasting
conditions hold.  As usual, however, broadcasting does not apply when
two dimensions differ and neither is 1:

     x = [1 2 3
          4 5 6];
     y = [10 20
          30 40];
     x + y

This will produce an error about nonconformant arguments.

   Besides common arithmetic operations, several functions of two
arguments also broadcast.  The full list of functions and operators that
broadcast is

           plus      +  .+
           minus     -  .-
           times     .*
           rdivide   ./
           ldivide   .\
           power     .^  .**
           lt        <
           le        <=
           eq        ==
           gt        >
           ge        >=
           ne        !=  ~=
           and       &
           or        |
           atan2
           hypot
           max
           min
           mod
           rem
           xor

           +=  -=  .+=  .-=  .*=  ./=  .\=  .^=  .**=  &=  |=

   Beware of resorting to broadcasting if a simpler operation will
suffice.  For matrices A and B, consider the following:

     C = sum (permute (A, [1, 3, 2]) .* permute (B, [3, 2, 1]), 3);

This operation broadcasts the two matrices with permuted dimensions
across each other during elementwise multiplication in order to obtain a
larger 3-D array, and this array is then summed along the third
dimension.  A moment of thought will prove that this operation is simply
the much faster ordinary matrix multiplication, ‘C = A*B;’.

   A note on terminology: “broadcasting” is the term popularized by the
Numpy numerical environment in the Python programming language.  In
other programming languages and environments, broadcasting may also be
known as _binary singleton expansion_ (BSX, in MATLAB, and the origin of
the name of the ‘bsxfun’ function), _recycling_ (R programming
language), _single-instruction multiple data_ (SIMD), or _replication_.

19.2.1 Broadcasting and Legacy Code
-----------------------------------

The new broadcasting semantics almost never affect code that worked in
previous versions of Octave.  Consequently, all code inherited from
MATLAB that worked in previous versions of Octave should still work
without change in Octave.  The only exception is code such as

     try
       c = a.*b;
     catch
       c = a.*a;
     end_try_catch

that may have relied on matrices of different size producing an error.
Because such operation is now valid Octave syntax, this will no longer
produce an error.  Instead, the following code should be used:

     if (isequal (size (a), size (b)))
       c = a .* b;
     else
       c = a .* a;
     endif


File: octave.info,  Node: Function Application,  Next: Accumulation,  Prev: Broadcasting,  Up: Vectorization and Faster Code Execution

19.3 Function Application
=========================

As a general rule, functions should already be written with matrix
arguments in mind and should consider whole matrix operations in a
vectorized manner.  Sometimes, writing functions in this way appears
difficult or impossible for various reasons.  For those situations,
Octave provides facilities for applying a function to each element of an
array, cell, or struct.

 -- : arrayfun (FUNC, A)
 -- : X = arrayfun (FUNC, A)
 -- : X = arrayfun (FUNC, A, B, ...)
 -- : [X, Y, ...] = arrayfun (FUNC, A, ...)
 -- : arrayfun (..., "UniformOutput", VAL)
 -- : arrayfun (..., "ErrorHandler", ERRFUNC)

     Execute a function on each element of an array.

     This is useful for functions that do not accept array arguments.
     If the function does accept array arguments it is better to call
     the function directly.

     The first input argument FUNC can be a string, a function handle,
     an inline function, or an anonymous function.  The input argument A
     can be a logic array, a numeric array, a string array, a structure
     array, or a cell array.  By a call of the function ‘arrayfun’ all
     elements of A are passed on to the named function FUNC
     individually.

     The named function can also take more than two input arguments,
     with the input arguments given as third input argument B, fourth
     input argument C, ... If given more than one array input argument
     then all input arguments must have the same sizes, for example:

          arrayfun (@atan2, [1, 0], [0, 1])
               ⇒ [ 1.57080   0.00000 ]

     If the parameter VAL after a further string input argument
     "UniformOutput" is set ‘true’ (the default), then the named
     function FUNC must return a single element which then will be
     concatenated into the return value and is of type matrix.
     Otherwise, if that parameter is set to ‘false’, then the outputs
     are concatenated in a cell array.  For example:

          arrayfun (@(x,y) x:y, "abc", "def", "UniformOutput", false)
          ⇒
             {
               [1,1] = abcd
               [1,2] = bcde
               [1,3] = cdef
             }

     If more than one output arguments are given then the named function
     must return the number of return values that also are expected, for
     example:

          [A, B, C] = arrayfun (@find, [10; 0], "UniformOutput", false)
          ⇒
          A =
          {
             [1,1] =  1
             [2,1] = [](0x0)
          }
          B =
          {
             [1,1] =  1
             [2,1] = [](0x0)
          }
          C =
          {
             [1,1] =  10
             [2,1] = [](0x0)
          }

     If the parameter ERRFUNC after a further string input argument
     "ErrorHandler" is another string, a function handle, an inline
     function, or an anonymous function, then ERRFUNC defines a function
     to call in the case that FUNC generates an error.  The definition
     of the function must be of the form

          function [...] = errfunc (S, ...)

     where there is an additional input argument to ERRFUNC relative to
     FUNC, given by S.  This is a structure with the elements
     "identifier", "message", and "index" giving, respectively, the
     error identifier, the error message, and the index of the array
     elements that caused the error.  The size of the output argument of
     ERRFUNC must have the same size as the output argument of FUNC,
     otherwise a real error is thrown.  For example:

          function y = ferr (s, x), y = "MyString"; endfunction
          arrayfun (@str2num, [1234],
                    "UniformOutput", false, "ErrorHandler", @ferr)
          ⇒
             {
               [1,1] = MyString
             }

     See also: *note spfun: XREFspfun, *note cellfun: XREFcellfun, *note
     structfun: XREFstructfun.

 -- : Y = spfun (F, S)
     Compute ‘f(S)’ for the nonzero values of S.

     This results in a sparse matrix with the same structure as S.  The
     function F can be passed as a string, a function handle, or an
     inline function.

     See also: *note arrayfun: XREFarrayfun, *note cellfun: XREFcellfun,
     *note structfun: XREFstructfun.

 -- : cellfun (NAME, C)
 -- : cellfun ("size", C, K)
 -- : cellfun ("isclass", C, CLASS)
 -- : cellfun (FUNC, C)
 -- : cellfun (FUNC, C, D)
 -- : [A, ...] = cellfun (...)
 -- : cellfun (..., "ErrorHandler", ERRFUNC)
 -- : cellfun (..., "UniformOutput", VAL)

     Evaluate the function named NAME on the elements of the cell array
     C.

     Elements in C are passed on to the named function individually.
     The function NAME can be one of the functions

     ‘isempty’
          Return 1 for empty elements.

     ‘islogical’
          Return 1 for logical elements.

     ‘isnumeric’
          Return 1 for numeric elements.

     ‘isreal’
          Return 1 for real elements.

     ‘length’
          Return a vector of the lengths of cell elements.

     ‘ndims’
          Return the number of dimensions of each element.

     ‘numel’
     ‘prodofsize’
          Return the number of elements contained within each cell
          element.  The number is the product of the dimensions of the
          object at each cell element.

     ‘size’
          Return the size along the K-th dimension.

     ‘isclass’
          Return 1 for elements of CLASS.

     Additionally, ‘cellfun’ accepts an arbitrary function FUNC in the
     form of an inline function, function handle, or the name of a
     function (in a character string).  The function can take one or
     more arguments, with the inputs arguments given by C, D, etc.
     Equally the function can return one or more output arguments.  For
     example:

          cellfun ("atan2", {1, 0}, {0, 1})
               ⇒ [ 1.57080   0.00000 ]

     The number of output arguments of ‘cellfun’ matches the number of
     output arguments of the function.  The outputs of the function will
     be collected into the output arguments of ‘cellfun’ like this:

          function [a, b] = twoouts (x)
            a = x;
            b = x*x;
          endfunction
          [aa, bb] = cellfun (@twoouts, {1, 2, 3})
               ⇒
                  aa =
                     1 2 3
                  bb =
                     1 4 9

     Note that per default the output argument(s) are arrays of the same
     size as the input arguments.  Input arguments that are singleton
     (1x1) cells will be automatically expanded to the size of the other
     arguments.

     If the parameter "UniformOutput" is set to true (the default), then
     the function must return scalars which will be concatenated into
     the return array(s).  If "UniformOutput" is false, the outputs are
     concatenated into a cell array (or cell arrays).  For example:

          cellfun ("tolower", {"Foo", "Bar", "FooBar"},
                   "UniformOutput", false)
          ⇒ {"foo", "bar", "foobar"}

     Given the parameter "ErrorHandler", then ERRFUNC defines a function
     to call in case FUNC generates an error.  The form of the function
     is

          function [...] = errfunc (S, ...)

     where there is an additional input argument to ERRFUNC relative to
     FUNC, given by S.  This is a structure with the elements
     "identifier", "message", and "index" giving respectively the error
     identifier, the error message, and the index into the input
     arguments of the element that caused the error.  For example:

          function y = foo (s, x), y = NaN; endfunction
          cellfun ("factorial", {-1,2}, "ErrorHandler", @foo)
          ⇒ [NaN 2]

     Use ‘cellfun’ intelligently.  The ‘cellfun’ function is a useful
     tool for avoiding loops.  It is often used with anonymous function
     handles; however, calling an anonymous function involves an
     overhead quite comparable to the overhead of an m-file function.
     Passing a handle to a built-in function is faster, because the
     interpreter is not involved in the internal loop.  For example:

          a = {...}
          v = cellfun (@(x) det (x), a); # compute determinants
          v = cellfun (@det, a); # faster

     See also: *note arrayfun: XREFarrayfun, *note structfun:
     XREFstructfun, *note spfun: XREFspfun.

 -- : structfun (FUNC, S)
 -- : [A, ...] = structfun (...)
 -- : structfun (..., "ErrorHandler", ERRFUNC)
 -- : structfun (..., "UniformOutput", VAL)

     Evaluate the function named NAME on the fields of the structure S.
     The fields of S are passed to the function FUNC individually.

     ‘structfun’ accepts an arbitrary function FUNC in the form of an
     inline function, function handle, or the name of a function (in a
     character string).  In the case of a character string argument, the
     function must accept a single argument named X, and it must return
     a string value.  If the function returns more than one argument,
     they are returned as separate output variables.

     If the parameter "UniformOutput" is set to true (the default), then
     the function must return a single element which will be
     concatenated into the return value.  If "UniformOutput" is false,
     the outputs are placed into a structure with the same fieldnames as
     the input structure.

          s.name1 = "John Smith";
          s.name2 = "Jill Jones";
          structfun (@(x) regexp (x, '(\w+)$', "matches"){1}, s,
                     "UniformOutput", false)
            ⇒ scalar structure containing the fields:
                 name1 = Smith
                 name2 = Jones

     Given the parameter "ErrorHandler", ERRFUNC defines a function to
     call in case FUNC generates an error.  The form of the function is

          function [...] = errfunc (SE, ...)

     where there is an additional input argument to ERRFUNC relative to
     FUNC, given by SE.  This is a structure with the elements
     "identifier", "message" and "index", giving respectively the error
     identifier, the error message, and the index into the input
     arguments of the element that caused the error.  For an example on
     how to use an error handler, *note cellfun: XREFcellfun.

     See also: *note cellfun: XREFcellfun, *note arrayfun: XREFarrayfun,
     *note spfun: XREFspfun.

   Consistent with earlier advice, seek to use Octave built-in functions
whenever possible for the best performance.  This advice applies
especially to the four functions above.  For example, when adding two
arrays together element-by-element one could use a handle to the
built-in addition function ‘@plus’ or define an anonymous function
‘@(x,y) x + y’.  But, the anonymous function is 60% slower than the
first method.  *Note Operator Overloading::, for a list of basic
functions which might be used in place of anonymous ones.


File: octave.info,  Node: Accumulation,  Next: JIT Compiler,  Prev: Function Application,  Up: Vectorization and Faster Code Execution

19.4 Accumulation
=================

Whenever it’s possible to categorize according to indices the elements
of an array when performing a computation, accumulation functions can be
useful.

 -- : accumarray (SUBS, VALS, SZ, FUNC, FILLVAL, ISSPARSE)
 -- : accumarray (SUBS, VALS, ...)

     Create an array by accumulating the elements of a vector into the
     positions defined by their subscripts.

     The subscripts are defined by the rows of the matrix SUBS and the
     values by VALS.  Each row of SUBS corresponds to one of the values
     in VALS.  If VALS is a scalar, it will be used for each of the row
     of SUBS.  If SUBS is a cell array of vectors, all vectors must be
     of the same length, and the subscripts in the Kth vector must
     correspond to the Kth dimension of the result.

     The size of the matrix will be determined by the subscripts
     themselves.  However, if SZ is defined it determines the matrix
     size.  The length of SZ must correspond to the number of columns in
     SUBS.  An exception is if SUBS has only one column, in which case
     SZ may be the dimensions of a vector and the subscripts of SUBS are
     taken as the indices into it.

     The default action of ‘accumarray’ is to sum the elements with the
     same subscripts.  This behavior can be modified by defining the
     FUNC function.  This should be a function or function handle that
     accepts a column vector and returns a scalar.  The result of the
     function should not depend on the order of the subscripts.

     The elements of the returned array that have no subscripts
     associated with them are set to zero.  Defining FILLVAL to some
     other value allows these values to be defined.  This behavior
     changes, however, for certain values of FUNC.  If FUNC is ‘@min’
     (respectively, ‘@max’) then the result will be filled with the
     minimum (respectively, maximum) integer if VALS is of integral
     type, logical false (respectively, logical true) if VALS is of
     logical type, zero if FILLVAL is zero and all values are
     non-positive (respectively, non-negative), and NaN otherwise.

     By default ‘accumarray’ returns a full matrix.  If ISSPARSE is
     logically true, then a sparse matrix is returned instead.

     The following ‘accumarray’ example constructs a frequency table
     that in the first column counts how many occurrences each number in
     the second column has, taken from the vector X.  Note the usage of
     ‘unique’ for assigning to all repeated elements of X the same index
     (*note unique: XREFunique.).

          X = [91, 92, 90, 92, 90, 89, 91, 89, 90, 100, 100, 100];
          [U, ~, J] = unique (X);
          [accumarray(J', 1), U']
            ⇒  2    89
                3    90
                2    91
                2    92
                3   100

     Another example, where the result is a multi-dimensional 3-D array
     and the default value (zero) appears in the output:

          accumarray ([1, 1, 1;
                       2, 1, 2;
                       2, 3, 2;
                       2, 1, 2;
                       2, 3, 2], 101:105)
          ⇒ ans(:,:,1) = [101, 0, 0; 0, 0, 0]
          ⇒ ans(:,:,2) = [0, 0, 0; 206, 0, 208]

     The sparse option can be used as an alternative to the ‘sparse’
     constructor (*note sparse: XREFsparse.).  Thus

          sparse (I, J, SV)

     can be written with ‘accumarray’ as

          accumarray ([I, J], SV', [], [], 0, true)

     For repeated indices, ‘sparse’ adds the corresponding value.  To
     take the minimum instead, use ‘min’ as an accumulator function:

          accumarray ([I, J], SV', [], @min, 0, true)

     The complexity of accumarray in general for the non-sparse case is
     generally O(M+N), where N is the number of subscripts and M is the
     maximum subscript (linearized in multi-dimensional case).  If FUNC
     is one of ‘@sum’ (default), ‘@max’, ‘@min’ or ‘@(x) {x}’, an
     optimized code path is used.  Note that for general reduction
     function the interpreter overhead can play a major part and it may
     be more efficient to do multiple accumarray calls and compute the
     results in a vectorized manner.

     See also: *note accumdim: XREFaccumdim, *note unique: XREFunique,
     *note sparse: XREFsparse.

 -- : accumdim (SUBS, VALS, DIM, N, FUNC, FILLVAL)
     Create an array by accumulating the slices of an array into the
     positions defined by their subscripts along a specified dimension.

     The subscripts are defined by the index vector SUBS.  The dimension
     is specified by DIM.  If not given, it defaults to the first
     non-singleton dimension.  The length of SUBS must be equal to ‘size
     (VALS, DIM)’.

     The extent of the result matrix in the working dimension will be
     determined by the subscripts themselves.  However, if N is defined
     it determines this extent.

     The default action of ‘accumdim’ is to sum the subarrays with the
     same subscripts.  This behavior can be modified by defining the
     FUNC function.  This should be a function or function handle that
     accepts an array and a dimension, and reduces the array along this
     dimension.  As a special exception, the built-in ‘min’ and ‘max’
     functions can be used directly, and ‘accumdim’ accounts for the
     middle empty argument that is used in their calling.

     The slices of the returned array that have no subscripts associated
     with them are set to zero.  Defining FILLVAL to some other value
     allows these values to be defined.

     An example of the use of ‘accumdim’ is:

          accumdim ([1, 2, 1, 2, 1], [ 7, -10,   4;
                                      -5, -12,   8;
                                     -12,   2,   8;
                                     -10,   9,  -3;
                                      -5,  -3, -13])
          ⇒ [-10,-11,-1;-15,-3,5]

     See also: *note accumarray: XREFaccumarray.


File: octave.info,  Node: JIT Compiler,  Next: Miscellaneous Techniques,  Prev: Accumulation,  Up: Vectorization and Faster Code Execution

19.5 JIT Compiler
=================

Vectorization is the preferred technique for eliminating loops and
speeding up code.  Nevertheless, it is not always possible to replace
every loop.  In such situations it may be worth trying Octave’s
*experimental* Just-In-Time (JIT) compiler.

   A JIT compiler works by analyzing the body of a loop, translating the
Octave statements into another language, compiling the new code segment
into an executable, and then running the executable and collecting any
results.  The process is not simple and there is a significant amount of
work to perform for each step.  It can still make sense, however, if the
number of loop iterations is large.  Because Octave is an interpreted
language every time through a loop Octave must parse the statements in
the loop body before executing them.  With a JIT compiler this is done
just once when the body is translated to another language.

   The JIT compiler is a very new feature in Octave and not all valid
Octave statements can currently be accelerated.  However, if no other
technique is available it may be worth benchmarking the code with JIT
enabled.  The function ‘jit_enable’ is used to turn compilation on or
off.  The function ‘jit_startcnt’ sets the threshold for acceleration.
Loops with iteration counts above ‘jit_startcnt’ will be accelerated.
The functions ‘jit_failcnt’ and ‘debug_jit’ are not likely to be of use
to anyone not working directly on the implementation of the JIT
compiler.

 -- : VAL = jit_enable ()
 -- : OLD_VAL = jit_enable (NEW_VAL)
 -- : jit_enable (NEW_VAL, "local")
     Query or set the internal variable that enables Octave’s JIT
     compiler.

     When called from inside a function with the "local" option, the
     variable is changed locally for the function and any subroutines it
     calls.  The original variable value is restored when exiting the
     function.

     See also: *note jit_startcnt: XREFjit_startcnt, *note debug_jit:
     XREFdebug_jit.

 -- : VAL = jit_startcnt ()
 -- : OLD_VAL = jit_startcnt (NEW_VAL)
 -- : jit_startcnt (NEW_VAL, "local")
     Query or set the internal variable that determines whether JIT
     compilation will take place for a specific loop.

     Because compilation is a costly operation it does not make sense to
     employ JIT when the loop count is low.  By default only loops with
     greater than 1000 iterations will be accelerated.

     When called from inside a function with the "local" option, the
     variable is changed locally for the function and any subroutines it
     calls.  The original variable value is restored when exiting the
     function.

     See also: *note jit_enable: XREFjit_enable, *note jit_failcnt:
     XREFjit_failcnt, *note debug_jit: XREFdebug_jit.

 -- : VAL = jit_failcnt ()
 -- : OLD_VAL = jit_failcnt (NEW_VAL)
 -- : jit_failcnt (NEW_VAL, "local")
     Query or set the internal variable that counts the number of JIT
     fail exceptions for Octave’s JIT compiler.

     When called from inside a function with the "local" option, the
     variable is changed locally for the function and any subroutines it
     calls.  The original variable value is restored when exiting the
     function.

     See also: *note jit_enable: XREFjit_enable, *note jit_startcnt:
     XREFjit_startcnt, *note debug_jit: XREFdebug_jit.

 -- : VAL = debug_jit ()
 -- : OLD_VAL = debug_jit (NEW_VAL)
 -- : debug_jit (NEW_VAL, "local")
     Query or set the internal variable that determines whether
     debugging/tracing is enabled for Octave’s JIT compiler.

     When called from inside a function with the "local" option, the
     variable is changed locally for the function and any subroutines it
     calls.  The original variable value is restored when exiting the
     function.

     See also: *note jit_enable: XREFjit_enable, *note jit_startcnt:
     XREFjit_startcnt.


File: octave.info,  Node: Miscellaneous Techniques,  Next: Examples,  Prev: JIT Compiler,  Up: Vectorization and Faster Code Execution

19.6 Miscellaneous Techniques
=============================

Here are some other ways of improving the execution speed of Octave
programs.

   • Avoid computing costly intermediate results multiple times.  Octave
     currently does not eliminate common subexpressions.  Also, certain
     internal computation results are cached for variables.  For
     instance, if a matrix variable is used multiple times as an index,
     checking the indices (and internal conversion to integers) is only
     done once.

   • Be aware of lazy copies (copy-on-write).  When a copy of an object
     is created, the data is not immediately copied, but rather shared.
     The actual copying is postponed until the copied data needs to be
     modified.  For example:

          a = zeros (1000); # create a 1000x1000 matrix
          b = a; # no copying done here
          b(1) = 1; # copying done here

     Lazy copying applies to whole Octave objects such as matrices,
     cells, struct, and also individual cell or struct elements (not
     array elements).

     Additionally, index expressions also use lazy copying when Octave
     can determine that the indexed portion is contiguous in memory.
     For example:

          a = zeros (1000); # create a 1000x1000 matrix
          b = a(:,10:100);  # no copying done here
          b = a(10:100,:);  # copying done here

     This applies to arrays (matrices), cell arrays, and structs indexed
     using ‘()’.  Index expressions generating comma-separated lists can
     also benefit from shallow copying in some cases.  In particular,
     when A is a struct array, expressions like ‘{a.x}, {a(:,2).x}’ will
     use lazy copying, so that data can be shared between a struct array
     and a cell array.

     Most indexing expressions do not live longer than their parent
     objects.  In rare cases, however, a lazily copied slice outlasts
     its parent, in which case it becomes orphaned, still occupying
     unnecessarily more memory than needed.  To provide a remedy working
     in most real cases, Octave checks for orphaned lazy slices at
     certain situations, when a value is stored into a "permanent"
     location, such as a named variable or cell or struct element, and
     possibly economizes them.  For example:

          a = zeros (1000); # create a 1000x1000 matrix
          b = a(:,10:100);  # lazy slice
          a = []; # the original "a" array is still allocated
          c{1} = b; # b is reallocated at this point

   • Avoid deep recursion.  Function calls to m-file functions carry a
     relatively significant overhead, so rewriting a recursion as a loop
     often helps.  Also, note that the maximum level of recursion is
     limited.

   • Avoid resizing matrices unnecessarily.  When building a single
     result matrix from a series of calculations, set the size of the
     result matrix first, then insert values into it.  Write

          result = zeros (big_n, big_m)
          for i = over:and_over
            ridx = ...
            cidx = ...
            result(ridx, cidx) = new_value ();
          endfor

     instead of

          result = [];
          for i = ever:and_ever
            result = [ result, new_value() ];
          endfor

     Sometimes the number of items can not be computed in advance, and
     stack-like operations are needed.  When elements are being
     repeatedly inserted or removed from the end of an array, Octave
     detects it as stack usage and attempts to use a smarter memory
     management strategy by pre-allocating the array in bigger chunks.
     This strategy is also applied to cell and struct arrays.

          a = [];
          while (condition)
            ...
            a(end+1) = value; # "push" operation
            ...
            a(end) = []; # "pop" operation
            ...
          endwhile

   • Avoid calling ‘eval’ or ‘feval’ excessively.  Parsing input or
     looking up the name of a function in the symbol table are
     relatively expensive operations.

     If you are using ‘eval’ merely as an exception handling mechanism,
     and not because you need to execute some arbitrary text, use the
     ‘try’ statement instead.  *Note The try Statement::.

   • Use ‘ignore_function_time_stamp’ when appropriate.  If you are
     calling lots of functions, and none of them will need to change
     during your run, set the variable ‘ignore_function_time_stamp’ to
     "all".  This will stop Octave from checking the time stamp of a
     function file to see if it has been updated while the program is
     being run.


File: octave.info,  Node: Examples,  Prev: Miscellaneous Techniques,  Up: Vectorization and Faster Code Execution

19.7 Examples
=============

The following are examples of vectorization questions asked by actual
users of Octave and their solutions.

   • For a vector ‘A’, the following loop

          n = length (A);
          B = zeros (n, 2);
          for i = 1:length (A)
            ## this will be two columns, the first is the difference and
            ## the second the mean of the two elements used for the diff.
            B(i,:) = [A(i+1)-A(i), (A(i+1) + A(i))/2];
          endfor

     can be turned into the following one-liner:

          B = [diff(A)(:), 0.5*(A(1:end-1)+A(2:end))(:)]

     Note the usage of colon indexing to flatten an intermediate result
     into a column vector.  This is a common vectorization trick.


File: octave.info,  Node: Nonlinear Equations,  Next: Diagonal and Permutation Matrices,  Prev: Vectorization and Faster Code Execution,  Up: Top

20 Nonlinear Equations
**********************

* Menu:

* Solvers::
* Minimizers::


File: octave.info,  Node: Solvers,  Next: Minimizers,  Up: Nonlinear Equations

20.1 Solvers
============

Octave can solve sets of nonlinear equations of the form

     F (x) = 0

using the function ‘fsolve’, which is based on the MINPACK subroutine
‘hybrd’.  This is an iterative technique so a starting point must be
provided.  This also has the consequence that convergence is not
guaranteed even if a solution exists.

 -- : fsolve (FCN, X0)
 -- : fsolve (FCN, X0, OPTIONS)
 -- : [X, FVAL, INFO, OUTPUT, FJAC] = fsolve (...)
     Solve a system of nonlinear equations defined by the function FCN.

     FCN should accept a vector (array) defining the unknown variables,
     and return a vector of left-hand sides of the equations.
     Right-hand sides are defined to be zeros.  In other words, this
     function attempts to determine a vector X such that ‘FCN (X)’ gives
     (approximately) all zeros.

     X0 is an initial guess for the solution.  The shape of X0 is
     preserved in all calls to FCN, but otherwise is treated as a column
     vector.

     OPTIONS is a structure specifying additional parameters which
     control the algorithm.  Currently, ‘fsolve’ recognizes these
     options: "AutoScaling", "ComplexEqn", "FinDiffType", "FunValCheck",
     "Jacobian", "MaxFunEvals", "MaxIter", "OutputFcn", "TolFun",
     "TolX", "TypicalX", and "Updating".

     If "AutoScaling" is "on", the variables will be automatically
     scaled according to the column norms of the (estimated) Jacobian.
     As a result, "TolFun" becomes scaling-independent.  By default,
     this option is "off" because it may sometimes deliver unexpected
     (though mathematically correct) results.

     If "ComplexEqn" is "on", ‘fsolve’ will attempt to solve complex
     equations in complex variables, assuming that the equations possess
     a complex derivative (i.e., are holomorphic).  If this is not what
     you want, you should unpack the real and imaginary parts of the
     system to get a real system.

     If "Jacobian" is "on", it specifies that FCN—when called with 2
     output arguments—also returns the Jacobian matrix of right-hand
     sides at the requested point.

     "MaxFunEvals" proscribes the maximum number of function evaluations
     before optimization is halted.  The default value is ‘100 *
     number_of_variables’, i.e., ‘100 * length (X0)’.  The value must be
     a positive integer.

     If "Updating" is "on", the function will attempt to use Broyden
     updates to update the Jacobian, in order to reduce the number of
     Jacobian calculations.  If your user function always calculates the
     Jacobian (regardless of number of output arguments) then this
     option provides no advantage and should be disabled.

     "TolX" specifies the termination tolerance in the unknown
     variables, while "TolFun" is a tolerance for equations.  Default is
     ‘1e-6’ for both "TolX" and "TolFun".

     For a description of the other options, see ‘optimset’.  To
     initialize an options structure with default values for ‘fsolve’
     use ‘options = optimset ("fsolve")’.

     The first output X is the solution while the second output FVAL
     contains the value of the function FCN evaluated at X (ideally a
     vector of all zeros).

     The third output INFO reports whether the algorithm succeeded and
     may take one of the following values:

     1
          Converged to a solution point.  Relative residual error is
          less than specified by ‘TolFun’.

     2
          Last relative step size was less than ‘TolX’.

     3
          Last relative decrease in residual was less than ‘TolFun’.

     0
          Iteration limit (either ‘MaxIter’ or ‘MaxFunEvals’) exceeded.

     -1
          Stopped by ‘OutputFcn’.

     -3
          The trust region radius became excessively small.

     OUTPUT is a structure containing runtime information about the
     ‘fsolve’ algorithm.  Fields in the structure are:

     ‘iterations’
          Number of iterations through loop.

     ‘successful’
          Number of successful iterations.

     ‘funcCount’
          Number of function evaluations.

     The final output FJAC contains the value of the Jacobian evaluated
     at X.

     Note: If you only have a single nonlinear equation of one variable,
     using ‘fzero’ is usually a much better idea.

     Note about user-supplied Jacobians: As an inherent property of the
     algorithm, a Jacobian is always requested for a solution vector
     whose residual vector is already known, and it is the last accepted
     successful step.  Often this will be one of the last two calls, but
     not always.  If the savings by reusing intermediate results from
     residual calculation in Jacobian calculation are significant, the
     best strategy is to employ ‘OutputFcn’: After a vector is evaluated
     for residuals, if ‘OutputFcn’ is called with that vector, then the
     intermediate results should be saved for future Jacobian
     evaluation, and should be kept until a Jacobian evaluation is
     requested or until ‘OutputFcn’ is called with a different vector,
     in which case they should be dropped in favor of this most recent
     vector.  A short example how this can be achieved follows:

          function [fval, fjac] = user_func (x, optimvalues, state)
          persistent sav = [], sav0 = [];
          if (nargin == 1)
            ## evaluation call
            if (nargout == 1)
              sav0.x = x; # mark saved vector
              ## calculate fval, save results to sav0.
            elseif (nargout == 2)
              ## calculate fjac using sav.
            endif
          else
            ## outputfcn call.
            if (all (x == sav0.x))
              sav = sav0;
            endif
            ## maybe output iteration status, etc.
          endif
          endfunction

          ## ...

          fsolve (@user_func, x0, optimset ("OutputFcn", @user_func, ...))

     See also: *note fzero: XREFfzero, *note optimset: XREFoptimset.

   The following is a complete example.  To solve the set of equations

     -2x^2 + 3xy   + 4 sin(y) = 6
      3x^2 - 2xy^2 + 3 cos(x) = -4

you first need to write a function to compute the value of the given
function.  For example:

     function y = f (x)
       y = zeros (2, 1);
       y(1) = -2*x(1)^2 + 3*x(1)*x(2)   + 4*sin(x(2)) - 6;
       y(2) =  3*x(1)^2 - 2*x(1)*x(2)^2 + 3*cos(x(1)) + 4;
     endfunction

   Then, call ‘fsolve’ with a specified initial condition to find the
roots of the system of equations.  For example, given the function ‘f’
defined above,

     [x, fval, info] = fsolve (@f, [1; 2])

results in the solution

     x =

       0.57983
       2.54621

     fval =

       -5.7184e-10
        5.5460e-10

     info = 1

A value of ‘info = 1’ indicates that the solution has converged.

   When no Jacobian is supplied (as in the example above) it is
approximated numerically.  This requires more function evaluations, and
hence is less efficient.  In the example above we could compute the
Jacobian analytically as

     function [y, jac] = f (x)
       y = zeros (2, 1);
       y(1) = -2*x(1)^2 + 3*x(1)*x(2)   + 4*sin(x(2)) - 6;
       y(2) =  3*x(1)^2 - 2*x(1)*x(2)^2 + 3*cos(x(1)) + 4;
       if (nargout == 2)
         jac = zeros (2, 2);
         jac(1,1) =  3*x(2) - 4*x(1);
         jac(1,2) =  4*cos(x(2)) + 3*x(1);
         jac(2,1) = -2*x(2)^2 - 3*sin(x(1)) + 6*x(1);
         jac(2,2) = -4*x(1)*x(2);
       endif
     endfunction

The Jacobian can then be used with the following call to ‘fsolve’:

     [x, fval, info] = fsolve (@f, [1; 2], optimset ("jacobian", "on"));

which gives the same solution as before.

 -- : fzero (FUN, X0)
 -- : fzero (FUN, X0, OPTIONS)
 -- : [X, FVAL, INFO, OUTPUT] = fzero (...)
     Find a zero of a univariate function.

     FUN is a function handle, inline function, or string containing the
     name of the function to evaluate.

     X0 should be a two-element vector specifying two points which
     bracket a zero.  In other words, there must be a change in sign of
     the function between X0(1) and X0(2).  More mathematically, the
     following must hold

          sign (FUN(X0(1))) * sign (FUN(X0(2))) <= 0

     If X0 is a single scalar then several nearby and distant values are
     probed in an attempt to obtain a valid bracketing.  If this is not
     successful, the function fails.

     OPTIONS is a structure specifying additional options.  Currently,
     ‘fzero’ recognizes these options: "FunValCheck", "MaxFunEvals",
     "MaxIter", "OutputFcn", and "TolX".

     "MaxFunEvals" proscribes the maximum number of function evaluations
     before the search is halted.  The default value is ‘Inf’.  The
     value must be a positive integer.

     "MaxIter" proscribes the maximum number of algorithm iterations
     before the search is halted.  The default value is ‘Inf’.  The
     value must be a positive integer.

     "TolX" specifies the termination tolerance for the solution X.  The
     default value is ‘eps’.

     For a description of the other options, see *note optimset:
     XREFoptimset.  To initialize an options structure with default
     values for ‘fzero’ use ‘options = optimset ("fzero")’.

     On exit, the function returns X, the approximate zero point, and
     FVAL, the function evaluated at X.

     The third output INFO reports whether the algorithm succeeded and
     may take one of the following values:

        • 1 The algorithm converged to a solution.

        • 0 Maximum number of iterations or function evaluations has
          been reached.

        • -1 The algorithm has been terminated by a user ‘OutputFcn’.

        • -5 The algorithm may have converged to a singular point.

     OUTPUT is a structure containing runtime information about the
     ‘fzero’ algorithm.  Fields in the structure are:

        • iterations Number of iterations through loop.

        • funcCount Number of function evaluations.

        • algorithm The string "bisection, interpolation".

        • bracketx A two-element vector with the final bracketing of the
          zero along the x-axis.

        • brackety A two-element vector with the final bracketing of the
          zero along the y-axis.

     See also: *note optimset: XREFoptimset, *note fsolve: XREFfsolve.


File: octave.info,  Node: Minimizers,  Prev: Solvers,  Up: Nonlinear Equations

20.2 Minimizers
===============

Often it is useful to find the minimum value of a function rather than
just the zeroes where it crosses the x-axis.  ‘fminbnd’ is designed for
the simpler, but very common, case of a univariate function where the
interval to search is bounded.  For unbounded minimization of a function
with potentially many variables use ‘fminunc’ or ‘fminsearch’.  The two
functions use different internal algorithms and some knowledge of the
objective function is required.  For functions which can be
differentiated, ‘fminunc’ is appropriate.  For functions with
discontinuities, or for which a gradient search would fail, use
‘fminsearch’.  *Note Optimization::, for minimization with the presence
of constraint functions.  Note that searches can be made for maxima by
simply inverting the objective function (‘Fto_max = -Fto_min’).

 -- : X = fminbnd (FUN, A, B)
 -- : X = fminbnd (FUN, A, B, OPTIONS)
 -- : [X, FVAL, INFO, OUTPUT] = fminbnd (...)
     Find a minimum point of a univariate function.

     FUN must be a function handle or name.

     The starting interval is specified by A (left boundary) and B
     (right boundary).  The endpoints must be finite.

     OPTIONS is a structure specifying additional parameters which
     control the algorithm.  Currently, ‘fminbnd’ recognizes these
     options: "Display", "FunValCheck", "MaxFunEvals", "MaxIter",
     "OutputFcn", "TolX".

     "MaxFunEvals" proscribes the maximum number of function evaluations
     before optimization is halted.  The default value is 500.  The
     value must be a positive integer.

     "MaxIter" proscribes the maximum number of algorithm iterations
     before optimization is halted.  The default value is 500.  The
     value must be a positive integer.

     "TolX" specifies the termination tolerance for the solution X.  The
     default is ‘1e-4’.

     For a description of the other options, see *note optimset:
     XREFoptimset.  To initialize an options structure with default
     values for ‘fminbnd’ use ‘options = optimset ("fminbnd")’.

     On exit, the function returns X, the approximate minimum point, and
     FVAL, the function evaluated X.

     The third output INFO reports whether the algorithm succeeded and
     may take one of the following values:

        • 1 The algorithm converged to a solution.

        • 0 Iteration limit (either ‘MaxIter’ or ‘MaxFunEvals’)
          exceeded.

        • -1 The algorithm was terminated by a user ‘OutputFcn’.

     Programming Notes: The search for a minimum is restricted to be in
     the finite interval bound by A and B.  If you have only one initial
     point to begin searching from then you will need to use an
     unconstrained minimization algorithm such as ‘fminunc’ or
     ‘fminsearch’.  ‘fminbnd’ internally uses a Golden Section search
     strategy.

     See also: *note fzero: XREFfzero, *note fminunc: XREFfminunc, *note
     fminsearch: XREFfminsearch, *note optimset: XREFoptimset.

 -- : fminunc (FCN, X0)
 -- : fminunc (FCN, X0, OPTIONS)
 -- : [X, FVAL, INFO, OUTPUT, GRAD, HESS] = fminunc (FCN, ...)
     Solve an unconstrained optimization problem defined by the function
     FCN.

     FCN should accept a vector (array) defining the unknown variables,
     and return the objective function value, optionally with gradient.
     ‘fminunc’ attempts to determine a vector X such that ‘FCN (X)’ is a
     local minimum.

     X0 determines a starting guess.  The shape of X0 is preserved in
     all calls to FCN, but otherwise is treated as a column vector.

     OPTIONS is a structure specifying additional parameters which
     control the algorithm.  Currently, ‘fminunc’ recognizes these
     options: "AutoScaling", "FinDiffType", "FunValCheck", "GradObj",
     "MaxFunEvals", "MaxIter", "OutputFcn", "TolFun", "TolX",
     "TypicalX".

     If "AutoScaling" is "on", the variables will be automatically
     scaled according to the column norms of the (estimated) Jacobian.
     As a result, "TolFun" becomes scaling-independent.  By default,
     this option is "off" because it may sometimes deliver unexpected
     (though mathematically correct) results.

     If "GradObj" is "on", it specifies that FCN–when called with two
     output arguments—also returns the Jacobian matrix of partial first
     derivatives at the requested point.

     "MaxFunEvals" proscribes the maximum number of function evaluations
     before optimization is halted.  The default value is ‘100 *
     number_of_variables’, i.e., ‘100 * length (X0)’.  The value must be
     a positive integer.

     "MaxIter" proscribes the maximum number of algorithm iterations
     before optimization is halted.  The default value is 400.  The
     value must be a positive integer.

     "TolX" specifies the termination tolerance for the unknown
     variables X, while "TolFun" is a tolerance for the objective
     function value FVAL.  The default is ‘1e-6’ for both options.

     For a description of the other options, see ‘optimset’.

     On return, X is the location of the minimum and FVAL contains the
     value of the objective function at X.

     INFO may be one of the following values:

     1
          Converged to a solution point.  Relative gradient error is
          less than specified by ‘TolFun’.

     2
          Last relative step size was less than ‘TolX’.

     3
          Last relative change in function value was less than ‘TolFun’.

     0
          Iteration limit exceeded—either maximum number of algorithm
          iterations ‘MaxIter’ or maximum number of function evaluations
          ‘MaxFunEvals’.

     -1
          Algorithm terminated by ‘OutputFcn’.

     -3
          The trust region radius became excessively small.

     Optionally, ‘fminunc’ can return a structure with convergence
     statistics (OUTPUT), the output gradient (GRAD) at the solution X,
     and approximate Hessian (HESS) at the solution X.

     Application Notes: If the objective function is a single nonlinear
     equation of one variable then using ‘fminbnd’ is usually a better
     choice.

     The algorithm used by ‘fminunc’ is a gradient search which depends
     on the objective function being differentiable.  If the function
     has discontinuities it may be better to use a derivative-free
     algorithm such as ‘fminsearch’.

     See also: *note fminbnd: XREFfminbnd, *note fminsearch:
     XREFfminsearch, *note optimset: XREFoptimset.

 -- : X = fminsearch (FUN, X0)
 -- : X = fminsearch (FUN, X0, OPTIONS)
 -- : X = fminsearch (PROBLEM)
 -- : [X, FVAL, EXITFLAG, OUTPUT] = fminsearch (...)

     Find a value of X which minimizes the multi-variable function FUN.

     The search begins at the point X0 and iterates using the Nelder &
     Mead Simplex algorithm (a derivative-free method).  This algorithm
     is better-suited to functions which have discontinuities or for
     which a gradient-based search such as ‘fminunc’ fails.

     Options for the search are provided in the parameter OPTIONS using
     the function ‘optimset’.  Currently, ‘fminsearch’ accepts the
     options: "Display", "FunValCheck","MaxFunEvals", "MaxIter",
     "OutputFcn", "TolFun", "TolX".

     "MaxFunEvals" proscribes the maximum number of function evaluations
     before optimization is halted.  The default value is ‘200 *
     number_of_variables’, i.e., ‘200 * length (X0)’.  The value must be
     a positive integer.

     "MaxIter" proscribes the maximum number of algorithm iterations
     before optimization is halted.  The default value is ‘200 *
     number_of_variables’, i.e., ‘200 * length (X0)’.  The value must be
     a positive integer.

     For a description of the other options, see ‘optimset’.  To
     initialize an options structure with default values for
     ‘fminsearch’ use ‘options = optimset ("fminsearch")’.

     ‘fminsearch’ may also be called with a single structure argument
     with the following fields:

     ‘objective’
          The objective function.

     ‘x0’
          The initial point.

     ‘solver’
          Must be set to "fminsearch".

     ‘options’
          A structure returned from ‘optimset’ or an empty matrix to
          indicate that defaults should be used.

     The field ‘options’ is optional.  All others are required.

     On exit, the function returns X, the minimum point, and FVAL, the
     function value at the minimum.

     The third output EXITFLAG reports whether the algorithm succeeded
     and may take one of the following values:

     1
          if the algorithm converged (size of the simplex is smaller
          than ‘TolX’ *AND* the step in function value between
          iterations is smaller than ‘TolFun’).

     0
          if the maximum number of iterations or the maximum number of
          function evaluations are exceeded.

     -1
          if the iteration is stopped by the "OutputFcn".

     The fourth output is a structure OUTPUT containing runtime about
     the algorithm.  Fields in the structure are ‘funcCount’ containing
     the number of function calls to FUN, ‘iterations’ containing the
     number of iteration steps, ‘algorithm’ with the name of the search
     algorithm (always: "Nelder-Mead simplex direct search"), and
     ‘message’ with the exit message.

     Example:

          fminsearch (@(x) (x(1)-5).^2+(x(2)-8).^4, [0;0])

     Note: If you need to find the minimum of a single variable function
     it is probably better to use ‘fminbnd’.

     See also: *note fminbnd: XREFfminbnd, *note fminunc: XREFfminunc,
     *note optimset: XREFoptimset.

   The function ‘humps’ is a useful function for testing zero and
extrema finding functions.

 -- : Y = humps (X)
 -- : [X, Y] = humps (X)
     Evaluate a function with multiple minima, maxima, and zero
     crossings.

     The output Y is the evaluation of the rational function:

                  1200*X^4 - 2880*X^3 + 2036*X^2 - 348*X - 88
           Y = - ---------------------------------------------
                   200*X^4 - 480*X^3 + 406*X^2 - 138*X + 17

     X may be a scalar, vector or array.  If X is omitted, the default
     range [0:0.05:1] is used.

     When called with two output arguments, [X, Y], X will contain the
     input values, and Y will contain the output from ‘humps’.

     Programming Notes: ‘humps’ has two local maxima located near X =
     0.300 and 0.893, a local minimum near X = 0.637, and zeros near X =
     -0.132 and 1.300.  ‘humps’ is a useful function for testing
     algorithms which find zeros or local minima and maxima.

     Try ‘demo humps’ to see a plot of the ‘humps’ function.

     See also: *note fzero: XREFfzero, *note fminbnd: XREFfminbnd, *note
     fminunc: XREFfminunc, *note fminsearch: XREFfminsearch.


File: octave.info,  Node: Diagonal and Permutation Matrices,  Next: Sparse Matrices,  Prev: Nonlinear Equations,  Up: Top

21 Diagonal and Permutation Matrices
************************************

* Menu:

* Basic Usage::          Creation and Manipulation of Diagonal/Permutation Matrices
* Matrix Algebra::       Linear Algebra with Diagonal/Permutation Matrices
* Function Support::     Functions That Are Aware of These Matrices
* Example Code::         Examples of Usage
* Zeros Treatment::      Differences in Treatment of Zero Elements


File: octave.info,  Node: Basic Usage,  Next: Matrix Algebra,  Up: Diagonal and Permutation Matrices

21.1 Creating and Manipulating Diagonal/Permutation Matrices
============================================================

A diagonal matrix is defined as a matrix that has zero entries outside
the main diagonal; that is, ‘D(i,j) == 0’ if ‘i != j’.  Most often,
square diagonal matrices are considered; however, the definition can
equally be applied to non-square matrices, in which case we usually
speak of a rectangular diagonal matrix.

   A permutation matrix is defined as a square matrix that has a single
element equal to unity in each row and each column; all other elements
are zero.  That is, there exists a permutation (vector) ‘p’ such that
‘P(i,j) == 1’ if ‘j == p(i)’ and ‘P(i,j) == 0’ otherwise.

   Octave provides special treatment of real and complex rectangular
diagonal matrices, as well as permutation matrices.  They are stored as
special objects, using efficient storage and algorithms, facilitating
writing both readable and efficient matrix algebra expressions in the
Octave language.  The special treatment may be disabled by using the
functions “disable_diagonal_matrix” and “disable_permutation_matrix”.

 -- : VAL = disable_diagonal_matrix ()
 -- : OLD_VAL = disable_diagonal_matrix (NEW_VAL)
 -- : disable_diagonal_matrix (NEW_VAL, "local")
     Query or set the internal variable that controls whether diagonal
     matrices are stored in a special space-efficient format.

     The default value is true.  If this option is disabled Octave will
     store diagonal matrices as full matrices.

     When called from inside a function with the "local" option, the
     variable is changed locally for the function and any subroutines it
     calls.  The original variable value is restored when exiting the
     function.

     See also: *note disable_range: XREFdisable_range, *note
     disable_permutation_matrix: XREFdisable_permutation_matrix.

 -- : VAL = disable_permutation_matrix ()
 -- : OLD_VAL = disable_permutation_matrix (NEW_VAL)
 -- : disable_permutation_matrix (NEW_VAL, "local")
     Query or set the internal variable that controls whether
     permutation matrices are stored in a special space-efficient
     format.

     The default value is true.  If this option is disabled Octave will
     store permutation matrices as full matrices.

     When called from inside a function with the "local" option, the
     variable is changed locally for the function and any subroutines it
     calls.  The original variable value is restored when exiting the
     function.

     See also: *note disable_range: XREFdisable_range, *note
     disable_diagonal_matrix: XREFdisable_diagonal_matrix.

   The space savings are significant as demonstrated by the following
code.

     x = diag (rand (10, 1));
     xf = full (x);
     sizeof (x)
     ⇒ 80
     sizeof (xf)
     ⇒ 800

* Menu:

* Creating Diagonal Matrices::
* Creating Permutation Matrices::
* Explicit and Implicit Conversions::


File: octave.info,  Node: Creating Diagonal Matrices,  Next: Creating Permutation Matrices,  Up: Basic Usage

21.1.1 Creating Diagonal Matrices
---------------------------------

The most common and easiest way to create a diagonal matrix is using the
built-in function “diag”.  The expression ‘diag (v)’, with V a vector,
will create a square diagonal matrix with elements on the main diagonal
given by the elements of V, and size equal to the length of V.  ‘diag
(v, m, n)’ can be used to construct a rectangular diagonal matrix.  The
result of these expressions will be a special diagonal matrix object,
rather than a general matrix object.

   Diagonal matrix with unit elements can be created using “eye”.  Some
other built-in functions can also return diagonal matrices.  Examples
include “balance” or “inv”.

   Example:

       diag (1:4)
     ⇒
     Diagonal Matrix

        1   0   0   0
        0   2   0   0
        0   0   3   0
        0   0   0   4

       diag (1:3,5,3)

     ⇒
     Diagonal Matrix

        1   0   0
        0   2   0
        0   0   3
        0   0   0
        0   0   0


File: octave.info,  Node: Creating Permutation Matrices,  Next: Explicit and Implicit Conversions,  Prev: Creating Diagonal Matrices,  Up: Basic Usage

21.1.2 Creating Permutation Matrices
------------------------------------

For creating permutation matrices, Octave does not introduce a new
function, but rather overrides an existing syntax: permutation matrices
can be conveniently created by indexing an identity matrix by
permutation vectors.  That is, if Q is a permutation vector of length N,
the expression

       P = eye (n) (:, q);

will create a permutation matrix - a special matrix object.

     eye (n) (q, :)

will also work (and create a row permutation matrix), as well as

     eye (n) (q1, q2).

   For example:

       eye (4) ([1,3,2,4],:)
     ⇒
     Permutation Matrix

        1   0   0   0
        0   0   1   0
        0   1   0   0
        0   0   0   1

       eye (4) (:,[1,3,2,4])
     ⇒
     Permutation Matrix

        1   0   0   0
        0   0   1   0
        0   1   0   0
        0   0   0   1

   Mathematically, an identity matrix is both diagonal and permutation
matrix.  In Octave, ‘eye (n)’ returns a diagonal matrix, because a
matrix can only have one class.  You can convert this diagonal matrix to
a permutation matrix by indexing it by an identity permutation, as shown
below.  This is a special property of the identity matrix; indexing
other diagonal matrices generally produces a full matrix.

       eye (3)
     ⇒
     Diagonal Matrix

        1   0   0
        0   1   0
        0   0   1

       eye(3)(1:3,:)
     ⇒
     Permutation Matrix

        1   0   0
        0   1   0
        0   0   1

   Some other built-in functions can also return permutation matrices.
Examples include “inv” or “lu”.


File: octave.info,  Node: Explicit and Implicit Conversions,  Prev: Creating Permutation Matrices,  Up: Basic Usage

21.1.3 Explicit and Implicit Conversions
----------------------------------------

The diagonal and permutation matrices are special objects in their own
right.  A number of operations and built-in functions are defined for
these matrices to use special, more efficient code than would be used
for a full matrix in the same place.  Examples are given in further
sections.

   To facilitate smooth mixing with full matrices, backward
compatibility, and compatibility with MATLAB, the diagonal and
permutation matrices should allow any operation that works on full
matrices, and will either treat it specially, or implicitly convert
themselves to full matrices.

   Instances include matrix indexing, except for extracting a single
element or a leading submatrix, indexed assignment, or applying most
mapper functions, such as “exp”.

   An explicit conversion to a full matrix can be requested using the
built-in function “full”.  It should also be noted that the diagonal and
permutation matrix objects will cache the result of the conversion after
it is first requested (explicitly or implicitly), so that subsequent
conversions will be very cheap.


File: octave.info,  Node: Matrix Algebra,  Next: Function Support,  Prev: Basic Usage,  Up: Diagonal and Permutation Matrices

21.2 Linear Algebra with Diagonal/Permutation Matrices
======================================================

As has been already said, diagonal and permutation matrices make it
possible to use efficient algorithms while preserving natural linear
algebra syntax.  This section describes in detail the operations that
are treated specially when performed on these special matrix objects.

* Menu:

* Expressions Involving Diagonal Matrices::
* Expressions Involving Permutation Matrices::


File: octave.info,  Node: Expressions Involving Diagonal Matrices,  Next: Expressions Involving Permutation Matrices,  Up: Matrix Algebra

21.2.1 Expressions Involving Diagonal Matrices
----------------------------------------------

Assume D is a diagonal matrix.  If M is a full matrix, then ‘D*M’ will
scale the rows of M.  That means, if ‘S = D*M’, then for each pair of
indices i,j it holds

     S(i,j) = D(i,i) * M(i,j).

   Similarly, ‘M*D’ will do a column scaling.

   The matrix D may also be rectangular, m-by-n where ‘m != n’.  If ‘m <
n’, then the expression ‘D*M’ is equivalent to

     D(:,1:m) * M(1:m,:),

i.e., trailing ‘n-m’ rows of M are ignored.  If ‘m > n’, then ‘D*M’ is
equivalent to

     [D(1:n,:) * M; zeros(m-n, columns (M))],

i.e., null rows are appended to the result.  The situation for
right-multiplication ‘M*D’ is analogous.

   The expressions ‘D \ M’ and ‘M / D’ perform inverse scaling.  They
are equivalent to solving a diagonal (or rectangular diagonal) in a
least-squares minimum-norm sense.  In exact arithmetic, this is
equivalent to multiplying by a pseudoinverse.  The pseudoinverse of a
rectangular diagonal matrix is again a rectangular diagonal matrix with
swapped dimensions, where each nonzero diagonal element is replaced by
its reciprocal.  The matrix division algorithms do, in fact, use
division rather than multiplication by reciprocals for better numerical
accuracy; otherwise, they honor the above definition.  Note that a
diagonal matrix is never truncated due to ill-conditioning; otherwise,
it would not be of much use for scaling.  This is typically consistent
with linear algebra needs.  A full matrix that only happens to be
diagonal (and is thus not a special object) is of course treated
normally.

   Multiplication and division by diagonal matrices work efficiently
also when combined with sparse matrices, i.e., ‘D*S’, where D is a
diagonal matrix and S is a sparse matrix scales the rows of the sparse
matrix and returns a sparse matrix.  The expressions ‘S*D’, ‘D\S’, ‘S/D’
work analogically.

   If D1 and D2 are both diagonal matrices, then the expressions

     D1 + D2
     D1 - D2
     D1 * D2
     D1 / D2
     D1 \ D2

again produce diagonal matrices, provided that normal dimension matching
rules are obeyed.  The relations used are same as described above.

   Also, a diagonal matrix D can be multiplied or divided by a scalar,
or raised to a scalar power if it is square, producing diagonal matrix
result in all cases.

   A diagonal matrix can also be transposed or conjugate-transposed,
giving the expected result.  Extracting a leading submatrix of a
diagonal matrix, i.e., ‘D(1:m,1:n)’, will produce a diagonal matrix,
other indexing expressions will implicitly convert to full matrix.

   Adding a diagonal matrix to a full matrix only operates on the
diagonal elements.  Thus,

     A = A + eps * eye (n)

is an efficient method of augmenting the diagonal of a matrix.
Subtraction works analogically.

   When involved in expressions with other element-by-element operators,
‘.*’, ‘./’, ‘.\’ or ‘.^’, an implicit conversion to full matrix will
take place.  This is not always strictly necessary but chosen to
facilitate better consistency with MATLAB.


File: octave.info,  Node: Expressions Involving Permutation Matrices,  Prev: Expressions Involving Diagonal Matrices,  Up: Matrix Algebra

21.2.2 Expressions Involving Permutation Matrices
-------------------------------------------------

If P is a permutation matrix and M a matrix, the expression ‘P*M’ will
permute the rows of M.  Similarly, ‘M*P’ will yield a column
permutation.  Matrix division ‘P\M’ and ‘M/P’ can be used to do inverse
permutation.

   The previously described syntax for creating permutation matrices can
actually help an user to understand the connection between a permutation
matrix and a permuting vector.  Namely, the following holds, where ‘I =
eye (n)’ is an identity matrix:

       I(p,:) * M = (I*M) (p,:) = M(p,:)

   Similarly,

       M * I(:,p) = (M*I) (:,p) = M(:,p)

   The expressions ‘I(p,:)’ and ‘I(:,p)’ are permutation matrices.

   A permutation matrix can be transposed (or conjugate-transposed,
which is the same, because a permutation matrix is never complex),
inverting the permutation, or equivalently, turning a row-permutation
matrix into a column-permutation one.  For permutation matrices,
transpose is equivalent to inversion, thus ‘P\M’ is equivalent to
‘P'*M’.  Transpose of a permutation matrix (or inverse) is a
constant-time operation, flipping only a flag internally, and thus the
choice between the two above equivalent expressions for inverse
permuting is completely up to the user’s taste.

   Multiplication and division by permutation matrices works efficiently
also when combined with sparse matrices, i.e., ‘P*S’, where P is a
permutation matrix and S is a sparse matrix permutes the rows of the
sparse matrix and returns a sparse matrix.  The expressions ‘S*P’,
‘P\S’, ‘S/P’ work analogically.

   Two permutation matrices can be multiplied or divided (if their sizes
match), performing a composition of permutations.  Also a permutation
matrix can be indexed by a permutation vector (or two vectors), giving
again a permutation matrix.  Any other operations do not generally yield
a permutation matrix and will thus trigger the implicit conversion.


File: octave.info,  Node: Function Support,  Next: Example Code,  Prev: Matrix Algebra,  Up: Diagonal and Permutation Matrices

21.3 Functions That Are Aware of These Matrices
===============================================

This section lists the built-in functions that are aware of diagonal and
permutation matrices on input, or can return them as output.  Passed to
other functions, these matrices will in general trigger an implicit
conversion.  (Of course, user-defined dynamically linked functions may
also work with diagonal or permutation matrices).

* Menu:

* Diagonal Matrix Functions::
* Permutation Matrix Functions::


File: octave.info,  Node: Diagonal Matrix Functions,  Next: Permutation Matrix Functions,  Up: Function Support

21.3.1 Diagonal Matrix Functions
--------------------------------

“inv” and “pinv” can be applied to a diagonal matrix, yielding again a
diagonal matrix.  “det” will use an efficient straightforward
calculation when given a diagonal matrix, as well as “cond”.  The
following mapper functions can be applied to a diagonal matrix without
converting it to a full one: “abs”, “real”, “imag”, “conj”, “sqrt”.  A
diagonal matrix can also be returned from the “balance” and “svd”
functions.  The “sparse” function will convert a diagonal matrix
efficiently to a sparse matrix.


File: octave.info,  Node: Permutation Matrix Functions,  Prev: Diagonal Matrix Functions,  Up: Function Support

21.3.2 Permutation Matrix Functions
-----------------------------------

“inv” and “pinv” will invert a permutation matrix, preserving its
specialness.  “det” can be applied to a permutation matrix, efficiently
calculating the sign of the permutation (which is equal to the
determinant).

   A permutation matrix can also be returned from the built-in functions
“lu” and “qr”, if a pivoted factorization is requested.

   The “sparse” function will convert a permutation matrix efficiently
to a sparse matrix.  The “find” function will also work efficiently with
a permutation matrix, making it possible to conveniently obtain the
permutation indices.


File: octave.info,  Node: Example Code,  Next: Zeros Treatment,  Prev: Function Support,  Up: Diagonal and Permutation Matrices

21.4 Examples of Usage
======================

The following can be used to solve a linear system ‘A*x = b’ using the
pivoted LU factorization:

       [L, U, P] = lu (A); ## now L*U = P*A
       x = U \ (L \ P) * b;

This is one way to normalize columns of a matrix X to unit norm:

       s = norm (X, "columns");
       X /= diag (s);

The same can also be accomplished with broadcasting (*note
Broadcasting::):

       s = norm (X, "columns");
       X ./= s;

The following expression is a way to efficiently calculate the sign of a
permutation, given by a permutation vector P.  It will also work in
earlier versions of Octave, but slowly.

       det (eye (length (p))(p, :))

Finally, here’s how to solve a linear system ‘A*x = b’ with Tikhonov
regularization (ridge regression) using SVD (a skeleton only):

       m = rows (A); n = columns (A);
       [U, S, V] = svd (A);
       ## determine the regularization factor alpha
       ## alpha = ...
       ## transform to orthogonal basis
       b = U'*b;
       ## Use the standard formula, replacing A with S.
       ## S is diagonal, so the following will be very fast and accurate.
       x = (S'*S + alpha^2 * eye (n)) \ (S' * b);
       ## transform to solution basis
       x = V*x;


File: octave.info,  Node: Zeros Treatment,  Prev: Example Code,  Up: Diagonal and Permutation Matrices

21.5 Differences in Treatment of Zero Elements
==============================================

Making diagonal and permutation matrices special matrix objects in their
own right and the consequent usage of smarter algorithms for certain
operations implies, as a side effect, small differences in treating
zeros.  The contents of this section apply also to sparse matrices,
discussed in the following chapter.  (*note Sparse Matrices::)

   The IEEE floating point standard defines the result of the
expressions ‘0*Inf’ and ‘0*NaN’ as ‘NaN’.  This is widely agreed to be a
good compromise.  Numerical software dealing with structured and sparse
matrices (including Octave) however, almost always makes a distinction
between a "numerical zero" and an "assumed zero".  A "numerical zero" is
a zero value occurring in a place where any floating-point value could
occur.  It is normally stored somewhere in memory as an explicit value.
An "assumed zero", on the contrary, is a zero matrix element implied by
the matrix structure (diagonal, triangular) or a sparsity pattern; its
value is usually not stored explicitly anywhere, but is implied by the
underlying data structure.

   The primary distinction is that an assumed zero, when multiplied by
any number, or divided by any nonzero number, yields *always* a zero,
even when, e.g., multiplied by ‘Inf’ or divided by ‘NaN’.  The reason
for this behavior is that the numerical multiplication is not actually
performed anywhere by the underlying algorithm; the result is just
assumed to be zero.  Equivalently, one can say that the part of the
computation involving assumed zeros is performed symbolically, not
numerically.

   This behavior not only facilitates the most straightforward and
efficient implementation of algorithms, but also preserves certain
useful invariants, like:

   • scalar * diagonal matrix is a diagonal matrix

   • sparse matrix / scalar preserves the sparsity pattern

   • permutation matrix * matrix is equivalent to permuting rows

   all of these natural mathematical truths would be invalidated by
treating assumed zeros as numerical ones.

   Note that MATLAB does not strictly follow this principle and converts
assumed zeros to numerical zeros in certain cases, while not doing so in
other cases.  As of today, there are no intentions to mimic such
behavior in Octave.

   Examples of effects of assumed zeros vs.  numerical zeros:

     Inf * eye (3)
     ⇒
        Inf     0     0
          0   Inf     0
          0     0   Inf

     Inf * speye (3)
     ⇒
     Compressed Column Sparse (rows = 3, cols = 3, nnz = 3 [33%])

       (1, 1) -> Inf
       (2, 2) -> Inf
       (3, 3) -> Inf

     Inf * full (eye (3))
     ⇒
        Inf   NaN   NaN
        NaN   Inf   NaN
        NaN   NaN   Inf


     diag (1:3) * [NaN; 1; 1]
     ⇒
        NaN
          2
          3

     sparse (1:3,1:3,1:3) * [NaN; 1; 1]
     ⇒
        NaN
          2
          3
     [1,0,0;0,2,0;0,0,3] * [NaN; 1; 1]
     ⇒
        NaN
        NaN
        NaN


File: octave.info,  Node: Sparse Matrices,  Next: Numerical Integration,  Prev: Diagonal and Permutation Matrices,  Up: Top

22 Sparse Matrices
******************

* Menu:

* Basics::                      Creation and Manipulation of Sparse Matrices
* Sparse Linear Algebra::       Linear Algebra on Sparse Matrices
* Iterative Techniques::        Iterative Techniques
* Real Life Example::           Using Sparse Matrices


File: octave.info,  Node: Basics,  Next: Sparse Linear Algebra,  Up: Sparse Matrices

22.1 Creation and Manipulation of Sparse Matrices
=================================================

The size of mathematical problems that can be treated at any particular
time is generally limited by the available computing resources.  Both,
the speed of the computer and its available memory place limitation on
the problem size.

   There are many classes of mathematical problems which give rise to
matrices, where a large number of the elements are zero.  In this case
it makes sense to have a special matrix type to handle this class of
problems where only the nonzero elements of the matrix are stored.  Not
only does this reduce the amount of memory to store the matrix, but it
also means that operations on this type of matrix can take advantage of
the a priori knowledge of the positions of the nonzero elements to
accelerate their calculations.

   A matrix type that stores only the nonzero elements is generally
called sparse.  It is the purpose of this document to discuss the basics
of the storage and creation of sparse matrices and the fundamental
operations on them.

* Menu:

* Storage of Sparse Matrices::
* Creating Sparse Matrices::
* Information::
* Operators and Functions::


File: octave.info,  Node: Storage of Sparse Matrices,  Next: Creating Sparse Matrices,  Up: Basics

22.1.1 Storage of Sparse Matrices
---------------------------------

It is not strictly speaking necessary for the user to understand how
sparse matrices are stored.  However, such an understanding will help to
get an understanding of the size of sparse matrices.  Understanding the
storage technique is also necessary for those users wishing to create
their own oct-files.

   There are many different means of storing sparse matrix data.  What
all of the methods have in common is that they attempt to reduce the
complexity and storage given a priori knowledge of the particular class
of problems that will be solved.  A good summary of the available
techniques for storing sparse matrix is given by Saad (1).  With full
matrices, knowledge of the point of an element of the matrix within the
matrix is implied by its position in the computers memory.  However,
this is not the case for sparse matrices, and so the positions of the
nonzero elements of the matrix must equally be stored.

   An obvious way to do this is by storing the elements of the matrix as
triplets, with two elements being their position in the array (rows and
column) and the third being the data itself.  This is conceptually easy
to grasp, but requires more storage than is strictly needed.

   The storage technique used within Octave is the compressed column
format.  It is similar to the Yale format.  (2) In this format the
position of each element in a row and the data are stored as previously.
However, if we assume that all elements in the same column are stored
adjacent in the computers memory, then we only need to store information
on the number of nonzero elements in each column, rather than their
positions.  Thus assuming that the matrix has more nonzero elements than
there are columns in the matrix, we win in terms of the amount of memory
used.

   In fact, the column index contains one more element than the number
of columns, with the first element always being zero.  The advantage of
this is a simplification in the code, in that there is no special case
for the first or last columns.  A short example, demonstrating this in C
is.

       for (j = 0; j < nc; j++)
         for (i = cidx(j); i < cidx(j+1); i++)
            printf ("nonzero element (%i,%i) is %d\n",
                ridx(i), j, data(i));

   A clear understanding might be had by considering an example of how
the above applies to an example matrix.  Consider the matrix

         1   2   0  0
         0   0   0  3
         0   0   0  4

   The nonzero elements of this matrix are

        (1, 1)  ⇒ 1
        (1, 2)  ⇒ 2
        (2, 4)  ⇒ 3
        (3, 4)  ⇒ 4

   This will be stored as three vectors CIDX, RIDX and DATA,
representing the column indexing, row indexing and data respectively.
The contents of these three vectors for the above matrix will be

       CIDX = [0, 1, 2, 2, 4]
       RIDX = [0, 0, 1, 2]
       DATA = [1, 2, 3, 4]

   Note that this is the representation of these elements with the first
row and column assumed to start at zero, while in Octave itself the row
and column indexing starts at one.  Thus the number of elements in the
I-th column is given by ‘CIDX (I + 1) - CIDX (I)’.

   Although Octave uses a compressed column format, it should be noted
that compressed row formats are equally possible.  However, in the
context of mixed operations between mixed sparse and dense matrices, it
makes sense that the elements of the sparse matrices are in the same
order as the dense matrices.  Octave stores dense matrices in column
major ordering, and so sparse matrices are equally stored in this
manner.

   A further constraint on the sparse matrix storage used by Octave is
that all elements in the rows are stored in increasing order of their
row index, which makes certain operations faster.  However, it imposes
the need to sort the elements on the creation of sparse matrices.
Having disordered elements is potentially an advantage in that it makes
operations such as concatenating two sparse matrices together easier and
faster, however it adds complexity and speed problems elsewhere.

   ---------- Footnotes ----------

   (1) Y. Saad "SPARSKIT: A basic toolkit for sparse matrix
computation", 1994,
<https://www-users.cs.umn.edu/~saad/software/SPARSKIT/paper.ps>

   (2) <https://en.wikipedia.org/wiki/Sparse_matrix#Yale_format>


File: octave.info,  Node: Creating Sparse Matrices,  Next: Information,  Prev: Storage of Sparse Matrices,  Up: Basics

22.1.2 Creating Sparse Matrices
-------------------------------

There are several means to create sparse matrix.

Returned from a function
     There are many functions that directly return sparse matrices.
     These include “speye”, “sprand”, “diag”, etc.

Constructed from matrices or vectors
     The function “sparse” allows a sparse matrix to be constructed from
     three vectors representing the row, column and data.
     Alternatively, the function “spconvert” uses a three column matrix
     format to allow easy importation of data from elsewhere.

Created and then filled
     The function “sparse” or “spalloc” can be used to create an empty
     matrix that is then filled by the user

From a user binary program
     The user can directly create the sparse matrix within an oct-file.

   There are several basic functions to return specific sparse matrices.
For example the sparse identity matrix, is a matrix that is often
needed.  It therefore has its own function to create it as ‘speye (N)’
or ‘speye (R, C)’, which creates an N-by-N or R-by-C sparse identity
matrix.

   Another typical sparse matrix that is often needed is a random
distribution of random elements.  The functions “sprand” and “sprandn”
perform this for uniform and normal random distributions of elements.
They have exactly the same calling convention, where ‘sprand (R, C, D)’,
creates an R-by-C sparse matrix with a density of filled elements of D.

   Other functions of interest that directly create sparse matrices, are
“diag” or its generalization “spdiags”, that can take the definition of
the diagonals of the matrix and create the sparse matrix that
corresponds to this.  For example,

     s = diag (sparse (randn (1,n)), -1);

creates a sparse (N+1)-by-(N+1) sparse matrix with a single diagonal
defined.

 -- : B = spdiags (A)
 -- : [B, D] = spdiags (A)
 -- : B = spdiags (A, D)
 -- : A = spdiags (V, D, A)
 -- : A = spdiags (V, D, M, N)
     A generalization of the function ‘diag’.

     Called with a single input argument, the nonzero diagonals D of A
     are extracted.

     With two arguments the diagonals to extract are given by the vector
     D.

     The other two forms of ‘spdiags’ modify the input matrix by
     replacing the diagonals.  They use the columns of V to replace the
     diagonals represented by the vector D.  If the sparse matrix A is
     defined then the diagonals of this matrix are replaced.  Otherwise
     a matrix of M by N is created with the diagonals given by the
     columns of V.

     Negative values of D represent diagonals below the main diagonal,
     and positive values of D diagonals above the main diagonal.

     For example:

          spdiags (reshape (1:12, 4, 3), [-1 0 1], 5, 4)
             ⇒ 5 10  0  0
                1  6 11  0
                0  2  7 12
                0  0  3  8
                0  0  0  4

     See also: *note diag: XREFdiag.

 -- : S = speye (M, N)
 -- : S = speye (M)
 -- : S = speye (SZ)
     Return a sparse identity matrix of size MxN.

     The implementation is significantly more efficient than ‘sparse
     (eye (M))’ as the full matrix is not constructed.

     Called with a single argument a square matrix of size M-by-M is
     created.  If called with a single vector argument SZ, this argument
     is taken to be the size of the matrix to create.

     See also: *note sparse: XREFsparse, *note spdiags: XREFspdiags,
     *note eye: XREFeye.

 -- : R = spones (S)
     Replace the nonzero entries of S with ones.

     This creates a sparse matrix with the same structure as S.

     See also: *note sparse: XREFsparse, *note sprand: XREFsprand, *note
     sprandn: XREFsprandn, *note sprandsym: XREFsprandsym, *note spfun:
     XREFspfun, *note spy: XREFspy.

 -- : sprand (M, N, D)
 -- : sprand (M, N, D, RC)
 -- : sprand (S)
     Generate a sparse matrix with uniformly distributed random values.

     The size of the matrix is MxN with a density of values D.  D must
     be between 0 and 1.  Values will be uniformly distributed on the
     interval (0, 1).

     If called with a single matrix argument, a sparse matrix is
     generated with random values wherever the matrix S is nonzero.

     If called with a scalar fourth argument RC, a random sparse matrix
     with reciprocal condition number RC is generated.  If RC is a
     vector, then it specifies the first singular values of the
     generated matrix (‘length (RC) <= min (M, N)’).

     See also: *note sprandn: XREFsprandn, *note sprandsym:
     XREFsprandsym, *note rand: XREFrand.

 -- : sprandn (M, N, D)
 -- : sprandn (M, N, D, RC)
 -- : sprandn (S)
     Generate a sparse matrix with normally distributed random values.

     The size of the matrix is MxN with a density of values D.  D must
     be between 0 and 1.  Values will be normally distributed with a
     mean of 0 and a variance of 1.

     If called with a single matrix argument, a sparse matrix is
     generated with random values wherever the matrix S is nonzero.

     If called with a scalar fourth argument RC, a random sparse matrix
     with reciprocal condition number RC is generated.  If RC is a
     vector, then it specifies the first singular values of the
     generated matrix (‘length (RC) <= min (M, N)’).

     See also: *note sprand: XREFsprand, *note sprandsym: XREFsprandsym,
     *note randn: XREFrandn.

 -- : sprandsym (N, D)
 -- : sprandsym (S)
     Generate a symmetric random sparse matrix.

     The size of the matrix will be NxN, with a density of values given
     by D.  D must be between 0 and 1 inclusive.  Values will be
     normally distributed with a mean of zero and a variance of 1.

     If called with a single matrix argument, a random sparse matrix is
     generated wherever the matrix S is nonzero in its lower triangular
     part.

     See also: *note sprand: XREFsprand, *note sprandn: XREFsprandn,
     *note spones: XREFspones, *note sparse: XREFsparse.

   The recommended way for the user to create a sparse matrix, is to
create two vectors containing the row and column index of the data and a
third vector of the same size containing the data to be stored.  For
example,

       ri = ci = d = [];
       for j = 1:c
         ri = [ri; randperm(r,n)'];
         ci = [ci; j*ones(n,1)];
         d = [d; rand(n,1)];
       endfor
       s = sparse (ri, ci, d, r, c);

creates an R-by-C sparse matrix with a random distribution of N (<R)
elements per column.  The elements of the vectors do not need to be
sorted in any particular order as Octave will sort them prior to storing
the data.  However, pre-sorting the data will make the creation of the
sparse matrix faster.

   The function “spconvert” takes a three or four column real matrix.
The first two columns represent the row and column index respectively
and the third and four columns, the real and imaginary parts of the
sparse matrix.  The matrix can contain zero elements and the elements
can be sorted in any order.  Adding zero elements is a convenient way to
define the size of the sparse matrix.  For example:

     s = spconvert ([1 2 3 4; 1 3 4 4; 1 2 3 0]')
     ⇒ Compressed Column Sparse (rows=4, cols=4, nnz=3)
           (1 , 1) -> 1
           (2 , 3) -> 2
           (3 , 4) -> 3

   An example of creating and filling a matrix might be

     k = 5;
     nz = r * k;
     s = spalloc (r, c, nz)
     for j = 1:c
       idx = randperm (r);
       s (:, j) = [zeros(r - k, 1); ...
             rand(k, 1)] (idx);
     endfor

   It should be noted, that due to the way that the Octave assignment
functions are written that the assignment will reallocate the memory
used by the sparse matrix at each iteration of the above loop.
Therefore the “spalloc” function ignores the NZ argument and does not
pre-assign the memory for the matrix.  Therefore, it is vitally
important that code using to above structure should be vectorized as
much as possible to minimize the number of assignments and reduce the
number of memory allocations.

 -- : FM = full (SM)
     Return a full storage matrix from a sparse, diagonal, or
     permutation matrix, or a range.

     See also: *note sparse: XREFsparse, *note issparse: XREFissparse.

 -- : S = spalloc (M, N, NZ)
     Create an M-by-N sparse matrix with pre-allocated space for at most
     NZ nonzero elements.

     This is useful for building a matrix incrementally by a sequence of
     indexed assignments.  Subsequent indexed assignments after
     ‘spalloc’ will reuse the pre-allocated memory, provided they are of
     one of the simple forms

        • ‘S(I:J) = X’

        • ‘S(:,I:J) = X’

        • ‘S(K:L,I:J) = X’

     and that the following conditions are met:

        • the assignment does not decrease nnz (S).

        • after the assignment, nnz (S) does not exceed NZ.

        • no index is out of bounds.

     Partial movement of data may still occur, but in general the
     assignment will be more memory and time efficient under these
     circumstances.  In particular, it is possible to efficiently build
     a pre-allocated sparse matrix from a contiguous block of columns.

     The amount of pre-allocated memory for a given matrix may be
     queried using the function ‘nzmax’.

     See also: *note nzmax: XREFnzmax, *note sparse: XREFsparse.

 -- : S = sparse (A)
 -- : S = sparse (I, J, SV, M, N)
 -- : S = sparse (I, J, SV)
 -- : S = sparse (M, N)
 -- : S = sparse (I, J, S, M, N, "unique")
 -- : S = sparse (I, J, SV, M, N, NZMAX)
     Create a sparse matrix from a full matrix, or row, column, value
     triplets.

     If A is a full matrix, convert it to a sparse matrix
     representation, removing all zero values in the process.

     Given the integer index vectors I and J, and a 1-by-‘nnz’ vector of
     real or complex values SV, construct the sparse matrix
     ‘S(I(K),J(K)) = SV(K)’ with overall dimensions M and N.  If any of
     SV, I or J are scalars, they are expanded to have a common size.

     If M or N are not specified their values are derived from the
     maximum index in the vectors I and J as given by ‘M = max (I)’, ‘N
     = max (J)’.

     *Note*: if multiple values are specified with the same I, J
     indices, the corresponding value in S will be the sum of the values
     at the repeated location.  See ‘accumarray’ for an example of how
     to produce different behavior, such as taking the minimum instead.

     If the option "unique" is given, and more than one value is
     specified at the same I, J indices, then the last specified value
     will be used.

     ‘sparse (M, N)’ will create an empty MxN sparse matrix and is
     equivalent to ‘sparse ([], [], [], M, N)’

     The argument NZMAX is ignored but accepted for compatibility with
     MATLAB.

     Example 1 (sum at repeated indices):

          I = [1 1 2]; J = [1 1 2]; SV = [3 4 5];
          sparse (I, J, SV, 3, 4)
          ⇒
             Compressed Column Sparse (rows = 3, cols = 4, nnz = 2 [17%])

               (1, 1) ->  7
               (2, 2) ->  5

     Example 2 ("unique" option):

          I = [1 1 2]; J = [1 1 2]; SV = [3 4 5];
          sparse (I, J, SV, 3, 4, "unique")
          ⇒
             Compressed Column Sparse (rows = 3, cols = 4, nnz = 2 [17%])

               (1, 1) ->  4
               (2, 2) ->  5

     See also: *note full: XREFfull, *note accumarray: XREFaccumarray,
     *note spalloc: XREFspalloc, *note spdiags: XREFspdiags, *note
     speye: XREFspeye, *note spones: XREFspones, *note sprand:
     XREFsprand, *note sprandn: XREFsprandn, *note sprandsym:
     XREFsprandsym, *note spconvert: XREFspconvert, *note spfun:
     XREFspfun.

 -- : X = spconvert (M)
     Convert a simple sparse matrix format easily generated by other
     programs into Octave’s internal sparse format.

     The input M is either a 3 or 4 column real matrix, containing the
     row, column, real, and imaginary parts of the elements of the
     sparse matrix.  An element with a zero real and imaginary part can
     be used to force a particular matrix size.

     See also: *note sparse: XREFsparse.

   The above problem of memory reallocation can be avoided in oct-files.
However, the construction of a sparse matrix from an oct-file is more
complex than can be discussed here.  *Note External Code Interface::,
for a full description of the techniques involved.


File: octave.info,  Node: Information,  Next: Operators and Functions,  Prev: Creating Sparse Matrices,  Up: Basics

22.1.3 Finding Information about Sparse Matrices
------------------------------------------------

There are a number of functions that allow information concerning sparse
matrices to be obtained.  The most basic of these is “issparse” that
identifies whether a particular Octave object is in fact a sparse
matrix.

   Another very basic function is “nnz” that returns the number of
nonzero entries there are in a sparse matrix, while the function “nzmax”
returns the amount of storage allocated to the sparse matrix.  Note that
Octave tends to crop unused memory at the first opportunity for sparse
objects.  There are some cases of user created sparse objects where the
value returned by “nzmax” will not be the same as “nnz”, but in general
they will give the same result.  The function “spstats” returns some
basic statistics on the columns of a sparse matrix including the number
of elements, the mean and the variance of each column.

 -- : issparse (X)
     Return true if X is a sparse matrix.

     See also: *note ismatrix: XREFismatrix.

 -- : N = nnz (A)
     Return the number of nonzero elements in A.

     See also: *note nzmax: XREFnzmax, *note nonzeros: XREFnonzeros,
     *note find: XREFfind.

 -- : V = nonzeros (A)
     Return a column vector of the nonzero values of the matrix A.

     See also: *note find: XREFfind, *note nnz: XREFnnz.

 -- : N = nzmax (SM)
     Return the amount of storage allocated to the sparse matrix SM.

     Note that Octave tends to crop unused memory at the first
     opportunity for sparse objects.  Thus, in general the value of
     ‘nzmax’ will be the same as ‘nnz’ except for some cases of
     user-created sparse objects.

     See also: *note nnz: XREFnnz, *note spalloc: XREFspalloc, *note
     sparse: XREFsparse.

 -- : [COUNT, MEAN, VAR] = spstats (S)
 -- : [COUNT, MEAN, VAR] = spstats (S, J)
     Return the stats for the nonzero elements of the sparse matrix S.

     COUNT is the number of nonzeros in each column, MEAN is the mean of
     the nonzeros in each column, and VAR is the variance of the
     nonzeros in each column.

     Called with two input arguments, if S is the data and J is the bin
     number for the data, compute the stats for each bin.  In this case,
     bins can contain data values of zero, whereas with ‘spstats (S)’
     the zeros may disappear.

   When solving linear equations involving sparse matrices Octave
determines the means to solve the equation based on the type of the
matrix (*note Sparse Linear Algebra::).  Octave probes the matrix type
when the div (/) or ldiv (\) operator is first used with the matrix and
then caches the type.  However the “matrix_type” function can be used to
determine the type of the sparse matrix prior to use of the div or ldiv
operators.  For example,

     a = tril (sprandn (1024, 1024, 0.02), -1) ...
         + speye (1024);
     matrix_type (a);
     ans = Lower

shows that Octave correctly determines the matrix type for lower
triangular matrices.  “matrix_type” can also be used to force the type
of a matrix to be a particular type.  For example:

     a = matrix_type (tril (sprandn (1024, ...
        1024, 0.02), -1) + speye (1024), "Lower");

   This allows the cost of determining the matrix type to be avoided.
However, incorrectly defining the matrix type will result in incorrect
results from solutions of linear equations, and so it is entirely the
responsibility of the user to correctly identify the matrix type

   There are several graphical means of finding out information about
sparse matrices.  The first is the “spy” command, which displays the
structure of the nonzero elements of the matrix.  *Note Figure 22.1:
fig:spmatrix, for an example of the use of “spy”.  More advanced
graphical information can be obtained with the “treeplot”, “etreeplot”
and “gplot” commands.

[image src="spmatrix.png" text="
            |  * *                          
            |  * * * *                      
            |    * *   * *                  
            |    *   *     * *              
          5 -      *   *       * *          
            |      *     *         * *      
            |        *     *           * *  
            |        *       *             *
            |          *       *            
         10 -          *         *          
            |            *         *        
            |            *           *      
            |              *           *    
            |              *             *  
         15 -                *             *
            |----------|---------|---------|
                       5        10        15"]

Figure 22.1: Structure of simple sparse matrix.

   One use of sparse matrices is in graph theory, where the
interconnections between nodes are represented as an adjacency matrix.
That is, if the i-th node in a graph is connected to the j-th node.
Then the ij-th node (and in the case of undirected graphs the ji-th
node) of the sparse adjacency matrix is nonzero.  If each node is then
associated with a set of coordinates, then the “gplot” command can be
used to graphically display the interconnections between nodes.

   As a trivial example of the use of “gplot” consider the example,

     A = sparse ([2,6,1,3,2,4,3,5,4,6,1,5],
         [1,1,2,2,3,3,4,4,5,5,6,6],1,6,6);
     xy = [0,4,8,6,4,2;5,0,5,7,5,7]';
     gplot (A,xy)

which creates an adjacency matrix ‘A’ where node 1 is connected to nodes
2 and 6, node 2 with nodes 1 and 3, etc.  The coordinates of the nodes
are given in the n-by-2 matrix ‘xy’.

   The dependencies between the nodes of a Cholesky factorization can be
calculated in linear time without explicitly needing to calculate the
Cholesky factorization by the ‘etree’ command.  This command returns the
elimination tree of the matrix and can be displayed graphically by the
command ‘treeplot (etree (A))’ if ‘A’ is symmetric or ‘treeplot (etree
(A+A'))’ otherwise.

 -- : spy (X)
 -- : spy (..., MARKERSIZE)
 -- : spy (..., LINE_SPEC)
     Plot the sparsity pattern of the sparse matrix X.

     If the argument MARKERSIZE is given as a scalar value, it is used
     to determine the point size in the plot.

     If the string LINE_SPEC is given it is passed to ‘plot’ and
     determines the appearance of the plot.

     See also: *note plot: XREFplot, *note gplot: XREFgplot.

 -- : P = etree (S)
 -- : P = etree (S, TYP)
 -- : [P, Q] = etree (S, TYP)

     Return the elimination tree for the matrix S.

     By default S is assumed to be symmetric and the symmetric
     elimination tree is returned.  The argument TYP controls whether a
     symmetric or column elimination tree is returned.  Valid values of
     TYP are "sym" or "col", for symmetric or column elimination tree
     respectively.

     Called with a second argument, ‘etree’ also returns the postorder
     permutations on the tree.

 -- : etreeplot (A)
 -- : etreeplot (A, NODE_STYLE, EDGE_STYLE)
     Plot the elimination tree of the matrix A or A+A’ if A in not
     symmetric.

     The optional parameters NODE_STYLE and EDGE_STYLE define the output
     style.

     See also: *note treeplot: XREFtreeplot, *note gplot: XREFgplot.

 -- : gplot (A, XY)
 -- : gplot (A, XY, LINE_STYLE)
 -- : [X, Y] = gplot (A, XY)
     Plot a graph defined by A and XY in the graph theory sense.

     A is the adjacency matrix of the array to be plotted and XY is an
     N-by-2 matrix containing the coordinates of the nodes of the graph.

     The optional parameter LINE_STYLE defines the output style for the
     plot.  Called with no output arguments the graph is plotted
     directly.  Otherwise, return the coordinates of the plot in X and
     Y.

     See also: *note treeplot: XREFtreeplot, *note etreeplot:
     XREFetreeplot, *note spy: XREFspy.

 -- : treeplot (TREE)
 -- : treeplot (TREE, NODE_STYLE, EDGE_STYLE)
     Produce a graph of tree or forest.

     The first argument is vector of predecessors.

     The optional parameters NODE_STYLE and EDGE_STYLE define the output
     plot style.

     The complexity of the algorithm is O(n) in terms of is time and
     memory requirements.

     See also: *note etreeplot: XREFetreeplot, *note gplot: XREFgplot.

 -- : treelayout (TREE)
 -- : treelayout (TREE, PERMUTATION)
     treelayout lays out a tree or a forest.

     The first argument TREE is a vector of predecessors.

     The parameter PERMUTATION is an optional postorder permutation.

     The complexity of the algorithm is O(n) in terms of time and memory
     requirements.

     See also: *note etreeplot: XREFetreeplot, *note gplot: XREFgplot,
     *note treeplot: XREFtreeplot.


File: octave.info,  Node: Operators and Functions,  Prev: Information,  Up: Basics

22.1.4 Basic Operators and Functions on Sparse Matrices
-------------------------------------------------------

* Menu:

* Sparse Functions::
* Return Types of Operators and Functions::
* Mathematical Considerations::


File: octave.info,  Node: Sparse Functions,  Next: Return Types of Operators and Functions,  Up: Operators and Functions

22.1.4.1 Sparse Functions
.........................

Many Octave functions have been overloaded to work with either sparse or
full matrices.  There is no difference in calling convention when using
an overloaded function with a sparse matrix, however, there is also no
access to potentially sparse-specific features.  At any time the sparse
matrix specific version of a function can be used by explicitly calling
its function name.

   The table below lists all of the sparse functions of Octave.  Note
that the names of the specific sparse forms of the functions are
typically the same as the general versions with a “sp” prefix.  In the
table below, and in the rest of this article, the specific sparse
versions of functions are used.

Generate sparse matrices:
     “spalloc”, “spdiags”, “speye”, “sprand”, “sprandn”, “sprandsym”

Sparse matrix conversion:
     “full”, “sparse”, “spconvert”

Manipulate sparse matrices
     “issparse”, “nnz”, “nonzeros”, “nzmax”, “spfun”, “spones”, “spy”

Graph Theory:
     “etree”, “etreeplot”, “gplot”, “treeplot”

Sparse matrix reordering:
     “amd”, “ccolamd”, “colamd”, “colperm”, “csymamd”, “dmperm”,
     “symamd”, “randperm”, “symrcm”

Linear algebra:
     “condest”, “eigs”, “matrix_type”, “normest”, “normest1”, “sprank”,
     “spaugment”, “svds”

Iterative techniques:
     “ichol”, “ilu”, “pcg”, “pcr”

Miscellaneous:
     “spparms”, “symbfact”, “spstats”

   In addition all of the standard Octave mapper functions (i.e., basic
math functions that take a single argument) such as “abs”, etc.  can
accept sparse matrices.  The reader is referred to the documentation
supplied with these functions within Octave itself for further details.


File: octave.info,  Node: Return Types of Operators and Functions,  Next: Mathematical Considerations,  Prev: Sparse Functions,  Up: Operators and Functions

22.1.4.2 Return Types of Operators and Functions
................................................

The two basic reasons to use sparse matrices are to reduce the memory
usage and to not have to do calculations on zero elements.  The two are
closely related in that the computation time on a sparse matrix operator
or function is roughly linear with the number of nonzero elements.

   Therefore, there is a certain density of nonzero elements of a matrix
where it no longer makes sense to store it as a sparse matrix, but
rather as a full matrix.  For this reason operators and functions that
have a high probability of returning a full matrix will always return
one.  For example adding a scalar constant to a sparse matrix will
almost always make it a full matrix, and so the example,

     speye (3) + 0
     ⇒   1  0  0
       0  1  0
       0  0  1

returns a full matrix as can be seen.

   Additionally, if ‘sparse_auto_mutate’ is true, all sparse functions
test the amount of memory occupied by the sparse matrix to see if the
amount of storage used is larger than the amount used by the full
equivalent.  Therefore ‘speye (2) * 1’ will return a full matrix as the
memory used is smaller for the full version than the sparse version.

   As all of the mixed operators and functions between full and sparse
matrices exist, in general this does not cause any problems.  However,
one area where it does cause a problem is where a sparse matrix is
promoted to a full matrix, where subsequent operations would resparsify
the matrix.  Such cases are rare, but can be artificially created, for
example ‘(fliplr (speye (3)) + speye (3)) - speye (3)’ gives a full
matrix when it should give a sparse one.  In general, where such cases
occur, they impose only a small memory penalty.

   There is however one known case where this behavior of Octave’s
sparse matrices will cause a problem.  That is in the handling of the
“diag” function.  Whether “diag” returns a sparse or full matrix
depending on the type of its input arguments.  So

      a = diag (sparse ([1,2,3]), -1);

should return a sparse matrix.  To ensure this actually happens, the
“sparse” function, and other functions based on it like “speye”, always
returns a sparse matrix, even if the memory used will be larger than its
full representation.

 -- : VAL = sparse_auto_mutate ()
 -- : OLD_VAL = sparse_auto_mutate (NEW_VAL)
 -- : sparse_auto_mutate (NEW_VAL, "local")
     Query or set the internal variable that controls whether Octave
     will automatically mutate sparse matrices to full matrices to save
     memory.

     For example:

          s = speye (3);
          sparse_auto_mutate (false);
          s(:, 1) = 1;
          typeinfo (s)
          ⇒ sparse matrix
          sparse_auto_mutate (true);
          s(1, :) = 1;
          typeinfo (s)
          ⇒ matrix

     When called from inside a function with the "local" option, the
     variable is changed locally for the function and any subroutines it
     calls.  The original variable value is restored when exiting the
     function.

   Note that the ‘sparse_auto_mutate’ option is incompatible with
MATLAB, and so it is off by default.


File: octave.info,  Node: Mathematical Considerations,  Prev: Return Types of Operators and Functions,  Up: Operators and Functions

22.1.4.3 Mathematical Considerations
....................................

The attempt has been made to make sparse matrices behave in exactly the
same manner as there full counterparts.  However, there are certain
differences and especially differences with other products sparse
implementations.

   First, the "./" and ".^" operators must be used with care.  Consider
what the examples

       s = speye (4);
       a1 = s .^ 2;
       a2 = s .^ s;
       a3 = s .^ -2;
       a4 = s ./ 2;
       a5 = 2 ./ s;
       a6 = s ./ s;

will give.  The first example of S raised to the power of 2 causes no
problems.  However S raised element-wise to itself involves a large
number of terms ‘0 .^ 0’ which is 1.  There ‘S .^ S’ is a full matrix.

   Likewise ‘S .^ -2’ involves terms like ‘0 .^ -2’ which is infinity,
and so ‘S .^ -2’ is equally a full matrix.

   For the "./" operator ‘S ./ 2’ has no problems, but ‘2 ./ S’ involves
a large number of infinity terms as well and is equally a full matrix.
The case of ‘S ./ S’ involves terms like ‘0 ./ 0’ which is a ‘NaN’ and
so this is equally a full matrix with the zero elements of S filled with
‘NaN’ values.

   The above behavior is consistent with full matrices, but is not
consistent with sparse implementations in other products.

   A particular problem of sparse matrices comes about due to the fact
that as the zeros are not stored, the sign-bit of these zeros is equally
not stored.  In certain cases the sign-bit of zero is important.  For
example:

      a = 0 ./ [-1, 1; 1, -1];
      b = 1 ./ a
      ⇒ -Inf            Inf
          Inf           -Inf
      c = 1 ./ sparse (a)
      ⇒  Inf            Inf
          Inf            Inf

   To correct this behavior would mean that zero elements with a
negative sign-bit would need to be stored in the matrix to ensure that
their sign-bit was respected.  This is not done at this time, for
reasons of efficiency, and so the user is warned that calculations where
the sign-bit of zero is important must not be done using sparse
matrices.

   In general any function or operator used on a sparse matrix will
result in a sparse matrix with the same or a larger number of nonzero
elements than the original matrix.  This is particularly true for the
important case of sparse matrix factorizations.  The usual way to
address this is to reorder the matrix, such that its factorization is
sparser than the factorization of the original matrix.  That is the
factorization of ‘L * U = P * S * Q’ has sparser terms ‘L’ and ‘U’ than
the equivalent factorization ‘L * U = S’.

   Several functions are available to reorder depending on the type of
the matrix to be factorized.  If the matrix is symmetric
positive-definite, then “symamd” or “csymamd” should be used.  Otherwise
“amd”, “colamd” or “ccolamd” should be used.  For completeness the
reordering functions “colperm” and “randperm” are also available.

   *Note Figure 22.2: fig:simplematrix, for an example of the structure
of a simple positive definite matrix.

[image src="spmatrix.png" text="
            |  * *                          
            |  * * * *                      
            |    * *   * *                  
            |    *   *     * *              
          5 -      *   *       * *          
            |      *     *         * *      
            |        *     *           * *  
            |        *       *             *
            |          *       *            
         10 -          *         *          
            |            *         *        
            |            *           *      
            |              *           *    
            |              *             *  
         15 -                *             *
            |----------|---------|---------|
                       5        10        15"]

Figure 22.2: Structure of simple sparse matrix.

   The standard Cholesky factorization of this matrix can be obtained by
the same command that would be used for a full matrix.  This can be
visualized with the command ‘r = chol (A); spy (r);’.  *Note Figure
22.3: fig:simplechol.  The original matrix had 43 nonzero terms, while
this Cholesky factorization has 71, with only half of the symmetric
matrix being stored.  This is a significant level of fill in, and
although not an issue for such a small test case, can represents a large
overhead in working with other sparse matrices.

   The appropriate sparsity preserving permutation of the original
matrix is given by “symamd” and the factorization using this reordering
can be visualized using the command ‘q = symamd (A); r = chol (A(q,q));
spy (r)’.  This gives 29 nonzero terms which is a significant
improvement.

   The Cholesky factorization itself can be used to determine the
appropriate sparsity preserving reordering of the matrix during the
factorization, In that case this might be obtained with three return
arguments as ‘[r, p, q] = chol (A); spy (r)’.

[image src="spchol.png" text="
            |  * *                          
            |    * * *                      
            |      * * * *                  
            |        * * * * *              
          5 -          * * * * * *          
            |            * * * * * * *      
            |              * * * * * * * *  
            |                * * * * * * * *
            |                  * * * * * * *
         10 -                    * * * * * *
            |                      * * * * *
            |                        * * * *
            |                          * * *
            |                            * *
         15 -                              *
            |----------|---------|---------|
                       5        10        15"]

Figure 22.3: Structure of the unpermuted Cholesky factorization of the
above matrix.

[image src="spcholperm.png" text="
            |  * *                          
            |    *       *                  
            |      *   *                    
            |        * *                    
          5 -          * *                  
            |            *                 *
            |              *   *            
            |                * *            
            |                  *       *    
         10 -                    *   *      
            |                      * *      
            |                        * *    
            |                          *   *
            |                            * *
         15 -                              *
            |----------|---------|---------|
                       5        10        15"]

Figure 22.4: Structure of the permuted Cholesky factorization of the
above matrix.

   In the case of an asymmetric matrix, the appropriate sparsity
preserving permutation is “colamd” and the factorization using this
reordering can be visualized using the command ‘q = colamd (A); [l, u,
p] = lu (A(:,q)); spy (l+u)’.

   Finally, Octave implicitly reorders the matrix when using the div (/)
and ldiv (\) operators, and so no the user does not need to explicitly
reorder the matrix to maximize performance.

 -- : P = amd (S)
 -- : P = amd (S, OPTS)

     Return the approximate minimum degree permutation of a matrix.

     This is a permutation such that the Cholesky factorization of ‘S
     (P, P)’ tends to be sparser than the Cholesky factorization of S
     itself.  ‘amd’ is typically faster than ‘symamd’ but serves a
     similar purpose.

     The optional parameter OPTS is a structure that controls the
     behavior of ‘amd’.  The fields of the structure are

     OPTS.dense
          Determines what ‘amd’ considers to be a dense row or column of
          the input matrix.  Rows or columns with more than ‘max (16,
          (dense * sqrt (N)))’ entries, where N is the order of the
          matrix S, are ignored by ‘amd’ during the calculation of the
          permutation.  The value of dense must be a positive scalar and
          the default value is 10.0

     OPTS.aggressive
          If this value is a nonzero scalar, then ‘amd’ performs
          aggressive absorption.  The default is not to perform
          aggressive absorption.

     The author of the code itself is Timothy A. Davis (see
     <http://faculty.cse.tamu.edu/davis/suitesparse.html>).

     See also: *note symamd: XREFsymamd, *note colamd: XREFcolamd.

 -- : P = ccolamd (S)
 -- : P = ccolamd (S, KNOBS)
 -- : P = ccolamd (S, KNOBS, CMEMBER)
 -- : [P, STATS] = ccolamd (...)

     Constrained column approximate minimum degree permutation.

     ‘P = ccolamd (S)’ returns the column approximate minimum degree
     permutation vector for the sparse matrix S.  For a non-symmetric
     matrix S, ‘S(:, P)’ tends to have sparser LU factors than S.  ‘chol
     (S(:, P)' * S(:, P))’ also tends to be sparser than ‘chol (S' *
     S)’.  ‘P = ccolamd (S, 1)’ optimizes the ordering for ‘lu (S(:,
     P))’.  The ordering is followed by a column elimination tree
     post-ordering.

     KNOBS is an optional 1-element to 5-element input vector, with a
     default value of ‘[0 10 10 1 0]’ if not present or empty.  Entries
     not present are set to their defaults.

     ‘KNOBS(1)’
          if nonzero, the ordering is optimized for ‘lu (S(:, p))’.  It
          will be a poor ordering for ‘chol (S(:, P)' * S(:, P))’.  This
          is the most important knob for ccolamd.

     ‘KNOBS(2)’
          if S is m-by-n, rows with more than ‘max (16, KNOBS(2) * sqrt
          (n))’ entries are ignored.

     ‘KNOBS(3)’
          columns with more than ‘max (16, KNOBS(3) * sqrt (min (M,
          N)))’ entries are ignored and ordered last in the output
          permutation (subject to the cmember constraints).

     ‘KNOBS(4)’
          if nonzero, aggressive absorption is performed.

     ‘KNOBS(5)’
          if nonzero, statistics and knobs are printed.

     CMEMBER is an optional vector of length n.  It defines the
     constraints on the column ordering.  If ‘CMEMBER(j) = C’, then
     column J is in constraint set C (C must be in the range 1 to n).
     In the output permutation P, all columns in set 1 appear first,
     followed by all columns in set 2, and so on.  ‘CMEMBER = ones
     (1,n)’ if not present or empty.  ‘ccolamd (S, [], 1 : n)’ returns
     ‘1 : n’

     ‘P = ccolamd (S)’ is about the same as ‘P = colamd (S)’.  KNOBS and
     its default values differ.  ‘colamd’ always does aggressive
     absorption, and it finds an ordering suitable for both ‘lu (S(:,
     P))’ and ‘chol (S(:, P)' * S(:, P))’; it cannot optimize its
     ordering for ‘lu (S(:, P))’ to the extent that ‘ccolamd (S, 1)’
     can.

     STATS is an optional 20-element output vector that provides data
     about the ordering and the validity of the input matrix S.
     Ordering statistics are in ‘STATS(1 : 3)’.  ‘STATS(1)’ and
     ‘STATS(2)’ are the number of dense or empty rows and columns
     ignored by CCOLAMD and ‘STATS(3)’ is the number of garbage
     collections performed on the internal data structure used by
     CCOLAMD (roughly of size ‘2.2 * nnz (S) + 4 * M + 7 * N’ integers).

     ‘STATS(4 : 7)’ provide information if CCOLAMD was able to continue.
     The matrix is OK if ‘STATS(4)’ is zero, or 1 if invalid.
     ‘STATS(5)’ is the rightmost column index that is unsorted or
     contains duplicate entries, or zero if no such column exists.
     ‘STATS(6)’ is the last seen duplicate or out-of-order row index in
     the column index given by ‘STATS(5)’, or zero if no such row index
     exists.  ‘STATS(7)’ is the number of duplicate or out-of-order row
     indices.  ‘STATS(8 : 20)’ is always zero in the current version of
     CCOLAMD (reserved for future use).

     The authors of the code itself are S. Larimore, T. Davis and S.
     Rajamanickam in collaboration with J. Bilbert and E. Ng.  Supported
     by the National Science Foundation (DMS-9504974, DMS-9803599,
     CCR-0203270), and a grant from Sandia National Lab.  See
     <http://faculty.cse.tamu.edu/davis/suitesparse.html> for ccolamd,
     csymamd, amd, colamd, symamd, and other related orderings.

     See also: *note colamd: XREFcolamd, *note csymamd: XREFcsymamd.

 -- : P = colamd (S)
 -- : P = colamd (S, KNOBS)
 -- : [P, STATS] = colamd (S)
 -- : [P, STATS] = colamd (S, KNOBS)

     Compute the column approximate minimum degree permutation.

     ‘P = colamd (S)’ returns the column approximate minimum degree
     permutation vector for the sparse matrix S.  For a non-symmetric
     matrix S, ‘S(:,P)’ tends to have sparser LU factors than S.  The
     Cholesky factorization of ‘S(:,P)' * S(:,P)’ also tends to be
     sparser than that of ‘S' * S’.

     KNOBS is an optional one- to three-element input vector.  If S is
     m-by-n, then rows with more than ‘max(16,KNOBS(1)*sqrt(n))’ entries
     are ignored.  Columns with more than ‘max
     (16,KNOBS(2)*sqrt(min(m,n)))’ entries are removed prior to
     ordering, and ordered last in the output permutation P.  Only
     completely dense rows or columns are removed if ‘KNOBS(1)’ and
     ‘KNOBS(2)’ are < 0, respectively.  If ‘KNOBS(3)’ is nonzero, STATS
     and KNOBS are printed.  The default is ‘KNOBS = [10 10 0]’.  Note
     that KNOBS differs from earlier versions of colamd.

     STATS is an optional 20-element output vector that provides data
     about the ordering and the validity of the input matrix S.
     Ordering statistics are in ‘STATS(1:3)’.  ‘STATS(1)’ and ‘STATS(2)’
     are the number of dense or empty rows and columns ignored by COLAMD
     and ‘STATS(3)’ is the number of garbage collections performed on
     the internal data structure used by COLAMD (roughly of size ‘2.2 *
     nnz(S) + 4 * M + 7 * N’ integers).

     Octave built-in functions are intended to generate valid sparse
     matrices, with no duplicate entries, with ascending row indices of
     the nonzeros in each column, with a non-negative number of entries
     in each column (!)  and so on.  If a matrix is invalid, then COLAMD
     may or may not be able to continue.  If there are duplicate entries
     (a row index appears two or more times in the same column) or if
     the row indices in a column are out of order, then COLAMD can
     correct these errors by ignoring the duplicate entries and sorting
     each column of its internal copy of the matrix S (the input matrix
     S is not repaired, however).  If a matrix is invalid in other ways
     then COLAMD cannot continue, an error message is printed, and no
     output arguments (P or STATS) are returned.  COLAMD is thus a
     simple way to check a sparse matrix to see if it’s valid.

     ‘STATS(4:7)’ provide information if COLAMD was able to continue.
     The matrix is OK if ‘STATS(4)’ is zero, or 1 if invalid.
     ‘STATS(5)’ is the rightmost column index that is unsorted or
     contains duplicate entries, or zero if no such column exists.
     ‘STATS(6)’ is the last seen duplicate or out-of-order row index in
     the column index given by ‘STATS(5)’, or zero if no such row index
     exists.  ‘STATS(7)’ is the number of duplicate or out-of-order row
     indices.  ‘STATS(8:20)’ is always zero in the current version of
     COLAMD (reserved for future use).

     The ordering is followed by a column elimination tree
     post-ordering.

     The authors of the code itself are Stefan I. Larimore and Timothy
     A. Davis.  The algorithm was developed in collaboration with John
     Gilbert, Xerox PARC, and Esmond Ng, Oak Ridge National Laboratory.
     (see <http://faculty.cse.tamu.edu/davis/suitesparse.html>)

     See also: *note colperm: XREFcolperm, *note symamd: XREFsymamd,
     *note ccolamd: XREFccolamd.

 -- : P = colperm (S)
     Return the column permutations such that the columns of ‘S (:, P)’
     are ordered in terms of increasing number of nonzero elements.

     If S is symmetric, then P is chosen such that ‘S (P, P)’ orders the
     rows and columns with increasing number of nonzeros elements.

 -- : P = csymamd (S)
 -- : P = csymamd (S, KNOBS)
 -- : P = csymamd (S, KNOBS, CMEMBER)
 -- : [P, STATS] = csymamd (...)

     For a symmetric positive definite matrix S, return the permutation
     vector P such that ‘S(P,P)’ tends to have a sparser Cholesky factor
     than S.

     Sometimes ‘csymamd’ works well for symmetric indefinite matrices
     too.  The matrix S is assumed to be symmetric; only the strictly
     lower triangular part is referenced.  S must be square.  The
     ordering is followed by an elimination tree post-ordering.

     KNOBS is an optional 1-element to 3-element input vector, with a
     default value of ‘[10 1 0]’.  Entries not present are set to their
     defaults.

     ‘KNOBS(1)’
          If S is n-by-n, then rows and columns with more than
          ‘max(16,KNOBS(1)*sqrt(n))’ entries are ignored, and ordered
          last in the output permutation (subject to the cmember
          constraints).

     ‘KNOBS(2)’
          If nonzero, aggressive absorption is performed.

     ‘KNOBS(3)’
          If nonzero, statistics and knobs are printed.

     CMEMBER is an optional vector of length n.  It defines the
     constraints on the ordering.  If ‘CMEMBER(j) = S’, then row/column
     j is in constraint set C (C must be in the range 1 to n).  In the
     output permutation P, rows/columns in set 1 appear first, followed
     by all rows/columns in set 2, and so on.  ‘CMEMBER = ones (1,n)’ if
     not present or empty.  ‘csymamd (S,[],1:n)’ returns ‘1:n’.

     ‘P = csymamd (S)’ is about the same as ‘P = symamd (S)’.  KNOBS and
     its default values differ.

     ‘STATS(4:7)’ provide information if CCOLAMD was able to continue.
     The matrix is OK if ‘STATS(4)’ is zero, or 1 if invalid.
     ‘STATS(5)’ is the rightmost column index that is unsorted or
     contains duplicate entries, or zero if no such column exists.
     ‘STATS(6)’ is the last seen duplicate or out-of-order row index in
     the column index given by ‘STATS(5)’, or zero if no such row index
     exists.  ‘STATS(7)’ is the number of duplicate or out-of-order row
     indices.  ‘STATS(8:20)’ is always zero in the current version of
     CCOLAMD (reserved for future use).

     The authors of the code itself are S. Larimore, T. Davis and S.
     Rajamanickam in collaboration with J. Bilbert and E. Ng.  Supported
     by the National Science Foundation (DMS-9504974, DMS-9803599,
     CCR-0203270), and a grant from Sandia National Lab.  See
     <http://faculty.cse.tamu.edu/davis/suitesparse.html> for ccolamd,
     colamd, csymamd, amd, colamd, symamd, and other related orderings.

     See also: *note symamd: XREFsymamd, *note ccolamd: XREFccolamd.

 -- : P = dmperm (S)
 -- : [P, Q, R, S] = dmperm (S)

     Perform a Dulmage-Mendelsohn permutation of the sparse matrix S.

     With a single output argument ‘dmperm’ performs the row
     permutations P such that ‘S(P,:)’ has no zero elements on the
     diagonal.

     Called with two or more output arguments, returns the row and
     column permutations, such that ‘S(P, Q)’ is in block triangular
     form.  The values of R and S define the boundaries of the blocks.
     If S is square then ‘R == S’.

     The method used is described in: A. Pothen & C.-J. Fan.  ‘Computing
     the Block Triangular Form of a Sparse Matrix’.  ACM Trans.  Math.
     Software, 16(4):303-324, 1990.

     See also: *note colamd: XREFcolamd, *note ccolamd: XREFccolamd.

 -- : P = symamd (S)
 -- : P = symamd (S, KNOBS)
 -- : [P, STATS] = symamd (S)
 -- : [P, STATS] = symamd (S, KNOBS)

     For a symmetric positive definite matrix S, returns the permutation
     vector p such that ‘S(P, P)’ tends to have a sparser
     Cholesky factor than S.

     Sometimes ‘symamd’ works well for symmetric indefinite matrices
     too.  The matrix S is assumed to be symmetric; only the strictly
     lower triangular part is referenced.  S must be square.

     KNOBS is an optional one- to two-element input vector.  If S is
     n-by-n, then rows and columns with more than ‘max
     (16,KNOBS(1)*sqrt(n))’ entries are removed prior to ordering, and
     ordered last in the output permutation P.  No rows/columns are
     removed if ‘KNOBS(1) < 0’.  If ‘KNOBS(2)’ is nonzero, STATS and
     KNOBS are printed.  The default is ‘KNOBS = [10 0]’.  Note that
     KNOBS differs from earlier versions of ‘symamd’.

     STATS is an optional 20-element output vector that provides data
     about the ordering and the validity of the input matrix S.
     Ordering statistics are in ‘STATS(1:3)’.  ‘STATS(1) = STATS(2)’ is
     the number of dense or empty rows and columns ignored by SYMAMD and
     ‘STATS(3)’ is the number of garbage collections performed on the
     internal data structure used by SYMAMD (roughly of size ‘8.4 * nnz
     (tril (S, -1)) + 9 * N’ integers).

     Octave built-in functions are intended to generate valid sparse
     matrices, with no duplicate entries, with ascending row indices of
     the nonzeros in each column, with a non-negative number of entries
     in each column (!)  and so on.  If a matrix is invalid, then SYMAMD
     may or may not be able to continue.  If there are duplicate entries
     (a row index appears two or more times in the same column) or if
     the row indices in a column are out of order, then SYMAMD can
     correct these errors by ignoring the duplicate entries and sorting
     each column of its internal copy of the matrix S (the input matrix
     S is not repaired, however).  If a matrix is invalid in other ways
     then SYMAMD cannot continue, an error message is printed, and no
     output arguments (P or STATS) are returned.  SYMAMD is thus a
     simple way to check a sparse matrix to see if it’s valid.

     ‘STATS(4:7)’ provide information if SYMAMD was able to continue.
     The matrix is OK if ‘STATS (4)’ is zero, or 1 if invalid.
     ‘STATS(5)’ is the rightmost column index that is unsorted or
     contains duplicate entries, or zero if no such column exists.
     ‘STATS(6)’ is the last seen duplicate or out-of-order row index in
     the column index given by ‘STATS(5)’, or zero if no such row index
     exists.  ‘STATS(7)’ is the number of duplicate or out-of-order row
     indices.  ‘STATS(8:20)’ is always zero in the current version of
     SYMAMD (reserved for future use).

     The ordering is followed by a column elimination tree
     post-ordering.

     The authors of the code itself are Stefan I. Larimore and Timothy
     A. Davis.  The algorithm was developed in collaboration with John
     Gilbert, Xerox PARC, and Esmond Ng, Oak Ridge National Laboratory.
     (see <http://faculty.cse.tamu.edu/davis/suitesparse.html>)

     See also: *note colperm: XREFcolperm, *note colamd: XREFcolamd.

 -- : P = symrcm (S)
     Return the symmetric reverse Cuthill-McKee permutation of S.

     P is a permutation vector such that ‘S(P, P)’ tends to have its
     diagonal elements closer to the diagonal than S.  This is a good
     preordering for LU or Cholesky factorization of matrices that come
     from “long, skinny” problems.  It works for both symmetric and
     asymmetric S.

     The algorithm represents a heuristic approach to the NP-complete
     bandwidth minimization problem.  The implementation is based in the
     descriptions found in

     E. Cuthill, J. McKee.  ‘Reducing the Bandwidth of Sparse Symmetric
     Matrices’.  Proceedings of the 24th ACM National Conference,
     157–172 1969, Brandon Press, New Jersey.

     A. George, J.W.H. Liu.  ‘Computer Solution of Large Sparse Positive
     Definite Systems’, Prentice Hall Series in Computational
     Mathematics, ISBN 0-13-165274-5, 1981.

     See also: *note colperm: XREFcolperm, *note colamd: XREFcolamd,
     *note symamd: XREFsymamd.

