AbstractIntervalScalar.java

/*
 * Created on 2010/01/19
 * Copyright (C) 2010 Koga Laboratory. All rights reserved.
 *
 */
package org.mklab.cga.interval.scalar;

import org.mklab.cga.interval.matrix.IntervalComplexNumericalMatrix;
import org.mklab.cga.interval.matrix.IntervalMatrix;
import org.mklab.cga.interval.matrix.IntervalRealNumericalMatrix;
import org.mklab.nfc.matrix.ComplexNumericalMatrix;
import org.mklab.nfc.matrix.Matrix;
import org.mklab.nfc.matrix.RealNumericalMatrix;
import org.mklab.nfc.scalar.AbstractScalar;
import org.mklab.nfc.scalar.ComplexNumericalScalar;
import org.mklab.nfc.scalar.RealNumericalScalar;
import org.mklab.nfc.scalar.Scalar;
import org.mklab.nfc.util.RoundMode;
import org.mklab.nfc.util.RoundModeManager;


/**
 * 区間を表す抽象クラスです。
 * 
 * @author koga
 * @version $Revision$, 2010/01/19
 * @param <IS> 区間スカラーの型
 * @param <IM> 区間行列の型
 * @param <S> スカラーの型
 * @param <M> 行列の型
 */
public abstract class AbstractIntervalScalar<IS extends IntervalScalar<IS, IM, S, M>, IM extends IntervalMatrix<IS, IM, S, M>, S extends Scalar<S, M>, M extends Matrix<S, M>>
    extends AbstractScalar<IS, IM> implements IntervalScalar<IS, IM, S, M> {

  /** シリアル番号 */
  private static final long serialVersionUID = -6952457040272642271L;

  /**
   * {@inheritDoc}
   */
  public boolean isFinite() {
    return (isInfinite() == false) && (isNaN() == false);
  }

  /**
   * 区間の中心を求めます。
   * 
   * @param <RIS> 実区間スカラーの型
   * @param <RIM> 実区間行列の型
   * @param <CIS> 複素区間スカラーの型
   * @param <CIM> 複素区間行列の型
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param inf infimum
   * @param sup supremum
   * 
   * @return 区間の中心。
   */
  public static <RIS extends IntervalRealNumericalScalar<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, RIM extends IntervalRealNumericalMatrix<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, CIS extends IntervalComplexNumericalScalar<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, CIM extends IntervalComplexNumericalMatrix<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> RS middle(
      RS inf, RS sup) {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_UP);
    RS mid = inf.add(sup.subtract(inf).divide(2));

    manager.setRoundMode(oldRoundMode);
    return mid;
  }

  /**
   * 区間の半径を求めます。
   * 
   * @param <RIS> 実区間スカラーの型
   * @param <RIM> 実区間行列の型
   * @param <CIS> 複素区間スカラーの型
   * @param <CIM> 複素区間行列の型
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param inf infimum
   * @param sup supremum
   * 
   * @return 区間の半径。
   */
  public static <RIS extends IntervalRealNumericalScalar<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, RIM extends IntervalRealNumericalMatrix<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, CIS extends IntervalComplexNumericalScalar<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, CIM extends IntervalComplexNumericalMatrix<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> RS radius(
      RS inf, RS sup) {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_UP);
    RS mid = middle(inf, sup);
    RS rad = mid.subtract(inf);

    manager.setRoundMode(oldRoundMode);
    return rad;
  }

  /**
   * 下限を求めます。
   * 
   * @param <RIS> 実区間スカラーの型
   * @param <RIM> 実区間行列の型
   * @param <CIS> 複素区間スカラーの型
   * @param <CIM> 複素区間行列の型
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param mid middle
   * @param rad radius
   * @return 下限
   */
  public static <RIS extends IntervalRealNumericalScalar<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, RIM extends IntervalRealNumericalMatrix<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, CIS extends IntervalComplexNumericalScalar<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, CIM extends IntervalComplexNumericalMatrix<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> RS infimum(
      RS mid, RS rad) {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_DOWN);

    RS inf = mid.subtract(rad);

    manager.setRoundMode(oldRoundMode);
    return inf;
  }

  /**
   * 上限を求めます。
   * 
   * @param <RIS> 実区間スカラーの型
   * @param <RIM> 実区間行列の型
   * @param <CIS> 複素区間スカラーの型
   * @param <CIM> 複素区間行列の型
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param mid middle
   * @param rad radius
   * @return 上限
   */
  public static <RIS extends IntervalRealNumericalScalar<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, RIM extends IntervalRealNumericalMatrix<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, CIS extends IntervalComplexNumericalScalar<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, CIM extends IntervalComplexNumericalMatrix<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> RS supremum(
      RS mid, RS rad) {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_UP);

    RS sup = mid.add(rad);

    manager.setRoundMode(oldRoundMode);
    return sup;
  }

  /**
   * 上限を求めます。
   * 
   * @param <RIS> 実区間スカラーの型
   * @param <RIM> 実区間行列の型
   * @param <CIS> 複素区間スカラーの型
   * @param <CIM> 複素区間行列の型
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * 
   * @param mid middle
   * @param rad radius
   * @return 上限
   */
  public static <RIS extends IntervalRealNumericalScalar<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, RIM extends IntervalRealNumericalMatrix<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, CIS extends IntervalComplexNumericalScalar<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, CIM extends IntervalComplexNumericalMatrix<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> CS supremum(
      CS mid, RS rad) {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_UP);

    RS real = mid.getRealPart().add(rad);
    RS imag = mid.getImaginaryPart().add(rad);
    CS sup = real.toComplex().create(real, imag);

    manager.setRoundMode(oldRoundMode);
    return sup;
  }

  /**
   * 下限を求めます。
   * 
   * @param <RIS> 実区間スカラーの型
   * @param <RIM> 実区間行列の型
   * @param <CIS> 複素区間スカラーの型
   * @param <CIM> 複素区間行列の型
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * 
   * @param mid middle
   * @param rad radius
   * @return 下限
   */
  public static <RIS extends IntervalRealNumericalScalar<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, RIM extends IntervalRealNumericalMatrix<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, CIS extends IntervalComplexNumericalScalar<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, CIM extends IntervalComplexNumericalMatrix<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> CS infimum(CS mid, RS rad) {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_DOWN);

    RS real = mid.getRealPart().subtract(rad);
    RS imag = mid.getImaginaryPart().subtract(rad);
    CS inf = real.toComplex().create(real, imag);

    manager.setRoundMode(oldRoundMode);
    return inf;
  }

  /**
   * 区間の中心を求めます。
   * 
   * @param <RIS> 実区間スカラーの型
   * @param <RIM> 実区間行列の型
   * @param <CIS> 複素区間スカラーの型
   * @param <CIM> 複素区間行列の型
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * 
   * @param inf infimum
   * @param sup supremum
   * @return 区間の中心。
   */
  public static <RIS extends IntervalRealNumericalScalar<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, RIM extends IntervalRealNumericalMatrix<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, CIS extends IntervalComplexNumericalScalar<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, CIM extends IntervalComplexNumericalMatrix<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> CS middle(CS inf, CS sup) {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_UP);
    CS mid = inf.add(sup.subtract(inf).divide(2));

    manager.setRoundMode(oldRoundMode);
    return mid;
  }

  /**
   * 区間の半径を求めます。
   * 
   * @param <RIS> 実区間スカラーの型
   * @param <RIM> 実区間行列の型
   * @param <CIS> 複素区間スカラーの型
   * @param <CIM> 複素区間行列の型
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * 
   * @param inf infimum
   * @param sup supremum
   * @return 区間の半径。
   */
  public static <RIS extends IntervalRealNumericalScalar<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, RIM extends IntervalRealNumericalMatrix<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, CIS extends IntervalComplexNumericalScalar<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, CIM extends IntervalComplexNumericalMatrix<RIS, RIM, CIS, CIM, RS, RM, CS, CM>, RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> RS radius(CS inf, CS sup) {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_UP);
    CS mid = middle(inf, sup);
    RS rad = mid.subtract(inf).abs().getRealPart();

    manager.setRoundMode(oldRoundMode);
    return rad;
  }

}