Пример #1
0
            /// <summary>Computes the unconstrained minimum of function F in x0.Length dimensions subject to equality constraint Ax=b</summary>
            /// <param name="x0">Start point. Problem dimension is assumed to be x0.Length</param>
            /// <param name="F">Function to minimize</param>
            /// <param name="A">Equality constraint matrix</param>
            /// <param name="b">Equality constraint rhs</param>            
            /// <param name="iters">Number of iterations used to solve the problem</param>
            public static float[] Solve(float[] x0, C2Function F, float[,] A, float[] b, out int iters)
            {
                floatLinalg.floatVector CLx = new floatLinalg.floatVector(x0);

                //Creates Hessian and Gradient
                floatLinalg.floatSymPosDefMatrix HessF = new floatLinalg.floatSymPosDefMatrix(x0.Length);
                floatLinalg.floatVector gradF = new floatLinalg.floatVector(x0);

                //Line search variables
                floatLinalg.floatVector temp = new floatLinalg.floatVector(x0);
                floatLinalg.floatVector deltaX = new floatLinalg.floatVector(x0);

                //Equality constraint vars
                if (A != null)
                {
                    int c = A.GetLength(0);
                    int n = x0.Length;
                    floatLinalg.floatMatrix CLA = new floatLinalg.floatMatrix(A);
                    floatLinalg.floatVector CLb = new floatLinalg.floatVector(b);
                    floatLinalg.floatVector CLDeltaNu = new floatLinalg.floatVector(b);

                    floatLinalg.floatVector rPri = new floatLinalg.floatVector(new float[c]);
                    floatLinalg.floatVector Atnu = new floatLinalg.floatVector(new float[n]);
                    floatLinalg.floatVector tempC = new floatLinalg.floatVector(new float[c]);
                    floatLinalg.floatVector temp2 = new floatLinalg.floatVector(x0);

                    floatLinalg.floatSymPosDefMatrix AinvHAt = new floatLinalg.floatSymPosDefMatrix(c);
                    floatLinalg.floatVector AinvHrhs = new floatLinalg.floatVector(new float[c]);
                    floatLinalg.floatMatrix tempAinvMatrix = new floatLinalg.floatMatrix(new float[n, c]);

                    float[] fOnes = new float[c];
                    for (int i = 0; i < fOnes.Length; i++) fOnes[i] = 1;
                    floatLinalg.floatVector onesC = new floatLinalg.floatVector(fOnes);
                    return Solve(CLx, F, out iters, HessF, gradF, temp, deltaX, CLA, CLb, AinvHAt, tempAinvMatrix, temp2, AinvHrhs, rPri, tempC, CLDeltaNu, Atnu, onesC);
                }
                else return Solve(CLx, F, out iters, HessF, gradF, temp, deltaX, null, null, null, null, null, null, null, null, null, null, null);
            }
Пример #2
0
            /// <summary>Computes the unconstrained minimum of function F in x0.Length dimensions</summary>
            /// <param name="x0">Start point. Problem dimension is assumed to be x0.Length</param>
            /// <param name="F">Function to minimize</param>
            /// <param name="iters">Number of iterations used to solve the problem</param>
            public static float[] Solve(float[] x0, C2Function F, out int iters)
            {
                floatLinalg.floatVector CLx = new floatLinalg.floatVector(x0);

                //Creates Hessian and Gradient
                floatLinalg.floatSymPosDefMatrix HessF = new floatLinalg.floatSymPosDefMatrix(x0.Length);
                floatLinalg.floatVector gradF = new floatLinalg.floatVector(x0);

                //Line search variables
                floatLinalg.floatVector temp = new floatLinalg.floatVector(x0);
                floatLinalg.floatVector deltaX = new floatLinalg.floatVector(x0);

                return Solve(CLx, F, out iters, HessF, gradF, temp, deltaX);
            }
