IO.java
package org.mklab.sdpj.iocenter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Scanner;
import java.util.regex.MatchResult;
import java.util.regex.Pattern;
/**
* SDPJSolverの中からファイル読み込みをするときに使います。
*
* @author takafumi
*/
public class IO {
/** */
private final static String REALNUMBER = "([+-]?\\d+[.]?\\d*[e]?[E]?[+-]?[0-9]*)"; //$NON-NLS-1$
/** */
private final static String SPACE = "(\\p{Space}*)"; //$NON-NLS-1$
/** */
private final static String INTEGER = "([+-]?\\d+)"; //$NON-NLS-1$
/** */
private final static String NONUMBER = "[.&&[^0-9]&&[^+-]]*"; //$NON-NLS-1$
/** */
private final static String OTHERSTRING_REALNUMBER = NONUMBER + REALNUMBER;
/** */
private final static String OTHERSTRING_INTEGER = NONUMBER + INTEGER;
/**
* Read an integer from the string
*
* @param string a string
* @return value
*/
public static int readInteger(String string) {
try {
MatchResult result = scan(string, INTEGER);
return Integer.parseInt(result.group(1));
} catch (IllegalStateException e) {
throw new IllegalArgumentException(e);
}
}
/**
* 最初のコメントを削除 read m
*
* @param reader is a instance of class BufferedReader
* @param out is a instance of class PrintStream
* @return value
* @throws IOException if failure, IOException is thrown.
*/
public static int readInteger(BufferedReader reader, PrintStream out) throws IOException {
String string;
do {
string = reader.readLine();
if (string.charAt(0) == '*' || string.charAt(0) == '"') {
// out.printf("The description of file is : %s\n\n", string); //$NON-NLS-1$
continue;
}
break;
} while (true);
string = string.replaceAll(SPACE, ""); //$NON-NLS-1$
return readInteger(string);
}
/**
* "%*[^0-9+-]%d"
*
* @param reader Reader for string
* @return int data
*/
public static int readOtherStringInteger(StringBuffer reader) {
try {
MatchResult result = scan(reader.toString(), OTHERSTRING_INTEGER);
reader.delete(0, reader.indexOf(result.group(0)) + result.group(0).length());
return Integer.parseInt(result.group(1));
} catch (IllegalStateException e) {
throw new IllegalArgumentException(e);
}
}
/**
* pattetrnと照合してMatcherを返します
*
* @param string String to scan
* @param pattern Pattern for data
* @return data
* @throws IllegalStateException if failure
*/
private static MatchResult scan(String string, String pattern) throws IllegalStateException {
try (Scanner scanner = new Scanner(string)) {
scanner.findInLine(Pattern.compile(pattern));
MatchResult result = scanner.match();
return result;
}
}
/**
* @param reader is a instance of BufferedReader
* @param nBlock is the number of block
* @return integer array
* @throws IOException if failure, IOException is thrown
*/
public static int[] readBlockStruct(BufferedReader reader, int nBlock) throws IOException {
int[] blockStruct = new int[nBlock];
StringBuffer buffer = new StringBuffer(reader.readLine());
for (int i = 0; i < nBlock; ++i) {
blockStruct[i] = readOtherStringInteger(buffer);
if (blockStruct[i] == 1) {
blockStruct[i] = -1;
}
}
return blockStruct;
}
/**
* @param reader is a instance of StringBuffer
* @return real number
*/
public static String readOtherStringRealNumber(StringBuffer reader) {
try {
MatchResult result = scan(reader.toString(), OTHERSTRING_REALNUMBER);
reader.delete(0, reader.indexOf(result.group(0)) + result.group(0).length());
return result.group(1);
} catch (IllegalStateException e) {
throw new IllegalArgumentException(e);
}
}
/**
* @param string is a instance of StringBuffer
* @return real number
*/
public static String readOtherStringRealNumber(String string) {
try {
MatchResult result = scan(string, OTHERSTRING_REALNUMBER);
return result.group(1);
} catch (IllegalStateException e) {
throw new IllegalArgumentException(e);
}
}
/**
* @param reader is class BufferReader information
* @param dimension is the dimension of vector
* @return vector
* @throws IOException if reading is failure, IOException is thrown.
*/
public static String[] readVector(BufferedReader reader, int dimension) throws IOException {
String[] vector = new String[dimension];
StringBuffer buffer = new StringBuffer(reader.readLine());
for (int i = 0; i < dimension; i++) {
vector[i] = readOtherStringRealNumber(buffer);
}
return vector;
}
/**
* データ読み込み(SparseMatrix形式)
*
* @param reader is class BufferReader information
* @param m is the number of matrix block
* @param blockStruct is a matrix block information
* @return data of matrix block
* @throws IOException if reading file is failure, IOException is thrown.
*/
public static String[][] readSparseMatrix(BufferedReader reader, int m, int[] blockStruct) throws IOException {
int numberOfElements = getNumberOfElements(blockStruct);
String[][] data = new String[m + 1][numberOfElements];
for (int i = 0; i < m + 1; i++) {
for (int j = 0; j < numberOfElements; j++) {
data[i][j] = "0"; //$NON-NLS-1$
}
}
int[] blockSizes = getBlockSizes(blockStruct);
String line = ""; //$NON-NLS-1$
while ((line = reader.readLine()) != null) {
StringBuffer buffer = new StringBuffer(line);
int i = readOtherStringInteger(buffer);
int j = readOtherStringInteger(buffer);
int k = readOtherStringInteger(buffer);
int l = readOtherStringInteger(buffer);
String value = readOtherStringRealNumber(buffer);
if (k != l) {
data[i][sparseMatrixIndex(blockSizes, blockStruct, j, k, l)] = value;
data[i][sparseMatrixIndex(blockSizes, blockStruct, j, l, k)] = value;
} else {
data[i][sparseMatrixIndex(blockSizes, blockStruct, j, k, l)] = value;
}
}
return data;
}
/**
* @param blockStruct Structure of blocks
* @return Sizes of blocks
*/
private static int[] getBlockSizes(int[] blockStruct) {
int nBlock = blockStruct.length;
int[] blockSizes = new int[nBlock + 1];
int sum = 0;
blockSizes[0] = 0;
blockSizes[1] = 0;
for (int i = 2; i < nBlock + 1; i++) {
int blockSize = blockStruct[i - 2];
if (blockSize < 0) {
sum += -blockSize;
} else {
sum += blockSize * blockSize;
}
blockSizes[i] = sum;
}
return blockSizes;
}
/**
* @param blockSizes Sizes of blocks
* @param blockStruct Structure of blocks
* @param j j
* @param k k
* @param l l
* @return Index of sparse matrix
*/
private static int sparseMatrixIndex(int[] blockSizes, int[] blockStruct, int j, int k, int l) {
int index = 0;
index = blockSizes[j];
if (blockStruct[j - 1] < 0) {
index += (k - 1);//+(l-1);
} else {
index += (k - 1) * blockStruct[j - 1] + (l - 1);
}
return index;
}
/**
* データ読み込み(DenseMatrix形式)
*
* @param reader is class BufferedReader information
* @param m is the number of matrix
* @param blockStruct is a matrix block information
* @return data of matrix block
* @throws IOException is exception information
*/
public static String[][] readDenseMatrix(BufferedReader reader, int m, int[] blockStruct) throws IOException {
int numberOfElements = getNumberOfElements(blockStruct);
String[][] data = new String[m + 1][numberOfElements];
for (int i = 0; i < m + 1; i++) {
StringBuffer buffer = new StringBuffer(reader.readLine());
for (int j = 0; j < numberOfElements; j++) {
String value = readOtherStringRealNumber(buffer);
if (i == 0) {
value = unaryMinus(value);
}
data[i][j] = value;
}
}
return data;
}
/**
* 符号を反転した値を返します。
*
* @param value value
* @return sign opposite value
*/
private static String unaryMinus(String value) {
StringBuffer ans = new StringBuffer(value);
if (value.charAt(0) == '-') {
ans.delete(0, 1);
} else {
ans.insert(0, '-');
}
return ans.toString();
}
/**
* ブロックの成分の数の総和を返します。
*
* @param blockStruct ブロック構造
* @return ブロックの成分の数の総和
*/
private static int getNumberOfElements(int[] blockStruct) {
int sum = 0;
for (int i = 0; i < blockStruct.length; i++) {
if (blockStruct[i] < 0) {
sum += -blockStruct[i];
} else {
sum += blockStruct[i] * blockStruct[i];
}
}
return sum;
}
}