Найти матрицу, удовлетворяющую условиям - PullRequest
2 голосов
/ 04 февраля 2020

Я пытаюсь решить следующую проблему в MATLAB, но не знаю, какую команду использовать.

Найти матрицу B, st A * B = I и 0 <= B * a <= b </p>

Где A и B - матрицы, а a и b - векторы. Я это тождественная матрица.

Есть идеи, что использовать? fsolve не сработало, и я не знаю, как сформулировать это в linprog.

Пример:

A = [1 0 -1; 0 1 1];
a = [8; 6];
b = [15; 10; 10];

Решение с использованием cvx:

cvx_begin
variable B(3,2)
min (B)
subject to
    A*B == diag(ones(2,1));
    0 <= B*a;
    b >= B*a;
cvx_end

Ответы [ 2 ]

3 голосов
/ 04 февраля 2020

Чтобы решить эту проблему с linprog, вам нужно перечислить:

  • Соотношения
  • Неравенства

Итак, у нас есть шесть неизвестные:

B = [x1 x2
     x3 x4
     x5 x6]

Неравенства составляют:

enter image description here

и

enter image description here

В формате, поддерживаемом linprog (A*x <= b), что дает нам:

A = [8  6  0  0  0  0
     0  0  8  6  0  0
     8  6  0  0  8  6
    -8 -6  0  0  0  0
     0  0 -8 -6  0  0
     0  0  0  0 -8 -6];

b = [15 10 10 0 0 0]

заметил, что для преобразования >=0 в <=0 умножили обе стороны на -1.

Соотношения:

enter image description here

В формат поддерживается linprog (Aeq*x == beq), что дает нам:

Aeq = [1  0  0  0 -1  0
       0  1  0  0  0 -1
       0  0  1  0  1  0
       0  0  0  1  0  1]

beq = [1 0 0 1]

Мы можем считать, что все переменные имеют одинаковый «вес», наша целевая функция может быть определена как f = [1 1 1 1 1 1]. Но это также будет работать (и предоставит другое решение), если вы измените эти веса. Вы можете видеть это как форму вашего 6D-пространства, где некоторое измерение можно сжать или растянуть (но не согнуть). Например, f = [1 0.25 1 1 -1 1/2] также является опцией ...

f = [1 1 1 1 1 1] %which correspond to [x1 x2 x3 x4 x5 x6]

s = linprog(f, A,b,Aeq,beq,-10,10) %solve the problem with arbitrary lower and upper boundary.

Один возможный результат:

s = [ 10
     -12 
      9
      13 
      9 
     -12]

, который дает:

B = [10 -12
     9   13
     9   -12]

Автоматизация для больших задач:

% B Matrix size
s1 = 3;
s2 = 2;

% Variable
A  = [1 0 -1; 0 1 1];
B  = sym('X', [s1 s2])
ax = [8; 6];
bx = [15; 10; 10];

% Convert linear equations to matrix form
[Aeq,beq] = equationsToMatrix(A*B == eye(s2))
[A1,b1]   = equationsToMatrix(B*ax == bx)
[A2,b2]   = equationsToMatrix(-B*ax == 0)

% Solve the problem
%      (      f      ,          A            ,            b           ,       Aeq  ,      beq  ,  lb,ub)
linprog(ones(s1*s2,1),[double(A1);double(A2)], [double(b1);double(b2)], double(Aeq),double(beq), -10,10)
0 голосов
/ 04 февраля 2020

Вот две разные ситуации, с которыми вы можете столкнуться:

  • С вашим ограничением равенства

    A * B = I

Я думаю, что вы уже можете решить B, используя обратную матрицу Мура-Пенроуза матрицы, т. Е. pinv (в MATLAB) или ginv (в R):

B = pinv(A);

или

B <- ginv(A)

В связи с уникальностью обратного Мура-Пенроуза, вам необходимо проверить решенное B для условия

0 <= B * a <= b </p>

  • Если ограничение неравенства нарушается при использовании метода, описанного выше, то вы можете попробовать метод ниже (загрузить CVX в MATLAB ИЛИ CVXR в R):

К сожалению, у меня нет компьютера MATLAB, но я пробовал CVXR с языком R, который хорошо работает. Возможно, вам нужны незначительные синтаксические адаптации или переводы в версию MATLAB.

Вот пример, показывающий, как сформулировать проблему:

# given matrices
A <- matrix(c(1,0,-1,0,1,1),nrow = 2,byrow = TRUE)
a <- matrix(c(8,6))
b <- matrix(c(15,10,10))

# formulate optimization problem and solve it
library(CVXR)
B <- Variable(3,2)
obj <- Minimize(norm(A%*%B - diag(c(1,1)),"2"))
cons <- list(B%*%a >= 0, b>=B%*%a )
problem <- Problem(obj,cons)
res <- solve(problem)

такой, что

> res$getValue(B)
            [,1]      [,2]
[1,]  0.90183254 0.6467117
[2,]  0.09816746 0.3532883
[3,] -0.09816746 0.6467117
...