/* * PlayMatrix.java * Copyright (c) 2006 Sherman Visual Lab. All Rights Reserved. * Author : Sherman Wang * */ import java.lang.System; /** * This program is used to do some simple matrix-related computations. * The data are based on the LSI-SVD example in the book: * David A. Grossman and Ophir Frieder: Information Retrieval, Springer 2004, page 71-73 * The eingenvalues and eigenvectors are computed using online tool at: * http://www.bluebit.gr/matrix-calculator/ * The same example is discussed by Dr. E. Garcia at: * http://www.miislita.com/information-retrieval-tutorial/svd-lsi-tutorial-4-lsi-how-to-calculations.html */ public class PlayMatrix { static double[] query = {0,0,0,0,0,1,0,0,0,1,1}; static double[] doc1 = {1,0,1,0,1,1,1,1,1,0,0}; static double[] doc2 = {1,1,0,1,0,0,1,1,0,2,1}; static double[] doc3 = {1,1,0,0,0,1,1,1,1,0,1}; static double[][] A = { {1,1,1}, {0,1,1}, {1,0,0}, {0,1,0}, {1,0,0}, {1,0,1}, {1,1,1}, {1,1,1}, {1,0,1}, {0,2,0}, {0,1,1} }; static double[][] AT = { {1,0,1,0,1,1,1,1,1,0,0}, {1,1,0,1,0,0,1,1,0,2,1}, {1,1,0,0,0,1,1,1,1,0,1} }; static double newdoc3[][] = { {-0.4201, -0.2995, -0.1206, -0.1576, -0.1206, -0.2626, -0.4201, -0.4201, -0.2626, -0.3151, -0.2995}, {-0.0748, 0.2001, -0.2749, 0.3046, -0.2749, -0.3794, -0.0748, -0.0748, -0.3794, 0.6093, 0.2001}, {-0.0460, 0.4078, -0.4538, -0.2006, -0.4538, 0.1547, -0.0460, -0.0460, 0.1547, -0.4013, 0.4078} }; static double newdoc2[][] = { {-0.4201, -0.2995, -0.1206, -0.1576, -0.1206, -0.2626, -0.4201, -0.4201, -0.2626, -0.3151, -0.2995}, {-0.0748, 0.2001, -0.2749, 0.3046, -0.2749, -0.3794, -0.0748, -0.0748, -0.3794, 0.6093, 0.2001} }; static double newdocTrans[][] = null; static double sss3[] = {4.0989, 2.3616, 1.2737}; static double sss2[] = {4.0989, 2.3616}; public static double[][] devideMatrixByRow(double[][] in, double[] div){ double[][] out = null; int h = in.length; // then h = 11 int w = in[0].length; // then w = 3 out = new double[h][w]; // this is 11 x 3 double db = 0; for (int i = 0; i < h; i++){ for (int j = 0; j < w; j++){ db = in[i][j]/div[i]; out[i][j] = chopDecimalNumber(db, 4); } } return out; } public static double[][] transposeMatrix(double[][] in){ double[][] out = null; // if in is 3x11 int h = in.length; // then h = 3 int w = in[0].length; // then w = 11 out = new double[w][h]; // this is 11 x 3 double db = 0; for (int i = 0; i < h; i++){ for (int j = 0; j < w; j++){ db = in[i][j]; out[j][i] = chopDecimalNumber(db, 4); } } return out; } public static double[][] multiplyMatrix(double[][] max1, double[][] max2){ // if max1 is 3x11 int h1 = max1.length; // then h = 3 int w1 = max1[0].length; // then w = 11 // if max2 is 11x3 int h2 = max2.length; // then h = 11 int w2 = max2[0].length; // then w = 3 if (h1 != w2 || h2 != w1){ System.out.println("Invalid: max1.h != max2.w OR max1.w != max2.h"); return null; } double[][] out = new double[h1][h1]; double db = 0; for (int i = 0; i < h1; i++){ for (int j = 0; j < h1; j++){ db = 0; for (int k = 0; k < w1; k++){ db += max1[i][k] * max2[k][j]; } out[i][j] = chopDecimalNumber(db, 4); } } return out; } public static double multiplyRowWithCol(double[] row, double[] col){ double db = 0; for (int i = 0; i < row.length; i++){ db += row[i]* col[i]; } db = chopDecimalNumber(db, 4); return db; } public static double innerproductWithMetric(double[] row, double[][] max1, double[] col){ double db = 0; // if max1 is 11x11 int h1 = max1.length; // then h = 11 int w1 = max1[0].length; // then w = 11 for (int i = 0; i < h1; i++){ for (int j = 0; j < w1; j++){ db += row[i]*max1[i][j]*col[j]; } } db = chopDecimalNumber(db, 4); return db; } public static void printMatrix(double[][] in){ double row[] = null; double db = 0; System.out.println("The Matrix:"); String line = null; for (int i = 0; i < in.length; i++){ row = in[i]; line = ""; for (int j = 0; j < row.length; j++){ db = in[i][j]; line += db + "\t"; } System.out.println(line); } } public static double chopDecimalNumber(double original, int numberOfDecimal){ double mult = 1; int div = 1; switch(numberOfDecimal){ case 2: mult = 100.0; div = 100; break; case 3: mult = 1000.0; div = 1000; break; case 4: mult = 10000.0; div = 10000; break; case 5: mult = 100000.0; div = 100000; break; } int newInt = (int) (original * mult); return (double) newInt/div; } public static void calculateDistance(double[] doc1, double[][] metric, double[] doc2, int doc1N, int doc2N){ double dist = 0; String d1 = "d" + doc1N; String d2 = "d" + doc2N; double db = innerproductWithMetric(doc1, metric, doc2); System.out.println("\n("+d1+", "+d2+") = " + db); double normd1 = innerproductWithMetric(doc1, metric, doc1); double normd2 = innerproductWithMetric(doc2, metric, doc2); db = db/Math.sqrt(normd1*normd2); db = chopDecimalNumber(db, 4); System.out.println("\n("+d1+", "+d2+")/|"+d1+"|/|"+d2+"| = " + db); dist = Math.sqrt(2*(1-db)); dist = chopDecimalNumber(dist, 4); System.out.println("\nd("+d1+","+d2+") = " + dist + "\n"); } public static void calculateSC(double[] doc1, double[][] product, double[] query, int doc1N){ double db = innerproductWithMetric(doc1, product, query); System.out.println("\n(d"+doc1N+", q) = " + db); double normd = innerproductWithMetric(doc1, product, doc1); double normq = innerproductWithMetric(query, product, query); db = db/Math.sqrt(normd*normq); db = chopDecimalNumber(db, 4); System.out.println("\n(d"+doc1N+", q)/|d1|/|q| = " + db); double dist = Math.sqrt(2*(1-db)); dist = chopDecimalNumber(dist, 4); System.out.println("\nd(d"+doc1N+",q) = " + dist); } public static void calculateSCandDist(int vecN) { double[][] newdoc = null; if (vecN == 3){ newdoc = devideMatrixByRow(newdoc3, sss3); } else { newdoc = devideMatrixByRow(newdoc2, sss2); } newdocTrans = transposeMatrix(newdoc); printMatrix(newdocTrans); double dist = 0; System.out.println("\n\n"); double[][] product = multiplyMatrix(newdocTrans, newdoc); printMatrix(product); System.out.println("\n\n"); calculateSC(doc1, product, query, 1); calculateSC(doc2, product, query, 2); calculateSC(doc3, product, query, 3); System.out.println("\n\n"); calculateDistance(doc1, product, doc2, 1, 2); calculateDistance(doc1, product, doc3, 1, 3); calculateDistance(doc2, product, doc3, 2, 3); } public static void generateRightTransMatrix() { double[][] R = multiplyMatrix(AT, A); printMatrix(R); double sum = 0; double[] row = null; double[] div = new double[R.length]; for (int i = 0; i < R.length; i++){ row = R[i]; sum = 0; for (int j= 0; j