MATLAB, оптимизирующий вызовы функции подгонки

У меня есть трехмерный массив размеров (строки x столбцы x 8). Для каждого элемента в первых двух измерениях у меня есть 8 значений в третьем измерении, которые я должен подогнать под такое уравнение, как экспоненциальное, полиномиальное и т. д. Я написал код для этой функции, и в настоящее время я получаю результат, перебирая первые два измерения, как показано ниже:

for i=1:rows
    for j=1:cols
        outputArray(i,j) = functionHandle(inputArray(i,j,1:8));
    end
end

Могу ли я каким-то образом использовать bsxfun, arrayfun или какой-либо другой метод векторизации, чтобы избавиться от циклов for, чтобы я генерировал свой вывод, используя что-то вроде этого?

outputArray = bsxfun(@functionHandle,inputArray)

Добавление дескриптора функции

function output = functionHandle(xData,yData)
    ft = fittype( 'a*exp(-b*x)+c','independent', 'x','dependent','y' );
    opts = fitoptions( 'Method', 'NonlinearLeastSquares' );
    opts.Algorithm = 'Trust-Region';
    opts.Display = 'Off';
    opts.MaxFunEvals = 100;
    opts.MaxIter = 100;
    opts.Robust = 'LAR';
    opts.Lower = [-Inf 0 -Inf];
    opts.StartPoint = [0.35 0.05 0.90];

    % Fit model to data.
    [FitResult,~] = fit(xData,yData,ft,opts);
    output = FitResult.a;
end

person Rohit    schedule 09.07.2020    source источник
comment
Ответ полностью зависит от того, векторизована ли ваша функция (functionHandle) или нет. Вы должны написать эту функцию так, чтобы она допускала ввод RxCx8 и выдавала вывод RxCxN, где N — количество подходящих параметров. То есть векторизация должна выполняться внутри функции; это не может быть сделано снаружи. Извне вы можете использовать функцию только в цикле. Обратите внимание, что arrayfun похож и имеет сравнимую производительность с циклом for.   -  person Luis Mendo    schedule 09.07.2020
comment
Вот чего я боялся. Тем не менее, как бы вы векторизовали это? Мне нужно было бы вызвать некоторую подходящую функцию RxC раз, и единственный способ, который я могу придумать, - это использовать цикл for. Если вы опубликуете это как ответ, я приму это.   -  person Rohit    schedule 10.07.2020
comment
Единственный способ, который я вижу, - это изменить внутреннюю работу functionHandle, которая, как я полагаю, является написанной вами функцией. Вы должны объяснить, что делает эта функция, возможно, опубликовать (соответствующую часть) ее текущий код, и, возможно, кто-то сможет найти способ его векторизации.   -  person Luis Mendo    schedule 10.07.2020
comment
Я добавил фрагмент кода functionHandle. Большое спасибо. Кроме того, извините, я имел в виду, что если вы опубликуете свой первый комментарий в качестве ответа, я приму его, поскольку это отвечает на вопрос, который я изначально задал, и на самом деле я не понимаю, как я могу векторизовать functionHandle.   -  person Rohit    schedule 10.07.2020
comment
Ах хорошо. Я опубликую это тогда. Поскольку вы используете fit, похоже, вы не можете векторизовать, потому что fit принимает один набор входных данных за раз и создает соответствующий вывод.   -  person Luis Mendo    schedule 10.07.2020
comment
Вы хотите векторизовать это, потому что это узкое место в вашем коде, или потому что вы слышали, что циклы в MATLAB медленные? Циклы были медленными 20 лет назад, но эта идея каким-то образом все еще сохраняется.   -  person Cris Luengo    schedule 10.07.2020
comment
Это узкое место производительности в моем коде. Мой inputArray на самом деле является изображением, и мне нужна выходная карта, представляющая коэффициент. Даже относительно маленькое изображение 256x256 вычисляется примерно за 2 часа, а у меня есть изображения 1024x1024, которые также нужно запустить.   -  person Rohit    schedule 10.07.2020
comment
Затем, возможно, измените свою функцию подбора: вы используете нелинейный метод наименьших квадратов и ряд опций, которые (на мой неподготовленный взгляд) кажутся довольно дорогими. Кроме того, использование анонимной функции вместо строки, вероятно, будет более эффективным: ft = fittype(@(a,b,c,x) a*exp(-b*x)+c).   -  person Cris Luengo    schedule 10.07.2020


Ответы (1)


Ответ полностью зависит от того, векторизована ли ваша функция или нет. Что вам нужно сделать, так это написать эту функцию так, чтобы она допускала ввод R×C×8 и выдавала вывод R×C×N, где N — количество подходящих параметров.

То есть векторизация должна выполняться внутри функции; это не может быть сделано снаружи. Извне вы можете использовать функцию только в цикле. Обратите внимание, что arrayfun похож и имеет сравнимую производительность с < цикл href="https://www.mathworks.com/help/matlab/ref/for.html" rel="nofollow noreferrer">for.

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

person Luis Mendo    schedule 10.07.2020