Кадрирование функции наименьших квадратов с использованием fmin_slsqp

StackOverflow https://stackoverflow.com/questions/19850455

Вопрос

Я новичок в оптимизации. Я пытаюсь решить линейную проблему наименьших квадратов, используя fmin_slsqp функционировать в scipy.optimize.

У меня есть объективная функция как Норма Фросениуса |q0_T*P-q1_T| квадрат, где q0_T это транспонирование nX1 вектор и P является nXn Матрица и q1_T является транспонированием nX1 вектор. Это в основном процесс Маркова с q векторы как вероятность быть в состоянии и P быть матрицей вероятностей перехода.

Целевая функция будет минимизирована WRT P где ограничения:

1) Все элементы в P Должен быть неотрицательным

2) Все ряды в P должен суммировать до 1

Я определил эту целевую функцию, которую я не уверен, верна:

def func(P, q):
  return (np.linalg.norm(np.dot(transpose(q[0,]),P)-transpose(q[1,])))**2

Второй аргумент в FMIN_SLSQP запрашивает 1D NDARRAY X0, который является первоначальным предположением для независимой переменной. Но здесь, поскольку моя независимая переменная будет P, мне понадобится 2D -массив для моего первоначального предположения. Я не уверен, правильно ли я создаю проблему, или мне придется использовать другую функцию. Спасибо.

Это было полезно?

Решение

Таким образом, есть проблема в том, что он принимает только 1D -массив в качестве независимой переменной, одно хакерское решение будет пройти его как 1D и изменить функцию.

import numpy as np
from scipy.optimize import fmin_slsqp

# some fake data
d = 3 # dimensionality of the problem
P0 = np.arange(d*d).reshape(d, d)
P0 /= P0.sum(1, keepdims=True) # so that each row sums to 1
q = np.random.rand(2, d)       # assuming this is the structure of your q
q /= q.sum(1, keepdims=True)

# the function to minimize
def func(P, q):
    n = q.shape[-1] # or n = np.sqrt(P.size)
    P = P.reshape(n, n)
    return np.linalg.norm(np.dot(q[0], P) - q[1])**2  # no changes here, just simplified syntax

def row_sum(P0, q):
    """ row sums - 1 are zero """
    n = np.sqrt(P0.size)
    return P0.reshape(n,n).sum(1) - 1.

def non_neg(P0, q):
    """ all elements >= 0 """
    return P0

P_opt = fmin_slsqp(func, P0.ravel(), args=(q,), f_eqcons=row_sum, f_ieqcons=non_neg).reshape(d, d)

assert np.allclose(P_opt.sum(1), 1)
assert np.all(P_opt >= 0)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top