Math::MatrixLUP - Matrix operations and LUP decomposition.
Version 0.02
use Math::MatrixLUP; use Math::AnyNum qw(:overload); my $A = Math::MatrixLUP->new([ [2, -1, 5, 1], [3, 2, 2, -6], [1, 3, 3, -1], [5, -2, -3, 3], ]); my $det = $A->determinant; my $sol = $A->solve([-3, -32, -47, 49]); my $inv = $A->invert; my $pow = $A**3; my $pwm = $A->powmod(100, 10000019); my $mod = $A % 10007;
Math::MatrixLUP provides generic support for matrix operations and LUP decomposition, allowing any type of numbers inside the matrix, including native Perl numbers and numerical objects provided by other mathematical libraries, such as Math::AnyNum.
The following matrix operations are provided:
matrix-scalar arithmetical operations
matrix multiplication and division
matrix exponentiation
determinant of a square-matrix
inverting a square-matrix
solving a system of linear equations
Math::MatrixLUP objects are immutable.
Create a new Math::MatrixLUP object, given a 2D array-ref:
my $A = Math::MatrixLUP->new([ [rand,rand,rand], [rand,rand,rand], [rand,rand,rand], ]);
Returns a nXn identity matrix, given an integer argument:
my $I = Math::MatrixLUP->I(3); my $I = Math::MatrixLUP->identity(3);
Build a new nXm matrix, given two integers and a subroutine reference as arguments:
my $A = Math::MatrixLUP->build($n, $m, sub ($i, $j) { $i * $j });
If only one integer is given, it creates a square nXn matrix:
my $B = Math::MatrixLUP->build($n, sub ($i, $j) { $i**$j });
The values of i (row number) and j (column number) range from [0, n-1] and [0, m-1].
i
j
[0, n-1]
[0, m-1]
Returns a new nXm matrix with all entries set to 0.
my $A = Math::MatrixLUP->zero(3); # 3x3 zero-matrix my $A = Math::MatrixLUP->zero(3, 4); # 3x4 zero-matrix
Returns a new square matrix with the diagonal set a given value.
my $A = Math::MatrixLUP->scalar(3, 42); # 3x3 scalar with value 42
A construct method that creates a new matrix, given a list of array-ref rows:
my $A = Math::MatrixLUP->from_rows( [1, 2, 3], [4, 5, 6], [7, 8, 9], );
A construct method that creates a new matrix, given a list of array-ref columns:
my $A = Math::MatrixLUP->from_columns( [1, 4, 7], [2, 5, 8], [3, 6, 9], );
Returns a new matrix with the n-th (zero-based) row set to the given array-ref of values:
my $B = $A->set_row(0, [1,2,3,4]); # set first row
Returns a new matrix with the n-th (zero-based) column set to the given array-ref of values:
my $B = $A->set_column(0, [1,2,3,4]); # set first column
A constructor method that creates a row vector, given a single array-ref of numbers.
my $row_vector = Math::MatrixLUP->row([1, 4, 4, 8]);
When called on a matrix object, it returns the n-th row (zero-based) as an array-ref.
my $row = $A->row(0); # first row as an array-ref
Returns the rows of the matrix as an array of array-refs.
my @rows = $A->rows;
A constructor method that creates a column vector, given a single array-ref of numbers.
my $column_vector = Math::MatrixLUP->column([1, 4, 4, 8]);
When called on a matrix object, it returns the n-th column (zero-based) as an array-ref.
my $col = $A->column(0); # first column as an array-ref
Returns the columns of the matrix as an array of array-refs.
my @columns = $A->columns;
A constructor method that creates a diagonal matrix from a single array-ref of numbers.
my $A = Math::MatrixLUP->diagonal([1, 4, 4, 8]);
The matrix is zero filled except for the diagonal, which take the value of the given vector.
When called on a matrix object, it returns the diagonal as an array-ref:
my $diag = $A->diagonal;
A constructor method that creates an anti-diagonal matrix from a single array-ref of numbers.
my $A = Math::MatrixLUP->anti_diagonal([1, 4, 4, 8]);
The matrix is zero filled except for the anti-diagonal, which take the value of the given vector.
When called on a matrix object, it returns the anti-diagonal as an array-ref:
my $diag = $A->anti_diagonal;
Returns a new matrix with all the terms negated.
my $B = -$A; my $B = $A->neg;
Returns a new matrix with the abs() function applied to all terms.
abs()
my $B = abs($A); my $B = $A->abs;
Returns a new matrix with the floor() function applied to all terms.
floor()
my $B = $A->floor;
Returns a new matrix with the ceil() function applied to all terms.
ceil()
my $B = $A->ceil;
Add two matrices of the same dimensions:
my $C = $A + $B; my $C = $A->add($B);
If one of the arguments it not a Math::MatrixLUP object, scalar addition is performed:
my $B = $A + $scalar;
Subtract two matrices of the same dimensions:
my $C = $A - $B; my $C = $A->sub($B);
If one of the arguments it not a Math::MatrixLUP object, scalar subtraction is performed:
my $B = $A - $scalar; my $B = $scalar - $A;
Multiplication of two matrices, where the number of columns in A equals the number of rows in B.
my $C = $A * $B; my $C = $A->mul($B);
If one of the arguments it not a Math::MatrixLUP object, scalar multiplication is performed:
my $B = $A * $scalar;
Division of two matrices.
my $C = $A / $B; my $C = $A->div($B);
Defined as:
A/B = A * B^(-1)
If one of the arguments it not a Math::MatrixLUP object, scalar division is performed:
my $B = $A / $scalar; my $B = $scalar / $A;
Modulo operation.
my $C = $A % $B; my $C = $A->mod($B);
A mod B = A - B*floor(A/B)
If one of the arguments it not a Math::MatrixLUP object, scalar modulo is performed:
my $B = $A % $scalar; my $B = $scalar % $A;
Matrix exponentiation, where the exponent is a native integer:
my $B = $A**$n; my $B = $A->pow($n);
For negative n, this operation is defined only if the matrix can be inverted.
n
Matrix exponentiation modulo m, where the exponent is an arbitrary large positive integer:
m
my $B = $A->powmod($n, $m);
Negative exponents are not supported yet.
This section includes method for scalar and entrywise matrix bitwise operations.
Bitwise scalar operations:
my $B = $A->lsft(2); # left-shift by 2 applied to each value my $B = $A->rsft(2); # right-shift by 2 applied to each value my $B = $A->or(2); # OR 2 applied to each value my $B = $A->xor(2); # XOR 2 applied to each value my $B = $A->and(2); # AND 2 applied to each value
Entrywise bitwise operations:
my $C = $A->lsft($B); # entrywise left-shift my $C = $A->rsft($B); # entrywise right-shift my $C = $A->or($B); # entrywise OR my $C = $A->xor($B); # entrywise XOR my $C = $A->and($B); # entrywise AND
Returns a new matrix with rows and columns flipped.
Returns a new matrix with rows flipped.
Returns a new matrix with columns flipped.
Returns the transposed matrix. This is the matrix where colums and rows of the argument matrix are swaped.
Concatenates two matrices of same row count. The result is a new matrix.
Map each entry of a matrix to a given subroutine callback.
my $B = $A->map(sub { $_**2 }); # new matrix with each entry squared
The subroutine is called with $i and $j as arguments, such that $_ = $A->[$i][$j].
$i
$j
$_ = $A->[$i][$j]
Decide if two matrices are equal or not.
$A == $B # true if equal $A != $B # true if not equal
Compare two matrices, entrywise:
$A < $B # true if A is less than B $A <= $B # true if A is less than or equal to B $A > $B # true if A is greater than B $A >= $B # true if A is greater than or equal to B $A <=> $B # -1 if A < B, 0 if A == B, 1 if A > B
Solve a system of linear equations.
my $A = Math::MatrixLUP->new([ [2, -1, 5, 1], [3, 2, 2, -6], [1, 3, 3, -1], [5, -2, -3, 3], ]); my $solution = $A->solve([-3, -32, -47, 49]); say join(', ', @{$solution}); #=> 2, -12, -4, 1
Invert a square matrix.
my $B = $A->inv;
Compute the determinant of a square matrix.
Returns the reduced row echelon form of the self-matrix.
my $B = $A->rref;
Returns the LUP decomposition of the self matrix.
my ($N, $A, $P) = $matrix->decompose;
There is no need to call this method explicitly. It is called internally automatically and is cached at object-level.
Returns a deep copy of the self-matrix.
Returns the dimensions of the matrix (1-based):
my ($rows, $cols) = $A->size;
Returns the matrix as a 2D array-ref.
Retruns a stringified version of the self-matrix.
The entries of a Math::MatrixLUP object can be accessed as an array-ref:
my $Aij = $A->[$i][$j];
However, modifying the matrix in-place is not recommended, as Math::MatrixLUP uses dynamic caching at object-level in order to avoid recomputing the LUP decomposition multiple times for the same matrix-object.
Related libraries
Math::Matrix - Multiply and invert matrices.
Math::GSL::Matrix - Mathematical functions concerning Matrices using the GNU Scientific Library (GSL).
Math::MatrixDecomposition::LU - LU decomposition with partial pivoting of a real matrix.
Math::AnyNum - Arbitrary size precision for integers, rationals, floating-points and complex numbers.
https://github.com/trizen/Math-MatrixLUP
https://en.wikipedia.org/wiki/LU_decomposition
Daniel Șuteu, <trizen at cpan.org>
<trizen at cpan.org>
Copyright (C) 2019 Daniel Șuteu
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.22.0 or, at your option, any later version of Perl 5 you may have available.
To install Math::MatrixLUP, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Math::MatrixLUP
CPAN shell
perl -MCPAN -e shell install Math::MatrixLUP
For more information on module installation, please visit the detailed CPAN module installation guide.