public override BenchmarkResult Run(BenchmarkSetup config) { int rows = config.RowCount; int cols = config.ColumnCount; int repeat = config.Repeat; double density = config.Density; bool symmetric = config.Symmetric; var A = Create.SparseMatrix(rows, cols, density, symmetric); var result = new BenchmarkResult(); var a = DenseVector.Create(rows, (i) => 1.0 + i); var D = DiagonalMatrix.OfDiagonal(rows, cols, a); var C = (SparseMatrix)A.Clone(); Util.Tic(); var B = A.Add(D); result.Time1 = Util.Toc(); Util.Tic(); C.FastAddDiagonalMatrix(Util.GetData(a), C); result.Time2 = Util.Toc(); result.Success = MatrixComparer.Equals(B, C, EPS); return(result); }
private void UpdateDynamicExplicit_Lumped(float dT) { // https://www.youtube.com/watch?v=YqynfK8qwFI&t=202s - Schuster Engineering, FEA 22: Transient Explicit var stiffness = ComputeGlobalStiffnessMatrix(); var force = ComputeForceVector(); var damping = ComputeGlobalLumpedDampingVector(); var mass = ComputeGlobalLumpedMassVector(); dT /= numIterationsPerUpdateForExplicitAnalysis; for (int i = 0; i < numIterationsPerUpdateForExplicitAnalysis; ++i) { float dTInvSq = 1.0f / (dT * dT); float dTInv2 = 1.0f / (dT * 2.0f); // "left hand" var leftHand = dTInvSq * mass + dTInv2 * damping; // not sure what to call a mass + damping thing // "right hand" var currentContrib = (DiagonalMatrix.OfDiagonal(mass.Count, mass.Count, (2.0f * dTInvSq) * mass) - stiffness) * nodeDisplacement; var pastContrib = (dTInvSq * mass - dTInv2 * damping).PointwiseMultiply(nodeDisplacementOld); var rightHand = force + currentContrib - pastContrib; // not sure what to call a ... whatever that is // solve! ApplyConstraints(rightHand); ApplyConstraints(leftHand); nodeDisplacementOld = nodeDisplacement; nodeDisplacement = rightHand.PointwiseDivide(leftHand); ApplyConstraints(nodeDisplacement); } // computing displacement and speed directly from this requires some thought (it's in there!), but can of course always be done using central differences. }
public DiagonalMatrix MakeDiagonalMatrix(double[,] adjacencyMatrix) { var sumVector = MakeSumVector(adjacencyMatrix); var diagonalMatrix = DiagonalMatrix.OfDiagonal(sumVector.Length, sumVector.Length, sumVector); return(diagonalMatrix); }
public void TestAddDiagonalMatrix(int size) { var A = MatrixLoader.A(size); int rows = A.RowCount; int cols = A.ColumnCount; var a = DenseVector.Create(rows, (i) => 1.0 + i); var D = DiagonalMatrix.OfDiagonal(rows, cols, a); var B = A.Add(D); var C = A.Clone() as SparseMatrix; C.FastAddDiagonalMatrix(Util.GetData(a), C); Assert.IsTrue(MatrixComparer.Equals(B, C, EPS)); }
public static Matrix <double> Scale(Matrix <double> input) { int n = input.RowCount; Matrix <double> p = DenseMatrix.Build.DenseIdentity(n) - DenseMatrix.Create(n, n, (_, __) => 1.0 / n); Matrix <double> a = -.5 * input.PointwiseMultiply(input); Matrix <double> b = p.Multiply(p.Multiply(a)); b = (b + b.Transpose()).Divide(2.0); var evd = b.Evd(); Vector <double> E = DenseVector.OfEnumerable(evd.EigenValues.Select(x => x.Real)); Matrix <double> V = evd.EigenVectors; DenseVector i = DenseVector.Create(E.Count, x => x); Sorting.Sort(E, i); var e = DenseVector.OfEnumerable(E.Reverse()); i = DenseVector.OfEnumerable(i.Reverse()); Vector keep = DenseVector.Create(e.Count(x => x > 0.000000001), _ => 0); int counter = 0; for (int j = 0; j < e.Count; j++) { if (e[j] > 0.000000001) { keep[j] = counter; counter++; } } Matrix <double> Y; if (e.Count(x => x > 0.000000001) == 0) { Y = DenseMatrix.Create(n, n, (_, __) => 0); } else { Y = DenseMatrix.Create(V.RowCount, keep.Count, (_, __) => 0); for (int j = 0; j < keep.Count; j++) { Y.SetColumn(j, (V.Column((int)(i[(int)(keep[j] + 0.5)] + 0.5)).ToArray())); } Y = Y.Multiply(DiagonalMatrix.OfDiagonal(keep.Count, keep.Count, e.Where((x, j) => keep.Contains(j)).Select(Math.Sqrt))); } //Enforce a sign convention on the solution -- the largest element //in each coordinate will have a positive sign. List <int> maxIndices = Y.EnumerateColumns().Select(x => x.AbsoluteMaximumIndex()).ToList(); var colSigns = maxIndices.Select((x, j) => Math.Sign(Y[x, j])).ToList(); for (int j = 0; j < Y.ColumnCount; j++) { Y.SetColumn(j, Y.Column(j) * colSigns[j]); } return(Y); }
/// <summary> /// up to 3 dimension scale, rotation, translation /// </summary> /// <param name="src"></param> /// <param name="align2"></param> /// <returns></returns> public static Vector <double> Transform2(Vector <double> src, Tuple <Matrix <double>, Vector <double>, Vector <double> > align2) { return(DiagonalMatrix.OfDiagonal(2, 2, align2.Item2) * align2.Item1 * src + align2.Item3); }