Provides support for generic matrix calculations, numbers (real, complex, large integer) and functions.
With this package you will be able to resolve linear system of equations
involving any kind of elements (e.g. LargeInteger, Complex, Quantity,
Function, etc.). The only requirement being that your elements must
implement the interface {@link com.dautelle.math.Operable} (basically any
class which defines the additive and multiplicative operations as well as
their respective inverses).
The classes {@link com.dautelle.math.Real}, {@link com.dautelle.math.Complex} but also {@link com.dautelle.math.Matrix} implement the {@link com.dautelle.math.Operable} interface. Therefore nothing prevents you from performing operations on matrices of matrices!
More seriously, the combination of physical quantities and matrix operations is a very power tool. Don't forget all physical quantities embed automatic error calculation. Therefore, when you try to resolve a system of equation involving real world quantities, the error on the solution obtained will tell you if can trust that solution or not (i.e. system close to singularity).
Let's say you have a simple electric circuit composed of 2 resistors in series with a battery. You want to know the voltage (U1, U2) at the nodes of the resistors and the current (I) traversing the circuit.
ElectricResistance R1 = (ElectricResistance) Quantity.valueOf(100, 0.1, SI.OHM); // 0.1% error.
ElectricResistance R2 = (ElectricResistance) Quantity.valueOf(300, 0.3, SI.OHM); // 0.1% error
ElectricPotential U0 = (ElectricPotential) Quantity.valueOf(28, 0.1, SI.VOLT);
// Equations: U0 = U1 + U2 |1 1 0 | |U1| |U0|
// U1 = R1 * I => |-1 0 R1| * |U2| = |0 |
// U2 = R2 * I |0 -1 R2| |I | |0 |
//
// A * X = B
//
Quantity[][] Aq = {
{Scalar.ONE, Scalar.ONE, ElectricResistance.ZERO },
{Scalar.ONE.negate(), Scalar.ZERO, R1 },
{Scalar.ZERO, Scalar.ONE.negate(), R2 }};
Matrix A = Matrix.valueOf(Aq);
Quantity[][] Bq = { {U0},
{ElectricPotential.ZERO},
{ElectricPotential.ZERO} };
Matrix B = Matrix.valueOf(Bq);
Matrix X = A.lu().solve(B);
ElectricCurrent.showAs(SI.MILLI(SI.AMPERE));
System.out.println(X);
System.out.println("Estimated current = " + ((Quantity) X.get(2, 0)).doubleValue());
System.out.println("Absolute error = " + ((Quantity) X.get(2, 0)).getAbsoluteError());
> {{7 V},
> {21 V},
> {70 mA}}
> Estimated current = 0.07000032000032
> Absolute error = 3.200003200004922E-4
As you can see the estimated current (70.00032 mA) is slightly higher than the current
you would get using real numbers (28.0 / 400.0 = 70mA). This is due to the errors
on the input values (R1, R2, U0) and the fact that the relationship between the
resistors and the current is not linear (I = U/R).
The estimated value is the median value of the quantity interval. In this particular
case, the current is guaranteed to be: 70.00032 �0.32 mA.
If the inputs have no error specified, the error on the result corresponds to
calculations numeric errors only.