ResidualImprover.java

/*
 * Created on 2004/10/19
 *
 * $Id: ResidualImprover.java,v 1.13 2008/02/02 03:30:29 koga Exp $
 * Copyringht (C) 2004 Koga Laboratory. All rights reserved.
 */
package org.mklab.cga.linear;

import org.mklab.cga.interval.matrix.IntervalComplexNumericalMatrix;
import org.mklab.cga.interval.matrix.IntervalNumericalMatrix;
import org.mklab.cga.interval.matrix.IntervalRealNumericalMatrix;
import org.mklab.cga.interval.scalar.IntervalComplexNumericalScalar;
import org.mklab.cga.interval.scalar.IntervalNumericalScalar;
import org.mklab.cga.interval.scalar.IntervalRealNumericalScalar;
import org.mklab.nfc.matrix.ComplexNumericalMatrix;
import org.mklab.nfc.matrix.NumericalMatrix;
import org.mklab.nfc.matrix.RealNumericalMatrix;
import org.mklab.nfc.scalar.ComplexNumericalScalar;
import org.mklab.nfc.scalar.NumericalScalar;
import org.mklab.nfc.scalar.RealNumericalScalar;


/**
 * 残差 <code>b-Ax</code> もしくは <code>I-Ax</code> の近似値の改善を行うクラスです。
 * 
 * @author hiroki
 * @version $Revision: 1.13 $. 2004/10/19
 */
public class ResidualImprover {

  /**
   * 残差を求めます。
   * 
   * @param <IS> 区間スカラーの型
   * @param <IM> 区間行列の型
   * @param <S> 成分の型
   * @param <M> 行列の型
   * @param A 係数行列
   * @param x 解
   * @param b 右辺ベクトル
   * @return 残差
   */
  public static <IS extends IntervalNumericalScalar<IS, IM, S, M>, IM extends IntervalNumericalMatrix<IS, IM, S, M>, S extends NumericalScalar<S, M>, M extends NumericalMatrix<S, M>> M lssresidual(
      final M A, final M x, final M b) {
    return residual(A, x, b);
  }

  /**
   * 残差を求めます。
   * 
   * @param <RIS> 実区間スカラーの型
   * @param <RIM> 実区間行列の型
   * @param <CIS> 複素区間スカラーの型
   * @param <CIM> 複素区間行列の型
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param A 係数行列
   * @param x 解
   * @param b 右辺ベクトル
   * @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>> RM lssresidual(
      final RM A, final RM x, final RM b) {
    return residual(A, x, b);
  }

  /**
   * 残差を求めます。
   * 
   * @param <RIS> 実区間スカラーの型
   * @param <RIM> 実区間行列の型
   * @param <CIS> 複素区間スカラーの型
   * @param <CIM> 複素区間行列の型
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param A 係数行列
   * @param x 解
   * @param b 右辺ベクトル
   * @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>> CM lssresidual(
      final CM A, final CM x, final CM b) {
    return residual(A, x, b);
  }

  /**
   * @param <RIS> 実区間スカラーの型
   * @param <RIM> 実区間行列の型
   * @param <CIS> 複素区間スカラーの型
   * @param <CIM> 複素区間行列の型
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param midA Aの中心
   * @param xs 解
   * @param matrix 区間行列
   * @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>> RM lssresidual(
      final RM midA, final RM xs, final RIM matrix) {
    RM m = matrix.getMiddle();
    return lssresidual(midA, xs, m);
  }

  /**
   * @param <RIS> 実区間スカラーの型
   * @param <RIM> 実区間行列の型
   * @param <CIS> 複素区間スカラーの型
   * @param <CIM> 複素区間行列の型
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param midA Aの中心
   * @param xs 解
   * @param matrix 区間行列
   * @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>> CM lssresidual(
      final CM midA, final CM xs, final CIM matrix) {
    CM m = matrix.getMiddle();
    return lssresidual(midA, xs, m);
  }

  /**
   * @param <RIS> 実区間スカラーの型
   * @param <RIM> 実区間行列の型
   * @param <CIS> 複素区間スカラーの型
   * @param <CIM> 複素区間行列の型
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param A A
   * @param x x
   * @param b b
   * @return ?
   */
  private 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>> RM residual(
      final RM A, final RM x, final RM b) {
    // ヒューリスティックで求めた最も良い値らしい(精度に依存しそう。。。)
    double factor = Math.pow(2, 36) - 1;

    RM C = A.multiply(factor);
    RM Abig = C.subtract(A);
    RM A1 = C.subtract(Abig);
    RM A2 = A.subtract(A1);

    RM mx = x.unaryMinus();
    RM y = mx.multiply(factor);
    RM xbig = y.subtract(mx);
    RM x1 = y.subtract(xbig);
    RM x2 = mx.subtract(x1);

    RM residual = (A1.multiply(x1).add(b)).add(A1.multiply(x2).add(A2.multiply(mx)));
    return residual;
  }

  /**
   * @param <RIS> 実区間スカラーの型
   * @param <RIM> 実区間行列の型
   * @param <CIS> 複素区間スカラーの型
   * @param <CIM> 複素区間行列の型
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param A A
   * @param x x
   * @param b b
   * @return ?
   */
  private 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>> CM residual(
      final CM A, final CM x, final CM b) {
    // ヒューリスティックで求めた最も良い値らしい(精度に依存しそう。。。)
    double factor = Math.pow(2, 36) - 1;

    CM C = A.multiply(factor);
    CM Abig = C.subtract(A);
    CM A1 = C.subtract(Abig);
    CM A2 = A.subtract(A1);

    CM mx = x.unaryMinus();
    CM y = mx.multiply(factor);
    CM xbig = y.subtract(mx);
    CM x1 = y.subtract(xbig);
    CM x2 = mx.subtract(x1);

    CM residual = (A1.multiply(x1).add(b)).add(A1.multiply(x2).add(A2.multiply(mx)));
    return residual;
  }

  /**
   * @param <IS> 区間スカラーの型
   * @param <IM> 区間行列の型
   * @param <S> 成分の型
   * @param <M> 行列の型
   * @param A A
   * @param x x
   * @param b b
   * @return ?
   */
  private static <IS extends IntervalNumericalScalar<IS, IM, S, M>, IM extends IntervalNumericalMatrix<IS, IM, S, M>, S extends NumericalScalar<S, M>, M extends NumericalMatrix<S, M>> M residual(
      final M A, final M x, final M b) {
    // ヒューリスティックで求めた最も良い値らしい(精度に依存しそう。。。)
    double factor = Math.pow(2, 36) - 1;

    M C = A.multiply(factor);
    M Abig = C.subtract(A);
    M A1 = C.subtract(Abig);
    M A2 = A.subtract(A1);

    M mx = x.unaryMinus();
    M y = mx.multiply(factor);
    M xbig = y.subtract(mx);
    M x1 = y.subtract(xbig);
    M x2 = mx.subtract(x1);

    M residual = (A1.multiply(x1).add(b)).add(A1.multiply(x2).add(A2.multiply(mx)));
    return residual;
  }

}