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); }
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); }
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); }
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); }
/// <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); }
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); }
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); }
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); }
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); }
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 }
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 }
/// 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); }