2

I'm trying to run a basin-hopping simulation 3 times and save each tuple of x and f(x) into an array of 1x2, below code is my best attempt so far. I don't need detailed information on results, just tuples in numbers, how can I get such an array in a way that I can also use them for further process (select the minimum of different runs for example)

from math import *
from math import ceil
from math import floor
import time
from decimal import *
import numpy as np
from scipy.optimize import basinhopping
minimizer_kwargs = {"method": "BFGS"}

def f(x):

    b = 5306246123
    estimator1=(sqrt(b)+x[0])
    estimator2=(sqrt(b)+x[1])
    d=abs(estimator1*estimator2-b)
    return d

b = 5306246123

results = []
for x in range(3): results.append(basinhopping(f, [1,1], minimizer_kwargs=minimizer_kwargs,
niter=1000, stepsize=sqrt(sqrt(b))))
print(results)

part of (1/3) example output (I only need -6403.48941568, 7020.65333737 and 2 other instance of this tuple for example):

[                        fun: 2.86102294921875e-06
 lowest_optimization_result:       fun: 2.86102294921875e-06
 hess_inv: array([[ 0.13347587, -0.13347587],
       [-0.13347587,  0.13347587]])
      jac: array([ 79872.,  66432.])
  message: 'Desired error not necessarily achieved due to precision loss.'
     nfev: 463
      nit: 2
     njev: 113
   status: 2
  success: False
        x: array([-6403.48941568,  7020.65333737])
                    message: ['requested number of basinhopping iterations completed successfully']
msalperen
  • 135
  • 8
  • I don't quite understand, what structure is the result? if the result is a dictionary, can't you just do `results.append(basinhopping(...)['x'])`? – user2464424 Jul 26 '17 at 18:59
  • What about `[r.x for r in results]`? Or `results.append(basinhopping(...).x)`? – Roland W Jul 26 '17 at 18:59
  • user2464424, thanks it worked, now the output is like: [array([-4813.75229033, 5154.36866417]), array([ -9068.45177035, 10357.92460721]), array([ 7749.21249951, -7004.1087393 ])] How can I access these arrays individually or process (i.e.sort) them? – msalperen Jul 26 '17 at 19:05
  • @msalperen you have put them into a list so access them as usual via the index, therefore with `results[0]`, `results[1]` or `results[2]`. if you want to step through the results, do `for item in results:` – user2464424 Jul 26 '17 at 19:10
  • check this question for sorting lists of lists: https://stackoverflow.com/questions/4174941/how-to-sort-a-list-of-lists-by-a-specific-index-of-the-inner-list – user2464424 Jul 26 '17 at 19:11
  • @user2464424, thanks again I was trying for example: print(results[0][1],results[1][1]) and it worked. – msalperen Jul 26 '17 at 19:14
  • @user2464424, Is there a way to append two values? something like (['fun'],['x'])? – msalperen Jul 31 '17 at 19:17

1 Answers1

1

I'll put the solution in an self-contained answer.

Because the result of the basinhopping() function is a subclass of dict, its elements can be accessed like in any dictionary using the square bracket notation. For example:

results.append(basinhopping(...)['x'])

Once all the results are saved in the results list, they can be accessed like in any list via their zero-based index. To get the second element of the first result:

results[0][1]
user2464424
  • 1,536
  • 1
  • 14
  • 28