This manual documents lineqpp version 1.1, a program that solves linear equations and then substitutes the solutions into a document at prescribed locations.

Copyright © 2008 John D. Ramsdell

Permission is granted to copy, distribute and/or modify this document under the terms of the MIT Licence. The terms are contained in the fileCOPYINGin the source distribution of the software.

The software described in this manual was written by John D. Ramsdell.

The lineqpp program solves linear equations and then substitutes the solutions into a document at prescribed locations. It provides linear equation solving capability similar to what is provided by MetaPost, as a general purpose preprocessor.

The program was original conceived to ease the task of creating Scalable Vector Graphics (SVG), so the program is introduced by showing how to use it to specify an SVG image. The image is described by John D. Hobby in A User's Manual for MetaPost, documented version 0.99, Page 12, part of the Tex Live distribution of December 2007. The MetaPost description of the image follows.

beginfig(13); z1=-z2=(.2in,0); x3=-x6=.3in; x3+y3=x6+y6=1.1in; z4=1/3[z3,z6]; z5=2/3[z3,z6]; z20=whatever[z1,z3]=whatever[z2,z4]; z30=whatever[z1,z4]=whatever[z2,z5]; z40=whatever[z1,z5]=whatever[z2,z6]; draw z1--z20--z2--z30--z1--z40--z2; pickup pencircle scaled 1pt; draw z1--z2; draw z3--z6; endfig;

The first eight lines of the body of the figure are a set of linear equations, and the remaining four lines contain commands for drawing straight lines. The end points for the lines are determined by solving the linear equations.

The MetaPost specification uses mediation expressions of the form
*t[z1,z2]*, which is equivalent to *z1+t*z2*. The
`whatever`

expression is not a variable, but a macro that
generates an anonymous variable wherever it occurs.

The `lineqpp` syntax for linear equations is similar to what
is used by MetaPost. Preprocessor equation input is identified by a
line of text that begins with `#lineqpp`

. A solution to the
linear equations is retrieved by mentioning a variable. If the
variable `z`

occurs in the equations, the x-part of its solution
is retrieved by mentioning `z#x`

and the y-part with `z#y`

.
The input to the preprocessor follows.

<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <!-- #lineqpp z1=-z2=.2; #lineqpp x3=-x6=.3; #lineqpp x3+y3=x6+y6=1.1; #lineqpp z3=x3+y3*i; z6=x6+y6*i; #lineqpp z4=(1/3)[z3,z6]; #lineqpp z5=(2/3)[z3,z6]; #lineqpp z20=?[z1,z3]=?[z2,z4]; #lineqpp z30=?[z1,z4]=?[z2,z5]; #lineqpp z40=?[z1,z5]=?[z2,z6]; #lineqpp w=z20-z40; --> <svg width="w#xin" height="z20#yin" viewBox="z40#x 0 w#x z20#y" xmlns="http://www.w3.org/2000/svg" version="1.1"> <path d = "M z1#x z1#y L z20#x z20#y z2#x z2#y z30#x z30#y z1#x z1#y z40#x z40#y z2#x z2#y" style = "stroke-width: 0.02; fill: none; stroke: black"/> <path d = "M z1#x z1#y L z2#x z2#y M z3#x z3#y L z6#x z6#y" style = "stroke-width: 0.04; fill: none; stroke: black"/> </svg>

The root element of the image produced by the preprocessor follows.

<svg width="0.8457in" height="2.2857in" viewBox="-0.3600 0 0.8457 2.2857" xmlns="http://www.w3.org/2000/svg" version="1.1"> <path d = "M 0.2000 0.0000 L 0.4857 2.2857 -0.2000 0.0000 -0.0182 2.1818 0.2000 0.0000 -0.3600 2.2400 -0.2000 0.0000" style = "stroke-width: 0.02; fill: none; stroke: black"/> <path d = "M 0.2000 0.0000 L -0.2000 0.0000 M 0.3000 0.8000 L -0.3000 1.4000" style = "stroke-width: 0.04; fill: none; stroke: black"/> </svg>

