Problem.java

package org.mklab.sdpj.problem;

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.algorithm.Parameter;
import org.mklab.sdpj.algorithm.Solution;
import org.mklab.sdpj.datastructure.BlockSparseMatrix;
import org.mklab.sdpj.datastructure.Vector;
import org.mklab.sdpj.tool.Tools;


/**
 * Class <code>Problem</code> is defined for managing inputting data efficiently, 
 * which can be solved correctly by solver.
 * 
 * @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 Problem<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>> {

  /**setting parameter */
  private Parameter<RS,RM,CS,CM> param;
  /**dimension of vector */
  private int m;
  /**size of block */
  private int blockSize;
  /**structure of block-matrices matrix */
  private int[] blockStruct;
  /**vector <code>b</code> */
  private Vector<RS,RM,CS,CM> b;
  /**sparse block-matrices matrix <code>C</code>*/
  private BlockSparseMatrix<RS,RM,CS,CM> C;
  /**sparse block-matrices matrix array <code>A</code>*/
  private BlockSparseMatrix<RS,RM,CS,CM>[] A;
  /**initial primal-dual solution */
  private Solution<RS,RM,CS,CM> initPt;
  /** */
  private Solution<RS,RM,CS,CM> currentPt;
  /**dimension of block-matrices matrix array */
  private int nDim = 0;
  /**if initializing primal-dual solution, true; else, false */
  private boolean isInitializeInitPt = false;
  /**initial constant matrix <code>C</code> */
  private BlockSparseMatrix<RS,RM,CS,CM> initialC;
  /**initial vector */
  private Vector<RS,RM,CS,CM> initialVector;
  

  /**
   * 新しく生成された<code>Problem</code>オブジェクトを初期化します。
   * 
   * @param m dimension of vector
   * @param nBlock the number of block
   * @param blockStruct information of block-matrices matrix array
   * @param A block-matrices matrix array
   * @param b vector
   * @param C block-matrices matrix
   * @param param setting parameter
   * @param currentPt current primal-dual solution
   * @param initPt initial primal-dual solution
   */
  public Problem(int m, int nBlock, int[] blockStruct, BlockSparseMatrix<RS,RM,CS,CM>[] A, Vector<RS,RM,CS,CM> b, BlockSparseMatrix<RS,RM,CS,CM> C, Parameter<RS,RM,CS,CM> param, Solution<RS,RM,CS,CM> currentPt, Solution<RS,RM,CS,CM> initPt) {
    this.m = m;
    this.blockSize = nBlock;
    this.blockStruct = blockStruct;
    this.A = A;
    this.b = b;
    this.C = C;
    this.param = param;

    cratenDim();
    changeToDense();

    if (currentPt == null) {
      this.currentPt = new Solution<>(m, nBlock, blockStruct, param.lambdaStar);
    } else {
      this.currentPt = currentPt;
    }

    if (initPt == null) {
      this.initPt = new Solution<>(m, nBlock, blockStruct, param.lambdaStar);
    } else {
      this.initPt = initPt;
      this.isInitializeInitPt = true;
    }
  }

  /**
   * change sparse matrix into dense matrix.
   */
  private void changeToDense() {
    // if possible , change C and A to Dense
    this.C.changeToDense();
    for (int i = 0; i < this.m; ++i) {
      this.A[i].changeToDense();
    }
  }

  /**
   *compute the dimension of block-matrices matrix array
   */
  private void cratenDim() {
    this.nDim = 0;
    for (int i = 0; i < this.blockSize; ++i) {
      this.nDim += Math.abs(this.blockStruct[i]);
    }
  }

  /**
   * get an initial primal-dual solution.
   * 
   * @return initial primal-dual solution
   */
  public Solution<RS,RM,CS,CM> getInitPt() {
    return this.initPt;
  }

  /**
   * get a dimension of block-matrices matrix array.
   * 
   * @return dimension of block-matrices matrix array
   */
  public int getNDim() {
    return this.nDim;
  }

  /**
   * set the dimension of block-matrices matrix array.
   * 
   * @param dim dimension of block-matrices matrix array 
   */
  public void setNDim(int dim) {
    this.nDim = dim;
  }

  /**
   * get a current primal-dual solution
   * 
   * @return current primal-dual solution
   */
  public Solution<RS,RM,CS,CM> getCurrentPt() {
    return this.currentPt;
  }

  /**
   * get a setting parameter of solver.
   * 
   * @return a setting parameter
   */
  public Parameter<RS,RM,CS,CM> getParam() {
    return this.param;
  }

  /**
   * set a setting parameter of solving SDP problem.
   * 
   * @param param a setting parameter
   */
  public void setParam(Parameter<RS,RM,CS,CM> param) {
    this.param = param;
  }

  /**
   * get a dimension of vector <code>c</code>
   * 
   * @return dimension of vector
   */
  public int getM() {
    return this.m;
  }

  /**
   * get a specified block size
   * 
   * @return specified block size
   */
  public int getBlockSize() {
    return this.blockSize;
  }

  /**
   * get a integer array that is the information of structure of block-matrices array.
   * 
   * @return a integer array
   */
  public int[] getBlockStruct() {
    return this.blockStruct;
  }

  /**
   * get a vector <code>b</code>
   * <blockquote><tt>
   * Note:<br>
   *  vector <code>b</code>  := vector <code>c</code><br>
   * </tt></blockquote>
   * 
   * @return a vector
   */
  public Vector<RS,RM,CS,CM> getB() {
    return this.b;
  }

  /**
   * get a block-matrices array <code>C</code>
   * <blockquote><tt>
   * Note:<br>
   *  matrix <code>C</code>  := matrix <code>F0</code><br>
   *  matrix <code>A</code>  := matrix <code>Fi</code><br>
   * </tt></blockquote>
   * 
   * @return block-matrices array
   */
  public BlockSparseMatrix<RS,RM,CS,CM> getC() {
    return this.C;
  }

  /**
   * get a matrix <code>A</code>
   * <blockquote><tt>
   * Note:<br>
   *  matrix <code>C</code>  := matrix <code>F0</code><br>
   *  matrix <code>A</code>  := matrix <code>Fi</code><br>
   * </tt></blockquote>
   * 
   * 
   * @return matrix <code>A</code>
   */
  public BlockSparseMatrix<RS,RM,CS,CM>[] getA() {
    return this.A;
  }

  /**
   * if an initializing primal-dual solution, true; else, false.
   * 
   * @return a boolean value
   */
  public boolean isInitializeInitPt() {
    return this.isInitializeInitPt;
  }

  /**
   * @param out 表示先
   */
  public void display(PrintStream out) {
    Tools.message(this.m + " \t= mDIM", out); //$NON-NLS-1$
    Tools.message(this.blockSize + " \t= nBLOCK", out); //$NON-NLS-1$
    String struct = ""; //$NON-NLS-1$
    for (int i = 0; i < this.blockStruct.length; i++) {
      struct += this.blockStruct[i] + " "; //$NON-NLS-1$
    }
    Tools.message(struct + " = bLOCKsTRUCT", out); //$NON-NLS-1$
    Tools.message("vec:", out); //$NON-NLS-1$
    this.b.display(out);
    Tools.message("-F[0]:", out); //$NON-NLS-1$
    out.print(this.C);
    for (int i = 0; i < this.m; i++) {
      Tools.message("F[" + (i + 1) + "]:", out); //$NON-NLS-1$ //$NON-NLS-2$
      out.print(this.A[i]);
    }
  }

  /**
   * show solution
   */
  public void display() {
    display(System.out);
  }

  
  /**
   * @param C Cを設定します。
   */
  public void setC(BlockSparseMatrix<RS,RM,CS,CM> C) {
    this.C = C;
  }
  
  /**
   * @param vector a instance of class
   */
  public void setVector(Vector<RS,RM,CS,CM> vector) {
    this.b = vector;
  }
  
  /**
   * @param initialC initialCを設定します。
   */
  public void setInitialC(BlockSparseMatrix<RS,RM,CS,CM> initialC) {
    this.initialC = initialC;
  }

  /**
   * @return tempCを返します。
   */
  public BlockSparseMatrix<RS,RM,CS,CM> getInitialC() {
    return this.initialC;
  }

  /**
   * @param initialVector tempVectorを設定します。
   */
  public void setInitialVector(Vector<RS,RM,CS,CM> initialVector) {
    this.initialVector = initialVector;
  }

  /**
   * @return tempVectorを返します。
   */
  public Vector<RS,RM,CS,CM> getInitialVector() {
    return this.initialVector;
  }
}