SdpjMain.java

package org.mklab.sdpj.main;

import java.io.IOException;

import org.mklab.mpf.ap.MPFloat;
import org.mklab.mpf.ap.MPFloatComplexMatrix;
import org.mklab.mpf.ap.MPFloatComplexNumber;
import org.mklab.mpf.ap.MPFloatMatrix;
import org.mklab.nfc.matrix.ComplexNumericalMatrix;
import org.mklab.nfc.matrix.DoubleComplexMatrix;
import org.mklab.nfc.matrix.DoubleMatrix;
import org.mklab.nfc.matrix.RealNumericalMatrix;
import org.mklab.nfc.scalar.ComplexNumericalScalar;
import org.mklab.nfc.scalar.DoubleComplexNumber;
import org.mklab.nfc.scalar.DoubleNumber;
import org.mklab.nfc.scalar.RealNumericalScalar;
import org.mklab.sdpj.solver.Solver;


/**
 * Class <code>SdpjMain</code> is stand-alone starting by command line style, which can solve a SDP problem with highly accurate based on multiple precision arithmetic. About more details of usage of
 * class <code> SdpjMain</code>, you can refer to method <code>{@link SdpjParameters#showMessage <tt>showMessage</tt>}</code>.
 * 
 * @author takafumi
 * @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 SdpjMain<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>> {

  /** ソルバー */
  // private SDPJSolver<? extends NumericalScalar<?>> solver;
  private Solver<RS,RM,CS,CM> solver;

  /**
   * interpreter subroutine of class <code>Sdpj</code>
   * 
   * @param args arguments string
   * @throws IOException If I/O exception occurs
   */
  public static void main(String[] args) throws IOException {
    final SdpjParameters parameters = new SdpjParameters();
    parameters.parseArguments(args);

    //    EFFloat.setLogEnable(true);
    //    EFFloat.setLogFileName("sdpj.log"); //$NON-NLS-1$

    if (parameters.dataType.equals("mpfloat")) { //$NON-NLS-1$
      MPFloat.setDefaultPrecisionDigits(parameters.precision);
      
      final SdpjMain<MPFloat,MPFloatMatrix,MPFloatComplexNumber,MPFloatComplexMatrix> main = new SdpjMain<>();
      main.setSolver(new Solver<>(new MPFloat(1)));
      System.out.println("\nSDPJ is based on the datatype : MPFloat"); //$NON-NLS-1$
      System.out.println("SdpjMain approximate significant digits : " + MPFloat.getDefaultNumberOfPrecisionDigits()); //$NON-NLS-1$   
      if (parameters.kappaString != null) {
        main.solver.setKappa(new MPFloat(1).valueOf(parameters.kappaString));
      }
      main.run(parameters);
    } else if (parameters.dataType.equals("double")) { //$NON-NLS-1$
      DoubleNumber.setDisplayAsZero(false);
      
      final SdpjMain<DoubleNumber,DoubleMatrix,DoubleComplexNumber,DoubleComplexMatrix> main = new SdpjMain<>();
      main.setSolver(new Solver<>(new DoubleNumber(1)));
      System.out.println("\nSDPJ is based on the datatype : double"); //$NON-NLS-1$
      System.out.println("SdpjMain approximate significant digits : 16"); //$NON-NLS-1$
      if (parameters.kappaString != null) {
        main.solver.setKappa(new DoubleNumber(1).valueOf(parameters.kappaString));
      }
      main.run(parameters);
    } else {
      System.err.println("Please decide a data type correctly in your parameter file!"); //$NON-NLS-1$
      System.exit(0);
    }
  }

  /**
   * a constructor of class <code>SdpjMain</code>, which initialize a instance of <code>SdpjMain</code>.
   * 
   * 新しく生成された{@link SdpjMain}オブジェクトを初期化します。
   */
  public SdpjMain() {}

  /**
   * Returning a solver.
   * 
   * @return information of a solver of SdpjMain
   */
  public Solver<RS,RM,CS,CM> getSolver() {
    return this.solver;
  }
  
  /**
   * Sets solver.
   * 
   * @param solver solver
   */
  public void setSolver(Solver<RS,RM,CS,CM> solver) {
    this.solver = solver;
  }

  /**
   * This is a solver of SdpjMain, which can compute a optimal solution of SDP problem, is an entry of solving a SDP problem.
   * 
   * @param parameters parameters
   * @throws IOException  If I/O exception occurs
   */
  public void run(SdpjParameters parameters) throws IOException {
    //set some parameters of solver before running 
    this.solver.setDataFile(parameters.dataFile);
    this.solver.setInitFile(parameters.initFile);
    this.solver.setOutFile(parameters.outFile);
    this.solver.setParaFile(parameters.paraFile);
    this.solver.setIsInitFile(parameters.isInitFile);
    this.solver.setIsInitSparse(parameters.isInitSparse);
    this.solver.setIsDataSparse(parameters.isDataSparse);
    this.solver.setIsParameter(parameters.isParameter);
    this.solver.setParameterType(parameters.parameterType);
    this.solver.setPrintStreamForDisplay(System.out);
    this.solver.setPrintStreamForSave(parameters.fpOut);

    final double startTime = System.nanoTime();
    this.solver.run();
    final double endTime = System.nanoTime();
    System.out.printf("The elapsed time of solving this SDP problem is : %.3f seconds\n\n", Double.valueOf((endTime - startTime) / 1e9)); //$NON-NLS-1$
  }

//  /**
//   * Change a data string into a data based on the data type, which is used in program.
//   * 
//   * @param <E> a generic data type
//   * @param string a data string
//   * @return a data based on a data type
//   */
//  private <E extends NumericalScalar<E>> E atof(String string) {
//    if (this.dataType.equals("double")) { //$NON-NLS-1$
//      return (E)new DoubleNumber(1).valueOf(string);
//    }
//    if (this.dataType.equals("mpfloat")) { //$NON-NLS-1$
//      return (E)new MPFloat(1).valueOf(string);
//    }
//    return null;
//  }

}