Package caterpillarssa

Source Code of caterpillarssa.SpectrumAnalysis

package caterpillarssa;

import Jama.EigenvalueDecomposition;
import Jama.Matrix;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.swing.DefaultListModel;

/**
*
* @author Васькин Александр
*/
public class SpectrumAnalysis {

    /**
     * перевод исходного временного ряда в последовательность многомерных
     * векторов
     *
     * @param data данные для анализа
     */
    public static void inclosure(SSAData data) {
        int L = data.getL(); //длина окна
        int K = data.getTimeSeries().size() - L + 1; //количество векторов вложения
        double inclosureMatrix[][] = new double[L][K]; //траекторная матрица
        //формируем векторы вложения
        for (int i = 1; i <= K; i++) {
            int num = 0;
            for (int j = i - 1; j <= i + L - 2; j++) {
                inclosureMatrix[num][i - 1] = data.getTimeSeries().get(j);
                num++;
            }
        }
        data.setInclosureMatrix(inclosureMatrix);
    }

    /**
     * сингулярное разложение
     *
     * @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++) {
                    double val = V[i].get(j, k) / Math.sqrt(eigenvalueList.get(i));
                    V[i].set(j, k, val);
                }
            }
        }
        data.setV(V);
        for (int i = 0; i < X.length; i++) {
            X[i] = U[i].times(V[i].transpose());
            for (int j = 0; j < X[i].getRowDimension(); j++) {
                for (int k = 0; k < X[i].getColumnDimension(); k++) {
                    double val = X[i].get(j, k) * Math.sqrt(eigenvalueList.get(i));
                    X[i].set(j, k, val);
                }
            }
        }
        data.setX(X);
    }

    /**
     * восстановление временного ряда (этап группировки)
     *
     * @param model модель JList (список групп)
     * @param data данные для анализа
     */
    public static void grouping(DefaultListModel model, SSAData data) {
        Matrix grouX[] = new Matrix[model.getSize()];
        for (int i = 0; i < model.getSize(); i++) {
            GroupListObject obj = (GroupListObject) model.get(i);
            for (int j = 0; j < obj.getGroups().size(); j++) {
                UnselectListObject unselect = (UnselectListObject) obj.getGroups().get(j);
                if (j == 0) {
                    grouX[i] = data.getX()[unselect.getIndex()];
                } else {
                    grouX[i] = grouX[i].plus(data.getX()[unselect.getIndex()]);
                }
            }
        }
        data.setGroupX(grouX);
    }

    /**
     * восстановление временного ряда (этап диагонального усреднения)
     *
     * @param data данные для анализа
     */
    public static void diagonalAveraging(SSAData data) {
        int L;
        int K;
        int N;
        List<List> list = new ArrayList<List>();
        for (int i = 0; i < data.getGroupX().length; i++) {
            if (data.getGroupX()[i].getRowDimension() < data.getGroupX()[i].getColumnDimension()) {
                L = data.getGroupX()[i].getRowDimension();
                K = data.getGroupX()[i].getColumnDimension();
            } else {
                K = data.getGroupX()[i].getRowDimension();
                L = data.getGroupX()[i].getColumnDimension();
            }
            N = data.getGroupX()[i].getRowDimension() + data.getGroupX()[i].getColumnDimension() - 1;
            List series = new ArrayList();
            double element;
            for (int k = 0; k <= N - 1; k++) {
                element = 0;
                if (k >= 0 && k < L - 1) {
                    for (int m = 0; m <= k; m++) {
                        if (data.getGroupX()[i].getRowDimension() <= data.getGroupX()[i].getColumnDimension()) {
                            element += data.getGroupX()[i].get(m, k - m);
                        } else if (data.getGroupX()[i].getRowDimension() > data.getGroupX()[i].getColumnDimension()) {
                            element += data.getGroupX()[i].get(k - m, m);
                        }
                    }
                    element = element * (1.0 / (k + 1));
                    series.add(element);
                }
                if (k >= L - 1 && k < K - 1) {
                    for (int m = 0; m <= L - 2; m++) {
                        if (data.getGroupX()[i].getRowDimension() <= data.getGroupX()[i].getColumnDimension()) {
                            element += data.getGroupX()[i].get(m, k - m);
                        } else if (data.getGroupX()[i].getRowDimension() > data.getGroupX()[i].getColumnDimension()) {
                            element += data.getGroupX()[i].get(k - m, m);
                        }
                    }
                    element = element * (1.0 / L);
                    series.add(element);
                }
                if (k >= K - 1 && k < N) {
                    for (int m = k - K + 1; m <= N - K; m++) {
                        if (data.getGroupX()[i].getRowDimension() <= data.getGroupX()[i].getColumnDimension()) {
                            element += data.getGroupX()[i].get(m, k - m);
                        } else if (data.getGroupX()[i].getRowDimension() > data.getGroupX()[i].getColumnDimension()) {
                            element += data.getGroupX()[i].get(k - m, m);
                        }
                    }
                    element = element * (1.0 / (N - k));
                    series.add(element);
                }
            }
            list.add(series);
        }
        double sum;
        //суммируем полученные ряды и получаем исходный ряд
        List<Double> reconstructionList = new ArrayList<Double>();
        for (int j = 0; j < list.get(0).size(); j++) {
            sum = 0;
            for (int i = 0; i < list.size(); i++) {
                sum += (Double) list.get(i).get(j);
            }
            reconstructionList.add(sum);
        }
        data.setReconstructionList(reconstructionList);
    }

