public static CholmodInfo ConverterDouble(ref SparseMatrixDouble A, CholmodInfo.CholmodMatrixStorage storage) { CholmodInfo info = new CholmodInfo(); info.MatrixType = CholmodInfo.CholmodMatrixType.Sparse; info.MatrixStorageType = storage; info.RowCount = A.RowCount; info.ColumnCount = A.ColumnCount; switch (storage) { case CholmodInfo.CholmodMatrixStorage.CRS: A.ToCRS(out info.rowIndex, out info.colIndex, out info.values, out info.nnz); break; case CholmodInfo.CholmodMatrixStorage.CCS: A.ToCCS(out info.colIndex, out info.rowIndex, out info.values, out info.nnz); break; case CholmodInfo.CholmodMatrixStorage.Triplet: A.ToTriplet(out info.colIndex, out info.rowIndex, out info.values, out info.nnz); break; default: A.ToTriplet(out info.colIndex, out info.rowIndex, out info.values, out info.nnz); break; } return info; }
public DECMeshDouble(TriMesh mesh) { Stopwatch clock = new Stopwatch(); clock.Start(); HodgeStar0Form = DECDouble.Instance.BuildHodgeStar0Form(mesh); clock.Stop(); decimal micro = clock.Elapsed.Ticks / 10m; Console.WriteLine("Total Building Matrix star0 time cost:{0}", micro); clock.Start(); HodgeStar1Form = DECDouble.Instance.BuildHodgeStar1Form(mesh); clock.Stop(); micro = clock.Elapsed.Ticks / 10m; Console.WriteLine("Total Building Matrix star1 time cost:{0}", micro); clock.Start(); ExteriorDerivative0Form = DECDouble.Instance.BuildExteriorDerivative0Form(mesh); clock.Stop(); micro = clock.Elapsed.Ticks / 10m; Console.WriteLine("Total Building Matrix d0 time cost:{0}", micro); clock.Start(); ExteriorDerivative1Form = DECDouble.Instance.BuildExteriorDerivative1Form(mesh); clock.Stop(); micro = clock.Elapsed.Ticks / 10m; Console.WriteLine("Total Building Matrix d1 time cost:{0}", micro); }
// solves the positive definite sparse linear system Ax = b using sparse QR factorization public DenseMatrixDouble solveLeastNormal(ref SparseMatrixDouble A, ref DenseMatrixDouble b) { LinearSystemGenericByLib linearSolver = new LinearSystemGenericByLib(); linearSolver.FactorizationQR(ref A); DenseMatrixDouble x = null; linearSolver.FreeSolver(); return x; }
// solves the positive definite sparse linear system Ax = b using sparse Cholesky factorization public DenseMatrixDouble solvePositiveDefinite(ref SparseMatrixDouble A, ref DenseMatrixDouble b) { LinearSystemGenericByLib linearSolver = new LinearSystemGenericByLib(); linearSolver.FactorizationCholesky(ref A); DenseMatrixDouble x = null; linearSolver.FreeSolver(); return x; }
public Eigen ComputeEigensByLib(SparseMatrix sparse, int count) { SparseMatrixDouble ds = new SparseMatrixDouble(sparse); Eigen eigen = ComputeEigensByLib(ds, 0.0, count); return eigen; }
// solves the positive definite sparse linear system Ax = b using sparse QR factorization public DenseMatrixDouble solveLeastNormal(ref SparseMatrixDouble A, ref DenseMatrixDouble b) { LinearSystemGenericByLib linearSolver = new LinearSystemGenericByLib(); linearSolver.FactorizationQR(ref A); DenseMatrixDouble x = null; linearSolver.FreeSolver(); return(x); }
// solves the positive definite sparse linear system Ax = b using sparse Cholesky factorization public DenseMatrixDouble solvePositiveDefinite(ref SparseMatrixDouble A, ref DenseMatrixDouble b) { LinearSystemGenericByLib linearSolver = new LinearSystemGenericByLib(); linearSolver.FactorizationCholesky(ref A); DenseMatrixDouble x = null; linearSolver.FreeSolver(); return(x); }
public static SparseMatrixDouble Copy(ref SparseMatrixDouble B) { Dictionary <Pair, double> newData = new Dictionary <Pair, double>(B.mapData); SparseMatrixDouble newMatrix = new SparseMatrixDouble(B.rowCount, B.columnCount); newMatrix.mapData = newData; return(newMatrix); }
public Eigen ComputeEigensByLib(SparseMatrixDouble sparse, double sigma, int count) { int[] pCol; int[] iRow; double[] Values; int NNZ; int m = sparse.RowCount; sparse.ToCCS(out pCol, out iRow, out Values, out NNZ); double[] ImagePart = new double[count]; double[] RealPart = new double[count]; double[] Vectors = new double[count * m]; fixed(int *ri = iRow, cp = pCol) fixed(double *val = Values, vets = Vectors, imgPart = ImagePart, relPart = RealPart) { int result = ComputeEigenNoSymmetricShiftModeCRS(ri, cp, val, NNZ, m, count, sigma, relPart, imgPart, vets); } List <EigenPair> list = new List <EigenPair>(); for (int i = 0; i < count; i++) { double realPart = RealPart[i]; List <double> vector = new List <double>(); int startIndex = i * m; int endIndex = i * m + m; for (int j = startIndex; j < endIndex; j++) { double value = Vectors[j]; vector.Add(value); } EigenPair newPair = new EigenPair(realPart, vector); list.Add(newPair); } list.Sort(); Eigen eigen = new Eigen(); eigen.SortedEigens = list.ToArray(); return(eigen); }
public SparseMatrixDouble SubMatrix(int rowStart, int rowEnd, int columnStart, int columnEnd) { if (rowEnd < rowStart || columnEnd < columnStart) { throw new ArgumentOutOfRangeException(); } int rows = rowEnd - rowStart + 1; int columns = columnEnd - columnStart + 1; SparseMatrixDouble subMatrix = new SparseMatrixDouble(rows, columns); int subMatrixEntiries = rows * columns; if (subMatrixEntiries < mapData.Count) { for (int i = 0; i < rows; i++) { int rowInx = i + rowStart; for (int j = 0; j < columns; j++) { int columnInx = j + columnStart; Pair pair = new Pair(rowInx, columnInx); if (!mapData.ContainsKey(pair)) { continue; } Pair subPair = new Pair(i, j); subMatrix.mapData[subPair] = mapData[pair]; } } } else if (subMatrixEntiries >= mapData.Count) { foreach (KeyValuePair <Pair, double> item in mapData) { Pair pair = item.Key; double value = item.Value; int m = pair.Key; int n = pair.Value; if ((m >= rowStart && m <= rowEnd) && (n >= columnStart && m <= columnEnd)) { int i = m - rowStart; int j = n - columnStart; subMatrix.mapData[new Pair(i, j)] = value; } } } return(subMatrix); }
public static SparseMatrixDouble Identity(int N) { SparseMatrixDouble identity = new SparseMatrixDouble(N, N); for (int i = 0; i < N; i++) { identity.mapData.Add(new Pair(i, i), 1); } return(identity); }
public Eigen ComputeEigensByLib(SparseMatrixDouble sparse, double sigma, int count) { int[] pCol; int[] iRow; double[] Values; int NNZ; int m = sparse.RowCount; sparse.ToCCS(out pCol, out iRow, out Values, out NNZ); double[] ImagePart = new double[count]; double[] RealPart = new double[count]; double[] Vectors = new double[count * m]; fixed (int* ri = iRow, cp = pCol) fixed (double* val = Values, vets = Vectors, imgPart = ImagePart, relPart = RealPart) { int result = ComputeEigenNoSymmetricShiftModeCRS(ri, cp, val, NNZ, m, count, sigma, relPart, imgPart, vets); } List<EigenPair> list = new List<EigenPair>(); for (int i = 0; i < count; i++) { double realPart = RealPart[i]; List<double> vector = new List<double>(); int startIndex = i * m; int endIndex = i * m + m; for (int j = startIndex; j < endIndex; j++) { double value = Vectors[j]; vector.Add(value); } EigenPair newPair = new EigenPair(realPart, vector); list.Add(newPair); } list.Sort(); Eigen eigen = new Eigen(); eigen.SortedEigens = list.ToArray(); return eigen; }
public static CholmodInfo ConverterDouble(ref SparseMatrixDouble A) { CholmodInfo info = new CholmodInfo(); info.MatrixType = CholmodInfo.CholmodMatrixType.Sparse; info.RowCount = A.RowCount; info.ColumnCount = A.ColumnCount; A.ToTriplet(out info.colIndex, out info.rowIndex, out info.values, out info.nnz); return(info); }
public static CholmodInfo ConverterDouble(ref SparseMatrixDouble A) { CholmodInfo info = new CholmodInfo(); info.MatrixType = CholmodInfo.CholmodMatrixType.Sparse; info.RowCount = A.RowCount; info.ColumnCount = A.ColumnCount; A.ToTriplet(out info.colIndex, out info.rowIndex, out info.values, out info.nnz); return info; }
public SparseMatrixDouble BuildHodgeStar2Form(TriMesh mesh) { SparseMatrixDouble star2 = new SparseMatrixDouble(mesh.Faces.Count, mesh.Faces.Count); foreach (TriMesh.Face face in mesh.Faces) { star2[face.Index, face.Index] = 1 / TriMeshUtil.ComputeAreaFace(face); } Star2 = star2; return(star2); }
public SparseMatrixDouble BuildHodgeStar0Form(TriMesh mesh) { SparseMatrixDouble star0 = new SparseMatrixDouble(mesh.Vertices.Count, mesh.Vertices.Count); foreach (TriMesh.Vertex vertex in mesh.Vertices) { star0[vertex.Index, vertex.Index] = ComputeVertexDualArea(vertex); } this.Star0 = star0; return star0; }
public SparseMatrixDouble BuildHodgeStar0Form(TriMesh mesh) { SparseMatrixDouble star0 = new SparseMatrixDouble(mesh.Vertices.Count, mesh.Vertices.Count); foreach (TriMesh.Vertex vertex in mesh.Vertices) { star0[vertex.Index, vertex.Index] = ComputeVertexDualArea(vertex); } this.Star0 = star0; return(star0); }
public static SparseMatrixDouble operator *(double left, SparseMatrixDouble right) { SparseMatrixDouble result = new SparseMatrixDouble(right.rowCount, right.columnCount); foreach (KeyValuePair <Pair, double> item in right.mapData) { Pair pair = item.Key; double value = left * item.Value; result.mapData.Add(pair, value); } return(result); }
public static SparseMatrixDouble operator *(double left, SparseMatrixDouble right) { SparseMatrixDouble result = new SparseMatrixDouble(right.rowCount, right.columnCount); foreach (KeyValuePair<Pair, double> item in right.mapData) { Pair pair = item.Key; double value = left * item.Value; result.mapData.Add(pair, value); } return result; }
public SparseMatrixDouble Transpose() { SparseMatrixDouble trMatrix = new SparseMatrixDouble(this.columnCount, this.rowCount); foreach (KeyValuePair <Pair, double> item in mapData) { Pair pair = item.Key; double value = item.Value; trMatrix.mapData[new Pair(pair.Value, pair.Key)] = value; } return(trMatrix); }
public void ToCRS(out int[] rowPtr, out int[] colIndices, out double[] values, out int nnz) { SparseMatrixDouble sparse = new SparseMatrixDouble(4 * this.rowCount, 4 * this.columnCount); foreach (KeyValuePair <Pair, Quaternion> e in mapData) { Pair pair = e.Key; double q0 = e.Value.x; double q1 = e.Value.y; double q2 = e.Value.z; double q3 = e.Value.w; if (q0 != 0) { sparse.Datas.Add(new Pair(4 * pair.Key, 4 * pair.Value), q0); sparse.Datas.Add(new Pair(4 * pair.Key + 1, 4 * pair.Value + 1), q0); sparse.Datas.Add(new Pair(4 * pair.Key + 2, 4 * pair.Value + 2), q0); sparse.Datas.Add(new Pair(4 * pair.Key + 3, 4 * pair.Value + 3), q0); } if (q1 != 0) { sparse.Datas.Add(new Pair(4 * pair.Key + 1, 4 * pair.Value), q1); sparse.Datas.Add(new Pair(4 * pair.Key, 4 * pair.Value + 1), q1); sparse.Datas.Add(new Pair(4 * pair.Key + 3, 4 * pair.Value + 2), q1); sparse.Datas.Add(new Pair(4 * pair.Key + 2, 4 * pair.Value + 3), q1); } if (q2 != 0) { sparse.Datas.Add(new Pair(4 * pair.Key + 2, 4 * pair.Value), q1); sparse.Datas.Add(new Pair(4 * pair.Key, 4 * pair.Value + 2), q1); sparse.Datas.Add(new Pair(4 * pair.Key + 3, 4 * pair.Value + 1), q1); sparse.Datas.Add(new Pair(4 * pair.Key + 1, 4 * pair.Value + 3), q1); } if (q3 != 0) { sparse.Datas.Add(new Pair(4 * pair.Key + 3, 4 * pair.Value), q1); sparse.Datas.Add(new Pair(4 * pair.Key, 4 * pair.Value + 3), q1); sparse.Datas.Add(new Pair(4 * pair.Key + 2, 4 * pair.Value + 1), q1); sparse.Datas.Add(new Pair(4 * pair.Key + 1, 4 * pair.Value + 2), q1); } } sparse.ToCRS(out rowPtr, out colIndices, out values, out nnz); }
public SparseMatrixDouble BuildHodgeStar1Form(TriMesh mesh) { SparseMatrixDouble star1 = new SparseMatrixDouble(mesh.Edges.Count, mesh.Edges.Count); foreach (TriMesh.Edge edge in mesh.Edges) { double cotAlpha = ComputeTan(edge.HalfEdge0); double cotBeta = ComputeTan(edge.HalfEdge1); star1[edge.Index, edge.Index] = (cotAlpha + cotBeta) / 2; } this.Star1 = star1; return star1; }
public SparseMatrixDouble BuildHodgeStar1Form(TriMesh mesh) { SparseMatrixDouble star1 = new SparseMatrixDouble(mesh.Edges.Count, mesh.Edges.Count); foreach (TriMesh.Edge edge in mesh.Edges) { double cotAlpha = ComputeTan(edge.HalfEdge0); double cotBeta = ComputeTan(edge.HalfEdge1); star1[edge.Index, edge.Index] = (cotAlpha + cotBeta) / 2; } this.Star1 = star1; return(star1); }
public SparseMatrixDouble BuildExteriorDerivative0Form(TriMesh mesh) { SparseMatrixDouble d0 = new SparseMatrixDouble(mesh.Edges.Count, mesh.Vertices.Count); foreach (TriMesh.Edge edge in mesh.Edges) { int ci = edge.HalfEdge0.FromVertex.Index; int cj = edge.HalfEdge0.ToVertex.Index; d0[edge.Index, ci] = 1; d0[edge.Index, cj] = -1; } D0 = d0; return(d0); }
public void Build(TriMesh mesh) { int nBasisCycles = basisCycles.Count; //Build Matrix A A = BuildCycleMatrix(mesh, basisCycles); ApplyCotanWeights(ref A); //Factorize LinearSystemGenericByLib.Instance.FactorizationQR(ref A); K = new DenseMatrixDouble(basisCycles.Count, 1); b = new DenseMatrixDouble(basisCycles.Count, 1); //Add constraint of angle defect for (int i = 0; i < nContractibleCycles; i++) { K[i, 0] = -ComputeGeneratorDefect(basisCycles[i]); } //Add constraint of Generator int nGenerators = dualCycles.Count; for (int i = nContractibleCycles; i < nGenerators + nContractibleCycles; i++) { List <TriMesh.HalfEdge> generatorCycle = basisCycles[i]; //Boundary condition if (treeCotree.IsBoundaryGenerator(generatorCycle)) { K[i, 0] = -BoundaryLoopCurvature(generatorCycle); GeneratorOnBoundary[i - nContractibleCycles] = true; } //None-Boundary condition else { K[i, 0] = -ComputeGeneratorDefect(generatorCycle); GeneratorOnBoundary[i - nContractibleCycles] = false; } } //Copy to b for (int i = 0; i < nBasisCycles; i++) { b[i, 0] = K[i, 0]; } }
public void InitProcess() { SparseMatrixDouble d0 = DECDouble.Instance.BuildExteriorDerivative0Form(mesh); SparseMatrixDouble d1 = DECDouble.Instance.BuildExteriorDerivative1Form(mesh); //SparseMatrixDouble d1 = SparseMatrixDouble.ReadFromFile("d1.mat"); double[] guassianCurvatures = TriMeshUtil.ComputeGaussianCurvatureIntegrated(mesh); //Seize all singularities if (Singularities.Count == 0) { Singularities.Add(new KeyValuePair <TriMesh.Vertex, double>(mesh.Vertices[0], 2.0f)); } x = ComputeTrivaialConnection(d0, d1, guassianCurvatures); }
// solves A x = lambda x for the smallest nonzero eigenvalue lambda // A must be symmetric; x is used as an initial guess public DenseMatrixDouble smallestEig(ref SparseMatrixDouble A, bool ignoreConstantVector) { ignoreConstantVector = true; DenseMatrixDouble x = new DenseMatrixDouble(); for (int iter = 0; iter < maxEigIter; iter++) { x = solveLU(ref A, ref x); if (ignoreConstantVector) { // x.removeMean(); } //x.normalize(); } return(x); }
public static SparseMatrixComplex Copy(ref SparseMatrixDouble B) { //We only copy of realpart Dictionary <Pair, Complex> newData = new Dictionary <Pair, Complex>(); foreach (KeyValuePair <Pair, double> e in B.Datas) { Pair pair = e.Key; double value = e.Value; newData.Add(pair, new Complex(value, 0)); } SparseMatrixComplex newMatrix = new SparseMatrixComplex(B.RowCount, B.ColumnCount); newMatrix.mapData = newData; return(newMatrix); }
public static SparseMatrixDouble ReadFromFile(String path) { StreamReader sr = new StreamReader(path); String line = null; int m = int.MinValue; int n = int.MinValue; int count = 0; SparseMatrixDouble sm = null; while ((line = sr.ReadLine()) != null) { String[] token = line.Split(' '); if (count == 0) { m = int.Parse(token[1]); n = int.Parse(token[3]); int nnz = int.Parse(token[5]); sm = new SparseMatrixDouble(m, n); count++; continue; } int index_i = int.Parse(token[0]); int index_j = int.Parse(token[1]); double value = double.Parse(token[2]); if (value != 0) { Pair newPair = new Pair(index_i, index_j); sm.Datas.Add(newPair, value); } } sr.Close(); GC.Collect(); return(sm); }
public SparseMatrixDouble BuildLaplaceWithNeumannBoundary(TriMesh mesh) { SparseMatrixDouble d0 = this.BuildExteriorDerivative0Form(mesh); D0 = d0; SparseMatrixDouble star1 = this.BuildHodgeStar1Form(mesh); Star1 = star1; SparseMatrixDouble star0 = this.BuildHodgeStar0Form(mesh); Star0 = star0; SparseMatrixDouble delta = d0.Transpose() * star1 * d0; delta += (1.0e-8) * star0; Laplace = delta; return(delta); }
protected DenseMatrixDouble ComputeTrivaialConnection(SparseMatrixDouble d0, SparseMatrixDouble d1, double[] Guassian) { DenseMatrixDouble b = CholmodConverter.dConvertArrayToDenseMatrix(ref Guassian, Guassian.Length, 1); double[] singularValues = new double[Singularities.Count]; //Init with avg of 2 double avgValue = 2.0f / (double)Singularities.Count; int j = 0; foreach (KeyValuePair <TriMesh.Vertex, double> vItem in Singularities) { int index = vItem.Key.Index; double value = vItem.Value; b[index, 0] = Guassian[index] - 2 * Math.PI * value; j++; } for (int i = 0; i < Guassian.Length; i++) { b[i, 0] = -b[i, 0]; } SparseMatrixDouble A = d0.Transpose(); DenseMatrixDouble x = LinearSystemGenericByLib.Instance.SolveLinerSystem(ref A, ref b); SparseMatrixDouble d1T = d1.Transpose(); SparseMatrixDouble Laplace = d1 * d1T; DenseMatrixDouble rhs = d1 * x; DenseMatrixDouble y = LinearSystemGenericByLib.Instance.SolveLinerSystem(ref Laplace, ref rhs); x = x - d1T * y; return(x); }
public DenseMatrixDouble SolveSymmetricSystem(ref SparseMatrixDouble A, ref DenseMatrixDouble b) { if (A.RowCount != b.RowCount) { throw new Exception("The dimension of A and b must be agree"); } if (!A.IsSymmetric()) { throw new Exception("The matrix is asymmetric"); } CholmodInfo cholmodb = CholmodConverter.ConvertDouble(ref b); CholmodInfo cholmodA = CholmodConverter.ConverterDouble(ref A, CholmodInfo.CholmodMatrixStorage.CCS); double[] x = new double[A.ColumnCount]; fixed(int *Index = cholmodA.rowIndex, Pt = cholmodA.colIndex) fixed(double *val = cholmodA.values, bp = cholmodb.values, xx = x) { SolveRealByLU_CCS(cholmodA.RowCount, cholmodA.ColumnCount, cholmodA.nnz, Index, //Row Index Pt, //Column Pointer val, xx, bp); } DenseMatrixDouble unknown = CholmodConverter.dConvertArrayToDenseMatrix(ref x, x.Length, 1); cholmodA = null; cholmodb = null; GC.Collect(); return(unknown); }
public void FactorizationQR(ref SparseMatrixDouble A) { // CholmodInfo cholmodA = CholmodConverter.Converter(ref A); int rowCount = A.RowCount; int columnCount = A.ColumnCount; int nnz = 0; this.m = rowCount; this.n = columnCount; int[] Ri = null; int[] Ci = null; double[] values = null; A.ToCCS(out Ci, out Ri, out values, out nnz); fixed(int *ri = Ri, ci = Ci) fixed(double *val = values) { solver = CreateSolverQRSuiteSparseQR_CCS(rowCount, columnCount, nnz, ri, ci, val); } if (solver == null) throw new Exception("Create Solver Fail"); }
void ApplyCotanWeights(ref SparseMatrixDouble A) { List <Pair> pairs = new List <Pair>(); foreach (KeyValuePair <Pair, double> e in A.Datas) { Pair pair = e.Key; pairs.Add(pair); } foreach (Pair item in pairs) { int row = item.Key; int column = item.Value; double value = A.Datas[item] * Math.Sqrt(EdgeHodgeStar1[row]); A.Datas[item] = value; } pairs.Clear(); pairs = null; }
public void FactorizationCholesky(ref SparseMatrixDouble A) { // CholmodInfo cholmodA = CholmodConverter.Converter(ref A); int rowCount = A.RowCount; int columnCount = A.ColumnCount; int nnz = 0; int[] Ri = null; int[] Ci = null; double[] values = null; A.ToTriplet(out Ci, out Ri, out values, out nnz); fixed(int *ri = Ri, ci = Ci) fixed(double *val = values) { solver = CreateSolverCholeskyCHOLMOD(rowCount, rowCount, nnz, nnz, ri, ci, val); } if (solver == null) { throw new Exception("Create Solver Fail"); } }
public DenseMatrixDouble InitWithTrivalHolonmy(SparseMatrixDouble Laplace, TriMesh mesh) { DenseMatrixDouble b = new DenseMatrixDouble(mesh.Vertices.Count, 1); double[] tempSingularities = new double[mesh.Vertices.Count]; for (int i = 0; i < tempSingularities.Length; i++) { tempSingularities[i] = 0; } foreach (KeyValuePair <TriMesh.Vertex, double> pair in Singularities) { int index = pair.Key.Index; double value = pair.Value; tempSingularities[index] = value; } double[] GuassianCurvs = TriMeshUtil.ComputeGaussianCurvatureIntegrated(mesh); foreach (TriMesh.Vertex v in mesh.Vertices) { double value = 0; if (!v.OnBoundary) { value -= GuassianCurvs[v.Index]; value += 2 * Math.PI * tempSingularities[v.Index]; } b[v.Index, 0] = value; } DenseMatrixDouble u = LinearSystemGenericByLib.Instance.SolveLinerSystem(ref Laplace, ref b); return(u); }
public SparseMatrixDouble BuildNeighborMatrix(TriMesh mesh) { SparseMatrixDouble sparse = new SparseMatrixDouble(); return sparse; }
public SparseMatrixDouble BuildAdjecentMatrix(TriMesh mesh) { SparseMatrixDouble sparse = new SparseMatrixDouble(); return sparse; }
SparseMatrixDouble BuildCycleMatrix(TriMesh mesh, List<List<TriMesh.HalfEdge>> cycles) { SparseMatrixDouble A = new SparseMatrixDouble(mesh.Edges.Count, cycles.Count); int l = 0; foreach (List<TriMesh.HalfEdge> cycle in cycles) { foreach (TriMesh.HalfEdge hf in cycle) { int k = hf.Edge.Index; int i = hf.FromVertex.Index; int j = hf.ToVertex.Index; if (i > j) { A[k, l] = 1; } else { A[k, l] = -1; } } l++; } return A; }
public void Write(ref SparseMatrixDouble A, string fileName) { }
public void InitProcess(TriMesh mesh) { TreeCoTree treeCotree = new TreeCoTree(mesh); generatorLoops = treeCotree.ExtractHonologyGenerator(mesh); HarmonicBasis basis = new HarmonicBasis(mesh); HarmonicBasis = basis.BuildHarmonicBasis(generatorLoops); int numberOfHarmBases = basis.NumberOfHarmonicBases(generatorLoops); //Still need to built u = InitWithTrivalHolonmy(Laplace, mesh); HarmonicCoffition = new double[numberOfHarmBases]; if (numberOfHarmBases == 0) { return; } DenseMatrixDouble b = new DenseMatrixDouble(numberOfHarmBases, 1); SparseMatrixDouble H = new SparseMatrixDouble(numberOfHarmBases, numberOfHarmBases); int row = 0; bool skipBoundaryLoop = true; for (int i = 0; i < generatorLoops.Count; i++) { List <TriMesh.HalfEdge> cycle = generatorLoops[i]; if (skipBoundaryLoop && treeCotree.IsBoundaryGenerator(cycle)) { skipBoundaryLoop = false; continue; } foreach (TriMesh.HalfEdge hf in cycle) { for (int col = 0; col < numberOfHarmBases; col++) { H[row, col] += HarmonicBasis[hf.Index][col]; } } double value = -GeneratorHolomy(cycle, HarmonicBasis, HarmonicCoffition, u); b[row, 0] = value; row++; } DenseMatrixDouble x = null; if (b.F_Norm() > 1.0e-8) { x = LinearSystemGenericByLib.Instance.SolveLinerSystem(ref H, ref b); } else { x = new DenseMatrixDouble(numberOfHarmBases, 1); } for (int i = 0; i < numberOfHarmBases; i++) { HarmonicCoffition[i] = x[i, 0]; } }
public void ToTriplet(out int[] colIndices, out int[] rowIndices, out double[] values, out int nnz) { SparseMatrixDouble sparse = new SparseMatrixDouble(4 * this.rowCount, 4 * this.columnCount); foreach (KeyValuePair<Pair, Quaternion> e in mapData) { Pair pair = e.Key; double q0 = e.Value.w; double q1 = e.Value.x; double q2 = e.Value.y; double q3 = e.Value.z; if (q0 != 0) { sparse.Datas.Add(new Pair(4 * pair.Key, 4 * pair.Value), q0); sparse.Datas.Add(new Pair(4 * pair.Key + 1, 4 * pair.Value + 1), q0); sparse.Datas.Add(new Pair(4 * pair.Key + 2, 4 * pair.Value + 2), q0); sparse.Datas.Add(new Pair(4 * pair.Key + 3, 4 * pair.Value + 3), q0); } if (q1 != 0) { sparse.Datas.Add(new Pair(4 * pair.Key + 1, 4 * pair.Value), q1); sparse.Datas.Add(new Pair(4 * pair.Key, 4 * pair.Value + 1), -q1); sparse.Datas.Add(new Pair(4 * pair.Key + 3, 4 * pair.Value + 2), q1); sparse.Datas.Add(new Pair(4 * pair.Key + 2, 4 * pair.Value + 3), -q1); } if (q2 != 0) { sparse.Datas.Add(new Pair(4 * pair.Key + 2, 4 * pair.Value), q2); sparse.Datas.Add(new Pair(4 * pair.Key + 3, 4 * pair.Value + 1), -q2); sparse.Datas.Add(new Pair(4 * pair.Key, 4 * pair.Value + 2), -q2); sparse.Datas.Add(new Pair(4 * pair.Key + 1, 4 * pair.Value + 3), q2); } if (q3 != 0) { sparse.Datas.Add(new Pair(4 * pair.Key + 3, 4 * pair.Value), q3); sparse.Datas.Add(new Pair(4 * pair.Key + 2, 4 * pair.Value + 1), q3); sparse.Datas.Add(new Pair(4 * pair.Key, 4 * pair.Value + 3), -q3); sparse.Datas.Add(new Pair(4 * pair.Key + 1, 4 * pair.Value + 2), -q3); } } sparse.ToTriplet(out colIndices, out rowIndices, out values, out nnz); }
public static SparseMatrixDouble Identity(int N) { SparseMatrixDouble identity = new SparseMatrixDouble(N, N); for (int i = 0; i < N; i++) { identity.mapData.Add(new Pair(i, i), 1); } return identity; }
public SparseMatrixDouble SubMatrix(int rowStart, int rowEnd, int columnStart, int columnEnd) { if (rowEnd < rowStart || columnEnd < columnStart) { throw new ArgumentOutOfRangeException(); } int rows = rowEnd - rowStart + 1; int columns = columnEnd - columnStart + 1; SparseMatrixDouble subMatrix = new SparseMatrixDouble(rows, columns); int subMatrixEntiries = rows * columns; if (subMatrixEntiries < mapData.Count) { for (int i = 0; i < rows; i++) { int rowInx = i + rowStart; for (int j = 0; j < columns; j++) { int columnInx = j + columnStart; Pair pair = new Pair(rowInx, columnInx); if (!mapData.ContainsKey(pair)) { continue; } Pair subPair = new Pair(i, j); subMatrix.mapData[subPair] = mapData[pair]; } } } else if (subMatrixEntiries >= mapData.Count) { foreach (KeyValuePair<Pair, double> item in mapData) { Pair pair = item.Key; double value = item.Value; int m = pair.Key; int n = pair.Value; if ((m >= rowStart && m <= rowEnd) && (n >= columnStart && m <= columnEnd)) { int i = m - rowStart; int j = n - columnStart; subMatrix.mapData[new Pair(i, j)] = value; } } } return subMatrix; }
public SparseMatrixDouble Transpose() { SparseMatrixDouble trMatrix = new SparseMatrixDouble(this.columnCount, this.rowCount); foreach (KeyValuePair<Pair, double> item in mapData) { Pair pair = item.Key; double value = item.Value; trMatrix.mapData[new Pair(pair.Value, pair.Key)] = value; } return trMatrix; }
public static SparseMatrixDouble operator -(SparseMatrixDouble left, SparseMatrixDouble right) { SparseMatrixDouble result = new SparseMatrixDouble(right.rowCount, right.columnCount); foreach (KeyValuePair<Pair, double> item in left.mapData) { Pair pair = item.Key; double value = item.Value; result.mapData.Add(pair, value); } foreach (KeyValuePair<Pair, double> item in right.mapData) { Pair pair = item.Key; double value = item.Value; if (result.mapData.ContainsKey(pair)) { double temp = result.mapData[pair] -= item.Value; if (temp == 0) { result.mapData.Remove(pair); } } else { result.mapData.Add(pair, value); } } return result; }
public static SparseMatrixDouble operator *(SparseMatrixDouble left, SparseMatrixDouble right) { //Make sure matrix dimensions are equal if (left.columnCount != right.rowCount) { throw new Exception("The dimension of two matrix must be equal"); } SparseMatrixDouble result = new SparseMatrixDouble(left.rowCount, right.columnCount); int leftNNZ = left.mapData.Count; int rightNNZ = right.mapData.Count; #region Left < Right //We use right as stardand sight //if (leftNNZ < rightNNZ) //{ //Connection nonezero for each row of matrix a List<KeyValuePair<int, double>>[] bRows = new List<KeyValuePair<int, double>>[right.rowCount]; for (int i = 0; i < bRows.Length; i++) { bRows[i] = new List<KeyValuePair<int, double>>(); } foreach (KeyValuePair<Pair, double> item in right.mapData) { Pair pair = item.Key; double value = item.Value; bRows[pair.Key].Add(new KeyValuePair<int, double>(pair.Value, value)); } //Compute C = A*B foreach (KeyValuePair<Pair, double> item in left.mapData) { Pair pair = item.Key; int mA = pair.Key; int nA = pair.Value; double value = item.Value; List<KeyValuePair<int, double>> bRow = bRows[nA]; for (int i = 0; i < bRow.Count; i++) { int k = bRow[i].Key; Pair pair2 = new Pair(mA, k); if (result.mapData.ContainsKey(pair2)) { result.mapData[pair2] += value * bRow[i].Value; } else { result.mapData.Add(pair2, value * bRow[i].Value); } } } //} #endregion #region Right < Left //else if (leftNNZ > rightNNZ) //{ // //Connection nonezero for each row of matrix a // List<KeyValuePair<int, double>>[] aCols = new List<KeyValuePair<int, double>>[left.columnCount]; // for (int i = 0; i < aCols.Length; i++) // { // aCols[i] = new List<KeyValuePair<int, double>>(); // } // foreach (KeyValuePair<Pair, double> item in left.mapData) // { // Pair pair = item.Key; // double value = item.Value; // aCols[pair.Value].Add(new KeyValuePair<int, double>(pair.Key, value)); // } // //Compute C = A*B // foreach (KeyValuePair<Pair, double> item in right.mapData) // { // Pair pair = item.Key; // int mA = pair.Key; // int nA = pair.Value; // double value = item.Value; // List<KeyValuePair<int, double>> aCol = aCols[mA]; // for (int i = 0; i < aCol.Count; i++) // { // int k = aCol[i].Key; // Pair pair2 = new Pair(k, nA); // if (result.mapData.ContainsKey(pair2)) // { // result.mapData[pair2] += value * aCol[i].Value; // } // else // { // result.mapData.Add(pair2, value * aCol[i].Value); // } // } // } //} #endregion return result; }
// solves A x = lambda (B - EE^T) x for the smallest nonzero eigenvalue lambda // A must be positive (semi-)definite, B must be symmetric; EE^T is a low-rank matrix, and // x is used as an initial guess public DenseMatrixDouble smallestEigPositiveDefinite(ref SparseMatrixDouble A, ref SparseMatrixDouble B, ref SparseMatrixDouble E) { DenseMatrixDouble x = new DenseMatrixDouble(); return(x); }
public void Build(TriMesh mesh) { int nBasisCycles = basisCycles.Count; //Build Matrix A A = BuildCycleMatrix(mesh, basisCycles); ApplyCotanWeights(ref A); //Factorize LinearSystemGenericByLib.Instance.FactorizationQR(ref A); K = new DenseMatrixDouble(basisCycles.Count, 1); b = new DenseMatrixDouble(basisCycles.Count, 1); //Add constraint of angle defect for (int i = 0; i < nContractibleCycles; i++) { K[i, 0] = -ComputeGeneratorDefect(basisCycles[i]); } //Add constraint of Generator int nGenerators = dualCycles.Count; for (int i = nContractibleCycles; i < nGenerators + nContractibleCycles; i++) { List<TriMesh.HalfEdge> generatorCycle = basisCycles[i]; //Boundary condition if (treeCotree.IsBoundaryGenerator(generatorCycle)) { K[i, 0] = -BoundaryLoopCurvature(generatorCycle); GeneratorOnBoundary[i - nContractibleCycles] = true; } //None-Boundary condition else { K[i, 0] = -ComputeGeneratorDefect(generatorCycle); GeneratorOnBoundary[i - nContractibleCycles] = false; } } //Copy to b for (int i = 0; i < nBasisCycles; i++) { b[i, 0] = K[i, 0]; } }
public void FactorizationCholesky(ref SparseMatrixDouble A) { // CholmodInfo cholmodA = CholmodConverter.Converter(ref A); int rowCount = A.RowCount; int columnCount = A.ColumnCount; int nnz = 0; int[] Ri = null; int[] Ci = null; double[] values = null; A.ToTriplet(out Ci, out Ri, out values, out nnz); fixed (int* ri = Ri, ci = Ci) fixed (double* val = values) { solver = CreateSolverCholeskyCHOLMOD(rowCount, rowCount, nnz, nnz, ri, ci, val); } if (solver == null) throw new Exception("Create Solver Fail"); }
public DenseMatrixDouble SolveLinearSystemByLU(ref SparseMatrixDouble A, ref DenseMatrixDouble b) { if (A.RowCount != b.RowCount) { throw new Exception("The dimension of A and b must be agree"); } CholmodInfo cholmodb = CholmodConverter.ConvertDouble(ref b); CholmodInfo cholmodA = CholmodConverter.ConverterDouble(ref A, CholmodInfo.CholmodMatrixStorage.CCS); double[] x = new double[A.ColumnCount]; fixed (int* Index = cholmodA.rowIndex, Pt = cholmodA.colIndex) fixed (double* val = cholmodA.values, bp = cholmodb.values, xx = x) { SolveRealByLU_CCS(cholmodA.RowCount, cholmodA.ColumnCount, cholmodA.nnz, Index, //Row Index Pt, //Column Pointer val, xx, bp); } DenseMatrixDouble unknown = CholmodConverter.dConvertArrayToDenseMatrix(ref x, x.Length, 1); cholmodA = null; cholmodb = null; GC.Collect(); return unknown; }
public static SparseMatrixDouble Copy(ref SparseMatrixDouble B) { Dictionary<Pair, double> newData = new Dictionary<Pair, double>(B.mapData); SparseMatrixDouble newMatrix = new SparseMatrixDouble(B.rowCount, B.columnCount); newMatrix.mapData = newData; return newMatrix; }
public void Run() { Stopwatch clock = new Stopwatch(); clock.Start(); double step = 0.01; DECMeshDouble decMesh = new DECMeshDouble(mesh); SparseMatrixDouble laplace = decMesh.Laplace; SparseMatrixDouble star0 = decMesh.HodgeStar0Form; SparseMatrixDouble star1 = decMesh.HodgeStar1Form; SparseMatrixDouble d0 = decMesh.ExteriorDerivative0Form; SparseMatrixDouble L = d0.Transpose() * star1 * d0; SparseMatrixDouble A = star0 + step * L; A.WriteToFile("A.ma"); double[] xs = new double[mesh.Vertices.Count]; double[] ys = new double[mesh.Vertices.Count]; double[] zs = new double[mesh.Vertices.Count]; foreach (TriMesh.Vertex v in mesh.Vertices) { xs[v.Index] = v.Traits.Position.x; ys[v.Index] = v.Traits.Position.y; zs[v.Index] = v.Traits.Position.z; } double[] rhs1 = star0 * xs; double[] rhs2 = star0 * ys; double[] rhs3 = star0 * zs; //SparseMatrix.WriteVectorToFile("xs.ve", rhs1); //SparseMatrix.WriteVectorToFile("ys.ve", rhs2); //SparseMatrix.WriteVectorToFile("zs.ve", rhs3); DenseMatrixDouble rhsx = new DenseMatrixDouble(mesh.Vertices.Count, 1); DenseMatrixDouble rhsy = new DenseMatrixDouble(mesh.Vertices.Count, 1); DenseMatrixDouble rhsz = new DenseMatrixDouble(mesh.Vertices.Count, 1); for (int i = 0; i < mesh.Vertices.Count; i++) { rhsx[i, 0] = rhs1[i]; rhsy[i, 0] = rhs2[i]; rhsz[i, 0] = rhs3[i]; } DenseMatrixDouble newX = LinearSystemGenericByLib.Instance.SolveLinerSystem(ref A, ref rhsx); DenseMatrixDouble newY = LinearSystemGenericByLib.Instance.SolveLinerSystem(ref A, ref rhsy); DenseMatrixDouble newZ = LinearSystemGenericByLib.Instance.SolveLinerSystem(ref A, ref rhsz); foreach (TriMesh.Vertex v in mesh.Vertices) { v.Traits.Position.x = newX[v.Index, 0]; v.Traits.Position.y = newY[v.Index, 0]; v.Traits.Position.z = newZ[v.Index, 0]; } TriMeshUtil.ScaleToUnit(mesh, 1.0f); TriMeshUtil.MoveToCenter(mesh); clock.Stop(); decimal micro = clock.Elapsed.Ticks / 10m; Console.WriteLine("Total time cost:{0}", micro); }
public static SparseMatrixDouble ReadFromFile(String path) { StreamReader sr = new StreamReader(path); String line = null; int m = int.MinValue; int n = int.MinValue; int count = 0; SparseMatrixDouble sm = null; while ((line = sr.ReadLine()) != null) { String[] token = line.Split(' '); if (count == 0) { m = int.Parse(token[1]); n = int.Parse(token[3]); int nnz = int.Parse(token[5]); sm = new SparseMatrixDouble(m, n); count++; continue; } int index_i = int.Parse(token[0]); int index_j = int.Parse(token[1]); double value = double.Parse(token[2]); if (value != 0) { Pair newPair = new Pair(index_i, index_j); sm.Datas.Add(newPair, value); } } sr.Close(); GC.Collect(); return sm; }
public SparseMatrixDouble(SparseMatrixDouble matrix) { mapData = new Dictionary<Pair, double>(matrix.mapData); this.rowCount = matrix.rowCount; this.columnCount = matrix.columnCount; }
public void FactorizationQR(ref SparseMatrixDouble A) { // CholmodInfo cholmodA = CholmodConverter.Converter(ref A); int rowCount = A.RowCount; int columnCount = A.ColumnCount; int nnz = 0; this.m = rowCount; this.n = columnCount; int[] Ri = null; int[] Ci = null; double[] values = null; A.ToCCS(out Ci, out Ri, out values, out nnz); fixed (int* ri = Ri, ci = Ci) fixed (double* val = values) { solver = CreateSolverQRSuiteSparseQR_CCS(rowCount, columnCount, nnz, ri, ci, val); } if (solver == null) throw new Exception("Create Solver Fail"); }
public Vector3D[] Process() { //Build laplace SparseMatrixDouble star0 = DECDouble.Instance.Star0; if (star0 == null) { star0 = DECDouble.Instance.BuildHodgeStar0Form(mesh); } SparseMatrixDouble star1 = DECDouble.Instance.Star1; if (star1 == null) { star1 = DECDouble.Instance.BuildHodgeStar1Form(mesh); } SparseMatrixDouble d0 = DECDouble.Instance.D0; if (d0 == null) { d0 = DECDouble.Instance.BuildExteriorDerivative0Form(mesh); } SparseMatrixDouble d1 = DECDouble.Instance.D1; if (d1 == null) { d1 = DECDouble.Instance.BuildExteriorDerivative1Form(mesh); } if (Singularities == null) { Singularities = new List <KeyValuePair <HalfEdgeMesh.Vertex, double> >(); } if (Singularities.Count == 0) { int count = 0; foreach (TriMesh.Vertex v in mesh.Vertices) { if (v.Traits.selectedFlag > 0) { count++; } } double avg = 2 / (double)count; int item = 0; foreach (TriMesh.Vertex V in mesh.Vertices) { if (V.Traits.selectedFlag > 0) { if (item % 2 == 0) //2 { Singularities.Add(new KeyValuePair <HalfEdgeMesh.Vertex, double>(V, -1)); } if (item % 2 == 1) //2 { Singularities.Add(new KeyValuePair <HalfEdgeMesh.Vertex, double>(V, 1)); } } } } Laplace = d0.Transpose() * star1 * d0; Laplace = Laplace + (1.0e-8) * star0; InitProcess(this.mesh); GenerateFaceNormals(); Vector3D[] VectorFields = ComputeVectorField(0); return(VectorFields); }
public void FactorizationLU(ref SparseMatrixDouble A) { CholmodInfo cholmodA = CholmodConverter.ConverterDouble(ref A, CholmodInfo.CholmodMatrixStorage.CCS); m = A.RowCount; n = A.ColumnCount; fixed (int* Index = cholmodA.rowIndex, Pt = cholmodA.colIndex) fixed (double* val = cholmodA.values) { solver = CreateSolverLUUMFPACK_CCS(cholmodA.RowCount, cholmodA.ColumnCount, cholmodA.nnz, Index, Pt, val ); } if (solver == null) throw new Exception("Create Solver Fail"); }
public void Read(out SparseMatrixDouble A, string fileName) { A = null; // A = new dSparseMatrix(); }
void ApplyCotanWeights(ref SparseMatrixDouble A) { List<Pair> pairs = new List<Pair>(); foreach (KeyValuePair<Pair, double> e in A.Datas) { Pair pair = e.Key; pairs.Add(pair); } foreach (Pair item in pairs) { int row = item.Key; int column = item.Value; double value = A.Datas[item] * Math.Sqrt(EdgeHodgeStar1[row]); A.Datas[item] = value; } pairs.Clear(); pairs = null; }