File: ApproxMemoMatrix.java

package info (click to toggle)
libsecondstring-java 0.1~dfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 764 kB
  • sloc: java: 9,592; xml: 114; makefile: 6
file content (142 lines) | stat: -rwxr-xr-x 4,328 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package com.wcohen.ss;

import com.wcohen.ss.api.*;

import org.apache.log4j.Logger;

/** 
 * Variant of MemoMatrix that only stores values near the diagonal,
 * for better efficiency.
 */

// to do: export scale, loJNearDiag(i), hiJNearDiag(i)
//

public abstract class ApproxMemoMatrix extends MemoMatrix
{
    private static Logger log=Logger.getLogger(ApproxMemoMatrix.class);

    // explicitly stored values
    private double[][] valuesNearDiagonal;
    private boolean[][] wasComputed;
    // value used for entries not explicitly stored
    private double defaultValue;   

    //
    // these define which values are explicitly stored
    //

    // since the matrix is not necessarily square, the 'diagonal'
    // entry for i is not i, but i*scale.
    private double scale; 

    // store m[i,i*scale-width] thru store m[i,i*scale+width] 
    private int width;  

    ApproxMemoMatrix(StringWrapper s,StringWrapper t,int width,double defaultValue) 
    {
        super(new BasicStringWrapper(""),new BasicStringWrapper(""));
        this.s = s;
        this.t = t;
        this.valuesNearDiagonal = new double[s.length()+1][2*width];
        this.wasComputed = new boolean[s.length()+1][2*width];
        this.defaultValue = defaultValue;
        this.width = width;
        this.scale = (t.length()+1.0)/(s.length()+1.0);
    }
	
    private int offsetFromDiagonal(int i,int j)
    {
        int diagForI = (int)Math.round( i*scale );
        int k = diagForI-j + width;
        return k;
    }
    private boolean nearDiagonal(int k)
    {
        return k>=1 && k<2*width;
    }

    double get(int i,int j) 
    {
        // value for i,j is stored in valuesNearDiagonal[i][k]
        int k = offsetFromDiagonal(i,j);
        if (!nearDiagonal(k)) {
            return defaultValue;
        } else if (wasComputed[i][k]) {
            return valuesNearDiagonal[i][k];
        } else {
            valuesNearDiagonal[i][k] = compute(i,j);
            wasComputed[i][k] = true;
            return valuesNearDiagonal[i][k];
        }
    }

    public boolean outOfRange(int i, int j)
    {
        boolean out = i<1 || i>s.length() || j<1 || j>t.length();
        if (out) log.error("out of range: |s|="+s.length()+" |t|="+t.length()+" s = '"+s+"' t="+t+"'");
        return out;
    }


    //
    // low-level access to the stored part of the matrix
    //

    int getWidth() { return width; }

    double getScale() { return scale; }

    int getFirstStoredEntryInRow(int i) 
    { 
        int diagForI = (int)Math.round( i*scale );
        return Math.max(1, (diagForI - width));
    }

    int getLastStoredEntryInRow(int i) 
    { 
        int diagForI = (int)Math.round( i*scale );
        return Math.min(t.length(), (diagForI + width));
    }


    /** Print the matrix, for debugging and/or explanation. */
    public String toString() 
    {
        PrintfFormat fmt = new PrintfFormat(cellFormat);
        StringBuffer buf = new StringBuffer();
        // line 1 - a ruler
        buf.append("   ");  buf.append("   ");
        for (int i=1; i<=s.length(); i++) buf.append(fmt.sprintf((double)i));
        buf.append("\n");
        // line 2 - the string
        buf.append("   "); buf.append("   ");
        for (int i=1; i<=s.length(); i++) buf.append(" "+trapNewline(sAt(i))+" ");
        buf.append("\n");
        // line 2 - an hrule
        buf.append("   "); buf.append("   ");
        for (int i=1; i<=s.length(); i++) buf.append("---");
        buf.append("\n");
        // remaining lines
        for (int j=1; j<=t.length(); j++) {
            buf.append(fmt.sprintf((double)j));
	    buf.append(" "+trapNewline(tAt(j))+"|");
	    for (int i=1; i<=s.length(); i++) {
                if (!nearDiagonal(offsetFromDiagonal(i,j)) || defaultValue==get(i,j)) {
                    buf.append(" * ");
                } else {
                    double v = printNegativeValues ? -get(i,j) : get(i,j);
                    buf.append(fmt.sprintf(v));
                }
	    }
	    buf.append("\n");
        }
        return buf.toString();
    }
    private char trapNewline(char ch)
    {
        return Character.isWhitespace(ch) ? ' ' : ch;
    }
}