Пример #3
0
            /// <summary>Solves a quadratic programming problem 1/2 x'Px + q'x subject to Mx less or equal d and Ax = b</summary>
            /// <param name="x0">Start point x0</param>
            /// <param name="P">Positive semidefinite quadratic objective matrix P</param>
            /// <param name="q">Linear objective q</param>
            /// <param name="M">Ineq constraint matrix M</param>
            /// <param name="d">Ineq constraint right hand side d</param>
            /// <param name="A">Constraint matrix A</param>
            /// <param name="b">Constraint right hand side b</param>
            /// <param name="sf">Stop function. The system won't check feasibility if this function is not null. Return true when you want the optimization to stop based on x, lambda and nu</param>
            private float[] SolveBarrier(float[] x0, floatLinalg.floatSymPosDefMatrix P,
                float[] q, float[,] M, float[] d, float[,] A, float[] b, StopFunc sf)
            {
                //Number of primal vars
                int n = x0.Length;
                //Number of dual vars
                int m = M.GetLength(0);

                //Constraint variables
                int c = A == null ? 0 : A.GetLength(0);

                if (P != null && P.getN != n) throw new Exception("Incompatible matrix P dimensions");
                if (M.GetLength(0) != m || M.GetLength(1) != n) throw new Exception("Incompatible matrix M dimensions");
                if (q.Length != n) throw new Exception("Incompatible vector q dimensions");
                if (d.Length != m) throw new Exception("Incompatible vector d dimensions");

                CLP = P;
                if (CLP != null && !CLP.IsMatrixInClMemoryUpdated)
                {
                    CLP.CLValues.WriteToDevice(CLP.Values);
                    CLP.IsMatrixInClMemoryUpdated = true;
                }

                if (c > 0)
                {
                    if (b.Length != c) throw new Exception("Incompatible vector b dimensions");
                    if (A.GetLength(0) != c || A.GetLength(1) != n) throw new Exception("Incompatible matrix A dimensions");
                }

                CLM = new floatLinalg.floatMatrix(M);

                CLx = new floatLinalg.floatVector(x0);

                return null;
            }
