public Vector <double> SeidelMethod(Matrix <double> A, Vector <double> B, double eps) { Vector <double> X = new DenseVector(A.RowCount); Vector <double> TempX = new DenseVector(A.RowCount); int count = 0; do { TempX = X.Clone(); for (int i = 0; i < A.RowCount; ++i) { double var = 0; for (int j = 0; j < i; j++) { var += (A[i, j] * X[j]); } for (int j = i + 1; j < A.RowCount; ++j) { var += (A[i, j] * TempX[j]); } X[i] = (B[i] - var) / A[i, i]; } if (++count == 1000) { break; } } while ((X - TempX).L2Norm() > eps); Console.WriteLine(count); return(X); }
public HistogramDataAndProperties(DenseVector data, int countOfBins = 10) { dvData = (DenseVector)data.Clone(); binsCount = countOfBins; color = Color.Black; description = "histogram"; stats = new DescriptiveStatistics(dvData); calculateProbDens(); CalculateQuantiles(); }
public HistogramDataAndProperties() { dvData = DenseVector.Create(1, i => 0.0d); binsCount = 1; color = Color.Black; description = "histogram"; dvbinsCenters = (DenseVector)dvData.Clone(); stats = new DescriptiveStatistics(dvData); calculateProbDens(); CalculateQuantiles(); }
public T Clone() { var r = new T(); r.A = (DenseMatrix)A.Clone(); r.B = (DenseVector)B.Clone(); r.C = (DenseVector)C.Clone(); if (J != null) { r.J = new List <int> (J); } r.N = N; r.M = M; r.DL = (DenseVector)DL.Clone(); r.DR = (DenseVector)DR.Clone(); return(r); }
public static DenseVector ExponentialMovingAverage(DenseVector dvValues, int gap = 10, double smoothingParameter = 0.4d) { DenseVector dvOutValues = (DenseVector)dvValues.Clone(); dvOutValues.MapIndexedInplace(new Func <int, double, double>((i, x) => { DenseVector dvWeights = DenseVector.Create(1 + gap * 2, new Func <int, double>(j => { int k = j - gap; if (i + k < 0) { return(0.0d); } if (i + k >= dvOutValues.Count) { return(0.0d); } return(Math.Exp(-Math.Abs(k) * smoothingParameter)); })); //dvWeights.MapIndexedInplace(new Func<int,double,double>((j, dVal) => //{ // if (double.IsNaN(dvValues[])) return 0.0d; //})) double sum = dvWeights.Sum(); dvWeights.MapInplace(new Func <double, double>(d => d / sum)); double retVal = 0.0d; for (int n = 0; n < 1 + gap * 2; n++) { int m = n - gap + i; if ((m < 0) || (m >= dvOutValues.Count)) { continue; } double weight = dvWeights[n]; retVal += weight * dvValues[m]; } return(retVal); })); return(dvOutValues); }
public GroupingQueryResult(List <UserQueryResult> InputList, List <string> ADGroupNames, string Name, string TypeName) : base(new DenseVector(InputList[0].ReturnAccessVector().Count)) { groupingName = Name; groupingType = TypeName; groupMemberCount = InputList.Count; List <string> MembersList = new List <string>(); Vector InterimAccessVector = new DenseVector(InputList[0].ReturnAccessVector().Count); foreach (UserQueryResult UQR in InputList) { if (UQR != null) { InterimAccessVector = (Vector)(InterimAccessVector + UQR.ReturnAccessVector()); MembersList.Add(UQR.AccountName); } } members = HelperFunctions.StringListToCommaSeparatedString(MembersList); accessSummaryVector = (Vector)(InterimAccessVector / groupMemberCount); aDGroupsRepresented = HelperFunctions.StringListToCommaSeparatedString(ReturnAccessList(ADGroupNames)); rawCountVector = (Vector)InterimAccessVector.Clone(); }
/// <summary> /// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the /// solution vector and x is the unknown vector. /// </summary> /// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param> /// <param name="input">The solution <see cref="Vector"/>, <c>b</c>.</param> /// <param name="result">The result <see cref="Vector"/>, <c>x</c>.</param> public void Solve(Matrix matrix, Vector input, Vector result) { // If we were stopped before, we are no longer // We're doing this at the start of the method to ensure // that we can use these fields immediately. _hasBeenStopped = false; // Parameters checks if (matrix == null) { throw new ArgumentNullException("matrix"); } if (matrix.RowCount != matrix.ColumnCount) { throw new ArgumentException(Resources.ArgumentMatrixSquare, "matrix"); } if (input == null) { throw new ArgumentNullException("input"); } if (result == null) { throw new ArgumentNullException("result"); } if (result.Count != input.Count) { throw new ArgumentException(Resources.ArgumentVectorsSameLength); } if (input.Count != matrix.RowCount) { throw Matrix.DimensionsDontMatch<ArgumentException>(input, result); } // Initialize the solver fields // Set the convergence monitor if (_iterator == null) { _iterator = Iterator.CreateDefault(); } if (_preconditioner == null) { _preconditioner = new UnitPreconditioner(); } _preconditioner.Initialize(matrix); // Compute r_0 = b - Ax_0 for some initial guess x_0 // In this case we take x_0 = vector // This is basically a SAXPY so it could be made a lot faster Vector residuals = new DenseVector(matrix.RowCount); CalculateTrueResidual(matrix, residuals, result, input); // Choose r~ (for example, r~ = r_0) var tempResiduals = residuals.Clone(); // create seven temporary vectors needed to hold temporary // coefficients. All vectors are mangled in each iteration. // These are defined here to prevent stressing the garbage collector Vector vecP = new DenseVector(residuals.Count); Vector vecPdash = new DenseVector(residuals.Count); Vector nu = new DenseVector(residuals.Count); Vector vecS = new DenseVector(residuals.Count); Vector vecSdash = new DenseVector(residuals.Count); Vector temp = new DenseVector(residuals.Count); Vector temp2 = new DenseVector(residuals.Count); // create some temporary double variables that are needed // to hold values in between iterations Complex currentRho = 0; Complex alpha = 0; Complex omega = 0; var iterationNumber = 0; while (ShouldContinue(iterationNumber, result, input, residuals)) { // rho_(i-1) = r~^T r_(i-1) // dotproduct r~ and r_(i-1) var oldRho = currentRho; currentRho = tempResiduals.DotProduct(residuals); // if (rho_(i-1) == 0) // METHOD FAILS // If rho is only 1 ULP from zero then we fail. if (currentRho.Real.AlmostEqual(0, 1) && currentRho.Imaginary.AlmostEqual(0, 1)) { // Rho-type breakdown throw new Exception("Iterative solver experience a numerical break down"); } if (iterationNumber != 0) { // beta_(i-1) = (rho_(i-1)/rho_(i-2))(alpha_(i-1)/omega(i-1)) var beta = (currentRho / oldRho) * (alpha / omega); // p_i = r_(i-1) + beta_(i-1)(p_(i-1) - omega_(i-1) * nu_(i-1)) nu.Multiply(-omega, temp); vecP.Add(temp, temp2); temp2.CopyTo(vecP); vecP.Multiply(beta, vecP); vecP.Add(residuals, temp2); temp2.CopyTo(vecP); } else { // p_i = r_(i-1) residuals.CopyTo(vecP); } // SOLVE Mp~ = p_i // M = preconditioner _preconditioner.Approximate(vecP, vecPdash); // nu_i = Ap~ matrix.Multiply(vecPdash, nu); // alpha_i = rho_(i-1)/ (r~^T nu_i) = rho / dotproduct(r~ and nu_i) alpha = currentRho * 1 / tempResiduals.DotProduct(nu); // s = r_(i-1) - alpha_i nu_i nu.Multiply(-alpha, temp); residuals.Add(temp, vecS); // Check if we're converged. If so then stop. Otherwise continue; // Calculate the temporary result. // Be careful not to change any of the temp vectors, except for // temp. Others will be used in the calculation later on. // x_i = x_(i-1) + alpha_i * p^_i + s^_i vecPdash.Multiply(alpha, temp); temp.Add(vecSdash, temp2); temp2.CopyTo(temp); temp.Add(result, temp2); temp2.CopyTo(temp); // Check convergence and stop if we are converged. if (!ShouldContinue(iterationNumber, temp, input, vecS)) { temp.CopyTo(result); // Calculate the true residual CalculateTrueResidual(matrix, residuals, result, input); // Now recheck the convergence if (!ShouldContinue(iterationNumber, result, input, residuals)) { // We're all good now. return; } // Continue the calculation iterationNumber++; continue; } // SOLVE Ms~ = s _preconditioner.Approximate(vecS, vecSdash); // temp = As~ matrix.Multiply(vecSdash, temp); // omega_i = temp^T s / temp^T temp omega = temp.DotProduct(vecS) / temp.DotProduct(temp); // x_i = x_(i-1) + alpha_i p^ + omega_i s^ temp.Multiply(-omega, residuals); residuals.Add(vecS, temp2); temp2.CopyTo(residuals); vecSdash.Multiply(omega, temp); result.Add(temp, temp2); temp2.CopyTo(result); vecPdash.Multiply(alpha, temp); result.Add(temp, temp2); temp2.CopyTo(result); // for continuation it is necessary that omega_i != 0.0 // If omega is only 1 ULP from zero then we fail. if (omega.Real.AlmostEqual(0, 1) && omega.Imaginary.AlmostEqual(0, 1)) { // Omega-type breakdown throw new Exception("Iterative solver experience a numerical break down"); } if (!ShouldContinue(iterationNumber, result, input, residuals)) { // Recalculate the residuals and go round again. This is done to ensure that // we have the proper residuals. // The residual calculation based on omega_i * s can be off by a factor 10. So here // we calculate the real residual (which can be expensive) but we only do it if we're // sufficiently close to the finish. CalculateTrueResidual(matrix, residuals, result, input); } iterationNumber++; } }
/// <summary> /// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the /// solution vector and x is the unknown vector. /// </summary> /// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param> /// <param name="input">The solution <see cref="Vector"/>, <c>b</c>.</param> /// <param name="result">The result <see cref="Vector"/>, <c>x</c>.</param> public void Solve(Matrix <float> matrix, Vector <float> input, Vector <float> result) { // If we were stopped before, we are no longer // We're doing this at the start of the method to ensure // that we can use these fields immediately. _hasBeenStopped = false; // Parameters checks if (matrix == null) { throw new ArgumentNullException("matrix"); } if (matrix.RowCount != matrix.ColumnCount) { throw new ArgumentException(Resources.ArgumentMatrixSquare, "matrix"); } if (input == null) { throw new ArgumentNullException("input"); } if (result == null) { throw new ArgumentNullException("result"); } if (result.Count != input.Count) { throw new ArgumentException(Resources.ArgumentVectorsSameLength); } if (input.Count != matrix.RowCount) { throw Matrix.DimensionsDontMatch <ArgumentException>(input, matrix); } // Initialize the solver fields // Set the convergence monitor if (_iterator == null) { _iterator = Iterator.CreateDefault(); } if (_preconditioner == null) { _preconditioner = new UnitPreconditioner <float>(); } _preconditioner.Initialize(matrix); // Compute r_0 = b - Ax_0 for some initial guess x_0 // In this case we take x_0 = vector // This is basically a SAXPY so it could be made a lot faster var residuals = new DenseVector(matrix.RowCount); CalculateTrueResidual(matrix, residuals, result, input); // Choose r~ (for example, r~ = r_0) var tempResiduals = residuals.Clone(); // create seven temporary vectors needed to hold temporary // coefficients. All vectors are mangled in each iteration. // These are defined here to prevent stressing the garbage collector var vecP = new DenseVector(residuals.Count); var vecPdash = new DenseVector(residuals.Count); var nu = new DenseVector(residuals.Count); var vecS = new DenseVector(residuals.Count); var vecSdash = new DenseVector(residuals.Count); var temp = new DenseVector(residuals.Count); var temp2 = new DenseVector(residuals.Count); // create some temporary float variables that are needed // to hold values in between iterations float currentRho = 0; float alpha = 0; float omega = 0; var iterationNumber = 0; while (ShouldContinue(iterationNumber, result, input, residuals)) { // rho_(i-1) = r~^T r_(i-1) // dotproduct r~ and r_(i-1) var oldRho = currentRho; currentRho = tempResiduals.DotProduct(residuals); // if (rho_(i-1) == 0) // METHOD FAILS // If rho is only 1 ULP from zero then we fail. if (currentRho.AlmostEqual(0, 1)) { // Rho-type breakdown throw new Exception("Iterative solver experience a numerical break down"); } if (iterationNumber != 0) { // beta_(i-1) = (rho_(i-1)/rho_(i-2))(alpha_(i-1)/omega(i-1)) var beta = (currentRho / oldRho) * (alpha / omega); // p_i = r_(i-1) + beta_(i-1)(p_(i-1) - omega_(i-1) * nu_(i-1)) nu.Multiply(-omega, temp); vecP.Add(temp, temp2); temp2.CopyTo(vecP); vecP.Multiply(beta, vecP); vecP.Add(residuals, temp2); temp2.CopyTo(vecP); } else { // p_i = r_(i-1) residuals.CopyTo(vecP); } // SOLVE Mp~ = p_i // M = preconditioner _preconditioner.Approximate(vecP, vecPdash); // nu_i = Ap~ matrix.Multiply(vecPdash, nu); // alpha_i = rho_(i-1)/ (r~^T nu_i) = rho / dotproduct(r~ and nu_i) alpha = currentRho * 1 / tempResiduals.DotProduct(nu); // s = r_(i-1) - alpha_i nu_i nu.Multiply(-alpha, temp); residuals.Add(temp, vecS); // Check if we're converged. If so then stop. Otherwise continue; // Calculate the temporary result. // Be careful not to change any of the temp vectors, except for // temp. Others will be used in the calculation later on. // x_i = x_(i-1) + alpha_i * p^_i + s^_i vecPdash.Multiply(alpha, temp); temp.Add(vecSdash, temp2); temp2.CopyTo(temp); temp.Add(result, temp2); temp2.CopyTo(temp); // Check convergence and stop if we are converged. if (!ShouldContinue(iterationNumber, temp, input, vecS)) { temp.CopyTo(result); // Calculate the true residual CalculateTrueResidual(matrix, residuals, result, input); // Now recheck the convergence if (!ShouldContinue(iterationNumber, result, input, residuals)) { // We're all good now. return; } // Continue the calculation iterationNumber++; continue; } // SOLVE Ms~ = s _preconditioner.Approximate(vecS, vecSdash); // temp = As~ matrix.Multiply(vecSdash, temp); // omega_i = temp^T s / temp^T temp omega = temp.DotProduct(vecS) / temp.DotProduct(temp); // x_i = x_(i-1) + alpha_i p^ + omega_i s^ temp.Multiply(-omega, residuals); residuals.Add(vecS, temp2); temp2.CopyTo(residuals); vecSdash.Multiply(omega, temp); result.Add(temp, temp2); temp2.CopyTo(result); vecPdash.Multiply(alpha, temp); result.Add(temp, temp2); temp2.CopyTo(result); // for continuation it is necessary that omega_i != 0.0 // If omega is only 1 ULP from zero then we fail. if (omega.AlmostEqual(0, 1)) { // Omega-type breakdown throw new Exception("Iterative solver experience a numerical break down"); } if (!ShouldContinue(iterationNumber, result, input, residuals)) { // Recalculate the residuals and go round again. This is done to ensure that // we have the proper residuals. // The residual calculation based on omega_i * s can be off by a factor 10. So here // we calculate the real residual (which can be expensive) but we only do it if we're // sufficiently close to the finish. CalculateTrueResidual(matrix, residuals, result, input); } iterationNumber++; } }
/// <summary> /// Clones this unnormalised discrete distribution. /// </summary> /// <returns>An object which is a clone of the current instance. This must be cast /// if you want to assign the result to a UnnormalizedDiscrete type</returns> public object Clone() { return(FromLogProbs((DenseVector)logProb.Clone())); }
/// <summary> /// Run example /// </summary> public void Run() { // Format vector output to console var formatProvider = (CultureInfo)CultureInfo.InvariantCulture.Clone(); formatProvider.TextInfo.ListSeparator = " "; // Create new empty vector var vectorA = new DenseVector(10); Console.WriteLine(@"Empty vector A"); Console.WriteLine(vectorA.ToString("#0.00\t", formatProvider)); Console.WriteLine(); // 1. Fill vector by data using indexer [] for (var i = 0; i < vectorA.Count; i++) { vectorA[i] = i; } Console.WriteLine(@"1. Fill vector by data using indexer []"); Console.WriteLine(vectorA.ToString("#0.00\t", formatProvider)); Console.WriteLine(); // 2. Fill vector by data using SetValues method vectorA.SetValues(new[] { 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0, 0.0 }); Console.WriteLine(@"2. Fill vector by data using SetValues method"); Console.WriteLine(vectorA.ToString("#0.00\t", formatProvider)); Console.WriteLine(); // 3. Convert Vector to double[] var data = vectorA.ToArray(); Console.WriteLine(@"3. Convert vector to double array"); for (var i = 0; i < data.Length; i++) { Console.Write(data[i].ToString("#0.00\t", formatProvider) + @" "); } Console.WriteLine(); Console.WriteLine(); // 4. Convert Vector to column matrix. A matrix based on this vector in column form (one single column) var columnMatrix = vectorA.ToColumnMatrix(); Console.WriteLine(@"4. Convert vector to column matrix"); Console.WriteLine(columnMatrix.ToString("#0.00\t", formatProvider)); Console.WriteLine(); // 5. Convert Vector to row matrix. A matrix based on this vector in row form (one single row) var rowMatrix = vectorA.ToRowMatrix(); Console.WriteLine(@"5. Convert vector to row matrix"); Console.WriteLine(rowMatrix.ToString("#0.00\t", formatProvider)); Console.WriteLine(); // 6. Clone vector var cloneA = vectorA.Clone(); Console.WriteLine(@"6. Clone vector"); Console.WriteLine(cloneA.ToString("#0.00\t", formatProvider)); Console.WriteLine(); // 7. Clear vector cloneA.Clear(); Console.WriteLine(@"7. Clear vector"); Console.WriteLine(cloneA.ToString("#0.00\t", formatProvider)); Console.WriteLine(); // 8. Copy part of vector into another vector. If you need to copy all data then use CopoTy(vector) method. vectorA.CopyTo(cloneA, 3, 3, 4); Console.WriteLine(@"8. Copy part of vector into another vector"); Console.WriteLine(cloneA.ToString("#0.00\t", formatProvider)); Console.WriteLine(); // 9. Get part of vector as another vector var subvector = vectorA.SubVector(0, 5); Console.WriteLine(@"9. Get subvector"); Console.WriteLine(subvector.ToString("#0.00\t", formatProvider)); Console.WriteLine(); // 10. Enumerator usage Console.WriteLine(@"10. Enumerator usage"); foreach (var value in vectorA) { Console.Write(value.ToString("#0.00\t", formatProvider) + @" "); } Console.WriteLine(); Console.WriteLine(); // 11. Indexed enumerator usage Console.WriteLine(@"11. Enumerator usage"); foreach (var value in vectorA.GetIndexedEnumerator()) { Console.WriteLine(@"Index = {0}; Value = {1}", value.Item1, value.Item2.ToString("#0.00\t", formatProvider)); } Console.WriteLine(); }
/// <summary> /// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the /// solution vector and x is the unknown vector. /// </summary> /// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param> /// <param name="input">The solution <see cref="Vector"/>, <c>b</c>.</param> /// <param name="result">The result <see cref="Vector"/>, <c>x</c>.</param> /// <param name="iterator">The iterator to use to control when to stop iterating.</param> /// <param name="preconditioner">The preconditioner to use for approximations.</param> public void Solve(Matrix <Maths.Complex32> matrix, Vector <Maths.Complex32> input, Vector <Maths.Complex32> result, Iterator <Maths.Complex32> iterator, IPreconditioner <Maths.Complex32> preconditioner) { if (matrix.RowCount != matrix.ColumnCount) { throw new ArgumentException("Matrix must be square.", nameof(matrix)); } if (result.Count != input.Count) { throw new ArgumentException("All vectors must have the same dimensionality."); } if (input.Count != matrix.RowCount) { throw Matrix.DimensionsDontMatch <ArgumentException>(input, matrix); } if (iterator == null) { iterator = new Iterator <Maths.Complex32>(); } if (preconditioner == null) { preconditioner = new UnitPreconditioner <Maths.Complex32>(); } preconditioner.Initialize(matrix); // Compute r_0 = b - Ax_0 for some initial guess x_0 // In this case we take x_0 = vector // This is basically a SAXPY so it could be made a lot faster var residuals = new DenseVector(matrix.RowCount); CalculateTrueResidual(matrix, residuals, result, input); // Choose r~ (for example, r~ = r_0) var tempResiduals = residuals.Clone(); // create seven temporary vectors needed to hold temporary // coefficients. All vectors are mangled in each iteration. // These are defined here to prevent stressing the garbage collector var vecP = new DenseVector(residuals.Count); var vecPdash = new DenseVector(residuals.Count); var nu = new DenseVector(residuals.Count); var vecS = new DenseVector(residuals.Count); var vecSdash = new DenseVector(residuals.Count); var temp = new DenseVector(residuals.Count); var temp2 = new DenseVector(residuals.Count); // create some temporary float variables that are needed // to hold values in between iterations Maths.Complex32 currentRho = 0; Maths.Complex32 alpha = 0; Maths.Complex32 omega = 0; var iterationNumber = 0; while (iterator.DetermineStatus(iterationNumber, result, input, residuals) == IterationStatus.Continue) { // rho_(i-1) = r~^T r_(i-1) // dotproduct r~ and r_(i-1) var oldRho = currentRho; currentRho = tempResiduals.ConjugateDotProduct(residuals); // if (rho_(i-1) == 0) // METHOD FAILS // If rho is only 1 ULP from zero then we fail. if (currentRho.Real.AlmostEqualNumbersBetween(0, 1) && currentRho.Imaginary.AlmostEqualNumbersBetween(0, 1)) { // Rho-type breakdown throw new NumericalBreakdownException(); } if (iterationNumber != 0) { // beta_(i-1) = (rho_(i-1)/rho_(i-2))(alpha_(i-1)/omega(i-1)) var beta = (currentRho / oldRho) * (alpha / omega); // p_i = r_(i-1) + beta_(i-1)(p_(i-1) - omega_(i-1) * nu_(i-1)) nu.Multiply(-omega, temp); vecP.Add(temp, temp2); temp2.CopyTo(vecP); vecP.Multiply(beta, vecP); vecP.Add(residuals, temp2); temp2.CopyTo(vecP); } else { // p_i = r_(i-1) residuals.CopyTo(vecP); } // SOLVE Mp~ = p_i // M = preconditioner preconditioner.Approximate(vecP, vecPdash); // nu_i = Ap~ matrix.Multiply(vecPdash, nu); // alpha_i = rho_(i-1)/ (r~^T nu_i) = rho / dotproduct(r~ and nu_i) alpha = currentRho * 1 / tempResiduals.ConjugateDotProduct(nu); // s = r_(i-1) - alpha_i nu_i nu.Multiply(-alpha, temp); residuals.Add(temp, vecS); // Check if we're converged. If so then stop. Otherwise continue; // Calculate the temporary result. // Be careful not to change any of the temp vectors, except for // temp. Others will be used in the calculation later on. // x_i = x_(i-1) + alpha_i * p^_i + s^_i vecPdash.Multiply(alpha, temp); temp.Add(vecSdash, temp2); temp2.CopyTo(temp); temp.Add(result, temp2); temp2.CopyTo(temp); // Check convergence and stop if we are converged. if (iterator.DetermineStatus(iterationNumber, temp, input, vecS) != IterationStatus.Continue) { temp.CopyTo(result); // Calculate the true residual CalculateTrueResidual(matrix, residuals, result, input); // Now recheck the convergence if (iterator.DetermineStatus(iterationNumber, result, input, residuals) != IterationStatus.Continue) { // We're all good now. return; } // Continue the calculation iterationNumber++; continue; } // SOLVE Ms~ = s preconditioner.Approximate(vecS, vecSdash); // temp = As~ matrix.Multiply(vecSdash, temp); // omega_i = temp^T s / temp^T temp omega = temp.ConjugateDotProduct(vecS) / temp.ConjugateDotProduct(temp); // x_i = x_(i-1) + alpha_i p^ + omega_i s^ temp.Multiply(-omega, residuals); residuals.Add(vecS, temp2); temp2.CopyTo(residuals); vecSdash.Multiply(omega, temp); result.Add(temp, temp2); temp2.CopyTo(result); vecPdash.Multiply(alpha, temp); result.Add(temp, temp2); temp2.CopyTo(result); // for continuation it is necessary that omega_i != 0.0f // If omega is only 1 ULP from zero then we fail. if (omega.Real.AlmostEqualNumbersBetween(0, 1) && omega.Imaginary.AlmostEqualNumbersBetween(0, 1)) { // Omega-type breakdown throw new NumericalBreakdownException(); } if (iterator.DetermineStatus(iterationNumber, result, input, residuals) != IterationStatus.Continue) { // Recalculate the residuals and go round again. This is done to ensure that // we have the proper residuals. // The residual calculation based on omega_i * s can be off by a factor 10. So here // we calculate the real residual (which can be expensive) but we only do it if we're // sufficiently close to the finish. CalculateTrueResidual(matrix, residuals, result, input); } iterationNumber++; } }
public static Vector Fit(Matrix input, Vector y) { if (input == null || y == null) { throw new ArgumentNullException("输入不能为空"); } if (input.RowCount != y.Count) { throw new ArgumentException("输入的长度不一致"); } //tol = 10*eps*norm(C,1)*length(C); // norm(C,1) = sum(abs(C)) var norm = new DenseVector(input.ColumnCount); for (int i = 0; i < input.RowCount; i++) { for (int j = 0; j < input.ColumnCount; j++) { norm[j] += Math.Abs(input[i, j]); } } var tol = 10 * Single.Epsilon * norm.Sum() * input.RowCount; var P = new DenseVector(input.ColumnCount); var Z = new DenseVector(input.ColumnCount); for (int i = 1; i <= Z.Count; i++) { Z[i - 1] = i; } var ra = P.Clone(); var ZZ = Z.Clone(); var resid = y - input * ra; var w = input.Transpose() * resid; // set up iteration criterion var outeriter = 0; var iter = 0; var itmax = 3 * input.ColumnCount; var exitflag = 1; while (Z.Any()) { var widx = ((Vector)w).Slice((Vector)ZZ.Subtract(1)); bool brk = true; foreach (var www in widx) { if ((www - tol) > 0) { brk = false; break; } } if (brk) { break; } if (!widx.Any()) { break; } outeriter++; var wt = widx.Maximum(); var t = widx.MaximumIndex(); t = (int)ZZ[t]; P[t - 1] = t; Z[t - 1] = 0; var PP = P.Find(); ZZ = Z.Find().Add(1); var nzz = ZZ.Count; var CP = new DenseMatrix(input.RowCount, input.ColumnCount); for (int j = 0; j < input.RowCount; j++) { foreach (var pj in PP) { CP[j, (int)pj] = input[j, (int)pj]; } foreach (var zj in ZZ) { CP[j, (int)zj - 1] = 0; } } var z = CP.PseudoInverse() * y; foreach (var zj in ZZ) { z[(int)zj - 1] = 0; } while (true) { var ztemp = ((Vector)z).Slice((Vector)PP); brk = true; foreach (var ztempp in ztemp) { if (ztempp <= tol) { brk = false; break; } } if (brk) { break; } iter = iter + 1; if (iter > itmax) { exitflag = 0; ra = z; break; } var lst = new List <int>(); for (int i = 0; i < z.Count; i++) { if (z[i] <= tol && P[i] != 0) { lst.Add(i); } } var QQ = lst.ToArray(); var ratemp = ((Vector)ra).Slice(QQ); var alpha = (ratemp.PointwiseDivide(ratemp - ((Vector)z).Slice(QQ))).Min(); ra = ra + alpha * (z - ra); lst = new List <int>(); for (int i = 0; i < ra.Count; i++) { if (Math.Abs(ra[i]) < tol && P[i] != 0) { lst.Add(i); } } foreach (var i in lst) { Z[i] = i; P[i] = 0; } PP = P.Find(); ZZ = Z.Find().Add(1); nzz = ZZ.Count; for (int j = 0; j < input.RowCount; j++) { foreach (var pj in PP) { CP[j, (int)pj] = input[j, (int)pj]; } foreach (var zj in ZZ) { CP[j, (int)zj - 1] = 0; } } z = CP.PseudoInverse() * y; foreach (var zj in ZZ) { z[(int)zj - 1] = 0; } } ra = z; resid = y - input * ra; w = input.Transpose() * resid; } return((Vector)ra); }
public void Fit(IList <Point> points, ref double alpha, ref double beta, ref double gamma) { var model = new Model(); var minimumDeltaValue = 1; var minimumDeltaParameters = 1; var maximumIterations = 10; var pointCount = points.Count; Vector <double> dataX = new DenseVector(points.Select(p => p.X).ToArray()); Vector <double> dataY = new DenseVector(points.Select(p => p.Y).ToArray()); var iterations = new List <Vector <double> >(); var guess = new[] { alpha, beta, gamma }; Vector <double> parametersCurrent = new DenseVector(guess); Vector <double> parametersNew = new DenseVector(parametersCurrent.Count); var valueCurrent = GetObjectiveValue(model, pointCount, dataX, dataY, parametersCurrent[0], parametersCurrent[1], parametersCurrent[2]); while (true) { var jacobian = GetObjectiveJacobian(model, pointCount, dataX, parametersCurrent[0], parametersCurrent[1], parametersCurrent[2]); var residual = model.GetResidualVector(pointCount, dataX, dataY, parametersCurrent[0], parametersCurrent[1], parametersCurrent[2]); try { var jacobianT = jacobian.Transpose(); var res = jacobianT.Multiply(residual); var jjT = jacobian.Transpose().Multiply(jacobian); var cholesky = jjT.Cholesky(); var step = cholesky.Solve(res); parametersCurrent.Subtract(step, parametersNew); } catch (Exception) { alpha = 0; beta = 0; gamma = 0; return; } var valueNew = GetObjectiveValue(model, pointCount, dataX, dataY, parametersCurrent[0], parametersCurrent[1], parametersCurrent[2]); iterations.Add(parametersNew.Clone()); if (ShouldTerminate(valueCurrent, valueNew, iterations.Count, parametersCurrent, parametersNew, minimumDeltaValue, minimumDeltaParameters, maximumIterations)) { break; } parametersNew.CopyTo(parametersCurrent); valueCurrent = valueNew; } alpha = parametersCurrent[0]; beta = parametersCurrent[1]; gamma = parametersCurrent[2]; }