/// <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); }
/// <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 }; }
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; }
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)); } } }
/// <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); }
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); }
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; }