package mikera.vectorz.ops; import mikera.vectorz.Op; public final class Product extends Op { public final Op a; public final Op b; private Product(Op a, Op b) { this.a=a; this.b=b; } private static Op tryOptimisedCreate(Op a, Op b) { if (a instanceof Constant) { return Linear.create(((Constant) a).value,0.0).compose(b); } if ((a instanceof ALinearOp)&&(b instanceof ALinearOp)) { ALinearOp la=(ALinearOp)a; ALinearOp lb=(ALinearOp)b; double a1=la.getFactor(); double a2=la.getConstant(); double b1=lb.getFactor(); double b2=lb.getConstant(); return Quadratic.create(a1*b1,a1*b2+b1*a2,b2*a2); } return null; } public static Op create(Op a, Op b) { Op t1=tryOptimisedCreate(a,b); if (t1!=null) return t1; Op t2=tryOptimisedCreate(b,a); if (t2!=null) return t2; return new Product(a,b); } @Override public double apply(double x) { return a.apply(x)*b.apply(x); } @Override public double averageValue() { return a.averageValue()*b.averageValue(); } @Override public boolean hasDerivative() { return (a.hasDerivative())&&(b.hasDerivative()); } @Override public boolean hasDerivativeForOutput() { return false; } @Override public double derivative(double x) { double ay=a.apply(x); double by=b.apply(x); return a.derivative(x)*by+b.derivative(x)*ay; } @Override public Op getDerivativeOp() { Op da=a.getDerivativeOp(); Op db=b.getDerivativeOp(); return (da.product(b)).sum(db.product(a)); } @Override public boolean isStochastic() { return a.isStochastic()||b.isStochastic(); } @Override public String toString() { return "Product("+a+","+b+")"; } }