Example #1
0
        public void gh335()
        {
            // https://github.com/accord-net/framework/issues/335
            Func <Double[], Double> eval = (val) =>
            {
                // WxMaxima command: plot3d(y^2+4*y+x^2-2*x,[x,-3,5], [y,-5,3],[grid,8,8]);
                Double x   = val[0];
                Double y   = val[1];
                Double ret = y * y + 4 * y + x * x - 2 * x;

                Debug.WriteLine("{2}; x={0}; y={1}", x, y, ret);

                return(ret);
            };

            // This values are relevant for my RealWorld(TM) scenario
            Double[] init = new double[] { 0.5, 0 };

            NelderMead nm = new NelderMead(2, eval);

            nm.Minimize(init);

            // Solution
            Assert.AreEqual(1, nm.Solution[0], 1e-7);
            Assert.AreEqual(-2, nm.Solution[1], 1e-6);
        }
Example #2
0
        public void Strip()
        {
            // Set the dates for all the curves
            foreach (ICurveForStripping curve in curveDates.Keys)
            {
                curve.SetDates(curveDates[curve].ToArray());
            }

            // Check that all the products can be valued
            double[] values = new double[targetMetrics.Count];
            for (int i = 0; i < targetMetrics.Count; i++)
            {
                values[i] = targetMetrics[i]();
            }

            // Get the vector to be solved
            List <double> guessList    = new List <double>();
            int           totalCounter = 0;

            for (int i = 0; i < curveSet.Count; i++)
            {
                double[] rates = curveSet[i].GetRates();
                for (int j = 0; j < rates.Length; j++)
                {
                    guessList.Add(rates[j]);
                    curveAndIndexMap[totalCounter] = new Tuple <int, int>(i, j);
                    totalCounter++;
                }
            }
            if (guessList.Count != targetMetrics.Count)
            {
                throw new ArgumentException(string.Format("There are {0} metrics as contraints but the curves have {1} free parameters.", targetMetrics.Count, guessList.Count));
            }

            double[] guess     = guessList.ToArray();
            var      optimizer = new NelderMead(numberOfVariables: guess.Length, function: ErrorFunction);
            //var optimizer = new Cobyla(numberOfVariables: guess.Length, function: ErrorFunction);
            //var optimizer = new BroydenFletcherGoldfarbShanno(numberOfVariables: guess.Length);
            //optimizer.Function = ErrorFunction;
            //optimizer.Gradient = ??
            //nm.Convergence.
            bool   success  = optimizer.Minimize(guess);
            double minValue = optimizer.Value;

            double[] solution = optimizer.Solution;

            var optimizer2 = new NelderMead(numberOfVariables: guess.Length, function: ErrorFunction);

            optimizer2.Minimize(solution);
        }
Example #3
0
        public void TestRosenbrock()
        {
            var cf    = new Rosenbrock();
            var optim = new NelderMead(cf);

            var x0 = new DoubleVector(new double[5] {
                1.3, 0.7, 0.8, 1.9, 1.2
            });

            optim.Minimize(x0);

            Assert.AreEqual(optim.SolutionValue, 0.0, 0.0001);
            Assert.AreEqual(optim.SolutionVector[0], 1.0, 0.0001);
            Assert.AreEqual(optim.SolutionVector[1], 1.0, 0.0001);
            Assert.AreEqual(optim.SolutionVector[2], 1.0, 0.0001);
            Assert.AreEqual(optim.SolutionVector[3], 1.0, 0.0001);
            Assert.AreEqual(optim.SolutionVector[4], 1.0, 0.0001);
        }
Example #4
0
        public void ConstructorTest4()
        {
            var function = new NonlinearObjectiveFunction(2, x =>
                Math.Pow(x[0] * x[0] - x[1], 2.0) + Math.Pow(1.0 + x[0], 2.0));

            NelderMead solver = new NelderMead(function);

            Assert.IsTrue(solver.Minimize());
            double minimum = solver.Value;
            double[] solution = solver.Solution;

            Assert.AreEqual(0, minimum, 1e-10);
            Assert.AreEqual(-1, solution[0], 1e-5);
            Assert.AreEqual(1, solution[1], 1e-4);

            double expectedMinimum = function.Function(solver.Solution);
            Assert.AreEqual(expectedMinimum, minimum);
        }
