RatioInitResCurrentRes.java

package org.mklab.sdpj.algorithm;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;

import org.mklab.nfc.matrix.ComplexNumericalMatrix;
import org.mklab.nfc.matrix.RealNumericalMatrix;
import org.mklab.nfc.scalar.ComplexNumericalScalar;
import org.mklab.nfc.scalar.RealNumericalScalar;
import org.mklab.sdpj.tool.Tools;


/**
 * class <code>RatioInitResCurrentRes</code>, which is computed to judge whether computing can be done correctly or not,
 * is based on the theory of interior method and implemented based on algorithm of <code>SDPA</code>. About information of
 * <code>SDPA</code>, please refer to web site:
 *  <a href = "http://sdpa.sourceforge.net/" style=text-decoration:none>
 * <tt>http://sdpa.sourceforge.net/</tt></a>.<br>  
 * 
 * @author koga
 * @version $Revision$, 2009/04/24
 * @param <RS> type of real scalar
 * @param <RM> type of real matrix
 * @param <CS> type of complex scalar
 * @param <CM> type of complex Matrix
 */
public class RatioInitResCurrentRes<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>> {

  /**ratio of primal residual */
  private RS primal;
  /**ratio of dual residual */
  private RS dual;

  
  /**
   * constructor of class <code>RatioInitResCurrentRes</code>.
   * <br>新しく生成された{@link RatioInitResCurrentRes}オブジェクトを初期化します。
   * 
   * @param param setting parameter
   * @param initRes initial residual
   */
  public RatioInitResCurrentRes(Parameter<RS,RM,CS,CM> param, Residuals<RS,RM,CS,CM> initRes) {
    final RS unit = param.epsilonDash.createUnit();

    RS accuracy = param.epsilonDash;
    if (initRes.getNormPrimalVec().isLessThan(accuracy)) {
      this.primal = unit.createZero();
    } else {
      this.primal = unit.createUnit();
    }
    if (initRes.getNormDualMat().isLessThan(accuracy)) {
      this.dual = unit.createZero();
    } else {
      this.dual = unit.createUnit();
    }
  }

  /**
   * update the ratio of current residual by each iteration of computing.
   * 
   * @param reduction type of switch
   * @param alpha step length <code>alpha</code>
   */
  public void update(Switch<RS,RM,CS,CM> reduction, StepLength<RS,RM,CS,CM> alpha) {
    final RS unit = this.getPrimal().createUnit();
    if (reduction.getSwitchType() == SwitchType.ON) {
      // At least one of primal or dual is infeasible
      this.primal = ((unit.createUnit().subtract(alpha.getPrimal())).multiply(this.getPrimal())).abs();
      this.dual = ((unit.createUnit().subtract(alpha.getDual())).multiply(this.getDual())).abs();
    }
  }

  /**
   * update the ratio of current residual by each iteration of computing exactly.
   * 
   * @param initRes initial residual
   * @param currentRes current residual
   */
  public void update_exact(Residuals<RS,RM,CS,CM> initRes, Residuals<RS,RM,CS,CM> currentRes) {
    final RS unit = this.getPrimal().createUnit();

    // TODO パラメータとして抽出すべきです。
    final RS tolerance = unit.create(10).power(-10);

    if (initRes.getNormPrimalVec().isGreaterThan(tolerance)) {
      this.primal = currentRes.getNormPrimalVec().divide(initRes.getNormPrimalVec());
    } else {
      this.primal = unit.createZero();
    }
    if (initRes.getNormDualMat().isGreaterThan(tolerance)) {
      this.dual = currentRes.getNormDualMat().divide(initRes.getNormDualMat());
    } else {
      this.dual = unit.createZero();
    }
  }

  /**
   * @see java.lang.Object#toString()
   */
  @Override
  public String toString() {
    return "theta.primal = " + this.getPrimal() + "\n" + "theta.dual   = " + this.getDual() + "\n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
  }

  /**
   * 標準出力に表示
   */
  public void display() {
    Tools.message(toString());
  }

  /**
   * show the information of inputting file
   * 
   * @param file <i>data</i> file
   */
  public void display(File file) {
    try (PrintStream ps = new PrintStream(new FileOutputStream(file))) {
      Tools.message(toString(), ps);
      ps.close();
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  /**
   * primalを返します。
   * 
   * @return primal
   */
  public RS getPrimal() {
    return this.primal;
  }

  /**
   * dualを返します。
   * 
   * @return dual
   */
  public RS getDual() {
    return this.dual;
  }
}