DoubleMaxima.java
/*
* Created on 2008/01/28
* Copyright (C) 2008 Koga Laboratory. All rights reserved.
*
*/
package org.mklab.tool.control.system.rpn;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import org.mklab.nfc.matrix.DoubleMatrix;
import org.mklab.nfc.rpn.ReversePolishNotationOperator;
import org.mklab.nfc.rpn.ReversePolishNotationSymbol;
import org.mklab.nfc.scalar.DoubleNumber;
import org.mklab.tool.control.system.DoubleSystemOperator;
import org.mklab.tool.control.system.math.DoubleConstantSystem;
import org.mklab.tool.control.system.math.DoubleNegativeUnitSystem;
import org.mklab.tool.control.system.math.DoubleUnitSystem;
/**
* Maximaエンジンを呼び出すクラスです。
*
* @author Anan
* @version $Revision: 1.9 $, 2008/01/28
*/
public class DoubleMaxima {
/** lineSeparator */
private static final String lineSeparator = System.getProperty("line.separator"); //$NON-NLS-1$
/** variableList */
// private static final List<ConstantSystem> variableList = new
// ArrayList<ConstantSystem>();
private static final List<String> variableList = new ArrayList<>();
/** process */
private Process process = null;
/** writer */
private PrintWriter writer = null;
/** reader */
private BufferedReader reader = null;
/**
* ConstantSystemからMaxima用のMatrixを作ります。
*
* @param system 対象となるシステム
* @return Maxima用に変換されたMatrix
*/
private static String createMatrixFromConstantSystem(final DoubleConstantSystem system) {
String variable = system.getExpression();
variable = variable.replaceAll("/", "division"); //$NON-NLS-1$ //$NON-NLS-2$
return (variable + ":" + getMatrixString(system.getD())); //$NON-NLS-1$
}
/**
* MatrixからMaxima用のMatrixを作ります。
*
* @param matrix 対象となる行列
* @return Maxima用に変換されたMatrix
*/
private static String getMatrixString(final DoubleMatrix matrix) {
final StringBuilder str = new StringBuilder();
str.append("matrix("); //$NON-NLS-1$
for (int i = 1; i < matrix.getRowSize() + 1; i++) {
str.append("["); //$NON-NLS-1$
for (int j = 1; j < matrix.getColumnSize() + 1; j++) {
// if (matrix instanceof IntMatrix) {
// str.append((((IntMatrix)matrix).getIntElement(i, j)));
// } else {
str.append((matrix.getElement(i, j)));
// }
if ((j >= matrix.getColumnSize()) == false) {
str.append(","); //$NON-NLS-1$
}
}
str.append("]"); //$NON-NLS-1$
if ((i >= matrix.getRowSize()) == false) {
str.append(","); //$NON-NLS-1$
}
}
str.append(");" + lineSeparator); //$NON-NLS-1$
return str.toString();
}
/**
* Maximaを起動し引数に渡されたコマンドを実行します。
*
* @throws IOException 出力できない場合
*/
public void open() throws IOException {
final String maximaHome = System.getenv("MAXIMA_HOME"); //$NON-NLS-1$
final String command = "\"" + maximaHome + "\\" + "maxima.bat\" --very-quiet --disable-readline"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
this.process = Runtime.getRuntime().exec(command);
this.writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(this.process.getOutputStream())));
this.reader = new BufferedReader(new InputStreamReader(this.process.getInputStream()));
initialize();
}
/**
* Maximaにコマンドを送ります。
*
* @param comands コマンド
*/
public void sendComand(final StringBuilder comands) {
this.writer.print(comands.toString() + lineSeparator);
this.writer.flush();
}
/**
* Maximaに終了処理コマンドを送ります。
*/
private void terminate() {
this.writer.print("quit();" + lineSeparator); //$NON-NLS-1$
this.writer.flush();
}
/**
* Maximaに初期化コマンドを送ります。
*/
private void initialize() {
this.writer.print("ttyoff:true;" + lineSeparator); //$NON-NLS-1$
this.writer.flush();
this.writer.print("ratprint:false;" + lineSeparator); //$NON-NLS-1$
this.writer.flush();
this.writer.print("display2d:false;" + lineSeparator); //$NON-NLS-1$
this.writer.flush();
this.writer.print("scalarmatrixp:all;" + lineSeparator); //$NON-NLS-1$
this.writer.flush();
this.writer.print("linel:200;" + lineSeparator); //$NON-NLS-1$
this.writer.flush();
this.writer.print("doallmxops:false;" + lineSeparator); //$NON-NLS-1$
this.writer.flush();
}
/**
* Maximaからの結果を受け取ります。
*
* @return 実行結果
* @throws IOException 入力できない場合
*/
public String receiveResult() throws IOException {
this.reader.readLine();
final String result = this.reader.readLine();
// String resultMatrix = "";
// while (true) {
// String result = this.reader.readLine();
// if (result == null) break;
// resultMatrix = result;
System.out.println(result);
// }
// System.out.println(resultMatrix);
close();
return result;
}
/**
* Maximaを終了します。
*
* @throws IOException 入力を閉じれない場合
*/
private void close() throws IOException {
terminate();
this.writer.close();
this.reader.close();
this.process.destroy();
variableList.clear();
}
/**
* systemの定数システムの宣言をMaxima用に生成します。
*
* @param system システム
* @return systemの定数システムの変数宣言
*/
public static StringBuilder getDeclearOfSystems(final DoubleSystemOperator system) {
final StringBuilder systemsDeclear = new StringBuilder();
final DoubleConstantSystem constantSystem = (DoubleConstantSystem)system;
for (ReversePolishNotationSymbol<DoubleNumber,DoubleMatrix> sys : constantSystem.getSymbolStack()) {
if (sys instanceof ReversePolishNotationOperator) {
continue;
}
if (((DoubleConstantSystem)sys).getExpression() == "" && (((DoubleConstantSystem)sys).getSymbolStack().size() >= 2)) { //$NON-NLS-1$
systemsDeclear.append(DoubleMaxima.getDeclearOfSystems((DoubleSystemOperator)sys));
} else {
if ((variableList.contains(sys.getStringOfSymbol())) == false) {
if (((DoubleConstantSystem)sys).isVariable()) {
// variableList.add((DoubleConstantSystem)sys);
variableList.add(sys.getStringOfSymbol());
continue;
}
if (sys instanceof DoubleNegativeUnitSystem) {
continue;
}
if (sys instanceof DoubleUnitSystem) {
systemsDeclear.append("I:ident(" + ((DoubleConstantSystem)sys).getD().getColumnSize() + ");" + lineSeparator); //$NON-NLS-1$ //$NON-NLS-2$
} else {
systemsDeclear.append(DoubleMaxima.createMatrixFromConstantSystem((DoubleConstantSystem)sys));
}
// variableList.add((DoubleConstantSystem)sys);
variableList.add(sys.getStringOfSymbol());
}
}
}
return systemsDeclear;
}
}