Вы можете создать анонимную функцию, которая фиксирует значение первого и третьего элементов.Вам также нужно настроить начальные точки (2-й аргумент) и верхнюю и нижнюю границы так, чтобы они применялись только ко 2-му элементу, например,
a = lsqcurvefit( @(x, xdata) myfun([a0(1); x; a0(3)], xdata), a0(2), x, y, ...
lb(2), ub(2), curvefitoptions );
Вы можете легко изменить это, чтобы исправить 2-ю и 3-юэлементы, например,
a = lsqcurvefit( @(x, xdata) myfun([x; a0(2); a0(3)], xdata), a0(1), x, y, ...
lb(1), ub(1), curvefitoptions );
Или исправить только 2-й элемент
a = lsqcurvefit( @(x, xdata) myfun([x(1); a0(2); x(2)], xdata), a0([1,3]), x, y, ...
lb([1,3]), ub([1,3]), curvefitoptions );
Чтобы сделать это в общем, начните с определения следующей (или аналогичной) функции
function a = interlace( a, x, fix )
a(~fix) = x;
end
Затем вы можете заменить код, подобный [a0(1); x; a0(3)]
в приведенных выше примерах, на вызов interlace()
.Например,
fix = [1; 0; 1];
a_free = lsqcurvefit( @(x, xdata) myfun( interlace( a0, x, fix ), xdata), ...
a0(~fix), x, y, lb(~fix), ub(~fix), curvefitoptions );
a = interlace( a0, a_free, fix );
Мое тестирование этого ограничено следующим кодом:
%% A function
myfun = @(x, xdata) x(1) + x(2)*xdata + x(3)./xdata;
%% Some Data
x = [0.036;0.14;0.42;0.49;0.66;0.68;0.76;0.79;0.8;0.85;0.92;0.93;0.96];
y = [0.83;1;0.66;0.53;0.58;0.6;0.64;0.62;0.62;0.55;0.41;0.39;0.33];
%% Initial conditions
a0 = [1; 2; 3];
%% Bounds
lb = [-1; -2; -3];
ub = [0.1; 0.2; 0.3];
%% Fitting options
curvefitoptions = optimset( 'Display', 'iter' );
%% Fit all three parameters
a = lsqcurvefit( myfun, a0, x, y, lb, ub, curvefitoptions )
%% Fix some parameters
fix = [1; 0; 1];
a_free = lsqcurvefit( @(x, xdata) myfun( interlace( a0, x, fix ), xdata), ...
a0(~fix), x, y, lb(~fix), ub(~fix), curvefitoptions );
a = interlace( a0, a_free, fix );