package photogrammetry.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import Jama.EigenvalueDecomposition;
import Jama.Matrix;
/**
* Wraps JAMA into vecmath matrices
*
* @author johannes
*/
public class MatrixUtils {
/**
* Compute eigenvectors and eigenvalues of a (symmetric) matrix.
*
* @param m the matrix to find the eigenvalues and eigenvectors of. All the
* eigenvalues must be real.
* @return eigenvalues and eigenvectors as column vectors
*/
public static Pair<double[], Matrix[]> eig(Matrix m) {
EigenvalueDecomposition ev = new EigenvalueDecomposition(m);
Pair<double[], Matrix[]> result = new Pair<>();
result.a = ev.getRealEigenvalues();
Matrix eigvs = ev.getV();
result.b = new Matrix[eigvs.getColumnDimension()];
double[] eigvsCols = eigvs.getColumnPackedCopy();
double[] oneColumn = new double[eigvs.getRowDimension()];
for (int i = 0; i < eigvs.getColumnDimension(); i++) {
System.arraycopy(eigvsCols, i * oneColumn.length, oneColumn, 0, oneColumn.length);
result.b[i] = new Matrix(oneColumn.length, 1);
for (int row = 0; row < oneColumn.length; row++) {
result.b[i].set(row, 0, oneColumn[row]);
}
}
return result;
}
/**
* <p>
* Load a matrix from a text file.
* </p>
* <p>
* The order of the numbers in the array is the same as the order in the
* text file.
* </p>
*
* @param file the file to load the matrix from
* @throws IOException
*/
public static double[] loadMatrix(File file) throws IOException {
return loadMatrix(file, ",");
}
/**
* <p>
* Load a matrix from a text file.
* </p>
* <p>
* The order of the numbers in the array is the same as the order in the
* text file.
* </p>
*
* @param file the file to load the matrix from
* @param separator the separator between columns
* @throws IOException
*/
public static double[] loadMatrix(File file, String separator) throws IOException {
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader(file));
String line;
List<String[]> lines = new ArrayList<>();
while ((line = in.readLine()) != null) {
lines.add(line.split(separator));
if (lines.get(lines.size() - 1).length != lines.get(0).length) {
throw new IOException("Invalid matrix!");
}
}
double[] result = new double[lines.size() * lines.get(0).length];
int k = 0;
for (String[] row : lines) {
for (int j = 0; j < row.length; j++) {
result[k++] = Double.valueOf(row[j].trim());
}
}
return result;
} finally {
if (in != null) {
in.close();
}
}
}
public static String matrixToString(Matrix m) {
StringBuilder result = new StringBuilder();
for (int row = 0; row < m.getRowDimension(); row++) {
for (int col = 0; col < m.getColumnDimension(); col++) {
result.append(String.format("%10.5f ", m.get(row, col)));
}
result.append("\n");
}
return result.toString();
}
}