/** * Computes the Moore–Penrose pseudoinverse using the SVD method. * * Modified version of the original implementation by Kim van der Linde. */ public static GeneralMatrix pinv(GeneralMatrix x) { if (x.Rank() < 1) return null; if (x.ColumnDimension > x.RowDimension) return pinv(x.Transpose()).Transpose(); SingularValueDecomposition svdX = new SingularValueDecomposition(x); double[] singularValues = svdX.SingularValues; double tol = Math.Max(x.ColumnDimension, x.RowDimension) * singularValues[0] * 2E-16; double[] singularValueReciprocals = new double[singularValues.Count()]; for (int i = 0; i < singularValues.Count(); i++) singularValueReciprocals[i] = Math.Abs(singularValues[i]) < tol ? 0 : (1.0 / singularValues[i]); double[][] u = svdX.GetU().Array; double[][] v = svdX.GetV().Array; int min = Math.Min(x.ColumnDimension, u[0].Count()); double[][] inverse = new double[x.ColumnDimension][]; for (int i = 0; i < x.ColumnDimension; i++) { inverse[i] = new double[x.RowDimension]; for (int j = 0; j < u.Count(); j++) for (int k = 0; k < min; k++) inverse[i][j] += v[i][k] * singularValueReciprocals[k] * u[j][k]; } return new GeneralMatrix(inverse); }
private void computeaccCalButton_Click(object sender, EventArgs e) { int i,j; calStatusText.Text = "Computing Calibration..."; // Construct D matrix // D = [x.^2, y.^2, z.^2, x.*y, x.*z, y.*z, x, y, z, ones(N,1)]; for (i = 0; i < SAMPLES; i++ ) { // x^2 term D.SetElement(i,0, loggedData[i,0]*loggedData[i,0]); // y^2 term D.SetElement(i,1,loggedData[i,1]*loggedData[i,1]); // z^2 term D.SetElement(i, 2, loggedData[i, 2] * loggedData[i, 2]); // x*y term D.SetElement(i,3,loggedData[i,0]*loggedData[i,1]); // x*z term D.SetElement(i,4,loggedData[i,0]*loggedData[i,2]); // y*z term D.SetElement(i,5,loggedData[i,1]*loggedData[i,2]); // x term D.SetElement(i,6,loggedData[i,0]); // y term D.SetElement(i,7,loggedData[i,1]); // z term D.SetElement(i,8,loggedData[i,2]); // Constant term D.SetElement(i,9,1); } // QR=triu(qr(D)) QRDecomposition QR = new QRDecomposition(D); // [U,S,V] = svd(D) SingularValueDecomposition SVD = new SingularValueDecomposition(QR.R); GeneralMatrix V = SVD.GetV(); GeneralMatrix A = new GeneralMatrix(3, 3); double[] p = new double[V.RowDimension]; for (i = 0; i < V.RowDimension; i++ ) { p[i] = V.GetElement(i,V.ColumnDimension-1); } /* A = [p(1) p(4)/2 p(5)/2; p(4)/2 p(2) p(6)/2; p(5)/2 p(6)/2 p(3)]; */ if (p[0] < 0) { for (i = 0; i < V.RowDimension; i++) { p[i] = -p[i]; } } A.SetElement(0,0,p[0]); A.SetElement(0,1,p[3]/2); A.SetElement(1,2,p[4]/2); A.SetElement(1,0,p[3]/2); A.SetElement(1,1,p[1]); A.SetElement(1,2,p[5]/2); A.SetElement(2,0,p[4]/2); A.SetElement(2,1,p[5]/2); A.SetElement(2,2,p[2]); CholeskyDecomposition Chol = new CholeskyDecomposition(A); GeneralMatrix Ut = Chol.GetL(); GeneralMatrix U = Ut.Transpose(); double[] bvect = {p[6]/2,p[7]/2,p[8]/2}; double d = p[9]; GeneralMatrix b = new GeneralMatrix(bvect,3); GeneralMatrix v = Ut.Solve(b); double vnorm_sqrd = v.GetElement(0,0)*v.GetElement(0,0) + v.GetElement(1,0)*v.GetElement(1,0) + v.GetElement(2,0)*v.GetElement(2,0); double s = 1/Math.Sqrt(vnorm_sqrd - d); GeneralMatrix c = U.Solve(v); for (i = 0; i < 3; i++) { c.SetElement(i, 0, -c.GetElement(i, 0)); } U = U.Multiply(s); for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { calMat[i, j] = U.GetElement(i, j); } } for (i = 0; i < 3; i++) { bias[i] = c.GetElement(i, 0); } accAlignment00.Text = calMat[0, 0].ToString(); accAlignment01.Text = calMat[0, 1].ToString(); accAlignment02.Text = calMat[0, 2].ToString(); accAlignment10.Text = calMat[1, 0].ToString(); accAlignment11.Text = calMat[1, 1].ToString(); accAlignment12.Text = calMat[1, 2].ToString(); accAlignment20.Text = calMat[2, 0].ToString(); accAlignment21.Text = calMat[2, 1].ToString(); accAlignment22.Text = calMat[2, 2].ToString(); biasX.Text = bias[0].ToString(); biasY.Text = bias[1].ToString(); biasZ.Text = bias[2].ToString(); calStatusText.Text = "Done"; flashCommitButton.Enabled = true; accAlignmentCommitButton.Enabled = true; }
public GeneralMatrix[] decompose(int svCount, GeneralMatrix m) { SingularValueDecomposition s = new SingularValueDecomposition(m); try { sv = svCount; frameScale = m.RowDimension; if (m.RowDimension > m.ColumnDimension) { frameScale = m.ColumnDimension; } else if (m.RowDimension < m.ColumnDimension) { frameScale = m.RowDimension; } // Make square matrix of data if (m.RowDimension != m.ColumnDimension) { squareM = m.GetMatrix(0, frameScale - 1, 0, frameScale - 1); } else { squareM = m; } //perform the SVD here: SingularValueDecomposition svd = new SingularValueDecomposition(squareM); GeneralMatrix U = svd.GetU().GetMatrix(0, frameScale - 1, 0, sv - 1); GeneralMatrix V = svd.GetV(); double[] D = svd.SingularValues; GeneralMatrix dMat = makeDiagonalSquare(D, sv); GeneralMatrix vMat = V.Transpose().GetMatrix(0, sv - 1, 0, frameScale - 1); /*Console.WriteLine(U.RowDimension + "x" + U.ColumnDimension + " * " + dMat.RowDimension + "x" + dMat.ColumnDimension + " * " + vMat.RowDimension + "x" + vMat.ColumnDimension); recomposition = U.Multiply(dMat).Multiply(vMat); int[,] recompositionData = new int[recomposition.ColumnDimension, recomposition.RowDimension]; for (int i = 0; i < recomposition.ColumnDimension; i++) { for (int j = 0; j < recomposition.RowDimension; j++) { recompositionData[j, i] = (int)(recomposition.GetElement(j, i)); } }*/ GeneralMatrix[] result = new GeneralMatrix[2]; result[0] = U; result[1] = vMat; return result; } catch (Exception ex) { Console.WriteLine(ex.ToString()); } return null; }
private void GetFiles_Decompose_WriteToArff() { try { // sampleFactor is the amount to divide by the total size of the // data set // when determining the subsample that will be used in svd Console.WriteLine("Creating arff file..."); DisplayMessage("Creating arff file..."); // Create folder System.IO.Directory.CreateDirectory(OutputDir + "Results/"); StreamWriter output = new StreamWriter(OutputDir + "Results/" + "resultsGalaxy.arff"); output.Write("@relation 'galaxy'\n"); output.Write("@attribute class real\n"); output.Write("@attribute colorF real\n"); output.Write("@attribute bulgeF real\n"); output.Write("@attribute constF real\n"); for (int i = 0; i < sv * 3; i++) { output.Write("@attribute " + i + " real\n"); } output.Write("@data\n"); Console.WriteLine("Begin galaxy sampling"); DisplayMessage("Begin galaxy sampling"); // Initialize a three matrices that will hold all of the images // (r,g,b of each image where each row is an image) dataRed = new GeneralMatrix(galaxyData.Count() / sampleFactor, imageScaleSize * imageScaleSize); dataGreen = new GeneralMatrix(galaxyData.Count() / sampleFactor, imageScaleSize * imageScaleSize); dataBlue = new GeneralMatrix(galaxyData.Count() / sampleFactor, imageScaleSize * imageScaleSize); // subsample from galaxydata System.Threading.Tasks.Parallel.For(0, galaxyData.Count() / sampleFactor, (int index) => { Bitmap tempImage = getImage(OutputDir + "galaxies/" + galaxyData[sampleFactor * index][0] + ".jpg", imageScaleSize); for (int i = 0; i < imageScaleSize; i++) { for (int j = 0; j < imageScaleSize; j++) { int pixelColor = tempImage.GetPixel(i, j).ToArgb(); int[] rgb = new int[3]; rgb[0] += ((pixelColor & 0x00ff0000) >> 16); rgb[1] += ((pixelColor & 0x0000ff00) >> 8); rgb[2] += (pixelColor & 0x000000ff); dataRed.SetElement(index, i * imageScaleSize + j, rgb[0]); dataGreen.SetElement(index, i * imageScaleSize + j, rgb[1]); dataBlue.SetElement(index, i * imageScaleSize + j, rgb[2]); } } //if (index % 10 == 0) //DisplayImage(index); //Console.WriteLine("Galaxy " + (sampleFactor * index) + " finished"); }); Console.WriteLine("Galaxy sampling finished\nBegin R, G and B channel SVD"); DisplayMessage("Galaxy sampling finished, Begin R, G and B channel SVD"); // Perform svd on subsample: var redWorker = System.Threading.Tasks.Task.Factory.StartNew(() => svdR = new SingularValueDecomposition(dataRed)); var greenWorker = System.Threading.Tasks.Task.Factory.StartNew(() => svdG = new SingularValueDecomposition(dataGreen)); var blueWorker = System.Threading.Tasks.Task.Factory.StartNew(() => svdB = new SingularValueDecomposition(dataBlue)); System.Threading.Tasks.Task.WaitAll(redWorker, greenWorker, blueWorker); // Create the basis for each component GeneralMatrix rV = svdR.GetV(); Console.Write("dim rU: " + rV.RowDimension + ", " + rV.ColumnDimension); GeneralMatrix gV = svdG.GetV(); GeneralMatrix bV = svdB.GetV(); rV = GetSVs(rV, sv); Console.Write("Svs: " + sv); Console.Write("Dim SsV: " + rV.RowDimension + ", " + rV.ColumnDimension); gV = GetSVs(gV, sv); bV = GetSVs(bV, sv); // Perform the pseudoinverses frV = pinv(rV.Transpose()); fgV = pinv(gV.Transpose()); fbV = pinv(bV.Transpose()); // Stores frV, fgV and fbV to file WriteToFile(); Console.WriteLine("SVD finished"); DisplayMessage("SVD finished, load full dataset for testing"); Console.WriteLine("Begin filling dataset for testing"); // fill the 'full' datasets dataRed = new GeneralMatrix(galaxyData.Count(), imageScaleSize * imageScaleSize); dataGreen = new GeneralMatrix(galaxyData.Count(), imageScaleSize * imageScaleSize); dataBlue = new GeneralMatrix(galaxyData.Count(), imageScaleSize * imageScaleSize); System.Threading.Tasks.Parallel.For(0, galaxyData.Count(), (int index) => { Bitmap tempImage = getImage(OutputDir + "galaxies/" + galaxyData[index][0] + ".jpg", imageScaleSize); for (int i = 0; i < imageScaleSize; i++) { for (int j = 0; j < imageScaleSize; j++) { int pixelColor = tempImage.GetPixel(i, j).ToArgb(); int[] rgb = new int[3]; rgb[0] += ((pixelColor & 0x00ff0000) >> 16); rgb[1] += ((pixelColor & 0x0000ff00) >> 8); rgb[2] += (pixelColor & 0x000000ff); dataRed.SetElement(index, i * imageScaleSize + j, rgb[0]); dataGreen.SetElement(index, i * imageScaleSize + j, rgb[1]); dataBlue.SetElement(index, i * imageScaleSize + j, rgb[2]); } } }); Console.WriteLine("Finished filling dataset for testing"); DisplayMessage("Finished filling dataset for testing, begin projecting galaxies to U coordinate system"); Console.WriteLine("Begin projecting galaxies to U coordinate system, writing to ARFF file"); // Do the coordinate conversion rV = dataRed.Multiply(frV); gV = dataGreen.Multiply(fgV); bV = dataBlue.Multiply(fbV); Console.Write("Dim Final rU: " + rV.ColumnDimension + ", " + rV.RowDimension); Console.WriteLine("galaxyData.Count(): " + galaxyData.Count()); // write to the output file here: for (int imageIndex = 0; imageIndex < galaxyData.Count(); imageIndex++) { Bitmap tempImage = getImage(OutputDir + "galaxies/" + galaxyData[imageIndex][0] + ".jpg", imageScaleSize); float colorFactor = (GetColor(tempImage)[0] / GetColor(tempImage)[2]); float centralBulgeFactor = getCentralBulge(tempImage); float consistencyFactor = GetConsistency(tempImage); output.Write(galaxyData[imageIndex][1] + ", "); output.Write(colorFactor + ", "); output.Write(centralBulgeFactor + ", "); output.Write(consistencyFactor + ", "); // output data (r,g,b) for (int i = 0; i < rV.ColumnDimension; i++) { output.Write(rV.GetElement(imageIndex, i) + ", "); output.Write(gV.GetElement(imageIndex, i) + ", "); if (i == rV.ColumnDimension - 1) { output.Write(bV.GetElement(imageIndex, i) + "\n"); } else { output.Write(bV.GetElement(imageIndex, i) + ", "); } } //if (imageIndex % (galaxyData.Count() / 100) == 0) // DisplayImage(imageIndex); DisplayMessage("Finished galaxy " + imageIndex.ToString() + " - " + (100 * imageIndex / galaxyData.Count()).ToString() + "%"); } output.Flush(); output.Close(); output.Dispose(); Console.Write("Finished creating arff file..."); DisplayMessage("Finished creating arff file..."); } catch (Exception ex) { Console.Write(ex.ToString()); } }
public int classify(Bitmap currentImage) { try { currentImage.Save(OutputDir + "Results/temp.png", System.Drawing.Imaging.ImageFormat.Png); // Create folder System.IO.Directory.CreateDirectory(OutputDir + "Results/"); StreamWriter output = new StreamWriter(OutputDir + "Results/" + "temp.arff"); output.Write("@relation 'galaxy'\n"); output.Write("@attribute class real\n"); output.Write("@attribute colorF real\n"); output.Write("@attribute bulgeF real\n"); output.Write("@attribute constF real\n"); for (int i = 0; i < sv * 3; i++) { output.Write("@attribute " + i + " real\n"); } output.Write("@data\n"); Bitmap tempImage = getImage(OutputDir + "Results/temp.png", imageScaleSize); for (int i = 0; i < imageScaleSize; i++) { for (int j = 0; j < imageScaleSize; j++) { int pixelColor = tempImage.GetPixel(i, j).ToArgb(); int[] rgb = new int[3]; rgb[0] += ((pixelColor & 0x00ff0000) >> 16); rgb[1] += ((pixelColor & 0x0000ff00) >> 8); rgb[2] += (pixelColor & 0x000000ff); dataRed.SetElement(galaxyData.Count() - 1, i * imageScaleSize + j, rgb[0]); dataGreen.SetElement(galaxyData.Count() - 1, i * imageScaleSize + j, rgb[1]); dataBlue.SetElement(galaxyData.Count() - 1, i * imageScaleSize + j, rgb[2]); } } var redWorker = System.Threading.Tasks.Task.Factory.StartNew(() => svdR = new SingularValueDecomposition(dataRed)); var greenWorker = System.Threading.Tasks.Task.Factory.StartNew(() => svdG = new SingularValueDecomposition(dataGreen)); var blueWorker = System.Threading.Tasks.Task.Factory.StartNew(() => svdB = new SingularValueDecomposition(dataBlue)); System.Threading.Tasks.Task.WaitAll(redWorker, greenWorker, blueWorker); GeneralMatrix rU = svdR.GetU(); GeneralMatrix gU = svdG.GetU(); GeneralMatrix bU = svdB.GetU(); rU = GetSVs(rU, sv); gU = GetSVs(gU, sv); bU = GetSVs(bU, sv); float colorFactor = (GetColor(tempImage)[0] / GetColor(tempImage)[2]); float centralBulgeFactor = getCentralBulge(tempImage); float consistencyFactor = GetConsistency(tempImage); output.Write(galaxyData[galaxyData.Count() - 1][1] + ", "); output.Write(colorFactor + ", "); output.Write(centralBulgeFactor + ", "); output.Write(consistencyFactor + ", "); // output data (r,g,b) for (int i = 0; i < rU.ColumnDimension; i++) { output.Write(rU.GetElement(galaxyData.Count() - 1, i) + ", "); output.Write(gU.GetElement(galaxyData.Count() - 1, i) + ", "); if (i == rU.ColumnDimension - 1) { output.Write(bU.GetElement(galaxyData.Count() - 1, i) + "\n"); } else { output.Write(bU.GetElement(galaxyData.Count() - 1, i) + ", "); } } output.Flush(); output.Close(); output.Dispose(); weka.core.converters.ConverterUtils.DataSource source = new weka.core.converters.ConverterUtils.DataSource(OutputDir + "Results/temp.arff"); weka.core.Instances test = source.getDataSet(); test.setClassIndex(0); int classPrediction = (int)Math.Round(fc.classifyInstance(test.instance(0))); if (classPrediction < -6) { classPrediction = -6; } else if (classPrediction > 11) { classPrediction = 11; } return classPrediction; } catch (Exception ex) { Console.Write(ex.ToString()); } return -99; }