* @param data данные для анализа
*/
public static void singularDecomposition(SSAData data) {
double inclosureMatrix[][] = data.getInclosureMatrix();
double transp[][] = transpositionMatrix(inclosureMatrix);
Matrix S = new Matrix(inclosureMatrix).times(new Matrix(transp));
//int d = new Matrix(inclosureMatrix).rank(); //ранг матрицы вложений
EigenvalueDecomposition decomposition = new EigenvalueDecomposition(S);
Matrix eigenvalue = decomposition.getD(); //матрица с собственными значениями
Matrix eigenvec = decomposition.getV(); //матрица собственных векторов
List<Double> eigenvalueList = new ArrayList<Double>();
//формируем набор собственных значений, стоящих на диагонали
for (int i = 0; i < eigenvalue.getRowDimension(); i++) {
for (int j = 0; j < eigenvalue.getRowDimension(); j++) {
if (i == j) {
eigenvalueList.add(eigenvalue.get(i, j));
}
}
}
Comparator comparator = Collections.reverseOrder();
/*
* собственные значения должны быть в убывающем порядке, поэтому
* сортируем их в обратном порядке (изначально значения в возрастающем
* порядке)
*/
Collections.sort(eigenvalueList, comparator);
data.setEigenValueList(eigenvalueList);
double sumValueList = 0;
List<Double> percentList;
List<Double> accruePercentList;
for (int i = 0; i < data.getEigenValueList().size(); i++) {
sumValueList = sumValueList + data.getEigenValueList().get(i);
}
//формирование процентов собственных чисел и накопленных процентов
percentList = new ArrayList<Double>();
accruePercentList = new ArrayList<Double>();
double accruePercent = 0;
for (int i = 0; i < data.getEigenValueList().size(); i++) {
percentList.add(data.getEigenValueList().get(i) / sumValueList * 100);
accruePercent += percentList.get(i);
accruePercentList.add(accruePercent);
}
data.setAccruePercentList(accruePercentList);
data.setPercentList(percentList);
int size = eigenvec.getColumnDimension();
Matrix V[] = new Matrix[size];
Matrix U[] = new Matrix[size];
Matrix X[] = new Matrix[size]; //элементарные матрицы сингулярного разложения
ArrayList listSeries = new ArrayList();
for (int j = 0; j < eigenvec.getColumnDimension(); j++) {
double uVec[][] = new double[size][1];
ArrayList series = new ArrayList();
for (int k = 0; k < eigenvec.getRowDimension(); k++) {
/*
* векторы должны соответствовать собственным числа (!), поэтому
* начинаем с последнего собственного вектора
*/
uVec[k][0] = eigenvec.get(k, eigenvec.getColumnDimension() - j - 1);
series.add(uVec[k][0]);
}
listSeries.add(series);
U[j] = new Matrix(uVec);
V[j] = new Matrix(transp).times(U[j]);
}
data.setEigenVectors(listSeries);
for (int i = 0; i < V.length; i++) {
for (int j = 0; j < V[i].getRowDimension(); j++) {
for (int k = 0; k < V[i].getColumnDimension(); k++) {