Example #5
0
        /// <summary>
        /// Fits a Nelson Siegel curve to data
        /// </summary>
        /// <param name="t"></param>
        /// <param name="r"></param>
        /// <returns></returns>
        public static NelsonSiegel Fit(Date anchorDate, Date[] dates, double[] rates)
        {
            var times = new double[dates.Length];

            for (var i = 0; i < dates.Length; i++)
            {
                times[i] = dates[i] - anchorDate;
            }

            Func <double[], double> f = x => ErrorFunction(x, times, rates);

            var nm       = new NelderMead(4, f);
            var success  = nm.Minimize(new[] { rates[0], rates[0], rates[0], times.Last() / 5.0 });
            var minValue = nm.Value;
            var solution = nm.Solution;
            var curve    = new NelsonSiegel(anchorDate, solution[0], solution[1], solution[2], solution[3]);

            return(curve);
        }
Example #6
0
        public void ConstructorTest1()
        {
            Func<double[], double> function = // min f(x) = 10 * (x+1)^2 + y^2
              x => 10.0 * Math.Pow(x[0] + 1.0, 2.0) + Math.Pow(x[1], 2.0);

            NelderMead solver = new NelderMead(2, function);

            Assert.IsTrue(solver.Minimize());
            double minimum = solver.Value;

            double[] solution = solver.Solution;

            Assert.AreEqual(0, minimum, 1e-10);
            Assert.AreEqual(-1, solution[0], 1e-5);
            Assert.AreEqual(0, solution[1], 1e-5);

            double expectedMinimum = function(solver.Solution);
            Assert.AreEqual(expectedMinimum, minimum);
        }
        /// <summary>
        /// Fits a Nelson Siegel curve to data
        /// </summary>
        /// <param name="t"></param>
        /// <param name="r"></param>
        /// <returns></returns>
        public static NelsonSiegel Fit(Date anchorDate, Date[] dates, double[] rates)
        {
            double[] times = new double[dates.Length];
            for (int i = 0; i < dates.Length; i++)
            {
                times[i] = dates[i] - anchorDate;
            }

            Func <double[], double> f = (x) => ErrorFunction(x, times, rates);

            var    nm       = new NelderMead(numberOfVariables: 4, function: f);
            bool   success  = nm.Minimize(new double[] { rates[0], rates[0], rates[0], times.Last() / 5.0 });
            double minValue = nm.Value;

            double[]     solution = nm.Solution;
            NelsonSiegel curve    = new NelsonSiegel(anchorDate, solution[0], solution[1], solution[2], solution[3]);

            return(curve);
        }
Example #8
0
        public void ConstructorTest4()
        {
            var function = new NonlinearObjectiveFunction(2, x =>
                                                          Math.Pow(x[0] * x[0] - x[1], 2.0) + Math.Pow(1.0 + x[0], 2.0));

            NelderMead solver = new NelderMead(function);

            Assert.IsTrue(solver.Minimize());
            double minimum = solver.Value;

            double[] solution = solver.Solution;

            Assert.AreEqual(0, minimum, 1e-10);
            Assert.AreEqual(-1, solution[0], 1e-5);
            Assert.AreEqual(1, solution[1], 1e-4);

            double expectedMinimum = function.Function(solver.Solution);

            Assert.AreEqual(expectedMinimum, minimum);
        }
Example #9
0
        public void ConstructorTest1()
        {
            Func <double[], double> function = // min f(x) = 10 * (x+1)^2 + y^2
                                               x => 10.0 * Math.Pow(x[0] + 1.0, 2.0) + Math.Pow(x[1], 2.0);

            NelderMead solver = new NelderMead(2, function);

            Assert.IsTrue(solver.Minimize());
            double minimum = solver.Value;

            double[] solution = solver.Solution;

            Assert.AreEqual(0, minimum, 1e-10);
            Assert.AreEqual(-1, solution[0], 1e-5);
            Assert.AreEqual(0, solution[1], 1e-5);

            double expectedMinimum = function(solver.Solution);

            Assert.AreEqual(expectedMinimum, minimum);
        }
