private SparseLU lu; //Initialize the LU factorizaation /// <summary> /// This is a small routine call to initialize the Neuron Cell /// this will initialize the solution vectors which are <c>U</c>, <c>M</c>, <c>N</c>, and <c>H</c> /// </summary> protected override void PreSolve() { InitializeNeuronCell(); ///<c>R</c> this is the reaction vector for the reaction solve R = Vector.Build.Dense(Neuron.nodes.Count); ///<c>reactConst</c> this is a small list for collecting the conductances and reversal potential which is sent to the reaction solve routine reactConst = new List <double> { gk, gna, gl, ek, ena, el }; /// this sets the target time step size timeStep = SetTargetTimeStep(cap, 2 * Neuron.MaxRadius, Neuron.TargetEdgeLength, gna, gk, res, Rmemscf, cfl); ///UnityEngine.Debug.Log("Target Time Step = " + timeStep); ///<c>List<CoordinateStorage<double>> sparse_stencils = makeSparseStencils(Neuron, res, cap, k);</c> Construct sparse RHS and LHS in coordinate storage format, no zeros are stored \n /// <c>sparse_stencils</c> this is a list which contains only two matrices the LHS and RHS matrices for the Crank-Nicolson solve sparse_stencils = makeSparseStencils(Neuron, res, cap, timeStep); ///<c>CompressedColumnStorage</c> call Compresses the sparse matrices which are stored in <c>sparse_stencils[0]</c> and <c>sparse_stencils[1]</c> r_csc = CompressedColumnStorage <double> .OfIndexed(sparse_stencils[0]); //null; l_csc = CompressedColumnStorage <double> .OfIndexed(sparse_stencils[1]); //null; ///<c>double [] b</c> we define storage for the diffusion solve part b = new double[Neuron.nodes.Count]; ///<c>var lu = SparseLU.Create(l_csc, ColumnOrdering.MinimumDegreeAtA, 0.1);</c> this creates the LU decomposition of the HINES matrix which is defined by <c>l_csc</c> lu = SparseLU.Create(l_csc, ColumnOrdering.MinimumDegreeAtA, 0.1); }
public static Vector SolveLU(CompressedColumnStorage <double> A, Vector x, Vector b, out bool status, out string algorithm) { var orderings = new[] { CSparse.ColumnOrdering.MinimumDegreeAtPlusA, CSparse.ColumnOrdering.MinimumDegreeAtA, CSparse.ColumnOrdering.MinimumDegreeStS, CSparse.ColumnOrdering.Natural }; status = false; algorithm = "LU"; try { status = true; if (A.RowCount == A.ColumnCount) { var lu = new SparseLU(A, CSparse.ColumnOrdering.MinimumDegreeAtA, 1.0); var xc = x.Clone(); var bc = b.Clone(); lu.Solve(bc.ToDouble(), xc.ToDouble()); algorithm = "LU/" + CSparse.ColumnOrdering.MinimumDegreeAtPlusA; status = true; return(xc); } } catch (Exception e) { status = false; } return(x); }
public void TestEmptyFactorize() { var A = new SparseMatrix(0, 0, 0); var lu = SparseLU.Create(A, ColumnOrdering.MinimumDegreeAtPlusA, 1.0); Assert.NotNull(lu); Assert.IsTrue(lu.NonZerosCount == 0); }
private double[] SolveSparseSystem(double[] h) { var order = ColumnOrdering.MinimumDegreeAtPlusA; double tolerance = 1.0; var lu = SparseLU.Create(Converter.ToCompressedColumnStorage(globalK), order, tolerance); lu.Solve(globalF, h); return(h); }
public SparseLUSolver(int totalCases, double[,] matrix, double[] vector) { TotalCases = totalCases; CompressedColumnStorage <double> e = CompressedColumnStorage <double> .OfArray(matrix); SparseLUMatrix = SparseLU.Create(e, CSparse.ColumnOrdering.MinimumDegreeAtPlusA, 1.0); SparseLUVector = vector; SparseLUResultVector = Vector.Create(vector.Length, 1.0); SparseLUMethod(); }
/// <summary> /// Performs the LU factorization: A = L * U of a ssquare matrix A. The matrix A is provided in CSC format by /// <paramref name="cscValues"/>, <paramref name="cscRowIndices"/> and <paramref name="cscColOffsets"/>. /// </summary> /// <param name="order">The number of rows/columns of the square matrix.</param> /// <param name="numNonZeros">The number of explicitly stored entries of the matrix before the factorization.</param> /// <param name="cscValues"> /// Contains the non-zero entries of the upper triangle. Its length must be equal to <paramref name="numNonZeros"/>. /// The non-zero entries of each row must appear consecutively in <paramref name="cscValues"/>. They should also be /// sorted in increasing order of their row indices, to speed up subsequent the factorization. /// </param> /// <param name="cscRowIndices"> /// Contains the row indices of the non-zero entries. Its length must be equal to <paramref name="numNonZeros"/>. /// There is an 1 to 1 matching between these two arrays: <paramref name="cscRowIndices"/>[i] is the row index of the /// entry <paramref name="cscValues"/>[i]. Also: 0 <= <paramref name="cscRowIndices"/>[i] < /// <paramref name="order"/>. /// </param> /// <param name="cscColOffsets"> /// Contains the index of the first entry of each column into the arrays <paramref name="cscValues"/> and /// <paramref name="cscRowIndices"/>. Its length must be <paramref name="order"/> + 1. The last entry must be /// <paramref name="numNonZeros"/>. /// </param> /// <param name="pivotTolerance">The partial pivoting tolerance (from 0.0 to 1.0).</param> /// <exception cref="SingularMatrixException">Thrown if the original matrix is not positive definite.</exception> public static LUCSparseNet Factorize(int order, int numNonZeros, double[] cscValues, int[] cscRowIndices, int[] cscColOffsets, double pivotTolerance = defaultPivotTolelance) { try { var matrixCSparse = new SparseMatrix(order, order, cscValues, cscRowIndices, cscColOffsets); var factorization = SparseLU.Create(matrixCSparse, ColumnOrdering.Natural, pivotTolerance); return(new LUCSparseNet(order, factorization)); } catch (Exception ex) //TODO: how can I make sure this exception was thrown because of an indefinite matrix? { throw new SingularMatrixException(ex.Message); } }
public void TestSolve() { // Load matrix from a file. var A = ResourceLoader.Get <Complex>("general-40x40.mat"); // Create test data. var x = Helper.CreateTestVector(A.ColumnCount); var b = Helper.Multiply(A, x); var r = Vector.Clone(b); // Create LU factorization. var lu = SparseLU.Create(A, ColumnOrdering.MinimumDegreeAtPlusA, 1.0); // Solve Ax = b. lu.Solve(b, x); // Compute residual r = b - Ax. A.Multiply(-1.0, x, 1.0, r); Assert.IsTrue(Vector.Norm(r.Length, r) < EPS); }
/// <inheritdoc /> public void Initialize() { var matrix = A; var sp = new Stopwatch(); sp.Start(); lu = SparseLU.Create(matrix, ColumnOrdering.MinimumDegreeAtPlusA, 0.01); IsInitialized = true; sp.Stop(); if (Target != null) { Target.Trace.Write(TraceRecord.Create(BriefFiniteElementNet.Common.TraceLevel.Info, string.Format(CultureInfo.CurrentCulture, "LU decomposition of matrix took about {0:#,##0} ms", sp.ElapsedMilliseconds))); } }
public static Vector SolveLU(CompressedColumnStorage <double> A, Vector x, Vector b, out bool status, out string error) { var orderings = new[] { CSparse.ColumnOrdering.MinimumDegreeAtPlusA, CSparse.ColumnOrdering.MinimumDegreeAtA, CSparse.ColumnOrdering.MinimumDegreeStS, CSparse.ColumnOrdering.Natural }; status = false; error = null; try { status = true; if (A.RowCount == A.ColumnCount) { var lu = SparseLU.Create(A, CSparse.ColumnOrdering.MinimumDegreeAtPlusA, 1.0); lu.Solve(b.ToDouble(), x.ToDouble()); status = true; return(x); } } catch (Exception e) { error = e.Message; status = false; } return(x); }
private void Solve() { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); double[] h = new double[Codend.dof]; double PrevTowSpeed = Codend.towSpeed; int PrevCatch = Codend.GetMeshesBlocked(); SparseLU LU; var LUorder = ColumnOrdering.MinimumDegreeAtPlusA; double LUtolerance = 1.0; bool hasConverged = false; // convergence flag bool correctSolution = false; // correctness of solution flag bool hasDiverged = false; // restart flag bool usePrecalc = CheckPrecalc(); int restartsCount = 0; int iter = 0; double hNorm = 1; double addStiff = SolverSettings.DiagStiffness; double addStiff0 = SolverSettings.DiagStiffness; double tolStiff = SolverSettings.StiffnessTol; //============================= // Start calculation //============================= for (int stage = 1; stage <= 2; stage++) { //=========================== // Restarts loop //=========================== while (!correctSolution) { // Set initial shape depending on whether it is precalculated from previous stage or not Codend.ClearState(); SetStageInitialShape(stage); Codend.UpdateTotalForces(IncludeBC: true); Codend.UpdateResidual(); if (addStiff0 == 0 && restartsCount > 0) // if the scheme doesnt work without extra stiffness { addStiff0 = 1; } addStiff = addStiff0; tolStiff = SolverSettings.StiffnessTol; //=========================== // Newton-Raphson loop //=========================== while (!hasConverged) { // check if diverged if (Codend.R > SolverSettings.ResidualMax) { hasDiverged = true; break; } // check whether to add less diagonal stiffness if (Codend.R < tolStiff) { addStiff *= SolverSettings.ReduceStiffnessBy; tolStiff *= SolverSettings.ReduceStiffnessBy; } // check if converged and no stiffness is added if (Codend.R < SolverSettings.ResidualTol && hNorm < SolverSettings.DisplacementTol) { break; } Codend.UpdateTotalJacobian(kDiag: -addStiff, IncludeBC: true); LU = SparseLU.Create(Codend.J, LUorder, LUtolerance); LU.Solve(Codend.F, h); hNorm = DisplacmentNorm(h); Codend.UpdatePosition(h, 1); Codend.UpdateTotalForces(IncludeBC: true); Codend.UpdateResidual(); iter++; // display iteration status Console.WriteLine( PrintIter(iter, 0, addStiff, Codend.R, hNorm)); } //=================== // Restart routine //=================== if (hasDiverged || IsIncorrectSolution()) { restartsCount += 1; addStiff0 *= SolverSettings.IncreaseStiffnessBy; ReportRestartCause(hasDiverged); hasDiverged = false; } else { correctSolution = true; // correct solution found Console.WriteLine("\nConvergence acheived in {0} iterations and {1} restarts in {2} [ms]\n", iter, restartsCount, stopwatch.ElapsedMilliseconds); } } if (usePrecalc) { Codend.X.CopyTo(precalcX, 0); Codend.ApplyCatch(PrevCatch); Codend.ApplyTowing(PrevTowSpeed); Console.WriteLine("\nInitial shape is precalculated. Moiving to and actual case.\n"); correctSolution = false; usePrecalc = false; hasConverged = false; } else { break; } } }
public void mosek2(List<leaf> _listLeaf, List<branch> _listBranch, List<node> _listNode, double force) { //variable settings ShoNS.Array.SparseDoubleArray mat = new SparseDoubleArray(_listNode.Count * 3, _listNode.Count * 3); ShoNS.Array.SparseDoubleArray F = new SparseDoubleArray(_listNode.Count * 3, 1); ShoNS.Array.SparseDoubleArray xx = new SparseDoubleArray(_listNode.Count*3,1); ShoNS.Array.SparseDoubleArray shift = new SparseDoubleArray(_listNode.Count*3, _listNode.Count*3); for (int k = 0; k < _listNode.Count;k++ ) { var node = _listNode[k]; xx[k * 3 + 0, 0] = node.x; xx[k * 3 + 1, 0] = node.y; xx[k * 3 + 2, 0] = node.z; /* if (node.nodeType == node.type.fx) { for (int i = 0; i < node.shareB.Count; i++) { var branch = node.shareB[i]; var index = node.numberB[i]; if (branch.branchType == branch.type.fix) { node.x = branch.crv.Points[index].Location.X; node.y = branch.crv.Points[index].Location.Y; node.z = branch.slice2.height; xx[k * 3 + 0, 0] = node.x; xx[k * 3 + 1, 0] = node.y; xx[k * 3 + 2, 0] = node.z; } } }*/ } List<int> series=new List<int>(); List<Point3d> origin = new List<Point3d>(); for(int i=0;i<_listNode.Count;i++) { series.Add(i); } int L1=0; int L2=_listNode.Count; for(int i=0;i<_listNode.Count;i++) { var node=_listNode[i]; if(node.nodeType==node.type.fx) { L2--; series[i]=L2; }else{ series[i]=L1; origin.Add(new Point3d(node.x, node.y, node.z)); L1++; } } for (int i = 0; i < _listNode.Count; i++) { shift[i * 3 + 0, series[i] * 3 + 0] = 1; shift[i * 3 + 1, series[i] * 3 + 1] = 1; shift[i * 3 + 2, series[i] * 3 + 2] = 1; F[i * 3 + 2, 0] = -force;//force } foreach (var leaf in _listLeaf) { foreach (var tup in leaf.tuples) { var det = tup.SPK[0, 0] * tup.SPK[1, 1] - tup.SPK[0, 1] * tup.SPK[0, 1]; if (det > 0) { for (int i = 0; i < tup.nNode; i++) { for (int j = 0; j < tup.nNode; j++) { for (int k = 0; k < 3; k++) { for (int l = 0; l < 2; l++) { for (int m = 0; m < 2; m++) { var val = tup.B[l, m, i * 3 + k, j * 3 + k] * tup.SPK[l, m] * tup.refDv * tup.area; mat[leaf.globalIndex[tup.internalIndex[i]] * 3 + k, leaf.globalIndex[tup.internalIndex[j]] * 3 + k] += val; } } } } } } } } foreach (var branch in _listBranch) { foreach (var tup in branch.tuples) { for (int i = 0; i < tup.nNode; i++) { for (int j = 0; j < tup.nNode; j++) { for (int k = 0; k < 3; k++) { //if (tup.SPK[0, 0] > 0) { var val = tup.B[0, 0, i * 3 + k, j * 3 + k] * tup.SPK[0, 0] * tup.refDv * tup.area; for (int l = 0; l < 1; l++) { for (int m = 0; m < 1; m++) { var val2 = tup.B[l, m, i * 3 + k, j * 3 + k] * tup.SPK[l, m] * tup.refDv * tup.area; mat[branch.globalIndex[tup.internalIndex[i]] * 3 + k, branch.globalIndex[tup.internalIndex[j]] * 3 + k] += val2; } } } } } } } } var reactionForce = mat * xx as SparseDoubleArray; double max1 = 0; double max2 = 0; for (int i = 0; i < _listNode.Count; i++) { if (_listNode[i].nodeType == node.type.fr) { var nx = reactionForce[i * 3 + 0, 0]; var ny = reactionForce[i * 3 + 1, 0]; var norm = Math.Sqrt(nx * nx + ny * ny); if (norm > max1) max1 = norm; } else { var nx = reactionForce[i * 3 + 0, 0]; var ny = reactionForce[i * 3 + 1, 0]; var norm = Math.Sqrt(nx * nx + ny * ny); if (norm > max2) max2 = norm; } } //System.Windows.Forms.MessageBox.Show(max1.ToString() + ".-." + max2.ToString()); var newMat = (shift.T.Multiply(mat) as SparseDoubleArray).Multiply(shift) as SparseDoubleArray; var newxx = shift.T.Multiply(xx) as SparseDoubleArray; var newF = shift.T.Multiply(F) as SparseDoubleArray; var T = newMat.GetSliceDeep(0, L1 * 3 - 1, 0, L1 * 3 - 1); var D = newMat.GetSliceDeep(0, L1 * 3 - 1, L1 * 3, _listNode.Count * 3 - 1); var fx = newxx.GetSliceDeep(L1 * 3, _listNode.Count * 3 - 1, 0, 0); newF = newF.GetSliceDeep(0, L1 * 3 - 1, 0, 0); var solve = new SparseLU(T); //var solve = new SparseSVD(T); //var _U = solve.U; //var _V = solve.V; //var _D = solve.D; //double tol=0.00000000001; //for (int i = 0; i < L1*3; i++) //{ // if (_D[i, i] > tol) _D[i, i] = 1d / _D[i, i]; // else if (_D[i, i] < -tol) _D[i, i] = 1d / _D[i, i]; // else _D[i, i] = 0d; //} var df = D * fx as SparseDoubleArray; var b = DoubleArray.From((-newF - df)); var sol=solve.Solve(b); //var sol = _V * _D * _U.T*b; var exSol = new SparseDoubleArray(sol.GetLength(0)+fx.GetLength(0),1); for (int i = 0; i < L1; i++) { exSol[i * 3 + 0, 0] = sol[i * 3 + 0, 0]; exSol[i * 3 + 1, 0] = sol[i * 3 + 1, 0]; exSol[i * 3 + 2, 0] = sol[i * 3 + 2, 0]; } for (int i = L1; i < _listNode.Count; i++) { exSol[i * 3 + 0, 0] = fx[(i - L1) * 3 + 0, 0]; exSol[i * 3 + 1, 0] = fx[(i - L1) * 3 + 1, 0]; exSol[i * 3 + 2, 0] = fx[(i - L1) * 3 + 2, 0]; } exSol = shift.Multiply(exSol) as SparseDoubleArray; foreach (var branch in _listBranch) { branch.shellCrv = branch.crv.Duplicate() as NurbsCurve; for (int i = 0; i < branch.N; i++) { var P = branch.shellCrv.Points[i].Location; branch.shellCrv.Points.SetPoint(i, new Point3d(exSol[branch.globalIndex[i] * 3 + 0, 0], exSol[branch.globalIndex[i] * 3 + 1, 0], exSol[branch.globalIndex[i] * 3 + 2, 0])); //if you don't want to allow movements of x and y coordinates, use the following instead of the above. //branch.shellCrv.Points.SetPoint(i, new Point3d(P.X, P.Y, exSol[branch.globalIndex[i] * 3 + 2, 0])); } } foreach (var leaf in _listLeaf) { leaf.shellSrf = leaf.srf.Duplicate() as NurbsSurface; for (int i = 0; i < leaf.nU; i++) { for (int j = 0; j < leaf.nV; j++) { var P = leaf.shellSrf.Points.GetControlPoint(i, j).Location; leaf.shellSrf.Points.SetControlPoint(i, j, new ControlPoint(exSol[leaf.globalIndex[i + j * leaf.nU] * 3 + 0, 0], exSol[leaf.globalIndex[i + j * leaf.nU] * 3 + 1, 0], exSol[leaf.globalIndex[i + j * leaf.nU] * 3 + 2, 0])); //if you don't want to allow movements of x and y coordinates, use the following instead of the above. //leaf.shellSrf.Points.SetControlPoint(i, j, new ControlPoint(P.X, P.Y, exSol[leaf.globalIndex[i + j * leaf.nU] * 3 + 2, 0])); } } } }
public DisposableSparseLU(SparseMatrix matrix) { lu = SparseLU.Create(matrix, ColumnOrdering.MinimumDegreeAtPlusA, 0.1); }
private LUCSparseNet(int order, SparseLU factorization) { this.Order = order; this.factorization = factorization; }