36 #ifndef VIGRA_WIGNER_MATRIX_HXX 
   37 #define VIGRA_WIGNER_MATRIX_HXX 
   43 #include "mathutil.hxx" 
   44 #include "array_vector.hxx" 
   46 #include "tinyvector.hxx" 
   47 #include "quaternion.hxx" 
   48 #include "clebsch-gordan.hxx" 
   68     typedef std::complex<Real> Complex;
 
   95     void compute_D(
int l, Real phi, Real theta, Real psi);
 
  103     Complex 
get_D(
int l, 
int n, 
int m)
 const 
  107             std::string message = std::string(
"WignerMatrix::get_D(): index out of bounds: l=");
 
  108             message << l << 
" l_max=" << D.
size() << 
" m=" << m << 
" n=" << n << 
"\n";
 
  110             vigra_precondition(l < D.
size() && m+l <= 2*l+1 &&
 
  111                                n+l <= 2*l+1 && m+l >= 0 && n+l >= 0,
 
  113             return D[l](n+l, m+l);
 
  117             return Complex(Real(1.0));
 
  125     Matrix<Complex> 
const & 
get_D(
int l)
 const 
  127         std::string message = std::string(
"WignerMatrix::get_D(): index out of bounds: l=");
 
  128         message << l << 
" l_max=" << l_max << 
"\n";
 
  130         vigra_precondition(l > 0 && l <= l_max, message.c_str());
 
  143     void rotatePH(NestedArray 
const & PH, Real phi, Real theta, Real psi,
 
  144                   NestedArray & PHresult);
 
  153         Q qr = Q::createRotation(angle, axis),
 
  155         return (qr * qv * 
conj(qr)).v();
 
  160     ArrayVector<double> CGcoeff;
 
  161     ArrayVector<Matrix<Complex> > D;
 
  164 template <
class Real>
 
  170     for (
int l = 2; l <= band+1; l++)
 
  172         for(
int m = -l; m <= l ; m++)
 
  174             for(
int n = -l; n <= l ; n++)
 
  176                 for (
int m2 = -1; m2 <= 1; m2++)
 
  178                     for (
int n2 = -1; n2 <= 1; n2++)
 
  182                         if (m1 > -l && m1 < l && n1 > -l && n1 < l)
 
  184                             CGcoeff.push_back((clebschGordan(l-1,m1,1,m2,l,m))*(clebschGordan(l-1,n1,1,n2,l,n)));
 
  193 template <
class Real>
 
  206     if (D.size() < (std::size_t)(l+1)) 
 
  210     D[1](0,0) = emipsi * Complex(Real(0.5*(1.0+c))) * emiphi;
 
  211     D[1](0,1) = Complex(Real(-s/M_SQRT2)) * emiphi;
 
  212     D[1](0,2) = eipsi * Complex(Real(0.5*(1.0-c))) * emiphi;
 
  213     D[1](1,0) = emipsi * Complex(Real(s/M_SQRT2));
 
  214     D[1](1,1) = Complex(Real(c));
 
  215     D[1](1,2) = eipsi * Complex(Real(-s/M_SQRT2));
 
  216     D[1](2,0) = emipsi * Complex(Real(0.5*(1.0-c))) * eiphi; 
 
  217     D[1](2,1) = Complex(Real(s/M_SQRT2)) * eiphi;
 
  218     D[1](2,2) = eipsi * Complex(Real(0.5*(1.0+c))) * eiphi;
 
  227 template <
class Real>
 
  231     if (D.size() < (std::size_t)(l+1) ) 
 
  243         D[1](0,0) = Real(0.5);
 
  244         D[1](0,1) = Real(0.5*M_SQRT2);
 
  245         D[1](0,2) = Real(0.5);
 
  246         D[1](1,0) = Real(-0.5*M_SQRT2);
 
  247         D[1](1,1) = Real(0.0);
 
  248         D[1](1,2) = Real(0.5*M_SQRT2);
 
  249         D[1](2,0) = Real(0.5);
 
  250         D[1](2,1) = Real(-0.5*M_SQRT2);
 
  251         D[1](2,2) = Real(0.5);
 
  264         D[l].init(Real(0.0));      
 
  266         for(
int m = -l; m <= l ; m++)
 
  268             for(
int n = -l; n <= l ; n++)
 
  270                 for (
int m2 = -1; m2 <= 1; m2++)
 
  272                     for (
int n2 = -1; n2 <= 1; n2++)
 
  276                         if ((m1 > -l) && (m1 < l) && (n1 > -l) && (n1 < l))
 
  278                             D[l](m+l,n+l) += D[1](m2+1,n2+1) * D[l-1](m1+l-1,n1+l-1) * Real(CGcoeff[cg1cnt++]);
 
  289 template <
class Real>
 
  294     int band = PH[1].
size()-1;
 
  295     compute_D(band, phi, theta, psi);
 
  297     PHresult.resize(PH.
size());
 
  299     for(
int n=1; n<=band; n++)
 
  301         PHresult[n].resize(band+1);
 
  302         for (
int l=0; l<=band; l++)
 
  304             PHresult[n][l].resize(2*band+1);
 
  305             for(
int m=-l; m<=l; m++)
 
  308                 for (
int h=-l; h<=l; h++)
 
  310                     tmp += get_D(l,h,m) * PH[n][l][h+l];
 
  313                 PHresult[n][l][m+l] = tmp;
 
  321 #endif // VIGRA_WIGNER_MATRIX_HXX 
Definition: quaternion.hxx:61
FFTWComplex< R > conj(const FFTWComplex< R > &a)
complex conjugate 
Definition: fftw3.hxx:1030
computation of Wigner D matrix + rotation functions in SH,VH and R³ 
Definition: wigner-matrix.hxx:63
linalg::TemporaryMatrix< T > sin(MultiArrayView< 2, T, C > const &v)
linalg::TemporaryMatrix< T > exp(MultiArrayView< 2, T, C > const &v)
void rotatePH(NestedArray const &PH, Real phi, Real theta, Real psi, NestedArray &PHresult)
Rotate in PH. 
Definition: wigner-matrix.hxx:291
Definition: array_vector.hxx:58
Definition: multi_fwd.hxx:63
void compute_D(int band)
Compute D with fixed theta = pi/2, phi=0, psi=0. 
Definition: wigner-matrix.hxx:229
Class for fixed size vectors.This class contains an array of size SIZE of the specified VALUETYPE...
Definition: accessor.hxx:940
Complex get_D(int l, int n, int m) const 
Get the (n,m) entry of D. 
Definition: wigner-matrix.hxx:103
size_type size() const 
Definition: array_vector.hxx:358
WignerMatrix(int l_max)
constructor 
Definition: wigner-matrix.hxx:165
linalg::TemporaryMatrix< T > cos(MultiArrayView< 2, T, C > const &v)
Matrix< Complex > const & get_D(int l) const 
Return the rotation matrix D for the lth band. 
Definition: wigner-matrix.hxx:125