Hauptseite | Liste aller Namensbereiche | Klassenhierarchie | Auflistung der Klassen | Auflistung der Dateien | Elemente eines Namensbereiches | Klassen-Elemente | Datei-Elemente

SHRotate.h

gehe zur Dokumentation dieser Datei
00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019 00020 00021 #ifndef _ZFXMATH_INCLUDE_SH_ROTATE_H_ 00022 #define _ZFXMATH_INCLUDE_SH_ROTATE_H_ 00023 00024 namespace ZFXMath 00025 { 00026 00027 namespace SphericalHarmonics 00028 { 00029 00030 inline int delta(const int m, const int n) 00031 { 00032 // Kronecker Delta 00033 return ( m == n ? 1 : 0 ); 00034 } 00035 00036 template<class PrecisionType> 00037 void uvw(const int l, const int m, const int n, PrecisionType& u, PrecisionType& v, PrecisionType& w) 00038 { 00039 // Pre-calculate simple reusable terms 00040 PrecisionType d = PrecisionType( delta(m, 0) ); 00041 int abs_m = abs(m); 00042 00043 // Only calculate the required denominator once 00044 PrecisionType denom; 00045 if (abs(n) == l) 00046 denom = PrecisionType( (2 * l) * (2 * l - 1) ); 00047 00048 else 00049 denom = PrecisionType( (l + n) * (l - n) ); 00050 00051 // Now just calculate the scalars 00052 u = PrecisionType( sqrt((l + m) * (l - m) / denom) ); 00053 v = PrecisionType( 0.5f * sqrt((1 + d) * (l + abs_m - 1) * (l + abs_m) / denom) * (1 - 2 * d) ); 00054 w = PrecisionType( -0.5f * sqrt((l - abs_m - 1) * (l - abs_m) / denom) * (1 - d) ); 00055 } 00056 00057 template<class PrecisionType, class FuncValueType> 00058 PrecisionType M(const int l, const int m, const int n, const TRotateMatrix<PrecisionType,FuncValueType>& M) 00059 { 00060 // First get the scalars 00061 PrecisionType u, v, w; 00062 uvw(l, m, n, u, v, w); 00063 00064 // Scale by their functions 00065 if (u) 00066 u *= U(l, m, n, M); 00067 if (v) 00068 v *= V(l, m, n, M); 00069 if (w) 00070 w *= W(l, m, n, M); 00071 00072 return (u + v + w); 00073 } 00074 00075 template<class PrecisionType, class FuncValueType> 00076 PrecisionType P(const int i, const int l, const int a, const int b, const TRotateMatrix<PrecisionType,FuncValueType>& M) 00077 { 00078 // Rather than passing the permuted rotation matrix around grab it directly from the first 00079 // rotation band which is never modified 00080 PrecisionType ri1 = M(1, i, 1); 00081 PrecisionType rim1 = M(1, i, -1); 00082 PrecisionType ri0 = M(1, i, 0); 00083 00084 if (b == -l) 00085 return (ri1 * M(l - 1, a, -l + 1) + rim1 * M(l - 1, a, l - 1)); 00086 00087 else if (b == l) 00088 return (ri1 * M(l - 1, a, l - 1) - rim1 * M(l - 1, a, -l + 1)); 00089 00090 else // |b|<l 00091 return (ri0 * M(l - 1, a, b)); 00092 } 00093 00094 00095 template<class PrecisionType, class FuncValueType> 00096 PrecisionType U(const int l, const int m, const int n, const TRotateMatrix<PrecisionType,FuncValueType>& M) 00097 { 00098 // All cases fall correctly through here 00099 return (P(0, l, m, n, M)); 00100 } 00101 00102 00103 template<class PrecisionType, class FuncValueType> 00104 PrecisionType V(const int l, const int m, const int n, const TRotateMatrix<PrecisionType,FuncValueType>& M) 00105 { 00106 if (m == 0) 00107 { 00108 PrecisionType p0 = P(1, l, 1, n, M); 00109 PrecisionType p1 = P(-1, l, -1, n, M); 00110 return (p0 + p1); 00111 } 00112 00113 else if (m > 0) 00114 { 00115 PrecisionType d = PrecisionType( delta(m, 1) ); 00116 PrecisionType p0 = P(1, l, m - 1, n, M); 00117 PrecisionType p1 = P(-1, l, -m + 1, n, M); 00118 return PrecisionType(p0 * sqrt(1 + d) - p1 * (1 - d)); 00119 } 00120 00121 else // m < 0 00122 { 00123 PrecisionType d = PrecisionType( delta(m, -1) ); 00124 PrecisionType p0 = P(1, l, m + 1, n, M); 00125 PrecisionType p1 = P(-1, l, -m - 1, n, M); 00126 return PrecisionType(p0 * (1 - d) + p1 * sqrt(1 + d)); 00127 } 00128 } 00129 00130 00131 template<class PrecisionType, class FuncValueType> 00132 PrecisionType W(const int l, const int m, const int n, const TRotateMatrix<PrecisionType,FuncValueType>& M) 00133 { 00134 if (m == 0) 00135 { 00136 // Never gets called as kd=0 00137 assert(false); 00138 return (0); 00139 } 00140 00141 else if (m > 0) 00142 { 00143 PrecisionType p0 = P(1, l, m + 1, n, M); 00144 PrecisionType p1 = P(-1, l, -m - 1, n, M); 00145 return (p0 + p1); 00146 } 00147 00148 else // m < 0 00149 { 00150 PrecisionType p0 = P(1, l, m - 1, n, M); 00151 PrecisionType p1 = P(-1, l, -m + 1, n, M); 00152 return (p0 - p1); 00153 } 00154 } 00155 00161 template<class PrecisionType, class FuncValueType> 00162 void SHRotate( TRotateMatrix<PrecisionType,FuncValueType>& shrm, const TMatrix3x3<PrecisionType>& rotation ) 00163 { 00164 // The first band is rotated by a permutation of the original matrix 00165 shrm(1, -1, -1) = (PrecisionType) rotation._22; 00166 shrm(1, -1, 0) = (PrecisionType) -rotation._32; 00167 shrm(1, -1, +1) = (PrecisionType) rotation._12; 00168 shrm(1, 0, -1) = (PrecisionType) -rotation._23; 00169 shrm(1, 0, 0) = (PrecisionType) rotation._33; 00170 shrm(1, 0, +1) = (PrecisionType) -rotation._13; 00171 shrm(1, +1, -1) = (PrecisionType) rotation._21; 00172 shrm(1, +1, 0) = (PrecisionType) -rotation._31; 00173 shrm(1, +1, +1) = (PrecisionType) rotation._11; 00174 00175 // Calculate each block of the rotation matrix for each subsequent band 00176 for (int band = 2; band < shrm.GetNbBands(); band++) 00177 { 00178 for (int m = -band; m <= band; m++) 00179 for (int n = -band; n <= band; n++) 00180 shrm(band, m, n) = M(band, m, n, shrm); 00181 } 00182 } 00183 }; // namespace SphericalHarmonics 00184 00185 }; // namespace ZFXMath 00186 00187 #endif //_ZFXMATH_INCLUDE_SH_ROTATE_H__

Erzeugt am Thu Nov 25 04:02:55 2004 für ZFX-Math Library von doxygen 1.3.8