Esempio n. 1
0
        public void LinearAlgebraComplexMatrix()
        {
            //using DotNumerics.LinearAlgebra;
            //using DotNumerics;

            ComplexMatrix A = new ComplexMatrix(3, 3);

            A[0, 0] = new Complex(3, 9); A[0, 1] = new Complex(4, 6); A[0, 2] = new Complex(1, 8);
            A[1, 0] = new Complex(8, 3); A[1, 1] = new Complex(2, 4); A[1, 2] = new Complex(5, 5);
            A[2, 0] = new Complex(2, 5); A[2, 1] = new Complex(7, 2); A[2, 2] = new Complex(5, 5);

            EigenSystem   es = new EigenSystem();
            ComplexMatrix eigenvectors;
            ComplexMatrix eigenvalues = es.GetEigenvalues(A, out eigenvectors);

            //Ax-lX=0
            Complex       lambda     = eigenvalues[0, 0];
            ComplexVector X          = eigenvectors.GetColumnVectors()[0];
            ComplexMatrix AXmlambdaX = A * X - lambda * X;

            ObjectDumper.Write("A=");
            ObjectDumper.Write(A.MatrixToString("0.000"));

            ObjectDumper.Write("Eigenvalues:");
            ObjectDumper.Write(eigenvalues.MatrixToString("0.000"));

            ObjectDumper.Write("Eigenvectors:");
            ObjectDumper.Write(eigenvectors.MatrixToString("0.000"));

            ObjectDumper.Write("A * X - lambda * X = ");
            ObjectDumper.Write(AXmlambdaX.MatrixToString("0.000"));
        }
