Esempio n. 1
0
        /// <summary>
        /// Constructs  the image from selection.
        /// </summary>
        /// <param name="theSelection">The selection.</param>
        /// <returns>imageConditionAndData.</returns>
        public imageConditionAndData SelectedImageData(PictureBoxSelection theSelection = null)
        {
            if ((theSelection == null) && (selection != null))
            {
                theSelection = selection;
            }
            if (theSelection == null)
            {
                return(this);
            }

            Rectangle   theSelectionRectangle = (Rectangle)theSelection.SelectionRectReal;
            DenseMatrix subMatrix             = (DenseMatrix)dmSourceData.SubMatrix(
                theSelectionRectangle.Location.Y,
                theSelectionRectangle.Height,
                theSelectionRectangle.Location.X,
                theSelectionRectangle.Width);
            Image <Gray, Byte> img = ImageProcessing.grayscaleImageFromDenseMatrix(subMatrix);

            DenseMatrix maskMatrix = ImageProcessing.DenseMatrixFromImage(maskImageBinary);

            maskMatrix = (DenseMatrix)maskMatrix.SubMatrix(
                theSelectionRectangle.Location.Y,
                theSelectionRectangle.Height,
                theSelectionRectangle.Location.X,
                theSelectionRectangle.Width);
            //Image<Gray, Byte> maskSubImageBinary = maskImageBinary.GetSubRect(theSelectionRectangle);
            Image <Gray, Byte> maskSubImageBinary = ImageProcessing.grayscaleImageFromDenseMatrixWithFixedValuesBounds(maskMatrix, 0.0d, 1.0d);//  maskImageBinary.GetSubRect(theSelectionRectangle);

            maskSubImageBinary = maskSubImageBinary / 255;

            //Image<Gray, double> tmpHighlightingImage = img.CopyBlank();
            //tmpHighlightingImage.Draw((Rectangle)theSelection.SelectionRectReal, new Gray(255), -1);
            //img = img.AddWeighted(tmpHighlightingImage, 1.0, 0.15, 0.0);
            //img.Draw((Rectangle)theSelection.SelectionRectReal, new Gray(255), 1);
            //ImageProcessing imgPr = new ImageProcessing(img.Bitmap, false);
            //imgPr.significantMaskImageBinary = maskSubImageBinary;
            //imgPr.significantMaskImage = maskSubImageBinary*255;
            imageConditionAndData retImageData = new imageConditionAndData(subMatrix, maskSubImageBinary);

            retImageData.currentColorScheme                     = currentColorScheme;
            retImageData.currentColorSchemeRuler                = new ColorSchemeRuler(currentColorSchemeRuler);
            retImageData.currentColorSchemeRuler.imgToRule      = retImageData;
            retImageData.currentColorSchemeRuler.IsMarginsFixed = false;
            //retImageData.UpdateColorSchemeRuler();
            return(retImageData);
        }