Пример #4
0
            /// <summary>Solves a quadratic programming problem 1/2 x'Px + q'x subject to Mx less or equal d and Ax = b</summary>
            /// <param name="x0">Start point x0</param>
            /// <param name="lambda0">Start dual point lambda0</param>
            /// <param name="nu0">Start nus (equality constraints)</param>
            /// <param name="P">Positive semidefinite quadratic objective matrix P</param>
            /// <param name="q">Linear objective q</param>
            /// <param name="M">Ineq constraint matrix M</param>
            /// <param name="d">Ineq constraint right hand side d</param>
            /// <param name="A">Constraint matrix A</param>
            /// <param name="b">Constraint right hand side b</param>
            /// <param name="sf">Stop function. The system won't check feasibility if this function is not null. Return true when you want the optimization to stop based on x, lambda and nu</param>
            public float[] SolvePrimalDual(float[] x0, float[] lambda0, float[] nu0, floatLinalg.floatSymPosDefMatrix P,
                float[] q, float[,] M, float[] d, float[,] A, float[] b, StopFunc sf)
            {
                //Number of primal vars
                int n = x0.Length;
                //Number of dual vars
                int m = lambda0.Length;
                //Constraint variables
                int c = nu0 == null ? 0 : nu0.Length;

                if (P!=null && P.getN != n) throw new Exception("Incompatible matrix P dimensions");
                if (M.GetLength(0) != m || M.GetLength(1) != n) throw new Exception("Incompatible matrix M dimensions");
                if (q.Length != n) throw new Exception("Incompatible vector q dimensions");
                if (d.Length != m) throw new Exception("Incompatible vector d dimensions");
                if (nu0 == null && A != null) throw new Exception("Equality constraint matrix was given. Please also give initial values for laplace multipliers nu0");

                CLP = P;
                if (CLP != null && !CLP.IsMatrixInClMemoryUpdated)
                {
                    CLP.CLValues.WriteToDevice(CLP.Values);
                    CLP.IsMatrixInClMemoryUpdated = true;
                }

                if (c > 0)
                {
                    if (b.Length != c) throw new Exception("Incompatible vector b dimensions");
                    if (A.GetLength(0) != c || A.GetLength(1) != n) throw new Exception("Incompatible matrix A dimensions");
                }

                CLM = new floatLinalg.floatMatrix(M);

                CLx = new floatLinalg.floatVector(x0);
                CLxPlus = new floatLinalg.floatVector(x0);
                CLlambda = new floatLinalg.floatVector(lambda0);
                CLlambdaPlus = new floatLinalg.floatVector(lambda0);
                CLDeltaX = new floatLinalg.floatVector(x0);
                CLDeltaLambda = new floatLinalg.floatVector(lambda0);

                CLq = new floatLinalg.floatVector(q);
                CLd = new floatLinalg.floatVector(d);

                //Auxiliary vars
                zerosN = new floatLinalg.floatVector(new float[n]);

                float[] fOnes = new float[m];
                for (int i = 0; i < fOnes.Length; i++) fOnes[i] = 1;
                onesM = new floatLinalg.floatVector(fOnes);

                Hpd = new floatLinalg.floatSymPosDefMatrix(n);
                MtDzM = new floatLinalg.floatSymPosDefMatrix(n);

                temp = new floatLinalg.floatVector(new float[n]);
                temp2 = new floatLinalg.floatVector(new float[n]);
                rhsXpd = new floatLinalg.floatVector(new float[n]);

                Mxd = new floatLinalg.floatVector(new float[m]);
                z2 = new floatLinalg.floatVector(new float[m]);
                z = new floatLinalg.floatVector(new float[m]);
                rCent = new floatLinalg.floatVector(new float[m]);
                tempM = new floatLinalg.floatVector(new float[m]);
                tempM2 = new floatLinalg.floatVector(new float[m]);

                CLPx = new floatLinalg.floatVector(new float[n]);

                //Equality constraint variables
                if (c > 0)
                {
                    CLA = new floatLinalg.floatMatrix(A);
                    CLb = new floatLinalg.floatVector(b);
                    CLnu = new floatLinalg.floatVector(nu0);
                    CLDeltaNu = new floatLinalg.floatVector(nu0);
                    rPri = new floatLinalg.floatVector(new float[c]);
                    Atnu = new floatLinalg.floatVector(new float[n]);
                    tempC = new floatLinalg.floatVector(new float[c]);
                    CLnuPlus = new floatLinalg.floatVector(new float[c]);

                    AinvHAt = new floatLinalg.floatSymPosDefMatrix(c);
                    AinvHrhs = new floatLinalg.floatVector(new float[c]);
                    tempAinvMatrix = new floatLinalg.floatMatrix(new float[n, c]);

                    fOnes = new float[c];
                    for (int i = 0; i < fOnes.Length; i++) fOnes[i] = 1;
                    onesC = new floatLinalg.floatVector(fOnes);
                }
                else
                {
                    CLA = null;
                    CLb = null;
                    CLnu = null;
                    CLnuPlus = null;
                }

                //Checks feasibility
                bool feasible = true;
                float[] xfeas;
                if (sf == null)
                {
                    xfeas = CheckFeasibility(x0, M, d, A, b);
                    feasible = (xfeas != null);

                    if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.UsingCL) CLx.CLValues.WriteToDevice(xfeas);
                    else for (int i = 0; i < xfeas.Length; i++) CLx.Values[i] = xfeas[i];
                }

                if (SolutionLog.KeepLog)
                {
                    CLx.ReadFromDevice();
                    SolutionLog.PtSequence.Add((float[])CLx.Values.Clone());
                }

                if (feasible)
                {
                    float surrogDualityGap = 100;
                    float t = 0.1f;
                    int MAXITER = 60;
                    int curIter = 0;

                    while (surrogDualityGap > 5e-5f && curIter < MAXITER &&
                        (sf == null || (sf != null && !sf(CLx, CLlambda, CLnu)))
                        )
                    {

                        if (curIter == (MAXITER >> 1))
                        {
                            //DEBUG, taking too long to converge
                            for (int i = 0; i < CLlambda.Values.Length; i++) CLlambda.Values[i] = 0.1f;
                            if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.UsingCL) CLlambda.CLValues.WriteToDevice(CLlambda.Values);
                            t *= 0.1f;
                        }

                        //PDResidual(CLx, CLlambda, CLnu, t);
                        ComputePrimalDualSearchDir(t);
                        PrimalDualLineSearch(CLx, Mxd, CLlambda, CLnu, CLDeltaX, CLDeltaLambda,
                            CLDeltaNu, CLxPlus, CLlambdaPlus, CLnuPlus, CompRestric, PDResidual, ref t, out surrogDualityGap);

                        curIter++;

                        if (SolutionLog.KeepLog)
                        {
                            SolutionLog.SurrDualityGaps.Add(surrogDualityGap);
                            CLx.ReadFromDevice();
                            SolutionLog.PtSequence.Add((float[])CLx.Values.Clone());
                        }

                    }

                    SolutionLog.Iterations = curIter;
                    //ReadAll();

                    //Copies lambdas and nus
                    CLlambda.ReadFromDevice();
                    for (int i = 0; i < m; i++) lambda0[i] = CLlambda.Values[i];

                    if (CLnu != null)
                    {
                        CLnu.ReadFromDevice();
                        for (int i = 0; i < c; i++) nu0[i] = CLnu.Values[i];
                    }

                    CLx.ReadFromDevice();
                    return CLx.Values;
                }
                else return null; //Not feasible
            }
