// In perspective mode, the warping functions are: // x' = (a0 + a1 x + a2 y) / (c0 x + c1 y + 1) // y' = (b0 + b1 x + b2 y) / (c0 x + c1 y + 1) // // The following calculates the factors a#, b# and c#. // We do this by creating a set of eight equations with a#, b# and c# as unknowns. // The equations are derived by: // 1. substituting the srcPoints for (x, y); // 2. substituting the corresponding destPoints for (x', y'); // 3. solving the resulting set of equations, with the factors as unknowns. // // The equations are like these: // a0 x a1 y a2 0 0 0 -xx'c0 -yx'c1 = x' // 0 0 0 b0 x b1 y b2 -xy'c0 -yy'c1 = y' // The known factors of left hand side ar put in the 8x8 matrix mxLeft for // all four point pairs, and the right hand side in the one column matrix mxRight. // After solving, m_mxWarpFactors contains a0, a1, a2, b0, b1, b2, c0, c1. private void PreCalc(PointD[] destPoints, PointD[] srcPoints) { var mxLeft = new GeneralMatrix(8, 8); //mxLeft.Null(); var mxRight = new GeneralMatrix(8, 1); var row = 0; for (int i = 0; i < 4; i++) { mxLeft.Array[row][0] = 1.0; mxLeft.Array[row][1] = srcPoints[i].X; mxLeft.Array[row][2] = srcPoints[i].Y; mxLeft.Array[row][6] = - srcPoints[i].X * destPoints[i].X; mxLeft.Array[row][7] = - srcPoints[i].Y * destPoints[i].X; mxRight.Array[row][0] = destPoints[i].X; row++; mxLeft.Array[row][3] = 1.0f; mxLeft.Array[row][4] = srcPoints[i].X; mxLeft.Array[row][5] = srcPoints[i].Y; mxLeft.Array[row][6] = - srcPoints[i].X * destPoints[i].Y; mxLeft.Array[row][7] = - srcPoints[i].Y * destPoints[i].Y; mxRight.Array[row][0] = destPoints[i].Y; row++; } _mxWarpFactors = mxLeft.Solve(mxRight); }
public void ArrayMultiplyEquals() { A = R.Copy(); GeneralMatrix B = GeneralMatrix.Random(A.RowDimension, A.ColumnDimension); A.ArrayMultiplyEquals(B); Assert.IsTrue(GeneralTests.Check(A.ArrayRightDivideEquals(B), R)); }
/** * Computes the Moore–Penrose pseudoinverse using the SVD method. * * Modified version of the original implementation by Kim van der Linde. */ public static GeneralMatrix pinv(GeneralMatrix x) { if (x.Rank() < 1) return null; if (x.ColumnDimension > x.RowDimension) return pinv(x.Transpose()).Transpose(); SingularValueDecomposition svdX = new SingularValueDecomposition(x); double[] singularValues = svdX.SingularValues; double tol = Math.Max(x.ColumnDimension, x.RowDimension) * singularValues[0] * 2E-16; double[] singularValueReciprocals = new double[singularValues.Count()]; for (int i = 0; i < singularValues.Count(); i++) singularValueReciprocals[i] = Math.Abs(singularValues[i]) < tol ? 0 : (1.0 / singularValues[i]); double[][] u = svdX.GetU().Array; double[][] v = svdX.GetV().Array; int min = Math.Min(x.ColumnDimension, u[0].Count()); double[][] inverse = new double[x.ColumnDimension][]; for (int i = 0; i < x.ColumnDimension; i++) { inverse[i] = new double[x.RowDimension]; for (int j = 0; j < u.Count(); j++) for (int k = 0; k < min; k++) inverse[i][j] += v[i][k] * singularValueReciprocals[k] * u[j][k]; } return new GeneralMatrix(inverse); }
public void FindMinimum() { int i; _xCurrent = FirstStep(); double [] xPrev = new double[_nDim]; for (i=0;i<_nDim;i++) xPrev[i] = _initial[i]; double [] xNext; GeneralMatrix hPrev = GeneralMatrix.Identity(_nDim,_nDim); double currEps=1e5; _curIter=0; while (currEps>_epsilon && _curIter<_itMax) { _hessian = CalculateNextHessianApproximation(hPrev,xPrev,_xCurrent,_f.GetGradient(xPrev),_f.GetGradient(_xCurrent)); xNext = CalculateNextPoint(_xCurrent,_f.GetGradient(_xCurrent),_hessian); for (i=0;i<_nDim; i++) { xPrev[i] = _xCurrent[i]; _xCurrent[i] = xNext[i]; } currEps = Diff(_xCurrent,xPrev); _curIter++; } }
public void InitData() { A = new GeneralMatrix(columnwise, validld); R = GeneralMatrix.Random(A.RowDimension, A.ColumnDimension); S = new GeneralMatrix(columnwise, nonconformld); O = new GeneralMatrix(A.RowDimension, A.ColumnDimension, 1.0); }
public GyroCal(AHRS sensor) { int i = 0; InitializeComponent(); this.sensor = sensor; // Add DataReceived event handler. sensor.DataReceivedEvent += new DataReceivedDelegate(DataReceivedEventHandler); sensor.confReceivedEvent += new confReceivedDelegate(confReceivedEventHandler); confReceivedEventHandler(i); data_collection_enabled = false; next_data_index = 0; loggedData = new double[SAMPLES, 3]; threshold = 1.5 * 3.14159 / 180; bias = new double[3]; calMat = new double[3, 3]; calMat[0, 0] = 1.0; calMat[1, 1] = 1.0; calMat[2, 2] = 1.0; D = new GeneralMatrix(SAMPLES, 10); for (i = 0; i < SAMPLES; i++) { loggedData[i,0] = 0; loggedData[i, 1] = 0; loggedData[i, 2] = 0; } }
protected override GeneralMatrix CalculateNextHessianApproximation(GeneralMatrix previousH, double[]prevX, double[]curX, double[]prevGrad, double[]curGrad) { GeneralMatrix currentH = new GeneralMatrix(_nDim,_nDim); GeneralMatrix cX = new GeneralMatrix(curX,_nDim); GeneralMatrix pX = new GeneralMatrix(prevX,_nDim); GeneralMatrix cG = new GeneralMatrix(curGrad,_nDim); GeneralMatrix pG = new GeneralMatrix(prevGrad,_nDim); GeneralMatrix dX = cX.Subtract(pX); GeneralMatrix dG = cG.Subtract(pG); double aK1 = 1/(dX.Transpose().Multiply(dG).GetElement(0,0)); GeneralMatrix aK2 = dX.Multiply(dX.Transpose()); GeneralMatrix aK = aK2.Multiply(aK1); double bK1 = -1/(dG.Transpose().Multiply(previousH).Multiply(dG).GetElement(0,0)); GeneralMatrix bK2 = previousH.Multiply(dG).Multiply(dG.Transpose()).Multiply(previousH.Transpose()); GeneralMatrix bK =bK2.Multiply(bK1); currentH = previousH.Add(aK).Add(bK); return currentH; }
public GeneralMatrix CalculateHessian(double[]x) { GeneralMatrix hessian = new GeneralMatrix(Dimension,Dimension); for (int i=0; i<Dimension; i++) for (int j=0; j<Dimension; j++) hessian.SetElement(i,j,GetPartialDerivativeVal(i,j,x)); return hessian; }
public void CholeskyDecomposition1() { double[][] pvals = {new double[]{1.0, 1.0, 1.0}, new double[]{1.0, 2.0, 3.0}, new double[]{1.0, 3.0, 6.0}}; GeneralMatrix A = new GeneralMatrix(pvals); CholeskyDecomposition chol = A.chol(); GeneralMatrix L = chol.GetL(); Assert.IsTrue(GeneralTests.Check(A, L.Multiply(L.Transpose()))); }
public void CholeskyDecomposition2() { double[][] pvals = {new double[]{1.0, 1.0, 1.0}, new double[]{1.0, 2.0, 3.0}, new double[]{1.0, 3.0, 6.0}}; GeneralMatrix A = new GeneralMatrix(pvals); CholeskyDecomposition chol = A.chol(); GeneralMatrix X = chol.Solve(GeneralMatrix.Identity(3, 3)); Assert.IsTrue(GeneralTests.Check(A.Multiply(X), GeneralMatrix.Identity(3, 3))); }
public void EigenValueDecomposition1() { double[][] pvals = {new double[]{1.0, 1.0, 1.0}, new double[]{1.0, 2.0, 3.0}, new double[]{1.0, 3.0, 6.0}}; GeneralMatrix A = new GeneralMatrix(pvals); EigenvalueDecomposition Eig = A.Eigen(); GeneralMatrix D = Eig.D; GeneralMatrix V = Eig.GetV(); Assert.IsTrue(GeneralTests.Check(A.Multiply(V), V.Multiply(D))); }
public void Negative_BadColumnIndexSetGoodRowIndexSet() { double[][] avals = {new double[]{1.0, 4.0, 7.0, 10.0}, new double[]{2.0, 5.0, 8.0, 11.0}, new double[]{3.0, 6.0, 9.0, 12.0}}; int[] rowindexset = new int[]{1, 2}; int[] badcolumnindexset = new int[]{1, 2, 4}; GeneralMatrix B = new GeneralMatrix(avals); M = B.GetMatrix(badrowindexset, columnindexset); }
public void Negative_BadColumnIndexSet2() { int ib = 1, ie = 2; /* index ranges for sub GeneralMatrix */ double[][] avals = {new double[]{1.0, 4.0, 7.0, 10.0}, new double[]{2.0, 5.0, 8.0, 11.0}, new double[]{3.0, 6.0, 9.0, 12.0}}; int[] badrowindexset = new int[]{1, 3}; GeneralMatrix B = new GeneralMatrix(avals); M = B.GetMatrix(ib, ie + B.RowDimension + 1, columnindexset); }
//display specified matrix static void displayMatrix(GeneralMatrix displayMat) { for (int i = 0; i < displayMat.RowDimension; i++) { for (int j = 0; j < displayMat.ColumnDimension; j++) { Console.Write(displayMat.GetElement(i, j) + ","); } Console.WriteLine(); } }
public OneDWrapper(IGradientFunction func, GeneralMatrix pX, GeneralMatrix aX) { if (pX==null || aX==null) throw new ArgumentException("Previous x and alfaX may not be null"); _problemDimension = pX.RowDimension; _function = func; _previousX = new GeneralMatrix(pX.ArrayCopy); _alfaX = new GeneralMatrix(aX.ArrayCopy); }
/// <summary> /// Constructor where caller determines the value of all fields (used internally by RoundEigenMetric()) /// </summary> protected Metric(DotNetMatrix.GeneralMatrix matrix, DotNetMatrix.EigenvalueDecomposition eig, double[] eigenMetric, DotNetMatrix.GeneralMatrix invEigMatrix, bool isDiagonal, bool isEuclidean, bool isAntiEuclidean) { m_eigenMetric = eigenMetric; m_matrix = matrix; m_eig = eig; m_eigenMetric = eigenMetric; m_invEigMatrix = invEigMatrix; m_isDiagonal = isDiagonal; m_isEuclidean = isEuclidean; m_isAntiEuclidean = isAntiEuclidean; }
public void Hessian() { double eps = 1e-5; double[] vector = {0,0,0}; double[][] result = {new double[]{10.0, 2.0, -2.0}, new double[]{ 2.0, 4.0, 2.0}, new double[]{-2.0, 2.0, 4.0}}; GeneralMatrix expectedMatrix = new GeneralMatrix(result); TestFunction f = new TestFunction(); GeneralMatrix hessian = f.CalculateHessian(vector); for (int i=0;i<3; i++) for (int j=0;j<3; j++) Assert.IsTrue(System.Math.Abs(hessian.GetElement(i,j)-expectedMatrix.GetElement(i,j))<eps); }
/// <summary>QR Decomposition, computed by Householder reflections.</summary> /// <param name="A"> Rectangular matrix /// </param> /// <returns> Structure to access R and the Householder vectors and compute Q. /// </returns> public QRDecomposition(GeneralMatrix A) { // Initialize. QR = A.ArrayCopy; m = A.RowDimension; n = A.ColumnDimension; Rdiag = new double[n]; // Main loop. for (int k = 0; k < n; k++) { // Compute 2-norm of k-th column without under/overflow. double nrm = 0; for (int i = k; i < m; i++) { nrm = Maths.Hypot(nrm, QR[i][k]); } if (nrm != 0.0) { // Form k-th Householder vector. if (QR[k][k] < 0) { nrm = - nrm; } for (int i = k; i < m; i++) { QR[i][k] /= nrm; } QR[k][k] += 1.0; // Apply transformation to remaining columns. for (int j = k + 1; j < n; j++) { double s = 0.0; for (int i = k; i < m; i++) { s += QR[i][k] * QR[i][j]; } s = (- s) / QR[k][k]; for (int i = k; i < m; i++) { QR[i][j] += s * QR[i][k]; } } } Rdiag[k] = - nrm; } }
public Optimizer(int dim, double[]initialPar, IGradientFunction f, double step, double epsilon, int itMax) { _f = f; _epsilon = epsilon; _itMax = itMax; _nDim = dim; _xCurrent = new double[_nDim]; _initial = new double[_nDim]; _step = step; //initiate the first value of alpha to some random value less than 100; Random rnd = new Random(); _alpha = rnd.NextDouble()*100; _hessian = new GeneralMatrix(_nDim,_nDim); for (int i=0; i<_nDim; i++) _initial[i] = initialPar[i]; }
/// <summary>Initializes this Metric object from metric matrix (called by constructor) </summary> /// <param name="m">The NxN metric matrix</param> private void init(DotNetMatrix.GeneralMatrix m) { if (!Util.IsSymmetric(m)) { throw new Exception("The metric matrix must be symmetric"); } m_matrix = m.Copy(); // System.Console.WriteLine("m_matrix: " + Util.ToString(m_matrix)); // compute eigen value decomposition m_eig = new DotNetMatrix.EigenvalueDecomposition(m_matrix); // System.Console.WriteLine("m_eig: " + Util.ToString(m_eig.GetV())); m_invEigMatrix = m_eig.GetV().Transpose(); m_eigenMetric = m_eig.RealEigenvalues; // { // DotNetMatrix.GeneralMatrix D = Util.Diagonal(m_eigenMetric); // DotNetMatrix.GeneralMatrix tmp = m_eig.GetV().Multiply(D).Multiply(m_invEigMatrix); // System.Console.WriteLine("input_matrix = " + Util.ToString(tmp)); // } m_isDiagonal = Util.IsDiagonal(m_matrix); if (!m_isDiagonal) { m_isEuclidean = m_isAntiEuclidean = false; } else { m_isEuclidean = m_isAntiEuclidean = true; for (int i = 0; i < m.RowDimension; i++) { if (m_matrix.GetElement(i, i) != 1.0) { m_isEuclidean = false; } if (m_matrix.GetElement(i, i) != -1.0) { m_isAntiEuclidean = false; } } } }
// In bilinear mode, the warping functions are: // x' = a0 + a1 x y + a2 x + a3 y // y' = b0 + b1 x y + b2 x + b3 y // // Here, we have two sets of four equations. In the first set, the a# factors // are the unknowns, in the second set the b# factors. // The equations are of the form: // a0 + xy a1 + x a2 + y a3 = x' // The left hand side is identical for both sets. The right hand side differs. // Therefore, we can solve them in one operation. // The left hand side factors are put in the 4x4 matrix mxLeft, the right side // factors are put in the 4x2 matrix mxRight. // After solving, the first column of m_mxWarpFactors contains a0, a1, a2, a3; the // second columne contains b0, b1, b2, b3. private void PreCalc(PointD[] destPoints, PointD[] srcPoints) { var mxLeft = new GeneralMatrix(4, 4); var mxRight = new GeneralMatrix(4, 2); for (int row = 0; row < 4; row++) { mxLeft.Array[row][0] = 1.0; mxLeft.Array[row][1] = srcPoints[row].X * srcPoints[row].Y; mxLeft.Array[row][2] = srcPoints[row].X; mxLeft.Array[row][3] = srcPoints[row].Y; mxRight.Array[row][0] = destPoints[row].X; mxRight.Array[row][1] = destPoints[row].Y; } _mxWarpFactors = mxLeft.Solve(mxRight); }
public double[][] decompose(int svCount, double[][] m) { GeneralMatrix mMat = new GeneralMatrix(m); GeneralMatrix resultM = decompose(svCount, mMat); double[][] resultD = new double[resultM.RowDimension][]; for (int i = 0; i < resultM.RowDimension; i++) { resultD[i] = new double[resultM.ColumnDimension]; for (int j = 0; j < resultM.ColumnDimension; j++) { resultD[j][i] = resultM.GetElement(i, j); if ((j + 1) % 4 == 0) // To remove messed up byte { resultD[j][i] = 0; } } } return resultD; }
//decrypt line of input static void Decrypt(string input, GeneralMatrix key, GeneralMatrix invKey, Dictionary<char, int> hillDict, StringBuilder decText) { string pt = ""; string[] line = input.Trim().Split(' '); GeneralMatrix inverse = key.Inverse(); for (int i = 0; i < line.Length; i += 3) { //3 at a time double[] temp = new double[3]; temp[0] = Convert.ToInt32(line[i]); temp[1] = Convert.ToInt32(line[i + 1]); temp[2] = Convert.ToInt32(line[i + 2]); //new 3x1 matrix GeneralMatrix ctMat = new GeneralMatrix(new double[] { temp[0], temp[1], temp[2] }, 3); //multiply by inverse GeneralMatrix ptMat = inverse.Multiply(ctMat); //mod 31 the result for (int x = 0; x < ptMat.RowDimension; x++) { for (int y = 0; y < ptMat.ColumnDimension; y++) { var tempElement = Convert.ToInt32(ptMat.GetElement(x, y)) % 31; while (tempElement < 0) tempElement = tempElement + 31; ptMat.SetElement(x, y, tempElement); } } for (int x = 0; x < ptMat.RowDimension; x++) { for (int y = 0; y < ptMat.ColumnDimension; y++) { pt += hillDict.FirstOrDefault(z => z.Value == ptMat.GetElement(x, y)).Key; } } } //replace padding with space characters decText.Replace("?", " "); decText.AppendLine(pt); }
/// <summary> /// Transforms a basis blade to another basis which is represented by the columns of M. /// </summary> /// <param name="a">The basis blade to transform according to <paramref name="M"/>.</param> /// <param name="M">The matrix to use to transform <paramref name="a"/>.</param> /// <returns>a list of BasisBlade whose sum represents <paramref name="a"/> on the new basis.</returns> public static ArrayList Transform(BasisBlade a, DotNetMatrix.GeneralMatrix M) { ArrayList A = new ArrayList(); A.Add(new BasisBlade(0, a.scale, a.symScale)); // start with just the scalar part; int dim = M.RowDimension; // for each 1 bit: convert to list of blades int i = 0; uint b = a.bitmap; while (b != 0) { if ((b & 1) != 0) { // take column 'i' out of the matrix, wedge it to 'A' ArrayList tmp = new ArrayList(); for (int j = 0; j < dim; j++) { double m = M.GetElement(j, i); if (m != 0.0) { for (int k = 0; k < A.Count; k++) { BasisBlade o = BasisBlade.op((BasisBlade)A[k], new BasisBlade((uint)(1 << j), m)); if (o.scale != 0.0) { tmp.Add(o); } } } } A = tmp; } b >>= 1; i++; } return(A); }
/// <summary> ///Ctor. In the LMA fit N is the number of data points, M is the number of fit parameters. ///Call <code>fit()</code> to start the actual fitting. /// </summary> /// <param name="function">The model function to be fitted. Must be able to take M input parameters.</param> /// <param name="parameters">The initial guess for the fit parameters, length M.</param> /// <param name="dataPoints">The data points in an array, <code>double[0 = x, 1 = y][point index]</code>. Size must be <code>double[2][N]</code>.</param> /// <param name="weights">The weights, normally given as: <code>weights[i] = 1 / sigma_i^2</code>. /// If you have a bad data point, set its weight to zero. If the given array is null, /// a new array is created with all elements set to 1.</param> /// <param name="alpha">A Matrix instance. Must be initiated to (M x M) size. /// In this case we are using the GeneralMatrix type from the open source JAMA library</param> /// <param name="argDeltaChi2">delta chi square</param> /// <param name="argMaxIter">maximum number of iterations</param> public LMA( LMAFunction function, double[] parameters, double[][] dataPoints, double[] weights, GeneralMatrix alpha, double argDeltaChi2, int argMaxIter) { if (dataPoints[0].Length != dataPoints[1].Length) throw new ArgumentException("Data must have the same number of x and y points."); if (dataPoints.Length != 2) throw new ArgumentException("Data point array must be 2 x N"); this.function = function; this.parameters = parameters; this.dataPoints = dataPoints; this.weights = CheckWeights(dataPoints[0].Length, weights); this.incrementedParameters = new double[parameters.Length]; this.alpha = alpha; this.beta = new double[parameters.Length]; this.da = new double[parameters.Length]; minDeltaChi2 = argDeltaChi2; maxIterations = argMaxIter; lambda = Constants.lambda; }
/// <summary> /// Calculates priorities using the Saaty method /// </summary> /// <param name="argMatrix"> matrix of choices</param> /// <returns></returns> public void ComputePriorities(GeneralMatrix argMatrix) { double lMax=0.0; int n = argMatrix.ColumnDimension; int m = argMatrix.RowDimension; if (n!= m) throw new ArgumentException("Matrix must be symmetrical"); _matrix = new GeneralMatrix(n,1); PCalc(argMatrix,_matrix); GeneralMatrix product = FCalc(argMatrix,_matrix); for (int i=0;i<n; i++) lMax+=product.GetElement(i,0)/n; _lambdaMax = lMax; _consistency = (_lambdaMax-n)/(n-1); _consistencyRatio = _consistency/Constants.randomIndices[n]; }
/// <summary>Cholesky algorithm for symmetric and positive definite matrix.</summary> /// <param name="Arg"> Square, symmetric matrix. /// </param> /// <returns> Structure to access L and isspd flag. /// </returns> public CholeskyDecomposition(GeneralMatrix Arg) { // Initialize. double[][] A = Arg.Array; n = Arg.RowDimension; L = new double[n][]; for (int i = 0; i < n; i++) { L[i] = new double[n]; } isspd = (Arg.ColumnDimension == n); // Main loop. for (int j = 0; j < n; j++) { double[] Lrowj = L[j]; double d = 0.0; for (int k = 0; k < j; k++) { double[] Lrowk = L[k]; double s = 0.0; for (int i = 0; i < k; i++) { s += Lrowk[i] * Lrowj[i]; } Lrowj[k] = s = (A[j][k] - s) / L[k][k]; d = d + s * s; isspd = isspd & (A[k][j] == A[j][k]); } d = A[j][j] - d; isspd = isspd & (d > 0.0); L[j][j] = System.Math.Sqrt(System.Math.Max(d, 0.0)); for (int k = j + 1; k < n; k++) { L[j][k] = 0.0; } } }
public double[] decompose(int svCount, double[] m) { GeneralMatrix mMat = new GeneralMatrix(m, (int)Math.Sqrt(m.Length)); GeneralMatrix[] resultM = decompose(svCount, mMat); double[] resultD = new double[resultM[0].RowDimension * resultM[0].ColumnDimension + resultM[1].RowDimension * resultM[1].ColumnDimension]; for (int i = 0; i < resultM[0].RowDimension; i++) { for (int j = 0; j < resultM[0].ColumnDimension; j++) { resultD[i * resultM[0].ColumnDimension + j] = resultM[0].GetElement(i, j); } } for (int i = 0; i < resultM[1].RowDimension; i++) { for (int j = 0; j < resultM[1].ColumnDimension; j++) { resultD[resultM[0].RowDimension * resultM[0].ColumnDimension + i * resultM[1].ColumnDimension + j] = resultM[1].GetElement(i, j); } } return resultD; }
//encrypt line of input static void Encrypt(string input, GeneralMatrix key, Dictionary<char, int> hillDict, StringBuilder encText) { string ct = ""; string[] pt = input.Trim().Split(' '); for (int i = 0; i < pt.Length; i += 3) { //encrypt 3 letters at a time double[] temp = new double[3]; temp[0] = Convert.ToInt32(pt[i]); temp[1] = Convert.ToInt32(pt[i + 1]); temp[2] = Convert.ToInt32(pt[i + 2]); //create plain text matrix, transpose and encrypt it GeneralMatrix ptMat = new GeneralMatrix(new double[] { temp[0], temp[1], temp[2] }, 3); GeneralMatrix trnasPTMat = ptMat.Transpose(); GeneralMatrix ctMat = key.Multiply(ptMat); for (int x = 0; x < ctMat.RowDimension; x++) { for (int y = 0; y < ctMat.ColumnDimension; y++) { var tempElement = Convert.ToInt32(ctMat.GetElement(x, y)) % 31; ctMat.SetElement(x, y, tempElement); } } for (int x = 0; x < ctMat.RowDimension; x++) { for (int y = 0; y < ctMat.ColumnDimension; y++) { ct += hillDict.FirstOrDefault(z => z.Value == ctMat.GetElement(x, y)).Key; } } } //append to string builder encText.AppendLine(ct); }
protected override GeneralMatrix CalculateNextHessianApproximation(GeneralMatrix pH, double[]prevX, double[]curX, double[]prevGrad, double[]curGrad) { GeneralMatrix cH = new GeneralMatrix(_nDim,_nDim); GeneralMatrix cX = new GeneralMatrix(curX,_nDim); GeneralMatrix pX = new GeneralMatrix(prevX,_nDim); GeneralMatrix cG = new GeneralMatrix(curGrad,_nDim); GeneralMatrix pG = new GeneralMatrix(prevGrad,_nDim); GeneralMatrix sigma = cX.Subtract(pX); GeneralMatrix gamma = cG.Subtract(pG); double sigmaTGamma = sigma.Transpose().Multiply(gamma).GetElement(0,0); GeneralMatrix hGammaSigmaT = pH.Multiply(gamma.Multiply(sigma.Transpose())); GeneralMatrix sigmaGammaTH = sigma.Multiply(gamma.Transpose().Multiply(pH)); double gammaTHGamma = (gamma.Transpose().Multiply(pH.Multiply(gamma))).GetElement(0,0); GeneralMatrix sigmaSigmaT = sigma.Multiply(sigma.Transpose()); GeneralMatrix term1 = (hGammaSigmaT.Add(sigmaGammaTH)).Multiply(1/sigmaTGamma); GeneralMatrix term2 = (sigmaSigmaT.Multiply(1/sigmaTGamma)).Multiply(1+gammaTHGamma/sigmaTGamma); return pH.Subtract(term1).Add(term2); }
/// <summary>Solve A*X = B</summary> /// <param name="B"> right hand side /// </param> /// <returns> solution if A is square, least squares solution otherwise /// </returns> public virtual GeneralMatrix Solve(GeneralMatrix B) { return(m == n ? (new LUDecomposition(this)).Solve(B):(new QRDecomposition(this)).Solve(B)); }
public void DEF() { double[][] rankdef = {new double[]{1.0, 4.0, 7.0, 10.0}, new double[]{2.0, 5.0, 8.0, 11.0}, new double[]{3.0, 6.0, 9.0, 12.0}}; GeneralMatrix def = new GeneralMatrix(rankdef); Assert.IsTrue(GeneralTests.Check(def.Rank(), System.Math.Min(def.RowDimension, def.ColumnDimension) - 1)); }
/// <summary>Check for symmetry, then construct the eigenvalue decomposition</summary> /// <param name="Arg"> Square matrix /// </param> /// <returns> Structure to access D and V. /// </returns> public EigenvalueDecomposition(GeneralMatrix Arg) { double[][] A = Arg.Array; n = Arg.ColumnDimension; V = new double[n][]; for (int i = 0; i < n; i++) { V[i] = new double[n]; } d = new double[n]; e = new double[n]; issymmetric = true; for (int j = 0; (j < n) & issymmetric; j++) { for (int i = 0; (i < n) & issymmetric; i++) { issymmetric = (A[i][j] == A[j][i]); } } if (issymmetric) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { V[i][j] = A[i][j]; } } // Tridiagonalize. tred2(); // Diagonalize. tql2(); } else { H = new double[n][]; for (int i2 = 0; i2 < n; i2++) { H[i2] = new double[n]; } ort = new double[n]; for (int j = 0; j < n; j++) { for (int i = 0; i < n; i++) { H[i][j] = A[i][j]; } } // Reduce to Hessenberg form. orthes(); // Reduce Hessenberg to real Schur form. hqr2(); } }
public void SolveLinear() { double[][] subavals = {new double[]{5.0, 8.0, 11.0}, new double[]{6.0, 9.0, 12.0}}; double[][] sqSolution = {new double[]{13.0}, new double[]{15.0}}; GeneralMatrix sub = new GeneralMatrix(subavals); GeneralMatrix o = new GeneralMatrix(sub.RowDimension, 1, 1.0); GeneralMatrix sol = new GeneralMatrix(sqSolution); GeneralMatrix sq = sub.GetMatrix(0, sub.RowDimension - 1, 0, sub.RowDimension - 1); Assert.IsTrue(GeneralTests.Check(sq.Solve(sol), o)); }
public void SingularValues() { double[][] condmat = {new double[]{1.0, 3.0}, new double[]{7.0, 9.0}}; GeneralMatrix B = new GeneralMatrix(condmat); SingularValueDecomposition SVD = B.SVD(); double[] singularvalues = SVD.SingularValues; Assert.IsTrue(GeneralTests.Check(B.Condition(), singularvalues[0] / singularvalues[System.Math.Min(B.RowDimension, B.ColumnDimension) - 1])); }
/// <summary>Construct the singular value decomposition</summary> /// <param name="Arg"> Rectangular matrix /// </param> /// <returns> Structure to access U, S and V. /// </returns> public SingularValueDecomposition(GeneralMatrix Arg) { // Derived from LINPACK code. // Initialize. double[][] A = Arg.ArrayCopy; m = Arg.RowDimension; n = Arg.ColumnDimension; int nu = System.Math.Min(m, n); s = new double[System.Math.Min(m + 1, n)]; U = new double[m][]; for (int i = 0; i < m; i++) { U[i] = new double[nu]; } V = new double[n][]; for (int i2 = 0; i2 < n; i2++) { V[i2] = new double[n]; } double[] e = new double[n]; double[] work = new double[m]; bool wantu = true; bool wantv = true; // Reduce A to bidiagonal form, storing the diagonal elements // in s and the super-diagonal elements in e. int nct = System.Math.Min(m - 1, n); int nrt = System.Math.Max(0, System.Math.Min(n - 2, m)); for (int k = 0; k < System.Math.Max(nct, nrt); k++) { if (k < nct) { // Compute the transformation for the k-th column and // place the k-th diagonal in s[k]. // Compute 2-norm of k-th column without under/overflow. s[k] = 0; for (int i = k; i < m; i++) { s[k] = Maths.Hypot(s[k], A[i][k]); } if (s[k] != 0.0) { if (A[k][k] < 0.0) { s[k] = -s[k]; } for (int i = k; i < m; i++) { A[i][k] /= s[k]; } A[k][k] += 1.0; } s[k] = -s[k]; } for (int j = k + 1; j < n; j++) { if ((k < nct) & (s[k] != 0.0)) { // Apply the transformation. double t = 0; for (int i = k; i < m; i++) { t += A[i][k] * A[i][j]; } t = (-t) / A[k][k]; for (int i = k; i < m; i++) { A[i][j] += t * A[i][k]; } } // Place the k-th row of A into e for the // subsequent calculation of the row transformation. e[j] = A[k][j]; } if (wantu & (k < nct)) { // Place the transformation in U for subsequent back // multiplication. for (int i = k; i < m; i++) { U[i][k] = A[i][k]; } } if (k < nrt) { // Compute the k-th row transformation and place the // k-th super-diagonal in e[k]. // Compute 2-norm without under/overflow. e[k] = 0; for (int i = k + 1; i < n; i++) { e[k] = Maths.Hypot(e[k], e[i]); } if (e[k] != 0.0) { if (e[k + 1] < 0.0) { e[k] = -e[k]; } for (int i = k + 1; i < n; i++) { e[i] /= e[k]; } e[k + 1] += 1.0; } e[k] = -e[k]; if ((k + 1 < m) & (e[k] != 0.0)) { // Apply the transformation. for (int i = k + 1; i < m; i++) { work[i] = 0.0; } for (int j = k + 1; j < n; j++) { for (int i = k + 1; i < m; i++) { work[i] += e[j] * A[i][j]; } } for (int j = k + 1; j < n; j++) { double t = (-e[j]) / e[k + 1]; for (int i = k + 1; i < m; i++) { A[i][j] += t * work[i]; } } } if (wantv) { // Place the transformation in V for subsequent // back multiplication. for (int i = k + 1; i < n; i++) { V[i][k] = e[i]; } } } } // Set up the final bidiagonal matrix or order p. int p = System.Math.Min(n, m + 1); if (nct < n) { s[nct] = A[nct][nct]; } if (m < p) { s[p - 1] = 0.0; } if (nrt + 1 < p) { e[nrt] = A[nrt][p - 1]; } e[p - 1] = 0.0; // If required, generate U. if (wantu) { for (int j = nct; j < nu; j++) { for (int i = 0; i < m; i++) { U[i][j] = 0.0; } U[j][j] = 1.0; } for (int k = nct - 1; k >= 0; k--) { if (s[k] != 0.0) { for (int j = k + 1; j < nu; j++) { double t = 0; for (int i = k; i < m; i++) { t += U[i][k] * U[i][j]; } t = (-t) / U[k][k]; for (int i = k; i < m; i++) { U[i][j] += t * U[i][k]; } } for (int i = k; i < m; i++) { U[i][k] = -U[i][k]; } U[k][k] = 1.0 + U[k][k]; for (int i = 0; i < k - 1; i++) { U[i][k] = 0.0; } } else { for (int i = 0; i < m; i++) { U[i][k] = 0.0; } U[k][k] = 1.0; } } } // If required, generate V. if (wantv) { for (int k = n - 1; k >= 0; k--) { if ((k < nrt) & (e[k] != 0.0)) { for (int j = k + 1; j < nu; j++) { double t = 0; for (int i = k + 1; i < n; i++) { t += V[i][k] * V[i][j]; } t = (-t) / V[k + 1][k]; for (int i = k + 1; i < n; i++) { V[i][j] += t * V[i][k]; } } } for (int i = 0; i < n; i++) { V[i][k] = 0.0; } V[k][k] = 1.0; } } // Main iteration loop for the singular values. int pp = p - 1; int iter = 0; double eps = System.Math.Pow(2.0, -52.0); while (p > 0) { int k, kase; // Here is where a test for too many iterations would go. // This section of the program inspects for // negligible elements in the s and e arrays. On // completion the variables kase and k are set as follows. // kase = 1 if s(p) and e[k-1] are negligible and k<p // kase = 2 if s(k) is negligible and k<p // kase = 3 if e[k-1] is negligible, k<p, and // s(k), ..., s(p) are not negligible (qr step). // kase = 4 if e(p-1) is negligible (convergence). for (k = p - 2; k >= -1; k--) { if (k == -1) { break; } if (System.Math.Abs(e[k]) <= eps * (System.Math.Abs(s[k]) + System.Math.Abs(s[k + 1]))) { e[k] = 0.0; break; } } if (k == p - 2) { kase = 4; } else { int ks; for (ks = p - 1; ks >= k; ks--) { if (ks == k) { break; } double t = (ks != p?System.Math.Abs(e[ks]):0.0) + (ks != k + 1?System.Math.Abs(e[ks - 1]):0.0); if (System.Math.Abs(s[ks]) <= eps * t) { s[ks] = 0.0; break; } } if (ks == k) { kase = 3; } else if (ks == p - 1) { kase = 1; } else { kase = 2; k = ks; } } k++; // Perform the task indicated by kase. switch (kase) { // Deflate negligible s(p). case 1: { double f = e[p - 2]; e[p - 2] = 0.0; for (int j = p - 2; j >= k; j--) { double t = Maths.Hypot(s[j], f); double cs = s[j] / t; double sn = f / t; s[j] = t; if (j != k) { f = (-sn) * e[j - 1]; e[j - 1] = cs * e[j - 1]; } if (wantv) { for (int i = 0; i < n; i++) { t = cs * V[i][j] + sn * V[i][p - 1]; V[i][p - 1] = (-sn) * V[i][j] + cs * V[i][p - 1]; V[i][j] = t; } } } } break; // Split at negligible s(k). case 2: { double f = e[k - 1]; e[k - 1] = 0.0; for (int j = k; j < p; j++) { double t = Maths.Hypot(s[j], f); double cs = s[j] / t; double sn = f / t; s[j] = t; f = (-sn) * e[j]; e[j] = cs * e[j]; if (wantu) { for (int i = 0; i < m; i++) { t = cs * U[i][j] + sn * U[i][k - 1]; U[i][k - 1] = (-sn) * U[i][j] + cs * U[i][k - 1]; U[i][j] = t; } } } } break; // Perform one qr step. case 3: { // Calculate the shift. double scale = System.Math.Max(System.Math.Max(System.Math.Max(System.Math.Max(System.Math.Abs(s[p - 1]), System.Math.Abs(s[p - 2])), System.Math.Abs(e[p - 2])), System.Math.Abs(s[k])), System.Math.Abs(e[k])); double sp = s[p - 1] / scale; double spm1 = s[p - 2] / scale; double epm1 = e[p - 2] / scale; double sk = s[k] / scale; double ek = e[k] / scale; double b = ((spm1 + sp) * (spm1 - sp) + epm1 * epm1) / 2.0; double c = (sp * epm1) * (sp * epm1); double shift = 0.0; if ((b != 0.0) | (c != 0.0)) { shift = System.Math.Sqrt(b * b + c); if (b < 0.0) { shift = -shift; } shift = c / (b + shift); } double f = (sk + sp) * (sk - sp) + shift; double g = sk * ek; // Chase zeros. for (int j = k; j < p - 1; j++) { double t = Maths.Hypot(f, g); double cs = f / t; double sn = g / t; if (j != k) { e[j - 1] = t; } f = cs * s[j] + sn * e[j]; e[j] = cs * e[j] - sn * s[j]; g = sn * s[j + 1]; s[j + 1] = cs * s[j + 1]; if (wantv) { for (int i = 0; i < n; i++) { t = cs * V[i][j] + sn * V[i][j + 1]; V[i][j + 1] = (-sn) * V[i][j] + cs * V[i][j + 1]; V[i][j] = t; } } t = Maths.Hypot(f, g); cs = f / t; sn = g / t; s[j] = t; f = cs * e[j] + sn * s[j + 1]; s[j + 1] = (-sn) * e[j] + cs * s[j + 1]; g = sn * e[j + 1]; e[j + 1] = cs * e[j + 1]; if (wantu && (j < m - 1)) { for (int i = 0; i < m; i++) { t = cs * U[i][j] + sn * U[i][j + 1]; U[i][j + 1] = (-sn) * U[i][j] + cs * U[i][j + 1]; U[i][j] = t; } } } e[p - 2] = f; iter = iter + 1; } break; // Convergence. case 4: { // Make the singular values positive. if (s[k] <= 0.0) { s[k] = (s[k] < 0.0?-s[k]:0.0); if (wantv) { for (int i = 0; i <= pp; i++) { V[i][k] = -V[i][k]; } } } // Order the singular values. while (k < pp) { if (s[k] >= s[k + 1]) { break; } double t = s[k]; s[k] = s[k + 1]; s[k + 1] = t; if (wantv && (k < n - 1)) { for (int i = 0; i < n; i++) { t = V[i][k + 1]; V[i][k + 1] = V[i][k]; V[i][k] = t; } } if (wantu && (k < m - 1)) { for (int i = 0; i < m; i++) { t = U[i][k + 1]; U[i][k + 1] = U[i][k]; U[i][k] = t; } } k++; } iter = 0; p--; } break; } } }
/// <summary>Solve X*A = B, which is also A'*X' = B'</summary> /// <param name="B"> right hand side /// </param> /// <returns> solution if A is square, least squares solution otherwise. /// </returns> public virtual GeneralMatrix SolveTranspose(GeneralMatrix B) { return(Transpose().Solve(B.Transpose())); }
/// <summary>LU Decomposition</summary> /// <param name="A"> Rectangular matrix /// </param> /// <returns> Structure to access L, U and piv. /// </returns> public LUDecomposition(GeneralMatrix A) { // Use a "left-looking", dot-product, Crout/Doolittle algorithm. LU = A.ArrayCopy; m = A.RowDimension; n = A.ColumnDimension; piv = new int[m]; for (int i = 0; i < m; i++) { piv[i] = i; } pivsign = 1; double[] LUrowi; double[] LUcolj = new double[m]; // Outer loop. for (int j = 0; j < n; j++) { // Make a copy of the j-th column to localize references. for (int i = 0; i < m; i++) { LUcolj[i] = LU[i][j]; } // Apply previous transformations. for (int i = 0; i < m; i++) { LUrowi = LU[i]; // Most of the time is spent in the following dot product. int kmax = System.Math.Min(i, j); double s = 0.0; for (int k = 0; k < kmax; k++) { s += LUrowi[k] * LUcolj[k]; } LUrowi[j] = LUcolj[i] -= s; } // Find pivot and exchange if necessary. int p = j; for (int i = j + 1; i < m; i++) { if (System.Math.Abs(LUcolj[i]) > System.Math.Abs(LUcolj[p])) { p = i; } } if (p != j) { for (int k = 0; k < n; k++) { double t = LU[p][k]; LU[p][k] = LU[j][k]; LU[j][k] = t; } int k2 = piv[p]; piv[p] = piv[j]; piv[j] = k2; pivsign = -pivsign; } // Compute multipliers. if (j < m & LU[j][j] != 0.0) { for (int i = j + 1; i < m; i++) { LU[i][j] /= LU[j][j]; } } } }
protected RpropResult RPropLoop(double[] seed, bool precise) { //Console.WriteLine("RpropLoop"); InitialStepSize(); double[] curGradient; RpropResult ret = new RpropResult(); if (seed != null) { curGradient = InitialPointFromSeed(ret, seed); } else { curGradient = InitialPoint(ret); } double curUtil = ret.initialUtil; double oldUtil = curUtil; double[] formerGradient = new double[dim]; double[] curValue = new double[dim]; double[] testValue = new double[dim]; double lambda = 0.1; Tuple <double[], double> tup; Buffer.BlockCopy(ret.initialValue, 0, curValue, 0, sizeof(double) * dim); formerGradient = curGradient; //Buffer.BlockCopy(curGradient,0,formerGradient,0,sizeof(double)*dim); int itcounter = 0; int badcounter = 0; /*Console.WriteLine("Initial Sol:"); * for(int i=0; i<dim;i++) { * Console.Write("{0} ",curValue[i]); * } * Console.WriteLine(); * Console.WriteLine("Initial Util: {0}",curUtil); */ #if (GSOLVER_LOG) Log(curUtil, curValue); #endif int maxIter = 60; int maxBad = 30; double minStep = 1E-11; if (precise) { maxIter = 120; //110 maxBad = 60; //60 minStep = 1E-15; //15 } int convergendDims = 0; while (itcounter++ < maxIter && badcounter < maxBad) { convergendDims = 0; //First Order resp. approximated Second Order Gradient for (int i = 0; i < dim; i++) { if (curGradient[i] * formerGradient[i] > 0) { rpropStepWidth[i] *= 1.3; } else if (curGradient[i] * formerGradient[i] < 0) { rpropStepWidth[i] *= 0.5; } rpropStepWidth[i] = Math.Max(minStep, rpropStepWidth[i]); //rpropStepWidth[i] = Math.Max(0.000001,rpropStepWidth[i]); if (curUtil > 0.0) { //if (curGradient[i] > 0) curValue[i] += rpropStepWidth[i]; //else if (curGradient[i] < 0) curValue[i] -= rpropStepWidth[i]; } else { //linear assumption //curValue[i] += -curUtil/curGradient[i]; //quadratic assumption /*double ypSquare = 0; * for(int j=0; j<dim; j++) { * ypSquare += curGradient[j]*curGradient[j]; * } * double m=ypSquare/curUtil; * curValue[i] = -curGradient[i]/(2*m) + curValue[i];*/ } if (curValue[i] > limits[i, 1]) { curValue[i] = limits[i, 1]; } else if (curValue[i] < limits[i, 0]) { curValue[i] = limits[i, 0]; } if (rpropStepWidth[i] < rpropStepConvergenceThreshold[i]) { ++convergendDims; } } //Abort if all dimensions are converged if (!precise && convergendDims >= dim) { if (curUtil > ret.finalUtil) { ret.finalUtil = curUtil; Buffer.BlockCopy(curValue, 0, ret.finalValue, 0, sizeof(double) * dim); } return(ret); } // Conjugate Gradient if (curUtil < 0.5) { DotNetMatrix.GeneralMatrix X = new DotNetMatrix.GeneralMatrix(dim * 2 + 1, dim); DotNetMatrix.GeneralMatrix Y = new DotNetMatrix.GeneralMatrix(dim * 2 + 1, 1); for (int n = 0; n < dim; n++) { X.SetElement(0, n, curValue[n]); } Y.SetElement(0, 0, 0); for (int j = 0; j < dim * 2; j++) { for (int n = 0; n < dim; n++) { double rVal = rand.NextDouble() * rpropStepConvergenceThreshold[n] * 1000.0; testValue[n] = curValue[n] + rVal; } tup = term.Differentiate(testValue); for (int n = 0; n < dim; n++) { X.SetElement(j + 1, n, tup.Item1[n]); } Y.SetElement(j + 1, 0, tup.Item2 - curUtil); } DotNetMatrix.GeneralMatrix JJ = X.Transpose().Multiply(X); /*if(curUtil>oldUtil) lambda *= 10; * else lambda *= 0.1;*/ //DotNetMatrix.GeneralMatrix B = JJ.Add(GeneralMatrix.Identity(dim, dim).Multiply(lambda)).Inverse().Multiply(X.Transpose()).Multiply(Y); DotNetMatrix.GeneralMatrix B = JJ.Add(JJ.SVD().S.Multiply(lambda)).Inverse().Multiply(X.Transpose()).Multiply(Y); //DotNetMatrix.GeneralMatrix B = JJ.Inverse().Multiply(X.Transpose()).Multiply(Y); for (int j = 0; j < dim; j++) { curValue[j] += 0.01 * B.GetElement(j, 0); } Console.WriteLine(curUtil); Console.Write(B.Transpose()); Console.WriteLine(); } ///////////////////////// this.FEvals++; tup = term.Differentiate(curValue); bool allZero = true; for (int i = 0; i < dim; i++) { if (Double.IsNaN(tup.Item1[i])) { ret.aborted = true; #if (GSOLVER_LOG) LogStep(); #endif return(ret); } allZero &= (tup.Item1[i] == 0); } oldUtil = curUtil; curUtil = tup.Item2; formerGradient = curGradient; curGradient = tup.Item1; #if (GSOLVER_LOG) Log(curUtil, curValue); #endif //Console.WriteLine("CurUtil: {0} Final {1}",curUtil,ret.finalUtil); if (curUtil > ret.finalUtil) { badcounter = 0; //Math.Max(0,badcounter-1); //if (curUtil-ret.finalUtil < 0.00000000000001) { //Console.WriteLine("not better"); // badcounter++; //} else { //badcounter = 0; //} ret.finalUtil = curUtil; Buffer.BlockCopy(curValue, 0, ret.finalValue, 0, sizeof(double) * dim); //ret.finalValue = curValue; #if (ALWAYS_CHECK_THRESHOLD) if (curUtil > utilityThreshold) { return(ret); } #endif } else { //if (curUtil < ret.finalUtil || curUtil > 0) badcounter++; badcounter++; } if (allZero) { //Console.WriteLine("All Zero!"); /*Console.WriteLine("Util {0}",curUtil); * Console.Write("Vals: "); * for(int i=0; i < dim; i++) { * Console.Write("{0}\t",curValue[i]); * } * Console.WriteLine();*/ ret.aborted = false; #if (GSOLVER_LOG) LogStep(); #endif return(ret); } } #if (GSOLVER_LOG) LogStep(); #endif ret.aborted = false; return(ret); }
/// <summary>Creates a new instance of Metric</summary> /// <param name="m">The NxN metric matrix</param> public Metric(DotNetMatrix.GeneralMatrix m) { init(m); // forward call to init() }