public static Matrix<double> Scale(Matrix<double> input) { int n = input.RowCount; Matrix<double> p = DenseMatrix.Build.DenseIdentity(n) - DenseMatrix.Create(n,n, (_, __) => 1.0 / n); Matrix<double> a = -.5 * input.PointwiseMultiply(input); Matrix<double> b = p.Multiply(p.Multiply(a)); b = (b + b.Transpose()).Divide(2.0); var evd = b.Evd(); Vector<double> E = DenseVector.OfEnumerable(evd.EigenValues.Select(x => x.Real)); Matrix<double> V = evd.EigenVectors; DenseVector i = DenseVector.Create(E.Count, x => x); Sorting.Sort(E, i); var e = DenseVector.OfEnumerable(E.Reverse()); i = DenseVector.OfEnumerable(i.Reverse()); Vector keep = DenseVector.Create(e.Count(x => x > 0.000000001), _ => 0); int counter = 0; for (int j = 0; j < e.Count; j++) { if (e[j] > 0.000000001) { keep[j] = counter; counter++; } } Matrix<double> Y; if (e.Count(x => x > 0.000000001) == 0) { Y = DenseMatrix.Create(n, n, (_, __) => 0); } else { Y = DenseMatrix.Create(V.RowCount, keep.Count, (_, __) => 0); for (int j = 0; j < keep.Count; j++) { Y.SetColumn(j, (V.Column((int)(i[(int)(keep[j] + 0.5)] + 0.5)).ToArray())); } Y = Y.Multiply(DiagonalMatrix.OfDiagonal(keep.Count, keep.Count, e.Where((x, j) => keep.Contains(j)).Select(Math.Sqrt))); } //Enforce a sign convention on the solution -- the largest element //in each coordinate will have a positive sign. List<int> maxIndices = Y.EnumerateColumns().Select(x => x.AbsoluteMaximumIndex()).ToList(); var colSigns = maxIndices.Select((x, j) => Math.Sign(Y[x, j])).ToList(); for (int j = 0; j < Y.ColumnCount; j++) { Y.SetColumn(j, Y.Column(j) * colSigns[j]); } return Y; }
public void Test(Matrix<double> targetPattern, double activationCriterion, double inactivationCriterion, out List<double> meanSEList, out List<double> meanSSList, out List<double> meanCEList, out List<bool> correctnessList, out List<double> meanActivationList, out List<double> meanAUActivationList, out List<double> meanIUActivationList) { meanSEList = ((targetPattern - LayerActivationMatrix).PointwisePower(2).RowSums() / 2.0 / UnitCount).ToList(); meanSSList = ((((LayerActivationMatrix.PointwiseMultiply(LayerActivationMatrix.PointwiseLog()) + ((1 - LayerActivationMatrix).PointwiseMultiply((1 - LayerActivationMatrix).PointwiseLog()))) / Math.Log(2)) + 1).RowSums() / UnitCount).ToList(); meanCEList = (((targetPattern.PointwiseMultiply(LayerActivationMatrix.PointwiseLog()) + (1 - targetPattern).PointwiseMultiply((1 - LayerActivationMatrix).PointwiseLog())) / Math.Log(Math.E)).RowSums() * -1 / UnitCount).ToList(); meanActivationList = (LayerActivationMatrix.RowSums() / UnitCount).ToList(); correctnessList = new List<bool>(LayerActivationMatrix.RowCount); meanAUActivationList = new List<double>(LayerActivationMatrix.RowCount); meanIUActivationList = new List<double>(LayerActivationMatrix.RowCount); for (int index = 0; index < LayerActivationMatrix.RowCount; index++) { correctnessList.Add(true); meanAUActivationList.Add(0); meanIUActivationList.Add(0); } Matrix<double> activeUnitMatrix = DenseMatrix.Create(LayerActivationMatrix.RowCount, LayerActivationMatrix.ColumnCount, 0); Matrix<double> inactiveUnitMatrix = DenseMatrix.Create(LayerActivationMatrix.RowCount, LayerActivationMatrix.ColumnCount, 0); Matrix<double> countActive = DenseMatrix.Create(LayerActivationMatrix.RowCount, 1, 0); Matrix<double> countInactive = DenseMatrix.Create(LayerActivationMatrix.RowCount, 1, 0); for (int rowIndex = 0;rowIndex<LayerActivationMatrix.RowCount;rowIndex++) { for (int columnIndex = 0; columnIndex < LayerActivationMatrix.ColumnCount; columnIndex++) { if (targetPattern[rowIndex, columnIndex] > activationCriterion) { if(LayerActivationMatrix[rowIndex, columnIndex] < activationCriterion) correctnessList[rowIndex] = false; activeUnitMatrix[rowIndex, columnIndex] = 1; countActive[rowIndex, 0]++; } if (targetPattern[rowIndex, columnIndex] < inactivationCriterion) { if (LayerActivationMatrix[rowIndex, columnIndex] > activationCriterion) correctnessList[rowIndex] = false; inactiveUnitMatrix[rowIndex, columnIndex] = 1; countInactive[rowIndex, 0]++; } } } meanAUActivationList = LayerActivationMatrix.PointwiseMultiply(activeUnitMatrix).RowSums().ToList(); meanIUActivationList = LayerActivationMatrix.PointwiseMultiply(inactiveUnitMatrix).RowSums().ToList(); for (int rowIndex = 0; rowIndex < LayerActivationMatrix.RowCount; rowIndex++) { if (countActive[rowIndex, 0] > 0) meanAUActivationList[rowIndex] = meanAUActivationList[rowIndex] / countActive[rowIndex,0]; else { meanAUActivationList[rowIndex] = double.NaN; } if (countInactive[rowIndex, 0] > 0) meanIUActivationList[rowIndex] = meanIUActivationList[rowIndex] / countInactive[rowIndex,0]; else { meanIUActivationList[rowIndex] = double.NaN; } } }