Создание матрицы 2D косинус-волн с коэффициентами и переменным количеством записей - PullRequest
1 голос
/ 26 апреля 2019

После того, как я вчера отправил этот вопрос , я понял, что хочу создать похожие матрицы разных n x n измерений с каждой записью формы

a * cos (j * x + k * y)

где a - вектор коэффициентов; а j, x, k и y - индексы от 0 до n - 1.

Если, например, n = 4,

>> n = 4;
>> x = 0:(n-1);
>> y = 0:(n-1);
>> [x,y] = meshgrid(x,y)
x =

   0   1   2   3
   0   1   2   3
   0   1   2   3
   0   1   2   3

y =

   0   0   0   0
   1   1   1   1
   2   2   2   2
   3   3   3   3

Результирующая матрица будет иметь 16 записей, которые могут быть вычислены функцией:

f = @(x, y,a0,a1,a2,a3,b0,b1,b2,b3,c0,c1,c2,c3,d0,d1,d2,d3)... 
a0*cos(0*x + 0*y) + a1*cos(0*x + 1*y) +...
a2*cos(0*x + 2*y) + a3*cos(0*x + 3*y) + ...
b0*cos(1*x + 0*y) + b1*cos(1*x + 1*y) + ...
b2*cos(1*x + 2*y) + b3*cos(1*x + 3*y) + ...
c0*cos(2*x + 1*y) + c1*cos(2*x + 1*y) + ...
c2*cos(2*x + 2*y) + c3*cos(2*x + 3*y) + ...
d0*cos(3*x + 1*y) + d1*cos(3*x + 1*y) + ...
d2*cos(3*x + 2*y) + d3*cos(3*x + 3*y)

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

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

1 Ответ

3 голосов
/ 26 апреля 2019

РЕДАКТИРОВАТЬ: Я отредактировал свой первоначальный ответ, добавив идею, приведенную в Комментарий Гийя .(Не видел этого в первую очередь ...) Пожалуйста, посмотрите обновленный код.


Снова ".Вы можете комбинировать анонимные функции / дескрипторы функций следующим образом:

f = @(x) sin(x);
g = @(x) cos(x);
h = @(x) f(x) + g(x);

Тем не менее, я предполагаю, что необходимо инкапсулировать настройку вашей функции (дескриптора) f в некоторую "настоящую" функцию MATLAB, см.следующий код:

function f = setupF(n, a)

  % Possibly, add some checks, e.g. for numel(a) == n^2, and so on.

  % Initialize function handle.  
  f = @(x, y) 0;
  ind = 0;

  % Iteratively add cosine parts. 
  for ii = 0:(n-1)
    for jj = 0:(n-1)
      ind = ind + 1;
      g = @(x, y) a(ind) * cos(ii * x + jj * y);
      f = @(x, y) f(x, y) + g(x, y); 
    end
  end

end

А вот и тестовый скрипт:

% Set up parameters.
n = 3;
a = reshape(1:n^2, n, n);

% Set up f(x, y) by function.
f = setupF(n, a);

% Set up f explicitly, as g(x, y). 
g = @(x, y) ...
  a(1) * cos(0*x + 0*y) + ...
  a(2) * cos(0*x + 1*y) + ...
  a(3) * cos(0*x + 2*y) + ...
  a(4) * cos(1*x + 0*y) + ...
  a(5) * cos(1*x + 1*y) + ...
  a(6) * cos(1*x + 2*y) + ...
  a(7) * cos(2*x + 0*y) + ...
  a(8) * cos(2*x + 1*y) + ...
  a(9) * cos(2*x + 2*y);

% Set up f(x, y) by vectorization, as h(x, y).
I = 0:(n-1);
J = 0:(n-1);
[I, J] = meshgrid(I, J);
h = @(x, y, n, a) sum(reshape(a .* cos(x * I + y * J), n^2, 1));
h = @(x, y, n, a) arrayfun(@(x, y) h(x, y, n, a), x, y);

% Set up test data.
x = linspace(0, 2*pi, 5);
y = linspace(0, 2*pi, 5);
[X, Y] = meshgrid(x, y);

% Compare outputs.
fRet = f(X, Y)
gRet = g(X, Y)
hRet = h(X, Y, n, a)

И вывод:

fRet =
   45.0000  -18.0000   15.0000  -18.0000   45.0000
   -6.0000   -5.0000   -2.0000    5.0000   -6.0000
   15.0000   -6.0000    5.0000   -6.0000   15.0000
   -6.0000    5.0000   -2.0000   -5.0000   -6.0000
   45.0000  -18.0000   15.0000  -18.0000   45.0000

gRet =
   45.0000  -18.0000   15.0000  -18.0000   45.0000
   -6.0000   -5.0000   -2.0000    5.0000   -6.0000
   15.0000   -6.0000    5.0000   -6.0000   15.0000
   -6.0000    5.0000   -2.0000   -5.0000   -6.0000
   45.0000  -18.0000   15.0000  -18.0000   45.0000

hRet =
   45.0000  -18.0000   15.0000  -18.0000   45.0000
   -6.0000   -5.0000   -2.0000    5.0000   -6.0000
   15.0000   -6.0000    5.0000   -6.0000   15.0000
   -6.0000    5.0000   -2.0000   -5.0000   -6.0000
   45.0000  -18.0000   15.0000  -18.0000   45.0000

И, конечно же, «векторизация»подход выигрывает с точки зрения производительности:

Output

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