Parameter.java
package org.mklab.sdpj.algorithm;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
import org.mklab.mpf.ap.MPFloat;
import org.mklab.nfc.matrix.ComplexNumericalMatrix;
import org.mklab.nfc.matrix.RealNumericalMatrix;
import org.mklab.nfc.scalar.ComplexNumericalScalar;
import org.mklab.nfc.scalar.DoubleNumber;
import org.mklab.nfc.scalar.RealNumericalScalar;
import org.mklab.sdpj.iocenter.IO;
import org.mklab.sdpj.tool.Tools;
/**
* class <code>Parameter</code> is the setting parameter of solving SDP problem efficiently and correctly,
* which is based on the experiential data of computing experiment. About more detail information,
* 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 Parameter<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>> {
/**maximum iteration of computing, which is <code>400</code> by default. */
public int maxIteration;
/**parameter <code>epsilonStar</code>, which control the precision of solution. */
public RS epsilonStar;
/**parameter <code>lambdaStar</code>, which is initial value of solving SDP problem, is <code>100</code> by default. */
public RS lambdaStar;
/**parameter <code>omegaStar</code>, which is experiential data.*/
public RS omegaStar;
/**lower bound of SDP solution, which is <code>-100,000</code> by default. */
public RS lowerBound;
/**upper bound of SDP solution, which is <code>100,000</code> by default. */
public RS upperBound;
/**parameter <code>betaStar</code>, which is experiential data. */
public RS betaStar;
/**parameter <code>betaBar</code>, which which control the speed of numerical convergence of computing. */
public RS betaBar;
/**parameter <code>gammaStar</code>, which is experiential data.*/
public RS gammaStar;
/**parameter <code>epsilonDash</code>, which control the precision of solution. */
public RS epsilonDash;
/**unit based on a specific data type */
private RS unit;
/**
* constructor of class <code>Parameter</code>
* <br>新しく生成された{@link Parameter}オブジェクトを初期化します。
*
* @param unit unit based on a specified data type
*/
public Parameter(RS unit) {
this.unit = unit;
if (this.unit instanceof DoubleNumber) {
DoubleNumber.setDisplayAsZero(false);
}
}
/**
* an unit based on a specific data type.
*
* @return unit
*/
public RS getUnit() {
return this.unit;
}
/**
* パラメータタイプに従ったパラメータを設定します。
*
* @param type パラメータタイプ
*/
public void setDefaultParameter(ParameterType type) {
RS ten = this.unit.create(10);
if (type == ParameterType.PARAMETER_MP115_DEFAULT) {//MPFloat用のパラメータ
this.maxIteration = 200;
this.epsilonStar = ten.power(-30);
this.lambdaStar = ten.power(4);
this.omegaStar = this.unit.create(2);
this.lowerBound = ten.power(5).unaryMinus();
this.upperBound = this.lowerBound.unaryMinus();
this.betaStar = this.unit.createUnit().divide(10);
this.betaBar = this.unit.create(3).divide(10);
this.gammaStar = this.unit.create(9).divide(10);
this.epsilonDash = ten.power(-30);
} else if (type == ParameterType.PARAMETER_MP115_STABLE) {
this.maxIteration = 1000;
this.epsilonStar = ten.power(-30);
this.lambdaStar = ten.power(2);
this.omegaStar = this.unit.create(2);
this.lowerBound = ten.power(5).unaryMinus();
this.upperBound = this.lowerBound.unaryMinus();
this.betaStar = this.unit.create(2).divide(10);
this.betaBar = this.unit.create(4).divide(10);
this.gammaStar = this.unit.create(5).divide(10);
this.epsilonDash = ten.power(-30);
} else if (type == ParameterType.PARAMETER_STABLE) {
this.maxIteration = 1000;
this.epsilonStar = ten.power(-7);
this.lambdaStar = ten.power(2);
this.omegaStar = this.unit.createUnit().multiply(2);
this.lowerBound = ten.power(5).unaryMinus();
this.upperBound = ten.power(5);
this.betaStar = this.unit.create(2).divide(10);
this.betaBar = this.unit.create(4).divide(10);
this.gammaStar = this.unit.create(5).divide(10);
this.epsilonDash = ten.power(-7);
} else if (type == ParameterType.PARAMETER_AGGRESSIVE) {
this.maxIteration = 100;
this.epsilonStar = ten.power(-7);
this.lambdaStar = ten.power(2);
this.omegaStar = this.unit.createUnit().multiply(2);
this.lowerBound = ten.power(5).unaryMinus();
this.upperBound = ten.power(5);
this.betaStar = this.unit.createUnit().divide(100);
this.betaBar = this.unit.create(2).divide(100);
this.gammaStar = this.unit.create(98).divide(100);
this.epsilonDash = ten.power(-7);
} else {
this.maxIteration = 100;
this.epsilonStar = ten.power(-7);
this.lambdaStar = ten.power(2);
this.omegaStar = this.unit.create(2);
this.lowerBound = ten.power(5).unaryMinus();
this.upperBound = ten.power(5);
this.betaStar = this.unit.createUnit().divide(10);
this.betaBar = this.unit.create(2).divide(10);
this.gammaStar = this.unit.create(9).divide(10);
this.epsilonDash = ten.power(-7);
}
}
/**
* デフォルトパラメータを設定します。
*/
public void setDefaultParameter() {
this.setDefaultParameter(ParameterType.PARAMETER_DEFAULT);
}
/**
* ファイルからパラメータを読み込みます。 コメント文は無いものと考えています。 |[数字][その他] TODO
* IOで定義したパターンを使ってマッチさせると結果をStringでとってきてそのままMPFloatに渡せるかと。。。
*
* @param parameterFile パラメータファイル
* @throws IOException ファイルを読み込めない場合
*/
public void readFile(File parameterFile) throws IOException {
try (BufferedReader buffer = new BufferedReader(new FileReader(parameterFile))) {
this.maxIteration = IO.readInteger(buffer.readLine());
this.epsilonStar = this.unit.valueOf(IO.readOtherStringRealNumber(buffer.readLine()));
this.lambdaStar = this.unit.valueOf(IO.readOtherStringRealNumber(buffer.readLine()));
this.omegaStar = this.unit.valueOf(IO.readOtherStringRealNumber(buffer.readLine()));
this.lowerBound = this.unit.valueOf(IO.readOtherStringRealNumber(buffer.readLine()));
this.upperBound = this.unit.valueOf(IO.readOtherStringRealNumber(buffer.readLine()));
this.betaStar = this.unit.valueOf(IO.readOtherStringRealNumber(buffer.readLine()));
this.betaBar = this.unit.valueOf(IO.readOtherStringRealNumber(buffer.readLine()));
this.gammaStar = this.unit.valueOf(IO.readOtherStringRealNumber(buffer.readLine()));
this.epsilonDash = this.unit.valueOf(IO.readOtherStringRealNumber(buffer.readLine()));
buffer.close();
}
}
/**
* 出力します。
*
* @param output 出力先
*/
public void display(PrintStream output) {
Tools.message(this.toString(), output);
}
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
StringBuffer message = new StringBuffer();
message.append("betaBar : " + this.betaBar); //$NON-NLS-1$
message.append("\n"); //$NON-NLS-1$
message.append("betaStar : " + this.betaStar); //$NON-NLS-1$
message.append("\n"); //$NON-NLS-1$
message.append("epsilonDash : " + this.epsilonDash); //$NON-NLS-1$
message.append("\n"); //$NON-NLS-1$
message.append("epsilonStar : " + this.epsilonStar); //$NON-NLS-1$
message.append("\n"); //$NON-NLS-1$
message.append("gammaStar : " + this.gammaStar); //$NON-NLS-1$
message.append("\n"); //$NON-NLS-1$
message.append("lambdaStar : " + this.lambdaStar); //$NON-NLS-1$
message.append("\n"); //$NON-NLS-1$
message.append("lowerBound : " + this.lowerBound); //$NON-NLS-1$
message.append("\n"); //$NON-NLS-1$
message.append("maxIteration : " + this.maxIteration); //$NON-NLS-1$
message.append("\n"); //$NON-NLS-1$
message.append("omegaStar : " + this.omegaStar); //$NON-NLS-1$
message.append("\n"); //$NON-NLS-1$
message.append("upperBound : " + this.upperBound); //$NON-NLS-1$
message.append("\n"); //$NON-NLS-1$
if (this.betaBar instanceof MPFloat) {
message.append("The data type is based on : MPFloat\n"); //$NON-NLS-1$
message.append("approximate significant digits : " + MPFloat.getDefaultNumberOfPrecisionDigits()); //$NON-NLS-1$
}
if (this.betaBar instanceof DoubleNumber) {
message.append("The data type is based on : double\n"); //$NON-NLS-1$
message.append("approximate significant digits : 16"); //$NON-NLS-1$
}
message.append("\n"); //$NON-NLS-1$
return message.toString();
}
}