scipy.optimize.minimize и Minuit, возвращающие начальное значение догадки - PullRequest
2 голосов
/ 26 февраля 2020

У меня проблемы с scipy.minimize.optimize. Вот мой код.

from time import process_time 
import numpy as np
from scipy.optimize import minimize
class NMin(object):
    def __init__(self, error):
        self.error=error

    def func(self, N):
        i = np.arange(1, N+1)
        f = np.abs(np.sum(4/(N*(1+((i - 0.5)/N)**2))) - np.pi)-self.error
        return(f)

    def nMin(self):
        x0 = 1
        nMin = minimize(self.func, x0)
        return(nMin.x)


def main():
    t1_start = process_time()
    error=10**(-6)
    nMin = NMin(error).nMin()
    print("the minimum value of N is: " + str(nMin))
    t1_stop = process_time() 
    print("Elapsed time during the whole program in seconds:", 
                                         t1_stop-t1_start)

main ()  

Я пытаюсь минимизировать функцию func(x) относительно N, чтобы найти минимум N, но NMin(error).nMin(), похоже, возвращает x0 = 1, а не минимум N. Вот мой вывод.

the minimum value of N is: [1.]
Elapsed time during the whole program in seconds: 0.015625

Я действительно обеспокоен этим, так как не могу найти проблему и не понимаю, почему scipy.optimize не работает.

1 Ответ

2 голосов
/ 08 марта 2020

scipy.optimize.minimize в основном используется для непрерывных дифференцируемых функций. Использование arange в забаве c делает из этого отдельную проблему. Это вызывает большие скачки в градиенте из-за этих разрывов (см. Рисунок ниже).

Я добавил отладочную печать:

from time import process_time
import numpy as np
from scipy.optimize import minimize
class NMin(object):
    def __init__(self, error):
        self.error=error

    def func(self, N):
        print("func called N = {}".format(N))
        i = np.arange(1, N+1)
        print("i = {}".format(i))
        f = np.abs(np.sum(4/(N*(1+((i - 0.5)/N)**2))) - np.pi)-self.error
        print("f = {}".format(f))
        return(f)

    def nMin(self):
        x0 = 1
        nMin = minimize(self.func, x0)
        return(nMin.x)


def main():
    t1_start = process_time()
    error=10**(-6)
    nMin = NMin(error).nMin()
    print("the minimum value of N is: " + str(nMin))
    t1_stop = process_time()
    print("Elapsed time during the whole program in seconds:",
                                         t1_stop-t1_start)

main()

В результате:

func called N = [1.]
i = [1.]
f = 0.05840634641020706
func called N = [1.00000001]
i = [1. 2.]
f = 1.289175555623012

Может быть, вы хотели бы использовать другой решатель, более подходящий для дискретных задач, или изменить свою цель, чтобы обеспечить условие преемственности для градиентной оптимизации.

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...