Пример #5
0
            private void Init(float[,] Samples, float[] Classifications, float[] RegularizationWeights, float regularizationQ)
            {
                int n = Samples.GetLength(0);
                int p = Samples.GetLength(1);

                if (Classifications.Length != n) throw new Exception("Incompatible Classifications vector dimension");
                if (RegularizationWeights.Length != p) throw new Exception("Incompatible RegularizationWeights vector dimension");
                if (regularizationQ <= 1) throw new Exception("Regularization term Q should be > 1");

                //Includes intercept term
                float[,] X = new float[n, p + 1];
                for (int i = 0; i < n; i++)
                {
                    X[i, 0] = 1;
                    for (int j = 0; j < p; j++)
                    {
                        X[i, j + 1] = Samples[i, j];
                    }
                }

                //Regularization terms
                float[] regTerms = new float[p + 1];
                regTerms[0] = 0;
                for (int i = 0; i < RegularizationWeights.Length; i++) regTerms[i + 1] = RegularizationWeights[i];

                //Retrieves categories
                for (int i = 0; i < Classifications.Length; i++)
                {
                    if (Classifications[i] > 0 && Categories.IndexOf(Classifications[i]) < 0)
                        Categories.Add(Classifications[i]);
                }
                if (Categories.Count == 0) throw new Exception("At least one category should be given");

                //Creates samples matrix and vectors
                CLX = new floatLinalg.floatMatrix(X);
                y = new floatLinalg.floatVector(Classifications);

                //Don't regularize first term
                float[] newLambs = new float[p + 1];
                newLambs[0] = 0;
                for (int i = 0; i < p; i++) newLambs[i + 1] = RegularizationWeights[i];
                lambda = new floatLinalg.floatVector(newLambs);

                //Initial guess
                float[] t0 = new float[p + 1];
                for (int i = 0; i < t0.Length; i++) t0[i] = 1E-3f;
                //t0[0] = 1; t0[1] = 0.2f; t0[2] = 0.3f;
                CLTheta = new floatLinalg.floatVector(t0);

                CLGrad = new floatLinalg.floatVector(new float[p + 1]);
                CLtempGrad = new floatLinalg.floatVector(new float[p + 1]);

                CLq = new floatLinalg.floatVector(new float[] { regularizationQ });
                tempX = new floatLinalg.floatVector(new float[p + 1]);
                tempdX = new floatLinalg.floatVector(new float[p + 1]);
                tempd2X = new floatLinalg.floatVector(new float[p + 1]);

                temp = new floatLinalg.floatVector(new float[p + 1]);
                CLDeltaTheta = new floatLinalg.floatVector(new float[p + 1]);
                Hess = new floatLinalg.floatSymPosDefMatrix(p + 1);

                XTheta = new floatLinalg.floatVector(new float[n]);
                z1 = new floatLinalg.floatVector(new float[n]);
                z2 = new floatLinalg.floatVector(new float[n]);
                cost = new floatLinalg.floatVector(new float[n]);

                float[] vones = new float[n];
                for (int i = 0; i < n; i++) vones[i] = 1;
                ones = new floatLinalg.floatVector(vones);

                _classifs = Classifications;

                //Trains classifier
                Train();
            }
