package mikera.vectorz;
import mikera.arrayz.INDArray;
import mikera.matrixx.AMatrix;
import mikera.transformz.ATransform;
import mikera.transformz.impl.AOpTransform;
import mikera.vectorz.impl.ADenseArrayVector;
import mikera.vectorz.ops.Composed;
import mikera.vectorz.ops.Derivative;
import mikera.vectorz.ops.Division;
import mikera.vectorz.ops.Inverse;
import mikera.vectorz.ops.Product;
import mikera.vectorz.ops.Sum;
/**
* Abstract class for representing a unary operation
*
* @author Mike
*/
public abstract class Op implements IOperator {
@Override
public abstract double apply(double x);
/**
* Applies the inverse of this Op. Throws an error if the inverse function does not exist.
* Returns Double.NaN if no inverse exists for the specific value of y.
*
* @param y
* @return
*/
public double applyInverse(double y) {
throw new UnsupportedOperationException("Inverse not defined for operator: "+this.toString());
}
@Override
public void applyTo(AVector v) {
if (v instanceof ADenseArrayVector) {
applyTo((ADenseArrayVector)v);
} else {
v.applyOp(this);
}
}
/**
* Applies this operator to every element of a target matrix, mutating the matrix
*/
public void applyTo(AMatrix m) {
m.applyOp(this);
}
@Override
public void applyTo(AVector v, int offset, int length) {
if (offset<0) throw new IllegalArgumentException("Negative start position: "+offset);
if ((offset==0)&&(length==v.length())) {
v.applyOp(this);
} else {
v.subVector(offset, length).applyOp(this);
}
}
/**
* Applies this operator to a scalar, mutating the scalar
* @param s
*/
public void applyTo(AScalar s) {
s.set(apply(s.get()));
}
/**
* Applies this operator to a dense array vector, mutating the vector
* @param s
*/
public void applyTo(ADenseArrayVector v) {
applyTo(v.getArray(), v.getArrayOffset(),v.length());
}
/**
* Applies this operator to every element of a target array. Mutates the array in place.
* @param a
*/
public void applyTo(INDArray a) {
if (a instanceof AVector) {
applyTo((AVector)a);
} else if (a instanceof AMatrix) {
applyTo((AMatrix)a);
} else if (a instanceof AScalar) {
applyTo((AScalar)a);
} else {
a.applyOp(this);
}
}
@Override
public void applyTo(double[] data, int offset, int length) {
for (int i=0; i=-Double.MAX_VALUE)||(maxDomain()<=Double.MAX_VALUE);
}
/**
* Validates whether all values in a double[] are within the possible output range for this Op
* @param output
* @return
*/
public boolean validateOutput(double[] output) {
double min=minValue();
double max=maxValue();
for (double d: output) {
if ((dmax)) return false;
}
return true;
}
/**
* Creates a copy of the values of src in dest, constraining them to be within the valid
* range of output values from this Op
* @param src
* @param dest
* @param offset
* @param length
*/
public void constrainValues(double[] src, double[] dest, int offset, int length) {
if (!isBounded()) {
System.arraycopy(src, 0, dest, offset, length);
}
double min=minValue();
double max=maxValue();
for (int i=offset; i<(offset+length); i++) {
double v=src[i];
if (v>max) {
dest[i]=max;
} else if (v=-Double.MAX_VALUE)||(maxValue()<=Double.MAX_VALUE);
}
/**
* Gets an operator which represents the derivative of this operator.
*
* Returns nil if this cannot be computed or does not exist.
* @return
*/
public Op getDerivativeOp() {
if (!hasDerivative()) {
return null;
}
return new Derivative(this);
}
public static Op compose(Op op1, Op op2) {
return Ops.compose(op1,op2);
}
public Op compose(Op op) {
return Composed.create(this, op);
}
public Op product(Op op) {
return Product.create(this, op);
}
public Op divide(Op op) {
return Division.create(this, op);
}
public Op sum(Op op) {
return Sum.create(this, op);
}
@Override public String toString() {
return getClass().toString();
}
}
Ads help maintain this website.