The output was generated with the following command.

$ lineqpp -o lineqpp.svg lineqpp.lep

The SVG image looks similar to the MetaPost specified image, with one exception. It's upside down! MetaPost, following a long-standing mathematical tradition, uses a right-handed coordinate system. SVG follows the convention common in computer graphics of using a left-handed coordinate system.

The `lineqpp` program accepts the following options:

$ lineqpp -h Usage: lineqpp [options] [input] Options: -o file -- output to file (default is standard output) -d -- print equation debugging information -v -- print version information -h -- print this message Package: lineqpp 1.1

The Linear Equations Preprocessor reads lines of text. Preprocessor
equation input is identified by a line of text that begins with
`#lineqpp`

. All other lines are transform input.

The solution for a variable that occurs in the equation input is found as soon the linear equations determine its value. Once a value for a variable has been found, occurrences of the variable in transform input will be replaced by its value in the output. Each line of equation input is replace by a blank line in the output so that line numbers associated with errors in the output also refer to the same location in the input.

Variables in the equation input are complex. Occurrences of a
variable in transform input refers to its real or imaginary part, not
the whole complex number. The real part is referred to by adding the
suffix `#x`

, and the imaginary part by adding the suffix
`#y`

.

US-ASCII is used for equation input. Syntactically, a variable is a letter followed by letters, digits, and underscore characters, and a number is a sequence of digits that may include one decimal point.

Expressions are formed using the usual arithmetic operators: binary
`+`

(addition), `-`

(subtraction), `*`

(multiplication), `/`

(division), and `^`

(exponentiation);
and unary `-`

(negation).

Syntactically, equations are a sequence of two or more expressions separated by the equal sign, and terminated with a semicolon. Equations and expressions may span multiple lines of equation input, and transform input may intercede.

For each pair of expressions that are equated, the program interprets both expressions as a complex linear polynomial. Internally, it treats each complex polynomial as a pair of real polynomials, and each variable as a pair of real valued variables. As a result, the solution for the real part of a variable may found even when the input does not determine its imaginary part.

Equation solving operates on real linear polynomials. The program distinguishes between independent and dependent variables. A dependent variable is defined by a linear polynomial of independent variables. Each variable is initially independent, and solving one equation causes one independent variable to become dependent. A dependent variable defined by a constant polynomial is a candidate for substitution by the preprocessor in transform input. This program implements the equation solving algorithm described in Chapter 9 of Donald E. Knuth, The METAFONTbook, Addison-Wesley, 1986.

In general, the product of two linear polynomials is not a linear polynomial. An error is raised if the program is asked to multiply two linear polynomials unless at least one of the two is a constant. Division succeeds only when the divisor is a constant.

Following Knuth, the program supports mediation expressions of the
form *t[z1,z2]*, but since every variable is complex, it is
defined to be *z1+s*z2*, where *s* has the same real part as
does *t* and zero for its imaginary part. Each occurrence of
`?`

in equation input generates an anonymous variable, the analog
of Knuth's `whatever`

.

Functions may be applied to expressions that name constants. The
functions that can be applied to complex numbers are: `abs`

,
`exp`

, `log`

, `cos`

, and `sin`

. The functions that
can only be applied to real numbers convert between radians and
degrees and are: `rad`

and `deg`

.

The program begins with definitions for the variables `pi`

and
`i`

.

The command-line option `-d`

causes debugging information to be
written to standard error. In this mode, just before an equation is
solved, it is printed. In addition, output is generated whenever
there is an update to the linear polynomial that defines a dependent
variable. The word *is* identifies an update. A small part of
the debugging information generated by the example in the introduction
follows.

0.3000 + y3#x = -0.3000 + y6#x y6#x is 0.6000 + y3#x 0.3000 + y3#x = 1.1000 y3#x is 0.8000 y6#x is 1.4000

The software described by this manual is covered by the terms of the MIT Licence.

Copyright (C) 2008 John D. Ramsdell

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.