Esempio n. 2
0
        /// <summary>
        /// Gets a column vector from the matrix.
        /// </summary>
        /// <param name="Column">Zero-based column index into the matrix.</param>
        /// <param name="Vector">New column vector.</param>
        public void SetColumn(int Column, IVector Vector)
        {
            if (Column < 0 || Column >= this.columns)
            {
                throw new ScriptException("Index out of bounds.");
            }

            if (Vector.Dimension != this.rows)
            {
                throw new ScriptException("Vector dimension does not match number of rows");
            }

            ComplexVector V = Vector as ComplexVector;

            if (V == null)
            {
                throw new ScriptException("Column vectors in a Complex matrix must be Complex vectors.");
            }

            Complex[] V2 = V.Values;
            Complex[,] M  = this.Values;
            this.elements = null;
            int i = 0;

            for (i = 0; i < this.rows; i++)
            {
                M[i, Column] = V2[i];
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Use the Durand-Kerner method to find the roots of a polynomial
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public static List <Complex> DurandKerner(RealPolynomial p)
        {
            // According to Wikipedia, radius of initial condition should be 1 + max(|a_1|,|a_2|,...,|a_n-1|)
            ComplexVector current = InitialCondition(p.Degree, 1 + p.Coefficients.Select(d => System.Math.Abs(d)).Max());

            ComplexVector Iterate(ComplexVector v)
            {
                ComplexVector newVector = new ComplexVector(v);

                for (int i = 0; i < v.Dimension; i++)
                {
                }

                return(v);
            }

            ComplexVector next = new ComplexVector(current.Dimension);

            while (!next.CloseTo(current))
            {
                next = Iterate(current);
            }

            return(null);
        }
Esempio n. 4
0
        /// <summary>
        /// Быстрое кепстральное преобразование
        /// </summary>
        /// <param name="signal">Сигнал</param>
        /// <returns></returns>
        public static Vector FKT(ComplexVector signal)
        {
            ComplexVector spectr  = Furie.fft(signal);
            Vector        Aspectr = MathFunc.ln(spectr.MagnitudeToVector().TransformVector(x => x * x));

            return(Furie.fft(Aspectr).RealToVector() / Aspectr.N);
        }
Esempio n. 5
0
        /// <summary>
        /// Передискретизация сигнала
        /// (повышение частоты дискретизации в целое число раз)
        /// </summary>
        /// <param name="inp">Входной вектор</param>
        /// <param name="fd">Старая частота дискретизации</param>
        /// <param name="newfd">Новая частота дикретизации</param>
        /// <returns>Вектор тойже длительности, что и входной,
        /// но с более высокой частотой дискретизации</returns>
        public static Vector Perediscr(Vector inp, int fd, int newfd)
        {
            int           k = newfd / fd;
            ComplexVector inputSpectr = Furie.fft(inp);
            int           len = inp.N * (k - 1), lenFull = inp.N * k;
            int           i   = 0;
            ComplexVector cV  = new ComplexVector(lenFull);
            int           end = inp.N / 2;

            for (; i < end; i++)
            {
                cV[i] = inputSpectr[i];
            }

            end = lenFull - inp.N / 2;

            for (; i < end; i++)
            {
                cV[i] = new System.Numerics.Complex(0, 0);
            }

            for (int j = inp.N / 2; i < lenFull; i++)
            {
                cV[i] = inputSpectr[j];
            }


            return(Furie.ifft(cV).RealToVector());
        }
Esempio n. 6
0
        // Генерация вектора фич
        private Vector GenFeature()
        {
            ComplexVector cV = Furie.fft(points);
            double        k, cP1, cP2;
            Complex       kR;

            if (!_isScale)
            {
                cP1 = cV[0].Magnitude;
                cP2 = cV[cV.N - 1].Magnitude;
                k   = Math.Sqrt(cP1 * cP1 + cP2 * cP2);
                cV /= k;
            }


            if (!_isRot)
            {
                cP1 = cV[0].Phase;
                cP2 = cV[cV.N - 1].Phase;
                kR  = Complex.Exp(new Complex(0, 1) * (cP2 - cP1) / 2.0);
                cV *= kR;
            }

            if (!_isMove)
            {
                cV[0] = 0;
            }

            cV = cV.CutAndZero(n);

            Vector modules = cV.MagnitudeToVector();
            Vector phases  = cV.PhaseToVector();

            return(phases);//Vector.Concatinate(new Vector[]{modules, phases});
        }
Esempio n. 7
0
        /// <summary>
        /// Sets an element in the vector.
        /// </summary>
        /// <param name="Index">Index.</param>
        /// <param name="Value">Element to set.</param>
        public void SetElement(int Index, IElement Value)
        {
            if (Index < 0 || Index >= this.rows)
            {
                throw new ScriptException("Index out of bounds.");
            }

            ComplexVector V = Value as ComplexVector;

            if (V == null)
            {
                throw new ScriptException("Row vectors in a Complex matrix are required to be Complex vectors.");
            }

            if (V.Dimension != this.columns)
            {
                throw new ScriptException("Dimension mismatch.");
            }

            Complex[] V2 = V.Values;
            Complex[,] M  = this.Values;
            this.elements = null;

            int i;

            for (i = 0; i < this.columns; i++)
            {
                M[Index, i] = V2[i];
            }
        }
Esempio n. 8
0
        protected override void OnHFieldsAtSiteCalculated(ObservationSite site,
                                                          ComplexVector normalField, ComplexVector anomalyField)
        {
            var e = new MtFieldsAtSiteCalculatedEventArgs(CurrentSource, site, normalField, anomalyField);

            HFieldsAtSiteCalculated?.Invoke(this, e);
        }
Esempio n. 9
0
        public void LinearAlgebraEigenvaluesAndEigenvectors()
        {
            //using DotNumerics.LinearAlgebra;
            //using DotNumerics;

            Matrix A = new Matrix(3, 3);

            A[0, 0] = 2; A[0, 1] = 5; A[0, 2] = 3;
            A[1, 0] = 1; A[1, 1] = 5; A[1, 2] = 7;
            A[2, 0] = 8; A[2, 1] = 2; A[2, 2] = 3;

            EigenSystem   es = new EigenSystem();
            ComplexMatrix eigenvectors;
            ComplexMatrix eigenvalues = es.GetEigenvalues(A, out eigenvectors);

            //Ax-lX=0
            Complex       lambda     = eigenvalues[0, 0];
            ComplexVector X          = eigenvectors.GetColumnVectors()[0];
            ComplexMatrix AXmlambdaX = A.CopyToComplex() * X - lambda * X;

            ObjectDumper.Write("A=");
            ObjectDumper.Write(A.MatrixToString("0.000"));

            ObjectDumper.Write("Eigenvalues:");
            ObjectDumper.Write(eigenvalues.MatrixToString("0.000"));

            ObjectDumper.Write("Eigenvectors:");
            ObjectDumper.Write(eigenvectors.MatrixToString("0.000"));

            ObjectDumper.Write("A * X - lambda * X = ");
            ObjectDumper.Write(AXmlambdaX.MatrixToString("0.000"));
        }
Esempio n. 10
0
        public void VectorInverse()
        {
            var expected = new ComplexVector(
                new Complex[] { new Complex(-6, 4), new Complex(-7, -3), new Complex(-4.2, 8.1), new Complex(0, 3) });
            var result = v1.Inverse;

            Assert.AreEqual(expected, result);
        }
Esempio n. 11
0
        public void VectorSubtraction()
        {
            var expected = new ComplexVector(
                new Complex[] { new Complex(-10, -6.3), new Complex(7, 10), new Complex(-1.8, -8.1), new Complex(0, 1) });
            var result = v1 - v2;

            Assert.AreEqual(expected, result);
        }
Esempio n. 12
0
        public void MatrixColumn()
        {
            var expected = new ComplexVector(
                new Complex[] { new Complex(5, -4), new Complex(1, -1), new Complex(-4, 2) });
            var result = m1.Column(3);

            Assert.AreEqual(expected, result);
        }
Esempio n. 13
0
        public void MatrixRow()
        {
            var expected = new ComplexVector(
                new Complex[] { new Complex(3, -1), new Complex(1, 4), new Complex(-2, 1), new Complex(1, -1) });
            var result = m1.Row(1);

            Assert.AreEqual(expected, result);
        }
Esempio n. 14
0
        public void VectorConjugate()
        {
            var expected = new ComplexVector(
                new Complex[] { new Complex(6, -3), new Complex(0, 0), new Complex(5, -1), new Complex(4, 0) });
            var result = v3.Conjugate;

            Assert.AreEqual(expected, result);
        }
Esempio n. 15
0
        public void VectorAddition()
        {
            var expected = new ComplexVector(
                new Complex[] { new Complex(22, -1.7), new Complex(7, -4), new Complex(10.2, -8.1), new Complex(0, -7) });
            var result = v1 + v2;

            Assert.AreEqual(expected, result);
        }
Esempio n. 16
0
        public void VectorScalarMultiplication()
        {
            var expected = new ComplexVector(
                new Complex[] { new Complex(12, 21), new Complex(0, 0), new Complex(13, 13), new Complex(12, 8) });
            var result = v3.ScalarProduct(c9);

            Assert.AreEqual(expected, result);
        }
Esempio n. 17
0
        public void TestSerializeComplexVector()
        {
            ComplexVector before = ComplexVector.Random(10, _random);
            ComplexVector after  = SerializeDeserialize(before);

            Assert.That(after, Is.Not.Null, "Not Null");
            Assert.That(after, Is.EqualTo(before), "Equal");
            Assert.That(after, NumericIs.AlmostEqualTo(before), "Almost Equal");
        }
        /// <summary>
        /// Арктангенс
        /// </summary>
        /// <param name="Inp">Комплексный вектор значений для преобразования</param>
        public static ComplexVector arctg(ComplexVector Inp)
        {
            ComplexVector A = new ComplexVector(Inp.N);

            for (int i = 0; i < Inp.N; i++)
            {
                A.DataInVector[i] = Complex.Atan(Inp.DataInVector[i]);
            }

            return(A);
        }
        /// <summary>
        /// Модуль
        /// </summary>
        /// <param name="Inp">Комплексный вектор значений для преобразования</param>
        public static Vector abs(ComplexVector Inp)
        {
            Vector A = new Vector(Inp.N);

            for (int i = 0; i < Inp.N; i++)
            {
                A.DataInVector[i] = Complex.Abs(Inp.DataInVector[i]);
            }

            return(A);
        }
Esempio n. 20
0
        public static void Start(REngine engine)
        {
            Console.WriteLine("\n\nExporting Objects\n\n");
            string RCodeString = string.Empty;

            //R character vector -- R.NET RDotNet.RDotNet.CharacterVector
            Console.WriteLine("\nR character vector\n");
            string[]        myStringArray     = new string[] { "PIDataLink", "PIProcessBook", "PIWebParts" };
            CharacterVector myCharacterVector = engine.CreateCharacterVector(myStringArray.AsEnumerable());

            engine.SetSymbol("mycharvector", myCharacterVector);
            engine.Evaluate("print(mycharvector)");


            //R integer vector -- R.NET RDotNet.NumericVector
            Console.WriteLine("\nR int vector\n");
            int[]         myIntegerArray  = new int[] { 4, 6, 10, 140, 54, 25 };
            IntegerVector myIntegerVector = engine.CreateIntegerVector(myIntegerArray);

            engine.SetSymbol("myintvector", myIntegerVector);
            engine.Evaluate("print(myintvector)");

            //R real vector -- R.NET RDotNet.NumericVector
            Console.WriteLine("\nR real vector\n");
            NumericVector myNumericVector = engine.CreateNumericVector(new double[] { 30.02, 29.99, 30.11, 29.97, 30.01, 29.99 });

            engine.SetSymbol("mynumvector", myNumericVector);
            engine.Evaluate("print(mynumvector)");

            //R complex vector -- R.NET RDotNet.ComplexVector
            Console.WriteLine("\nR complex vector\n");
            Complex[]     myComplexArray  = new Complex[] { Complex.FromPolarCoordinates(10, 0.524), new Complex(12, 6), new Complex(14, 3), (Complex)12.3m, Complex.One + Complex.One };
            ComplexVector myComplexVector = engine.CreateComplexVector(myComplexArray);

            engine.SetSymbol("mycomplexvector", myComplexVector);
            engine.Evaluate("print(mycomplexvector)");


            //R raw vector -- R.NET RDotNet.RawVector
            Console.WriteLine("\nR raw vector\n");
            byte[]    myByteArray = System.Text.Encoding.ASCII.GetBytes("u03a0");
            RawVector myRawVector = engine.CreateRawVector(myByteArray);

            engine.SetSymbol("myrawvector", myRawVector);
            engine.Evaluate("print(myrawvector)");

            //R logical vector -- R.NET RDotNet.LogicalVector
            Console.WriteLine("\nR logical vector\n");
            LogicalVector myLogicalVector = engine.CreateLogicalVector(new Boolean[] { true, false, false, false, true });

            engine.SetSymbol("mylogicalvector", myLogicalVector);
            engine.Evaluate("print(mylogicalvector)");
        }
Esempio n. 21
0
        /// <summary>
        /// Householder Reflection: Evaluate symmetric? unitary Q such that Q*v = -sigma*||v||*e1 
        /// </summary>
        public static ComplexMatrix Reflection(ComplexVector v)
        {
            Complex sigma = v[0].Sign;

            ComplexVector u = v.Clone();
            u[0] += sigma * v.Norm();

            ComplexMatrix m = ComplexMatrix.Identity(v.Length, v.Length);
            m.MultiplyAccumulateInplace(u.TensorMultiply(u), -2d / u.ScalarMultiply(u));

            return m;
        }
Esempio n. 22
0
        /// <summary>
        /// Аналитический сигнал
        /// </summary>
        /// <param name="st">Входной сигнал</param>
        public static ComplexVector GetAnalSig(Vector st)
        {
            ComplexVector cv  = new ComplexVector(st.N);
            Vector        stH = ConjugateToTheHilbert(st);

            for (int i = 0; i < st.N; i++)
            {
                cv.DataInVector[i] = new Complex(st.DataInVector[i], stH.DataInVector[i]);
            }

            return(cv);
        }
Esempio n. 23
0
        /// <summary>
        /// Gets the eigenvalues of the given matrix, calculated numerically from the
        /// characteristic polynomial of this matrix. Continues until all eigenvalues
        /// have been found.
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public static RealVector RealEigenValues(this RealMatrix m)
        {
            if (!m.IsSquare())
            {
                throw new IncompatibleOperationException(MatrixOperationType.Eigenvalue);
            }

            ComplexVector values = new ComplexVector(m.Width);



            throw new NotImplementedException();
        }
Esempio n. 24
0
        /// <summary>
        /// Реализация простого фильтра
        /// </summary>
        /// <param name="st">Вектор сигнала</param>
        /// <param name="kw">АЧХ</param>
        /// <returns>Фильтрованный сигнал</returns>
        public static Vector Filter(Vector st, Vector kw)
        {
            Vector newSt = st.CutAndZero(Functions.NextPow2(st.N));
            Vector newKw = kw.CutAndZero(newSt.N / 2);

            newKw = newKw.AddSimmetr();
            //newKw.Visual();
            ComplexVector Sw = Furie.fft(newSt);

            Sw    = Sw * newKw;
            newSt = Furie.ifft(Sw).RealToVector();
            return(newSt.CutAndZero(st.N));//newSt.N;
        }
        /// <summary>
        /// Householder Reflection: Evaluate symmetric? unitary Q such that Q*v = -sigma*||v||*e1
        /// </summary>
        public static ComplexMatrix Reflection(ComplexVector v)
        {
            Complex sigma = v[0].Sign;

            ComplexVector u = v.Clone();

            u[0] += sigma * v.Norm();

            ComplexMatrix m = ComplexMatrix.Identity(v.Length, v.Length);

            m.MultiplyAccumulateInplace(u.TensorMultiply(u), -2d / u.ScalarMultiply(u));

            return(m);
        }
Esempio n. 26
0
        // Дискретное преобразование Фурье
        public ComplexVector DFT(Vector vector)
        {
            ComplexVector complex = new ComplexVector(vector.Count);

            for (int i = 0; i < vector.Count; i++)
            {
                for (int j = 0; j < complex.Count; j++)
                {
                    complex[i] += vector[j] * Complex.Exp(-Complex.ImaginaryOne * 2.0 * Math.PI * i * j / complex.Count);
                }
            }

            return(complex / complex.Count);
        }
Esempio n. 27
0
        /// <summary>
        /// Evaluates the function on a vector argument.
        /// </summary>
        /// <param name="Argument">Function argument.</param>
        /// <param name="Variables">Variables collection.</param>
        /// <returns>Function result.</returns>
        public override IElement EvaluateVector(ComplexVector Argument, Variables Variables)
        {
            int i, c = Argument.Dimension;

            Complex[] E = new Complex[c];
            Complex[] V = Argument.Values;

            for (i = 0; i < c; i++)
            {
                E[c - i - 1] = V[i];
            }

            return(new ComplexVector(E));
        }
Esempio n. 28
0
        /// <summary>
        /// Creates n
        /// </summary>
        /// <param name="n"></param>
        /// <param name="first"></param>
        /// <param name="radius"></param>
        /// <returns></returns>
        private static ComplexVector InitialCondition(int n, double radius, Complex first)
        {
            ComplexVector vector = new ComplexVector(n);

            // A unit vector in the same direction
            Complex unit = first / first.Modulus;

            for (int i = 0; i < vector.Dimension; i++)
            {
                vector[i] = radius * (unit ^ i);
            }

            return(vector);
        }
Esempio n. 29
0
        public AllFieldsAtSite(AllFieldsAtSite site)
        {
            Site = site.Site;

            NormalE1 = new ComplexVector(site.NormalE1);
            NormalE2 = new ComplexVector(site.NormalE2);
            NormalH1 = new ComplexVector(site.NormalH1);
            NormalH2 = new ComplexVector(site.NormalH2);

            AnomalyE1 = new ComplexVector(site.AnomalyE1);
            AnomalyE2 = new ComplexVector(site.AnomalyE2);
            AnomalyH1 = new ComplexVector(site.AnomalyH1);
            AnomalyH2 = new ComplexVector(site.AnomalyH2);
        }
Esempio n. 30
0
        /// <summary>
        /// Выделение огибающей на базе квадратурн. сост
        /// </summary>
        public static Vector OgibNew(Vector t, Vector st, double f0)
        {
            ComplexVector cV = new ComplexVector(t.N);

            for (int i = 0; i < t.N; i++)
            {
                cV[i] = Complex.Exp(-new Complex(0, 1) * Math.PI * 2 * f0 * t[i]);
            }

            ComplexVector newSt = st * cV;


            return(newSt.RealToVector() + newSt.ImgToVector());
        }
Esempio n. 31
0
        public static Tipper CalculateTipper(ComplexVector h1, ComplexVector h2)
        {
            var determinant = h1.X * h2.Y - h2.X * h1.Y;

            var hi11 = h2.Y / determinant;
            var hi12 = -h2.X / determinant;
            var hi21 = -h1.Y / determinant;
            var hi22 = h1.X / determinant;

            var wzx = h1.Z * hi11 + h2.Z * hi21;
            var wzy = h1.Z * hi12 + h2.Z * hi22;

            return(new Tipper(wzx, wzy));
        }
 public void TestOrthogonalReflectionComplex()
 {
     StandardDistribution gaussian = new StandardDistribution();
     for(int i = 0; i < 100; i++)
     {
         ComplexVector v = new ComplexVector(new Complex[] { Complex.Random(gaussian), Complex.Random(gaussian), Complex.Random(gaussian), Complex.Random(gaussian) });
         ComplexMatrix reflection = Orthogonal.Reflection(v);
         ComplexVector res = reflection * v;
         Assert.That(reflection.HermitianTranspose() * reflection, NumericIs.AlmostEqualTo(ComplexMatrix.Identity(4, 4)), "orthogonal reflection matrix");
         Assert.That(reflection[0, 0].IsReal, "c1 real");
         Assert.That(reflection[1, 1].IsReal, "c2 real");
         Assert.That(reflection[2, 2].IsReal, "c3 real");
         Assert.That(reflection[3, 3].IsReal, "c4 real");
         Assert.That(res[0].Modulus, NumericIs.AlmostEqualTo(v.Norm(), 1e-12), "res(1)");
         Assert.That(res[1], NumericIs.AlmostEqualTo((Complex) 0, 1e-12), "res(2)");
         Assert.That(res[2], NumericIs.AlmostEqualTo((Complex) 0, 1e-12), "res(3)");
         Assert.That(res[3], NumericIs.AlmostEqualTo((Complex) 0, 1e-12), "res(4)");
     }
 }
        ////OnDemandComputation<ComplexVector> _eigenValuesOnDemand;
        /// <summary>
        /// Initializes a new instance of the EigenvalueDecomposition class, which check
        /// the matrix for symmetry and then construct the eigenvalue decomposition.
        /// </summary>
        /// <remarks>Provides access to D and V</remarks>
        /// <param name="arg">Square matrix</param>
        public EigenvalueDecomposition(Matrix arg)
        {
            double[][] a = arg;
            _n = arg.ColumnCount;
            _v = Matrix.CreateMatrixData(_n, _n);
            _d = new double[_n];
            _e = new double[_n];

            _isSymmetric = true;
            for(int j = 0; (j < _n) & _isSymmetric; j++)
            {
                for(int i = 0; (i < _n) & _isSymmetric; i++)
                {
                    _isSymmetric &= (a[i][j] == a[j][i]);
                }
            }

            if(_isSymmetric)
            {
                for(int i = 0; i < _n; i++)
                {
                    for(int j = 0; j < _n; j++)
                    {
                        _v[i][j] = a[i][j];
                    }
                }

                SymmetricTridiagonalize();

                SymmetricDiagonalize();
            }
            else
            {
                _h = new double[_n][];
                for(int i = 0; i < _n; i++)
                {
                    double[] hi = new double[_n];
                    double[] ai = a[i];

                    for(int j = 0; j < _n; j++)
                    {
                        hi[j] = ai[j];
                    }

                    _h[i] = hi;
                }

                NonsymmetricReduceToHessenberg();

                NonsymmetricReduceHessenberToRealSchur();
            }

            _eigenValuesReal = new Vector(_d);
            _eigenValuesImag = new Vector(_e);
            _eigenValues = ComplexVector.Create(_d, _e);

            InitOnDemandComputations();
        }
        public void TestComplexMatrix_Multiplicative()
        {
            /*
            MATLAB:
            prod_cc = ca3x2 * cd2x4
            prod_cm = ca3x2 * md2x4
            prod_cs = ca3x2 * s
            prod_cc2 = cc2x2 * cc2x2
            prod_cm2 = cc2x2 * mc2x2
            prod_cs2 = cc2x2 * s
            prod_ccv = ca3x2 * cv2.'
            prod_cv = ca3x2 * v2.'
            prod_ccvdl = diag(cv2) * cc2x2
            prod_ccvdr = cc2x2 * diag(cv2)
            prod_cvdl = diag(v2) * cc2x2
            prod_cvdr = cc2x2 * diag(v2)
            */

            // ComplexMatrix * ComplexMatrix
            ComplexMatrix prod_cc = new ComplexMatrix(new Complex[][] {
                new Complex[] { -66+12*j, -66+72*j, -66-228*j, -66+672*j },
                new Complex[] { -154+268*j, -154+300*j, -154+308*j, -154+368*j },
                new Complex[] { -352+424*j, -352+582*j, -352+44*j, -352+1784*j }});
            NumericAssert.AreAlmostEqual(prod_cc, ca3x2 * cd2x4, "prod cc 1");
            NumericAssert.AreAlmostEqual(prod_cc, ca3x2.Multiply(cd2x4), "prod cc 2");

            // ComplexMatrix * Matrix
            ComplexMatrix prod_cm = new ComplexMatrix(new Complex[][] {
                new Complex[] { 6-12*j, 12-24*j, -18+36*j, 72-144*j },
                new Complex[] { 38-76*j,41.2-82.4*j, 42-84*j, 48-96*j },
                new Complex[] { 68-136*j, 83.8-167.6*j, 30-60*j, 204-408*j }});
            NumericAssert.AreAlmostEqual(prod_cm, ca3x2 * md2x4, "prod cm 1");
            NumericAssert.AreAlmostEqual(prod_cm, ca3x2.Multiply(md2x4), "prod cm 2");

            // ComplexMatrix * Complex
            ComplexMatrix prod_cs = new ComplexMatrix(new Complex[][] {
                new Complex[] { 18-6*j, 0 },
                new Complex[] { 6-2*j,36-12*j },
                new Complex[] { 42-14*j, 54-18*j }});
            NumericAssert.AreAlmostEqual(prod_cs, ca3x2 * s, "prod cs 1");
            NumericAssert.AreAlmostEqual(prod_cs, ca3x2.Multiply(s), "prod cs 2");

            // ComplexMatrix * ComplexMatrix (Square)
            ComplexMatrix prod_cc2 = new ComplexMatrix(new Complex[][] {
                new Complex[] { -1232-924*j, -1368-1026*j },
                new Complex[] { -1520-1140*j, -1688-1266*j }});
            NumericAssert.AreAlmostEqual(prod_cc2, cc2x2 * cc2x2, "prod cc2 1");
            NumericAssert.AreAlmostEqual(prod_cc2, cc2x2.Multiply(cc2x2), "prod cc2 2");
            ComplexMatrix prod_cc2_inplace = cc2x2.Clone();
            prod_cc2_inplace.MultiplyInplace(cc2x2);
            NumericAssert.AreAlmostEqual(prod_cc2, prod_cc2_inplace, "prod cc2 3");

            // ComplexMatrix * Matrix (Square)
            ComplexMatrix prod_cm2 = new ComplexMatrix(new Complex[][] {
                new Complex[] { 35-105*j, 52-156*j },
                new Complex[] { 43-129*j, 64-192*j }});
            NumericAssert.AreAlmostEqual(prod_cm2, cc2x2 * mc2x2, "prod cm2 1");
            NumericAssert.AreAlmostEqual(prod_cm2, cc2x2.Multiply(mc2x2), "prod cm2 2");
            ComplexMatrix prod_cm2_inplace = cc2x2.Clone();
            prod_cm2_inplace.MultiplyInplace(mc2x2);
            NumericAssert.AreAlmostEqual(prod_cm2, prod_cm2_inplace, "prod cm2 3");

            // ComplexMatrix * Complex (Square)
            ComplexMatrix prod_cs2 = new ComplexMatrix(new Complex[][] {
                new Complex[] { 32-16*j, 36-18*j },
                new Complex[] { 40-20*j, 44-22*j }});
            NumericAssert.AreAlmostEqual(prod_cs2, cc2x2 * s, "prod cs2 1");
            NumericAssert.AreAlmostEqual(prod_cs2, cc2x2.Multiply(s), "prod cs2 2");
            ComplexMatrix prod_cs2_inplace = cc2x2.Clone();
            prod_cs2_inplace.MultiplyInplace(s);
            NumericAssert.AreAlmostEqual(prod_cs2, prod_cs2_inplace, "prod cs2 3");

            // ComplexMatrix * ComplexVector (Column)
            ComplexVector prod_ccv = new ComplexVector(new Complex[] { 42 - 54 * j, 62 + 66 * j, 170 });
            NumericAssert.AreAlmostEqual(prod_ccv, ca3x2 * cv2, "prod ccv 1");
            NumericAssert.AreAlmostEqual(prod_ccv, ca3x2.MultiplyRightColumn(cv2), "prod ccv 2");

            // ComplexMatrix * Vector (Column)
            ComplexVector prod_cv = new ComplexVector(new Complex[] { 30 - 60 * j, -14 + 28 * j, 34 - 68 * j });
            NumericAssert.AreAlmostEqual(prod_cv, ca3x2 * v2, "prod cv 1");
            NumericAssert.AreAlmostEqual(prod_cv, ca3x2.MultiplyRightColumn(v2), "prod cv 2");

            // ComplexMatrix * ComplexVector (Diagonal, Left)
            ComplexMatrix prod_ccvdl = new ComplexMatrix(new Complex[][] {
                new Complex[] { 64-112*j, 72-126*j },
                new Complex[] { 70+90*j, 77+99*j }});
            NumericAssert.AreAlmostEqual(prod_ccvdl, cc2x2.MultiplyLeftDiagonal(cv2), "prod ccv dl 1");
            ComplexMatrix prod_ccvdl_inplace = cc2x2.Clone();
            prod_ccvdl_inplace.MultiplyLeftDiagonalInplace(cv2);
            NumericAssert.AreAlmostEqual(prod_ccvdl, prod_ccvdl_inplace, "prod ccv dl 2");
            NumericAssert.AreAlmostEqual(prod_ccvdl, ComplexMatrix.Diagonal(cv2) * cc2x2, "prod ccv dl 3");

            // ComplexMatrix * Vector (Diagonal, Left)
            ComplexMatrix prod_cvdl = new ComplexMatrix(new Complex[][] {
                new Complex[] { 40-120*j, 45-135*j },
                new Complex[] { -20+60*j, -22+66*j }});
            NumericAssert.AreAlmostEqual(prod_cvdl, cc2x2.MultiplyLeftDiagonal(v2), "prod cv dl 1");
            ComplexMatrix prod_cvdl_inplace = cc2x2.Clone();
            prod_cvdl_inplace.MultiplyLeftDiagonalInplace(v2);
            NumericAssert.AreAlmostEqual(prod_cvdl, prod_cvdl_inplace, "prod cv dl 2");

            // ComplexMatrix * ComplexVector (Diagonal, Right)
            ComplexMatrix prod_ccvdr = new ComplexMatrix(new Complex[][] {
                new Complex[] { 64-112*j, 63+81*j },
                new Complex[] { 80-140*j, 77+99*j }});
            NumericAssert.AreAlmostEqual(prod_ccvdr, cc2x2.MultiplyRightDiagonal(cv2), "prod ccv dr 1");
            ComplexMatrix prod_ccvdr_inplace = cc2x2.Clone();
            prod_ccvdr_inplace.MultiplyRightDiagonalInplace(cv2);
            NumericAssert.AreAlmostEqual(prod_ccvdr, prod_ccvdr_inplace, "prod ccv dr 2");
            NumericAssert.AreAlmostEqual(prod_ccvdr, cc2x2 * ComplexMatrix.Diagonal(cv2), "prod ccv dr 3");

            // ComplexMatrix * Vector (Diagonal, Right)
            ComplexMatrix prod_cvdr = new ComplexMatrix(new Complex[][] {
                new Complex[] { 40-120*j, -18+54*j },
                new Complex[] { 50-150*j, -22+66*j }});
            NumericAssert.AreAlmostEqual(prod_cvdr, cc2x2.MultiplyRightDiagonal(v2), "prod cv dr 1");
            ComplexMatrix prod_cvdr_inplace = cc2x2.Clone();
            prod_cvdr_inplace.MultiplyRightDiagonalInplace(v2);
            NumericAssert.AreAlmostEqual(prod_cvdr, prod_cvdr_inplace, "prod cv dr 2");
        }
        public void TestComplexMatrix_Setup()
        {
            /*
            MATLAB:
            ma3x2 = [1 -2;-1 4;5 7]
            mb3x2 = [10 2.5;-3 -1.5;19 -6]
            mc2x2 = [1 2;3 4]
            md2x4 = [1 2 -3 12;3 3.1 4 2]
            ra3x2 = ma3x2 + 2
            rb3x2 = mb3x2 - 1
            rc2x2 = mc2x2 + 5
            rd2x4 = md2x4 * 2
            ia3x2 = (ra3x2 * 2) * j
            ib3x2 = (rb3x2 * 3 + 1) * j
            ic2x2 = (rc2x2 + 2) * j
            id2x4 = (rd2x4 - 5) * j
            ca3x2 = 2*ra3x2 - 2*ia3x2
            cb3x2 = rb3x2 + 3*ib3x2
            cc2x2 = rc2x2 + 2 - 3*ic2x2
            cd2x4 = -2*rd2x4 + id2x4 + 1-j
            v2 = [5 -2]
            cv2 = [5+j, -2+3j]
            */

            ma3x2 = new Matrix(new double[][] {
                new double[] { 1, -2 },
                new double[] { -1, 4 },
                new double[] { 5, 7 }});
            mb3x2 = new Matrix(new double[][] {
                new double[] { 10, 2.5 },
                new double[] { -3, -1.5 },
                new double[] { 19, -6 }});
            mc2x2 = new Matrix(new double[][] {
                new double[] { 1, 2 },
                new double[] { 3, 4 }});
            md2x4 = new Matrix(new double[][] {
                new double[] { 1, 2, -3, 12 },
                new double[] { 3, 3.1, 4, 2 }});

            ra3x2 = ComplexMatrix.Create(ma3x2) + 2;
            rb3x2 = ComplexMatrix.Create(mb3x2) - 1;
            rc2x2 = ComplexMatrix.Create(mc2x2) + 5;
            rd2x4 = ComplexMatrix.Create(md2x4) * 2;

            ia3x2 = (ra3x2 * 2) * j;
            ib3x2 = (rb3x2 * 3 + 1) * j;
            ic2x2 = (rc2x2 + 2) * j;
            id2x4 = (rd2x4 - 5) * j;

            ca3x2 = 2 * ra3x2 - 2 * ia3x2;
            cb3x2 = rb3x2 + 3 * ib3x2;
            cc2x2 = rc2x2 + 2 - 3 * ic2x2;
            cd2x4 = -2 * rd2x4 + id2x4 + (1 - j);

            v2 = new Vector(new double[] { 5, -2 });
            cv2 = new ComplexVector(new Complex[] { 5 + j, -2 + 3 * j });
        }
 public static Animation ShowMatrixMultiplication(TimeSpan period,
                                             Rect pos,
                                             ComplexMatrix u,
                                             ComplexVector v,
                                             Ani<Brush> or,
                                             Ani<Brush> blu,
                                             Ani<Brush> bla)
 {
     var d = Math.Min(pos.Width/(u.Columns.Count + 2), pos.Height/u.Rows.Count)/2;
     pos = new Rect(pos.TopLeft, new Size(d * (u.Columns.Count + 2)*2, d*u.Rows.Count*2));
     var ur = d;
     var animation = new Animation {
         new RectDesc(new Rect(pos.X + d * 2, pos.Y, pos.Width - d * 4, pos.Height),
                      Brushes.Black,
                      strokeThickness: 0.6,
                      dashed: 5),
         new RectDesc(new Rect(pos.X, pos.Y, d * 2, pos.Height),
                      Brushes.Black,
                      strokeThickness: 0.6,
                      dashed: 5),
         new RectDesc(new Rect(pos.Right - d*2, pos.Y, d * 2, pos.Height),
                      Brushes.Black,
                      strokeThickness: 0.6,
                      dashed: 5)
     };
     var per = animation.Periodic(period);
     var s0 = per.LimitedSameTime(0.Seconds(), period.DividedBy(4));
     foreach (var r in u.Rows.Count.Range()) {
         var pp = s0.Proper;
         // input vector
         var p1 = pos.TopLeft + new Vector(d, d + r*d*2);
         var p2 = pos.TopLeft + new Vector(d*3 + r*d*2, 0);
         var p3 = pos.TopLeft + new Vector(d*3 + r*d*2, u.Rows.Count*d*2);
         s0.Add(ShowComplex(pp.Combine(blu, (p, b) => b.LerpToTransparent(p.SmoothTransition(0, 0, 1))),
                            pp.Combine(bla, (p, b) => b.LerpToTransparent(p.SmoothTransition(0, 0, 1))),
                            v.Values[r],
                            pp.Select(p => p.SmoothTransition(p1, p1, p2, p3)),
                            ur,
                            rotation: pp.Select(t => Turn.FromNaturalAngle(t.SmoothTransition(0, Math.PI/2, Math.PI/2)))));
         foreach (var c in u.Columns.Count.Range()) {
             // vector copied into matrix
             s0.Add(ShowComplex(pp.Combine(blu, (p, b) => b.LerpToTransparent(p.SmoothTransition(1, 1, 0))),
                                pp.Combine(bla, (p, b) => b.LerpToTransparent(p.SmoothTransition(1, 1, 0))),
                                v.Values[c],
                                (pos.TopLeft + new Vector(d*3 + c*d*2, d + r*d*2)),
                                ur,
                                Brushes.Transparent,
                                rotation: Turn.FromNaturalAngle(Math.PI/2)));
             // matrix
             s0.Add(ShowComplex(pp.Combine(or, (p, b) => b.LerpToTransparent(p.SmoothTransition(0, 0, 0))),
                                pp.Combine(bla, (p, b) => b.LerpToTransparent(p.SmoothTransition(0, 0, 0))),
                                u.Rows[r][c],
                                (pos.TopLeft + new Vector(d*3 + c*d*2, d + r*d*2)),
                                ur));
         }
     }
     var s1 = per.LimitedSameTime(period.Times(0.25), period.Times(0.5));
     foreach (var r in u.Rows.Count.Range()) {
         foreach (var c in u.Columns.Count.Range()) {
             s1.Add(
                 ShowComplexProduct(
                     blu,
                     or,
                     bla,
                     bla,
                     v.Values[c],
                     u.Rows[r][c],
                     (pos.TopLeft + new Vector(d*3 + c*d*2, d + r*d*2)),
                     ur,
                     s1.Proper));
         }
     }
     var s2 = per.LimitedSameTime(period.Times(0.5), period);
     foreach (var r in u.Rows.Count.Range()) {
         s2.Add(
             ShowComplexSum(
                 blu,
                 blu,
                 bla,
                 u.Rows[r].Count.Range()
                          .Select(e => u.Rows[r][e]*v.Values[e])
                          .Select(e => new ConstantAni<Complex>(e)),
                 (pos.TopLeft + new Vector(d*3, d + r*d*2)),
                 (pos.TopLeft + new Vector(d*3 + u.Columns.Count*d*2, d + r*d*2)),
                 new Vector(d*2, 0),
                 ur,
                 s2.Proper));
     }
     return animation;
 }
        public static Animation CreateTelepathyAnimation()
        {
            var i = Complex.ImaginaryOne;
            var beamSplit = ComplexMatrix.FromSquareData(
                1, i,
                i, 1) / Math.Sqrt(2);
            var swap = ComplexMatrix.FromSquareData(
                1, 0, 0, 0,
                0, 0, 1, 0,
                0, 1, 0, 0,
                0, 0, 0, 1);
            var controlledNot2When1 = ComplexMatrix.FromSquareData(
                1, 0, 0, 0,
                0, 1, 0, 0,
                0, 0, 0, 1,
                0, 0, 1, 0);
            var H = ComplexMatrix.MakeUnitaryHadamard(1);

            var v = new ComplexVector(new Complex[] { 0.5, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 0.5 });
            var controlledNot1When2 = ComplexMatrix.FromSquareData(
                1, 0, 0, 0,
                0, 0, 0, 1,
                0, 0, 1, 0,
                0, 1, 0, 0);
            var gates = new[] {
                H.TensorProduct(ComplexMatrix.MakeIdentity(2)).TensorProduct(ComplexMatrix.MakeIdentity(4)), //alice bottom 1
                ComplexMatrix.MakeIdentity(4).TensorProduct(controlledNot1When2), // bob left 1
                ComplexMatrix.MakeIdentity(4).TensorProduct(beamSplit.TensorSquare()), // bob left 2
                controlledNot2When1.TensorProduct(ComplexMatrix.MakeIdentity(4)), //alice bottom 2
                ComplexMatrix.MakeIdentity(4).TensorProduct(swap), // bob left 3
                H.TensorProduct(ComplexMatrix.MakeIdentity(2)).TensorProduct(ComplexMatrix.MakeIdentity(4)) //alice bottom 3
            };
            var ackGates = gates.Stream(ComplexMatrix.MakeIdentity(16), (a, m) => m * a, streamSeed: true).ToArray();
            var start = new Point(200, 200);
            return new Animation {
                MakeTransformAnimation(
                    start,
                    v.Values,
                    Ani.Anon(t => {
                        var p = t.TotalSeconds%(ackGates.Length + 4) - 1;
                        var pi = (int)Math.Floor(p);
                        var pd = p - pi;
                        pd = (pd*2 - 1).Clamp(0, 1);

                        var g1 = ackGates[pi.Clamp(0, ackGates.Length - 1)];
                        var g2 = ackGates[(pi + 1).Clamp(0, ackGates.Length - 1)];
                        return (g1*(1 - pd) + g2*pd);
                    }),
                    new[] {
                        "c₁ (win)", "c₂ (win)", "c₃", "c₄", "c₅", "c₆", "c₇ (win)", "c₈ (win)", "c₉", "c₁₀", "c₁₁ (win)", "c₁₂ (win)", "c₁₃ (win)", "c₁₄ (win)",
                        "c₁₅", "c₁₆"
                    }),
                MakeAxies(new Point(350, 295)),
                new TextDesc("Quantum Pseudotelepathy", new Point(400/2, 5), new Point(0.5, 0), fontSize: 20),
                new TextDesc("Applying Alice's and Bob's Gates for Bottom Left Case", new Point(400/2, 30), new Point(0.5, 0)),
                new TextDesc("(makes about as much sense as [insert political joke])", new Point(400/2, 50), new Point(0.5, 0), fontSize: 8),
            };
        }
        public static Animation CreateComplexTransformationAnimation()
        {
            var matrixFill = (Brush)Brushes.Orange.LerpToTransparent(0.5);
            var vectorFill = (Brush)Brushes.Blue.LerpToTransparent(0.7);

            var s = new Complex(Math.Sqrt(0.5), 0);
            var si = new Complex(0, s.Real);
            var c1 = Complex.FromPolarCoordinates(Math.Sqrt(0.75), 0);
            var c2 = Complex.FromPolarCoordinates(Math.Sqrt(0.2), Math.PI / 4);
            var m = ComplexMatrix.FromSquareData(s, si, -s, si);
            var v = new ComplexVector(new[] { c1, c2 });
            var u = 50;

            var animation = new Animation {
                new TextDesc("Matrix Multiplication with Complex Numbers",
                             new Point(25 + u*(v.Values.Count + 2), 5),
                             new Point(0.5, 0),
                             fontSize: 15,
                             foreground: Brushes.Gray),
            };
            var r = new Rect(25, 25, u*2*(v.Values.Count + 2), u*2*v.Values.Count);
            var p = animation.Dilated(0.5.Seconds()).Periodic(10.Seconds());
            var qx1 = p.Proper.Select(e => (e * 10 - 9).Clamp(0, 1));
            var qx2 = p.Proper.Select(e => ((e - 0.6) * 10).Clamp(0, 1));

            p.Add(ShowMatrixMultiplication(
                10.Seconds(),
                r,
                m,
                v,
                qx1.Select(matrixFill.LerpToTransparent),
                qx1.Select(vectorFill.LerpToTransparent),
                qx1.Select(x => (Brush)Brushes.Black.LerpToTransparent(x))));

            p.LimitedSameTime(0.Seconds(), 10.Seconds()).Add(ShowMatrixMultiplication(
                100000000.Seconds(),
                r,
                m,
                v,
                qx2.Select(x => matrixFill.LerpToTransparent(1 - x)),
                qx2.Select(x => vectorFill.LerpToTransparent(1 - x)),
                qx2.Select(x => (Brush)Brushes.Black.LerpToTransparent(1 - x))));

            return animation;
        }
        public void Setup()
        {
            // MATLAB: ma3x2 = [1 -2;-1 4;5 7]
            _ma3X2 = new Matrix(new double[][] {
                new double[] { 1, -2 },
                new double[] { -1, 4 },
                new double[] { 5, 7 }
                });

            // MATLAB: mb3x2 = [10 2.5;-3 -1.5;19 -6]
            _mb3X2 = new Matrix(new double[][] {
                new double[] { 10, 2.5 },
                new double[] { -3, -1.5 },
                new double[] { 19, -6 }
                });

            // MATLAB: mc2x2 = [1 2;3 4]
            _mc2X2 = new Matrix(new double[][] {
                new double[] { 1, 2 },
                new double[] { 3, 4 }
                });

            // MATLAB: md2x4 = [1 2 -3 12;3 3.1 4 2]
            _md2X4 = new Matrix(new double[][] {
                new double[] { 1, 2, -3, 12 },
                new double[] { 3, 3.1, 4, 2 }
                });

            // MATLAB: ra3x2 = ma3x2 + 2
            _ra3X2 = ComplexMatrix.Create(_ma3X2) + 2;

            // MATLAB: rb3x2 = mb3x2 - 1
            _rb3X2 = ComplexMatrix.Create(_mb3X2) - 1;

            // MATLAB: rc2x2 = mc2x2 + 5
            _rc2X2 = ComplexMatrix.Create(_mc2X2) + 5;

            // MATLAB: rd2x4 = md2x4 * 2
            _rd2X4 = ComplexMatrix.Create(_md2X4) * 2;

            // MATLAB:  ia3x2 = (ra3x2 * 2) * j
            _ia3X2 = (_ra3X2 * 2) * j;

            // MATLAB: ib3x2 = (rb3x2 * 3 + 1) * j
            _ib3X2 = ((_rb3X2 * 3) + 1) * j;

            // MATLAB: ic2x2 = (rc2x2 + 2) * j
            _ic2X2 = (_rc2X2 + 2) * j;

            // MATLAB: id2x4 = (rd2x4 - 5) * j
            _id2X4 = (_rd2X4 - 5) * j;

            // MATLAB: ca3x2 = 2*ra3x2 - 2*ia3x2
            _ca3X2 = (2 * _ra3X2) - (2 * _ia3X2);

            // MATLAB: cb3x2 = rb3x2 + 3*ib3x2
            _cb3X2 = _rb3X2 + (3 * _ib3X2);

            // MATLAB: cc2x2 = rc2x2 + 2 - 3*ic2x2
            _cc2X2 = _rc2X2 + 2 - (3 * _ic2X2);

            // MATLAB: cd2x4 = -2*rd2x4 + id2x4 + 1-j
            _cd2X4 = (-2 * _rd2X4) + _id2X4 + (1 - j);

            // MATLAB: v2 = [5 -2]
            _v2 = new Vector(new double[] { 5, -2 });

            // MATLAB: cv2 = [5+j, -2+3j]
            _cv2 = new ComplexVector(new Complex[] { 5 + j, -2 + (3 * j) });
        }
        EigenvalueDecomposition(
            Matrix Arg
            )
        {
            double[][] A = Arg;
            n = Arg.ColumnCount;
            V = Matrix.CreateMatrixData(n, n);
            d = new double[n];
            e = new double[n];

            isSymmetric = true;
            for(int j = 0; (j < n) & isSymmetric; j++)
            {
                for(int i = 0; (i < n) & isSymmetric; i++)
                {
                    isSymmetric &= (A[i][j] == A[j][i]);
                }
            }

            if(isSymmetric)
            {
                for(int i = 0; i < n; i++)
                {
                    for(int j = 0; j < n; j++)
                    {
                        V[i][j] = A[i][j];
                    }
                }

                SymmetricTridiagonalize();

                SymmetricDiagonalize();
            }
            else
            {
                H = new double[n][];
                for(int i = 0; i < n; i++)
                {
                    double[] Hi = new double[n];
                    double[] Ai = A[i];

                    for(int j = 0; j < n; j++)
                    {
                        Hi[j] = Ai[j];
                    }

                    H[i] = Hi;
                }

                NonsymmetricReduceToHessenberg();

                NonsymmetricReduceHessenberToRealSchur();
            }

            _eigenValuesReal = new Vector(d);
            _eigenValuesImag = new Vector(e);
            _eigenValues = ComplexVector.Create(d, e);

            InitOnDemandComputations();
        }
        EigenvalueDecomposition(
            double[] d,
            double[] e
            )
        {
            // TODO: unit test missing for EigenvalueDecomposition constructor.

            n = d.Length;
            V = Matrix.CreateMatrixData(n, n);

            this.d = new double[n];
            Array.Copy(d, 0, this.d, 0, n);

            this.e = new double[n];
            Array.Copy(e, 0, this.e, 1, n - 1);

            for(int i = 0; i < n; i++)
            {
                V[i][i] = 1;
            }

            SymmetricDiagonalize();

            _eigenValuesReal = new Vector(this.d);
            _eigenValuesImag = new Vector(this.e);
            _eigenValues = ComplexVector.Create(this.d, this.e);

            InitOnDemandComputations();
        }
        /// <summary>
        /// Initializes a new instance of the EigenvalueDecomposition class,
        /// by decomposing symmetrical, tridiagonal matrices.
        /// </summary>
        public EigenvalueDecomposition(
            double[] d,
            double[] e)
        {
            /* TODO: unit test missing for EigenvalueDecomposition constructor. */

            _n = d.Length;
            _v = Matrix.CreateMatrixData(_n, _n);

            _d = new double[_n];
            Array.Copy(d, 0, _d, 0, _n);

            _e = new double[_n];
            Array.Copy(e, 0, _e, 1, _n - 1);

            for(int i = 0; i < _n; i++)
            {
                _v[i][i] = 1;
            }

            SymmetricDiagonalize();

            _eigenValuesReal = new Vector(_d);
            _eigenValuesImag = new Vector(_e);
            _eigenValues = ComplexVector.Create(_d, _e);

            InitOnDemandComputations();
        }
Esempio n. 43
0
        /// <summary>
        /// Givens Rotation: Evaluate unitary G = [c,s;-s,c] such that |G*v| = [norm(v);0] and c is real. 
        /// </summary>
        public static ComplexMatrix Rotation(ComplexVector v)
        {
            double c;
            Complex s;

            Rotation(v[0], v[1], out c, out s);

            Complex[][] m = ComplexMatrix.CreateMatrixData(2, 2);
            m[0][0] = c;
            m[0][1] = s;
            m[1][0] = -s.Conjugate;
            m[1][1] = c;

            return new ComplexMatrix(m);
        }
        private static Animation MakeTransformAnimation(Point center, IEnumerable<Complex> input, Ani<ComplexMatrix> transform, string[] labels = null)
        {
            var vector = new ComplexVector(input);
            var aniValues = from m in transform
                            select (m * vector).Values;
            var valuesAni = vector.Values.Count.Range().Select(i => from values in aniValues
                                                                    select values[i]);
            var colors = new[] { 0x3366CC, 0xdc3912, 0xff9900, 0x109618, 0x990099, 0x0099c6, 0xdd4477, 0x66aa00,
                                 0xb82e2e, 0x316395, 0x994499, 0x22aa99, 0xaaaa11, 0x6633cc, 0xe67300, 0x8b0707}
                .Select(e => Color.FromRgb((byte)(e >> 16), (byte)(e >> 8), (byte)(e >> 0)))
                .Select(e => new SolidColorBrush(e))
                .Cast<Brush>()
                .ToArray();

            labels = labels ?? new[] { "c₁", "c₂", "c₃", "c₄", "c₅", "c₆", "c₇", "c₈", "c₉", "c₁₀", "c₁₁", "c₁₂", "c₁₃", "c₁₄", "c₁₅", "c₁₆" };
            var labelledAniValues = labels
                .Zip(valuesAni, (label, v) => new KeyValuePair<string, Ani<Complex>>(label, v))
                .ToDictionary(e => e.Key, e => e.Value);
            var ani = new Animation {
                MakeSuperpositionAnimation(
                    center,
                    labelledAniValues,
                    colors)
            };
            return ani;
        }
        public static Animation CreateFullGroverAnimation(int numWire)
        {
            var vectorFill = (Brush)Brushes.Blue.LerpToTransparent(0.7);
            var H = ComplexMatrix.MakeUnitaryHadamard(numWire);
            var I2 = ComplexMatrix.MakeSinglePhaseInverter(1 << numWire, 0);
            var D = H * I2 * H;
            var U = ComplexMatrix.MakeSinglePhaseInverter(1 << numWire, 1);
            var S = U*D;
            var input = new ComplexVector(new Complex[] {1}.Concat(Complex.Zero.Repeat((1 << numWire) - 1)).ToArray());

            var steps = (int)Math.Round(Math.PI/4*Math.Sqrt(1 << numWire));
            var GS = new CircuitOperationWithStyle {
                Description = "Step",
                MinWire = 0,
                MaxWire = numWire-1,
                Operation = S,
                Width = 80,
                WireHints=new[] {"Off"}.Concat("On".Repeat(numWire-1)).ToArray()
            };
            return CreateCircuitAnimation(
                900,
                20.Seconds(),
                new[] {
                    new CircuitOperationWithStyle {
                        Description="H",
                        MinWire=0,
                        MaxWire=numWire-1,
                        Operation=H,
                        Width=80
                    }
                }.Concat(GS.Repeat(steps)).ToArray(),
                ReadOnlyList.Repeat(
                    new CircuitInputWithStyle {
                        Value = input,
                        Color = vectorFill
                    },
                    steps+2),
                "Grover's Algorithm",
                showMatrix: false,
                wireSpace: numWire * 80 / 3.0);
        }
 public static void AreAlmostEqual(ComplexVector expected, ComplexVector actual, double relativeAccuracy, string message)
 {
     Assert.DoAssert(new AlmostEqualAsserter(expected.Norm1(), actual.Norm1(), (expected - actual).Norm1(), relativeAccuracy, message));
 }
        public void ComplexMatrixMultiplication()
        {
            /*
            MATLAB:
            prod_cc = ca3x2 * cd2x4
            prod_cm = ca3x2 * md2x4
            prod_cs = ca3x2 * s
            prod_cc2 = cc2x2 * cc2x2
            prod_cm2 = cc2x2 * mc2x2
            prod_cs2 = cc2x2 * s
            prod_ccv = ca3x2 * cv2.'
            prod_cv = ca3x2 * v2.'
            prod_ccvdl = diag(cv2) * cc2x2
            prod_ccvdr = cc2x2 * diag(cv2)
            prod_cvdl = diag(v2) * cc2x2
            prod_cvdr = cc2x2 * diag(v2)
            */

            // ComplexMatrix * ComplexMatrix
            ComplexMatrix prodCmCm = new ComplexMatrix(new Complex[][] {
                new Complex[] { -66+(12*j), -66+(72*j), -66-(228*j), -66+(672*j) },
                new Complex[] { -154+(268*j), -154+(300*j), -154+(308*j), -154+(368*j) },
                new Complex[] { -352+(424*j), -352+(582*j), -352+(44*j), -352+(1784*j) }
                });

            Assert.That(_ca3X2 * _cd2X4, NumericIs.AlmostEqualTo(prodCmCm), "prod cc 1");
            Assert.That(_ca3X2.Multiply(_cd2X4), NumericIs.AlmostEqualTo(prodCmCm), "prod cc 2");

            // ComplexMatrix * Matrix
            ComplexMatrix prodCmM = new ComplexMatrix(new Complex[][] {
                new Complex[] { 6-(12*j), 12-(24*j), -18+(36*j), 72-(144*j) },
                new Complex[] { 38-(76*j), 41.2-(82.4*j), 42-(84*j), 48-(96*j) },
                new Complex[] { 68-(136*j), 83.8-(167.6*j), 30-(60*j), 204-(408*j) }
                });

            Assert.That(_ca3X2 * _md2X4, NumericIs.AlmostEqualTo(prodCmM), "prod cm 1");
            Assert.That(_ca3X2.Multiply(_md2X4), NumericIs.AlmostEqualTo(prodCmM), "prod cm 2");

            // ComplexMatrix * Complex
            ComplexMatrix prodCmC = new ComplexMatrix(new Complex[][] {
                new Complex[] { 18-(6*j), 0 },
                new Complex[] { 6-(2*j), 36-(12*j) },
                new Complex[] { 42-(14*j), 54-(18*j) }
                });

            Assert.That(_ca3X2 * _s, NumericIs.AlmostEqualTo(prodCmC), "prod cs 1");
            Assert.That(_ca3X2.Multiply(_s), NumericIs.AlmostEqualTo(prodCmC), "prod cs 2");

            // ComplexMatrix * ComplexMatrix (Square)
            ComplexMatrix prodCmCmSquare = new ComplexMatrix(new Complex[][] {
                new Complex[] { -1232-(924*j), -1368-(1026*j) },
                new Complex[] { -1520-(1140*j), -1688-(1266*j) }
                });

            Assert.That(_cc2X2 * _cc2X2, NumericIs.AlmostEqualTo(prodCmCmSquare), "prod cc2 1");
            Assert.That(_cc2X2.Multiply(_cc2X2), NumericIs.AlmostEqualTo(prodCmCmSquare), "prod cc2 2");
            ComplexMatrix prodCmCmSquareInplace = _cc2X2.Clone();
            prodCmCmSquareInplace.MultiplyInplace(_cc2X2);
            Assert.That(prodCmCmSquareInplace, NumericIs.AlmostEqualTo(prodCmCmSquare), "prod cc2 3");

            // ComplexMatrix * Matrix (Square)
            ComplexMatrix prodCmMSquare = new ComplexMatrix(new Complex[][] {
                new Complex[] { 35-(105*j), 52-(156*j) },
                new Complex[] { 43-(129*j), 64-(192*j) }
                });

            Assert.That(_cc2X2 * _mc2X2, NumericIs.AlmostEqualTo(prodCmMSquare), "prod cm2 1");
            Assert.That(_cc2X2.Multiply(_mc2X2), NumericIs.AlmostEqualTo(prodCmMSquare), "prod cm2 2");
            ComplexMatrix prodCmMSquareInplace = _cc2X2.Clone();
            prodCmMSquareInplace.MultiplyInplace(_mc2X2);
            Assert.That(prodCmMSquareInplace, NumericIs.AlmostEqualTo(prodCmMSquare), "prod cm2 3");

            // ComplexMatrix * Complex (Square)
            ComplexMatrix prodCmCSquare = new ComplexMatrix(new Complex[][] {
                new Complex[] { 32-(16*j), 36-(18*j) },
                new Complex[] { 40-(20*j), 44-(22*j) }
                });

            Assert.That(_cc2X2 * _s, NumericIs.AlmostEqualTo(prodCmCSquare), "prod cs2 1");
            Assert.That(_cc2X2.Multiply(_s), NumericIs.AlmostEqualTo(prodCmCSquare), "prod cs2 2");
            ComplexMatrix prodCmCSquareInplace = _cc2X2.Clone();
            prodCmCSquareInplace.MultiplyInplace(_s);
            Assert.That(prodCmCSquareInplace, NumericIs.AlmostEqualTo(prodCmCSquare), "prod cs2 3");

            // ComplexMatrix * ComplexVector (Column)
            ComplexVector prodCmCvc = new ComplexVector(new Complex[] { 42 - (54 * j), 62 + (66 * j), 170 });
            Assert.That(_ca3X2 * _cv2, NumericIs.AlmostEqualTo(prodCmCvc), "prod ccv 1");
            Assert.That(_ca3X2.MultiplyRightColumn(_cv2), NumericIs.AlmostEqualTo(prodCmCvc), "prod ccv 2");

            // ComplexMatrix * Vector (Column)
            ComplexVector prodCmVc = new ComplexVector(new Complex[] { 30 - (60 * j), -14 + (28 * j), 34 - (68 * j) });
            Assert.That(_ca3X2 * _v2, NumericIs.AlmostEqualTo(prodCmVc), "prod cv 1");
            Assert.That(_ca3X2.MultiplyRightColumn(_v2), NumericIs.AlmostEqualTo(prodCmVc), "prod cv 2");

            // ComplexMatrix * ComplexVector (Diagonal, Left)
            ComplexMatrix prodCmCvdl = new ComplexMatrix(new Complex[][] {
                new Complex[] { 64-(112*j), 72-(126*j) },
                new Complex[] { 70+(90*j), 77+(99*j) }
                });

            Assert.That(_cc2X2.MultiplyLeftDiagonal(_cv2), NumericIs.AlmostEqualTo(prodCmCvdl), "prod ccv dl 1");
            ComplexMatrix prodCmCvdlInplace = _cc2X2.Clone();
            prodCmCvdlInplace.MultiplyLeftDiagonalInplace(_cv2);
            Assert.That(prodCmCvdlInplace, NumericIs.AlmostEqualTo(prodCmCvdl), "prod ccv dl 2");
            Assert.That(ComplexMatrix.Diagonal(_cv2) * _cc2X2, NumericIs.AlmostEqualTo(prodCmCvdl), "prod ccv dl 3");

            // ComplexMatrix * Vector (Diagonal, Left)
            ComplexMatrix prodCmVdl = new ComplexMatrix(new Complex[][] {
                new Complex[] { 40-(120*j), 45-(135*j) },
                new Complex[] { -20+(60*j), -22+(66*j) }
                });

            Assert.That(_cc2X2.MultiplyLeftDiagonal(_v2), NumericIs.AlmostEqualTo(prodCmVdl), "prod cv dl 1");
            ComplexMatrix prodCmVdlInplace = _cc2X2.Clone();
            prodCmVdlInplace.MultiplyLeftDiagonalInplace(_v2);
            Assert.That(prodCmVdlInplace, NumericIs.AlmostEqualTo(prodCmVdl), "prod cv dl 2");

            // ComplexMatrix * ComplexVector (Diagonal, Right)
            ComplexMatrix prodCmCvdr = new ComplexMatrix(new Complex[][] {
                new Complex[] { 64-(112*j), 63+(81*j) },
                new Complex[] { 80-(140*j), 77+(99*j) }
                });

            Assert.That(_cc2X2.MultiplyRightDiagonal(_cv2), NumericIs.AlmostEqualTo(prodCmCvdr), "prod ccv dr 1");
            ComplexMatrix prodCmCvdrInplace = _cc2X2.Clone();
            prodCmCvdrInplace.MultiplyRightDiagonalInplace(_cv2);
            Assert.That(prodCmCvdrInplace, NumericIs.AlmostEqualTo(prodCmCvdr), "prod ccv dr 2");
            Assert.That(_cc2X2 * ComplexMatrix.Diagonal(_cv2), NumericIs.AlmostEqualTo(prodCmCvdr), "prod ccv dr 3");

            // ComplexMatrix * Vector (Diagonal, Right)
            ComplexMatrix prodCmVdr = new ComplexMatrix(new Complex[][] {
                new Complex[] { 40-(120*j), -18+(54*j) },
                new Complex[] { 50-(150*j), -22+(66*j) }
                });

            Assert.That(_cc2X2.MultiplyRightDiagonal(_v2), NumericIs.AlmostEqualTo(prodCmVdr), "prod cv dr 1");
            ComplexMatrix prodCmVdrInplace = _cc2X2.Clone();
            prodCmVdrInplace.MultiplyRightDiagonalInplace(_v2);
            Assert.That(prodCmVdrInplace, NumericIs.AlmostEqualTo(prodCmVdr), "prod cv dr 2");
        }