/** Build an instance with all values and derivatives set to 0. * @param compiler compiler to use for computation */ private DerivativeStructure(final DSCompiler compiler) { this.compiler = compiler; this.data = new double[compiler.getSize()]; }
/** Perform subtraction of two derivative structures. * @param lhs array holding left hand side of subtraction * @param lhsOffset offset of the left hand side in its array * @param rhs array right hand side of subtraction * @param rhsOffset offset of the right hand side in its array * @param result array where result must be stored (it may be * one of the input arrays) * @param resultOffset offset of the result in its array */ public void subtract(final double[] lhs, final int lhsOffset, final double[] rhs, final int rhsOffset, final double[] result, final int resultOffset) { for (int i = 0; i < getSize(); ++i) { result[resultOffset + i] = lhs[lhsOffset + i] - rhs[rhsOffset + i]; } }
/** Perform addition of two derivative structures. * @param lhs array holding left hand side of addition * @param lhsOffset offset of the left hand side in its array * @param rhs array right hand side of addition * @param rhsOffset offset of the right hand side in its array * @param result array where result must be stored (it may be * one of the input arrays) * @param resultOffset offset of the result in its array */ public void add(final double[] lhs, final int lhsOffset, final double[] rhs, final int rhsOffset, final double[] result, final int resultOffset) { for (int i = 0; i < getSize(); ++i) { result[resultOffset + i] = lhs[lhsOffset + i] + rhs[rhsOffset + i]; } } /** Perform subtraction of two derivative structures.
/** Compile the lower derivatives indirection array. * <p> * This indirection array contains the indices of all elements * except derivatives for last derivation order. * </p> * @param parameters number of free parameters * @param order derivation order * @param valueCompiler compiler for the value part * @param derivativeCompiler compiler for the derivative part * @return lower derivatives indirection array */ private static int[] compileLowerIndirection(final int parameters, final int order, final DSCompiler valueCompiler, final DSCompiler derivativeCompiler) { if (parameters == 0 || order <= 1) { return new int[] { 0 }; } // this is an implementation of definition 6 in Dan Kalman's paper. final int vSize = valueCompiler.lowerIndirection.length; final int dSize = derivativeCompiler.lowerIndirection.length; final int[] lowerIndirection = new int[vSize + dSize]; System.arraycopy(valueCompiler.lowerIndirection, 0, lowerIndirection, 0, vSize); for (int i = 0; i < dSize; ++i) { lowerIndirection[vSize + i] = valueCompiler.getSize() + derivativeCompiler.lowerIndirection[i]; } return lowerIndirection; }
/** Compute linear combination. * The derivative structure built will be a1 * ds1 + a2 * ds2 * @param a1 first scale factor * @param c1 first base (unscaled) component * @param offset1 offset of first operand in its array * @param a2 second scale factor * @param c2 second base (unscaled) component * @param offset2 offset of second operand in its array * @param result array where result must be stored (it may be * one of the input arrays) * @param resultOffset offset of the result in its array */ public void linearCombination(final double a1, final double[] c1, final int offset1, final double a2, final double[] c2, final int offset2, final double[] result, final int resultOffset) { for (int i = 0; i < getSize(); ++i) { result[resultOffset + i] = MathArrays.linearCombination(a1, c1[offset1 + i], a2, c2[offset2 + i]); } }
/** Compute linear combination. * The derivative structure built will be a1 * ds1 + a2 * ds2 + a3 * ds3 + a4 * ds4 * @param a1 first scale factor * @param c1 first base (unscaled) component * @param offset1 offset of first operand in its array * @param a2 second scale factor * @param c2 second base (unscaled) component * @param offset2 offset of second operand in its array * @param a3 third scale factor * @param c3 third base (unscaled) component * @param offset3 offset of third operand in its array * @param result array where result must be stored (it may be * one of the input arrays) * @param resultOffset offset of the result in its array */ public void linearCombination(final double a1, final double[] c1, final int offset1, final double a2, final double[] c2, final int offset2, final double a3, final double[] c3, final int offset3, final double[] result, final int resultOffset) { for (int i = 0; i < getSize(); ++i) { result[resultOffset + i] = MathArrays.linearCombination(a1, c1[offset1 + i], a2, c2[offset2 + i], a3, c3[offset3 + i]); } }
final double a4, final double[] c4, final int offset4, final double[] result, final int resultOffset) { for (int i = 0; i < getSize(); ++i) { result[resultOffset + i] = MathArrays.linearCombination(a1, c1[offset1 + i],
/** Compute power of a derivative structure. * @param x array holding the base * @param xOffset offset of the base in its array * @param y array holding the exponent * @param yOffset offset of the exponent in its array * @param result array where result must be stored (for * power the result array <em>cannot</em> be the input * array) * @param resultOffset offset of the result in its array */ public void pow(final double[] x, final int xOffset, final double[] y, final int yOffset, final double[] result, final int resultOffset) { final double[] logX = new double[getSize()]; log(x, xOffset, logX, 0); final double[] yLogX = new double[getSize()]; multiply(logX, 0, y, yOffset, yLogX, 0); exp(yLogX, 0, result, resultOffset); }
/** Perform division of two derivative structures. * @param lhs array holding left hand side of division * @param lhsOffset offset of the left hand side in its array * @param rhs array right hand side of division * @param rhsOffset offset of the right hand side in its array * @param result array where result must be stored (for * division the result array <em>cannot</em> be one of * the input arrays) * @param resultOffset offset of the result in its array */ public void divide(final double[] lhs, final int lhsOffset, final double[] rhs, final int rhsOffset, final double[] result, final int resultOffset) { final double[] reciprocal = new double[getSize()]; pow(rhs, lhsOffset, -1, reciprocal, 0); multiply(lhs, lhsOffset, reciprocal, 0, result, resultOffset); }
/** Perform remainder of two derivative structures. * @param lhs array holding left hand side of remainder * @param lhsOffset offset of the left hand side in its array * @param rhs array right hand side of remainder * @param rhsOffset offset of the right hand side in its array * @param result array where result must be stored (it may be * one of the input arrays) * @param resultOffset offset of the result in its array */ public void remainder(final double[] lhs, final int lhsOffset, final double[] rhs, final int rhsOffset, final double[] result, final int resultOffset) { // compute k such that lhs % rhs = lhs - k rhs final double rem = FastMath.IEEEremainder(lhs[lhsOffset], rhs[rhsOffset]); final double k = FastMath.rint((lhs[lhsOffset] - rem) / rhs[rhsOffset]); // set up value result[resultOffset] = rem; // set up partial derivatives for (int i = 1; i < getSize(); ++i) { result[resultOffset + i] = lhs[lhsOffset + i] - k * rhs[rhsOffset + i]; } }
/** Build an instance representing a variable. * <p>Instances built using this constructor are considered * to be the free variables with respect to which differentials * are computed. As such, their differential with respect to * themselves is +1.</p> * @param parameters number of free parameters * @param order derivation order * @param index index of the variable (from 0 to {@code parameters - 1}) * @param value value of the variable * @exception NumberIsTooLargeException if {@code index >= parameters}. * @see #DerivativeStructure(int, int, double) */ public DerivativeStructure(final int parameters, final int order, final int index, final double value) throws NumberIsTooLargeException { this(parameters, order, value); if (index >= parameters) { throw new NumberIsTooLargeException(index, parameters, false); } if (order > 0) { // the derivative of the variable with respect to itself is 1. data[DSCompiler.getCompiler(index, order).getSize()] = 1.0; } }
Arrays.fill(result, resultOffset + 1, resultOffset + getSize(), 0); return;
/** Evaluate Taylor expansion of a derivative structure. * @param ds array holding the derivative structure * @param dsOffset offset of the derivative structure in its array * @param delta parameters offsets (Δx, Δy, ...) * @return value of the Taylor expansion at x + Δx, y + Δy, ... * @throws MathArithmeticException if factorials becomes too large */ public double taylor(final double[] ds, final int dsOffset, final double ... delta) throws MathArithmeticException { double value = 0; for (int i = getSize() - 1; i >= 0; --i) { final int[] orders = getPartialDerivativeOrders(i); double term = ds[dsOffset + i]; for (int k = 0; k < orders.length; ++k) { if (orders[k] > 0) { try { term *= FastMath.pow(delta[k], orders[k]) / CombinatoricsUtils.factorial(orders[k]); } catch (NotPositiveException e) { // this cannot happen throw new MathInternalError(e); } } } value += term; } return value; }
/** Build an instance with all values and derivatives set to 0. * @param compiler compiler to use for computation */ private DerivativeStructure(final DSCompiler compiler) { this.compiler = compiler; this.data = new double[compiler.getSize()]; }
/** Build an instance with all values and derivatives set to 0. * @param compiler compiler to use for computation */ private DerivativeStructure(final DSCompiler compiler) { this.compiler = compiler; this.data = new double[compiler.getSize()]; }
/** Perform subtraction of two derivative structures. * @param lhs array holding left hand side of subtraction * @param lhsOffset offset of the left hand side in its array * @param rhs array right hand side of subtraction * @param rhsOffset offset of the right hand side in its array * @param result array where result must be stored (it may be * one of the input arrays) * @param resultOffset offset of the result in its array */ public void subtract(final double[] lhs, final int lhsOffset, final double[] rhs, final int rhsOffset, final double[] result, final int resultOffset) { for (int i = 0; i < getSize(); ++i) { result[resultOffset + i] = lhs[lhsOffset + i] - rhs[rhsOffset + i]; } }
/** Perform subtraction of two derivative structures. * @param lhs array holding left hand side of subtraction * @param lhsOffset offset of the left hand side in its array * @param rhs array right hand side of subtraction * @param rhsOffset offset of the right hand side in its array * @param result array where result must be stored (it may be * one of the input arrays) * @param resultOffset offset of the result in its array */ public void subtract(final double[] lhs, final int lhsOffset, final double[] rhs, final int rhsOffset, final double[] result, final int resultOffset) { for (int i = 0; i < getSize(); ++i) { result[resultOffset + i] = lhs[lhsOffset + i] - rhs[rhsOffset + i]; } }
/** Perform addition of two derivative structures. * @param lhs array holding left hand side of addition * @param lhsOffset offset of the left hand side in its array * @param rhs array right hand side of addition * @param rhsOffset offset of the right hand side in its array * @param result array where result must be stored (it may be * one of the input arrays) * @param resultOffset offset of the result in its array */ public void add(final double[] lhs, final int lhsOffset, final double[] rhs, final int rhsOffset, final double[] result, final int resultOffset) { for (int i = 0; i < getSize(); ++i) { result[resultOffset + i] = lhs[lhsOffset + i] + rhs[rhsOffset + i]; } } /** Perform subtraction of two derivative structures.
/** Perform division of two derivative structures. * @param lhs array holding left hand side of division * @param lhsOffset offset of the left hand side in its array * @param rhs array right hand side of division * @param rhsOffset offset of the right hand side in its array * @param result array where result must be stored (for * division the result array <em>cannot</em> be one of * the input arrays) * @param resultOffset offset of the result in its array */ public void divide(final double[] lhs, final int lhsOffset, final double[] rhs, final int rhsOffset, final double[] result, final int resultOffset) { final double[] reciprocal = new double[getSize()]; pow(rhs, lhsOffset, -1, reciprocal, 0); multiply(lhs, lhsOffset, reciprocal, 0, result, resultOffset); }