approximate pseudo inverse solver (see: http://en.wikipedia.org/wiki/Moore�Penrose_pseudoinverse ) solves ( t(a) a + epsilon I ) x = t(a) y (not if a x = y, then x nearly solves the above ) note: this does square the matrix condition number (bad) @author johnmount
| 15 | * |
| 16 | */ |
| 17 | public class APISolver implements LinearSolver { |
| 18 | private final Algebra algebra = Algebra.ZERO; |
| 19 | private final double epsilon = 1.0e-5; |
| 20 | |
| 21 | @Override |
| 22 | public double[] solve(final double[][] a, final double[] b) { |
| 23 | final int dim = b.length; |
| 24 | final DoubleMatrix2D mb = new DenseDoubleMatrix2D(dim,1); |
| 25 | for(int i=0;i<dim;++i) { |
| 26 | final double bi = b[i]; |
| 27 | mb.set(i,0,bi); |
| 28 | } |
| 29 | final DoubleMatrix2D ab = new DenseDoubleMatrix2D(a); |
| 30 | final DoubleMatrix2D ta = algebra.transpose(ab); |
| 31 | final DoubleMatrix2D taa = algebra.mult(ta,ab); |
| 32 | double sumAbs = 0.0; |
| 33 | for(int i=0;i<dim;++i) { |
| 34 | for(int j=0;j<dim;++j) { |
| 35 | sumAbs += Math.abs(taa.get(i,j)); |
| 36 | } |
| 37 | } |
| 38 | final double escale = epsilon*sumAbs/(1.0+((double)dim)*((double)dim)); |
| 39 | for(int i=0;i<dim;++i) { |
| 40 | taa.set(i, i, taa.get(i,i) + escale); |
| 41 | } |
| 42 | final DoubleMatrix2D mx = algebra.solve(taa,algebra.mult(ta,mb)); |
| 43 | final double[] x = new double[dim]; |
| 44 | for(int i=0;i<dim;++i) { |
| 45 | x[i] = mx.get(i,0); |
| 46 | } |
| 47 | return x; |
| 48 | } |
| 49 | |
| 50 | } |
nothing calls this directly
no outgoing calls
no test coverage detected