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.