/// <summary>
        /// Run example
        /// </summary>
        public void Run()
        {
            // 1. Initialize a new instance of the empty vector with a given size
            var vector1 = new DenseVector(5);

            // 2. Initialize a new instance of the vector with a given size and each element set to the given value
            var vector2 = DenseVector.Create(5, i => 3.0);

            // 3. Initialize a new instance of the vector from an array.
            var vector3 = new DenseVector(new[] { 1.0, 2.0, 3.0, 4.0, 5.0 });

            // 4. Initialize a new instance of the vector by copying the values from another.
            var vector4 = DenseVector.OfVector(vector3);

            // Format vector output to console
            var formatProvider = (CultureInfo)CultureInfo.InvariantCulture.Clone();
            formatProvider.TextInfo.ListSeparator = " ";

            Console.WriteLine(@"Vector 1");
            Console.WriteLine(vector1.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            Console.WriteLine(@"Vector 2");
            Console.WriteLine(vector2.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            Console.WriteLine(@"Vector 3");
            Console.WriteLine(vector3.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            Console.WriteLine(@"Vector 4");
            Console.WriteLine(vector4.ToString("#0.00\t", formatProvider));
            Console.WriteLine();
        }
        /// <summary>
        /// Run example
        /// </summary>
        public void Run()
        {
            // Format matrix output to console
            var formatProvider = (CultureInfo)CultureInfo.InvariantCulture.Clone();
            formatProvider.TextInfo.ListSeparator = " ";

            // Solve next system of linear equations (Ax=b):
            // 5*x + 2*y - 4*z = -7
            // 3*x - 7*y + 6*z = 38
            // 4*x + 1*y + 5*z = 43

            // Create matrix "A" with coefficients
            var matrixA = DenseMatrix.OfArray(new[,] { { 5.00, 2.00, -4.00 }, { 3.00, -7.00, 6.00 }, { 4.00, 1.00, 5.00 } });
            Console.WriteLine(@"Matrix 'A' with coefficients");
            Console.WriteLine(matrixA.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Create vector "b" with the constant terms.
            var vectorB = new DenseVector(new[] { -7.0, 38.0, 43.0 });
            Console.WriteLine(@"Vector 'b' with the constant terms");
            Console.WriteLine(vectorB.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Create stop criteriums to monitor an iterative calculation. There are next available stop criteriums:
            // - DivergenceStopCriterium: monitors an iterative calculation for signs of divergence;
            // - FailureStopCriterium: monitors residuals for NaN's;
            // - IterationCountStopCriterium: monitors the numbers of iteration steps;
            // - ResidualStopCriterium: monitors residuals if calculation is considered converged;

            // Stop calculation if 1000 iterations reached during calculation
            var iterationCountStopCriterium = new IterationCountStopCriterium<double>(1000);

            // Stop calculation if residuals are below 1E-10 --> the calculation is considered converged
            var residualStopCriterium = new ResidualStopCriterium(1e-10);

            // Create monitor with defined stop criteriums
            var monitor = new Iterator<double>(new IIterationStopCriterium<double>[] { iterationCountStopCriterium, residualStopCriterium });

            // Create Transpose Free Quasi-Minimal Residual solver
            var solver = new TFQMR(monitor);

            // 1. Solve the matrix equation
            var resultX = solver.Solve(matrixA, vectorB);
            Console.WriteLine(@"1. Solve the matrix equation");
            Console.WriteLine();

            // 2. Check solver status of the iterations.
            // Solver has property IterationResult which contains the status of the iteration once the calculation is finished.
            // Possible values are:
            // - CalculationCancelled: calculation was cancelled by the user;
            // - CalculationConverged: calculation has converged to the desired convergence levels;
            // - CalculationDiverged: calculation diverged;
            // - CalculationFailure: calculation has failed for some reason;
            // - CalculationIndetermined: calculation is indetermined, not started or stopped;
            // - CalculationRunning: calculation is running and no results are yet known;
            // - CalculationStoppedWithoutConvergence: calculation has been stopped due to reaching the stopping limits, but that convergence was not achieved;
            Console.WriteLine(@"2. Solver status of the iterations");
            Console.WriteLine(solver.IterationResult);
            Console.WriteLine();

            // 3. Solution result vector of the matrix equation
            Console.WriteLine(@"3. Solution result vector of the matrix equation");
            Console.WriteLine(resultX.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 4. Verify result. Multiply coefficient matrix "A" by result vector "x"
            var reconstructVecorB = matrixA * resultX;
            Console.WriteLine(@"4. Multiply coefficient matrix 'A' by result vector 'x'");
            Console.WriteLine(reconstructVecorB.ToString("#0.00\t", formatProvider));
            Console.WriteLine();
        }
        /// <summary>
        /// Run example
        /// </summary>
        public void Run()
        {
            // Format matrix output to console
            var formatProvider = (CultureInfo)CultureInfo.InvariantCulture.Clone();
            formatProvider.TextInfo.ListSeparator = " ";

            // Solve next system of linear equations (Ax=b):
            // 5*x + 2*y - 4*z = -7
            // 3*x - 7*y + 6*z = 38
            // 4*x + 1*y + 5*z = 43

            // Create matrix "A" with coefficients
            var matrixA = new DenseMatrix(new[,] { { 5.00, 2.00, -4.00 }, { 3.00, -7.00, 6.00 }, { 4.00, 1.00, 5.00 } });
            Console.WriteLine(@"Matrix 'A' with coefficients");
            Console.WriteLine(matrixA.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Create vector "b" with the constant terms.
            var vectorB = new DenseVector(new[] { -7.0, 38.0, 43.0 });
            Console.WriteLine(@"Vector 'b' with the constant terms");
            Console.WriteLine(vectorB.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 1. Solve linear equations using LU decomposition
            var resultX = matrixA.LU().Solve(vectorB);
            Console.WriteLine(@"1. Solution using LU decomposition");
            Console.WriteLine(resultX.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 2. Solve linear equations using QR decomposition
            resultX = matrixA.QR().Solve(vectorB);
            Console.WriteLine(@"2. Solution using QR decomposition");
            Console.WriteLine(resultX.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 3. Solve linear equations using SVD decomposition
            matrixA.Svd(true).Solve(vectorB, resultX);
            Console.WriteLine(@"3. Solution using SVD decomposition");
            Console.WriteLine(resultX.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 4. Solve linear equations using Gram-Shmidt decomposition
            matrixA.GramSchmidt().Solve(vectorB, resultX);
            Console.WriteLine(@"4. Solution using Gram-Shmidt decomposition");
            Console.WriteLine(resultX.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 5. Verify result. Multiply coefficient matrix "A" by result vector "x"
            var reconstructVecorB = matrixA * resultX;
            Console.WriteLine(@"5. Multiply coefficient matrix 'A' by result vector 'x'");
            Console.WriteLine(reconstructVecorB.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // To use Cholesky or Eigenvalue decomposition coefficient matrix must be
            // symmetric (for Evd and Cholesky) and positive definite (for Cholesky)
            // Multipy matrix "A" by its transpose - the result will be symmetric and positive definite matrix
            var newMatrixA = matrixA.TransposeAndMultiply(matrixA);
            Console.WriteLine(@"Symmetric positive definite matrix");
            Console.WriteLine(newMatrixA.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 6. Solve linear equations using Cholesky decomposition
            newMatrixA.Cholesky().Solve(vectorB, resultX);
            Console.WriteLine(@"6. Solution using Cholesky decomposition");
            Console.WriteLine(resultX.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 7. Solve linear equations using eigen value decomposition
            newMatrixA.Evd().Solve(vectorB, resultX);
            Console.WriteLine(@"7. Solution using eigen value decomposition");
            Console.WriteLine(resultX.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 8. Verify result. Multiply new coefficient matrix "A" by result vector "x"
            reconstructVecorB = newMatrixA * resultX;
            Console.WriteLine(@"8. Multiply new coefficient matrix 'A' by result vector 'x'");
            Console.WriteLine(reconstructVecorB.ToString("#0.00\t", formatProvider));
            Console.WriteLine();
        }
        /// <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.CopySubVectorTo(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>
        /// Run example.
        /// </summary>
        /// <seealso cref="http://en.wikipedia.org/wiki/Euclidean_vector#Scalar_multiplication">Multiply vector by scalar</seealso>
        /// <seealso cref="http://en.wikipedia.org/wiki/Euclidean_vector#Dot_product">Multiply vector by vector (compute the dot product between two vectors)</seealso>
        /// <seealso cref="http://en.wikipedia.org/wiki/Euclidean_vector#Addition_and_subtraction">Vector addition and subtraction</seealso>
        /// <seealso cref="http://en.wikipedia.org/wiki/Outer_product">Outer Product of two vectors</seealso>
        public void Run()
        {
            // Initialize IFormatProvider to print matrix/vector data
            var formatProvider = (CultureInfo)CultureInfo.InvariantCulture.Clone();
            formatProvider.TextInfo.ListSeparator = " ";

            // Create vector "X"
            var vectorX = new DenseVector(new[] { 1.0, 2.0, 3.0, 4.0, 5.0 });
            Console.WriteLine(@"Vector X");
            Console.WriteLine(vectorX.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Create vector "Y"
            var vectorY = new DenseVector(new[] { 5.0, 4.0, 3.0, 2.0, 1.0 });
            Console.WriteLine(@"Vector Y");
            Console.WriteLine(vectorY.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Multiply vector by scalar
            // 1. Using Multiply method and getting result into different vector instance
            var resultV = vectorX.Multiply(3.0);
            Console.WriteLine(@"Multiply vector by scalar using method Multiply. (result = X.Multiply(3.0))");
            Console.WriteLine(resultV.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 2. Using operator "*"
            resultV = 3.0 * vectorX;
            Console.WriteLine(@"Multiply vector by scalar using operator *. (result = 3.0 * X)");
            Console.WriteLine(resultV.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 3. Using Multiply method and updating vector itself
            vectorX.Multiply(3.0, vectorX);
            Console.WriteLine(@"Multiply vector by scalar using method Multiply. (X.Multiply(3.0, X))");
            Console.WriteLine(vectorX.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Multiply vector by vector (compute the dot product between two vectors)
            // 1. Using operator "*"
            var dotProduct = vectorX * vectorY;
            Console.WriteLine(@"Dot product between two vectors using operator *. (result = X * Y)");
            Console.WriteLine(dotProduct);
            Console.WriteLine();

            // 2. Using DotProduct method and getting result into different vector instance
            dotProduct = vectorX.DotProduct(vectorY);
            Console.WriteLine(@"Dot product between two vectors using method DotProduct. (result = X.DotProduct(Y))");
            Console.WriteLine(dotProduct.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Pointwise multiplies vector with another vector
            // 1. Using PointwiseMultiply method and getting result into different vector instance
            resultV = vectorX.PointwiseMultiply(vectorY);
            Console.WriteLine(@"Pointwise multiplies vector with another vector using method PointwiseMultiply. (result = X.PointwiseMultiply(Y))");
            Console.WriteLine(resultV.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 2. Using PointwiseMultiply method and updating vector itself
            vectorX.PointwiseMultiply(vectorY, vectorX);
            Console.WriteLine(@"Pointwise multiplies vector with another vector using method PointwiseMultiply. (X.PointwiseMultiply(Y, X))");
            Console.WriteLine(vectorX.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Pointwise divide vector with another vector
            // 1. Using PointwiseDivide method and getting result into different vector instance
            resultV = vectorX.PointwiseDivide(vectorY);
            Console.WriteLine(@"Pointwise divide vector with another vector using method PointwiseDivide. (result = X.PointwiseDivide(Y))");
            Console.WriteLine(resultV.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 2. Using PointwiseDivide method and updating vector itself
            vectorX.PointwiseDivide(vectorY, vectorX);
            Console.WriteLine(@"Pointwise divide vector with another vector using method PointwiseDivide. (X.PointwiseDivide(Y, X))");
            Console.WriteLine(vectorX.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Addition
            // 1. Using operator "+"
            resultV = vectorX + vectorY;
            Console.WriteLine(@"Add vectors using operator +. (result = X + Y)");
            Console.WriteLine(resultV.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 2. Using Add method and getting result into different vector instance
            resultV = vectorX.Add(vectorY);
            Console.WriteLine(@"Add vectors using method Add. (result = X.Add(Y))");
            Console.WriteLine(resultV.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 3. Using Add method and updating vector itself
            vectorX.Add(vectorY, vectorX);
            Console.WriteLine(@"Add vectors using method Add. (X.Add(Y, X))");
            Console.WriteLine(vectorX.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Subtraction
            // 1. Using operator "-"
            resultV = vectorX - vectorY;
            Console.WriteLine(@"Subtract vectors using operator -. (result = X - Y)");
            Console.WriteLine(resultV.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 2. Using Subtract method and getting result into different vector instance
            resultV = vectorX.Subtract(vectorY);
            Console.WriteLine(@"Subtract vectors using method Subtract. (result = X.Subtract(Y))");
            Console.WriteLine(resultV.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 3. Using Subtract method and updating vector itself
            vectorX.Subtract(vectorY, vectorX);
            Console.WriteLine(@"Subtract vectors using method Subtract. (X.Subtract(Y, X))");
            Console.WriteLine(vectorX.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Divide by scalar
            // 1. Using Divide method and getting result into different vector instance
            resultV = vectorX.Divide(3.0);
            Console.WriteLine(@"Divide vector by scalar using method Divide. (result = A.Divide(3.0))");
            Console.WriteLine(resultV.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 2. Using Divide method and updating vector itself
            vectorX.Divide(3.0, vectorX);
            Console.WriteLine(@"Divide vector by scalar using method Divide. (X.Divide(3.0, X))");
            Console.WriteLine(vectorX.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Outer Product of two vectors
            // 1. Using instanse method OuterProduct
            var resultM = vectorX.OuterProduct(vectorY);
            Console.WriteLine(@"Outer Product of two vectors using method OuterProduct. (X.OuterProduct(Y))");
            Console.WriteLine(resultM.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 2. Using static method of the Vector class
            resultM = Vector.OuterProduct(vectorX, vectorY);
            Console.WriteLine(@"Outer Product of two vectors using method OuterProduct. (Vector.OuterProduct(X,Y))");
            Console.WriteLine(resultM.ToString("#0.00\t", formatProvider));
            Console.WriteLine();
        }
        /// <summary>
        /// Run example
        /// </summary>
        /// <seealso cref="http://en.wikipedia.org/wiki/Matrix_multiplication#Scalar_multiplication">Multiply matrix by scalar</seealso>
        /// <seealso cref="http://reference.wolfram.com/mathematica/tutorial/MultiplyingVectorsAndMatrices.html">Multiply matrix by vector</seealso>
        /// <seealso cref="http://en.wikipedia.org/wiki/Matrix_multiplication#Matrix_product">Multiply matrix by matrix</seealso>
        /// <seealso cref="http://en.wikipedia.org/wiki/Matrix_multiplication#Hadamard_product">Pointwise multiplies matrix with another matrix</seealso>
        /// <seealso cref="http://en.wikipedia.org/wiki/Matrix_%28mathematics%29#Basic_operations">Addition and subtraction</seealso>
        public void Run()
        {
            // Initialize IFormatProvider to print matrix/vector data 
            var formatProvider = (CultureInfo)CultureInfo.InvariantCulture.Clone();
            formatProvider.TextInfo.ListSeparator = " ";

            // Create matrix "A"
            var matrixA = DenseMatrix.OfArray(new[,] { { 1.0, 2.0, 3.0 }, { 4.0, 5.0, 6.0 }, { 7.0, 8.0, 9.0 } });
            Console.WriteLine(@"Matrix A");
            Console.WriteLine(matrixA.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Create matrix "B"
            var matrixB = DenseMatrix.OfArray(new[,] { { 1.0, 3.0, 5.0 }, { 2.0, 4.0, 6.0 }, { 3.0, 5.0, 7.0 } });
            Console.WriteLine(@"Matrix B");
            Console.WriteLine(matrixB.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Multiply matrix by scalar
            // 1. Using operator "*"
            var resultM = 3.0 * matrixA;
            Console.WriteLine(@"Multiply matrix by scalar using operator *. (result = 3.0 * A)");
            Console.WriteLine(resultM.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 2. Using Multiply method and getting result into different matrix instance
            resultM = (DenseMatrix)matrixA.Multiply(3.0);
            Console.WriteLine(@"Multiply matrix by scalar using method Multiply. (result = A.Multiply(3.0))");
            Console.WriteLine(resultM.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 3. Using Multiply method and updating matrix itself
            matrixA.Multiply(3.0, matrixA);
            Console.WriteLine(@"Multiply matrix by scalar using method Multiply. (A.Multiply(3.0, A))");
            Console.WriteLine(matrixA.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Multiply matrix by vector (right-multiply)
            var vector = new DenseVector(new[] { 1.0, 2.0, 3.0 });
            Console.WriteLine(@"Vector");
            Console.WriteLine(vector.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 1. Using operator "*"
            var resultV = matrixA * vector;
            Console.WriteLine(@"Multiply matrix by vector using operator *. (result = A * vec)");
            Console.WriteLine(resultV.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 2. Using Multiply method and getting result into different vector instance
            resultV = (DenseVector)matrixA.Multiply(vector);
            Console.WriteLine(@"Multiply matrix by vector using method Multiply. (result = A.Multiply(vec))");
            Console.WriteLine(resultV.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 3. Using Multiply method and updating vector itself
            matrixA.Multiply(vector, vector);
            Console.WriteLine(@"Multiply matrix by vector using method Multiply. (A.Multiply(vec, vec))");
            Console.WriteLine(vector.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Multiply vector by matrix (left-multiply)
            // 1. Using operator "*"
            resultV = vector * matrixA;
            Console.WriteLine(@"Multiply vector by matrix using operator *. (result = vec * A)");
            Console.WriteLine(resultV.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 2. Using LeftMultiply method and getting result into different vector instance
            resultV = (DenseVector)matrixA.LeftMultiply(vector);
            Console.WriteLine(@"Multiply vector by matrix using method LeftMultiply. (result = A.LeftMultiply(vec))");
            Console.WriteLine(resultV.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 3. Using LeftMultiply method and updating vector itself
            matrixA.LeftMultiply(vector, vector);
            Console.WriteLine(@"Multiply vector by matrix using method LeftMultiply. (A.LeftMultiply(vec, vec))");
            Console.WriteLine(vector.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Multiply matrix by matrix
            // 1. Using operator "*"
            resultM = matrixA * matrixB;
            Console.WriteLine(@"Multiply matrix by matrix using operator *. (result = A * B)");
            Console.WriteLine(resultM.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 2. Using Multiply method and getting result into different matrix instance
            resultM = (DenseMatrix)matrixA.Multiply(matrixB);
            Console.WriteLine(@"Multiply matrix by matrix using method Multiply. (result = A.Multiply(B))");
            Console.WriteLine(resultM.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 3. Using Multiply method and updating matrix itself
            matrixA.Multiply(matrixB, matrixA);
            Console.WriteLine(@"Multiply matrix by matrix using method Multiply. (A.Multiply(B, A))");
            Console.WriteLine(matrixA.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Pointwise multiplies matrix with another matrix
            // 1. Using PointwiseMultiply method and getting result into different matrix instance
            resultM = (DenseMatrix)matrixA.PointwiseMultiply(matrixB);
            Console.WriteLine(@"Pointwise multiplies matrix with another matrix using method PointwiseMultiply. (result = A.PointwiseMultiply(B))");
            Console.WriteLine(resultM.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 2. Using PointwiseMultiply method and updating matrix itself
            matrixA.PointwiseMultiply(matrixB, matrixA);
            Console.WriteLine(@"Pointwise multiplies matrix with another matrix using method PointwiseMultiply. (A.PointwiseMultiply(B, A))");
            Console.WriteLine(matrixA.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Pointwise divide matrix with another matrix
            // 1. Using PointwiseDivide method and getting result into different matrix instance
            resultM = (DenseMatrix)matrixA.PointwiseDivide(matrixB);
            Console.WriteLine(@"Pointwise divide matrix with another matrix using method PointwiseDivide. (result = A.PointwiseDivide(B))");
            Console.WriteLine(resultM.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 2. Using PointwiseDivide method and updating matrix itself
            matrixA.PointwiseDivide(matrixB, matrixA);
            Console.WriteLine(@"Pointwise divide matrix with another matrix using method PointwiseDivide. (A.PointwiseDivide(B, A))");
            Console.WriteLine(matrixA.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Addition
            // 1. Using operator "+"
            resultM = matrixA + matrixB;
            Console.WriteLine(@"Add matrices using operator +. (result = A + B)");
            Console.WriteLine(resultM.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 2. Using Add method and getting result into different matrix instance
            resultM = (DenseMatrix)matrixA.Add(matrixB);
            Console.WriteLine(@"Add matrices using method Add. (result = A.Add(B))");
            Console.WriteLine(resultM.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 3. Using Add method and updating matrix itself
            matrixA.Add(matrixB, matrixA);
            Console.WriteLine(@"Add matrices using method Add. (A.Add(B, A))");
            Console.WriteLine(matrixA.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Subtraction
            // 1. Using operator "-"
            resultM = matrixA - matrixB;
            Console.WriteLine(@"Subtract matrices using operator -. (result = A - B)");
            Console.WriteLine(resultM.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 2. Using Subtract method and getting result into different matrix instance
            resultM = (DenseMatrix)matrixA.Subtract(matrixB);
            Console.WriteLine(@"Subtract matrices using method Subtract. (result = A.Subtract(B))");
            Console.WriteLine(resultM.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 3. Using Subtract method and updating matrix itself
            matrixA.Subtract(matrixB, matrixA);
            Console.WriteLine(@"Subtract matrices using method Subtract. (A.Subtract(B, A))");
            Console.WriteLine(matrixA.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Divide by scalar
            // 1. Using Divide method and getting result into different matrix instance
            resultM = (DenseMatrix)matrixA.Divide(3.0);
            Console.WriteLine(@"Divide matrix by scalar using method Divide. (result = A.Divide(3.0))");
            Console.WriteLine(resultM.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 2. Using Divide method and updating matrix itself
            matrixA.Divide(3.0, matrixA);
            Console.WriteLine(@"Divide matrix by scalar using method Divide. (A.Divide(3.0, A))");
            Console.WriteLine(matrixA.ToString("#0.00\t", formatProvider));
            Console.WriteLine();
        }
        /// <summary>
        /// Run example
        /// </summary>
        public void Run()
        {
            // Format matrix output to console
            var formatProvider = (CultureInfo)CultureInfo.InvariantCulture.Clone();
            formatProvider.TextInfo.ListSeparator = " ";
            
            // Create square matrix
            var matrix = new DenseMatrix(5);
            var k = 0;
            for (var i = 0; i < matrix.RowCount; i++)
            {
                for (var j = 0; j < matrix.ColumnCount; j++)
                {
                    matrix[i, j] = k++;
                }
            }

            Console.WriteLine(@"Initial matrix");
            Console.WriteLine(matrix.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Create vector
            var vector = new DenseVector(new[] { 50.0, 51.0, 52.0, 53.0, 54.0 });
            Console.WriteLine(@"Sample vector");
            Console.WriteLine(vector.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 1. Insert new column
            var result = matrix.InsertColumn(3, vector);
            Console.WriteLine(@"1. Insert new column");
            Console.WriteLine(result.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 2. Insert new row
            result = matrix.InsertRow(3, vector);
            Console.WriteLine(@"2. Insert new row");
            Console.WriteLine(result.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 3. Set column values
            matrix.SetColumn(2, (Vector)vector);
            Console.WriteLine(@"3. Set column values");
            Console.WriteLine(matrix.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 4. Set row values. 
            matrix.SetRow(3, (double[])vector);
            Console.WriteLine(@"4. Set row values");
            Console.WriteLine(matrix.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 5. Set diagonal values. SetRow/SetColumn/SetDiagonal accepts Vector and double[] as input parameter
            matrix.SetDiagonal(new[] { 5.0, 4.0, 3.0, 2.0, 1.0 });
            Console.WriteLine(@"5. Set diagonal values");
            Console.WriteLine(matrix.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 6. Set submatrix values
            matrix.SetSubMatrix(1, 3, 1, 3, DenseMatrix.Identity(3));
            Console.WriteLine(@"6. Set submatrix values");
            Console.WriteLine(matrix.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Permutations. 
            // Initialize a new instance of the Permutation class. An array represents where each integer is permuted too: 
            // indices[i] represents that integer "i" is permuted to location indices[i]
            var permutations = new Permutation(new[] { 0, 1, 3, 2, 4 });
            
            // 7. Permute rows 3 and 4
            matrix.PermuteRows(permutations);
            Console.WriteLine(@"7. Permute rows 3 and 4");
            Console.WriteLine(matrix.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 8. Permute columns 1 and 2, 3 and 5
            permutations = new Permutation(new[] { 1, 0, 4, 3, 2 });
            matrix.PermuteColumns(permutations);
            Console.WriteLine(@"8. Permute columns 1 and 2, 3 and 5");
            Console.WriteLine(matrix.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 9. Concatenate the matrix with the given matrix
            var append = matrix.Append(matrix);

            // Concatenate into result matrix
            matrix.Append(matrix, append);
            Console.WriteLine(@"9. Append matrix to matrix");
            Console.WriteLine(append.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

             // 10. Stack the matrix on top of the given matrix matrix
            var stack = matrix.Stack(matrix);

            // Stack into result matrix
            matrix.Stack(matrix, stack);
            Console.WriteLine(@"10. Stack the matrix on top of the given matrix matrix");
            Console.WriteLine(stack.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 11. Diagonally stack the matrix on top of the given matrix matrix
            var diagoinalStack = matrix.DiagonalStack(matrix);

            // Diagonally stack into result matrix
            matrix.DiagonalStack(matrix, diagoinalStack);
            Console.WriteLine(@"11. Diagonally stack the matrix on top of the given matrix matrix");
            Console.WriteLine(diagoinalStack.ToString("#0.00\t", formatProvider));
            Console.WriteLine();
        }
        /// <summary>
        /// Run example
        /// </summary>
        public void Run()
        {
            // Format matrix output to console
            var formatProvider = (CultureInfo)CultureInfo.InvariantCulture.Clone();
            formatProvider.TextInfo.ListSeparator = " ";

            // Solve next system of linear equations (Ax=b):
            // 5*x + 2*y - 4*z = -7
            // 3*x - 7*y + 6*z = 38
            // 4*x + 1*y + 5*z = 43

            // Create matrix "A" with coefficients
            var matrixA = new DenseMatrix(new[,] { { 5.00, 2.00, -4.00 }, { 3.00, -7.00, 6.00 }, { 4.00, 1.00, 5.00 } });
            Console.WriteLine(@"Matrix 'A' with coefficients");
            Console.WriteLine(matrixA.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Create vector "b" with the constant terms.
            var vectorB = new DenseVector(new[] { -7.0, 38.0, 43.0 });
            Console.WriteLine(@"Vector 'b' with the constant terms");
            Console.WriteLine(vectorB.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Create stop criteriums to monitor an iterative calculation. There are next available stop criteriums:
            // - DivergenceStopCriterium: monitors an iterative calculation for signs of divergence;
            // - FailureStopCriterium: monitors residuals for NaN's;
            // - IterationCountStopCriterium: monitors the numbers of iteration steps;
            // - ResidualStopCriterium: monitors residuals if calculation is considered converged;

            // Stop calculation if 1000 iterations reached during calculation
            var iterationCountStopCriterium = new IterationCountStopCriterium(1000);

            // Stop calculation if residuals are below 1E-10 --> the calculation is considered converged
            var residualStopCriterium = new ResidualStopCriterium(1e-10);

            // Create monitor with defined stop criteriums
            var monitor = new Iterator(new IIterationStopCriterium[] { iterationCountStopCriterium, residualStopCriterium });

            // Load all suitable solvers from current assembly. Below in this example, there is user-defined solver
            // "class UserBiCgStab : IIterativeSolverSetup<double>" which uses regular BiCgStab solver. But user may create any other solver
            // and solver setup classes which implement IIterativeSolverSetup<T> and pass assembly to next function:
            CompositeSolver.LoadSolverInformationFromAssembly(Assembly.GetExecutingAssembly());

            // Create composite solver
            var solver = new CompositeSolver(monitor);

            // 1. Solve the matrix equation
            var resultX = solver.Solve(matrixA, vectorB);
            Console.WriteLine(@"1. Solve the matrix equation");
            Console.WriteLine();

            // 2. Check solver status of the iterations.
            // Solver has property IterationResult which contains the status of the iteration once the calculation is finished.
            // Possible values are:
            // - CalculationCancelled: calculation was cancelled by the user;
            // - CalculationConverged: calculation has converged to the desired convergence levels;
            // - CalculationDiverged: calculation diverged;
            // - CalculationFailure: calculation has failed for some reason;
            // - CalculationIndetermined: calculation is indetermined, not started or stopped;
            // - CalculationRunning: calculation is running and no results are yet known;
            // - CalculationStoppedWithoutConvergence: calculation has been stopped due to reaching the stopping limits, but that convergence was not achieved;
            Console.WriteLine(@"2. Solver status of the iterations");
            Console.WriteLine(solver.IterationResult);
            Console.WriteLine();

            // 3. Solution result vector of the matrix equation
            Console.WriteLine(@"3. Solution result vector of the matrix equation");
            Console.WriteLine(resultX.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 4. Verify result. Multiply coefficient matrix "A" by result vector "x"
            var reconstructVecorB = matrixA * resultX;
            Console.WriteLine(@"4. Multiply coefficient matrix 'A' by result vector 'x'");
            Console.WriteLine(reconstructVecorB.ToString("#0.00\t", formatProvider));
            Console.WriteLine();
        }