Example #10
0
        public void SubspaceTest1()
        {
            var function = new NonlinearObjectiveFunction(5, x =>
                                                          10.0 * Math.Pow(x[0] * x[0] - x[1], 2.0) + Math.Pow(1.0 + x[0], 2.0));

            NelderMead solver = new NelderMead(function);

            solver.NumberOfVariables = 2;

            Assert.IsTrue(solver.Minimize());
            double minimum = solver.Value;

            double[] solution = solver.Solution;

            Assert.AreEqual(5, solution.Length);
            Assert.AreEqual(-0, minimum, 1e-6);
            Assert.AreEqual(-1, solution[0], 1e-3);
            Assert.AreEqual(+1, solution[1], 1e-3);

            double expectedMinimum = function.Function(solver.Solution);

            Assert.AreEqual(expectedMinimum, minimum);
        }
Example #11
0
        public void ConstructorTest1()
        {
            #region doc_min
            // Let's say we would like to find the minimum
            // of the function "f(x) = 10 * (x+1)^2 + y^2".

            // In code, this means we would like to minimize:
            Func <double[], double> function = (double[] x) =>
                                               10.0 * Math.Pow(x[0] + 1.0, 2.0) + Math.Pow(x[1], 2.0);

            // We can do so using the NelderMead class:
            var solver = new NelderMead(numberOfVariables: 2)
            {
                Function = function // f(x) = 10 * (x+1)^2 + y^2
            };

            // Now, we can minimize it with:
            bool success = solver.Minimize();

            // And get the solution vector using
            double[] solution = solver.Solution; // should be (-1, 1)

            // The minimum at this location would be:
            double minimum = solver.Value; // should be 0

            // Which can be double-checked against Wolfram Alpha if there is need:
            // https://www.wolframalpha.com/input/?i=min+10+*+(x%2B1)%5E2+%2B+y%5E2
            #endregion

            Assert.IsTrue(success);
            Assert.AreEqual(0, minimum, 1e-10);
            Assert.AreEqual(-1, solution[0], 1e-5);
            Assert.AreEqual(0, solution[1], 1e-5);

            double expectedMinimum = function(solver.Solution);
            Assert.AreEqual(expectedMinimum, minimum);
        }
