Ejemplo n.º 1
0
            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);
            }
Ejemplo n.º 2
0
    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.
    }
Ejemplo n.º 3
0
        public DiagonalMatrix MakeDiagonalMatrix(double[,] adjacencyMatrix)
        {
            var sumVector      = MakeSumVector(adjacencyMatrix);
            var diagonalMatrix = DiagonalMatrix.OfDiagonal(sumVector.Length, sumVector.Length, sumVector);

            return(diagonalMatrix);
        }
Ejemplo n.º 4
0
        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));
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
 /// <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);
 }