pub struct Matrix { /* private fields */ }Expand description
A dense matrix of symbolic expressions.
Elements are stored in row-major order as Vec<Vec<Ex>>.
Equality (==) is structural: two matrices are equal when they have
the same shape and every pair of entries is the same canonical
expression in the same Context. Use
equals for a mathematical (simplifying) comparison.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let a = matrix![ctx, [1, 2], [3, 4]];
let b = matrix![ctx, [0, 1], [1, 0]];
let c = &a * &b; // matrix product
assert_eq!(c, matrix![ctx, [2, 1], [4, 3]]);
assert_eq!(format!("{}", a.det().unwrap()), "-2");
assert_eq!(a[(1, 0)], ctx.int(3));Implementations§
Source§impl Matrix
impl Matrix
Sourcepub fn new(rows: Vec<Vec<Ex>>) -> Result<Self, SymplexError>
pub fn new(rows: Vec<Vec<Ex>>) -> Result<Self, SymplexError>
Create a matrix from nested Vecs (row-major).
§Errors
Returns SymplexError::InvalidArgument if rows is empty,
any row is empty, or rows have inconsistent lengths.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let m = Matrix::new(vec![vec![ctx.int(1), ctx.int(2)], vec![ctx.int(3), ctx.int(4)]]).unwrap();
assert_eq!(m.shape(), (2, 2));
assert!(Matrix::new(vec![vec![ctx.int(1)], vec![]]).is_err());Sourcepub fn row_vector(elems: Vec<Ex>) -> Self
pub fn row_vector(elems: Vec<Ex>) -> Self
Sourcepub fn col_vector(elems: Vec<Ex>) -> Self
pub fn col_vector(elems: Vec<Ex>) -> Self
Sourcepub fn from_i64(ctx: &Context, rows: &[&[i64]]) -> Result<Matrix, SymplexError>
pub fn from_i64(ctx: &Context, rows: &[&[i64]]) -> Result<Matrix, SymplexError>
Create a matrix of integer literals in the given context.
§Errors
Returns SymplexError::InvalidArgument for empty or jagged input.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let m = Matrix::from_i64(&ctx, &[&[1, 2], &[3, 4]]).unwrap();
assert_eq!(m, matrix![ctx, [1, 2], [3, 4]]);Sourcepub fn block_diag(blocks: &[&Matrix]) -> Result<Matrix, SymplexError>
pub fn block_diag(blocks: &[&Matrix]) -> Result<Matrix, SymplexError>
Block-diagonal matrix built from the given blocks.
Blocks need not be square; the result is
(Σ rows) × (Σ cols) with zeros off the block diagonal.
§Errors
Returns SymplexError::InvalidArgument if blocks is empty.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let a = matrix![ctx, [1]];
let b = matrix![ctx, [2, 3], [4, 5]];
let bd = Matrix::block_diag(&[&a, &b]).unwrap();
assert_eq!(bd, matrix![ctx, [1, 0, 0], [0, 2, 3], [0, 4, 5]]);Source§impl Matrix
impl Matrix
Sourcepub fn try_get(&self, i: usize, j: usize) -> Option<&Ex>
pub fn try_get(&self, i: usize, j: usize) -> Option<&Ex>
Checked immutable reference to element (i, j).
Returns None if i >= nrows or j >= ncols.
Sourcepub fn diagonal(&self) -> Vec<Ex> ⓘ
pub fn diagonal(&self) -> Vec<Ex> ⓘ
The main diagonal [a₀₀, a₁₁, …] (length min(nrows, ncols)).
The constructor building a diagonal matrix is diag.
Sourcepub fn submatrix(&self, rows: Range<usize>, cols: Range<usize>) -> Matrix
pub fn submatrix(&self, rows: Range<usize>, cols: Range<usize>) -> Matrix
The sub-block with the given row and column ranges.
§Panics
Panics if either range is empty or extends past the matrix bounds, mirroring slice indexing.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let m = matrix![ctx, [1, 2, 3], [4, 5, 6], [7, 8, 9]];
assert_eq!(m.submatrix(1..3, 0..2), matrix![ctx, [4, 5], [7, 8]]);Sourcepub fn iter(&self) -> impl Iterator<Item = &Ex> + '_
pub fn iter(&self) -> impl Iterator<Item = &Ex> + '_
Iterate over all entries in row-major order.
Sourcepub fn eval_f64(&self) -> Result<Vec<Vec<f64>>, SymplexError>
pub fn eval_f64(&self) -> Result<Vec<Vec<f64>>, SymplexError>
Evaluate every entry to f64.
§Errors
Propagates the first entry that cannot be evaluated (free symbols, non-real values, …).
Source§impl Matrix
impl Matrix
Sourcepub fn adjoint(&self) -> Matrix
pub fn adjoint(&self) -> Matrix
Conjugate transpose Aᴴ = conj(A)ᵀ.
Uses Ex::conjugate on every entry; for real-valued entries this
coincides with transpose.
Sourcepub fn add(&self, other: &Matrix) -> Result<Matrix, SymplexError>
pub fn add(&self, other: &Matrix) -> Result<Matrix, SymplexError>
Element-wise addition (method form of operator +).
§Errors
Returns SymplexError::InvalidArgument if shapes differ.
Sourcepub fn sub(&self, other: &Matrix) -> Result<Matrix, SymplexError>
pub fn sub(&self, other: &Matrix) -> Result<Matrix, SymplexError>
Element-wise subtraction (method form of operator -).
§Errors
Returns SymplexError::InvalidArgument if shapes differ.
Sourcepub fn scale(&self, scalar: &Ex) -> Matrix
pub fn scale(&self, scalar: &Ex) -> Matrix
Scalar multiplication: multiply every element by scalar.
Sourcepub fn matmul(&self, other: &Matrix) -> Result<Matrix, SymplexError>
pub fn matmul(&self, other: &Matrix) -> Result<Matrix, SymplexError>
Matrix multiplication (self * other).
self is n × p and other is p × m; the result is n × m.
Each element is computed symbolically:
result[i][j] = Σ_k self[i][k] * other[k][j].
§Errors
Returns SymplexError::InvalidArgument if self.ncols != other.nrows.
Sourcepub fn trace(&self) -> Result<Ex, SymplexError>
pub fn trace(&self) -> Result<Ex, SymplexError>
Trace: sum of the diagonal elements.
§Errors
Returns SymplexError::InvalidArgument if the matrix is not square.
Sourcepub fn det(&self) -> Result<Ex, SymplexError>
pub fn det(&self) -> Result<Ex, SymplexError>
Determinant of a square matrix.
Dispatch strategy:
- 1×1 → element
- 2×2 →
ad − bc - 3×3 → cofactor expansion (hard-coded, fast)
- n ≥ 4, all entries rational numbers → Bareiss fraction-free elimination (O(n³), exact)
- n ≥ 4, symbolic entries → Berkowitz’s division-free algorithm (O(n⁴)), which yields a fully expanded polynomial in the entries instead of an unsimplified rational function.
§Errors
SymplexError::InvalidArgumentif the matrix is not square.SymplexError::ComputationFailedif the entries or an intermediate result exceedEXPRESSION_BUDGET.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let (a, b, c, d) = (ctx.symbol("a"), ctx.symbol("b"), ctx.symbol("c"), ctx.symbol("d"));
let m = Matrix::new(vec![vec![a.clone(), b.clone()], vec![c.clone(), d.clone()]]).unwrap();
assert_eq!(m.det().unwrap(), &a * &d - &b * &c);Sourcepub fn map(&self, f: impl FnMut(&Ex) -> Ex) -> Matrix
pub fn map(&self, f: impl FnMut(&Ex) -> Ex) -> Matrix
Apply a function to every element, producing a new matrix.
Sourcepub fn map_indexed(&self, f: impl FnMut(usize, usize, &Ex) -> Ex) -> Matrix
pub fn map_indexed(&self, f: impl FnMut(usize, usize, &Ex) -> Ex) -> Matrix
Apply f(i, j, &a_ij) to every element, producing a new matrix.
Sourcepub fn minor_matrix(
&self,
row: usize,
col: usize,
) -> Result<Matrix, SymplexError>
pub fn minor_matrix( &self, row: usize, col: usize, ) -> Result<Matrix, SymplexError>
The (n−1) × (n−1) matrix obtained by deleting row row and
column col.
§Errors
Returns SymplexError::InvalidArgument if the matrix is not
square, has dimension ≤ 1, or the indices are out of range.
Sourcepub fn adjugate(&self) -> Result<Matrix, SymplexError>
pub fn adjugate(&self) -> Result<Matrix, SymplexError>
Adjugate matrix (transpose of the cofactor matrix):
adj(A)[i][j] = cofactor(A, j, i).
§Errors
Returns SymplexError::InvalidArgument if the matrix is not square.
Sourcepub fn inv(&self) -> Result<Matrix, SymplexError>
pub fn inv(&self) -> Result<Matrix, SymplexError>
Matrix inverse.
Uses Gauss–Jordan elimination on [A | I] for matrices whose
entries are all rational numbers (exact, O(n³)) and the adjugate
formula A⁻¹ = adj(A) / det(A) for symbolic matrices (keeps
entries as polynomial / det).
§Errors
SymplexError::InvalidArgumentif the matrix is not square.SymplexError::ComputationFailedif the determinant is zero or the entries / intermediate results exceedEXPRESSION_BUDGET(“expression swell”).
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let a = matrix![ctx, [2, 1], [1, 1]];
let inv = a.inv().unwrap();
assert_eq!(&a * &inv, Matrix::identity(&ctx, 2));
assert!(matrix![ctx, [1, 2], [2, 4]].inv().is_err());Sourcepub fn solve(&self, b: &Matrix) -> Result<Matrix, SymplexError>
pub fn solve(&self, b: &Matrix) -> Result<Matrix, SymplexError>
Solve the linear system Ax = b where self is A.
Uses Gauss–Jordan elimination on the augmented matrix [A | b].
Returns the solution as a Matrix (column vector or multi-column
for multiple right-hand sides). Each entry is passed through
eval() to fold constants.
§Errors
SymplexError::InvalidArgumentifAis not square orAandbhave different row counts.SymplexError::ComputationFailedif the system is singular (no unique solution) or the entries / solution exceedEXPRESSION_BUDGET.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let a = matrix![ctx, [2, 1], [1, 3]];
let b = matrix![ctx, [5], [10]];
let x = a.solve(&b).unwrap();
assert_eq!(x, matrix![ctx, [1], [3]]);Sourcepub fn solve_least_squares(&self, b: &Matrix) -> Result<Matrix, SymplexError>
pub fn solve_least_squares(&self, b: &Matrix) -> Result<Matrix, SymplexError>
Least-squares solution of Ax ≈ b via the normal equations
AᵀA x = Aᵀb.
Requires A to have full column rank (so that AᵀA is invertible).
§Errors
SymplexError::InvalidArgumentifbhas a different number of rows thanA.SymplexError::ComputationFailedifAᵀAis singular.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
// Fit y = c0 + c1·x through (0,1), (1,2), (2,4): least squares gives c1 = 3/2, c0 = 5/6
let a = matrix![ctx, [1, 0], [1, 1], [1, 2]];
let b = matrix![ctx, [1], [2], [4]];
let x = a.solve_least_squares(&b).unwrap();
assert_eq!(x[(0, 0)], ctx.rational(5, 6));
assert_eq!(x[(1, 0)], ctx.rational(3, 2));Sourcepub fn char_poly_coeffs(&self) -> Result<Vec<Ex>, SymplexError>
pub fn char_poly_coeffs(&self) -> Result<Vec<Ex>, SymplexError>
Coefficients of the characteristic polynomial det(A − λI) in
ascending degree order: [c_0, c_1, …, c_n] with c_0 = det(A)
and c_n = (−1)ⁿ.
Computed with Berkowitz’s division-free algorithm, so the coefficients are expanded polynomials in the entries even for fully symbolic matrices.
§Errors
Returns SymplexError::InvalidArgument if the matrix is not square.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let a = matrix![ctx, [1, 2], [3, 4]];
// det(A − λI) = λ² − 5λ − 2
let c = a.char_poly_coeffs().unwrap();
assert_eq!(c, vec![ctx.int(-2), ctx.int(-5), ctx.int(1)]);Sourcepub fn char_poly(&self, var: &Ex) -> Result<Ex, SymplexError>
pub fn char_poly(&self, var: &Ex) -> Result<Ex, SymplexError>
Characteristic polynomial det(A − λI) as a polynomial in var.
This is the one eigen-related method that takes a caller-supplied
variable, because the result is a polynomial in that variable.
char_poly(λ) evaluated at λ = 0 is det(A).
§Errors
Returns SymplexError::InvalidArgument if the matrix is not square.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let lam = ctx.symbol("lambda");
let a = matrix![ctx, [2, 1], [1, 2]];
let p = a.char_poly(&lam).unwrap();
assert_eq!(p, &lam.powi(2) - &lam * 4 + 3);Sourcepub fn eigenvals_with_multiplicity(
&self,
) -> Result<Vec<(Ex, usize)>, SymplexError>
pub fn eigenvals_with_multiplicity( &self, ) -> Result<Vec<(Ex, usize)>, SymplexError>
Eigenvalues with algebraic multiplicities: [(λ, multiplicity), …].
The characteristic polynomial is factored over ℤ (exact
multiplicities); each irreducible factor is then solved. Rational
and quadratic roots are returned in closed form. Irreducible
cubic/quartic factors are solved in radicals only when the result is
compact (binomial-like after depressing, e.g. λ³ − 2 or
λ⁴ − 10λ² + 1); otherwise — and always for degree ≥ 5 — the roots
are exact RootOf expressions whose bound variable displays as λ
and which evaluate numerically via eval_f64/eval_complex64.
(The general Cardano/Ferrari formulas produce nested complex cube
roots that make eigenvectors and P⁻¹ swell exponentially.) For
1×1 and 2×2 matrices with symbolic entries the closed-form
(quadratic) formula is used.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
// Symmetric with an irreducible cubic characteristic polynomial.
let m = matrix![ctx, [4, 1, 2], [1, 3, 1], [2, 1, 5]];
let ev = m.eigenvals_with_multiplicity().unwrap();
assert_eq!(ev.len(), 3);
assert!(ev.iter().all(|(v, m)| *m == 1 && v.to_string().starts_with("RootOf")));
let sum: f64 = ev.iter().map(|(v, _)| v.eval_f64().unwrap()).sum();
assert!((sum - 12.0).abs() < 1e-9); // Σλ = tr(A)If the solver cannot find every root, the multiplicities sum to less
than n and a warning is logged.
§Errors
SymplexError::InvalidArgumentif the matrix is not square.SymplexError::ComputationFailedif no eigenvalue could be found.
Sourcepub fn eigenvals(&self) -> Result<Vec<Ex>, SymplexError>
pub fn eigenvals(&self) -> Result<Vec<Ex>, SymplexError>
Eigenvalues, repeated according to algebraic multiplicity.
For an n × n matrix whose characteristic polynomial the solver
can fully handle this list has exactly n entries. See
eigenvals_with_multiplicity
for the grouped form and for the handling of unsolvable factors.
§Errors
SymplexError::InvalidArgumentif the matrix is not square.SymplexError::ComputationFailedif no eigenvalue could be found.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let a = matrix![ctx, [2, 1], [1, 2]];
let mut ev: Vec<String> = a.eigenvals().unwrap().iter().map(|e| e.to_string()).collect();
ev.sort();
assert_eq!(ev, ["1", "3"]);
// Symbolic 2×2: closed form via the quadratic formula
let (a, b) = (ctx.symbol("a"), ctx.symbol("b"));
let m = Matrix::new(vec![vec![a.clone(), b.clone()], vec![b.clone(), a.clone()]]).unwrap();
let ev = m.eigenvals().unwrap();
assert_eq!(ev.len(), 2);Sourcepub fn eigenvects(&self) -> Result<Vec<(Ex, usize, Vec<Matrix>)>, SymplexError>
pub fn eigenvects(&self) -> Result<Vec<(Ex, usize, Vec<Matrix>)>, SymplexError>
Eigenvectors: for each eigenvalue, a basis for its eigenspace.
Returns a list of (eigenvalue, algebraic_multiplicity, eigenvectors)
tuples. Each eigenvector is a column-vector Matrix; the number
of vectors is the geometric multiplicity.
§Errors
SymplexError::InvalidArgumentif the matrix is not square.SymplexError::ComputationFailedif no eigenvalue could be found.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let m = matrix![ctx, [2, 1], [0, 3]];
for (val, mult, vecs) in m.eigenvects().unwrap() {
assert_eq!(mult, 1);
assert_eq!(vecs.len(), 1);
// A·v = λ·v
assert_eq!((&m * &vecs[0]).simplify(), vecs[0].scale(&val).simplify());
}Sourcepub fn is_diagonalizable(&self) -> Option<bool>
pub fn is_diagonalizable(&self) -> Option<bool>
Is the matrix diagonalizable (three-valued)?
Some(true)— every eigenvalue’s geometric multiplicity equals its algebraic multiplicity.Some(false)— non-square, or some eigenvalue is defective (decided only for matrices without free symbols).None— the eigenvalue solver could not find all eigenvalues, or the entries are symbolic and an eigenspace dimension could not be established.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
assert_eq!(matrix![ctx, [1, 0], [0, 2]].is_diagonalizable(), Some(true));
assert_eq!(matrix![ctx, [1, 1], [0, 1]].is_diagonalizable(), Some(false));Sourcepub fn diagonalize(&self) -> Result<(Matrix, Matrix), SymplexError>
pub fn diagonalize(&self) -> Result<(Matrix, Matrix), SymplexError>
Diagonalize: find invertible P and diagonal D with A = P D P⁻¹.
P has the eigenvectors as columns; D carries the eigenvalues in
the same order.
§Errors
SymplexError::InvalidArgumentif the matrix is not square.SymplexError::ComputationFailedif the matrix is not diagonalizable, the eigenvalue solver could not find all eigenvalues, or the eigenvectors exceedEXPRESSION_BUDGET.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let m = matrix![ctx, [2, 1], [0, 3]];
let (p, d) = m.diagonalize().unwrap();
let back = (&(&p * &d) * &p.inv().unwrap()).simplify();
assert_eq!(back, m);Sourcepub fn jordan_form(&self) -> Result<(Matrix, Matrix), SymplexError>
pub fn jordan_form(&self) -> Result<(Matrix, Matrix), SymplexError>
Jordan normal form: P and block-diagonal J such that A = P J P⁻¹.
J consists of Jordan blocks J_k(λ) (eigenvalue on the diagonal,
ones on the superdiagonal); P holds the (generalized)
eigenvectors. For diagonalizable matrices this equals
diagonalize.
§Errors
SymplexError::InvalidArgumentif the matrix is not square.SymplexError::ComputationFailedif the eigenvalue solver cannot find all eigenvalues or an intermediate result exceedsEXPRESSION_BUDGET.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
// Defective: eigenvalue 2 with algebraic mult 2, geometric mult 1
let m = matrix![ctx, [2, 1, 0, 0], [0, 2, 0, 0], [0, 0, 3, 0], [0, 0, 0, 4]];
let (p, j) = m.jordan_form().unwrap();
assert_eq!((&(&p * &j) * &p.inv().unwrap()).simplify(), m);Sourcepub fn powi(&self, n: u32) -> Result<Matrix, SymplexError>
pub fn powi(&self, n: u32) -> Result<Matrix, SymplexError>
Integer power of a square matrix via repeated squaring.
powi(0) is the identity. Negative powers are not supported —
use inv()?.powi(k).
§Errors
Returns SymplexError::InvalidArgument if the matrix is not square.
Sourcepub fn kronecker(&self, other: &Matrix) -> Matrix
pub fn kronecker(&self, other: &Matrix) -> Matrix
Kronecker (tensor) product A ⊗ B.
For A (m×n) and B (p×q), produces an (mp×nq) matrix.
Sourcepub fn exp_series(&self, order: usize) -> Result<Matrix, SymplexError>
pub fn exp_series(&self, order: usize) -> Result<Matrix, SymplexError>
Matrix exponential via truncated Taylor series eᴬ ≈ Σₖ₌₀ⁿ Aᵏ/k!.
This is an approximation. For exact results use
matrix_exp.
§Errors
Returns SymplexError::InvalidArgument if the matrix is not square.
Sourcepub fn matrix_exp(&self) -> Result<Matrix, SymplexError>
pub fn matrix_exp(&self) -> Result<Matrix, SymplexError>
Exact matrix exponential eᴬ via the Jordan decomposition
eᴬ = P · e^J · P⁻¹.
For each Jordan block J_k(λ):
e^{J_k(λ)} = e^λ · [ 1, 1, 1/2!, …, 1/(k−1)! ]
[ 0, 1, 1, …, 1/(k−2)! ]
[ … ]Unlike a numerical library this never falls back to a series
approximation; use exp_series explicitly if
an approximation is acceptable.
§Errors
SymplexError::InvalidArgumentif the matrix is not square.SymplexError::ComputationFailedif the Jordan form cannot be computed (eigenvalues not found in closed form) or the result exceedsEXPRESSION_BUDGET.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let m = matrix![ctx, [0, 1], [-1, 0]];
let e = m.matrix_exp().unwrap();
// e^A = [[cos 1, sin 1], [−sin 1, cos 1]]: complex-conjugate eigenvalue
// pairs are rewritten with Euler's formula, so the entries are real trig.
assert_eq!(e[(0, 0)], ctx.one().cos());
assert_eq!(e[(0, 1)], ctx.one().sin());Sourcepub fn matrix_exp_t(&self, t: &Ex) -> Result<Matrix, SymplexError>
pub fn matrix_exp_t(&self, t: &Ex) -> Result<Matrix, SymplexError>
Exact matrix exponential e^{At} for a scalar t.
Equivalent to self.scale(t).matrix_exp() but keeps t out of the
eigenvalue computation, so it works for any t (including symbols)
whenever matrix_exp works for A. For each
Jordan block the entries are e^{λt} · t^{j−i} / (j−i)!.
§Errors
Same conditions as matrix_exp.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let t = ctx.symbol("t");
let a = matrix![ctx, [0, 1], [0, 0]];
let e = a.matrix_exp_t(&t).unwrap();
assert_eq!(e, Matrix::new(vec![vec![ctx.int(1), t.clone()], vec![ctx.int(0), ctx.int(1)]]).unwrap());Sourcepub fn pinv(&self) -> Result<Matrix, SymplexError>
pub fn pinv(&self) -> Result<Matrix, SymplexError>
Moore–Penrose pseudo-inverse via A⁺ = (AᵀA)⁻¹Aᵀ.
Valid for full-column-rank matrices.
§Errors
Returns SymplexError::ComputationFailed if AᵀA is singular
(the matrix does not have full column rank).
Source§impl Matrix
impl Matrix
Source§impl Matrix
impl Matrix
Sourcepub fn to_rust_fn(
&self,
name: &str,
params: &[&str],
) -> Result<String, SymplexError>
pub fn to_rust_fn( &self, name: &str, params: &[&str], ) -> Result<String, SymplexError>
Generate a Rust function that computes this matrix and returns a flat array.
Uses cross-entry common subexpression elimination for optimal performance.
§Examples
use symplex::prelude::*;
use symplex::matrix::Matrix;
let ctx = Context::new();
let x = ctx.symbol("x");
let m = Matrix::new(vec![
vec![x.sin(), x.cos()],
vec![-x.cos(), x.sin()],
]).unwrap();
let code = m.to_rust_fn("rotation", &["x"]).unwrap();
assert!(code.contains("pub fn rotation"));
assert!(code.contains("[f64; 4]"));Sourcepub fn to_rust_fn_with_options(
&self,
name: &str,
params: &[&str],
options: &CodegenOptions,
) -> Result<String, SymplexError>
pub fn to_rust_fn_with_options( &self, name: &str, params: &[&str], options: &CodegenOptions, ) -> Result<String, SymplexError>
Generate a Rust function with custom code generation options.
See CodegenOptions for available settings (precision, math backend,
annotations, CSE toggle).
Source§impl Matrix
impl Matrix
Sourcepub fn lu(&self) -> Result<(Matrix, Matrix, Vec<usize>), SymplexError>
pub fn lu(&self) -> Result<(Matrix, Matrix, Vec<usize>), SymplexError>
LU decomposition with partial pivoting: P·A = L·U.
Returns (L, U, perm) where L is unit lower triangular, U is
upper triangular and perm is the row permutation (perm[i] is
the original index of row i of P·A). Pivots are chosen as the
first structurally non-zero entry, so symbolic entries are treated
as non-zero.
§Errors
SymplexError::InvalidArgumentif the matrix is not square.SymplexError::ComputationFailedif the matrix is singular.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let a = matrix![ctx, [4, 3], [6, 3]];
let (l, u, perm) = a.lu().unwrap();
// Rebuild P·A from perm and compare with L·U
let pa = Matrix::new(perm.iter().map(|&i| a.row(i).to_vec()).collect()).unwrap();
assert_eq!((&l * &u).eval(), pa);
assert!(matrix![ctx, [1, 2], [2, 4]].lu().is_err());Sourcepub fn rref(&self) -> (Matrix, Vec<usize>)
pub fn rref(&self) -> (Matrix, Vec<usize>)
Row-reduced echelon form via Gauss–Jordan elimination.
Returns (rref_matrix, pivot_columns). Uses exact arithmetic;
pivots are the first structurally non-zero entries, so symbolic
entries are always treated as non-zero. (The eigen-family uses a
simplifying zero test internally so that irrational eigenvalues
still yield eigenvectors.)
Sourcepub fn nullspace(&self) -> Vec<Matrix>
pub fn nullspace(&self) -> Vec<Matrix>
Null space (kernel): basis vectors for Ax = 0, as column vectors.
Empty for a full-column-rank matrix. Uses structural pivoting like
rref.
Sourcepub fn columnspace(&self) -> Vec<Matrix>
pub fn columnspace(&self) -> Vec<Matrix>
Column space basis: the pivot columns of the original matrix.
Sourcepub fn rowspace(&self) -> Vec<Matrix>
pub fn rowspace(&self) -> Vec<Matrix>
Row space basis: the non-zero rows of the RREF, as row vectors.
Sourcepub fn left_nullspace(&self) -> Vec<Matrix>
pub fn left_nullspace(&self) -> Vec<Matrix>
Left null space: basis of { y : yᵀA = 0 } = nullspace(Aᵀ).
Source§impl Matrix
impl Matrix
Sourcepub fn norm_frobenius(&self) -> Ex
pub fn norm_frobenius(&self) -> Ex
Frobenius norm ‖A‖_F = √(Σ |a_ij|²).
Entries are treated as real (squared, not |·|²); for complex
entries apply adjoint manually.
Sourcepub fn norm(&self) -> Ex
pub fn norm(&self) -> Ex
Default norm — the Frobenius norm (norm_frobenius).
Sourcepub fn hstack(matrices: &[&Matrix]) -> Result<Matrix, SymplexError>
pub fn hstack(matrices: &[&Matrix]) -> Result<Matrix, SymplexError>
Stack matrices horizontally (side by side).
§Errors
Returns SymplexError::InvalidArgument if matrices is empty
or row counts differ.
Sourcepub fn vstack(matrices: &[&Matrix]) -> Result<Matrix, SymplexError>
pub fn vstack(matrices: &[&Matrix]) -> Result<Matrix, SymplexError>
Stack matrices vertically (on top of each other).
§Errors
Returns SymplexError::InvalidArgument if matrices is empty
or column counts differ.
Source§impl Matrix
impl Matrix
Sourcepub fn extract(
&self,
rows: &[usize],
cols: &[usize],
) -> Result<Matrix, SymplexError>
pub fn extract( &self, rows: &[usize], cols: &[usize], ) -> Result<Matrix, SymplexError>
The sub-matrix formed by the given rows and columns, in the order listed. Indices may be repeated or reordered.
§Errors
SymplexError::InvalidArgument if either list is empty or contains
an out-of-range index.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let m = matrix![ctx, [1, 2, 3], [4, 5, 6], [7, 8, 9]];
assert_eq!(m.extract(&[2, 0], &[0, 2, 2]).unwrap(), matrix![ctx, [7, 9, 9], [1, 3, 3]]);
assert!(m.extract(&[3], &[0]).is_err());
assert!(m.extract(&[], &[0]).is_err());Sourcepub fn select_rows(&self, rows: &[usize]) -> Result<Matrix, SymplexError>
pub fn select_rows(&self, rows: &[usize]) -> Result<Matrix, SymplexError>
The rows with the given indices (all columns), in the order listed.
§Errors
SymplexError::InvalidArgument if rows is empty or contains an
out-of-range index.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let m = matrix![ctx, [1, 2], [3, 4], [5, 6]];
assert_eq!(m.select_rows(&[2, 0]).unwrap(), matrix![ctx, [5, 6], [1, 2]]);Sourcepub fn select_cols(&self, cols: &[usize]) -> Result<Matrix, SymplexError>
pub fn select_cols(&self, cols: &[usize]) -> Result<Matrix, SymplexError>
The columns with the given indices (all rows), in the order listed.
§Errors
SymplexError::InvalidArgument if cols is empty or contains an
out-of-range index.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let m = matrix![ctx, [1, 2, 3], [4, 5, 6]];
assert_eq!(m.select_cols(&[2, 2]).unwrap(), matrix![ctx, [3, 3], [6, 6]]);Sourcepub fn delete_row(&self, i: usize) -> Result<Matrix, SymplexError>
pub fn delete_row(&self, i: usize) -> Result<Matrix, SymplexError>
The matrix with row i removed.
§Errors
SymplexError::InvalidArgument if i is out of range or the
matrix has a single row (the result would be empty).
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let m = matrix![ctx, [1, 2], [3, 4], [5, 6]];
assert_eq!(m.delete_row(1).unwrap(), matrix![ctx, [1, 2], [5, 6]]);
assert!(matrix![ctx, [1, 2]].delete_row(0).is_err());Sourcepub fn delete_col(&self, j: usize) -> Result<Matrix, SymplexError>
pub fn delete_col(&self, j: usize) -> Result<Matrix, SymplexError>
The matrix with column j removed.
§Errors
SymplexError::InvalidArgument if j is out of range or the
matrix has a single column (the result would be empty).
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let m = matrix![ctx, [1, 2, 3], [4, 5, 6]];
assert_eq!(m.delete_col(0).unwrap(), matrix![ctx, [2, 3], [5, 6]]);
assert!(matrix![ctx, [1], [2]].delete_col(0).is_err());Sourcepub fn is_integer_matrix(&self) -> Option<bool>
pub fn is_integer_matrix(&self) -> Option<bool>
Is every entry an integer literal? Three-valued: Some(true) when
every entry is an integer literal, Some(false) when some entry is a
non-integer numeric literal (1/2), None when some entry is
symbolic (a symbol, pi, an unevaluated sum, …).
Entries are inspected as they are — call eval first
to constant-fold 2 + 3 into 5.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
assert_eq!(matrix![ctx, [1, -2], [3, 0]].is_integer_matrix(), Some(true));
let half = Matrix::new(vec![vec![ctx.rational(1, 2)]]).unwrap();
assert_eq!(half.is_integer_matrix(), Some(false));
let sym = Matrix::new(vec![vec![ctx.symbol("x")]]).unwrap();
assert_eq!(sym.is_integer_matrix(), None);Sourcepub fn to_rational_rows(&self) -> Option<Vec<Vec<Ratio<BigInt>>>>
pub fn to_rational_rows(&self) -> Option<Vec<Vec<Ratio<BigInt>>>>
The entries as exact rationals, row-major.
Returns None if any entry is not a numeric literal. Entries are
inspected as they are — call eval first to fold
constant expressions such as 1/2 + 1/3.
§Examples
use symplex::prelude::*;
use num_bigint::BigInt;
use num_rational::Ratio;
let ctx = Context::new();
let m = Matrix::new(vec![vec![ctx.rational(1, 2), ctx.int(3)]]).unwrap();
let rows = m.to_rational_rows().unwrap();
assert_eq!(rows[0][0], Ratio::new(BigInt::from(1), BigInt::from(2)));
assert_eq!(rows[0][1], Ratio::from_integer(BigInt::from(3)));
assert!(Matrix::new(vec![vec![ctx.symbol("x")]]).unwrap().to_rational_rows().is_none());Sourcepub fn to_bigint_rows(&self) -> Option<Vec<Vec<BigInt>>>
pub fn to_bigint_rows(&self) -> Option<Vec<Vec<BigInt>>>
The entries as big integers, row-major.
Returns None if any entry is not an integer literal (a fraction,
a symbol, an unevaluated expression, …).
§Examples
use symplex::prelude::*;
use num_bigint::BigInt;
let ctx = Context::new();
let rows = matrix![ctx, [1, -2], [3, 4]].to_bigint_rows().unwrap();
assert_eq!(rows[0][1], BigInt::from(-2));
let half = Matrix::new(vec![vec![ctx.rational(1, 2)]]).unwrap();
assert!(half.to_bigint_rows().is_none());Sourcepub fn from_ratio(
ctx: &Context,
rows: &[Vec<Ratio<BigInt>>],
) -> Result<Matrix, SymplexError>
pub fn from_ratio( ctx: &Context, rows: &[Vec<Ratio<BigInt>>], ) -> Result<Matrix, SymplexError>
Create a matrix of exact rational literals.
§Errors
SymplexError::InvalidArgument for empty or jagged input.
§Examples
use symplex::prelude::*;
use num_bigint::BigInt;
use num_rational::Ratio;
let ctx = Context::new();
let q = |n: i64, d: i64| Ratio::new(BigInt::from(n), BigInt::from(d));
let m = Matrix::from_ratio(&ctx, &[vec![q(1, 2), q(3, 1)]]).unwrap();
assert_eq!(m.get(0, 0), &ctx.rational(1, 2));
assert_eq!(m.to_rational_rows().unwrap(), vec![vec![q(1, 2), q(3, 1)]]);Sourcepub fn from_bigint(
ctx: &Context,
rows: &[Vec<BigInt>],
) -> Result<Matrix, SymplexError>
pub fn from_bigint( ctx: &Context, rows: &[Vec<BigInt>], ) -> Result<Matrix, SymplexError>
Create a matrix of integer literals from big integers.
§Errors
SymplexError::InvalidArgument for empty or jagged input.
§Examples
use symplex::prelude::*;
use num_bigint::BigInt;
let ctx = Context::new();
let rows = vec![vec![BigInt::from(1), BigInt::from(2)], vec![BigInt::from(3), BigInt::from(4)]];
let m = Matrix::from_bigint(&ctx, &rows).unwrap();
assert_eq!(m, matrix![ctx, [1, 2], [3, 4]]);Sourcepub fn from_f64_rows(
ctx: &Context,
rows: &[Vec<f64>],
) -> Result<Matrix, SymplexError>
pub fn from_f64_rows( ctx: &Context, rows: &[Vec<f64>], ) -> Result<Matrix, SymplexError>
Create a matrix from f64 values, converting each exactly to
the dyadic rational it represents (via Context::from_f64): 0.5
becomes 1/2, but 0.1 becomes 3602879701896397/36028797018963968,
not 1/10. Use Context::from_f64_nice entry-wise if you want
the “human” rational reading of a float.
§Errors
SymplexError::InvalidArgument for empty or jagged input or a
NaN entry.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let m = Matrix::from_f64_rows(&ctx, &[vec![0.5, -3.0], vec![0.25, 2.0]]).unwrap();
assert_eq!(m.get(0, 0), &ctx.rational(1, 2));
assert_eq!(m.get(1, 0), &ctx.rational(1, 4));
assert!(Matrix::from_f64_rows(&ctx, &[vec![f64::NAN]]).is_err());Sourcepub fn subs_map(&self, replacements: &[(&Ex, &Ex)]) -> Matrix
pub fn subs_map(&self, replacements: &[(&Ex, &Ex)]) -> Matrix
Simultaneous substitution of several (old, new) pairs in every
entry (see Ex::subs_map).
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let (x, y) = (ctx.symbol("x"), ctx.symbol("y"));
let m = Matrix::new(vec![vec![x.clone(), y.clone()]]).unwrap();
// Swap x and y in one step — sequential `subs` would collapse both to y.
let swapped = m.subs_map(&[(&x, &y), (&y, &x)]);
assert_eq!(swapped, Matrix::new(vec![vec![y, x]]).unwrap());Sourcepub fn nnz(&self) -> usize
pub fn nnz(&self) -> usize
Number of structurally non-zero entries (entries that are not the
literal 0). Symbolic entries count as non-zero even if they
would simplify to zero.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
assert_eq!(matrix![ctx, [1, 0, 2], [0, 0, 3]].nnz(), 3);
assert_eq!(Matrix::identity(&ctx, 4).nnz(), 4);Source§impl Matrix
impl Matrix
Sourcepub fn hermite_normal_form(&self) -> Result<Matrix, SymplexError>
pub fn hermite_normal_form(&self) -> Result<Matrix, SymplexError>
Row-style Hermite normal form H = U·A of an integer matrix.
See normalforms::hermite_normal_form
for the exact normalisation and
normalforms::hermite_normal_form_with_transform
to obtain U as well.
§Errors
SymplexError::InvalidArgument if any entry is not an integer
literal.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let a = matrix![ctx, [2, 4, 4], [-6, 6, 12], [10, -4, -16]];
let h = a.hermite_normal_form().unwrap();
assert_eq!(h, matrix![ctx, [2, 4, 4], [0, 6, 0], [0, 0, 12]]);Sourcepub fn smith_normal_form(&self) -> Result<Matrix, SymplexError>
pub fn smith_normal_form(&self) -> Result<Matrix, SymplexError>
Smith normal form S = U·A·V of an integer matrix: a diagonal
matrix diag(d₁, …, dᵣ, 0, …) with dᵢ > 0 and dᵢ | dᵢ₊₁.
See normalforms::smith_normal_form
and
normalforms::smith_normal_form_with_transforms.
§Errors
SymplexError::InvalidArgument if any entry is not an integer
literal.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let a = matrix![ctx, [2, 4, 4], [-6, 6, 12], [10, -4, -16]];
assert_eq!(a.smith_normal_form().unwrap(), matrix![ctx, [2, 0, 0], [0, 6, 0], [0, 0, 12]]);Sourcepub fn integer_nullspace(&self) -> Result<Vec<Matrix>, SymplexError>
pub fn integer_nullspace(&self) -> Result<Vec<Matrix>, SymplexError>
A ℤ-basis of the integer kernel {x ∈ ℤⁿ : A·x = 0}, as column
vectors (empty when the kernel is trivial).
See normalforms::integer_nullspace.
§Errors
SymplexError::InvalidArgument if any entry is not an integer
literal.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let a = matrix![ctx, [2, 4, 6]];
let basis = a.integer_nullspace().unwrap();
assert_eq!(basis.len(), 2);
for k in &basis {
assert_eq!((&a * k).eval(), matrix![ctx, [0]]);
}Source§impl Matrix
impl Matrix
Sourcepub fn qr(&self) -> Result<(Matrix, Matrix), SymplexError>
pub fn qr(&self) -> Result<(Matrix, Matrix), SymplexError>
QR decomposition via Gram–Schmidt: A = Q·R with Q (m×n) having
orthonormal columns and R (n×n) upper triangular.
Works exactly with radicals (entries like 1/√2). Requires the
columns of A to be linearly independent (rank == ncols).
§Errors
Returns SymplexError::ComputationFailed if the columns are
linearly dependent or symbolic entries swell beyond
EXPRESSION_BUDGET.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let a = matrix![ctx, [1, 1], [0, 1]];
let (q, r) = a.qr().unwrap();
assert_eq!((&q * &r).simplify(), a);
assert_eq!((&q.transpose() * &q).simplify(), Matrix::identity(&ctx, 2));
assert!(r[(1, 0)].is_zero_structural());Sourcepub fn cholesky(&self) -> Result<Matrix, SymplexError>
pub fn cholesky(&self) -> Result<Matrix, SymplexError>
Cholesky decomposition A = L·Lᵀ for a symmetric positive-definite
matrix (L lower triangular with positive diagonal).
Positive-definiteness is decided pivot by pivot: each diagonal pivot must be provably positive (assumption system, or numeric evaluation for constant entries).
§Errors
SymplexError::InvalidArgumentif the matrix is not square or provably not symmetric.SymplexError::ComputationFailedif a pivot is provably non-positive (not positive definite) or its sign cannot be decided symbolically.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let a = matrix![ctx, [4, 2], [2, 3]];
let l = a.cholesky().unwrap();
assert_eq!((&l * &l.transpose()).simplify(), a);
assert!(matrix![ctx, [1, 2], [2, 1]].cholesky().is_err()); // indefiniteSourcepub fn ldl(&self) -> Result<(Matrix, Matrix), SymplexError>
pub fn ldl(&self) -> Result<(Matrix, Matrix), SymplexError>
LDLᵀ decomposition A = L·D·Lᵀ for a symmetric matrix (L unit
lower triangular, D diagonal).
Unlike cholesky this needs no square roots and
no sign information, so it works for symbolic symmetric matrices
and for indefinite ones.
§Errors
SymplexError::InvalidArgumentif the matrix is not square or provably not symmetric.SymplexError::ComputationFailedif a zero pivot is encountered (no pivoting is performed).
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let a = matrix![ctx, [4, 2], [2, 3]];
let (l, d) = a.ldl().unwrap();
assert_eq!((&(&l * &d) * &l.transpose()).eval(), a);
assert_eq!(d, matrix![ctx, [4, 0], [0, 2]]);Sourcepub fn is_symmetric(&self) -> Option<bool>
pub fn is_symmetric(&self) -> Option<bool>
Is A = Aᵀ? Three-valued; Some(false) for non-square.
Sourcepub fn is_skew_symmetric(&self) -> Option<bool>
pub fn is_skew_symmetric(&self) -> Option<bool>
Is A = −Aᵀ? Three-valued; Some(false) for non-square.
Sourcepub fn is_hermitian(&self) -> Option<bool>
pub fn is_hermitian(&self) -> Option<bool>
Is A = Aᴴ (conjugate transpose)? Three-valued.
Sourcepub fn is_orthogonal(&self) -> Option<bool>
pub fn is_orthogonal(&self) -> Option<bool>
Is AᵀA = I? Three-valued; Some(false) for non-square.
Sourcepub fn is_unitary(&self) -> Option<bool>
pub fn is_unitary(&self) -> Option<bool>
Is AᴴA = I? Three-valued; Some(false) for non-square.
Sourcepub fn is_upper_triangular(&self) -> Option<bool>
pub fn is_upper_triangular(&self) -> Option<bool>
Are all entries below the main diagonal zero? Three-valued.
Sourcepub fn is_lower_triangular(&self) -> Option<bool>
pub fn is_lower_triangular(&self) -> Option<bool>
Are all entries above the main diagonal zero? Three-valued.
Sourcepub fn is_diagonal(&self) -> Option<bool>
pub fn is_diagonal(&self) -> Option<bool>
Are all off-diagonal entries zero? Three-valued (works for rectangular matrices too).
Sourcepub fn is_identity(&self) -> Option<bool>
pub fn is_identity(&self) -> Option<bool>
Is this the identity matrix? Three-valued; Some(false) for
non-square.
Sourcepub fn is_nilpotent(&self) -> Option<bool>
pub fn is_nilpotent(&self) -> Option<bool>
Is Aⁿ = 0 (n = dimension)? Three-valued; Some(false) for
non-square.
A square matrix is nilpotent iff Aⁿ = 0, so exactly one matrix
power is examined.
Sourcepub fn is_positive_definite(&self) -> Option<bool>
pub fn is_positive_definite(&self) -> Option<bool>
Positive-definiteness via Sylvester’s criterion: symmetric and all leading principal minors strictly positive. Three-valued.
Returns Some(false) for non-square or provably non-symmetric
matrices and None when a minor’s sign cannot be decided
(symbolic entries without assumptions).
§Examples
use symplex::prelude::*;
let ctx = Context::new();
assert_eq!(matrix![ctx, [2, -1], [-1, 2]].is_positive_definite(), Some(true));
assert_eq!(matrix![ctx, [1, 2], [2, 1]].is_positive_definite(), Some(false));
let x = ctx.symbol("x");
let m = Matrix::new(vec![vec![x.clone(), ctx.int(0)], vec![ctx.int(0), ctx.int(1)]]).unwrap();
assert_eq!(m.is_positive_definite(), None);Sourcepub fn is_positive_semidefinite(&self) -> Option<bool>
pub fn is_positive_semidefinite(&self) -> Option<bool>
Positive-semidefiniteness: symmetric and all principal minors non-negative (leading minors alone are not sufficient). Three-valued.
Examines 2ⁿ − 1 minors, so this is intended for small matrices.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
assert_eq!(matrix![ctx, [1, 1], [1, 1]].is_positive_semidefinite(), Some(true));
assert_eq!(matrix![ctx, [0, 0], [0, -1]].is_positive_semidefinite(), Some(false));Sourcepub fn norm_1(&self) -> Ex
pub fn norm_1(&self) -> Ex
Induced 1-norm: maximum absolute column sum.
For symbolic entries the result is a max(…) of abs(…) sums;
call .eval() to fold constants.
Sourcepub fn norm_p(&self, p: &Ex) -> Result<Ex, SymplexError>
pub fn norm_p(&self, p: &Ex) -> Result<Ex, SymplexError>
Vector p-norm (Σ |xᵢ|ᵖ)^(1/p) for a row or column vector.
§Errors
Returns SymplexError::InvalidArgument if the matrix is not a
row or column vector.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let v = matrix![ctx, [3], [-4]];
assert_eq!(v.norm_p(&ctx.int(2)).unwrap().eval(), ctx.int(5));
assert_eq!(v.norm_p(&ctx.int(1)).unwrap().eval(), ctx.int(7));Sourcepub fn matrix_pow_symbolic(&self, n: &Ex) -> Result<Matrix, SymplexError>
pub fn matrix_pow_symbolic(&self, n: &Ex) -> Result<Matrix, SymplexError>
Symbolic power Aⁿ for a diagonalizable matrix via P·Dⁿ·P⁻¹.
n may be any expression (a symbol, a rational, …); each diagonal
entry becomes λᵢⁿ. Entries are simplified.
§Errors
Same conditions as diagonalize.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let n = ctx.symbol("n");
let a = matrix![ctx, [2, 0], [0, 3]];
let an = a.matrix_pow_symbolic(&n).unwrap();
assert_eq!(an[(0, 0)], ctx.int(2).pow(&n));
assert_eq!(an[(1, 1)], ctx.int(3).pow(&n));Sourcepub fn matrix_sqrt(&self) -> Result<Matrix, SymplexError>
pub fn matrix_sqrt(&self) -> Result<Matrix, SymplexError>
Principal square root √A of a diagonalizable matrix via
P·√D·P⁻¹ (principal branch on each eigenvalue).
§Errors
Same conditions as diagonalize.
§Examples
use symplex::prelude::*;
let ctx = Context::new();
let a = matrix![ctx, [4, 0], [0, 9]];
let s = a.matrix_sqrt().unwrap();
assert_eq!((&s * &s).simplify(), a);Trait Implementations§
impl Eq for Matrix
impl StructuralPartialEq for Matrix
Source§impl TryFrom<&Matrix> for QMatrix
impl TryFrom<&Matrix> for QMatrix
Source§fn try_from(m: &Matrix) -> Result<Self, SymplexError>
fn try_from(m: &Matrix) -> Result<Self, SymplexError>
Every entry must be a rational literal (after a constant-folding
eval if the raw entries are not).
Source§type Error = SymplexError
type Error = SymplexError
Auto Trait Implementations§
impl !RefUnwindSafe for Matrix
impl !UnwindSafe for Matrix
impl Freeze for Matrix
impl Send for Matrix
impl Sync for Matrix
impl Unpin for Matrix
impl UnsafeUnpin for Matrix
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more