Esempio n. 2
0
        /// <summary>
        /// Run example
        /// </summary>
        public void Run()
        {
            // Format vector output to console
            var formatProvider = (CultureInfo)CultureInfo.InvariantCulture.Clone();
            formatProvider.TextInfo.ListSeparator = " ";

            // Create new empty square matrix
            var matrix = new DenseMatrix(10);
            Console.WriteLine(@"Empty matrix");
            Console.WriteLine(matrix.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 1. Fill matrix by data using indexer []
            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(@"1. Fill matrix by data using indexer []");
            Console.WriteLine(matrix.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 2. Fill matrix by data using At. The element is set without range checking.
            for (var i = 0; i < matrix.RowCount; i++)
            {
                for (var j = 0; j < matrix.ColumnCount; j++)
                {
                    matrix.At(i, j, k--);
                }
            }

            Console.WriteLine(@"2. Fill matrix by data using At");
            Console.WriteLine(matrix.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 3. Clone matrix
            var clone = matrix.Clone();
            Console.WriteLine(@"3. Clone matrix");
            Console.WriteLine(clone.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 4. Clear matrix
            clone.Clear();
            Console.WriteLine(@"4. Clear matrix");
            Console.WriteLine(clone.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 5. Copy matrix into another matrix
            matrix.CopyTo(clone);
            Console.WriteLine(@"5. Copy matrix into another matrix");
            Console.WriteLine(clone.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 6. Get submatrix into another matrix
            var submatrix = matrix.SubMatrix(2, 2, 3, 3);
            Console.WriteLine(@"6. Copy submatrix into another matrix");
            Console.WriteLine(submatrix.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 7. Get part of the row as vector. In this example: get 4 elements from row 5 starting from column 3
            var row = matrix.Row(5, 3, 4);
            Console.WriteLine(@"7. Get part of the row as vector");
            Console.WriteLine(row.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 8. Get part of the column as vector. In this example: get 3 elements from column 2 starting from row 6
            var column = matrix.Column(2, 6, 3);
            Console.WriteLine(@"8. Get part of the column as vector");
            Console.WriteLine(column.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 9. Get columns using column enumerator. If you need all columns you may use ColumnEnumerator without parameters
            Console.WriteLine(@"9. Get columns using column enumerator");
            foreach (var keyValuePair in matrix.ColumnEnumerator(2, 4))
            {
                Console.WriteLine(@"Column {0}: {1}", keyValuePair.Item1, keyValuePair.Item2.ToString("#0.00\t", formatProvider));
            }

            Console.WriteLine();

            // 10. Get rows using row enumerator. If you need all rows you may use RowEnumerator without parameters
            Console.WriteLine(@"10. Get rows using row enumerator");
            foreach (var keyValuePair in matrix.RowEnumerator(4, 3))
            {
                Console.WriteLine(@"Row {0}: {1}", keyValuePair.Item1, keyValuePair.Item2.ToString("#0.00\t", formatProvider));
            }

            Console.WriteLine();

            // 11. Convert matrix into multidimensional array
            var data = matrix.ToArray();
            Console.WriteLine(@"11. Convert matrix into multidimensional array");
            for (var i = 0; i < data.GetLongLength(0); i++)
            {
                for (var j = 0; j < data.GetLongLength(1); j++)
                {
                    Console.Write(data[i, j].ToString("#0.00\t"));
                }

                Console.WriteLine();
            }

            Console.WriteLine();

            // 12. Convert matrix into row-wise array
            var rowwise = matrix.ToRowWiseArray();
            Console.WriteLine(@"12. Convert matrix into row-wise array");
            for (var i = 0; i < matrix.RowCount; i++)
            {
                for (var j = 0; j < matrix.ColumnCount; j++)
                {
                    Console.Write(rowwise[(i * matrix.ColumnCount) + j].ToString("#0.00\t"));
                }

                Console.WriteLine();
            }

            Console.WriteLine();

            // 13. Convert matrix into column-wise array
            var columnise = matrix.ToColumnWiseArray();
            Console.WriteLine(@"13. Convert matrix into column-wise array");
            for (var i = 0; i < matrix.RowCount; i++)
            {
                for (var j = 0; j < matrix.ColumnCount; j++)
                {
                    Console.Write(columnise[(j * matrix.RowCount) + i].ToString("#0.00\t"));
                }

                Console.WriteLine();
            }

            Console.WriteLine();

            // 14. Get matrix diagonal as vector
            var diagonal = matrix.Diagonal();
            Console.WriteLine(@"14. Get matrix diagonal as vector");
            Console.WriteLine(diagonal.ToString("#0.00\t", formatProvider));
            Console.WriteLine();
        }
        /// <summary>
        /// Generate a random n-class classification problem.
        /// </summary>
        /// <param name="nSamples">The number of samples.</param>
        /// <param name="nFeatures">The total number of features. These comprise <paramref name="nInformative"/>
        /// informative features, <paramref name="nRedundant"/> redundant features, <paramref name="nRepeated"/>
        /// dupplicated features and `<paramref name="nFeatures"/>-<paramref name="nInformative"/>-<paramref name="nRedundant"/>-
        /// <paramref name="nRepeated"/>` useless features drawn at random.</param>
        /// <param name="nInformative">The number of informative features. Each class is composed of a number
        /// of gaussian clusters each located around the vertices of a hypercube
        /// in a subspace of dimension <paramref name="nInformative"/>. For each cluster,
        /// informative features are drawn independently from  N(0, 1) and then
        /// randomly linearly combined in order to add covariance. The clusters
        /// are then placed on the vertices of the hypercube.</param>
        /// <param name="nRedundant">The number of redundant features. These features are generated as
        /// random linear combinations of the informative features.</param>
        /// <param name="nRepeated"> The number of dupplicated features, drawn randomly from the informative
        /// and the redundant features.
        /// </param>
        /// <param name="nClasses">The number of classes (or labels) of the classification problem.</param>
        /// <param name="nClustersPerClass">The number of clusters per class.</param>
        /// <param name="weights">The proportions of samples assigned to each class. If None, then
        /// classes are balanced. Note that if `len(weights) == n_classes - 1`,
        /// then the last class weight is automatically inferred.
        /// </param>
        /// <param name="flipY">The fraction of samples whose class are randomly exchanged.</param>
        /// <param name="classSep">The factor multiplying the hypercube dimension.</param>
        /// <param name="hypercube">If True, the clusters are put on the vertices of a hypercube. If
        /// False, the clusters are put on the vertices of a random polytope.</param>
        /// <param name="shift">Shift all features by the specified value. If None, then features
        /// are shifted by a random value drawn in [-class_sep, class_sep].</param>
        /// <param name="scale">Multiply all features by the specified value. If None, then features
        /// are scaled by a random value drawn in [1, 100]. Note that scaling
        /// happens after shifting.
        /// </param>
        /// <param name="shuffle">Shuffle the samples and the features.</param>
        /// <param name="randomState">Random generator.</param>
        /// <returns>array of shape [n_samples]
        /// The integer labels for class membership of each sample.</returns>
        /// <remarks>
        /// The algorithm is adapted from Guyon [1] and was designed to generate
        /// the "Madelon" dataset.
        /// References
        /// ----------
        /// .. [1] I. Guyon, "Design of experiments for the NIPS 2003 variable
        ///   selection benchmark", 2003.
        /// </remarks>
        public static Classification MakeClassification(
            int nSamples = 100,
            int nFeatures = 20,
            int nInformative = 2,
            int nRedundant = 2,
            int nRepeated = 0,
            int nClasses = 2,
            int nClustersPerClass = 2,
            List<double> weights = null,
            double flipY = 0.01,
            double classSep = 1.0,
            bool hypercube = true,
            double? shift = 0.0,
            double? scale = 1.0,
            bool shuffle = true,
            Random randomState = null)
        {
            var generator = randomState ?? new Random();

            // Count features, clusters and samples
            if (nInformative + nRedundant + nRepeated > nFeatures)
            {
                throw new ArgumentException("Number of informative, redundant and repeated " +
                                            "features must sum to less than the number of total" +
                                            " features");
            }

            if (nInformative * nInformative < nClasses * nClustersPerClass)
            {
                throw new ArgumentException(
                    "n_classes * n_clusters_per_class must" +
                    "be smaller or equal 2 ** n_informative");
            }

            if (weights != null && !new[] { nClasses, nClasses - 1 }.Contains(weights.Count))
            {
                throw new ArgumentException("Weights specified but incompatible with number of classes.");
            }

            int nUseless = nFeatures - nInformative - nRedundant - nRepeated;
            int nClusters = nClasses * nClustersPerClass;

            if (weights != null && weights.Count == nClasses - 1)
            {
                weights.Add(1.0 - weights.Sum());
            }

            if (weights == null) 
            {
                weights = Enumerable.Repeat(1.0 / nClasses, nClasses).ToList();
                weights[weights.Count - 1] = 1.0 - weights.Take(weights.Count - 1).Sum();
            }

            var nSamplesPerCluster = new List<int>();

            for (int k = 0; k < nClusters; k++)
            {
                nSamplesPerCluster.Add(
                    (int)(nSamples * weights[k % nClasses] / nClustersPerClass));
            }

            for (int i = 0; i < nSamples - nSamplesPerCluster.Sum(); i++)
            {
                nSamplesPerCluster[i % nClusters] += 1;
            }

            // Intialize X and y
            Matrix x = new DenseMatrix(nSamples, nFeatures);
            int[] y = new int[nSamples];

            // Build the polytope
            Matrix c = new DenseMatrix(1 << nInformative, nInformative);
            for (int i = 0; i < 1 << nInformative; i++)
            {
                var row = new DenseVector(nInformative);
                for (int bitN = 0; bitN < nInformative; bitN++)
                {
                    row[bitN] = (i & (1 << bitN)) == 1 ? classSep : -classSep;
                }

                c.SetRow(i, row);
            }

            if (!hypercube)
            {
                for (int k = 0; k < nClusters; k++)
                {
                    c.SetRow(k, c.Row(k) * generator.NextDouble());
                }

                for (int f = 0; f < nInformative; f++)
                {
                    c.SetColumn(f, c.Column(f) * generator.NextDouble());
                }
            }

            // todo:
            // generator.shuffle(C)

            // Loop over all clusters
            int pos = 0;
            int posEnd = 0;

            for (int k = 0; k < nClusters; k++)
            {
                // Number of samples in cluster k
                int nSamplesK = nSamplesPerCluster[k];

                // Define the range of samples
                pos = posEnd;
                posEnd = pos + nSamplesK;

                // Assign labels
                for (int l = pos; l < posEnd; l++)
                {
                    y[l] = k % nClasses;
                }

                // Draw features at random
                var subMatrix = DenseMatrix.CreateRandom(
                    nSamplesK,
                    nInformative,
                    new Normal { RandomSource = generator });

                x.SetSubMatrix(pos, nSamplesK, 0, nInformative, subMatrix);

                // Multiply by a random matrix to create co-variance of the features
                var uniform = new ContinuousUniform(-1, 1) { RandomSource = generator };
                Matrix a = DenseMatrix.CreateRandom(nInformative, nInformative, uniform);

                x.SetSubMatrix(
                    pos,
                    nSamplesK,
                    0,
                    nInformative,
                    x.SubMatrix(pos, nSamplesK, 0, nInformative) * a);

                // Shift the cluster to a vertice
                var v = x.SubMatrix(pos, nSamplesK, 0, nInformative).AddRowVector(c.Row(k));
                x.SetSubMatrix(pos, nSamplesK, 0, nInformative, v);
            }

            // Create redundant features
            if (nRedundant > 0)
            {
                var uniform = new ContinuousUniform(-1, 1) { RandomSource = generator };
                Matrix b = DenseMatrix.CreateRandom(nInformative, nRedundant, uniform);
                x.SetSubMatrix(
                    0,
                    x.RowCount,
                    nInformative,
                    nRedundant,
                    x.SubMatrix(0, x.RowCount, 0, nInformative) * b);
            }

            // Repeat some features
            if (nRepeated > 0)
            {
                int n = nInformative + nRedundant;
                for (int i = 0; i < nRepeated; i++)
                {
                    int r = (int)((generator.Next(nRepeated) * (n - 1)) + 0.5);
                    x.SetColumn(i, x.Column(r));
                }
            }

            // Fill useless features
            var denseMatrix = DenseMatrix.CreateRandom(nSamples, nUseless, new Normal { RandomSource = generator });
            x.SetSubMatrix(0, nSamples, nFeatures - nUseless, nUseless, denseMatrix);

            // Randomly flip labels
            if (flipY >= 0.0)
            {
                for (int i = 0; i < nSamples; i++)
                {
                    if (generator.NextDouble() < flipY)
                    {
                        y[i] = generator.Next(nClasses);
                    }
                }
            }

            // Randomly shift and scale
            bool constantShift = shift != null;
            bool constantScale = scale != null;

            for (int f = 0; f < nFeatures; f++)
            {
                if (!constantShift)
                {
                    shift = ((2 * generator.NextDouble()) - 1) * classSep;
                }

                if (!constantScale)
                {
                    scale = 1 + (100 * generator.NextDouble());
                }

                x.SetColumn(f, (x.Column(f) + shift.Value) * scale.Value);
            }

            // Randomly permute samples and features
            // todo:
            /*
            if (shuffle)
            {
                X, y = util_shuffle(X, y, random_state=generator)

                indices = np.arange(n_features)
                generator.shuffle(indices)
                X[:, :] = X[:, indices]
            }*/

            return new Classification { X = x, Y = y };
        }
Esempio n. 4
0
        public DenseMatrix createMatrix(Model model)
        {
            int numConstraints = model.Constraints.Count;
            int numDecisionVars = model.Goal.Coefficients.Length;
            int varCounter = numDecisionVars;
            //  matrix(rows, columns)
            DenseMatrix coefficients = new DenseMatrix(numConstraints, numDecisionVars);
            DenseMatrix artificialVars = new DenseMatrix(numConstraints, 1);
            var constraintCounter = 0;
            this.rhsValues = new DenseVector(numConstraints);
            this.basics = new List<int>();
            this.artificialRows = new List<int>();
            foreach (var constraint in model.Constraints) {
                rhsValues[constraintCounter] = constraint.Value;

                // if the constraint RHS is negative, invert the coefficients and flip the inequality sign
                if (constraint.Value < 0)
                {
                    for (int i = 0; i< model.Goal.Coefficients.Length; i++) {
                        model.Goal.Coefficients[i] = model.Goal.Coefficients[i] * -1;
                    }
                    if (constraint.Relationship == Relationship.LessThanOrEquals)
                    {
                        constraint.Relationship = Relationship.GreaterThanOrEquals;
                    }
                    else if (constraint.Relationship == Relationship.GreaterThanOrEquals)
                    {
                        constraint.Relationship = Relationship.LessThanOrEquals;
                    }
                    // also flip the rhs value which we already put in the array for the simplex setup
                    rhsValues[constraintCounter] = rhsValues[constraintCounter] * -1;
                }

                coefficients.SetRow(constraintCounter, 0, constraint.Coefficients.Length, new DenseVector(constraint.Coefficients));
                // if it's a less than, add a slack column to the coefs matrix
                if (constraint.Relationship == Relationship.LessThanOrEquals)
                {
                    DenseVector slack = DenseVector.Create(model.Constraints.Count, delegate(int s) { return 0; });
                    slack.At(constraintCounter, 1);
                    coefficients = (DenseMatrix)coefficients.Append(slack.ToColumnMatrix());

                    this.basics.Add(varCounter);
                }
                else
                {
                    // Need to add an artificial variable for >= and = constraints

                    DenseVector surplus = DenseVector.Create(model.Constraints.Count, delegate(int s) { return 0; });
                    surplus.At(constraintCounter, -1);
                    coefficients = (DenseMatrix)coefficients.Append(surplus.ToColumnMatrix());

                    DenseVector artificial = DenseVector.Create(model.Constraints.Count, delegate(int s) { return 0; });
                    artificial.At(constraintCounter, 1);
                    artificialVars = (DenseMatrix)artificialVars.Append(artificial.ToColumnMatrix());

                    // Keeps track of the rows with artificial variable, for setting w
                    artificialRows.Add(constraintCounter);
                }
                varCounter++;
                constraintCounter++;
            }

            // put the constraints and stuff into the matrix
            if (artificialVars.ColumnCount > 1)
            {
                artificialVars = (DenseMatrix)artificialVars.SubMatrix(0, artificialVars.RowCount, 1, artificialVars.ColumnCount - 1);

                for (int i = coefficients.ColumnCount; i < coefficients.ColumnCount + artificialVars.ColumnCount; i++)
                {
                    this.basics.Add(i);
                }

                coefficients = (DenseMatrix)coefficients.Append(artificialVars);

                numArtificial = artificialVars.ColumnCount;
            }
            else
            {
                numArtificial = 0;
            }

            return coefficients;
        }
Esempio n. 5
0
        private void optimize(DenseMatrix coefficients, DenseVector objFunValues, bool artifical)
        {
            //for calculations on the optimal solution row
            int cCounter,
                width = coefficients.ColumnCount;
            DenseVector cBVect = new DenseVector(basics.Count);

            //Sets up the b matrix
            DenseMatrix b = new DenseMatrix(basics.Count, 1);

            //basics will have values greater than coefficients.ColumnCount - 1 if there are still artificial variables
            //or if Nathan is bad and didn't get rid of them correctly
            foreach (int index in basics)
            {
                b = (DenseMatrix)b.Append(DenseVector.OfVector(coefficients.Column(index)).ToColumnMatrix());
            }
            // removes the first column
            b = (DenseMatrix)b.SubMatrix(0, b.RowCount, 1, b.ColumnCount - 1);

            double[] cPrimes = new double[width];
            double[] rhsOverPPrime;
            DenseMatrix[] pPrimes = new DenseMatrix[width];
            DenseMatrix bInverse;

            int newEntering, exitingRow;

            bool optimal = false;

            if(artifical)
            {
                rhsOverPPrime = new double[numConstraints + 1];
            }
            else
            {
                rhsOverPPrime = new double[numConstraints];
            }

            while (!optimal)
            {
                //calculates the inverse of b for this iteration
                bInverse = (DenseMatrix)b.Inverse();

                //updates the C vector with the most recent basic variables
                cCounter = 0;
                foreach (int index in basics)
                {
                    cBVect[cCounter++] = objFunValues.At(index);
                }

                //calculates the pPrimes and cPrimes
                for (int i = 0; i < coefficients.ColumnCount; i++)
                {
                    if (!basics.Contains(i))
                    {
                        pPrimes[i] = (DenseMatrix)bInverse.Multiply((DenseMatrix)coefficients.Column(i).ToColumnMatrix());

                        //c' = objFunVals - cB * P'n
                        //At(0) to turn it into a double
                        cPrimes[i] = objFunValues.At(i) - (pPrimes[i].LeftMultiply(cBVect)).At(0);
                    }
                    else
                    {
                        pPrimes[i] = null;
                    }
                }

                //RHS'
                xPrime = (DenseMatrix)bInverse.Multiply((DenseMatrix)rhsValues.ToColumnMatrix());

                //Starts newEntering as the first nonbasic
                newEntering = -1;
                int iter = 0;
                while(newEntering == -1)
                {
                    if(!basics.Contains(iter))
                    {
                        newEntering = iter;
                    }

                    iter++;
                }

                //new entering becomes the small cPrime that corresponds to a non-basic value
                for (int i = 0; i < cPrimes.Length; i++)
                {
                    if (cPrimes[i] < cPrimes[newEntering] && !basics.Contains(i))
                    {
                        newEntering = i;
                    }
                }

                //if the smallest cPrime is >= 0, ie they are all positive
                if (cPrimes[newEntering] >= 0)
                {
                    optimal = true;
                }
                else
                {
                    //fix me to deal with if all these values are negative
                    exitingRow = 0;
                    for (int i = 0; i < xPrime.RowCount; i++)
                    {
                        double[,] pPrime = pPrimes[newEntering].ToArray();
                        rhsOverPPrime[i] = xPrime.ToArray()[i, 0] / pPrime[i, 0];

                        if (rhsOverPPrime[i] < rhsOverPPrime[exitingRow] && rhsOverPPrime[i] > 0 )
                        {
                            exitingRow = i;
                        }
                    }

                    //translates from the index in the basics list to the actual row
                    exitingRow = basics[exitingRow];

                    //make sure you're not being stupid here!!!!
                    int tempIndex = basics.IndexOf(exitingRow);
                    basics.Remove(exitingRow);

                    basics.Insert(tempIndex, newEntering);

                    b.SetColumn(basics.IndexOf(newEntering), coefficients.Column(newEntering));
                }
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Adaptive Cross Approximation (ACA) matrix compression
        /// the result is stored in U and V matrices like U*V
        /// </summary>
        /// <param name="acaThres">Relative error threshold to stop adding rows and columns in ACA iteration</param>
        /// <param name="m">Row indices of Z submatrix to compress</param>
        /// <param name="n">Column indices of Z submatrix to compress</param>
        /// <param name="U">to store result</param>
        /// <param name="V">to store result</param>
        /// <returns>pair with matrix U and V</returns>
        public static Tuple<Matrix, Matrix> Aca(double acaThres, List<int> m, List<int> n, Matrix U, Matrix V)
        {
            int M = m.Count;
            int N = n.Count;
            int Min = Math.Min(M, N);
            U = new DenseMatrix(Min, Min);
            V = new DenseMatrix(Min, Min);
            //if Z is a vector, there is nothing to compress
            if (M == 1 || N == 1)
            {
                U = UserImpedance(m, n);
                V = new DenseMatrix(1, 1);
                V[0, 0] = 1.0;
                return new Tuple<Matrix,Matrix>(U,V);
            }

            //Indices of columns picked up from Z
            //Vector J = new DenseVector(N);
            //List<int> J = new List<int>(N);

            List<int> J = new List<int>(new int [N]);
            //int[] J = new int[N];
            //Indices of rows picked up from Z
            //Vector I = new DenseVector(M);
            List<int> I = new List<int>(new int [M]);
            //int[] I = new int[M];
            //Row indices to search for maximum in R
            //Vector i = new DenseVector(M);
            List<int> i = new List<int>();
            //int[] i = new int[M];
            //Column indices to search for maximum in R
            //Vector j = new DenseVector(N);
            List<int> j = new List<int>();
            //int[] j = new int[N];

            for (int k = 1; k < M; k++)
            {
                i.Add(k);
            }

            for (int k = 0; k < N; k++)
            {
                j.Add(k);
            }

            //Initialization

            //Initialize the 1st row index I(1) = 1
            I[0] = 0;

            //Initialize the 1st row of the approximate error matrix
            List<int> m0 = new List<int>();
            m0.Add(m[I[0]]);
            Matrix Rik = UserImpedance(m0, n);

            //Find the 1st column index J(0)
            double max = -1.0;
            int col = 0;

            foreach (int ind in j)
            {
                if (Math.Abs(Rik[0, ind]) > max)
                {
                    max = Math.Abs(Rik[0, ind]);
                    col = ind;
                }
            }

            //J[0] = j[col];
            J[0] = col;
            j.Remove(J[0]);

            //First row of V
            V = new DenseMatrix(1, Rik.ColumnCount);
            V.SetRow(0, Rik.Row(0).Divide(Rik[0, J[0]]));

            //Initialize the 1st column of the approximate error matrix
            List<int> n0 = new List<int>();
            n0.Add(n[J[0]]);
            Matrix Rjk = UserImpedance(m, n0);

            //First column of U
            U = new DenseMatrix(Rjk.RowCount, 1);
            U.SetColumn(0, Rjk.Column(0));

            // Norm of (approximate) Z, to test error
            double d1 = U.L2Norm();
            double d2 = V.L2Norm();
            double normZ = d1 * d1 * d2 * d2;

            //Find 2nd row index I(2)
            int row = 0;
            max = -1.0;

            foreach (int ind in i)
            {
                if (Math.Abs(Rjk[ind, 0]) > max)
                {
                    max = Math.Abs(Rjk[ind, 0]);
                    row = ind;
                }
            }

            //I[1] = i[row];
            I[1] = row;
            i.Remove(I[1]);

            //Iteration
            for (int k = 1; k < Math.Min(M, N); k++)
            {
                //Update (Ik)th row of the approximate error matrix:
                List<int> t1 = new List<int>();
                t1.Add(m[I[k]]);
                Rik = (Matrix)(UserImpedance(t1, n) - U.SubMatrix(I[k], 1, 0, U.ColumnCount).Multiply(V));
                //CHECKED OK all code before works fine
                //Find kth column index Jk
                max = -1.0;
                col = 0;

                foreach (int ind in j)
                {
                    if (Math.Abs(Rik[0, ind]) > max)
                    {
                        max = Math.Abs(Rik[0, ind]);
                        col = ind;
                    }
                }

                J[k] = col;
                j.Remove(J[k]);

                //Terminate if R(I(k),J(k)) == 0
                if (Rik[0, J[k]] == 0)
                {
                    break;
                }

                //Set k-th row of V equal to normalized error
                Matrix Vk = (Matrix)Rik.Divide(Rik[0, J[k]]);

                //Update (Jk)th column of the approximate error matrix
                List<int> n1 = new List<int>();
                n1.Add(n[J[k]]);
                Rjk = (Matrix)(UserImpedance(m, n1) - U.Multiply(V.SubMatrix(0, V.RowCount, J[k], 1)));

                // Set k-th column of U equal to updated error
                Matrix Uk = Rjk;

                //Norm of approximate Z
                //Matrix s = (Matrix)(U.Transpose().Multiply(Uk)).Multiply((Vk.Multiply(V.Transpose())).Transpose());
                //Matrix s = (Matrix)((U.Transpose()).Multiply(Uk)).Multiply(((Vk.Multiply(V.Transpose())).Transpose()));
                Matrix a = (Matrix)U.Transpose().Multiply(Uk);
                Matrix b = (Matrix)Vk.Multiply(V.Transpose()).Transpose();
                Matrix s = (Matrix)a.PointwiseMultiply(b);
                double sum = 0;

                for (int i1 = 0; i1 < s.RowCount; i1++)
                {
                    for (int j1 = 0; j1 < s.ColumnCount; j1++)
                    {
                        sum += s[i1, j1];
                    }
                }

                d1 = Uk.L2Norm();
                d2 = Vk.L2Norm();

                normZ += 2 * sum + d1 * d1 * d2 * d2;

                //Update U and V

                //U.SetColumn(U.ColumnCount - 1, Uk.Column(0));
                //V.SetRow(V.RowCount - 1, Vk.Row(0));
                U = AddColumn(U, (Vector)Uk.Column(0));
                //U.SetColumn(k, Uk.Column(0));
                V = AddRow(V, (Vector)Vk.Row(0));
                //V.SetRow(k, Vk.Row(0));

                if (d1 * d2 <= acaThres * Math.Sqrt(normZ))
                {
                    break;
                }

                if (k == Math.Min(N, M) - 1)
                {
                    break;
                }

                max = -1;
                row = 0;

                foreach (int ind in i)
                {
                    if (Math.Abs(Rjk[ind, 0]) > max)
                    {
                        max = Math.Abs(Rjk[ind, 0]);
                        row = ind;
                    }
                }

                I[k + 1] = row;
                //i = removeIndex(i,I[k+1]);
                i.Remove(I[k + 1]);
            }
            return new Tuple<Matrix, Matrix>(U, V);
        }
Esempio n. 7
0
        static Tuple<int, double, double> RunValidation(double[][] trainingData, double[][] validationData, double[][] outSampleData, int k)
        {
            int N = trainingData.Length;
              var ZZ = new DenseMatrix(N, 8);
              var Y = new DenseVector(N);
              for (int j = 0; j < N; j++)
              {
            double x1 = trainingData[j][0], x2 = trainingData[j][1];
            ZZ[j, 0] = 1;
            ZZ[j, 1] = x1;
            ZZ[j, 2] = x2;
            ZZ[j, 3] = x1 * x1;
            ZZ[j, 4] = x2 * x2;
            ZZ[j, 5] = x1 * x2;
            ZZ[j, 6] = Math.Abs(x1 - x2);
            ZZ[j, 7] = Math.Abs(x1 + x2);

            Y[j] = trainingData[j][2];
              }

              var Z = ZZ.SubMatrix(0, N, 0, k + 1);
              var WW = Z.TransposeThisAndMultiply(Z).Inverse().TransposeAndMultiply(Z).Multiply(Y);

              var W = new DenseVector(8);
              WW.CopySubVectorTo(W, 0, 0, k + 1);

              Func<double, double, double> h = (x1, x2) =>
            W[0] + W[1] * x1 + W[2] * x2 + W[3] * x1 * x1 + W[4] * x2 * x2 + W[5] * x1 * x2
            + W[6] * Math.Abs(x1 - x2) + W[7] * Math.Abs(x1 + x2) >= 0 ? 1.0 : -1.0;

              return Tuple.Create(
            k,
            (validationData.Count(v => Math.Sign(h(v[0], v[1])) != Math.Sign(v[2])) + 0.0) / validationData.Length,
            (outSampleData.Count(v => Math.Sign(h(v[0], v[1])) != Math.Sign(v[2])) + 0.0) / outSampleData.Length);
        }
Esempio n. 8
0
        public static ResultFEM Solve(Matrix<double> K, Matrix<double> f, int[] bc)
        {
            // Create dof array:
            int ndof = f.RowCount;

            // Initialize displacement vector
            Matrix u = new DenseMatrix(ndof, 1);

            int[] dof = new int[ndof];
            for (int i = 0; i < ndof; i++)
            {
                dof[i] = i;
            }
            // Create the free dofs:
            int[] fdof = dof.Except(bc).ToArray();

            int nfdof = fdof.Length; // Number of free dofs.
            int nbdof = ndof - nfdof; //Constrained dofs

            // Create the permutation array which puts the constrained dofs last:
            int[] permute = bc.Union(fdof).ToArray();

            Permutation perm = new Permutation(permute);
            Permutation invPerm = perm.Inverse();
            Matrix<double> KPermuted = DenseMatrix.OfMatrix(K);
            KPermuted.PermuteRows(invPerm);
            KPermuted.PermuteColumns(invPerm);

            // Split K:::
            Matrix<double> Kff = KPermuted.SubMatrix(nbdof, nfdof, nbdof, nfdof);
            System.Console.WriteLine(Kff);  //Down right corner of matrix
            Matrix<double> Kfp = KPermuted.SubMatrix(nbdof, nfdof, 0, nbdof); //Down left corner of matrix

            // Split F:::
            Matrix<double> fPermuted = DenseMatrix.OfMatrix(f);
            fPermuted.PermuteRows(invPerm);
            Matrix<double> ff = fPermuted.SubMatrix(nbdof, nfdof, 0, 1);

            Matrix<double> up = u.SubMatrix(0, nbdof, 0, 1); // Must set up to constrained values in bc.

            // Solve for the unknown displacements:::
            Matrix<double> s = Kff.Solve(ff.Subtract(Kfp.Multiply(up)));
            u.SetSubMatrix(nbdof, 0, s); // Set displacements back.

            System.Console.WriteLine(u);
            // Permute back u
            u.PermuteRows(perm);

            System.Console.WriteLine("U after permut");
            System.Console.WriteLine(K);
            System.Console.WriteLine(u);
            System.Console.WriteLine(f);

            // Get reaction forces:
            Matrix<double> Q = K.Multiply(u).Subtract(f);

            ResultFEM result = new ResultFEM(u, Q);

            return result;
        }