AbstractIntervalDerivativeNumber.java
/*
* Created on 2004/12/14
* Copyright (C) 2004 Koga Laboratory. All rights reserved.
*
*/
package org.mklab.cga.derivative;
import org.mklab.cga.interval.matrix.IntervalNumericalMatrix;
import org.mklab.cga.interval.scalar.IntervalNumericalScalar;
import org.mklab.nfc.matrix.NumericalMatrix;
import org.mklab.nfc.scalar.AbstractNumericalScalar;
import org.mklab.nfc.scalar.NumericalScalar;
/**
* 微分値を精度保証付きで求めるクラスです。
*
* <p>自動微分法を実装しています。
*
* @author hiroki
* @version $Revision: 1.27 $.2004/12/14
* @param <IDS> 区間微分スカラーの型
* @param <IDM> 区間微分行列の型
* @param <IS> 区間スカラーの型
* @param <IM> 区間行列の型
* @param <S> スカラーの型
* @param <M> の型
*/
public abstract class AbstractIntervalDerivativeNumber<IDS extends IntervalDerivativeNumber<IDS ,IDM,IS,IM,S,M>, IDM extends IntervalDerivativeMatrix<IDS,IDM,IS,IM,S,M>, IS extends IntervalNumericalScalar<IS,IM,S,M>, IM extends IntervalNumericalMatrix<IS,IM,S,M>, S extends NumericalScalar<S,M>, M extends NumericalMatrix<S,M> > extends AbstractNumericalScalar<IDS,IDM> implements IntervalDerivativeNumber<IDS,IDM,IS,IM,S,M> {
/** シリアル番号 */
private static final long serialVersionUID = 5155625854053176474L;
/** 任意の区間 */
private IS x;
/** xの微分値の区間 */
private IS dx;
/**
* コンストラクター 定数の場合。
*
* @param x 値
*/
public AbstractIntervalDerivativeNumber(IS x) {
this.x = x.clone();
this.dx = this.x.createZero();
}
// /**
// * コンストラクタ
// *
// * @param x 値
// */
// public AbstractIntervalDerivative(double x) {
// this.x = (IS)new DoubleIntervalNumber(x);
// this.dx = this.x.createZero();
// }
//
// /**
// * コンストラクタ
// *
// * @param x 値
// */
// public AbstractIntervalDerivative(DoubleComplexNumber x) {
// this.x = (IS)new DoubleComplexIntervalNumber(x);
// this.dx = this.x.createZero();
// }
//
// /**
// * 新しく生成された<code>IntervalDerivative</code>オブジェクトを初期化します。
// *
// * @param x 値
// */
// public AbstractIntervalDerivative(T x) {
// if (x instanceof DoubleNumber) {
// this.x = (IS)new DoubleIntervalNumber(((DoubleNumber)x).doubleValue());
// this.dx = this.x.createZero();
// } else {
// this.x = new AbstractIntervalRealNumericalScalar<>(x);
// this.dx = this.x.createZero();
// }
// }
// /**
// * コンストラクタ
// *
// * @param x 値
// * @param dx 微分値
// */
// public AbstractIntervalDerivative(IS x, IS dx) {
// this.x = x;
// this.dx = dx;
// }
// /**
// * 新しく生成された<code>IntervalDerivative</code>オブジェクトを初期化します。
// *
// * @param x 値
// * @param dx 微分値
// */
// public AbstractIntervalDerivative(T x, T dx) {
// if (x instanceof DoubleNumber) {
// this.x = (IS)new DoubleIntervalNumber(((DoubleNumber)x).doubleValue());
// } else {
// this.x = new AbstractIntervalRealNumericalScalar<>(x);
// }
// if (dx instanceof DoubleNumber) {
// this.dx = (IS)new DoubleIntervalNumber(((DoubleNumber)dx).doubleValue());
// } else {
// this.dx = new AbstractIntervalRealNumericalScalar<>(dx);
// }
// }
//
// /**
// * コンストラクタ
// *
// * @param x 値
// * @param dx 微分値
// */
// public AbstractIntervalDerivative(DoubleComplexNumber x, DoubleComplexNumber dx) {
// this.x = (IS)new DoubleComplexIntervalNumber(x);
// this.dx = (IS)new DoubleComplexIntervalNumber(dx);
// }
/**
* コンストラクタ
*
* @param x 値
* @param dx 微分値
*/
public AbstractIntervalDerivativeNumber(IS x, IS dx) {
this.x = x;
this.dx = dx;
}
// /**
// * @see org.mklab.nfc.scalar.Scalar#create(int)
// */
// public IDS create(final int value) {
// return create(value);
// }
/**
* <code>y</code>との和を返します。
*
* @param y 自動微分型の値
* @return 自身とyの和
*/
public IDS add(final IDS y) {
return create(this.x.add(y.getX()), this.dx.add(y.getDX()));
}
/**
* <code>y</code>との差を返します。
*
* @param y 自動微分型の値
* @return 自身とyの差
*/
public IDS subtract(final IDS y) {
return create(this.x.subtract(y.getX()), this.dx.subtract(y.getDX()));
}
/**
* <code>y</code>との積を返します。
*
* @param y 自動微分型の値
* @return 自身とyの積
*/
public IDS multiply(final IDS y) {
return create(this.x.multiply(y.getX()), this.x.multiply(y.getDX()).add(this.dx.multiply(y.getX())));
}
/**
* <code>y</code>との商を返します。
*
* @param y 自動微分型の値
* @return 自身とyの商
*/
public IDS divide(final IDS y) {
return create(this.x.divide(y.getX()), (this.dx.multiply(y.getX()).subtract(this.x.multiply(y.getDX()))).divide(y.getX().multiply(y.getX())));
}
/**
* @see org.mklab.nfc.scalar.Scalar#unaryMinus()
*/
public IDS unaryMinus() {
return create(this.x.unaryMinus(), this.dx.unaryMinus());
}
/**
* <code>x</code>を取得します。
*
* @return x
*/
public IS getX() {
return this.x;
}
/**
* <code>dx</code>を取得します。
*
* @return dx
*/
public IS getDX() {
return this.dx;
}
/**
* <code>x</code>をセットします。
*
* @param x xの微分値の区間
*/
public void setX(IS x) {
this.x = x.clone();
}
/**
* <code>dx</code>をセットします。
*
* @param dx xの微分値の区間
*/
public void setDX(IS dx) {
this.dx = dx.clone();
}
/**
* Returns <code>true</code> if this <code>IntervalDerivative</code> is the same as the o argument.
*
* @return <code>true</code> if this <code>IntervalDerivative</code> is the same as the o argument.
*/
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null) {
return false;
}
if (o.getClass() != getClass()) {
return false;
}
IDS castedObj = (IDS)o;
return ((this.x == null ? castedObj.getX() == null : this.x.equals(castedObj.getX())) && (this.dx == null ? castedObj.getDX() == null : this.dx.equals(castedObj.getDX())));
}
/**
* Override hashCode.
*
* @return the Objects hashcode.
*/
@Override
public int hashCode() {
int hashCode = 1;
hashCode = 31 * hashCode + (this.x == null ? 0 : this.x.hashCode());
hashCode = 31 * hashCode + (this.dx == null ? 0 : this.dx.hashCode());
return hashCode;
}
// /**
// * @see org.mklab.nfc.scalar.Scalar#add(org.mklab.nfc.scalar.Scalar)
// */
// @Override
// public IDS add(final Scalar<?> value) {
// if (value instanceof AbstractIntervalDerivative) {
// return create(this.x.add(((AbstractIntervalDerivative)value).getX()), this.dx.add(((AbstractIntervalDerivative)value).getDX()));
// } else if (value instanceof IntervalScalar) {
// return create(this.x.add((IntervalScalar)value), this.dx);
// } else if (value instanceof DoubleComplexNumber) {
// return create(this.x.add((DoubleComplexNumber)value), this.dx);
// } else {
// throw new UnsupportedOperationException();
// }
// }
/**
* @see org.mklab.nfc.scalar.Scalar#add(double)
*/
public IDS add(final double value) {
return create(this.x.add(value), this.dx);
}
/**
* @see org.mklab.nfc.scalar.Scalar#add(int)
*/
public IDS add(final int value) {
return create(this.x.add(value), this.dx);
}
// /**
// * 自身に微分値を加えます。
// *
// * @param value 加える微分値
// * @return 自身
// */
// public IntervalDerivative<?> addSelf(final IntervalDerivative<?> value) {
// this.x = (IS)this.x.add(value.x);
// this.dx = (IS)this.dx.add(value.dx);
// return this;
// }
// /**
// * @see org.mklab.nfc.scalar.Scalar#addSelf(org.mklab.nfc.scalar.Scalar)
// */
// public IntervalDerivative<?> addSelf(final Scalar<?> value) {
// return addSelf((IntervalDerivative<?>)value);
// }
/**
* @see org.mklab.nfc.scalar.Scalar#compare(java.lang.String, int)
*/
public boolean compare(String operator, int opponent) {
return false;
}
/**
* @see org.mklab.nfc.scalar.Scalar#compare(java.lang.String, double)
*/
public boolean compare(String operator, double opponent) {
return false;
}
/**
* @see org.mklab.nfc.scalar.Scalar#conjugate()
*/
public IDS conjugate() {
return (IDS)this;
}
// /**
// * @see org.mklab.nfc.scalar.Scalar#createGrid(int, int, org.mklab.nfc.scalar.Scalar[][])
// */
// public IDM createGrid(int rowSize, int columnSize, Scalar<? extends Scalar<?>>[][] elements) {
// return new AbstractIntervalDerivativeMatrix(rowSize, columnSize, (AbstractIntervalDerivative[][])elements);
// }
//
// /**
// * @see org.mklab.nfc.scalar.Scalar#createGrid(org.mklab.nfc.scalar.Scalar[])
// */
// public IDM createGrid(Scalar<? extends Scalar<?>>[] elements) {
// return new AbstractIntervalDerivativeMatrix(new AbstractIntervalDerivative[][] {(AbstractIntervalDerivative[])elements});
// }
/**
* @see org.mklab.nfc.scalar.Scalar#createUnit()
*/
public IDS createUnit() {
return create(this.x.createUnit(), this.dx.createZero());
}
// /**
// * @see org.mklab.nfc.scalar.Scalar#divide(org.mklab.nfc.scalar.Scalar)
// */
// @Override
// public IDS divide(final Scalar<?> value) {
// if (value instanceof AbstractIntervalDerivative) {
// return new AbstractIntervalDerivative(this.x.divide(((AbstractIntervalDerivative)value).getX()), this.dx.multiply(((AbstractIntervalDerivative)value).getX())
// .subtract(this.x.multiply(((AbstractIntervalDerivative)value).getDX())).divide(((AbstractIntervalDerivative)value).getX().multiply(((AbstractIntervalDerivative)value).getX())));
// } else if (value instanceof IntervalScalar) {
// return new AbstractIntervalDerivative(this.x.multiply((IntervalScalar)value), this.dx);
// } else if (value instanceof DoubleComplexNumber) {
// return new AbstractIntervalDerivative(this.x.multiply((DoubleComplexNumber)value), this.dx);
// } else {
// throw new UnsupportedOperationException();
// }
// }
/**
* @see org.mklab.nfc.scalar.Scalar#divide(double)
*/
public IDS divide(final double value) {
return create(this.x.divide(value), this.dx);
}
/**
* @see org.mklab.nfc.scalar.Scalar#divide(int)
*/
public IDS divide(final int value) {
return create(this.x.divide(value), this.dx);
}
// /**
// * @see org.mklab.nfc.scalar.Scalar#equals(org.mklab.nfc.scalar.Scalar, double)
// */
// @Override
// public boolean equals(Scalar<?> opponent, double tolerance) {
// if (!(opponent instanceof AbstractIntervalDerivative)) return false;
// return equals((IDS)opponent, tolerance);
// }
/**
* 許容範囲内で等しいか判定します。
*
* @param opponent 比較する微分値成分
* @param tolerance 許容誤差
* @return 許容範囲内で等しければtrue、そうでなければfalse
*/
public boolean equals(IDS opponent, double tolerance) {
return this.x.subtract(opponent.getX()).abs().getSupremum().isLessThan(tolerance) && this.dx.subtract(opponent.getDX()).abs().getSupremum().isLessThan(tolerance);
}
/**
* @see org.mklab.nfc.scalar.Scalar#inverse()
*/
public IDS inverse() {
IS one = this.x.createUnit(); // new DoubleIntervalNumber(1.0);
return create(one.divide(this.x), one.divide(this.dx));
}
/**
* @see org.mklab.nfc.scalar.Scalar#isFinite()
*/
public boolean isFinite() {
return (!isInfinite()) && (!isNaN());
}
/**
* @see org.mklab.nfc.scalar.Scalar#isInfinite()
*/
public boolean isInfinite() {
return this.x.isFinite() || this.dx.isFinite();
}
/**
* @see org.mklab.nfc.scalar.Scalar#isNaN()
*/
public boolean isNaN() {
return this.x.isNaN() || this.dx.isNaN();
}
/**
* @see org.mklab.nfc.scalar.Scalar#isUnit()
*/
public boolean isUnit() {
return this.x.isUnit() && this.dx.isZero();
}
/**
* @see org.mklab.nfc.scalar.Scalar#isUnit(double)
*/
public boolean isUnit(double tolerance) {
return this.x.isUnit(tolerance) && this.dx.isZero(tolerance);
}
/**
* {@inheritDoc}
*/
public boolean isUnit(IDS tolerance) {
return this.x.isUnit(tolerance.getX()) && this.dx.isZero(tolerance.getX());
}
/**
* @see org.mklab.nfc.scalar.Scalar#isZero(double)
*/
public boolean isZero(double tolerance) {
return this.x.isZero(tolerance) && this.dx.isZero(tolerance);
}
/**
* {@inheritDoc}
*/
public boolean isZero(IDS tolerance) {
return this.x.isZero(tolerance.getX()) && this.dx.isZero(tolerance.getX());
}
/**
* @see org.mklab.nfc.scalar.Scalar#leftDivide(org.mklab.nfc.scalar.Scalar)
*/
@Override
public IDS leftDivide(IDS value) {
throw new UnsupportedOperationException();
}
/**
* @see org.mklab.nfc.scalar.Scalar#leftDivide(double)
*/
public IDS leftDivide(double value) {
return this.inverse().multiply(value);
}
/**
* @see org.mklab.nfc.scalar.Scalar#leftDivide(int)
*/
public IDS leftDivide(int value) {
return this.inverse().multiply(value);
}
// /**
// * @see org.mklab.nfc.scalar.Scalar#multiply(org.mklab.nfc.scalar.Scalar)
// */
// @Override
// public IDS multiply(final Scalar<?> value) {
// if (value instanceof AbstractIntervalDerivative) {
// return new AbstractIntervalDerivative(this.x.multiply(((AbstractIntervalDerivative)value).getX()), this.x.multiply(((AbstractIntervalDerivative)value).getDX()).add(this.dx.multiply(((AbstractIntervalDerivative)value).getX())));
// } else if (value instanceof IntervalScalar) {
// return new AbstractIntervalDerivative(this.x.multiply((IntervalScalar)value), this.dx);
// } else if (value instanceof DoubleComplexNumber) {
// return new AbstractIntervalDerivative(this.x.multiply((DoubleComplexNumber)value), this.dx);
// } else {
// throw new UnsupportedOperationException();
// }
// }
/**
* @see org.mklab.nfc.scalar.Scalar#multiply(double)
*/
public IDS multiply(final double value) {
return create(this.x.multiply(value), this.dx);
}
/**
* @see org.mklab.nfc.scalar.Scalar#multiply(int)
*/
public IDS multiply(final int value) {
return create(this.x.multiply(value), this.dx);
}
/**
* @see org.mklab.nfc.scalar.Scalar#power(int)
*/
public IDS power(int scalar) {
IDS value = this.clone();
for (int i = 0; i < scalar; i++) {
value = value.multiply(value);
}
return value;
}
// /**
// * @see org.mklab.nfc.scalar.Scalar#subtract(org.mklab.nfc.scalar.Scalar)
// */
// @Override
// public IDS subtract(final Scalar<?> value) {
// if (value instanceof AbstractIntervalDerivative) {
// return new AbstractIntervalDerivative(this.x.subtract(((AbstractIntervalDerivative)value).getX()), this.dx.subtract(((AbstractIntervalDerivative)value).getDX()));
// } else if (value instanceof IntervalScalar) {
// return new AbstractIntervalDerivative(this.x.subtract((IntervalScalar)value), this.dx);
// } else if (value instanceof DoubleComplexNumber) {
// return new AbstractIntervalDerivative(this.x.subtract((DoubleComplexNumber)value), this.dx);
// } else {
// throw new UnsupportedOperationException();
// }
// }
/**
* @see org.mklab.nfc.scalar.Scalar#subtract(double)
*/
public IDS subtract(final double value) {
return create(this.x.subtract(value), this.dx);
}
/**
* @see org.mklab.nfc.scalar.Scalar#subtract(int)
*/
public IDS subtract(final int value) {
return create(this.x.subtract(value), this.dx);
}
// /**
// * @see org.mklab.nfc.scalar.Scalar#transformFrom(int)
// */
// public IDS transformFrom(int value) {
// return null;
// }
//
// /**
// * @see org.mklab.nfc.scalar.Scalar#transformFrom(double)
// */
// public IDS transformFrom(double value) {
// return null;
// }
/**
* {@inheritDoc}
*/
public boolean compare(String operator, IDS opponent) {
return false;
}
// /**
// * @see org.mklab.nfc.matrix.GridElement#createArray(int)
// */
// public IDS[] createArray(int size) {
// return new AbstractIntervalDerivative[size];
// }
//
// /**
// * @see org.mklab.nfc.matrix.GridElement#createArray(int, int)
// */
// public IDS[][] createArray(int rowSize, int columnSize) {
// return new AbstractIntervalDerivative[rowSize][columnSize];
// }
// /**
// * @see org.mklab.nfc.matrix.GridElement#createArray(org.mklab.nfc.matrix.GridElement[])
// */
// public IDS[] createArray(GridElement<?>[] elements) {
// final int size = elements.length;
// final IDS[] array = (IDS[])elements[0].createArray(size);
// System.arraycopy(elements, 0, array, 0, size);
// return array;
// }
//
// /**
// * @see org.mklab.nfc.matrix.GridElement#createArray(GridElement[][])
// */
// public IDS[][] createArray(GridElement<?>[][] elements) {
// final int rowSize = elements.length;
// final int columnSize = rowSize == 0 ? 0 : elements[0].length;
// final IDS[][] array = (IDS[][])elements[0][0].createArray(rowSize, columnSize);
// for (int row = 0; row < rowSize; row++) {
// System.arraycopy(elements[row], 0, array[row], 0, columnSize);
// }
// return array;
// }
/**
* @see org.mklab.nfc.matrix.GridElement#createZero()
*/
public IDS createZero() {
return create(this.x.createZero(), this.dx.createZero());
}
// /**
// * @see org.mklab.nfc.scalar.AbstractScalar#isTransformableFrom(org.mklab.nfc.matrix.GridElement)
// */
// @Override
// public boolean isTransformableFrom(GridElement<?> value) {
// return false;
// }
//
// /**
// * @see org.mklab.nfc.scalar.AbstractScalar#isTransformableTo(org.mklab.nfc.matrix.GridElement)
// */
// @Override
// public boolean isTransformableTo(GridElement<?> value) {
// return false;
// }
/**
* @see org.mklab.nfc.matrix.GridElement#isZero()
*/
public boolean isZero() {
return this.x.isZero() && this.dx.isZero();
}
// /**
// * @see org.mklab.nfc.scalar.AbstractScalar#transformFrom(org.mklab.nfc.matrix.GridElement)
// */
// @Override
// public IDS transformFrom(GridElement<?> value) {
// return null;
// }
//
// /**
// * @see org.mklab.nfc.scalar.AbstractScalar#transformTo(org.mklab.nfc.matrix.GridElement)
// */
// @Override
// public GridElement<?> transformTo(GridElement<?> value) {
// return null;
// }
/**
* @see org.mklab.nfc.scalar.RoundableToInteger#ceil()
*/
public IDS ceil() {
return create(this.x.ceil(), this.dx.ceil());
}
/**
* @see org.mklab.nfc.scalar.RoundableToInteger#fix()
*/
public IDS fix() {
return create(this.x.fix(), this.dx.fix());
}
/**
* @see org.mklab.nfc.scalar.RoundableToInteger#floor()
*/
public IDS floor() {
return create(this.x.floor(), this.dx.floor());
}
/**
* @see org.mklab.nfc.scalar.RoundableToInteger#round()
*/
public IDS round() {
return create(this.x.round(), this.dx.round());
}
/**
* @see org.mklab.nfc.scalar.RoundableToInteger#roundToZero(double)
*/
public IDS roundToZero(double tolerance) {
return create(this.x.roundToZero(tolerance), this.dx.roundToZero(tolerance));
}
/**
* {@inheritDoc}
*/
public IDS roundToZero(IDS tolerance) {
return create(this.x.roundToZero(tolerance.getX()), this.dx.roundToZero(tolerance.getX()));
}
// /**
// * @see org.mklab.nfc.scalar.Scalar#getAddOperator()
// */
// public ScalarOperator getAddOperator() {
// throw new UnsupportedOperationException();
// }
//
// /**
// * @see org.mklab.nfc.scalar.Scalar#getDivideOperator()
// */
// public ScalarOperator getDivideOperator() {
// throw new UnsupportedOperationException();
// }
//
// /**
// * @see org.mklab.nfc.scalar.Scalar#getLeftDivideOperator()
// */
// public ScalarOperator getLeftDivideOperator() {
// throw new UnsupportedOperationException();
// }
//
// /**
// * @see org.mklab.nfc.scalar.Scalar#getMultiplyOperator()
// */
// public ScalarOperator getMultiplyOperator() {
// throw new UnsupportedOperationException();
// }
//
// /**
// * @see org.mklab.nfc.scalar.Scalar#getSubtractOperator()
// */
// public ScalarOperator getSubtractOperator() {
// throw new UnsupportedOperationException();
// }
//
// /**
// * @see org.mklab.nfc.scalar.Scalar#getEqualOperator()
// */
// public ScalarEqual getEqualOperator() {
// throw new UnsupportedOperationException();
// }
/**
* @see org.mklab.nfc.scalar.Scalar#toString(java.lang.String)
*/
public String toString(String valueFormat) {
throw new UnsupportedOperationException();
}
/**
* @see org.mklab.nfc.scalar.Scalar#isComplex()
*/
public boolean isComplex() {
return false;
}
/**
* @see org.mklab.nfc.scalar.Scalar#isReal()
*/
public boolean isReal() {
return true;
}
// /**
// * @see org.mklab.nfc.scalar.Scalar#setRealPart(org.mklab.nfc.scalar.Scalar)
// */
// public void setRealPart(Scalar<?> realPart) {
// throw new UnsupportedOperationException();
// }
// /**
// * @see org.mklab.nfc.scalar.Scalar#setImaginaryPart(org.mklab.nfc.scalar.Scalar)
// */
// public void setImaginaryPart(Scalar<?> imagPart) {
// throw new UnsupportedOperationException();
// }
/**
* @return result
*/
public IDS toComplex() {
throw new UnsupportedOperationException();
}
}