00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
#ifndef _ZFXMATH_INCLUDE_SH_ROTATEMATRIX_H_
00014
#define _ZFXMATH_INCLUDE_SH_ROTATEMATRIX_H_
00015
00016
namespace ZFXMath
00017 {
00018
00019
namespace SphericalHarmonics
00020 {
00021
00027
template<
class PrecisionType,
class FuncValueType>
00028 class TRotateMatrix
00029 {
00030
public:
00031
TRotateMatrix(
const int nb_bands) :
00032
00033 m_NbBands(nb_bands),
00034 m_Matrices(0),
00035 m_Elements(0)
00036
00037 {
00039 m_Matrices = (SubMatrix*)operator new (m_NbBands *
sizeof(SubMatrix));
00040
00041
int size = 0;
00042
for (
int i = 0; i < m_NbBands; i++)
00043 size += (i * 2 + 1) * (i * 2 + 1);
00044
00046 m_Elements =
new PrecisionType[size];
00047
00049
for (
int i = 0, j = 0; i < m_NbBands; i++)
00050 {
00051
int w = i * 2 + 1;
00052 m_Matrices[i] = *
new SubMatrix(m_Elements + j, w);
00053 j += (w * w);
00054 }
00055
00056
00057
00058 m_Elements[0] = 1;
00059 }
00060
00061
00062 ~
TRotateMatrix(
void)
00063 {
00064
if (m_Elements)
00065
delete [] m_Elements;
00066
if (m_Matrices)
00067
delete [] m_Matrices;
00068 }
00069
00070
00071
00072 PrecisionType& operator () (
const int l,
const int m,
const int n)
00073 {
00074
return (m_Matrices[l](m, n));
00075 }
00076 PrecisionType operator () (
const int l,
const int m,
const int n)
const
00077
{
00078
return (m_Matrices[l](m, n));
00079 }
00080
00081
00082
int GetNbBands(
void)
const
00083
{
00084
return (m_NbBands);
00085 }
00086
00092 void Transform(
const TCoeffs<FuncValueType>& source,
TCoeffs<FuncValueType>& dest)
const
00093
{
00094
00095
int nb_bands = source.
GetNbBands();
00096 assert(nb_bands == dest.
GetNbBands());
00097
00098
00099 dest(0) = source(0);
00100
00101
00102
for (
int l = 1; l < nb_bands; l++)
00103 {
00104 SubMatrix& M = m_Matrices[l];
00105
00106
00107
int band_offset = l * (l + 1);
00108
00109
00110
for (
int mo = -l; mo <= l; mo++)
00111 {
00112
00113 FuncValueType& d = dest(band_offset + mo);
00114 d = 0;
00115
00116
00117
int p_mo = (mo + M.GetShift()) * M.GetWidth() + M.GetShift();
00118
00119
00120
for (
int mi = -l; mi <= l; mi++)
00121 d += source(band_offset + mi) * FuncValueType( M(p_mo + mi) );
00122 }
00123 }
00124 }
00125
00126
private:
00127
class SubMatrix;
00128
00129
00130
int m_NbBands;
00131
00132
00133 SubMatrix* m_Matrices;
00134
00135
00136 PrecisionType* m_Elements;
00137
00138
class SubMatrix
00139 {
00140
public:
00141
00142 SubMatrix(PrecisionType* elements,
const int width) :
00143
00144 m_Elements(elements),
00145 m_Width(width),
00146 m_Size(width * width),
00147 m_Shift((width - 1) / 2)
00148
00149 {
00150 }
00151
00152
00153
00154 PrecisionType& operator () (
const int m,
const int n)
00155 {
00156
return (m_Elements[Index(m, n)]);
00157 }
00158 PrecisionType operator () (
const int m,
const int n)
const
00159
{
00160
return (m_Elements[Index(m, n)]);
00161 }
00162
00163
00164
00165 PrecisionType& operator () (
const int i)
00166 {
00167
return (m_Elements[Index(i)]);
00168 }
00169 PrecisionType operator () (
const int i)
const
00170
{
00171
return (m_Elements[Index(i)]);
00172 }
00173
00174
00175
int GetWidth(
void)
const
00176
{
00177
return (m_Width);
00178 }
00179
00180
int GetShift(
void)
const
00181
{
00182
return (m_Shift);
00183 }
00184
00185
00186
private:
00187
00188
int Index(
const int m,
const int n)
const
00189
{
00190
00191 assert(m >= -m_Shift && m <= m_Shift);
00192 assert(n >= -m_Shift && n <= m_Shift);
00193
00194
return ((m + m_Shift) * m_Width + (n + m_Shift));
00195 }
00196
00197
int Index(
const int i)
const
00198
{
00199
00200 assert(i >= 0 && i < m_Size);
00201
00202
return (i);
00203 }
00204
00205
00206 PrecisionType* m_Elements;
00207
00208
00209
int m_Width;
00210
00211
00212
int m_Size;
00213
00214
00215
int m_Shift;
00216 };
00217
00218 };
00219
00220 };
00221
00222 };
00223
00224
#endif //_ZFXMATH_INCLUDE_SH_ROTATEMATRIX_H__