MATLAB: эффективный способ запуска векторной входной функции с массивом входных данных


У меня есть функция HermitePCECoefficients, которая принимает в качестве входных данных несколько параметров, включая вектор столбца y, и выводит вектор столбца Coefficients, такой же длины, как y:

Coefficients=HermitePCECoefficients(grid,weights,indices,y,mu,sigma,normalized)
Теперь предположим, что y - это не вектор столбцов, а двумерный массив (матрица), и я хочу запустить HermitePCECoefficients на каждом из его столбцов, сохраняя соответствующие выходные данные в массиве. Делать это с помощью цикла for просто и понятно, но это занимает целую вечность:
Coefficients=zeros(size(y));
for i=1:size(y,2)
    Coefficients(:,i)=HermitePCECoefficients(grid,weights,indices,y(:,i),mu,sigma,normalized);
end

Таким образом, я поставил bsxfun на работу. Так как bsxfun только работая с двоичными функциями, я создал "фиктивную" двоичную функцию f, которая на самом деле является только функцией одного аргумента:

f=@(a,b) HermitePCECoefficients(grid,weights,indices,a,mu,sigma,normalized); 

Затем используется bsxfun таким образом:

Coefficients=bsxfun(f,y,omega_f);

Это прекрасно работает, и это намного быстрее, чем цикл for (Не беспокойтесь о omega_f, это просто вектор, длина которого соответствует количеству столбцов в y).

Вопрос 1: считаете ли вы, что это правильный способ использовать bsxfun в данном контексте?

Вопрос 2: возможно, лучшее решение было бы непосредственно модифицировать HermitePCECoefficients, чтобы он мог принять универсальный массив y в качестве входных данных. Внутри функции это единственная строка, которая требует, чтобы y был вектор столбца:

Coefficients(i)=dot(weights,y.*Psi)/norm;

weights и Psi - это два вектора столбцов, поэтому, если я передаю массив y, MATLAB жалуется. Есть предложения, как его изменить? Спасибо,

Серджио

2 3

2 ответа:

Вариант 2 кажется лучше (но только тестирование покажет). Просто замените

dot(weights,y.*Psi)/norm

By

sum(bsxfun(@times, weights.*Psi, y)/norm)

Или (вероятно, быстрее)

(weights.*Psi).'*y / norm
Любое из вышеперечисленных действий эквивалентно вычислению вектора [ dot(weights,y(:,1).*Psi)/norm, dot(weights,y(:,2).*Psi)/norm, ... ] для произвольного числа столбцов y. Каждая запись этого вектора является результатом для столбца y.

Вы можете использовать repmat на weights и Psi для репликации векторов по столбцам y:

nc = size(y,2);
Coefficients = dot(repmat(weights,1,nc), y.*repmat(Psi,1,nc))/norm;