Пример #6
0
            /// <summary>Computes the p-norm minimization of Ax - b with weights w, using q-norm regularization with weights lambda on x</summary>
            /// <param name="x0">Start point</param>
            /// <param name="A">Dependent variables</param>
            /// <param name="b">Independent variables measurements</param>
            /// <param name="W">Weights of each equation</param>
            /// <param name="lambda">Regularization term of each component of x</param>
            /// <param name="p">Ax - b minimization exponent</param>
            /// <param name="q">x regularization exponent</param>
            /// <param name="AeqConstr">Equality constraint matrix AeqConstr * x = bConstr</param>
            /// <param name="bEqConstr">Equality constraint right hand side</param>
            public static float[] PNormMinimization(float[] x0, float[,] A, float[] b, float[] W, float[] lambda, float p, float q, float[,] AeqConstr, float[] bEqConstr)
            {
                //Dimensionality check
                if (A.GetLength(1) != x0.Length) throw new Exception("Number of columns of A should be x.Length");
                if (A.GetLength(0) != b.Length) throw new Exception("Number of rows of A should be b.Length");
                if (A.GetLength(0) != W.Length) throw new Exception("Number of weights should be equal to b.Length");
                if (A.GetLength(1) != lambda.Length) throw new Exception("Number of lambda weights should be equal to x.Length");
                if (p < 1 || q < 1) throw new Exception("p and q values should be greater than 1");
                if (AeqConstr != null && AeqConstr.GetLength(1) != x0.Length) throw new Exception("Number of columns of AeqConstr should be x.Length");
                if (AeqConstr != null && bEqConstr.Length != AeqConstr.GetLength(0)) throw new Exception("bEqConstr.Length not compatible with AeqConstr");

                float[] resp = null;

                floatLinalg.floatMatrix CLA = new floatLinalg.floatMatrix(A);
                //floatLinalg.floatVector CLx = new floatLinalg.floatVector(x0);
                floatLinalg.floatVector CLb = new floatLinalg.floatVector(b);
                floatLinalg.floatVector CLW = new floatLinalg.floatVector(W);
                floatLinalg.floatVector CLlambda = new floatLinalg.floatVector(lambda);
                floatLinalg.floatVector CLp = new floatLinalg.floatVector(new float[] { p });
                floatLinalg.floatVector CLq = new floatLinalg.floatVector(new float[] { q });

                PNormMinClass pnm = new PNormMinClass(CLA, CLb, CLW, CLlambda, CLp, CLq);

                floatLinalg.floatVector x = new floatLinalg.floatVector(x0);
                floatLinalg.floatVector g = new floatLinalg.floatVector(x0);
                floatLinalg.floatSymPosDefMatrix h = new floatLinalg.floatSymPosDefMatrix(x0.Length);

                //pnm.F(x, true, ref g, ref h);
                int iters;
                resp = UnconstrainedMinimization.Solve(x0, pnm.F, AeqConstr, bEqConstr, out iters);

                return resp;
            }