package mikera.vectorz.ops; import mikera.vectorz.Op; /** * A logistic function, with input scaled by a fixed factor * @author Mike * */ public final class ScaledLogistic extends Op { private final double factor; private final double inverseFactor; private static final double DEFAULT_SCALE_FACTOR=8.0; public static final ScaledLogistic INSTANCE=new ScaledLogistic(DEFAULT_SCALE_FACTOR); public ScaledLogistic(double d) { factor=d; inverseFactor=1.0/d; } private double scaledLogisticFunction(double a) { double ea=Math.exp(-factor*a); double df=(1/(1.0f+ea)); if (Double.isNaN(df)) return (a>0)?1:0; return df; } private double inverseLogistic (double a) { if (a>=1) return 800*inverseFactor; if (a<=0) return -800*inverseFactor; double ea=a/(1.0-a); return inverseFactor*Math.log(ea); } @Override public double apply(double x) { return scaledLogisticFunction(x); } @Override public double applyInverse(double y) { return inverseLogistic(y); } @Override public void applyTo(double[] data, int start,int length) { for (int i=0; i<length; i++) { data[i+start]=scaledLogisticFunction(data[i+start]); } } @Override public boolean hasDerivative() { return true; } @Override public double derivativeForOutput(double y) { return factor*y*(1-y); } @Override public double derivative(double x) { double y=scaledLogisticFunction(x); return factor*y*(1-y); } @Override public double minValue() { return 0.0; } @Override public double maxValue() { return 1.0; } @Override public double averageValue() { return 0.5; } }