2013-11-26 3 views
1

Этот код работает хорошо, пока количество символических входов в symEq является 2, что приводит к описатель функции с двумя параметрами, x(1), x(2):Как создать несколько неизвестных переменных в функции ручки для fminunc

syms A 
A = sym('A', [2 1]); 
b = [1 2;3 4]; 
c = [3 4]; 
range = [1 1]; 
symEq(A) = abs(sum(b*(A-c'))); 
Eq = @(x) double(symEq(x(1), x(2))); 
[X,Y] = fminunc(Eq,range) 

Но если символический вход в symEq будет изменен на 3, это приведет к ошибке, если я не изменю дескриптор функции, чтобы принять три параметра: x(1), x(2), x(3).

Однако мне нужно, чтобы число параметров было произвольным числом, скажем, 510, и дескриптор функции автоматически имел столько параметров: x(1), x(2), ... x(510), без необходимости вручную вводить 510 неизвестных переменных в код.

Как я могу это достичь?

+0

Помог ли мой ответ? –

ответ

2

Ну, есть много вещей, которые нужно сказать.

Прежде всего, зачем использовать символику, если то, что вы получаете, в конце концов, числовое? Matlab может выполнять символические вычисления, но он превосходит численные значения, особенно в линейной алгебре. Другие второстепенные вещи: значение, которое вы даете A, не используется, потому что A позже появляется только как параметр, range является неправильным произношением, так как на самом деле это начальное значение A0 для fminunc, чтобы найти минимум, а Eq - фактически функция.

Что еще более важно, хотя, нет необходимости для обозначения элементов x (что на самом деле A) отдельно - матрица является естественной единицей для вычислений в Matlab.

Изменение всех этих вещей дает:

b = [1 2; 3 4]; 
c = [3 4]; 
A0 = [1 1]; 
fun = @(A) abs(sum(b * (A - c)')); 
[X, Y] = fminunc(fun, A0) 

В этой форме, расширение кода для более высоких размерностей тривиальна: Вы просто должны установить соответствующим образом параметры b и c, а также начальное значение A0. Для трех измерений, например:

b = [1 2 3; 4 5 6; 7 8 9]; 
c = [3 4 5]; 
A0 = [1 1 1]; 
fun = @(A) abs(sum(b * (A - c)')); 
[X, Y] = fminunc(fun, A0) 

И для 510 измерений, используя случайным образом инициализированы параметры только в качестве примера:

b = rand(501, 501); 
c = rand(1, 501); 
A0 = ones(1, 501); 
fun = @(A) abs(sum(b * (A - c)')); 
[X, Y] = fminunc(fun, A0) 

Но есть больше: Минимизация модуль функции эквивалентна минимизации его площадь:

fun = @(A) (sum(b * (A - c)')) .^ 2; 

Это простая проблема с наименьшими квадратами и использование fminunc для этого излишне. Более того, в этом конкретном случае найденное решение всегда имеет значение функции 0, что достигается, если A - c равно нулю. Таким образом, вся минимизация сводится к:

A = c; 
Смежные вопросы