===================================================
= Major New Features in Mathematica Version 2.2 =
===================================================
Summaries of New Features
- --------------------------
This listing contains brief summaries of some of the enhancements
to Mathematica between Version 2.1 and Version 2.2. Some of these
enhancements are explained at greater length in subsequent sections.
Particularly important changes are indicated by outlined bullets: o.
Incompatibilities between Versions 2.1 and 2.2 are indicated
below by crossed bullets: x.
Algebra
=======
o Symbolic definite integration now includes tests for non-integrable
singularities, and corrections for branch cuts in the range of integration.
o There is a new Method option for specifying the row reduction
algorithm used by the linear algebra functions Inverse,
LinearSolve, NullSpace, and RowReduce. Possible values for Method
are CofactorExpansion, DivisionFreeRowReduction, OneStepRowReduction,
and Automatic, which uses an internal heuristic for selecting
an algorithm.
- - The default value of the VerifySolutions option in Solve
has been changed from False to Automatic. With
VerifySolutions -> Automatic, solutions involving multiple-valued
functions are tested by substituting them back into the original
equation. For example, the solution {x -> (-1)^(2/3)} for the
equation Solve[x^(3/2) == 1, x] is rejected upon testing.
- - There is a new value, Automatic, for the ZeroTest option in the
linear algebra functions Inverse, LinearSolve, NullSpace,
RowReduce, Eigenvectors, and Eigensystem. ZeroTest->Automatic
applies various transformations, including numerical approximations,
to determine whether an expression is zero.
- - The code used by Solve for handling equations with nontrivial
powers has been revised and extended. Equations such as
Solve[Exp[x+1] == Exp[2 x], x] and Solve[y^(1+a) == 1, y]
will now be solved.
- - Transcendental dependency checking in Eliminate and related
functions has been improved so that it no longer rejects soluble
transcendental dependencies. For example,
Eliminate[{x^(a b) == f, b == E^(x y)}, b] will now
correctly eliminate the parameter b.
- - Equations involving repeated roots are now solved much more
quickly, typically by a factor equal to the multiplicity of the
root.
- - The speed of Roots for equations that can be factored or
decomposed has been improved.
- - The form of results from Solve has been simplified, especially
for polynomial equations involving roots.
- - The behavior of Roots for nonpolynomial equations and other
invalid inputs has been improved, as well as the ability to recognize
inputs that are not explicitly polynomial equations.
- - A shortcoming in handling of equations that are soluble by simple
elimination of variables has been corrected. For example,
Solve[b/(a x) == 1 && a == 1 && b == Sqrt[2], x] formerly
gave no solution.
- - Automatic recognition of linear equations has been improved. Formerly,
Solve and related functions sometimes failed to recognize linear
equations, and would compute solutions using methods designed for more
general equations.
- - Solve and Roots handle cubic and quartic equations
faster, and give more concise output.
- - There is a new function HermiteNormalForm that computes the
Hermite normal form of a matrix of integers.
- - LatticeReduce now handles integer matrices of deficient row rank.
- - AlgebraicRules now returns an AlgebraicRulesData object
rather than {{}} for the degenerate case AlgebraicRules[{},{}].
- - The speed of Solve for equations with several variables has
been greatly improved, in part through the use of an improved
algorithm for variable ordering.
- - The function Det has been speeded up for all exact matrices.
- - LUDecomposition now works for exact matrices.
- - An infinite loop in multivariate factorization has been corrected.
- - Dt[f, {x, n}] will now return unchanged for symbolic values of n.
- - The NonConstants option in Dt now works for parameters
within unrecognized functions.
- - A number of simplifications for trigonometric functions of inverse
trigonometric functions are now automatic. For example,
Cos[ArcSin[z]] becomes Sqrt[1 z^2] and
Cos[ArcTan[z]] becomes 1/Sqrt[1 + x^2].
- - The behavior of trigonometric and inverse trigonometric functions at
infinity has been made more consistent. For example, Tan[Infinity]
evaluates to Indeterminate rather than RealInterval[{-Infinity, Infinity}],
and ArcSin[-Infinity] now evaluates to I Infinity.
- - The function Beta[x, y] will now simplify automatically
when x + y is an integer.
- - Indefinite integration preserves the form of radicals in results
when possible, thereby improving behavior with respect to branch
cuts. For example, the results of Integrate[1/Sqrt[a-b x^2],x]
and Integrate[Sqrt[-1-x^2], x] are now given in terms of the
roots in the integrands.
- - Indefinite integration preserves logarithmic branch cuts
when possible, thereby improving consistency between constants
of integration. For example, Integrate[Log[1 - a t], t] now
gives an answer in terms of the Log[1 - a t] rather
than Log[a t - 1].
- - ComplexExpand is 10--20% faster for typical examples.
- - Limit and Residue now include support for the functions
Csch, Sech, Coth, Rational, Zeta, Gamma, and Beta.
Limit will also now handle the functions ArcCsch,
ArcSech, ArcTanh, and ArcCoth.
- - The ability of Integrate to handle integrands involving unknown
functions has been extended.
Example: Integrate[D[(E^b[x]*a[x]+E^d[x]*c[x])*Log[Log[x]],x],x].
- - The minus sign from a rational number with a numerator of 1
is distributed over Plus. For example, (-1/2) (-a-b)
now returns (a + b)/2.
- - An error in simplification of certain products of roots and rational
numbers has been corrected to prevent infinite recursion.
Example: (1/5) (Pi/2)^(3/2).
- - Differentiation of SphericalHarmonicY[l, m, theta, phi]
with respect to theta has been added.
- - A rule for differentiation of LogGamma has been added.
- - Series involving hyperbolic functions are now expressed in terms of
hyperbolic functions rather than exponentials. Results both
from Series and from functions such as Limit that use series
expansions internally are improved.
- - Limits involving the two argument form of Erf can now be computed.
- - Directional limits are used when definite integrals are evaluated by
computing limits of the corresponding indefinite integral.
- - Series expansions for Hypergeometric0F1 with constant arguments
are now handled correctly.
- - Series expansions of Erf, Erfc, and Erfi are now
supported. Asymptotic expansions have also been added for
SinIntegral, CosIntegral, SinhIntegral, CoshIntegral,
FresnelC, and FresnelS.
- - The behavior of Apart and Factor for certain expressions containing
roots and complex numbers has been improved. For example, the
result of Apart[1/(1 - c ((-1 - I) x^3)^(3/2))^3] is now correct
for all values of c and x.
- - The behavior of Factor for polynomials containing inexact
coefficients has been improved.
For example, Factor[0.511547 + z^2] no longer returns
a polynomial with a small linear term.
- - An error in Expand for certain expressions with complex exponents
has been corrected.
Example: Expand[(x^3)^(1/2 + 2*I)] is now correct.
- - Automatically simplified forms for Hypergeometric2F1 have been improved.
- - A number of formerly incorrect results from definite integration
have been corrected, including results for Gaussian definite integrals.
x Unique integration variables are now generated when necessary in
symbolic integration to prevent interaction between
integration variables in nested integrals.
x Automatic simplifications involving roots of integers have been changed and
made more consistent. For example, Sqrt[2^3] now factors out even
powers and returns 2 Sqrt[2].
x The behavior of LinearSolve[m, b] has been changed when
b is a matrix. The result now satisfies the relation
b == m.LinearSolve[m, b] rather than the transpose.
Corresponding changes have been made in LUDecomposition
and LUBackSubstitution.
Numerics
========
o There is a new global variable $RandomState that gives an integer
representing the internal state of the random number generator.
o Optimized code has been added for solving sparse numerical systems of linear
equations. Solve automatically applies this code to such equations.
- - Normalization and ordering of the vectors returned by Eigenvectors
is now independent of numerical precision.
- - The functions Dot and MatrixPower have been rewritten
for inexact numerical matrices, and are now faster.
- - The function NDSolve now has an option MaxStepSize for
controlling the maximum step size used in solving differential
equations.
- - The function NDSolve now accepts multiple segments of domains: for
example, NDSolve[ {y'[x]==x, y[1]==1}, y[x], {x, 1, 2, 3, 4} ].
- - The function SchurDecomposition now has an option RealBlockForm->False.
The option setting RealBlockForm->True reproduces the behavior of previous
versions, which was to give 2 X 2 real blocks rather than complex
numbers.
- - The permutation matrix returned by SchurDecomposition is
now a matrix of exact, rather than inexact, integers.
- - An error in the treatment of the SingularityDepth option
in NIntegrate for multi-dimensional integrals has
been corrected.
- - Det has been speeded up for complex numerical matrices and rational
matrices.
- - Inverse for matrices of machine real numbers or of integers has
been speeded up.
- - An error in NRoots related to automatic switching between
machine arithmetic and extended precision arithmetic has been
corrected.
- - Fourier for multidimensional arrays has been speeded up. The
initialization package Fourier.m is now obsolete.
- - Log[Infinity] now evaluates to Infinity. Log[Indeterminate]
now evaluates to Indeterminate.
- - FindMinimum is now better able to handle functions which become large
very rapidly away from the minimum.
- - The behavior of JacobiAmplitude for exact numerical arguments
has been corrected. Inputs such as JacobiAmplitude[2, 2] will
return unchanged, rather than the result of an internal rule being
returned.
- - An inconsistency in numerical evaluation of Hypergeometric2F1
across the branch cut has been corrected.
- - An error in numerical evaluation of Erfc along the imaginary
axis has been corrected.
- - Control of precision in numerical evaluation of trigonometric
functions has been corrected. For example, iteration of
x=ArcTan[Tan[x]] for inexact values of x will retain
the original precision.
- - Rounding used during conversion of high-precision numbers to
machine-precision numbers has been improved.
- - Numerical precision has been improved in computing square roots
of complex numbers.
x Canonical ordering for numbers has been changed and made more consistent.
This change affects Sort and functions with the Orderless attribute.
Numbers are now ordered first by real part, and if the real parts
are equal, by the absolute value of the imaginary part. In
particular, complex conjugate pairs will now be adjacent in sorted
order. Numbers were formerly sorted first by real part and then
by imaginary part.
Input and Output
================
o The input \(char) can now be used to enter characters from
an extended character set. For example \(Alpha) is recognized as
the corresponding Greek character. Extended characters can be used
in strings and in names for symbols. The InputForm of extended
characters will display as \(char). Extended characters are
encoded using the Unicode Standard.
- - The value of the WordSeparators option can now be a pair of
lists, as with RecordSeparators.
- - FortranForm and CForm have been changed to display
machine numbers at full machine precision.
- - Handling of syntax errors involving the backquote (`) has been
improved.
- - Processing of octal character codes has been improved. For example,
it is now possible to make a symbol whose name is an octal code.
- - Comments contained in input are now written to the stream $Echo.
- - The backquote character (`) can now appear in StringForm
using \`, as in StringForm["aaa\`bbb `1` ccc", x].
- - Mathematica can now format more deeply nested expressions.
- - Warning messages for incorrect parentheses in input have been improved.
- - The number of input digits is now preserved when displaying
negative machine numbers.
- - An error in the TeXForm of Intersection has been fixed.
- - Line breaking has been changed to prevent line breaks within
multibyte characters, before punctuation marks, and within
TeX tokens in the output of TeXForm.
- - All file operation functions will now issue a warning message if
the filename argument is an empty string.
- - The speed of ReadList when reading multiline expressions
has been greatly improved.
- - An error has been corrected in the behavior of ReadList
when the RecordLists -> True option is used and there
are tabs or spaces at the end of a line.
- - ReadList and related functions which read objects of type
Number from a file can now accept numbers in which the exponent
is specified with a D notation. For example,
1.D+8 will be read by ReadList as 1.0 * 10^8.
- - The RecordLists option in ReadList will now work in the presence
of a third argument specifying the number of objects to read.
- - The RecordSeparators option in ReadList can now be used
when reading Number format.
x The display of numbers with zero precision has been changed to indicate
the accuracy as an exponent: for example, 0. 10^99.
x Parsing of nested SameQ is now left associative.
SameQ[a, b] === SameQ[a, b] is now parsed as
SameQ[SameQ[a, b], SameQ[a, b]]
rather than SameQ[a, b, SameQ[a, b]].
x The input a != b == c is now equivalent to
Inequality[a, Unequal, b, Equal, c] rather than
Equal[Unequal[a, b], c], and the corresponding
formatting rules have been added so
Inequality[a, Unequal, b, Equal, c]
is displayed as a != b == c.
x The input a_:b/c is now treated as the pattern a_:(b/c)
rather than the fraction (a_:b)/c.
x The input x__:y is now treated as an optional pattern
rather than a syntax error.
Graphics and Sound
==================
- - Support for additional PostScript operators (sqrt, etc.) has
been added so that arrowheads and other objects can be drawn.
- - The rendering of three-dimensional polygons viewed edge-on
has been changed to show the polygon if it has visible edges.
- - The rendering of shaded ContourGraphics objects is considerably faster,
particularly when there is a large amount of small-scale structure in
the output. Errors in processing of the ContourStyles and
ContourLines options have also been corrected.
- - The fourth element in the first argument of ParametricPlot3D
can now be a list of graphics primitives.
- - Coercion of Graphics3D objects to Graphics objects has
been improved.
- - Polygons in Graphics3D objects that lie outside the bounding
box are now omitted from the display.
- - An input argument checking error in ListPlay has been corrected.
Machine-Specific Changes
- - The X PostScript interpreters now support the use of visuals other
than the default. This is particularly beneficial for users who have
a 24-bit display in which the 24-bit visual is not the default visual.
- - The X PostScript interpreters will now use Display PostScript if
the necessary extensions are present on the X server.
- - All X-based PostScript interpreter programs that use resource files
will now run only if the proper resource file has been installed.
This will help in repairing installation problems and enhance
the reliability of these utilities.
- - The X-based PostScript interpreters for Motif (motifps) and
OPEN LOOK (olps) can now display rotated text.
- - New output formats have been added to the PostScript interpreter
rasterps to produce Portable BitMap (pbm), Portable PixMap (ppm),
and Portable GrayMap (pgm) binary output files. Public domain
libraries such as the PBMPlus package available on MathSource2pt
exist to render this format into a wide variety of output types
such as TIFF. (Note: rasterps does not exist on the Macintosh.
The DOS version of rasterps is available on MathSource, but is
not distributed on Windows.)
System Features
===============
o MathBook is now included. MathBook is an X-based program
developed at Wolfram Research that provides a hypertext interface
to navigate through documentation such as the Mathematica Reference
Guide. Versions are available for Motif, OPEN LOOK, and Athena
widget sets.
- - Localization of variables in Module has been corrected for
the case when variable initialization also involves a Module.
- - A new option SameTest has been added to Union, Intersection,
and Complement, for specifying the function to use when comparing
expressions. As part of this change, Union and Intersection no longer
have the attribute Orderless, but instead sort their arguments
outside the main evaluator.
- - The usage messages for options have been extended to include more
complete information about possible values.
MathLink (Not supported in the Windows or DOS versions of Mathematica)
========
o The kernel and the Notebook front end now communicate using MathLink.
- - A new link protocol has been added for creating ``local'' link objects
within MathLink source files for use in storing and manipulating
Mathematica expressions.
- - The C function MLTransferExpression has been added to the MathLink
for copying an expression from one link to another.
- - The C function MLDeviceInformation has been added for obtaining
low-level device information.
- - New C functions MLSetUserData and MLUserData have been added
to the MathLink library for use in storing data in a link object.
- - MathLink now supports the AppleTalk Data Stream Protocol.
x The yield function interface has been changed.
Now the first argument passed to the yield function is
the link pointer. A slightly different implementation of the
yield function feature was present but not
documented in Version 2.1.
Packages
========
(For more information, see Guide to Standard Mathematica Packages,
Supplement V2.2.)
o There is a new package Graphics`ContourPlot3D` for plotting
implicit functions of three variables and constructing iso-surfaces
of three-dimensional data sets. The package includes the function
ContourPlot3D, for use with functions, and ListContourPlot3D,
for use with lists of data.
o There is a new package Calculus`PDSolve1` for symbolic solution
of first-order partial differential equations. This package
loads the package Calculus`DSolve` automatically as needed.
- - The package Calculus`DSolve` now supports additional Ricatti
equations and systems of nonlinear ordinary differential equations.
- - DSolve has been speeded up for systems of linear equations with
constant coefficients. Detection of degenerate solutions and rejection
of invalid branches for valid solutions has been improved. Solutions
have been added for inhomogeneous linear equations with constant
coefficients. Additional classes of equations are solved by
representing the result as an unevaluated definite integral (using
Integrate) or as the solution of a nondifferential equation
(using Solve). Certain classes of simultaneous equations and
linear equations with variable coefficients have been added.
Handling of equations with inexact coefficients has been improved.
- - There is a new package Utilities`Package` that introduces
functions for finding accessible Mathematica packages, and for getting
documentation and summary information from standard package headers.
- - A package NumericalMath`SplineFit` has been added.
- - The package Graphics`Spline` has been modified to use the
PostScript curveto operator so that splines corresponding
to four-point Bezier curves are rendered more efficiently.
The ability to render splines adaptively has also been added.
- - There is a new package Graphics`Arrow` for generating pointers and
arrowheads in graphical output.
- - Option processing has been corrected and improved in a number of
graphics packages, including Graphics`Graphics`,
Graphics`Graphics3D`, and Graphics`PlotField3D`.
Options are now supported in ErrorListPlot in
the Graphics`Graphics` package.
- - The functions Geodesate, Truncate, and OpenTruncate have
been added in the Graphics`Polyhedra` package.
- - Automatic numericalization in the packages
Statistics`ContinuousDistributions`, Statistics`NormalDistribution`,
and Statistics`DiscreteDistributions` has been made more
consistent. Also, distributions defined in these packages will now
return zero for parameters outside the domain of the distribution.
- - There is a new package Calculus`VariationalMethods` for
variational calculus.
- - There is a new package Calculus`EllipticIntegrate` for handling
standard classes of elliptic integrals.
- - Handling of messages and error conditions in the package
DiscreteMath`RSolve` has been improved.
- - Extensive improvements and corrections have been made in the package
Algebra`SymbolicSum`. Many finite sums of rational functions have
been speeded up.
- - The package NumericalMath`Butcher` has been modified.
The number of steps in the method can now be symbolic.
- - The package Calculus`FourierTransform` has been revised.
An inconsistency in normalization of DiracDelta has been
corrected.
- - The package Calculus`LaplaceTransform` has been revised, with
improved handling of multivariate transforms.
- - The behavior of NLimit in NumericalMath`NLimit` has
been improved for cases in which the algorithm fails.
- - SimplifyGamma has been improved for generalized incomplete
gamma functions.
- - SimplifyPolyGamma has been improved for sums of PolyGamma
functions, and an infinite recursion error has been corrected.
- - There is a new package Miscellaneous`Music`.
- - There is a new package Miscellaneous`Audio` that includes a variety
of utilities for creating and manipulating sounds.
- - A new package Statistics`Common`FitCommon` has been created
for defining symbols common to the Statistics`LinearRegression`
and Statistics`NonlinearFit` packages, and a package
Graphics`Common`GraphicsCommon` for defining common symbols in
graphics packages has been added.
- - The behavior near singularities of PlotVectorField and related
functions in the packages Graphics`PlotField` and
Graphics`PlotField3D` has been improved.
- - The precision of values used for colors in the Graphics`Colors`
package has been increased to produce results more suitable for
24-bit displays.
The package also includes specifications for 133 new colors.
- - An error has been corrected in processing of the FrameTicks
option for the logarithmic plotting functions (such as LogListPlot)
in the Graphics`Graphics` package.
- - Graphics created with FilledPlot in the Graphics`FilledPlot`
package can now be easily combined with other graphics. This package
now introduces an option to Graphics called AxesFront that
allows the axes and grid lines to be drawn over the graphic.
Also, a new function ListFilledPlot has been added.
- - The ListShadowPlot3D function defined in the Graphics`Graphics3D`
package can now be used with a nonsquare matrix of data.
- - The package Obsolete.m provides equivalent code or
warning messages for those Mathematica function usages that are
no longer valid in Version 2.2.
x The package PolynomialMod has been moved from the NumberTheory
directory to the Algebra directory. The new package context is
Algebra`PolynomialMod`.
Symbolic Linear Algebra
- ------------------------
Options in Linear Algebra Functions
===================================
The algorithms used in Mathematica for working with symbolic matrices
(matrices with exact or symbolic entries) and for solving linear
equations with symbolic coefficients have been substantially extended
for Version 2.2. The affected functions include Inverse, LinearSolve,
NullSpace, RowReduce, Eigenvectors, and other functions (such as
Solve and DSolve) that manipulate linear equations internally.
The two most visible changes are the introduction of a Method option
used to select an algorithm for row reduction, and the addition
of ZeroTest->Automatic as a value for the ZeroTest option. Row
reduction is described in the following sections.
The ZeroTest option specifies a function to apply in determining
whether a matrix element is zero. For complicated expressions,
making this determination can be very time consuming, or even
mathematically impossible. An expression involving transcendental
functions, for example, may simplify to zero only through application
of specialized identities. The ZeroTest option allows you to
control the types of transformations that are used.
The value ZeroTest->Automatic applies various transformations
including numerical approximations in an effort to determine whether
an expression is zero. This approach is particularly appropriate
for matrices involving transcendental functions, algebraic numbers,
or other complicated expressions.
- --------------------------------------------------------------------------------
| |
| ZeroTest->Automatic use built-in heuristics to decide whether an |
| expression is zero |
| |
| ZeroTest->(# == 0 &) test only for expressions that are |
| explicitly zero |
| |
| ZeroTest->(Together[#] == 0 &) |
| apply the function Together to an |
| expression before comparing it with zero |
| |
- --------------------------------------------------------------------------------
Values for the ZeroTest option in linear algebra functions.
This matrix is singular.
In[1]:= m = {{1, 2 Sin[x]^2}, {1, 1 - Cos[2 x]}}
2
Out[1]= {{1, 2 Sin[x] }, {1, 1 - Cos[2 x]}}
With a trivial value for the ZeroTest option, Inverse
does not detect that this matrix is singular.
In[2]:= Inverse[m, ZeroTest -> (# == 0 &)]
1 - Cos[2 x]
Out[2]= {{------------------------,
2
1 - Cos[2 x] - 2 Sin[x]
2
-2 Sin[x]
------------------------},
2
1 - Cos[2 x] - 2 Sin[x]
1
{-(------------------------),
2
1 - Cos[2 x] - 2 Sin[x]
1
------------------------}}
2
1 - Cos[2 x] - 2 Sin[x]
Although ZeroTest -> Automatic requires slightly more time to
evaluate, it does allow Inverse to determine that this matrix is
singular.
In[3]:= Inverse[m, ZeroTest -> Automatic]
Inverse::sing:
2
Matrix {{1, 2 Sin[x] }, {1, 1 + <<1>>}}
is singular.
2
Out[3]= Inverse[{{1, 2 Sin[x] },
{1, 1 - Cos[2 x]}}, ZeroTest -> Automatic]
Row Reduction
=============
Row reduction is the process of constructing linear combinations of
rows of a matrix to obtain the reduced row echelon form of the matrix,
in which all of the entries above and below the pivots are zero.
If the matrix is thought of as a system of linear equations, row
reduction corresponds to replacing a system of equations with an
equivalent system consisting of linear combinations of the original
equations.
Here is the result from solving a pair of linear equations.
In[4]:= Solve[{m11 x1 + m12 x2 == b1,
m21 x1 + m22 x2 == b2}, {x1, x2}]
b1 m12 (-(b2 m11) + b1 m21)
Out[4]= {{x1 -> --- + --------------------------,
m11 m11 (-(m12 m21) + m11 m22)
-(b2 m11) + b1 m21
x2 -> -(--------------------)}}
-(m12 m21) + m11 m22
These equations can be represented as the matrix
equation m.x == b.
In[5]:= m = {{m11, m12}, {m21, m22}}; b = {b1, b2} ;
LinearSolve gives the solution to the matrix equation.
This result is equivalent to the result obtained by Solve.
In[6]:= LinearSolve[m, b]
b1 m12 (b2 m11 - b1 m21)
Out[6]= {--- - --------------------------,
m11 m11 (-(m12 m21) + m11 m22)
b2 m11 - b1 m21
--------------------}
-(m12 m21) + m11 m22
Here is the row echelon form of the matrix of coefficients
for this pair of equations. The solution can be obtained
from the last column of the result.
In[7]:= RowReduce[{{m11, m21, -b1}, {m12, m22, -b2}}]
b1
Out[7]= {{1, 0, -(---) -
m11
(-(b2 m11) + b1 m12) m21
--------------------------},
m11 (-(m12 m21) + m11 m22)
-(b2 m11) + b1 m12
{0, 1, --------------------}}
-(m12 m21) + m11 m22
Methods of Row Reduction
In Version 2.2, the functions Inverse, LinearSolve, NullSpace,
and RowReduce include a Method option for selecting an algorithm
to use for row reduction. (A row reduction algorithm can also be
specified for Solve, with the command SetOptions[RowReduce,
Method -> method]). Although all values of the Method option give
mathematically equivalent results, the complexity of the answer,
and the time required to compute it, can differ significantly
between methods.
- --------------------------------------------------------------------------------
| |
| Method->CofactorExpansion |
| use cofactor expansion for row reduction |
| |
| Method->DivisionFreeRowReduction |
| use the division-free algorithm for row |
| reduction |
| |
| Method->OneStepRowReduction |
| use the one-step algorithm for row reduction |
| |
| Method->Automatic select a row reduction algorithm automatically |
| |
- --------------------------------------------------------------------------------
Values for the Method option in linear algebra functions.
Row reduction with Method->CofactorExpansion uses matrix cofactors
to compute the inverse of the left-most square submatrix, and effectively
multiplies by this inverse to get the row echelon form of the original
matrix. This method is typically useful for small dense matrices. It
will fail if the left-most square matrix is not invertible, or if there
are more rows than columns, in which case the left-most square submatrix
does not exist. If this method fails, the division-free algorithm is used.
Both the division-free algorithm, selected using
Method->DivisionFreeRowReduction, and the one-step algorithm,
selected using Method -> OneStepRowReduction, obtain results using
operations such as multiplying rows by constants, and adding one
row of the matrix to another. As the name suggests, the division-free
algorithm avoids division of matrix elements by pivots. The one-step
algorithm does do exact divisions, and as a consequence will often
give smaller intermediate and final results.The division-free and
one-step algorithms are described in Erwin H. Bareiss, "Sylvester's
Identity and Multistep Integer-Preserving Gaussian Elimination,"
Mathematical Computation 22, 103 (1968): 565--578.
(Note that if the matrix contains approximate real numbers or radicals,
Method -> OneStepRowReduction is ignored.)
The default values of the Method option are chosen to give the
preferred behavior for typical matrices. Although there is often a
tradeoff between speed and complexity, this is not always the case.
Sometimes the fastest method also gives the simplest results.
You may want to experiment with different values for the Method
option and select the method that seems most appropriate for
your situation.
Here is the default behavior for solving this set of linear
equations.
In[8]:= LinearSolve[{{x,y,0},{0,z,x},{y,x,0}}, {1,0,0}]
2
1 y y y z
Out[8]= {- + -----------, -(-------), -----------}
x 2 2 2 2 2 2
x (x - y ) x - y x (x - y )
Here is the solution obtained using Method >CofactorExpansion.
This solution is mathematically equivalent to the previous solution,
but may be given in a different form.
In[9]:= LinearSolve[{{x,y,0},{0,z,x},{y,x,0}}, {1,0,0},
Method->CofactorExpansion]
2
x x y y z
Out[9]= {-(----------), ----------, -(----------)}
3 2 3 2 3 2
-x + x y -x + x y -x + x y
Here is the solution obtained using Method >DivisionFreeRowReduction.
Again, both the time required for the computation and the size of the
result may be different.
In[10]:= LinearSolve[{{x,y,0},{0,z,x},{y,x,0}}, {1,0,0},
Method->DivisionFreeRowReduction]
2
1 y y y z
Out[10]= {- + -----------, -(-------), -----------}
x 2 2 2 2 2 2
x (x - y ) x - y x (x - y )
Other linear algebra functions, such as NullSpace, also have a Method option.
In[11]:= NullSpace[{{x, 1, 3, 0}, {3 x, 0, 5, x}},
Method->OneStepRowReduction]
1 x -5 4
Out[11]= {{-(-), -, 0, 1}, {---, -(-), 1, 0}}
3 3 3 x 3
Random Number Generation
- -------------------------
The functions SeedRandom[ ] and Random[ ] cause the internal state
of the random number generator to change. Random[ ] returns a
random number of the specified type and advances the random number
generator to the next state so that the next call to Random[ ] will
give you a different result. SeedRandom[ ] gives a completely new
state that depends on the value of the seed specified. This lets
you start the random number generator at the same place to get an
identical sequence of random numbers, so you can, for example,
repeat a simulated experiment.
The global variable $RandomState allows you to save and restore
the state of the random number generator. By saving its state, you
can make other, unrelated calls to Random[ ], restore the state
to what it was before the unrelated calls were made, and proceed as
if those unrelated calls had never been made.
This seeds the random number generator.
In[1]:= SeedRandom[23];
This forms a table of random numbers.
In[2]:= a = Table[Random[ ], {5}]
Out[2]= {0.613023, 0.180991, 0.777741, 0.120589,
0.424956}
This forms another table of random numbers.
In[3]:= b = Table[Random[ ], {5}]
Out[3]= {0.732973, 0.196755, 0.98667, 0.312975,
0.0609892}
This reseeds the random number generator to the same initial state.
In[4]:= SeedRandom[23];
You get the same random numbers as before.
In[5]:= a == Table[Random[ ], {5}]
Out[5]= True
This saves the state of the random number generator in the variable savestate.
In[6]:= savestate = $RandomState
Out[6]= 5719829100760399981454893431860139940790300
9635798944922537314783898244824711380021450072991
4804102788634400420529694445087671496265568889367
4550095209321010238262197439701197574743526444609
3564127810430134664259030065716049623689870822495
2794067585775161966764581555216272246194708272492
9903373393832357719647189005481258347258401968165
2028508126110637841044993503256704014951433039886
8683344334190448841852859928837339683045086834879
7664126973441062108863413681785839989776553985455
9816325795628835230588320678529285283598436177670
2416322826697143753448517
This calls Random[ ] a few times.
In[7]:= Table[Random[ ], {3}]
Out[7]= {0.732973, 0.196755, 0.98667}
This restores the state of the random number generator to what it was.
In[8]:= $RandomState = savestate;
You get the same random numbers as before.
In[9]:= b == Table[Random[ ], {5}]
Out[9]= True
You do not need to explicitly save the value of $RandomState in a
variable. This can be done for you
automatically with a Block[ ] construct.
You can define a function that saves and restores the random state.
In[10]:= t := Block[{$RandomState = savestate},
Table[Random[ ], {3}]]
This restores the state of the random number generator to what it
was before b was formed.
In[11]:= $RandomState = savestate;
This calls Random[ ] from within a Block[ ] that saves
the random state.
In[12]:= t
Out[12]= {0.732973, 0.196755, 0.98667}
You get the same random numbers as before.
In[13]:= b == Table[Random[ ], {5}]
Out[13]= True
Sparse Linear Systems
- ----------------------
Mathematica provides the function Solve to solve
systems of equations. When the system is linear
in the variables, it can be represented and solved
in a matrix form; this functionality is
available from LinearSolve.
This uses Solve to solve this system.
In[1]:= Solve[ {3. x + 2. y == 5., 5. x + 3. y == 1.},
{x, y}]
Out[1]= {{x -> -13., y -> 22.}}
This uses LinearSolve to solve the same system
represented as a matrix problem.
In[2]:= LinearSolve[ {{3., 2.}, {5., 3.}}, {5., 1.}]
Out[2]= {-13., 22.}
Under appropriate conditions, Solve calls the same LU decomposition
routines that LinearSolve uses. These conditions are that the set
of equations is linear, and that the coefficients consist only of
machine numbers. This technique for solving linear systems is
suited to dense matrices where the number of zero entries is small.
For these dense systems, the representation of the equations
is more compact for LinearSolve than for Solve.
Alternatively if the system is sparse, i.e., if it has a large
number of zero entries, the Solve representation becomes much more
efficient. Not only is there an efficient representation for these
sparse systems, but there are specialized algorithms to solve them.
Such algorithms have been added to Version 2.2, to be called
automatically from Solve when the coefficients are real or complex
machine numbers and the system is sparse.
This sets up the equations.
In[3]:= (n = 20;
vars = Table[x[i], {i, n}];
eqns = Join[{-2. x[1] + x[2] == 1},
Table[x[i-1] - 2. x[i] + x[i+1] == i,
{i, 2, n-1}],
{x[n-1] - 2. x[n] == n}];
)
You won't want to see all the equations, but here are a few of them.
In[4]:= Short[eqns, 4]
Out[4]//Short=
{-2. x[1] + x[2] == 1, x[1] - 2. x[2] + x[3] == 2,
x[2] - 2. x[3] + x[4] == 3, <<2>>, <<2>>, <<13>>,
x[18] - 2. x[19] + x[20] == 19,
x[19] - 2. x[20] == 20}
Solve will automatically call the sparse solver. This example
runs many times faster in Version 2.2 than in Version 2.1.
In[5]:= Solve[eqns, vars]
Out[5]= {{x[1] -> -73.3333, x[2] -> -145.667,
x[3] -> -216., x[4] -> -283.333,
x[5] -> -346.667, x[6] -> -405.,
x[7] -> -457.333, x[8] -> -502.667,
x[9] -> -540., x[10] -> -568.333,
x[11] -> -586.667, x[12] -> -594.,
x[13] -> -589.333, x[14] -> -571.667,
x[15] -> -540., x[16] -> -493.333,
x[17] -> -430.667, x[18] -> -351.,
x[19] -> -253.333, x[20] -> -136.667}}
Among the many uses for this functionality is the possibility of
solving partial differential equations with finite difference methods.
Interval Computation
- ---------------------
Introduction
============
An approximate number can be represented as an interval containing the
exact value. Interval computation allows rigorous error analysis
in calculations with approximate numbers.
In versions of Mathematica prior to 2.2 the function RealInterval was
available in the kernel for basic interval computations. The packages
NumericalMath`IntervalArithmetic` and NumericalMath`IntervalAnalysis`
provided some functionality that was not available in RealInterval. In
Version 2.2, RealInterval has been extensively revised and renamed
Interval (in anticipation of complex intervals to be supported in
the future). The packages NumericalMath`IntervalArithmetic` and
NumericalMath`IntervalAnalysis` are still included with Version 2.2,
but the kernel function Interval is more powerful than the packages.
Interval
========
- --------------------------------------------------------------------------------
| |
| Interval[{a, b}] the real interval from a to b |
| |
| Interval[{a_1, b_1}, {a_2, b_2}, ... ] |
| the union of the real intervals a_1 to b_1, |
| a_2 to b_2, ... |
| |
- --------------------------------------------------------------------------------
Representations of real intervals.
This is the interval from 1 to 4.
In[1]:= Interval[{1, 4}]
Out[1]= Interval[{1, 4}]
An interval may be a single real number.
In[2]:= Interval[4]
Out[2]= Interval[{4, 4}]
Several disjoint intervals may be part of a single Interval data object.
In[3]:= Interval[{1, 3}, 4, {7, 9}]
Out[3]= Interval[{1, 3}, {4, 4}, {7, 9}]
Intersecting pieces are merged into single intervals.
In[4]:= Interval[{1, 3}, {2, 4}]
Out[4]= Interval[{1, 4}]
Arithmetic can be done with intervals.
In[5]:= Interval[{1, 4}] + Interval[{1, 2}, {10, 12}]
Out[5]= Interval[{2, 6}, {11, 16}]
Arithmetic with a mixture of numbers and intervals also works.
In[6]:= Interval[{1, 5}] + 3
Out[6]= Interval[{4, 8}]
With inexact numbers, directed rounding is used to ensure that the interval
always contains the ``true'' value.
In[7]:= Interval[3.] - 3
-16 -16
Out[7]= Interval[{-4.44089 10 , 4.44089 10 }]
Division by an interval containing 0 results in two semi-infinite intervals.
In[8]:= 1/Interval[{-2, 3}]
1 1
Out[8]= Interval[{-Infinity, -(-)}, {-, Infinity}]
2 3
Numerical evaluation is sometimes used to decide whether intervals intersect.
In[9]:= Interval[{1, Pi}, {E, Sqrt[26]}, {4, 7}]
Out[9]= Interval[{1, 7}]
It should be noted that symbolic interval arithmetic is not supported.
This is because combinatorial explosion of expressions involving Min
and Max would quickly render any symbolic result useless.
Set Theoretic Interval Functions
================================
The functions IntervalUnion, IntervalIntersection, and
IntervalMemberQ provide set theoretic functionality.
- --------------------------------------------------------------------------------
| |
| IntervalUnion[int_1,int_2, ...] |
| gives the set theoretic union of the intervals |
| int_1, int_2, ... |
| |
| IntervalIntersection[int_1,int_2, ...] |
| gives the set theoretic intersection of the |
| intervals int_1, int_2, ... |
| |
| IntervalMemberQ[int,x] gives True if the number x is in the interval |
| int and False otherwise |
| |
| IntervalMemberQ[int_1,int_2] |
| gives True if the interval int_2 is contained |
| within the interval int_1 and False otherwise |
| |
- --------------------------------------------------------------------------------
Set theoretic interval functions.
This defines two intervals.
In[10]:= (a = Interval[{1, 3}, 4, {7, 12}];
b = Interval[{2, 4}, {10, 20}];)
This finds the union of the intervals.
In[11]:= IntervalUnion[a, b]
Out[11]= Interval[{1, 4}, {7, 20}]
This finds the intersection of the intervals.
In[12]:= IntervalIntersection[a, b]
Out[12]= Interval[{2, 3}, {4, 4}, {10, 12}]
The result may be an empty interval.
In[13]:= IntervalIntersection[a, b, Interval[{-3, -2}]]
Out[13]= Interval[]
The number 10 is in the interval a.
In[14]:= IntervalMemberQ[a, 10]
Out[14]= True
Numerical approximation is used when required.
In[15]:= IntervalMemberQ[a, E]
Out[15]= True
The interval Interval[{8, 10}] is contained within the interval a.
In[16]:= IntervalMemberQ[a, Interval[{8, 10}]]
Out[16]= True
Interval Comparisons
====================
In manipulating intervals, you often want to compare them or find their
extrema.
- --------------------------------------------------------------------------------
| |
| Min[int] gives the greatest lower bound of the interval |
| int |
| |
| Max[int] gives the least upper bound of the interval int |
| |
- --------------------------------------------------------------------------------
Extremal functions.
- --------------------------------------------------------------------------------
| |
| int_1 < int_2 gives True if every element in the interval |
| int_1 is less than every element of int_2 |
| |
| int_1 <= int_2 gives True if every element in the interval |
| int_1 is less than or equal to every element |
| of int_2 |
| |
| int_1 > int_2 gives True if every element in the interval |
| int_1 is greater than every element of |
| int_2 |
| |
| int_1 >= int_2 gives True if every element in the interval |
| int_1 is greater than or equal to every |
| element of int_2 |
| |
- --------------------------------------------------------------------------------
Interval comparisons.
The smallest number in this interval is 1.
In[17]:= Min[Interval[{1, Infinity}]]
Out[17]= 1
The smallest upper bound for this interval is Infinity.
In[18]:= Max[Interval[]]
Out[18]= -Infinity
The number 3 is common to both intervals so the inequality is False.
In[19]:= Interval[{1, 3}] < Interval[{3, 7}]
Out[19]= False
Only the number 4 is common to both intervals, so the inequality is True.
In[20]:= Interval[{4, 7}] >= Interval[{1, 4}]
Out[20]= True
Elementary Functions on Intervals
=================================
The basic arithmetic operations and the elementary functions are supported
for interval arithmetic. In all cases directed rounding is used when
inexact numbers are involved.
Sin maps one interval onto another.
In[21]:= Sin[Interval[{2, 4}]]
Out[21]= Interval[{Sin[4], Sin[2]}]
Intersecting intervals are merged.
In[22]:= Sin[Interval[{-1, 1}, {2, 4}]]
Out[22]= Interval[{-Sin[1], Sin[2]}]
Interior extrema are dealt with properly.
In[23]:= Cos[Interval[{3, 4}]]
Out[23]= Interval[{-1, Cos[4]}]
Abs maps intervals to intervals.
In[24]:= Abs[Interval[{-5, -2}, {1, 3}]]
Out[24]= Interval[{1, 5}]
To get a bound on the magnitudes of the numbers in an interval use
Max or Min in conjunction with Abs.
In[25]:= Max[Abs[Interval[{-5, 3}]]]
Out[25]= 5
Lists as Sets: Sameness of Elements
- ------------------------------------
The default comparison test for the functions Union[ ],
Intersection[ ], and Complement[ ] is based on canonical
ordering: if canonical ordering distinguishes between two elements
in a list, they are considered different. In many situations
this notion of sameness is much too stringent. For this reason,
the functions Union[ ], Intersection[ ], and Complement[ ]
now have an option called SameTest.
This creates a table of nearly equal values.
In[1]:= a = Table[1.0 + 2^k $MachineEpsilon, {k, 0, 8}]
Out[1]= {1., 1., 1., 1., 1., 1., 1., 1., 1.}
With the default SameTest each of these numbers is different.
In[2]:= Union[a]
Out[2]= {1., 1., 1., 1., 1., 1., 1., 1., 1.}
SameQ[ ] allows small differences to be ignored.
In[3]:= Union[a, SameTest -> SameQ]
Out[3]= {1., 1., 1., 1., 1., 1., 1., 1.}
Equal[ ] allows slightly larger differences to be ignored.
In[4]:= Union[a, SameTest -> Equal]
Out[4]= {1., 1.}
MathLink Programming
- --------------------
New Features
============
Loopback Links
MathLink now supports ``loopback'' link objects that use a new
``local'' link protocol.
- --------------------------------------------------------------------------------
| |
int argc = 2;
char* argv[ ] = {"-linkmode", "loopback"};
MLINK locallink = MLOpen(argc, argv);
| |
- --------------------------------------------------------------------------------
Opening a loopback link.
A ``loopback'' link object is created when a link is opened with the
MLOpen argument sequence "-linkmode" "loopback". This link mode
selection implies the choice of "local" as the link protocol. This
provides a Mathematica expression type for the C programmer.
Expressions are read back from a loopback link in the same order
that they were written to that link.
Local link objects are not available from within Mathematica.
Echoing Expressions from One Link to Another
The C function MLTransferExpression(MLINK dmlp, MLINK smlp) has
been added to the MathLink library; it transfers an expression off
of one link and onto another in one call. This function is
particularly useful for copying an expression off of the ``main''
link to a loopback link for later use.
Low-Level Device Information
The C function MLDeviceInformation(MLINK, unsigned long, void *, long *)
has been added to the MathLink library; it returns information on
the low-level device that may be important to the MathLink programmer.
Various kinds of information can be accessed, depending on the
device involved. A selector argument to MLDeviceInformation
determines what kind of information is returned. (The valid
selectors are listed in the mathlink.h header file.)
The arguments to MLDeviceInformation are a link pointer, a selector, a pointer
to a buffer, and a pointer to a buffer length.
- --------------------------------------------------------------------------------
| |
extern void get_mathlink_data(MLINK mlp);
...
int fd = -1;
long len = sizeof(fd);
...
if (MLDeviceInformation(mlp, SOCKET_FD, &fd, &len)) {
XtAddInput(fd, XtInputReadMask, get_mathlink_data, mlp);
}else{
/* [have to poll with MLReady] */
...
}
| |
- --------------------------------------------------------------------------------
A typical use of MLDeviceInformation for X Window System programmers.
Storing User Data within Link Data Structure
The C functions MLSetUserData(MLINK, void *userdat, void (*userfn)(MLINK))
and have been added to the MathLink library; they provide storage
inside a link object for use by the MathLink programmer.
These functions provide storage for two pieces of data, symbolized
here by userdat and userfn. The userdat value is an arbitrary
value to store in the link data structure for whatever purpose the
programmer wishes; it is of no significance to any MathLink library
function. The userfn value (if it is not NULL) specifies a function
to be invoked when the link is closed.
AppleTalk Data Stream Protocol
MathLink now supports the AppleTalk Data Stream Protocol. This
protocol is specified as "ADSP". When opening a link in Mathematica,
choose this protocol by setting the LinkOpen option LinkProtocol->"ADSP";
when opening a link in an external program, use the sequence
"-linkprotocol" "ADSP" in the MLOpen argument list.
This protocol is useful for communicating with Macintosh computers
running System 6. ADSP is available for System 6, and it is also
supported by AppleTalk Remote Access. Note that PPC, a System 7
protocol, is also supported by AppleTalk Remote Access.
New Packet Types
The following packet types are defined in addition to
those listed in the MathLink Reference Guide.
- --------------------------------------------------------------------------------
| Packet Packet type code Contents |
|------------------------------------------------------------------------------|
| |
| ILLEGALPKT (== 0) code returned by |
| MLNextPacket for unrecognized |
| packet head |
| EvaluatePacket[expr] EVALUATEPKT an expression to be evaluated |
| (by Mathematica), with no |
| line number increment |
| EnterTextPacket[string] ENTERTEXTPKT a string to be processed as an|
| input string by Mathematica, |
| including line number |
| incrementing and emission of |
| output and input prompts |
| InputStringPacket[string] INPUTSTRPKT packet sent by Mathematica it |
| evaluates InputString[string] |
| SuspendPacket[args] SUSPENDPKT packet sent by Mathematica to |
| suspend communication (when |
| switching control to another |
| front end) |
| ResumePacket[args] RESUMEPKT packet sent by Mathematica to |
| resume communication (when |
| switching control from |
| another front end) |
| BeginDialogPacket[args] BEGINDLGPKT packet sent by Mathematica |
| when it begins a dialog |
| (using Dialog[ ]) |
| EndDialogPacket[args] ENDDLGPKT packet sent by Mathematica |
| when it ends a dialog |
| (e.g., with Return[ ]) |
| |
- --------------------------------------------------------------------------------
Additional packet names, type codes returned by MLNextPacket,
and descriptions of enclosed expression(s).
Experimental Features
=====================
The following features are implemented in Version 2.2 on an
experimental basis. The interface to these functions may change,
or the functions may be removed from future versions.
Returning to a Marked Position in Incoming Data
Marks have been added. A mark (C type MLINKMark) stands for a
place in the stream of incoming data to a link. The MathLink library
functions related to marks are MLCreateMark, MLSeekToMark, and
MLDestroyMark, as illustrated in the following sequence.
- --------------------------------------------------------------------------------
| |
MLINKMark mark = MLCreateMark(mlp);
MLGetInteger(mlp, &i);
MLSeekToMark(mlp, mark, 0);
MLGetInteger(mlp, &j);
assert(i == j);
MLDestroyMark(mlp, mark);
| |
- --------------------------------------------------------------------------------
Experimental functions for marking and returning to a location in incoming data.
This provides a mechanism to return to previously marked positions in
the stream.
Forking a Link
Forked links have been implemented with the MathLink library function
MLDuplicateLink(MLINK mlp, char *name). By forking a link, a
programmer can have two different code sequences independently
access the same incoming data.
- --------------------------------------------------------------------------------
| |
MLINK childlink = MLDuplicateLink(parentlink, "child");
MLGetInteger(parentlink, &i);
MLGetInteger(childlink, &j);
assert(i == j);
MLClose(childlink);
| |
- --------------------------------------------------------------------------------
Using the experimental link-forking feature.
The fork feature has uses similar to those of the mark feature.
It also allows passing link objects by value rather than by reference.
Putting and Getting Arrays of Numbers
The MathLink library has a number of functions for transmitting
multidimensional arrays of numbers. For example, for arrays of
integers there are
MLPutIntegerArray(MLINK, int *, long *, char **, long),
MLGetIntegerArray(MLINK, int **, long **, char ***, long *), and
MLDisownIntegerArray(MLINK, int *, long *, char **, long).
There are similar functions for short integers, long integers,
floats, doubles, and long doubles.
MLPutIntegerArray puts an array of integers onto a link. Its
arguments are: a link pointer; a pointer to an array of integers;
a pointer to a vector of long integers that specify the dimensions
of the array; a pointer to a vector of strings giving the head to
use in each dimension ( i.e., at each succeeding level in the
expression); and a long integer giving the number of dimensions.
For example, the following sequence in a C program puts a three-by-three
matrix of integers onto a link.
- --------------------------------------------------------------------------------
| |
int iarray[3,3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
long ndims = 2;
long dims[2] = {3, 3};
char *heads[2] = {"List", "List"};
MLPutIntegerArray(mlp, iarray, dims, heads, ndims);
| |
- --------------------------------------------------------------------------------
Putting an array of integers onto a link.
A typical program sequence using MLGetIntegerArray to receive an
array of integers might look like the following.
- --------------------------------------------------------------------------------
| |
int * iarray;
long * dims;
char ** heads;
long ndims;
MLGetIntegerArray(mlp, &iarray, &dims, &heads, &ndims)
use_array(iarray, dims, heads, ndims);
MLDisownIntegerArray(mlp, iarray, dims, heads, ndims)
| |
- --------------------------------------------------------------------------------
Getting an array from a link.
After accessing the received data, a program should make
the memory used by MathLink for the array available again by calling
MLDisownIntegerArray.
Other MathLink Developments
===========================
The following MathLink features have been present since Version 2.1,
but have not been covered in the MathLink Reference Guide.
Accessing a Link's Name
The C function MLName(MLINK) defined in the MathLink returns a
pointer to the name of the specified link. The memory referenced
by this pointer should be considered read-only memory: a program
may look at this string, but should not change it or deallocate
it. Generally, the link name is set when the link is created.
User-Defined Error Conditions
The MathLink library function MLSetError(MLINK, int) can be
used to set the MathLink error condition for a link. The second
argument should be an integer identifying the type of error;
this integer will be returned by a subsequent call of MLError.
MLSetError has no effect if the error condition is already
set to something other than MLEOK.
Once the error condition has been set, subsequent MathLink function
calls will fail until the error condition is cleared with MLClearError.
The programmer can expand on the set of predefined error codes in
mathlink.h to include one or more additional values.
Message Data
It is often desirable for one program communicating with
another to have a way to send urgent data---bypassing
other data that have been sent, but have not yet been read
by the other program. MathLink provides a message data
channel for this purpose.
The MathLink Reference Guide includes a limited description of
message data features, in the context of interrupting Mathematica
an external program or interrupting an installed external program
from Mathematica. That discussion mentions the MathLink library
function MLPutMessage(MLINK, unsigned long), which may be used to
put messages onto a link. A message is a one of a set of predefined
unsigned long constants defined in mathlink.h.
The MathLink library includes several other functions related to
message data. A message-handling function may be specified with
the C function MLSetMessageHandler(MLINK, MLMessageHandlerType),
and a pointer to the message handler can be retrieved with
MLMessageHandler(MLINK). The message handler is invoked asynchronously
whenever a message arrives on a link. To check for arriving messages
and process them synchronously, the functions MLMessageReady(MLINK)
and MLGetMessage(MLINK, unsigned long *, unsigned long *) are also
provided. Pass NULL as the third argument to MLGetMessage.
Establishing a Connection before Transmitting Expression Data
When a link is opened with MLOpen or LinkOpen, a link data structure
is created, but a working connection is not established until both
partners in the communication have taken some further action.
That further action can be simply to call a MathLink function for
putting data to, or getting data from, the link. If necessary,
the put or get function will block and wait for the other side of
the connection to come up.
Another option is to explicitly establish the connection by calling the
MathLink library function MLConnect(MLINK). MLConnect attempts to
establish a connection on an opened link, and will block until the
connection is made.
MLConnect allows the programmer to control where in the program
blocking will occur while the connection is established.
The programmer may want to set the yield function (see the following
section) before calling MLConnect.
Yield Functions
Often, MathLink function calls must block and wait for something
to be written at the other end of the connection. For many
applications, it is desirable to have a program do something else
while the MathLink function waits. To do this, a programmer may
specify a yield function that should be invoked by MathLink while
a link operation is blocked.
The C functions MLSetYieldFunction(MLINK, MLYieldFunctionType)
and MLYieldFunction(MLINK) in the MathLink library allow the
programmer to specify or retrieve the yield function.
Every time a MathLink function blocks, the yield function will be
invoked. The link pointer for the link involved will be passed as
the first argument to the yield function.
A yield function must return 0 to tell MathLink to continue with
the function call (if the function is still blocked, the yield
function will be invoked again). The yield function may return 1
to tell MathLink to abort the blocked function call. The programmer
should be aware that aborting the function call might cause the
link to die.
Non-ASCII String Manipulation
Mathematica strings and symbols may contain characters outside of
the ASCII standard character set, and strings containing such
characters can be received and sent via MathLink.
Mathematica uses its own encoding to represent these characters as
a sequence of bytes. Therefore, if your program is going to handle
Mathematica strings that may include non-ASCII characters, you may
need to use special string functions defined in mathlink.h and the
MathLink library. An important virtue of these functions is that
they recognize characters that are encoded in multiple bytes and
treat them as single characters for character-by-character operations.
To iterate over the characters in a Mathematica string, use the
macro MLforString, in a construction like the following.
- --------------------------------------------------------------------------------
| |
MLStringPosition pos;
char *s;
MLforString(s, pos){
/* Do something with string s and character position pos. */
}
| |
- --------------------------------------------------------------------------------
Iterating over the characters in a Mathematica string.
In this loop construct, s is a Mathematica string and pos is a data
structure that will be used as the loop index, representing a
certain character position within the string.
The functions for manipulating the string position and the character
at a given position are MLStringChar(MLStringPosition pos) and
MLPutCharToString(int, char **).
MLStringChar should be used within an MLForString construct to
access the characters in a string. Given an MLStringPosition
argument representing a certain position within a string, MLStringChar
returns an integer character code for the character at that position.
MLPutCharToString takes an integer character code and a pointer to
a pointer to char as arguments; it writes the character's Mathematica
encoding to the given location, increments the pointer to point to
the next character location, and returns an integer indicating how
many bytes were needed for that character. If MLPutCharToString
is called with NULL as the second argument, it returns the number
of bytes needed for that character, but does not write the character
anywhere.
For examples of how these functions are used, refer to the reverse.tm
program, which is among the MathLink examples included in your
Mathematica distribution, or see the comments under ``MathLink
non-ASCII string interface'' in mathlink.h.
- -----------------------------------------
Copyright (c) 1993 Wolfram Research, Inc.
Mathematica and MathLink are registered trademarks, and
MathSource and Mathbook are trademarks of Wolfram Research, Inc. All other
product names mentioned are trademarks of their producers.