Sedumi.java
/*
* Created on 2010/01/23
* Copyright (C) 2010 Koga Laboratory. All rights reserved.
*
*/
package org.mklab.sdpj.convert;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import org.mklab.jmatx.matxengine.MaTXEngine;
import org.mklab.jmatx.matxengine.ParseException;
import org.mklab.matj.parser.statement.symbol.Constant;
import org.mklab.nfc.matrix.DoubleMatrix;
/**
* mmファイルからjavaファイルを生成し、sedumi形式のデータを生成します。
*
* @author Hiroaki Matsuo
* @version $Revision$, 2010/01/25
*/
public class Sedumi {
/**
* SeDuMi形式で記述されたmmファイルを読み込み、SDPA形式のdatファイルを出力します。
*
* @param mmFile mmファイル
* @param datFile datファイル
*/
public void SedumiLoad(String mmFile, String datFile) {
MaTXEngine engine = new MaTXEngine();
try {
engine.load(mmFile);
} catch (IOException e1) {
throw new RuntimeException(e1);
} catch (ParseException e1) {
throw new RuntimeException(e1);
}
final Constant A = (Constant)engine.getVariable("A").getConstant(); //$NON-NLS-1$
final Constant b = (Constant)engine.getVariable("b").getConstant(); //$NON-NLS-1$
final Constant c = (Constant)engine.getVariable("c").getConstant(); //$NON-NLS-1$
final Constant K_s = (Constant)engine.getVariable("K_s").getConstant(); //$NON-NLS-1$
DoubleMatrix sedumiA = (DoubleMatrix)A.getValue();
DoubleMatrix sedumib = (DoubleMatrix)b.getValue();
DoubleMatrix sedumic = (DoubleMatrix)c.getValue();
final int[] primitiveK_s = toIntArray((DoubleMatrix)K_s.getValue());
final K k = new K(primitiveK_s);
final SDPAM sdpam = convertToSedumi(sedumiA, sedumib, sedumic, k);
try {
sdpam.save(datFile);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* NFCの {@link DoubleMatrix}をJavaのプリミティブ配列に変換します。
*
* @param matrix 変換する行列
* @return int型配列
*/
private int[] toIntArray(DoubleMatrix matrix) {
final int[] data = new int[matrix.getRowSize() * matrix.getColumnSize()];
for (int i = 0; i < data.length; i++) {
data[i] = (int)matrix.getDoubleElement(i + 1);
}
return data;
}
/**
* Sedumi形式の引数からYALMIPで扱うSedumi形式を生成します。
*
* @param A A
* @param b b
* @param c c
* @param k K
* @return SDPAMのインスタンスを返します
*/
public SDPAM convertToSedumi(DoubleMatrix A, DoubleMatrix b, DoubleMatrix c, K k) {
double[][] F = new double[A.getRowSize()][A.getColumnSize() + c.getColumnSize()];
for (int i = 0; i < 1; i++) {
for (int j = 0; j < A.getRowSize(); j++) {
F[j][i] = c.getElement(j + 1, i + 1).doubleValue();
}
}
for (int i = 0; i < A.getColumnSize(); i++) {
for (int j = 0; j < A.getRowSize(); j++) {
F[j][i + 1] = -A.getElement(j + 1, i + 1).doubleValue();
}
}
double[] d = new double[b.getRowSize()];
for (int i = 0; i < b.getRowSize(); i++) {
d[i] = -b.getElement(i + 1).doubleValue();
}
Sedumi2Sdpa sedumi = new Sedumi2Sdpa();
return sedumi.convertToSDPAM(F, d, k);
}
/**
* ASCIIコードのファイルからMMファイルを生成します
*
* @param AFile A
* @param bFile b
* @param cFile c
* @param KsFile Ks
* @param mmFile mmFile
*/
public void convertAsciiToMM(String AFile, String bFile, String cFile, String KsFile, String mmFile) {
try (PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(new File(mmFile))))) {
pw.print("A=["); //$NON-NLS-1$
String str1;
try (BufferedReader br1 = new BufferedReader(new FileReader(AFile))) {
while ((str1 = br1.readLine()) != null) {
str1 = str1.trim();
str1 = str1.replace(" -", ",-"); //$NON-NLS-1$ //$NON-NLS-2$
pw.println("[" + str1 + "]"); //$NON-NLS-1$ //$NON-NLS-2$
}
pw.println("];"); //$NON-NLS-1$
br1.close();
}
pw.print("b=["); //$NON-NLS-1$
String str2;
try (BufferedReader br2 = new BufferedReader(new FileReader(bFile))) {
while ((str2 = br2.readLine()) != null) {
str2 = str2.trim();
str2 = str2.replace(" ", ","); //$NON-NLS-1$ //$NON-NLS-2$
pw.println("[" + str2 + "]"); //$NON-NLS-1$ //$NON-NLS-2$
}
pw.println("];"); //$NON-NLS-1$
br2.close();
}
pw.print("c=["); //$NON-NLS-1$
String str3;
try (BufferedReader br3 = new BufferedReader(new FileReader(cFile))) {
while ((str3 = br3.readLine()) != null) {
str3 = str3.trim();
str3 = str3.replace(" ", ","); //$NON-NLS-1$ //$NON-NLS-2$
pw.println("[" + str3 + "]"); //$NON-NLS-1$ //$NON-NLS-2$
}
pw.println("];"); //$NON-NLS-1$
br3.close();
}
pw.print("K_s=["); //$NON-NLS-1$
String str4;
try (BufferedReader br4 = new BufferedReader(new FileReader(KsFile))) {
while ((str4 = br4.readLine()) != null) {
str4 = str4.trim();
str4 = str4.replaceAll(" ", ","); //$NON-NLS-1$ //$NON-NLS-2$
pw.println("[" + str4 + "]"); //$NON-NLS-1$ //$NON-NLS-2$
}
pw.println("];"); //$NON-NLS-1$
br4.close();
}
pw.close();
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* ASCII形式で保存されているファイルからMファイルを生成するメソッドです
*
* @param AFile A
* @param bFile b
* @param cFile c
* @param KsFile Ks
* @param mFile mFile
*/
public void convertAsciiToM(String AFile, String bFile, String cFile, String KsFile, String mFile) {
try (PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(new File(mFile))))) {
pw.print("A=["); //$NON-NLS-1$
String str1;
try (BufferedReader br1 = new BufferedReader(new FileReader(AFile))) {
while ((str1 = br1.readLine()) != null) {
pw.print(str1 + ";"); //$NON-NLS-1$
}
pw.println("]"); //$NON-NLS-1$
br1.close();
}
pw.print("b=["); //$NON-NLS-1$
String str2;
try (BufferedReader br2 = new BufferedReader(new FileReader(bFile))) {
while ((str2 = br2.readLine()) != null) {
pw.print(str2 + ";"); //$NON-NLS-1$
}
pw.println("]"); //$NON-NLS-1$
br2.close();
}
pw.print("c=["); //$NON-NLS-1$
String str3;
try (BufferedReader br3 = new BufferedReader(new FileReader(cFile))) {
while ((str3 = br3.readLine()) != null) {
pw.print(str3 + ";"); //$NON-NLS-1$
}
pw.println("]"); //$NON-NLS-1$
br3.close();
}
pw.print("K_s=["); //$NON-NLS-1$
String str4;
try (BufferedReader br4 = new BufferedReader(new FileReader(KsFile))) {
while ((str4 = br4.readLine()) != null) {
pw.print(str4 + ";"); //$NON-NLS-1$
}
pw.println("]"); //$NON-NLS-1$
br4.close();
}
pw.close();
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* MファイルをMMファイルに変換するメソッドです。
*
* @param mFile Mファイル
* @param mmFile MMファイル
*/
public void convertToMM(String mFile, String mmFile) {
try (BufferedReader br = new BufferedReader(new FileReader(mFile)); PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(new File(mmFile))))) {
String str;
String matxCode = ""; //$NON-NLS-1$
while ((str = br.readLine()) != null) {
String[] params = str.split("="); //$NON-NLS-1$
matxCode = params[0] + " = "; //$NON-NLS-1$
if (params[1].trim().startsWith("-")) { //$NON-NLS-1$
String temp = params[1].trim().substring(1, params[1].length());
matxCode += "-" + Matrix.convertMatX(temp) + ";"; //$NON-NLS-1$ //$NON-NLS-2$
} else {
matxCode += Matrix.convertMatX(params[1].trim()) + ";"; //$NON-NLS-1$
}
pw.println(matxCode);
}
pw.close();
br.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* メインメソッドです。
*
* @param args コマンドライン引数
*/
public static void main(String[] args) {
Sedumi sedumi = new Sedumi();
String dir2 = "1"; //$NON-NLS-1$
String dir = "SDPLIB_ASCII/hinf" + dir2; //$NON-NLS-1$
String AFile = dir + "/A.txt"; //$NON-NLS-1$
String bFile = dir + "/b.txt"; //$NON-NLS-1$
String cFile = dir + "/c.txt"; //$NON-NLS-1$
String KsFile = dir + "/Ks.txt"; //$NON-NLS-1$
String mmFile = "hinf10.mm"; //$NON-NLS-1$
String datFile = "hinf" + dir2 + "sedumi.dat-s"; //$NON-NLS-1$ //$NON-NLS-2$
sedumi.convertAsciiToMM(AFile, bFile, cFile, KsFile, mmFile);
System.out.println(datFile + "を生成中です。"); //$NON-NLS-1$
sedumi.SedumiLoad(mmFile, datFile);
System.out.println("ファイルが生成されました。"); //$NON-NLS-1$
}
}