2012-05-19 3 views
0

С помощью следующих переменных:Вычислить каверзный сумму в Matlab

m = 1:4; n = 1:32; 
phi = linspace(0, 2*pi, 100); 
theta = linspace(-pi, pi, 50); 

S_mn = <a 4x32 coefficient matrix, corresponding to m and n>; 

Как рассчитать сумму по м и п из S_mn*exp(1i*(m*theta + n*phi)), т.е.

$\sum_m \sum_n S_mn exp(i(m\theta+n\phi))

Я думал о таких вещах, как

[m, n] = meshgrid(m,n); 
[theta, phi] = meshgrid(theta,phi); 
r_mn = S_mn.*exp(1i*(m.*theta + n.*phi)); 
thesum = sum(r_mn(:)); 

но это требует theta и phi иметь такое же количество элементов, как m и n, и это дает мне только один элемент в ответ - я хочу матрицу с размером meshgrid(theta,phi), независимо от размеров theta и phi (т.е. Я хочу иметь возможность оценить сумму как функцию theta и phi).

Как это сделать в MATLAB?

ответ

1

Поскольку я не знаю, что S является ...

S = randn(4,32); 

[m,n] = ndgrid(1:4,1:32); 
fun = @(theta,phi) sum(sum(S.*exp(sqrt(-1)*(m*theta + n*phi)))); 

отлично работает для меня.

fun(pi,3*pi/2) 
ans = 
      -15.8643373238676 -  1.45785698818839i 

Если теперь вы хотите сделать это для большого набора значений фи и тета, пара петель теперь тривиальное решение. Или вы можете сделать все это в одном вычислении, хотя массивы будут больше. Все еще не сложно. WTP?

Вы понимаете, что и meshgrid, и ndgrid принимают не только два аргумента? Итак, пришло время узнать, как использовать bsxfun, а затем сжать.

[m,n,theta,phi] = ndgrid(1:4,1:32,linspace(-pi, pi, 50),linspace(0, 2*pi, 100)); 
res = bsxfun(@times,S,exp(sqrt(-1)*(m.*theta + n.*phi))); 
res = squeeze(sum(sum(res,1),2)); 

Или сделайте это, что будет немного быстрее. Предыдущее вычисление заняло мою машину .07 секунд. Это последнее заняло 0,05, поэтому можно сэкономить, используя bsxfun.

m = (1:4)'; 
n = 1:32; 
[theta,phi] = ndgrid(linspace(-pi, pi, 50),linspace(0, 2*pi, 100)); 
theta = reshape(theta,[1,1,size(theta)]); 
phi = reshape(phi,size(theta)); 
res = bsxfun(@plus,bsxfun(@times,m,theta*sqrt(-1)),bsxfun(@times,n,phi*sqrt(-1))); 
res = bsxfun(@times,S,exp(res)); 
res = squeeze(sum(sum(res,1),2)); 

Если вам нужно сделать выше 2000 раз, то это займет 100 секунд. WTP? Выпейте кофе и расслабьтесь.

+0

Я собираюсь сделать это для высоких высоких разрешений в '' phi' и theta' по всему диапазону [- pi, pi] x [0, 2pi], для 2000 временных меток. Мне нужна более высокая производительность, чем эта. –

+0

Возможно, если бы вы сказали что-то о ваших потребностях в первую очередь, это может помочь в будущем? –

+1

Во всяком случае, только WANTING компьютер, чтобы работать быстрее, не помогает. Существует фиксированное количество кратных и добавляет здесь, и ваш компьютер будет обрабатывать их только так быстро, как это будет сделано. Если вам нужен более быстрый компьютер, то купите его. Как бы то ни было, приведенная выше схема полностью векторизована, и в ней нет провалов. –

0

Сначала сохраните размер каждой переменной:

size_m = size(m); 
size_n = size(n); 
size_theta = size(theta); 
size_phi = size(phi); 

Используйте ngrid функцию как это:

[theta, phi, m, n] = ngrid(theta, phi, m, n) 

Это даст вам массив с 4-х размеров (по одному для каждой из ваших переменных: тета , phi, m, n).Теперь вы можете рассчитать следующим образом:

m.*theta + n.*phi 

Теперь вам нужно сделать S_mn иметь 4 размеры с размерами size_theta, size_phi, size_m, size_n как это:

S_tpmn = repmat(S_mn, [size_theta size_phi size_m size_n]); 

Теперь вы можете рассчитать сумму, как это:

aux_sum = S_tpmn.*exp(1i*(m.*theta + n.*phi)); 

Наконец, вы можете подвести вдоль последних 2-х измерениях (т и п), чтобы получить массив с 2-х размеров с размером size_theta по size_phi:

final_sum = sum(sum(aux_sum, 4), 3); 

Примечание: У меня нет доступа к Matlab прямо сейчас, поэтому я не могу проверить, действительно ли это работает.

0

Существует несколько способов сделать это.

Один из способов - создать функцию (-handle), которая возвращает сумму как функцию theta и phi, а затем используйте arrayfun для выполнения сумм. Другой - полностью векторизовать вычисление, хотя это будет использовать больше памяти.

Версия arrayfun:

[m, n] = meshgrid(m,n); 

sumHandle = @(theta,phi)sum(reshape(... 
    S_mn.*exp(1i(m*theta + n*phi)),... 
    [],1)) 

[theta, phi] = meshgrid(theta,phi); 

sumAsFunOfThetaPhi = arrayfun(sumHandle,theta,phi); 

векторизованная версия:

[m, n] = meshgrid(m,n); 
m = permute(m(:),[2 4 1 3]); %# vector along dim 3 
n = permute(n(:),[2 3 4 1]); %# vector along dim 4 

S_mn = repmat(permute(S_mn,[3 4 1 2]), length(theta),length(phi)); 

theta = theta(:); %# vector along dim 1 (phi is along dim 2 b/c of linspace) 

fullSum = S_mn.* exp(1i*(... 
    bsxfun(@plus,... 
     bsxfun(@times, m, theta),... 
     bsxfun(@times, n, phi),... 
    ))); 

sumAsFunOfThetaPhi = sum(sum(fullSum, 3),4); 
Смежные вопросы