private QFactorResult calculateLeastSquareLorenz() { int i, j = 0; int f0_index; PointPairInt range; int n; // Preprocessing (removing data points which are far away from transmittance peak) f0_index = findCenterFrequencyIndex(); if (f0_index < 0 || f0_index > pointList.Count) { return(new QFactorResult()); // return "no result" if center frequency not found. } range = findBandwidthIndexes(f0_index, 3.0F); if (range.I0 == int.MaxValue) { return(new QFactorResult()); // return "no result" if center frequency not found. } n = range.I1 - range.I0; if (n < 5) { // When we have very small amount of points, turn off Q-calculations completely - we don't want to have useless results! // We need to return the center frequency which is already found. return(new QFactorResult(pointList[f0_index].frequency, n)); } GeneralMatrix X = new GeneralMatrix(n, 3); // vandermonde matrix with measured frequency points GeneralMatrix Y = new GeneralMatrix(n, 3); // vector with measured power levels for (i = 0; i < pointList.Count; i++) { if (i > range.I0 && i <= range.I1) { X.SetElement(j, 0, Math.Pow(pointList[i].frequency, 2)); X.SetElement(j, 1, pointList[i].frequency); X.SetElement(j, 2, 1); Y.SetElement(j, 0, Math.Pow(10, -pointList[i].gain / 10)); // measured power is converted to linear form and inverted (1/x) j++; } } QRDecomposition QR = new QRDecomposition(X); GeneralMatrix beta = QR.Solve(Y); // Linear regression used to find beta coefficients double A = beta.GetElement(0, 0); double B = beta.GetElement(1, 0); double C = beta.GetElement(2, 0); double F0 = -B / (2 * A); double Q = -B / (2 * Math.Sqrt(4 * A * C - B * B)); double P0 = -1 / ((B * B) / (4 * A) - C); P0 = 10 * Math.Log10(P0); //return new QFactorResult(Q, F0, F0 - 0.5 * F0 / Q, F0 + 0.5 * F0 / Q, P0-3, P0-3); return(new QFactorResult(Q, F0, P0, F0 / Q, n)); }
public void ExceptionDifferentRowCount() { var matrixA = new Matrix(2, 2); matrixA[0, 0] = 0; matrixA[0, 1] = 0; matrixA[1, 0] = 1; matrixA[1, 1] = 0; var matrixB = new Matrix(2, 2); matrixB[0, 0] = 0; matrixB[0, 1] = 0; matrixB[1, 0] = 0; matrixB[1, 1] = 1; var qrDecomposition = new QRDecomposition(matrixA); qrDecomposition.Solve(matrixB); }
public void ExceptionDifferentRowCount() { var matrixA = new Matrix(2, 2); matrixA[0, 0] = 0; matrixA[0, 1] = 0; matrixA[1, 0] = 1; matrixA[1, 1] = 0; var matrixB = new Matrix(2, 2); matrixB[0, 0] = 0; matrixB[0, 1] = 0; matrixB[1, 0] = 0; matrixB[1, 1] = 1; var qrDecomposition = new QRDecomposition(matrixA); Assert.Throws <ArgumentException>(() => qrDecomposition.Solve(matrixB)); }
public void ExceptionRankDeficient() { var matrixA = new Matrix(3, 2); matrixA[0, 0] = 1; matrixA[0, 1] = 2; matrixA[1, 0] = 3; matrixA[1, 1] = 4; matrixA[2, 0] = 4; matrixA[2, 1] = 2; var matrixB = new Matrix(2, 2); matrixB[0, 0] = 0; matrixB[0, 1] = 0; matrixB[1, 0] = 0; matrixB[1, 1] = 1; var qrDecomposition = new QRDecomposition(matrixA); qrDecomposition.Solve(matrixB); }
public void ExceptionRankDeficient() { var matrixA = new Matrix(3, 2); matrixA[0, 0] = 1; matrixA[0, 1] = 2; matrixA[1, 0] = 3; matrixA[1, 1] = 4; matrixA[2, 0] = 4; matrixA[2, 1] = 2; var matrixB = new Matrix(2, 2); matrixB[0, 0] = 0; matrixB[0, 1] = 0; matrixB[1, 0] = 0; matrixB[1, 1] = 1; var qrDecomposition = new QRDecomposition(matrixA); Assert.Throws <ArgumentException>(() => qrDecomposition.Solve(matrixB)); }
public void Simple() { var matrixA = new Matrix(3, 2); matrixA[0, 0] = 1; matrixA[0, 1] = 2; matrixA[1, 0] = 3; matrixA[1, 1] = 4; matrixA[2, 0] = 4; matrixA[2, 1] = 2; var matrixB = new Matrix(3, 2); matrixB[0, 0] = 3; matrixB[0, 1] = 4; matrixB[1, 0] = 4; matrixB[1, 1] = 2; matrixB[2, 0] = 1; matrixB[2, 1] = 2; var decomposition = new QRDecomposition(matrixA); var solveMatrix = decomposition.Solve(matrixB); Assert.AreEqual(solveMatrix.Rows, 2); Assert.AreEqual(solveMatrix.Columns, 2); Assert.AreEqual(solveMatrix[0, 0], -0.514285714, 0.00000001); Assert.AreEqual(solveMatrix[0, 1], -0.057142857, 0.00000001); Assert.AreEqual(solveMatrix[1, 0], 1.4714285714, 0.00000001); Assert.AreEqual(solveMatrix[1, 1], 0.8857142857, 0.00000001); }
public void MatrixQRDecomposition2() { /* * MATLAB: * md2x4 = [1 2 -3 12;3 3.1 4 2] * [Q0, R0] = qr(md2x4',0) * S_mdh = sign(tril(R0)) * Q_mdh = Q0*S_mdh * R_mdh = S_mdh(:,1:2)*R0 * [Q0, R0] = qr(md2x4,0) * S_md = sign(tril(R0)) * Q_md = Q0*S_md * R_md = S_md(:,1:2)*R0 */ Matrix md2X4 = new Matrix(new double[][] { new double[] { 1, 2, -3, 12 }, new double[] { 3, 3.1, 4, 2 } }); Matrix md2X4H = Matrix.Transpose(md2X4); QRDecomposition mdhQR = md2X4H.QRDecomposition; Matrix mdhQ = new Matrix(new double[][] { new double[] { 0.07955572841757, 0.47920079143039 }, new double[] { 0.15911145683515, 0.47348594100255 }, new double[] { -0.23866718525272, 0.73615739955605 }, new double[] { 0.95466874101088, 0.06519162710272 } }); Matrix mdhR = new Matrix(new double[][] { new double[] { 12.56980508997654, 1.68658144245255 }, new double[] { 0, 5.98042164382869 } }); Matrix mdhPInv = new Matrix(new double[][] { new double[] { -0.00442227310854, 0.00203505965379, -0.03550382768177, 0.07448672256297 }, new double[] { 0.08012826184670, 0.07917266861796, 0.12309456479807, 0.01090084127596 } }); Assert.That(mdhQR.Q, NumericIs.AlmostEqualTo(mdhQ, 1e-14), "real QR Q-matrix (H)"); Assert.That(mdhQR.R, NumericIs.AlmostEqualTo(mdhR), "real QR R-matrix (H)"); Assert.That(mdhQR.Q * mdhQR.R, NumericIs.AlmostEqualTo(md2X4H), "real QR product (H)"); Assert.That(Matrix.Transpose(mdhQR.Q) * mdhQR.Q, NumericIs.AlmostEqualTo(Matrix.Identity(2, 2)), "real QR QHQ=I (H)"); Assert.That(mdhQR.Solve(Matrix.Identity(4, 4)), NumericIs.AlmostEqualTo(mdhPInv, 1e-13), "real QR Solve/Pseudoinverse (H)"); Assert.That(md2X4H.Inverse(), NumericIs.AlmostEqualTo(mdhPInv, 1e-13), "real pseudoinverse (H)"); QRDecomposition mdQR = md2X4.QRDecomposition; Matrix mdQ = new Matrix(new double[][] { new double[] { 0.31622776601684, 0.94868329805051 }, new double[] { 0.94868329805051, -0.31622776601684 } }); Matrix mdR = new Matrix(new double[][] { new double[] { 3.16227766016838, 3.57337375599027, 2.84604989415154, 5.69209978830308 }, new double[] { 0, 0.91706052144883, -4.11096095821889, 10.75174404457249 } }); Matrix mdPInv = new Matrix(new double[][] { new double[] { -0.00442227310854, 0.08012826184670 }, new double[] { 0.00203505965379, 0.07917266861796 }, new double[] { -0.03550382768177, 0.12309456479807 }, new double[] { 0.07448672256297, 0.01090084127596 } }); Assert.That(mdQR.Q, NumericIs.AlmostEqualTo(mdQ, 1e-14), "real QR Q-matrix"); Assert.That(mdQR.R, NumericIs.AlmostEqualTo(mdR), "real QR R-matrix"); Assert.That(mdQR.Q * mdQR.R, NumericIs.AlmostEqualTo(md2X4), "real QR product"); Assert.That(Matrix.Transpose(mdQR.Q) * mdQR.Q, NumericIs.AlmostEqualTo(Matrix.Identity(2, 2)), "real QR QHQ=I"); /* * NOTE: QR.Solve won't work yet (LQ would be required instead of QR). * Hence check the matrix Solve instead, which is supposed to compute the transposed QR in this case. * NumericAssert.AreAlmostEqual(PInv_md, md2x4.Solve(Matrix.Identity(2, 2)), 1e-13, "real QR Solve/Pseudoinverse"); */ Assert.That(md2X4.Inverse(), NumericIs.AlmostEqualTo(mdPInv, 1e-13), "real pseudoinverse"); }
public void T01_BasicLinearEquations() { const double Accuracy = 2.2205e-15, SvdAccuracy = 4.46e-15, DeterminantAccuracy = 1.2e-13; // given w=-1, x=2, y=-3, and z=4... // w - 2x + 3y - 5z = -1 - 4 - 9 - 20 = -34 // w + 2x + 3y + 5z = -1 + 4 - 9 + 20 = 14 // 5w - 3x + 2y - z = -5 - 6 - 6 - 4 = -21 // 5w + 3x + 2y + z = -5 + 6 - 6 + 4 = -1 double[] coefficientArray = new double[16] { 1, -2, 3, -5, 1, 2, 3, 5, 5, -3, 2, -1, 5, 3, 2, 1, }; double[] valueArray = new double[4] { -34, 14, -21, -1 }; // first solve using Gauss-Jordan elimination Matrix4 coefficients = new Matrix4(coefficientArray); Matrix gjInverse, values = new Matrix(valueArray, 1); Matrix solution = GaussJordan.Solve(coefficients.ToMatrix(), values, out gjInverse); CheckSolution(solution, Accuracy); CheckSolution(gjInverse * values, Accuracy); // make sure multiplying by the matrix inverse also gives the right answer // then solve using LU decomposition LUDecomposition lud = new LUDecomposition(coefficients.ToMatrix()); solution = lud.Solve(values); CheckSolution(solution, Accuracy); CheckSolution(lud.GetInverse() * values, Accuracy); // check that the inverse can be multiplied to produce a good solution solution.Multiply(1.1); // mess up the solution lud.RefineSolution(values, solution); // test that refinement can fix it CheckSolution(solution, Accuracy); // check that the computed determinants are what we expect bool negative; Assert.AreEqual(coefficients.GetDeterminant(), lud.GetDeterminant(), DeterminantAccuracy); Assert.AreEqual(Math.Log(Math.Abs(coefficients.GetDeterminant())), lud.GetLogDeterminant(out negative), Accuracy); Assert.AreEqual(coefficients.GetDeterminant() < 0, negative); // check that the inverses are about the same from both methods Assert.IsTrue(gjInverse.Equals(lud.GetInverse(), Accuracy)); // then solve using QR decomposition QRDecomposition qrd = new QRDecomposition(coefficients.ToMatrix()); solution = qrd.Solve(values); CheckSolution(solution, Accuracy); CheckSolution(qrd.GetInverse() * values, Accuracy); // check that the inverse can be multiplied to produce a good solution // TODO: test qrd.Update() // finally, try solving using singular value decomposition SVDecomposition svd = new SVDecomposition(coefficients.ToMatrix()); solution = svd.Solve(values); CheckSolution(solution, SvdAccuracy); CheckSolution(svd.GetInverse() * values, SvdAccuracy); Assert.IsTrue(gjInverse.Equals(svd.GetInverse(), Accuracy)); Assert.AreEqual(4, svd.GetRank()); Assert.AreEqual(0, svd.GetNullity()); }
public override IVector Apply(IMatrix A, IVector b, IVector x) { double[] xs = (double[])decomp.Solve( new Matrix(Blas.Default.GetArrayCopy(b), b.Length)); return(Blas.Default.SetVector(xs, x)); }