Example #12
0
        static void Main(string[] args)
        {
            Console.Write("Run QE or VQE? ");
            String runString = Console.ReadLine();

            #region Parameters of Operation
            // filename of the molecule to be emulated

            // var FILENAME = "h2_2_sto6g_1.0au.yaml";
            // var FILENAME = "h4_sto6g_0.000.yaml";
            var FILENAME = "h20_nwchem.yaml";

            // use this state provided in the YAML.
            var STATE = "|G>";

            // the margin of error to use when approximating the expected value
            var MOE = 0.1;

            // precision to iterate over with the state preparation gate
            // the number of trials is directly proportional to this constant's inverse
            // the gate will be applying a transform of the form (2 pi i \phi) where \phi
            // varies by the precision specified below
            var ANGULAR_PRECISION = 0.01;

            Console.WriteLine($"STATE: {STATE} | MOE: {MOE} | PRECISION: {ANGULAR_PRECISION}");

            #endregion

            #region Creating the Hamiltonian and JW Terms

            // create the first hamiltonian from the YAML File
            var hamiltonian = FermionHamiltonian.LoadFromYAML($@"{FILENAME}").First();

            // convert the hamiltonian into it's JW Encoding
            var JWEncoding = JordanWignerEncoding.Create(hamiltonian);

            var data = JWEncoding.QSharpData(STATE);

            #endregion
            #region Hybrid Quantum/Classical accelerator
            // Feed created state and hamiltonian terms to VQE
            if (runString.Equals("VQE"))
            {
                Console.WriteLine("----- Begin VQE Simulation");
            }
            else
            {
                Console.WriteLine("----- Begin QE Simulation");
            }

            using (var qsim = new QuantumSimulator())
            {
                if (runString.Equals("VQE"))
                {
                    string useGroundState;
                    Console.Write("Use ground state? (yes or no): ");
                    useGroundState = Console.ReadLine();

                    var statePrepData = data.Item3; // statePrep data
                    var N             = statePrepData.Length;

                    double convertDoubleArrToJWInputStateArr(double[] x)
                    {
                        var JWInputStateArr = new QArray <JordanWignerInputState>();

                        for (int i = 0; i < N; i++)
                        {
                            var currJWInputState = statePrepData[i];
                            var positions        = currJWInputState.Item2;
                            JWInputStateArr.Add(new JordanWignerInputState(((x[i], 0.0), positions)));
                        }
                        return(Simulate_Variational.Run(qsim, data, 1.0, MOE, JWInputStateArr).Result);
                    }

                    Func <double[], double> Simulate_Wrapper = (double[] x) => convertDoubleArrToJWInputStateArr(x);

                    var solver = new NelderMead((int)N, Simulate_Wrapper);

                    // create initial condition vector
                    var initialConds = new double[N];
                    for (int i = 0; i < N; i++)
                    {
                        if (useGroundState.Equals("yes"))
                        {
                            var currJWInputState = statePrepData[i];
                            var groundStateGuess = currJWInputState.Item1;
                            initialConds[i] = groundStateGuess.Item1;
                        }
                        else
                        {
                            initialConds[i] = 0.0;
                        }
                    }

                    // Now, we can minimize it with:
                    bool success = solver.Minimize(initialConds);

                    // And get the solution vector using
                    double[] solution = solver.Solution;

                    // The minimum at this location would be:
                    double minimum = solver.Value;

                    Console.WriteLine($"Solution converged: {success}");
                    Console.WriteLine("The solution is: " + String.Join(" ", solution));
                    Console.WriteLine($"The minimum is: {minimum}");
                }
                else
                {
                    Console.WriteLine(Simulate.Run(qsim, data, 1.0, MOE).Result);
                }
            }
            #endregion
            #region Classical update scheme
            // Determine how to update the starting state using classical methods
            #endregion
        }
Example #13
0
        public void SubspaceTest1()
        {
            var function = new NonlinearObjectiveFunction(5, x =>
                10.0 * Math.Pow(x[0] * x[0] - x[1], 2.0) + Math.Pow(1.0 + x[0], 2.0));

            NelderMead solver = new NelderMead(function);

            solver.NumberOfVariables = 2;

            Assert.IsTrue(solver.Minimize());
            double minimum = solver.Value;
            double[] solution = solver.Solution;

            Assert.AreEqual(5, solution.Length);
            Assert.AreEqual(-0, minimum, 1e-6);
            Assert.AreEqual(-1, solution[0], 1e-3);
            Assert.AreEqual(+1, solution[1], 1e-3);

            double expectedMinimum = function.Function(solver.Solution);
            Assert.AreEqual(expectedMinimum, minimum);
        }
