/** * /check individual functions first */ @Test public void functionsTest() { for (int i = 0; i < 3; i++) { DoubleArray y = F[i].apply(X[i]); DoubleMatrix jac = F[i].calculateJacobian(X[i]); AssertMatrix.assertEqualsVectors(Y_EXP[i], y, 1e-15); AssertMatrix.assertEqualsMatrix(JAC_EXP[i], jac, 1e-15); } }
/** * Creates an instance. * <p> * This creates the concatenated function, in the order that the sub functions are given. * * @param functions the sub functions */ public ConcatenatedVectorFunction(VectorFunction[] functions) { ArgChecker.noNulls(functions, "functions"); this.functions = functions; this.nPartitions = functions.length; this.xPartition = new int[nPartitions]; this.yPartition = new int[nPartitions]; int m = 0; int n = 0; for (int i = 0; i < nPartitions; i++) { xPartition[i] = functions[i].getLengthOfDomain(); yPartition[i] = functions[i].getLengthOfRange(); m += xPartition[i]; n += yPartition[i]; } this.sizeDom = m; this.sizeRange = n; }
@Test public void test() { final ParameterizedCurveVectorFunctionProvider pro = new ParameterizedCurveVectorFunctionProvider(s_PCurve); final double[] points = new double[] {-1.0, 0.0, 1.0 }; final VectorFunction f = pro.from(points); assertEquals(2, f.getLengthOfDomain()); assertEquals(3, f.getLengthOfRange()); final DoubleArray x = DoubleArray.of(0.5, 2.0); //the parameters a & b final DoubleArray y = f.apply(x); assertEquals(0.5 * Math.sinh(-2.0), y.get(0), 1e-14); assertEquals(0.0, y.get(1), 1e-14); assertEquals(0.5 * Math.sinh(2.0), y.get(2), 1e-14); final DoubleMatrix jac = f.calculateJacobian(x); final DoubleMatrix fdJac = (new VectorFieldFirstOrderDifferentiator().differentiate(f)).apply(x); AssertMatrix.assertEqualsMatrix(fdJac, jac, 1e-9); } }
@Override public DoubleMatrix calculateJacobian(DoubleArray x) { ArgChecker.notNull(x, "x"); ArgChecker.isTrue( x.size() == getLengthOfDomain(), "Incorrect length of x. Is {} but should be {}", x.size(), getLengthOfDomain()); double[][] jac = new double[getLengthOfRange()][getLengthOfDomain()]; int posInput = 0; int pos1 = 0; int pos2 = 0; for (int i = 0; i < nPartitions; i++) { int nRows = yPartition[i]; int nCols = xPartition[i]; DoubleArray sub = x.subArray(posInput, posInput + nCols); DoubleMatrix subJac = functions[i].calculateJacobian(sub); if (nCols > 0) { for (int r = 0; r < nRows; r++) { System.arraycopy(subJac.toArrayUnsafe()[r], 0, jac[pos1++], pos2, nCols); } pos2 += nCols; } else { pos1 += nRows; } posInput += nCols; } return DoubleMatrix.copyOf(jac); }
@Override public DoubleArray apply(DoubleArray x) { ArgChecker.notNull(x, "x"); ArgChecker.isTrue( x.size() == getLengthOfDomain(), "Incorrect length of x. Is {} but should be {}", x.size(), getLengthOfDomain()); double[] y = new double[getLengthOfRange()]; int posInput = 0; int posOutput = 0; //evaluate each function (with the appropriate sub vector) and concatenate the results for (int i = 0; i < nPartitions; i++) { int length = xPartition[i]; DoubleArray sub = x.subArray(posInput, posInput + length); DoubleArray eval = functions[i].apply(sub); eval.copyInto(y, posOutput); posInput += length; posOutput += eval.size(); } return DoubleArray.copyOf(y); }