/* $Id: DTWCalculatorType1.java 125 2011-03-09 09:49:51Z ohura $ */
/*
 * 作成日： 2006/10/30
 */
package jp.ac.hokudai.meme.core_smart_gs.searcher;

public class DTWCalculatorType1 extends AbstractDTWCalculator {

    public DistanceAndIndex calcDTWDist(int startIndex, int endIndex, double[][] pattern, double[][] dtwArray) {
        int textLength = endIndex - startIndex + 1;
        int patLength = pattern.length;

        initDTWArray(dtwArray, startIndex);
        initDTWArrayLocal(dtwArray, startIndex);
        double diag = 0, left = 0, down = 0;
        double d1 = 0, d2 = 0, d3 = 0;
        for (int i = 2; i < patLength; i++) {
            for (int j = 2; j < textLength; j++) {

//                diag = getDist(pattern[i], text[j]);
//                left = getDist(pattern[i], text[j - 1]);
//                down = getDist(pattern[i - 1], text[j]);
                
                diag = getDist(startIndex + j, i);
                left = getDist(startIndex + j - 1, i);
                down = getDist(startIndex + j, i - 1);
                d1 = dtwArray[i - 2][j - 1] + (2.0d * left) + diag;
                d2 = dtwArray[i - 1][j - 1] + 2.0d * diag;
                d3 = dtwArray[i - 1][j - 2] + (2.0d * down) + diag;
                dtwArray[i][j] = min(d1, d2, d3);
            }
        }
        double minDist = Double.POSITIVE_INFINITY;
        int resEndIndex = 0;
        for (int i = 0; i < textLength; i++) {
            if (dtwArray[patLength - 1][i] < minDist) {
                minDist = dtwArray[patLength - 1][i];
                resEndIndex = startIndex + i;
            }

        }
        return new DistanceAndIndex(minDist, startIndex, resEndIndex);
    }

    private void  initDTWArrayLocal(double[][] dtwArray, int startIndex) {
        for (int i = 1; i < dtwArray.length; i++) {
            dtwArray[i][0] = Double.POSITIVE_INFINITY;
        }
        for (int i = 1; i < dtwArray[0].length; i++) {
            dtwArray[0][i] = Double.POSITIVE_INFINITY;
        }
        for (int i = 1; i < dtwArray.length; i++) {
            dtwArray[i][1] = Double.POSITIVE_INFINITY;
        }
        for (int i = 1; i < dtwArray[0].length; i++) {
            dtwArray[1][i] = Double.POSITIVE_INFINITY;
        }
        dtwArray[1][1] = dtwArray[0][0] + 2 * getDist(startIndex + 1, 1);
        dtwArray[1][2] = dtwArray[1][1] + getDist(startIndex + 1, 2);
        dtwArray[2][1] = dtwArray[1][1] + getDist(startIndex + 2, 1);
        

    }

    /**
     * <p>
     * </p>
     * 
     * @param args
     */
    public static void main(String[] args) {
        // TODO 自動生成されたメソッド・スタブ

    }

}
