Минимизация приводит к ошибке типа: bound1Expr() отсутствуют 2 обязательных позиционных аргумента

#python #optimization #scipy

Вопрос:

При вызове функции optimization() , определенной как

 def optimization():
    bound1 = {
            'type': 'eq',
            'fun': bound1Expr}
    bound2 = {
            'type': 'eq',
            'fun': bound2Expr}
    optimizeResult = minimize(
                    toOptimize,
                    (0,0,0),
                    method = "SLSQP",
                    options = {'disp': False},
                    constraints = (
                            bound1,
                            bound2
                            )
                        )
    return optimizeResult.x

def bound1Expr(x,y,z):
    return x   y   z -1
    
def bound2Expr(x,y,z):
    return x^2   y^2   z^2 - 10

def toOptimize(x,y,z):
    return (x^2   y^2   z^2)**0.5 
 

Я получаю ошибку

 File "C:ProgramDataAnaconda3libsite-packagesscipyoptimizeslsqp.py", line 313, in <listcomp>
        for c in cons['eq']]))
    
TypeError: bound1Expr() missing 2 required positional arguments: 'y' and 'z'
 

Я просмотрел все источники, которые смог найти, с той же ошибкой, но все равно не знаю, что делать. Часто возникает ошибка, связанная с собственной переменной, но я здесь не имею дела с классами. И даже когда Self неявно добавляется к лямбда-функциям, я не знаю, почему это проблема, когда я все равно ее не использую.

Комментарии:

1. Внимательно прочитайте, что minimize говорится об аргументах целевой функции и функциях ограничений. Читайте документы, а не чужие проблемы в Интернете.

2. Я внимательно прочитал документы, но все еще озадачен. На подобные вопросы было много ответов, поэтому я предположил, что размещение такого вопроса не противоречит (неофициальным) рекомендациям stackoverflow.

3. Минимизация-это передача переменной x и (args,) переменной. Замените определение lambda функции, которое позволяет включать диагностические инструкции печати.

4. Спасибо вам за ваши советы. Я отредактировал свою проблему, чтобы сделать ее более понятной, и поместил некоторые инструкции печати как в bound1Expr, bound2Expr, так и в toOptimize. И все же ни одно из них не было печально напечатано.

5. minimize передает массив из 3 элементов, такой как ваше начальное значение (np.array([0,0,0])). Это одна переменная, а не 3.. Попробуй def bound1Expr(x)

Ответ №1:

Ваш код изменен, чтобы использовать один аргумент, а не 3. Я тоже перешел ^ к ** власти.

 In [105]: def optimization():
     ...:     bound1 = {
     ...:             'type': 'eq',
     ...:             'fun': bound1Expr}
     ...:     bound2 = {
     ...:             'type': 'eq',
     ...:             'fun': bound2Expr}
     ...:     optimizeResult = minimize(
     ...:                     toOptimize,
     ...:                     (0,0,0),
     ...:                     method = "SLSQP",
     ...:                     options = {'disp': False},
     ...:                     constraints = (
     ...:                             bound1,
     ...:                             bound2
     ...:                             )
     ...:                         )
     ...:     return optimizeResult.x
     ...: 
     ...: def bound1Expr(xyz):
     ...:     x,y,z=xyz
     ...:     return x   y   z -1
     ...: 
     ...: def bound2Expr(xyz):
     ...:     x,y,z=xyz
     ...:     return x**2   y**2   z**2 - 10
     ...: 
     ...: def toOptimize(*args):
     ...:     print('args',args)
     ...:     x,y,z=args[0]
     ...:     return (x**2   y**2   z**2)**0.5
     ...: 
In [106]: optimization()
args (array([0., 0., 0.]),)
args (array([1.49011612e-08, 0.00000000e 00, 0.00000000e 00]),)
args (array([0.00000000e 00, 1.49011612e-08, 0.00000000e 00]),)
args (array([0.00000000e 00, 0.00000000e 00, 1.49011612e-08]),)
Out[106]: array([0., 0., 0.])
 

Как toOptimize показано, minimize передает одно значение, массив в качестве аргумента (он передал бы больше, если бы вы указали args параметр). Этот массив содержит 3 элемента, соответствующих массиву начальных значений (кортежу).

Правильное определение функций часто является проблемой при использовании этих scipy функций. Пользователи игнорируют или не понимают документированное определение

 fun : callable
    The objective function to be minimized.

        ``fun(x, *args) -> float``

    where ``x`` is an 1-D array with shape (n,) and ``args``
    is a tuple of the fixed parameters needed to completely
 

Мой первый комментарий был ответом на ваш последний абзац о просмотре «источников». Похоже, вы искали в Интернете ошибки, связанные с отсутствующими или обязательными позиционными аргументами. Это довольно общая проблема. Да, часто это происходит, когда люди не учитывают self аргумент методов класса. Но здесь это не так, и, следовательно, поиск в Интернете непродуктивен.

Слишком часто (новые) пользователи обращаются к веб-поискам (или около того), когда они должны сначала проверить документацию. Есть место для веб-поиска (например, уникальная ошибка или очень актуальные версии ошибок), но для таких основных проблем с использованием, как это, вы должны сначала убедиться, что понимаете, как правильно использовать функцию.