2014-10-14 3 views
0

У меня есть процедура БПФ fftconvx принимает два тензора Ttnsr и S в качестве входных параметров и получение результата в другой тензор G. Все тензоры определяются как массивы Blitz ++ Array<complex<double>, N>, где N - ранг массива. Процедура fftconvx должна быть вызвана несколько раз внутри двойной петли.Как пройти Блиц ++ подмассив в качестве входного/выходного параметра процедуры

В идеале я хотел бы передать подмассив Stnsr(ri,rj,rk,0) или Stnsr(ri,rj,rk,1) и получить результат в подмассивы Gtnsr(t,p,ri,rj,rk,0) или Gtnsr(t,p,ri,rj,rk,1) следующим образом:

fftconvx(Gtnsr(t,p,ri,rj,rk,0), Ttnsr, Stnsr(ri,rj,rk,0)); 

Переменных ri,rj,rk являются Blitz ++ диапазонов массива. К сожалению, это не работает и приводит к следующей ошибке компиляции:

error: invalid initialization of non-const reference of type 
‘blitz::Array<std::complex<double>, 3>&’ from an rvalue of type 
‘blitz::SliceInfo<std::complex<double>, int, int, blitz::Range, blitz::Range, 
blitz::Range, int, blitz::nilArraySection, blitz::nilArraySection, 
blitz::nilArraySection, blitz::nilArraySection, blitz::nilArraySection>::T_slice 
{aka blitz::Array<std::complex<double>, 3>}’ 

fftconvx(Gtnsr(t,p,ri,rj,rk,0), Ttnsr, Stnsr(ri,rj,rk,0)); 

Подписи fftconvx является:

void fftconvx(Array<complex<double>, 3> &c, 
       Array<complex<double>, 3> x2, 
       Array<complex<double>, 3> x1, 
       ...); 

Там больше массивов и переменных, передаваемым в качестве входных параметров, но я их опускаю для краткости.

До сих пор я придумал решение на основе временных массивов S и G:

S(ri,rj,rk) = Stnsr(ri,rj,rk,0); 

fftconvx(G, Ttnsr, S); 

Gtnsr(t,p,ri,rj,rk,0) = G(ri,rj,rk); 

Я считаю, что есть более элегантное решение.

+0

Как fftconvx объявленную? – Surt

ответ

1

Без знания Blitz ++ Я предлагаю это возможное решение.

Похоже, что Gtnsr является SliceInfo, а не массивом, но имеет оператор Array.

Так изменение fftconvx в

template<class SliceOrArray> 
void fftconvx(SliceOrArray &c, 
       const Array<complex<double>, 3> x2, 
       const Array<complex<double>, 3> x1, 
       ...); 

может работать, если операции в fftconvx позволяет использовать срез.

Если Blitz ++ является оппонентом для C++ 11, то может работать и следующее.

G fftconvx( const Array<complex<double>, 3> x2, 
       const Array<complex<double>, 3> x1, 
       ...) { 
    G c; 
    ... 
    return c; // C++11 NRVO 
}; 

и затем вызвать

Gtnsr(t,p,ri,rj,rk,0) = fftconvx(...); 
+0

Благодарим вас за предложение. Первый параметр приводит к следующей ошибке: 'error: при прохождении аргумента 1 из 'void ftconvx (SliceOrArray &, blitz :: Array , 3>, blitz :: Array , 3>, blitz :: Array , 3>, blitz :: Array , 3>, blitz :: Array , 3>, blitz :: Array , 3>, fftw_plan, fftw_plan, int, int, int, blitz :: Range, blitz :: Range, blitz :: Range) [с SliceOrArray = blitz :: Array , 3>; fftw_plan = fftw_plan_s *] ''. – mabalenk

+0

Второй вариант сработал. Функция должна быть определена как «Массив <комплекс , 3> fftconvx (массив <комплекс , 3> x2, массив <комплекс , 3> x1, ...) 'и возвращаемый массив Blitz ++ должен быть определен в конце' fftconvx' как 'Array , 3> c (x3t (ri, rj, rk)/(8.0 * mi * mj * mk)); return c; 'Это также решило проблему передачи подстроки' Stnsr (ri, rj, rk, 0) 'to' fftconvx' напрямую. – mabalenk