Example #14
0
        static void Main(string[] args)
        {
            // Prompts user whether to run naive eigensolver (QE)
            // or variational eigensolver (VQE)
            // QE will use the ground state provided in Broombridge file (FILENAME, see below)
            // VQE will give the user the option to use the ground state from Broombridge
            // as initial conditions, if not the initial conditions are all zero
            Console.Write("Run QE or VQE? ");
            String runString = Console.ReadLine();

            #region Parameters of Operation
            // filename of the molecule to be emulated
            var FILENAME = "h20_nwchem.yaml";

            // suggested state to include in JW Terms
            var STATE = "|G>";

            // the margin of error to use when approximating the expected value
            // note - our current code currently maxes the number of runs to 50
            // this is to prevent an exponential number of runs required given
            // an arbitrary small margin of error
            // if you'd like to change this parameter, feel free to edit the repeat/until loop
            // in the "FindExpectedValue" method
            var MOE = 0.1;

            #endregion

            #region Creating the Hamiltonian and JW Terms

            // create the first hamiltonian from the YAML File
            var hamiltonian = FermionHamiltonian.LoadFromYAML($@"{FILENAME}").First();

            // convert the hamiltonian into it's JW Encoding
            var JWEncoding = JordanWignerEncoding.Create(hamiltonian);

            // JW encoding data to be passed to Q#
            var data = JWEncoding.QSharpData(STATE);

            #endregion
            #region Hybrid Quantum/Classical accelerator

            // Communicate to the user the choice of eigensolver
            if (runString.Equals("VQE"))
            {
                Console.WriteLine("----- Begin VQE Setup");
            }
            else
            {
                Console.WriteLine("----- Begin QE Simulation");
            }

            using (var qsim = new QuantumSimulator())
            {
                // Block to run VQE
                if (runString.Equals("VQE"))
                {
                    string useGroundState;

                    // we begin by asking whether to use the YAML suggested ground or an ansatz
                    Console.Write("Use ground state? (yes or no): ");
                    useGroundState = Console.ReadLine();

                    // extract parameters for use below
                    var statePrepData = data.Item3;
                    var N             = statePrepData.Length;

                    // We'd like to have a method to create an input state given parameters
                    // method to convert optimized parameters, i.e. the
                    // coefficients of the creation/annihilation operators
                    // to JordanWignerInputStates that can be run in the
                    // simulation defined in Q#
                    double convertDoubleArrToJWInputStateArr(double[] x)
                    {
                        var JWInputStateArr = new QArray <JordanWignerInputState>();

                        for (int i = 0; i < N; i++)
                        {
                            var currJWInputState = statePrepData[i];
                            var positions        = currJWInputState.Item2; // registers to apply coefficients
                            JWInputStateArr.Add(new JordanWignerInputState(((x[i], 0.0), positions)));
                        }
                        return(Simulate_Variational.Run(qsim, data, MOE, JWInputStateArr).Result);
                    }

                    // wrapper function which feeds parameters to be optimized to minimize
                    // the output of the simulation of the molecule defined in FILENAME
                    Func <double[], double> Simulate_Wrapper = (double[] x) => convertDoubleArrToJWInputStateArr(x);

                    // create new Nelder-Mead solver on the simulation of the molecule
                    var solver = new NelderMead((int)N, Simulate_Wrapper);

                    // create initial condition vector
                    var initialConds = new double[N];
                    for (int i = 0; i < N; i++)
                    {
                        if (useGroundState.Equals("yes"))
                        {
                            var currJWInputState = statePrepData[i];
                            var groundStateGuess = currJWInputState.Item1;
                            initialConds[i] = groundStateGuess.Item1;
                        }
                        else
                        {
                            initialConds[i] = 0.0;
                        }
                    }

                    Console.WriteLine("----Beginning computational simulation----");

                    // Now, we can minimize it with:
                    bool success = solver.Minimize(initialConds);

                    // And get the solution vector using
                    double[] solution = solver.Solution;

                    // The minimum at this location would be:
                    double minimum = solver.Value;

                    // Communicate VQE results to the user
                    // success indicates wheter the solution converged
                    // solution is the vector of coefficients for the creation/annihilation
                    // operators defined in positions (defined in convertDoubleArrToJWInputStateArr)
                    // minimum is the value of the minimum energy found by VQE
                    Console.WriteLine($"Solution converged: {success}");
                    Console.WriteLine("The solution is: " + String.Join(" ", solution));
                    Console.WriteLine($"The minimum is: {minimum}");
                }
                else
                { // Run QE 5 times
                    Console.WriteLine(Simulate.Run(qsim, data, MOE, 5).Result);
                }
            }
            #endregion
        }
