Ejemplo n.º 1
0
        /// <summary>
        /// Multiplies a sparse matrix by a row vector.
        /// </summary>
        /// <param name="A">The matrix.</param>
        /// <param name="v">The row vector.</param>
        /// <returns>The product row vector.</returns>
        public static RowVector operator *(RowVector v, SparseSquareMatrix A)
        {
            if (v == null)
            {
                throw new ArgumentNullException("v");
            }
            if (A == null)
            {
                throw new ArgumentNullException("A");
            }
            if (v.Dimension != A.Dimension)
            {
                throw new DimensionMismatchException();
            }

            RowVector vA = new RowVector(A.Dimension);

            for (int i = 0; i < A.Dimension; i++)
            {
                SparseMatrixElement element = A.columns[i];
                while (element != null)
                {
                    vA[i]  += element.Value * v[element.Row];
                    element = element.NextInColumn;
                }
            }
            return(vA);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Multiplies any real, rectangular matrix by a row vector.
        /// </summary>
        /// <param name="v">The row vector.</param>
        /// <param name="A">The matrix.</param>
        /// <returns>The product row vector.</returns>
        public static RowVector operator *(RowVector v, AnyRectangularMatrix A)
        {
            if (v == null)
            {
                throw new ArgumentNullException(nameof(v));
            }
            if (A == null)
            {
                throw new ArgumentNullException(nameof(A));
            }
            if (v.Dimension != A.RowCount)
            {
                throw new DimensionMismatchException();
            }
            RowVector vA = new RowVector(A.ColumnCount);

            for (int r = 0; r < A.RowCount; r++)
            {
                for (int c = 0; c < A.ColumnCount; c++)
                {
                    vA[c] += v[r] * A[r, c];
                }
            }

            return(vA);
        }
        public void SparseSquareMatrixAgreement()
        {
            int d = 6;
            SparseSquareMatrix A = new SparseSquareMatrix(d);
            SquareMatrix B = new SquareMatrix(d);

            Random rng = new Random(1);
            for (int i = 0; i < 2 * d; i++) {
                int r = (int) Math.Floor(rng.NextDouble() * d);
                int c = (int) Math.Floor(rng.NextDouble() * d);
                A[r, c] = 2.0 * rng.NextDouble() - 1.0;
                B[r, c] = A[r, c];
            }

            RowVector u = new RowVector(d);
            ColumnVector v = new ColumnVector(d);
            for (int i = 0; i < d; i++) {
                u[i] = 2.0 * rng.NextDouble() - 1.0;
                v[i] = 2.0 * rng.NextDouble() - 1.0;
            }

            RowVector uA = u * A;
            RowVector uB = u * B;
            Assert.IsTrue(TestUtilities.IsNearlyEqual(uA, uB));

            ColumnVector Av = A * v;
            ColumnVector Bv = B * v;
            Assert.IsTrue(TestUtilities.IsNearlyEqual(Av, Bv));
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Returns a clone of the row vector.
        /// </summary>
        /// <returns>An independent row vector with the same components as the original.</returns>
        public RowVector Clone()
        {
            RowVector u = new RowVector(Dimension);

            for (int i = 0; i < Dimension; i++)
            {
                u[i] = this[i];
            }
            return(u);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Computes the product of a real number and a row vector.
        /// </summary>
        /// <param name="a">The real number.</param>
        /// <param name="v">The row vector.</param>
        /// <returns>The product of <paramref name="a"/> and <paramref name="v"/>.</returns>
        public static RowVector operator *(double a, RowVector v)
        {
            int       d = v.Dimension;
            RowVector u = new RowVector(d);

            for (int i = 0; i < d; i++)
            {
                u[i] = a * v[i];
            }
            return(u);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Returns a vector representing a given row of the matrix.
        /// </summary>
        /// <param name="r">The (zero-based) row number to return.</param>
        /// <returns>An independent copy of the specified row.</returns>
        /// <remarks>The returned vector is not linked to the matrix. If an entry in the matrix is updated after this method
        /// is called, the returned object will continue to represent a row of the original, not the updated, matrix. Similiarly,
        /// updates to the elements of the returned vector will not update the original matrix.</remarks>
        public override RowVector Row(int r)
        {
            if ((r < 0) || (r >= dimension))
            {
                throw new ArgumentOutOfRangeException("r");
            }
            RowVector row = new RowVector(dimension);

            for (int c = 0; c < dimension; c++)
            {
                row[c] = this[r, c];
            }
            return(row);
        }
        /// <summary>
        /// Gets a copy of the specified row.
        /// </summary>
        /// <param name="r">The (zero-based) row index.</param>
        /// <returns>An independent copy of the specified row.</returns>
        public virtual RowVector Row(int r)
        {
            if ((r < 0) || (r >= RowCount))
            {
                throw new ArgumentOutOfRangeException(nameof(r));
            }
            RowVector v = new RowVector(ColumnCount);

            for (int c = 0; c < ColumnCount; c++)
            {
                v[c] = this[r, c];
            }
            return(v);
        }
Ejemplo n.º 8
0
        public Network(int windowSize, int imagesNumber, double learningCoefficient, double maxError, int maxIterations)
        {
            this.windowSize = windowSize;
            this.imagesNumber = imagesNumber;
            this.learningCoefficient = learningCoefficient;
            this.maxError = maxError;
            this.maxIterations = maxIterations;

            weightMatrix1 = new RectangularMatrix(imagesNumber, windowSize + imagesNumber);
            CreateRandomMatrix(weightMatrix1);
            weightMatrix2 = new RowVector(imagesNumber);
            CreateRandomRowVector(weightMatrix2);
            contextNeurons = new ColumnVector(imagesNumber);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Computes the difference of two row vectors.
        /// </summary>
        /// <param name="v1">The first row vector.</param>
        /// <param name="v2">The second row vector.</param>
        /// <returns>The difference of <paramref name="v1"/> and <paramref name="v2"/>.</returns>
        public static RowVector operator -(RowVector v1, RowVector v2)
        {
            if (v1.Dimension != v2.Dimension)
            {
                throw new DimensionMismatchException();
            }
            int       d = v1.Dimension;
            RowVector u = new RowVector(d);

            for (int i = 0; i < d; i++)
            {
                u[i] = v1[i] - v2[i];
            }
            return(u);
        }
Ejemplo n.º 10
0
        // multliplication by a matrix

        /// <summary>
        /// Computes the product of a row vector and a matrix.
        /// </summary>
        /// <param name="v">The row vector.</param>
        /// <param name="M">The matrix.</param>
        /// <returns>The product vM.</returns>
        public static RowVector operator *(RowVector v, IMatrix M)
        {
            if (v.Dimension != M.RowCount)
            {
                throw new DimensionMismatchException();
            }
            RowVector u = new RowVector(M.ColumnCount);

            for (int i = 0; i < u.Dimension; i++)
            {
                u[i] = 0.0;
                for (int j = 0; j < v.Dimension; j++)
                {
                    u[i] += v[j] * M[j, i];
                }
            }
            return(u);
        }
Ejemplo n.º 11
0
 private void CreateRandomRowVector(RowVector weightMatrix)
 {
     Random rand = new Random();
     for (int j = 0; j < weightMatrix.ColumnCount; j++)
     {
         weightMatrix[j] = rand.NextDouble() * 0.1;
     }
 }
Ejemplo n.º 12
0
        /// <summary>
        /// Multiplies any real, rectangular matrix by a row vector.
        /// </summary>
        /// <param name="v">The row vector.</param>
        /// <param name="A">The matrix.</param>
        /// <returns>The product row vector.</returns>
        public static RowVector operator *(RowVector v, AnyRectangularMatrix A)
        {
            if (v == null) throw new ArgumentNullException("v");
            if (A == null) throw new ArgumentNullException("A");
            if (v.Dimension != A.RowCount) throw new DimensionMismatchException();
            RowVector vA = new RowVector(A.ColumnCount);

            for (int r = 0; r < A.RowCount; r++) {
                for (int c = 0; c < A.ColumnCount; c++) {
                    vA[c] += v[r] * A[r, c];
                }
            }

            return (vA);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Solves Ax = b using iterative methods.
        /// </summary>
        /// <param name="rhs">The right-hand side vector b.</param>
        /// <returns>The solution vector x.</returns>
        /// <remarks>
        /// <para>In general, neither the inverse nor any decomposition of a sparse matrix is itself sparse. Therefore,
        /// to solve large, sparse linear systems, iterative methods are employed. An iterative method begins with
        /// an approximate or guessed solution vector and progresses toward an improved solution. Iterative methods
        /// are often successful at converging to a sufficiently accurate solution vector, but this is not guaranteed.
        /// If this method fails to converge, it throws a <see cref="NonconvergenceException"/>.</para>
        /// </remarks>
        /// <exception cref="ArgumentNullException"><paramref name="rhs"/> is null.</exception>
        /// <exception cref="DimensionMismatchException"><paramref name="rhs"/>'s dimension does not equal the matrix's dimension.</exception>
        /// <exception cref="NonconvergenceException">The method did not converge to a solution.</exception>
        public ColumnVector Solve(ColumnVector rhs)
        {
            if (rhs == null)
            {
                throw new ArgumentNullException("rhs");
            }
            if (rhs.Dimension != dimension)
            {
                throw new DimensionMismatchException();
            }

            // accuracy and iteration limits are very huristic, revisit later
            double accuracyGoal = Global.Accuracy * 128.0;
            int    iterationMax = 256 + dimension / 2;

            // we use the stabilized biconjugate gradient algorithm

            // choose an initial guess
            ColumnVector x = new ColumnVector(dimension);

            for (int i = 0; i < x.Dimension; i++)
            {
                x[i] = 1.0;
            }

            //
            RowVector rt = x.Transpose();

            // r is the deviation vector that we are trying to drive to zero
            ColumnVector r = rhs - this * x;

            double rho0  = 1.0;
            double a     = 1.0;
            double omega = 1.0;

            ColumnVector v = new ColumnVector(dimension);
            ColumnVector p = new ColumnVector(dimension);

            for (int i = 1; i < iterationMax; i++)
            {
                double rho1 = rt * r;
                double beta = (rho1 / rho0) * (a / omega);
                p = r + beta * (p - omega * v);
                v = this * p;
                a = rho1 / (rt * v);
                ColumnVector s = r - a * v;
                ColumnVector t = this * s;

                omega = (t.Transpose() * s) / (t.Transpose() * t);

                x = x + a * p + omega * s;

                r = s - omega * t;

                if (r.FrobeniusNorm() <= accuracyGoal * rhs.FrobeniusNorm())
                {
                    return(x);
                }

                // prepare for next iteration
                rho0 = rho1;
            }

            throw new NonconvergenceException();
        }
        public void PrincipalComponentAnalysis()
        {
            int D = 3;
            int N = 10;

            // construct a sample
            Random rng = new Random(1);
            MultivariateSample sample = new MultivariateSample(D);
            for (int i = 0; i < N; i++) {
                double x = 1.0 * rng.NextDouble() - 1.0;
                double y = 4.0 * rng.NextDouble() - 2.0;
                double z = 9.0 * rng.NextDouble() - 3.0;
                sample.Add(x, y, z);
            }

            // get its column means
            RowVector mu = new RowVector(D);
            for (int i = 0; i < D; i++) {
                mu[i] = sample.Column(i).Mean;
            }

            // get total variance
            double tVariance = GetTotalVariance(sample);
            Console.WriteLine(tVariance);

            // do a principal component analysis
            PrincipalComponentAnalysis pca = sample.PrincipalComponentAnalysis();
            Assert.IsTrue(pca.Dimension == sample.Dimension);
            Assert.IsTrue(pca.Count == sample.Count);

            // check that the PCs behave as expected
            for (int i = 0; i < pca.Dimension; i++) {
                PrincipalComponent pc = pca.Component(i);
                Assert.IsTrue(pc.Index == i);
                Assert.IsTrue(TestUtilities.IsNearlyEqual(pc.Weight * pc.NormalizedVector(), pc.ScaledVector()));
                Assert.IsTrue((0.0 <= pc.VarianceFraction) && (pc.VarianceFraction <= 1.0));
                if (i == 0) {
                    Assert.IsTrue(pc.VarianceFraction == pc.CumulativeVarianceFraction);
                } else {
                    PrincipalComponent ppc = pca.Component(i - 1);
                    Assert.IsTrue(pc.VarianceFraction <= ppc.VarianceFraction);
                    Assert.IsTrue(TestUtilities.IsNearlyEqual(ppc.CumulativeVarianceFraction + pc.VarianceFraction, pc.CumulativeVarianceFraction));
                }
            }

            // express the sample in terms of principal components
            MultivariateSample csample = pca.TransformedSample();

            // check that the explained variances are as claimed
            for (int rD = 1; rD <= D; rD++) {
                MultivariateSample rSample = new MultivariateSample(D);
                foreach (double[] cEntry in csample) {
                    RowVector x = mu.Copy();
                    for (int i = 0; i < rD; i++) {
                        PrincipalComponent pc = pca.Component(i);
                        x += (cEntry[i] * pc.Weight) * pc.NormalizedVector();
                    }
                    rSample.Add(x);
                }
                double rVariance = GetTotalVariance(rSample);
                Console.WriteLine("{0} {1}", rD, rVariance);
                Assert.IsTrue(TestUtilities.IsNearlyEqual(rVariance / tVariance, pca.Component(rD-1).CumulativeVarianceFraction));
            }
        }
Ejemplo n.º 15
0
        private void TeachNeuralNetwork(ImageRectangle[] rectangles, BackgroundWorker worker, DoWorkEventArgs doWorkEvent, bool test)
        {
            int N = n * m * 3;

            RectangularMatrix weightMatrix = new RectangularMatrix(N, p);

            Random rand = new Random();
            for (int i = 0; i < N; i++)
            {
                for (int j = 0; j < p; j++)
                {
                    weightMatrix[i, j] = rand.NextDouble() * 0.1;
                }
            }

            RectangularMatrix secondWeightMatrix = weightMatrix.Transpose();

            double totalError = e + 1;
            int totalIterationNumber = 0;

            state = new CurrentState();

            RowVector[] vectors = new RowVector[rectangles.Length];

            for (int i = 0; i < rectangles.Length; i++)
            {
                vectors[i] = new RowVector(((ImageRectangle)rectangles.GetValue(i)).GetVector());
            }

            while (totalError > e && totalIterationNumber < iterationNumber)
            {
                totalError = 0;

                for (int i = 0; i < rectangles.Length; i++)
                {
                    RowVector xVector = vectors[i];

                    RowVector yVector = xVector * weightMatrix;
                    RowVector xSecondVector = yVector * secondWeightMatrix;
                    RowVector deltaXVector = xSecondVector - xVector;

                    weightMatrix = weightMatrix - a * xVector.Transpose() * deltaXVector * secondWeightMatrix.Transpose();
                    secondWeightMatrix = secondWeightMatrix - a * yVector.Transpose() * deltaXVector;
                }

                for (int i = 0; i < rectangles.Length; i++)
                {

                    RowVector xVector = vectors[i];

                    RowVector yVector = xVector * weightMatrix;
                    RowVector xSecondVector = yVector * secondWeightMatrix;
                    RowVector deltaXVector = xSecondVector - xVector;

                    for (int j = 0; j < deltaXVector.ColumnCount; j++)
                    {
                        totalError += deltaXVector[0, j] * deltaXVector[0, j];
                    }
                }

                totalIterationNumber++;

                state.CurentError = totalError;
                state.IterationNumber = totalIterationNumber;

                if (!test)
                {
                    worker.ReportProgress(0, state);

                    if (worker.CancellationPending)
                    {
                        doWorkEvent.Cancel = true;
                        break;
                    }
                }
            }

            for (int i = 0; i < rectangles.Length; i++)
            {
                RowVector xVector = vectors[i];

                RowVector yVector = xVector * weightMatrix;
                RowVector xSecondVector = yVector * secondWeightMatrix;

                ((ImageRectangle)rectangles.GetValue(i)).SetPixelMatrixFromVector(xSecondVector.ToArray());
            }

            state.Compressing = CalculateCompressing(rectangles.Length, N);
            state.FirstWeightMatrix = GetMatrixString(weightMatrix);
            state.SecondWeightMatrix = GetMatrixString(secondWeightMatrix);
        }
        public void RectangularMatrixAccess()
        {
            // create a matrix via outer product
            ColumnVector cv = new ColumnVector(new double[] { 1, 2 });
            RowVector rv = new RowVector(new double[] { 3, 4, 5 });
            RectangularMatrix M = cv * rv;

            // check dimensions
            Assert.IsTrue(M.RowCount == cv.Dimension);
            Assert.IsTrue(M.ColumnCount == rv.Dimension);

            // check values
            for (int r = 0; r < M.RowCount; r++) {
                for (int c = 0; c < M.ColumnCount; c++) {
                    Assert.IsTrue(M[r, c] == cv[r] * rv[c]);
                }
            }

            // extract a column
            ColumnVector mc = M.Column(1);
            Assert.IsTrue(mc.Dimension == M.RowCount);
            for (int i = 0; i < mc.Dimension; i++) {
                Assert.IsTrue(mc[i] == M[i, 1]);
            }

            // extract a row
            RowVector mr = M.Row(1);
            Assert.IsTrue(mr.Dimension == M.ColumnCount);
            for (int i = 0; i < mr.Dimension; i++) {
                Assert.IsTrue(mr[i] == M[1, i]);
            }

            // test clone
            RectangularMatrix MC = M.Copy();
            Assert.IsTrue(MC.RowCount == M.RowCount);
            Assert.IsTrue(MC.ColumnCount == M.ColumnCount);

            // test equality of clone
            Assert.IsTrue(MC == M);
            Assert.IsFalse(MC != M);

            // test independence of clone
            MC[0, 0] += 1.0;
            Assert.IsFalse(MC == M);
            Assert.IsTrue(MC != M);
        }
Ejemplo n.º 17
0
        private Image RecognizeImage(Image image)
        {
            int[] vector = image.ToVector();
            RowVector X = new RowVector(vector.Length);

            for (int i = 0; i < X.ColumnCount; i++)
            {
                X[i] = vector[i];
            }

            ColumnVector sMatrix = W * X.Transpose();

            int[] Y = new int[sMatrix.RowCount];
            for (int i = 0; i < Y.Length; i++) {
                Y[i] = sMatrix[i] > 0 ? 1 : -1;
            }

            return Image.GetImage(Y, image.Width, image.Height);
        }
Ejemplo n.º 18
0
        public void Learn(BackgroundWorker backgroundWorker, DoWorkEventArgs e, double[] sequence, bool? showIteration)
        {
            ColumnVector[] learningMatrix = createLearningMatrix(sequence);
            double[] etalons = createEtalons(sequence);

            backgroundResult = new BackgroundResult();
            backgroundResult.IsComplete = false;

            double totalError;
            int iterations = 0;

            do
            {
                // learn
                for (int i = 0; i < learningMatrix.Length; i++)
                {

                    ColumnVector X = ConcatVertically(learningMatrix[i], contextNeurons);

                    ColumnVector Xn = Normalize(X);
                    double norm = X.FrobeniusNorm();

                    ColumnVector Y1 = weightMatrix1 * Xn;
                    double Y2 = weightMatrix2 * Y1;

                    double gamma2 = (Y2 * norm) - etalons[i];
                    RowVector gamma1 = gamma2 * weightMatrix2;

                    RowVector a = learningCoefficient * gamma1;
                    RectangularMatrix b = Xn * a;

                    weightMatrix1 = weightMatrix1 - b.Transpose();
                    weightMatrix2 = weightMatrix2 - ((gamma2 * learningCoefficient) * Y1).Transpose();

                    contextNeurons = Y1;
                }

                totalError = 0;

                // calculate total error
                for (int i = 0; i < learningMatrix.Length; i++)
                {

                    ColumnVector X = ConcatVertically(learningMatrix[i], contextNeurons);

                    ColumnVector Xn = Normalize(X);
                    double norm = X.FrobeniusNorm();

                    ColumnVector Y1 = weightMatrix1 * Xn;
                    double Y2 = weightMatrix2 * Y1;

                    double gamma2 = Y2 * norm - etalons[i];

                    totalError += Math.Pow(gamma2, 2);
                }

                backgroundResult.IterationNumber = iterations;
                backgroundResult.Error = totalError;
                backgroundResult.IsComplete = false;

                if (showIteration.Equals(true))
                {
                    backgroundWorker.ReportProgress(0, backgroundResult);

                    Thread.Sleep(200);

                    if (backgroundWorker.CancellationPending)
                    {
                        e.Cancel = true;
                        break;
                    }
                }

                iterations++;
            }
            while (totalError >= maxError && iterations <= maxIterations);

            backgroundResult.IterationNumber = iterations;
            backgroundResult.Error = totalError;
            backgroundResult.IsComplete = true;

            backgroundWorker.ReportProgress(0, backgroundResult);
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Multiplies a sparse matrix by a row vector.
        /// </summary>
        /// <param name="A">The matrix.</param>
        /// <param name="v">The row vector.</param>
        /// <returns>The product row vector.</returns>
        public static RowVector operator *(RowVector v, SparseSquareMatrix A)
        {
            if (v == null) throw new ArgumentNullException("v");
            if (A == null) throw new ArgumentNullException("A");
            if (v.Dimension != A.Dimension) throw new DimensionMismatchException();

            RowVector vA = new RowVector(A.Dimension);
            for (int i = 0; i < A.Dimension; i++) {
                SparseMatrixElement element = A.columns[i];
                while (element != null) {
                    vA[i] += element.Value * v[element.Row];
                    element = element.NextInColumn;
                }
            }
            return (vA);
        }