    /**
     * транспонирование матрицы
     *
     * @param matrix исходная матрица
     * @return результирующая матрица
     */
    private static double[][] transpositionMatrix(double matrix[][]) {
        double transpMatrix[][] = new double[matrix[0].length][matrix.length];
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++) {
                transpMatrix[j][i] = matrix[i][j];
            }
        }
        return transpMatrix;
    }

    /**
     * формирование скользящих средних
     *
     * @param data данные для анализа
     */
    public static void setMovingAvarege(SSAData data) {
        List<Double> SMA = new ArrayList<Double>();
        int m = data.getTimeSeries().size() - data.getL() + 1; //период осреднения
        for (int i = 0; i < data.getL(); i++) {
            double sum = 0;
            double avg = 0;
            for (int j = i; j < m + i; j++) {
                sum += data.getTimeSeries().get(j);
            }
            avg = sum / m;
            SMA.add(avg);
            data.setSMA(SMA);
        }
    }
   
    /**
     * диагональное осреднение ковариационной матрицы
     * (относительно побочной диагонали)
     *
     * @param data данные для анализа
     */
    public static void averagedCovariance(SSAData data) {
        double avg;
        double K = data.getTimeSeries().size() - data.getL() + 1; //количество векторов вложения
        List<Double> covarianceList = new ArrayList<Double>();
        double transp[][] = transpositionMatrix(data.getInclosureMatrix());
        Matrix S = new Matrix(data.getInclosureMatrix()).times(new Matrix(transp));
        S = S.times(1.0 / K); //ковариационная матрица
        int size = S.getColumnDimension();
        int N = size + size - 1;
        int n;
        for (int k = 0; k < N; k++) {
            if ((k % 2) == 0) {
                if (k >= 0 && k < size) {
                    avg = 0;
                    n = 0;
                    for (int m = 0; m <= k; m++) {
                        avg += S.get(m, size - 1 - (k - m));
                        n++;
                    }
                    avg = avg / (n);
                    covarianceList.add(avg);
                }
                if (k >= size && k < N) {
                    avg = 0;
                    n = 0;
                    for (int m = k - size + 1; m <= N - size; m++) {
                        avg += S.get(m, size - 1 - (k - m));
                        n++;
                    }
                    avg = avg / (n);
                    covarianceList.add(avg);
                }
            }
        }
        data.setCov(covarianceList);
    }

    /**
     * формирование функций собственных чисел
     *
     * @param data данные для анализа
     */
    public static void functionEigenValue(SSAData data) {
        List<Double> lgList = new ArrayList<Double>();
        List<Double> sqrtList = new ArrayList<Double>();
        for (int i = 0; i < data.getEigenValueList().size(); i++) {
            lgList.add((Double) Math.log(data.getEigenValueList().get(i)));
            sqrtList.add(Math.sqrt(data.getEigenValueList().get(i)));
        }
        data.setLgEigenValue(lgList);
        data.setSqrtEigenValue(sqrtList);
    }
   
}
TOP

Related Classes of caterpillarssa.SpectrumAnalysis

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.