Минимизация наименьших квадратов для нескольких переменных - PullRequest
0 голосов
/ 01 мая 2020

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

f = (1/a)*(asinh((Z(i)/b)^(1/c))^(-1)

, где i - индекс вектора Z. Вектор Z имеет 9 значений, указанных в задании. У меня также есть вектор с 9 значениями для s. Метод наименьших квадратов должен суммировать различия между значениями, вычисленными функцией f, со значениями из вектора s. Это должно выглядеть примерно так:

((s(i)-f(i))/s(i))^2

У меня также есть границы для значений a, b и c:

10e10>a>10e19, 10e-7>b>50, 10e-15>c>10.

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

Я пытался сделать что-то вроде этого:

function f=Fsigma(x, Z, sigma)
f=0;
for i=1:length(sigma)
    f=f+((sigma(i)-((1/x(1,:))*(asinh((Z(i)/x(2,:))^(1/x(3,:)))^(-1))))/sigma(i))^2
end
end

и вызвать эту функцию в lsqnonlin следующим образом:

Z= [1.49E+18 1.49E+19 1.49E+20 1.99E+15 1.99E+16 1.99E+17 1.49E+13 1.49E+14 1.49E+15];
sigma = [55.1705 79.1016 105.636 25.4809 40.8572 61.7238 12.8147 21.4054 34.8319];

a=linspace(10e10,10e19);
b=linspace(10e-7,50);
c=linspace(10e-15,10);
x=[a; b; c];
p=lsqnonlin(Fsigma(x,Z,sigma));

1 Ответ

1 голос
/ 02 мая 2020

ОК @ Агата, я подробно расскажу об этом go, чтобы вы могли изучить некоторые основы.

Во-первых, как передать функции в функции: дескрипторы функций ака. @ -оператор

fnc = @(x) Fsigma(x,Z,sigma);

fnc является объектом - фактически, он указывает на функцию Fsigma. Однако он даже затмевает дополнительные входные данные Fsigma, заявляя, что его единственный вход - x (это называется дескриптор анонимной функции , обозначенный (), между которыми вы определяете входы, которые может использовать кто-то, вызывающий fnc. Другие входные данные для Fsigma в этой строке являются значениями переменных, которые * имеют в этой строке .

границ Границы следует указывать в виде векторов:

% bounds
lb = [  10e10;
        10e-7;
        10e-15];
ub = [  10e19;
        50;
        10];

начальное предположение + вызов оптимизации если вы прочитали документы lsqnonlin, для этого требуется начальное предположение

% initial guess
x0 = ones(3,1);
% optimization call: x = lsqnonlin(fun,x0,lb,ub)
[p,fval] = lsqnonlin(fnc,x0,lb,ub)

Примечание к функции стоимости lsqnonlin будет лучше, если вы укажете не суммированную стоимость, а массив ошибок (снова см. Документы). Поэтому я корректирую вас Fsigma -функция

function f = Fsigma(x, Z, sigma)
f = ((sigma-((1/x(1))./ asinh((Z./x(2)).^(1/x(3)))) )./sigma).^2;
end

Если вы хотите использовать один выход - поскольку большинство алгоритмов оптимизации требуют от их функции стоимости - вы можете использовать fmincon

Посмотрите полный код

Z = [1.49E+18 1.49E+19 1.49E+20 1.99E+15 1.99E+16 1.99E+17 1.49E+13 1.49E+14 1.49E+15];
sigma = [55.1705 79.1016 105.636 25.4809 40.8572 61.7238 12.8147 21.4054 34.8319];

% bounds
lb = [  10e10;
        10e-7;
        10e-15];
ub = [  10e19;
        50;
        10];
% initial guess
x0 = ones(3,1);

% create an anyonymous function handle (using @(x)
fnc = @(x) Fsigma(x,Z,sigma);
% optimization call: x = lsqnonlin(fun,x0,lb,ub)
[p,fval] = lsqnonlin(fnc,x0,lb,ub);

% optimization call: x = fmincon(fun,x0,A,b,Aeq,beq,lb,ub)
fnc2 = @(x) sqrt(sum(fnc(x).^2));
[p2,fval2] = fmincon(fnc2,x0,[],[],[],[],lb,ub);


% cost function
function f = Fsigma(x, Z, sigma)
f = ((sigma-((1/x(1))./ asinh((Z./x(2)).^(1/x(3)))) )./sigma).^2;
end

PS: обратите внимание, что это сообщество не является сервисом кодирования, так что сделайте ваши чтения в следующий раз!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...