Простой способ кусочно подогнать в Matlab разрывную функцию с различным количеством особенностей

У меня есть некоторые прерывистые данные, которые я хочу кусочно подогнать все сразу, поскольку есть один параметр подгонки, общий для всех частей функции. Количество разрывов и их места различны.

Я подумал об использовании класса и хранении индексов разрыва в качестве элемента данных, а затем использовании функции-члена с различным количеством входных данных в качестве функции, которую я отправляю в функцию соответствия Matlab.

e.g.

function f = approximate(obj,varargin)
        f = zeros(size(varargin{1}));
        for i = 1:nargin-3
            x = varargin{1}(obj.segmentStartIdx(i):obj.segmentEndIdx(i));
            f(obj.segmentStartIdx(i):obj.segmentEndIdx(i)) = varargin{2} + (0.25*(1-x/varargin{i+2}).^-2+x/varargin{i+2}-0.25);
        end
    end

Судя по всему, это не работает... Использование fit с

fittype = ('fp.approximate(x,A,B,C)');

Matlab выдает следующую ошибку:

Error using fittype/testCustomModelEvaluation (line 12)
Expression fp.approximate(x,A,B,C) is not a valid MATLAB expression, has non-scalar coefficients, or cannot be evaluated:
Error in fittype expression ==> fp.approximate(x,A,B,C)
??? Attempt to reference field of non-structure array.
Error in fittype>iCreateFittype (line 371)
    testCustomModelEvaluation( obj );

Error in fittype (line 328)
                obj = iCreateFittype( obj, varargin{:} );

Error in fit>iFit (line 157)
    model = fittype( fittypeobj, 'numindep', size( xdatain, 2 ) );

Error in fit (line 108)
[fitobj, goodness, output, convmsg] = iFit( xdatain, ydatain, fittypeobj, ...

Caused by:
    Error using fittype/evaluate (line 102)
    Error in fittype expression ==> fp.approximate(x,A,B,C)
    ??? Attempt to reference field of non-structure array.

Попытка использования функции, не являющейся членом, не устранила проблему, хотя я не уверен, что делаю неправильно... Я упростил это до следующей функции:

function [ f ] = moreArgTestFunc( p, xData )
f = zeros(size(xData));
global segmentStartIdx;
global segmentEndIdx;
for i = 1:length(p)-1
    x = xData(segmentStartIdx(i): segmentEndIdx(i));
    f(segmentStartIdx(i):segmentEndIdx(i)) = p(1) + (0.25*(1-x/p(i+1)).^-2+x/p(i+1)-0.25);
end
end

Попытка использовать его в NonLinearModel.fit или nlfit приводит к следующей ошибке:

Error using moreArgTestFunc (line 2)
Not enough input arguments.

Так что, возможно, я что-то упускаю здесь...

Есть ли лучший способ сделать это?


person Mr.WorshipMe    schedule 07.10.2015    source источник


Ответы (1)


При вызове NonLinearModel.fit, fitnlm или lsqcurvefit необходимо передать указатель функции в качестве параметра. Я думал, что передачи имени функции достаточно, но, видимо, это не так. Использование анонимной функции

funcToFit = @(p,x) myfunctionName(p,x)

а затем передать funcToFit вместо myfunctionName, поскольку аргумент решает проблему.

Различное количество подходящих параметров было решено с использованием вектора переменного размера для p.

person Mr.WorshipMe    schedule 08.10.2015