001 package calhoun.util;
002
003 import java.io.BufferedWriter;
004 import java.io.FileWriter;
005 import java.io.IOException;
006 import java.io.Writer;
007
008 import cern.colt.function.DoubleFunction;
009 import cern.colt.matrix.DoubleMatrix2D;
010 import cern.colt.matrix.impl.DenseDoubleMatrix2D;
011 import cern.colt.matrix.linalg.EigenvalueDecomposition;
012
013 public class ColtUtil {
014
015 public static void exponentiate_real_matrix(DoubleMatrix2D X, DoubleMatrix2D Y, int degree)
016 // Sets Y to equal exp(X); X is assumed to be real.
017 // Y can be expressed as a convergent power series in X:
018 // Y = I + X + X*X/2 + X*X*X/6 + X*X*X*X/24 + ...
019 // the power series is truncated after the X^(degree) term.
020 // Since X is real and each term above is real, Y is also real.
021 // An eigenvector of X with eigenvalue lambda is an eigenvector of Y with eigenvalue exp(lambda)
022 {
023 // S is a reall symmetric matrix, so it has real eigenvalues.
024 /*
025 EigenvalueDecomposition E = new EigenvalueDecomposition(X);
026
027 Assert.a(degree >= 1);
028
029 // A = V*D*V'
030 DoubleMatrix2D V = E.getV();
031 DoubleMatrix2D D = E.getD();
032
033 System.out.println("The matrix D is: ");
034 System.out.println(ColtUtil.format(D));
035 System.out.println("The matrix V is: ");
036 System.out.println(ColtUtil.format(V));
037
038 System.out.println("Real eigenvalues D is: ");
039 System.out.println(ColtUtil.format(E.getRealEigenvalues().toArray()));
040 System.out.println("Imaginary eigenvalues D is: ");
041 System.out.println(ColtUtil.format(E.getImagEigenvalues().toArray()));
042 */
043 /*
044 for (int i=0; i<4; i++) {
045 // only the diagonal entries:
046 D.setQuick(i,i,Math.exp(D.getQuick(i,i)));
047 }
048 */
049 /*
050 System.out.println("After exponentiating diagonal, The matrix D is: ");
051 System.out.println(ColtUtil.format(D));
052
053 DoubleMatrix2D B = new DenseDoubleMatrix2D(4,4); B.assign(0);
054 V.zMult(D,B); // B=V*D;
055
056 B.zMult(V,Y,1.0,0.0,false,true); // Y = 1.0*B*V' + 0.0*Y;
057 */
058
059 //ColtMatrix Z;
060
061 DenseDoubleMatrix2D EYE = new DenseDoubleMatrix2D(4,4);
062 EYE.assign(0.0); for (int i=0; i<4; i++) { EYE.setQuick(i,i,1.0); } // Intially sets Y to the identity matrix;
063 Y.assign(EYE);
064 DenseDoubleMatrix2D Z = new DenseDoubleMatrix2D(4,4); Z.assign(EYE);
065 DenseDoubleMatrix2D W = new DenseDoubleMatrix2D(4,4);
066 for (int j=1; j<=degree; j++) {
067 W.assign(Z);
068 W.zMult(X,Z,1.0/((double) j),0.0,false,false); // Z = (1/j)*W*X + 0*Z = X^j/j!
069 Z.zMult(EYE,Y,1.0,1.0,false,true); // Y = Z*I + Y = Z+Y = Y+X^j/j!
070 }
071
072 //Y = ((ColtMatrix) X).exponential(200);
073
074 /*public DoubleMatrix2D zMult(DoubleMatrix2D B,
075 DoubleMatrix2D C,
076 double alpha,
077 double beta,
078 boolean transposeA,
079 boolean transposeB)
080 Linear algebraic matrix-matrix multiplication; C = alpha * A x B + beta*C. C[i,j] = alpha*Sum(A[i,k] * B[k,j]) + beta*C[i,j], k=0..n-1.
081 Matrix shapes: A(m x n), B(n x p), C(m x p).
082 Note: Matrix shape conformance is checked after potential transpositions.
083 */
084
085 return;
086 }
087
088
089 public static void exponentiate_symmetric_matrix(DoubleMatrix2D X, DoubleMatrix2D Y)
090 // Sets Y to equal exp(X); X is assumed to be real and symmetric.
091 {
092 // S is a reall symmetric matrix, so it has real eigenvalues.
093 EigenvalueDecomposition E = new EigenvalueDecomposition(X);
094
095 // A = V*D*V'
096 DoubleMatrix2D V = E.getV();
097 DoubleMatrix2D D = E.getD();
098
099 for (int i=0; i<4; i++) {
100 // only the diagonal entries:
101 D.setQuick(i,i,Math.exp(D.getQuick(i,i)));
102 }
103
104 DoubleMatrix2D B = new DenseDoubleMatrix2D(4,4); B.assign(0);
105 V.zMult(D,B); // B=V*D;
106
107 B.zMult(V,Y,1.0,0.0,false,true); // Y = 1.0*B*V' + 0.0*Y;
108
109 return;
110 }
111
112 public static double dotProduct(double[] a, double[] b) {
113 int length = a.length;
114 Assert.a(a.length == b.length, length, " length array dotted with array of length ", b.length);
115 double ret = 0.0;
116 for(int i=0; i<length; ++i) {
117 ret += a[i]*b[i];
118 }
119 return ret;
120 }
121
122 public static String format(double[] str) {
123 StringBuffer b = new StringBuffer();
124 for (double d : str) {
125 b.append(String.format("%e, ", d));
126 }
127 if(b.length() > 2) {
128 b.setLength(b.length() - 2);
129 }
130 return b.toString();
131 }
132
133 public static void printToFile(double[] str, int numRows, int numCols) {
134 try {
135 Writer fout = new BufferedWriter(new FileWriter("test/working/crf_forwardPass_60kTEST.txt"));
136
137 fout.write("Viterbi Map from CRF Forward Pass\n");
138 fout.write("\n");
139 fout.write("\t");
140 for (int r=0; r<numRows; r++)
141 fout.write(String.format("%1$11d", r));
142 fout.write("\n\n");
143
144 for (int c=0; c<numCols; c++)
145 {
146 fout.write(c + ")\t");
147 for (int r=0; r<numRows; r++)
148 {
149 double val = str[numRows * c + r];
150 if (Double.isInfinite(val))
151 fout.write(String.format("%1$11.0f", 0.0f));
152 else
153 //fout.write(String.format("%e\t", bestScores[pos][st], 2));
154 fout.write(String.format("%1$11.2f", val));
155 }
156 fout.write("\n");
157 }
158 fout.close();
159
160 } catch (IOException e) {
161 // TODO Auto-generated catch block
162 e.printStackTrace();
163 }
164 }
165
166 public static void print(double[] str, int numRows, int numCols) {
167 System.out.print("\n");
168 for (int r=0; r<numRows; r++)
169 {
170 for (int c=0; c<numCols; c++)
171 {
172 double val = str[numRows * c + r];
173 if (Double.isInfinite(val))
174 val = 0.0;
175 System.out.print(String.format("%e\t", val));
176 }
177 System.out.print("\n");
178 }
179 }
180
181 public static void print(int[] str, int numRows, int numCols) {
182 System.out.print("\n");
183 for (int r=0; r<numRows; r++)
184 {
185 for (int c=0; c<numCols; c++)
186 {
187 System.out.print(String.format("%d\t", str[numRows * c + r]));
188 }
189 System.out.print("\n");
190 }
191 }
192
193 public static double norm(double ar[]) {
194 double v = 0;
195 for (int f = 0; f < ar.length; f++)
196 v += ar[f]*ar[f];
197 return Math.sqrt(v);
198 }
199
200 public static String format(DoubleMatrix2D mi) {
201 StringBuffer b = new StringBuffer();
202 for (int i = 0; i < mi.rows(); ++i) {
203 for (int j = 0; j < mi.columns(); ++j) {
204 b.append(String.format("%e, ", mi.getQuick(i, j)));
205 }
206 b.setLength(b.length() - 2);
207 b.append("; ");
208 }
209 return b.toString();
210 }
211
212 /** Returns the row with the largest value in the given column */
213 public static int maxInColumn(DoubleMatrix2D m, int col) {
214 double max = Double.NEGATIVE_INFINITY;
215 int bestRow = -1;
216 for(int j = 0; j<m.rows(); ++j) {
217 double current = m.getQuick(j, col);
218 if(current > max) {
219 max = current;
220 bestRow = j;
221 }
222 }
223 Assert.a(bestRow != -1);
224 return bestRow;
225 }
226
227 public static int maxInColumn(double[] m, int numRows, int col) {
228 double max = Double.NEGATIVE_INFINITY;
229 int bestRow = -1;
230 int offset = col*numRows;
231 for(int j = 0; j<numRows; ++j) {
232 double current = m[offset + j];
233 if(current > max) {
234 max = current;
235 bestRow = j;
236 }
237 }
238 Assert.a(bestRow != -1);
239 return bestRow;
240 }
241
242 public static double maxValueInColumn(double[] m, int numRows, int col) {
243 double max = Double.NEGATIVE_INFINITY;
244 int offset = col*numRows;
245 for(int j = 0; j<numRows; ++j) {
246 double current = m[offset + j];
247 if(current > max) {
248 max = current;
249 }
250 }
251 return max;
252 }
253
254 public static final DoubleFunction exp = new DoubleFunction() {
255 public double apply(double a) {
256 return Math.exp(a);
257 }
258 };
259 public static final DoubleFunction ln = new DoubleFunction() {
260 public double apply(double a) {
261 return Math.log(a);
262 }
263 };
264 public static void scalarmultiply(DoubleMatrix2D S, final double t) {
265 DoubleFunction mult = new DoubleFunction() {
266 public double apply(double a) {
267 return t*a;
268 }
269 };
270 S.assign(mult);
271 }
272
273 }