public void Matrices_Multiply_2x2() { Matrix left = new Matrix( new decimal[, ] { { 1, 2 }, { 3, 4 } }); Matrix right = new Matrix( new decimal[, ] { { 2, 0 }, { 1, 2 } }); Matrix result = Matrices.Multiply( left, right); Assert.AreEqual( new decimal[, ] { { 4, 4 }, { 10, 8 } }, result.Array); }
public void Matrices_Multiply_3x1times1x3() { Matrix left = new Matrix( new decimal[, ] { { 4 }, { 5 }, { 6 } }); Matrix right = new Matrix( new decimal[, ] { { 1, 2, 3 } }); Matrix result = Matrices.Multiply( left, right); Assert.AreEqual( new decimal[, ] { { 4, 8, 12 }, { 5, 10, 15 }, { 6, 12, 18 } }, result.Array); }
public void Matrices_Multiply_AnotherExample() { Matrix left = new Matrix( new decimal[, ] { { -1 }, { 3 }, { -2 } }); Matrix right = new Matrix( new decimal[, ] { { -1, 3, -2 } }); Matrix result = Matrices.Multiply( left, right); Assert.AreEqual( new decimal[, ] { { 1, -3, 2 }, { -3, 9, -6 }, { 2, -6, 4 } }, result.Array); }
public void Matrices_Multiply_1x3times3x1() { Matrix left = new Matrix( new decimal[, ] { { 1, 2, 3 } }); Matrix right = new Matrix( new decimal[, ] { { 4 }, { 5 }, { 6 } }); Matrix result = Matrices.Multiply( left, right); Assert.AreEqual( new decimal[, ] { { 32 } }, result.Array); }
public void Regression_Solve_OLS_Partials() { // Boston dataset downloaded from http://lib.stat.cmu.edu/datasets/boston // validating results against values from https://towardsdatascience.com/simple-and-multiple-linear-regression-in-python-c928425168f9 Matrix A = new Matrix( new decimal[, ] { { 12, -51, 4 }, { 6, 167, -68 }, { -4, 24, -41 } }); // don't alter a1 or it will alter A ColumnVector a1 = A.GetColumnVector( 0, 0, A.Height); decimal norm = a1.GetNorm(); // create copy of vector that can be edited Matrix u = a1.AsMatrix(); Assert.AreEqual( new decimal[, ] { { 12 }, { 6 }, { -4 } }, a1.AsMatrix().Array); // subtract norm * e vector // the sign is selected so it has the opposite sign of u1 decimal u1 = u[0, 0]; u[0, 0] -= Math.Sign(u1) * norm; u.DivideBy(2); Matrix uT = u.GetTranspose(); Matrix uuT = Matrices.Multiply( u, uT); Matrix I = Matrices.GetIdentity( uuT.Width); uuT.MultiplyBy( 2 / norm); Matrix H = Matrices.Subtract( I, uuT); Matrix HA = Matrices.Multiply( H, A); decimal[,] expected = new decimal[, ] { { 6 / 7m, 3 / 7m, -2 / 7m }, { 3 / 7m, -2 / 7m, 6 / 7m }, { -2 / 7m, 6 / 7m, 3 / 7m } }; Assert.AreEqual( expected, H.Array); A = new Matrix( new decimal[, ] { { 4, 1, -2, 2 }, { 1, 2, 0, 1 }, { -2, 0, 3, -2 }, { 2, 1, -2, -1 } }); //Q1 = A.GetHouseholderMatrix(); //expected = new decimal[,] // { // {1, 0, 0, 0}, // {0, -1/3m, 2/3m, -2/3m}, // {0, 2/3m, 2/3m, 1/3m}, // {0, -2/3m, 1/3m, 2/3m} // }; }
public void Regression_Solve_OLS() { Matrix A = new Matrix( new decimal[, ] { { 12, -51, 4 }, { 6, 167, -68 }, { -4, 24, -41 } }); //Matrix A = new Matrix( // new decimal[,] // { // {2, -2, 18}, // {2, 1, 0}, // {1, 2, 0} // }); int iteration = 1; Matrix H = A.GetHouseholder(); Matrix Q = H; Matrix R = Matrices.Multiply( H, A); if (iteration < A.Width) { // save storage space for the expanded versions of H Matrix HFinal = H; while (iteration < A.Width) { A = R.GetMinor( startingRowIndex: iteration, height: R.Height - iteration, startingColumnIndex: iteration, width: R.Width - iteration); H = A.GetHouseholder(); // expand H to add 1's on diagonal for dropped rows/columns for (int rowIndex = 0; rowIndex < iteration; rowIndex++) { for (int columnIndex = 0; columnIndex < HFinal.Width; columnIndex++) { if (rowIndex == columnIndex) { HFinal[rowIndex, columnIndex] = 1; } else { HFinal[rowIndex, columnIndex] = 0; } } } for (int rowIndex = iteration; rowIndex < HFinal.Height; rowIndex++) { for (int columnIndex = 0; columnIndex < iteration; columnIndex++) { HFinal[rowIndex, columnIndex] = 0; } } for (int rowIndex = 0; rowIndex < H.Width; rowIndex++) { for (int columnIndex = 0; columnIndex < H.Height; columnIndex++) { HFinal[rowIndex + iteration, columnIndex + iteration] = H[rowIndex, columnIndex]; } } Q = Matrices.Multiply( Q, HFinal); R = Matrices.Multiply( HFinal, R); iteration++; } } Matrix QR = Matrices.Multiply( Q, R); //decimal[] b = new decimal[width]; //decimal b0 = 0; //// need to loop including intercept //for (int variableIndex = width; variableIndex >= 0; variableIndex--) //{ // // use back substitution to drop out solved variables // decimal substitutionSum = 0; // for (int substituteIndex = b.Length - 1; substituteIndex > variableIndex - 1; substituteIndex--) // { // substitutionSum += b[substituteIndex] * QR[variableIndex, substituteIndex + 1]; // } // // solve for next variable coefficient // decimal coefficient = (values[variableIndex].y - substitutionSum) / QR[variableIndex, variableIndex + 1]; // if (variableIndex > 0) // { // b[variableIndex] = coefficient; // } // else // { // b0 = coefficient; // } //} }