Сципи Минимизировать и np.linlag.norm - PullRequest
0 голосов
/ 30 апреля 2020

Я впервые задаю вопрос здесь, поэтому, пожалуйста, потерпите меня. Теперь я «играл» с функцией минимизации и наткнулся на что-то странное.

Настройка проста, все, что я хочу сделать, это минимизировать евклидову норму вида:

sqrt [(x1 -a1) ^ 2 + (x2 -a2) ^ 2 + (x3 -a3) ^ 2 + (x4 -a4) ^ 2]

Где x - переменные, а a - фиксированные числа, константы. Конечно, решение простое, xi = ai для i = 1,2,3,4; и значение функции равно нулю.

Теперь, когда я делаю этот код в python, все работает отлично:

import numpy as np
from scipy.optimize import minimize

def w(x):
    a = np.array([[0,1,1,0]]).T
    return np.sqrt((x[0]-a[0])**2 + (x[1]-a[1])**2 + (x[2]-a[2])**2+(x[3]-a[3])**2)

np.random.seed(1)
x0 = np.random.random((4,1))

min_fun1 = minimize(w,x0,method='nelder-mead',options={'xatol': 1e-8, 'disp': True})
print(min_fun1.fun)
print(min_fun1.x)

Как я уже сказал, это работает просто отлично. Значение функции равно нулю и xi = ai. Но когда я пытаюсь установить проблему с помощью функции np.linlag.norm, это становится странным. Например, когда я запускаю этот код:

def y(x):
    a = np.array([[0,1,1,0]]).T
    return np.linalg.norm(x-a)

min_fun0 = minimize(y,x0,method='nelder-mead',options={'xatol': 1e-8, 'disp': True})
min_fun0.fun
min_fun0.x

Похоже, что оптимизация застревает, значение функции равно 2 и xi = 0,5, что, очевидно, неверно.

Более того, если я попытаюсь сделать это с помощью скалярного произведения, результат будет другим, но все же неправильным:

def v(x):
    a = np.array([[0,1,1,0]]).T

    return np.sqrt(np.dot((x-a).T,(x-a)))

min_fun2 = minimize(v,x0,method='nelder-mead',options={'xatol': 1e-8, 'disp': True})
min_fun2.fun
min_fun2.x

Что я смог понять, так это то, что он как-то связан с «типом» объекта. Например, no.linalg.norm возвращает float64, и для примера, который работает, это ndarray с размером 1. Поэтому я меняю «тип» для результата no.linalg.norm, чтобы он соответствовал ndarray размеру 1, но проблема остается.

1 Ответ

0 голосов
/ 30 апреля 2020

Похоже, вы пытаетесь минимизировать массив 1d, но np.array([[0,1,1,0]]) на самом деле 2d (форма (1, 4)).

Если вы преобразуете свой массив в 1d, минимизация будет работать:

def y(x):
    a = np.array([0,1,1,0])
    return np.linalg.norm(x-a)

min_fun0 = minimize(y,x0,method='nelder-mead',options={'xatol': 1e-8, 'disp': True})
min_fun0.fun
min_fun0.x
>>> array([-1.87741758e-09,  1.00000000e+00,  1.00000000e+00, -3.04858536e-09])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...