| FUNCTION |
The function solves linear equation system A@X = B.
A needs to be square matrix NxN
B has to have N rows and at least one column (vertical vector).
Then calling
X = MxSolve( A, B );
would give vertical vector holding solution of the system of equations A @ X = B
B can also be a matrix,with each of its column representing different vector B. This way single call to MxSolve can solve several systems with same matrix A but different right hand vectors.
If B is a matrix NxM then MxSolve will produce result also having NxM cells with each column representing single solution.
(Highly) Technical note about numerical precision
Despite the fact that both MxSolve and MxInverse use double precision arithmetic solving/inverting matrices is subject to numerical precision of double IEEE and for example zero result may come up as something like 1.4355e-16 (0.0000000000000001) due to the fact that double precision is still limited in accuracy (16 digits).
The result of
X = MxInverse( A ) @ B;
although mathematically the same as solving the system of equations, would yield slightly different result because if you do the inverse the returned matrix is converted back
to single precision and matrix product is performed with single precision. When you use MxSolve you are performing all calcs using 64-bit (double) precision and
only end result is converted back to single precision. So for example polynomial fit code works better with MxSolve than MxInverse. |
| EXAMPLE |
// Example 1:
A = MxFromString("[ 1, 1,
1, 1; 0, 2, 5, -1; 2, 5, -1, 1; 2, 2, 2, 1 ]");
B = MxFromString("[ 7; -5;
28; 13 ]" ); // single vertical vector B
printf( "Solving A * X = B
" );
printf("Matrix A
");
printf( MxToString(
A ) );
printf("
Matrix B
");
printf( MxToString(
B ) );
X = MxSolve( A, B );
printf("
Solution X
");
// Example 2:
A = MxFromString("[ 1, 1,
1, 1; 0, 2, 5, -1; 2, 5, -1, 1; 2, 2, 2, 1 ]");
B = MxFromString("[ 7, 14
; -5, -10; 28, 56; 13, 26 ]" ); // 2 right-hand
side vertical vectors
printf( "Solving A * X = B
" );
printf("Matrix A
");
printf( MxToString(
A ) );
printf("
Matrix B
");
printf( MxToString(
B ) );
X = MxSolve( A, B );
printf("
Solutions X
");
printf( MxToString(
X ) ); // two solutions
////////////////////////////////////////
// Example 3
// N-th order Polynomial Fit example
/////
order = Param( "n-th
Order", 10, 1, 16, 1 );
length = 60;
lvb = BarCount - 1;
fvb = lvb - length;
yy = Matrix( length + 1, 1, 0 );
xx = Matrix( length + 1,
order + 1, 1 );
yy = MxSetBlock( yy, 0,
length, 0, 0, Ref( C,
fvb ) );
x = BarIndex() - length/2;
for( j = 1;
j <= order; j++ )
{
xx = MxSetBlock( xx, 0,
length, j, j, x ^ j );
}
xxt = MxTranspose( xx );
aa = MxSolve( xxt @ xx, xxt ) @ yy;
//aa = MxInverse( xxt @ xx ) @ xxt @ yy; // alternative
way
if( aa ) // check if
matrix is not null (so solution exists)
{
rr = Null; // store the fit in rr
for( i = fvb; i <=
lvb; i++ )
{
rr[i] = aa[0][0];
for( j = 1;
j <= order; j++ )
{
rr[i] += aa[j][0] * x[ i - fvb ] ^ j;
}
}
if( IsNan( rr[
fvb ] ) )
{
// our polynomial yields infinite or not-a-number result
due to overflow/underflow
Title = "Polyfit
failed. The order of polynomial is too High";
}
else
{
SetChartOptions( 0, chartShowDates );
SetBarFillColor( IIf( C > O, ColorRGB( 0, 75, 0 ), IIf( C <= O, ColorRGB( 75, 0, 0 ), colorLightGrey )
) );
Plot( rr, "rr", colorWhite, styleLine | styleThick);
}
}
else
{
Title = "Matrix is singular. The order of polynomial
is too high";
}
Plot( C, "", IIf( C > O, ColorRGB( 0, 255, 0 ), IIf( C <= O, ColorRGB( 255, 0, 0 ), colorLightGrey )
), styleDots | styleNoLine ); |