예제 #1
0
            /// <summary>Computes A*inv(H)*A' and stores result in ans</summary>
            /// <param name="A">A matrix, mxn</param>
            /// <param name="H">H matrix, nxn</param>
            /// <param name="ans">answer, mxm</param>
            /// <param name="temp">Temporary matrix for the operation, size nxm</param>
            /// <param name="refine">Refine linear system solution?</param>
            public static floatSymPosDefMatrix ComputeAinvHTranspA(floatMatrix A, floatSymPosDefMatrix H, ref floatSymPosDefMatrix ans, ref floatMatrix temp, bool refine)
            {
                int m=A.Rows;
                int n=A.Cols;
                if (ans == null) ans = new floatSymPosDefMatrix(m);

                if (H.getN != n) throw new Exception("Matrix sizes not compatible");
                if (ans.getN != m) throw new Exception("Answer size not compatible");

                H.LinearSolve(A, refine, ref temp);

                //Go on to multiplying A*temp
                if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.UsingCL)
                {
                    kernelComputeAinvHAt.Execute(new CLCalc.Program.MemoryObject[] { A.CLValues, A.CLDim, temp.CLValues, ans.CLValues }, (m * (m + 1)) >> 1);
                    ans.IsCholeskyFactorized = false;
                }
                else
                {
                    for (int p = 0; p < m; p++)
                    {
                        int np = n * p;
                        for (int q = 0; q <= p; q++)
                        {
                            int nq = n * q;

                            float val = 0;
                            for (int k = 0; k < n; k++)
                            {
                                val += A.Values[k + np] * temp.Values[k + nq];
                            }
                            ans.Values[((p * (1 + p)) >> 1) + q] = val;
                        }
                    }
                }

                return ans;
            }
예제 #2
0
 /// <summary>Symmetric positive definite product with vector, Msym*v. resp gets constructed if ==null </summary>
 private static void MultiplyNoCL(floatSymPosDefMatrix M, floatVector v, ref floatVector resp)
 {
     for (int i = 0; i <  M.getN; i++)
     {
         float val = 0;
         for (int k = 0; k < M.getN; k++)
         {
             val += M[i, k] * v.Values[k];
         }
         resp.Values[i] = val;
     }
 }
예제 #3
0
            /// <summary>Computes transpose(A)*A and transpose(A)*b weighted by W using OpenCL. Lambda is regularization term</summary>
            private static floatSymPosDefMatrix AuxLSAtACL(floatMatrix A, floatDiag W, floatVector lambda, ref floatSymPosDefMatrix AtA)
            {
                if (AtA == null || AtA.CLValues.OriginalVarLength != (A.Cols * (A.Cols + 1)) >> 1)
                {
                    AtA = new floatSymPosDefMatrix(new float[(A.Cols * (A.Cols + 1)) >> 1]);
                }

                CLCalc.Program.Variable[] args = new CLCalc.Program.Variable[] { A.CLValues, A.CLDim, W.CLValues, AtA.CLValues, lambda.CLValues };
                kernelComputeAtWA.Execute(args, AtA.CLValues.OriginalVarLength);

                //Just modified values in CL memory, matrix is no longer Cholesky factorized
                AtA.IsCholeskyFactorized = false;

                return AtA;
            }
