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;
}
}