## `linsolve` -- solve a system of linear equations

#### Introduction

`linsolve``(eqs, vars)` solves a system of linear equations with respect to the unknowns `vars`.

#### Call(s)

`linsolve(eqs)`
`linsolve(eqs, vars)`
`linsolve(eqs, vars, ShowAssumptions)`
`linsolve(eqs, vars, Domain = R)`

#### Parameters

`eqs` | - | a list or a set of linear equations or arithmetical expressions
`vars` | - | a list or a set of unknowns to solve for: typically identifiers or indexed identifiers

#### Options

`ShowAssumptions` | - | additionally return information about internal assumptions that `linsolve` has made on symbolic parameters in `eqs`
`Domain= R` | - | solve the system over the field `R`, which must be a domain of category `Cat::Field`.

#### Returns

Without the option ShowAssumptions, a list of simplified equations is returned. It represents the general solution of the system `eqs`. `FAIL` is returned if the system is not solvable.

With ShowAssumptions, a list `[Solution, Constraints, Pivots]` is returned. `Solution` is a list of simplified equations representing the general solution of `eqs`. The lists `Constraints` and `Pivots` contain equations and inequalities involving symbolic parameters in `eqs`. Internally, these were assumed to hold true when solving the system.

#### Related Functions

`linalg::matlinsolve`, `numeric::linsolve`, `solve`

#### Details

- `linsolve(`eqs, <, vars <, ShowAssumptions>>`)` solves the linear system `eqs` with respect to the unknowns `vars`. If no unknowns are specified, then `linsolve` solves for all indeterminates in `eqs`; the unknowns are determined internally by `indets(eqs,PolyExpr)`.
- `linsolve(`eqs, vars, Domain = R`)` solves the system over the domain `R`, which must be a field, i.e., a domain of category `Cat::Field`.
- Each element of `eqs` must be either an equation or an arithmetical expression `f`, which is considered to be equivalent to the equation `f = 0`.
- The unknowns in `vars` need not be identifiers or indexed identifiers; expressions such as `sin(x)`, `f(x)`, or `y^(1/3)` are allowed as well. More generally, any expression accepted as indeterminate by `poly` is a valid unknown.
- If the option ShowAssumptions is not given and the system is solvable, then the return value is a list of equations of the form `var=value`, where `var` is one of the unknowns in `vars` and `value` is an arithmetical expression that does not involve any of the unknowns on the left hand side of a returned equation. Note that if the solution manifold has dimension greater than zero, then some of the unknowns in `vars` will occur on the right hand side of some returned equations, representing the degrees of freedom. See example 3.
- If `vars` is a list, then the solved equations are returned in the the same order as the unknowns in `vars`.
- The function `linsolve` can only solve systems of linear equations. Use `solve` for non-linear equations and systems of equations.
- `linsolve` is an interface function to the procedures `numeric::linsolve` and `linalg::matlinsolve`. For more details see the help pages `numeric::linsolve`, `linalg::matlinsolve` and the background section of this help page.
- The system `eqs` is checked for linearity. Since such a test may be expensive, it is recommended to use `numeric::linsolve` or `linalg::matlinsolve` directly in cases you be sure that the system is linear.

- `linsolve` does not react to properties of identifiers set by `assume`.

#### Option: ShowAssumptions

- With this option, a list `[Solution, Constraints, Pivots]` is returned. `Solution` is a list of solved equations representing the complete solution manifold of `eqs`, as described above. The lists `Constraints` and `Pivots` contain equations and inequalities involving symbolic parameters in `eqs`. Internally, these were assumed to hold true when solving the system. `[FAIL,[],[]]` is returned, if the system is not solvable. See `numeric::linsolve` for more details.

#### Example 1

Equations and variables may be entered as sets or lists:

    >> linsolve({x + y = 1, 2*x + y = 3}, {x, y}),
       linsolve({x + y = 1, 2*x + y = 3}, [x, y]),
       linsolve([x + y = 1, 2*x + y = 3], {x, y}),
       linsolve([x + y = 1, 2*x + y = 3], [x, y])

          [y = -1, x = 2], [x = 2, y = -1], [y = -1, x = 2],

             [x = 2, y = -1]

Also expressions may be used as variables:

    >> linsolve({cos(x) + sin(x) = 1, cos(x) - sin(x) = 0},
                {cos(x), sin(x)})

                           [cos(x) = 1/2, sin(x) = 1/2]

Furthermore, indexed identifiers are valid, too:

    >> linsolve({2*a[1] + 3*a[2] = 5, 7*a[2] + 11*a[3] = 13,
                 17*a[3] + 19*a[1] = 23}, {a[1], a[2], a[3]})

                 [a[1] = 691/865, a[2] = 981/865, a[3] = 398/865]

Next, we demonstrate the use of option Domain and solve a system over the field Z23 with it:

    >> linsolve([2*x + y = 1, -x - y = 0],
                Domain=Dom::IntegerMod(23))

                           [y = 22 mod 23, x = 1 mod 23]

The following system does not have a solution:

    >> linsolve({x+y=1, 2*x+2*y=3}, {x,y})

                                       FAIL

#### Example 2

We demonstrate the dependence of the solution of a systems from involved parameters:

    >> eqs := [x + a*y = b, x + A*y = b]:

    >> linsolve(eqs, [x, y])

                                  [x = b, y = 0]

Note that for a=A this is not the general solution. Using the option ShowAssumptions it turns out, that the above result is the general solution subject to the assumption a<>A:

    >> linsolve(eqs, [x, y], ShowAssumptions)

                        [[x = b, y = 0], [], [A - a <> 0]]

    >> delete eqs:

#### Example 3

If the solution of the linear system is not unique, then some of the unknowns are used as ``free parameters'' spanning the solution space. In the following example the unknown `z` is such a parameter. It does not turn up on the left hand side of the solved equations:

    >> eqs := [x + y = z, x + 2*y = 0, 2*x - z = -3*y, y + z = 0]:

    >> vars := [w, x, y, z]:

    >> linsolve(eqs, vars)

                                 [x = 2 z, y = -z]

#### Background

- If the option Domain is not present, the system is solved by calling `numeric::linsolve` with the option Symbolic.
- If the option `Domain = R` is given and `R` is one of the two domains `Dom::ExpressionField()` or `Dom::Float`, then `numeric::linsolve` is used to compute the solution of the system. This function uses a sparse representation of the equations.

  Otherwise, `eqs` is first converted into a matrix and then solved by `linalg::matlinsolve`. A possibly sparse structure of the input system is not taken into account.

#### Changes

- The system `eqs` is tested on linearity w.r.t. `vars`.
- New option ShowAssumptions.
- New syntax: `Domain = R`.

Do you have questions or comments?
Copyright © SciFace Software GmbH & Co. KG 2000