Example #15
0
        /// This function samples from parameter space using a Halton sequence and picks
        /// the model with best log-likelihood.
        /// Individual parameters are tagged as ParameterState.Locked, ParameterState.Free, or ParameterState.Consequential.
        /// Locked parameters are held at current values in optimization.
        /// Free parameters are optimized.
        /// Consequential parameters are computed as a function of other parameters and the data.
        public virtual void FitByMLE(int numIterationsLDS, int numIterationsOpt,
                                     double consistencyPenalty,
                                     Optimizer.OptimizationCallback optCallback)
        {
            thisAsMLEEstimable = this as IMLEEstimable;
            if (thisAsMLEEstimable == null)
            {
                throw new ApplicationException("MLE not supported for this model.");
            }

            int optDimension     = NumParametersOfType(ParameterState.Free);
            int numConsequential = NumParametersOfType(ParameterState.Consequential);
            int numIterations    = numIterationsLDS + numIterationsOpt;

            var trialParameterList = new Vector <double> [numIterationsLDS];
            var trialCubeList      = new Vector <double> [numIterationsLDS];

            var hsequence = new HaltonSequence(optDimension);

            if (optDimension == 0) // then all parameters are either locked or consequential
            {
                Vector <double> tparms = Parameters;
                Parameters = ComputeConsequentialParameters(tparms);
            }
            else
            {
                thisAsMLEEstimable.CarryOutPreMLEComputations();

                for (int i = 0; i < numIterationsLDS; ++i)
                {
                    Vector <double> smallCube = hsequence.GetNext();
                    Vector <double> cube      = CubeInsert(smallCube);
                    trialParameterList[i] = thisAsMLEEstimable.CubeToParameter(cube);
                    trialCubeList[i]      = cube;
                }

                var logLikes = new double[numIterationsLDS];

                //const bool multiThreaded = false;
                //if (multiThreaded)
                //{
                //    Parallel.For(0, numIterations,
                //                 i =>
                //                 {
                //                     Vector tparms = trialParameterList[i];
                //                     if (numConsequential > 0)
                //                     {
                //                         tparms = ComputeConsequentialParameters(tparms);
                //                         lock (trialParameterList)
                //                             trialParameterList[i] = tparms;
                //                     }

                //                     double ll = LogLikelihood(tparms);
                //                     if (optCallback != null)
                //                         lock (logLikes)
                //                             optCallback(tparms, ll,
                //                                         (int)(i * 100 / numIterations), false);

                //                     lock (logLikes)
                //                         logLikes[i] = ll;
                //                 });
                //}

                for (int i = 0; i < numIterationsLDS; ++i)
                {
                    Vector <double> tparms = trialParameterList[i];
                    if (numConsequential > 0)
                    {
                        tparms = ComputeConsequentialParameters(tparms);
                        trialParameterList[i] = tparms;
                    }

                    double ll = LogLikelihood(tparms, consistencyPenalty, false);
                    logLikes[i] = ll;

                    if (optCallback != null)
                    {
                        lock (logLikes)
                            optCallback(tparms, ll, i * 100 / numIterations, false);
                    }
                }

                // Step 1: Just take the best value.
                Array.Sort(logLikes, trialParameterList);
                Parameters = trialParameterList[numIterationsLDS - 1];

                // Step 2: Take some of the top values and use them to create a simplex, then optimize
                // further in natural parameter space with the Nelder Mead algorithm.
                // Here we optimize in cube space, reflecting the cube when necessary to make parameters valid.
                var simplex = new List <Vector <double> >();
                for (int i = 0; i <= optDimension; ++i)
                {
                    simplex.Add(
                        FreeParameters(thisAsMLEEstimable.ParameterToCube(trialParameterList[numIterationsLDS - 1 - i])));
                }
                var nmOptimizer = new NelderMead {
                    Callback = optCallback, StartIteration = numIterationsLDS
                };
                currentPenalty = consistencyPenalty;
                nmOptimizer.Minimize(NegativeLogLikelihood, simplex, numIterationsOpt);
                Parameters =
                    ComputeConsequentialParameters(
                        thisAsMLEEstimable.CubeToParameter(CubeFix(CubeInsert(nmOptimizer.ArgMin))));
            }

            LogLikelihood(null, 0.0, true);
        }