예제 #4
0
            /// <summary>Computes transpose(A)*A and transpose(A)*b weighted by W</summary>
            /// <param name="A">Original matrix</param>
            /// <param name="W">Measurement weight vector</param>
            /// <param name="lambda">Regularization term</param>
            /// <param name="AtA">Answer, A transpose times A</param>
            private static floatSymPosDefMatrix AuxLeastSquaresAtAnoCL(floatMatrix A, floatDiag W, floatVector lambda, ref floatSymPosDefMatrix AtA)
            {
                //A (mxn), AtA (nxn) positive semidef symmetric
                int m = A.Rows;
                int n = A.Cols;

                if (AtA == null) AtA = new floatSymPosDefMatrix(new float[(n * (n + 1)) >> 1]);

                if (W != null)
                {
                    for (int i = 0; i < n; i++)
                    {
                        for (int j = 0; j <= i; j++)
                        {
                            double val = 0;
                            for (int k = 0; k < m; k++)
                            {
                                val += A[k, i] * A[k, j] * W.Values[k];
                            }
                            AtA.Values[((i * (i + 1)) >> 1) + j] = (float)val;
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < n; i++)
                    {
                        for (int j = 0; j <= i; j++)
                        {
                            double val = 0;
                            for (int k = 0; k < m; k++)
                            {
                                val += A[k, i] * A[k, j];
                            }
                            AtA.Values[((i * (i + 1)) >> 1) + j] = (float)val;
                        }
                    }
                }

                //regularization term
                for (int i = 0; i < n; i++)
                {
                    AtA.Values[((i * (i + 1)) >> 1) + i] += lambda.Values[i];
                }

                return AtA;
            }
예제 #5
0
            /// <summary>Symmetric positive definite product with vector, Msym*v. resp gets constructed if ==null </summary>
            public static floatVector SymPosDefSymMatrVecMultiply(floatSymPosDefMatrix M, floatVector v, ref floatVector ans)
            {
                if (ans == null) ans = new floatVector(new float[v.Length]);
                if (ans.Length != v.Length) throw new Exception("ans and v should have the same length");
                if (v.Length != M.getN) throw new Exception("Invalid vector length to multiply by this matrix");

                if (CLCalc.CLAcceleration != CLCalc.CLAccelerationType.UsingCL)
                {
                    MultiplyNoCL(M, v, ref ans);
                    return ans;
                }

                if (!M.IsMatrixInClMemoryUpdated)
                {
                    M.CLValues.WriteToDevice(M.Values);
                    M.IsMatrixInClMemoryUpdated = true;
                }

                kernelSymMatrVecMultiply.Execute(new CLCalc.Program.Variable[] { M.CLValues, v.CLValues, ans.CLValues }, M.getN);

                return ans;
            }
예제 #6
0
            /// <summary>Symmetric positive definite product with matrix transpose, Msym*At. ans gets constructed if ==null </summary>
            public static floatMatrix SymPosDefMatrMatrMultiply(floatSymPosDefMatrix M, floatMatrix A, ref floatMatrix ans)
            {
                if (ans == null) ans = new floatMatrix(new float[A.Cols, M.getN]);

                if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.UsingCL)
                {
                    if (!M.IsMatrixInClMemoryUpdated) M.CLValues.WriteToDevice(M.Values);
                    kernelSymMatrMatrMultiply.Execute(new CLCalc.Program.MemoryObject[] { M.CLValues, A.CLValues, ans.CLValues }, new int[] { A.Rows, A.Cols });
                }
                else
                {
                    for (int j = 0; j < A.Cols; j++)
                    {
                        for (int i = 0; i < M.getN; i++)
                        {
                            float val = 0;
                            for (int k = 0; k < M.getN; k++)
                            {
                                val += M[i, k] * A.Values[k + j * A.Rows];
                            }
                            ans.Values[i + j * A.Rows] = val;
                        }
                    }
                }

                return ans;
            }
예제 #7
0
 /// <summary>Computes transpose(A)*A using weights W</summary>
 /// <param name="A">Original matrix</param>
 /// <param name="W">Measurement weight vector</param>
 /// <param name="lambda">Regularization term</param>
 /// <param name="AtA">Answer, A transpose times A</param>
 public static floatSymPosDefMatrix MatrTranspMatrProd(floatMatrix A, floatDiag W, floatVector lambda, ref floatSymPosDefMatrix AtA)
 {
     if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.UsingCL)
     {
         return AuxLSAtACL(A, W, lambda, ref AtA);
     }
     else
     {
         return AuxLeastSquaresAtAnoCL(A, W, lambda, ref AtA);
     }
 }
예제 #8
0
 /// <summary>Computes transpose(A)*A</summary>
 /// <param name="A">Original matrix</param>
 /// <param name="lambda">Regularization term</param>
 /// <param name="AtA">Answer, A transpose times A</param>
 public static floatSymPosDefMatrix MatrTranspMatrProd(floatMatrix A, floatVector lambda, ref floatSymPosDefMatrix AtA)
 {
     return MatrTranspMatrProd(A, null, lambda, ref AtA);
 }
예제 #9
0
            /// <summary>Creates vector from M elements sequentially</summary>
            /// <param name="symM">Symmetric matrix to use</param>
            public floatVector(floatSymPosDefMatrix symM)
            {
                this.CLValues = symM.CLValues;
                this.Values = symM.Values;

                //Since I'm probably going to modify the matrix, I want a new Cholesky factorization
                //if I ever call a LinearSolve
                symM.IsCholeskyFactorized = false;

                if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.UsingCL)
                {
                    CLCoef = new CLCalc.Program.Variable(new float[1]);
                }
            }
예제 #10
0
            /// <summary>Returns the identity matrix</summary>
            /// <param name="n">Matrix dimension nxn</param>
            public static floatSymPosDefMatrix Identity(int n)
            {
                floatSymPosDefMatrix M = new floatSymPosDefMatrix(n);

                for (int i = 0; i < n; i++) M[i, i] = 1;

                return M;
            }