00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 template <typename T>
00033 Sacado::PCE::UnitHermiteBasis<T>::
00034 UnitHermiteBasis(unsigned int degree) :
00035 d(degree),
00036 basis(d+1, StandardPoly<T>(d)),
00037 norms(d+1, T(0.0))
00038 {
00039
00040 basis[0].coeff(0) = T(1.0);
00041 if (d >= 1)
00042 basis[1].coeff(1) = T(2.0);
00043 for (unsigned int k=2; k<=d; k++) {
00044 basis[k].coeff(0) = -T(2.0)*T(k-1)*basis[k-2].coeff(0);
00045 for (unsigned int i=1; i<=k; i++)
00046 basis[k].coeff(i) =
00047 T(2.0)*(basis[k-1].coeff(i-1) - T(k-1)*basis[k-2].coeff(i));
00048 }
00049
00050
00051 norms[0] = 2.0*std::sqrt(std::atan(1.0));
00052 for (unsigned int k=1; k<=d; k++)
00053 norms[k] = T(2.0)*T(k)*norms[k-1];
00054
00055
00056 for (unsigned int k=0; k<=d; k++) {
00057 for (unsigned int i=0; i<=d; i++)
00058 basis[k].coeff(i) /= std::sqrt(norms[k]);
00059 norms[k] = 1.0;
00060 }
00061 }
00062
00063 template <typename T>
00064 Sacado::PCE::UnitHermiteBasis<T>::
00065 UnitHermiteBasis(const Sacado::PCE::UnitHermiteBasis<T>& b) :
00066 d(b.d),
00067 basis(b.basis),
00068 norms(b.norms)
00069 {
00070 }
00071
00072 template <typename T>
00073 Sacado::PCE::UnitHermiteBasis<T>&
00074 Sacado::PCE::UnitHermiteBasis<T>::
00075 operator=(const Sacado::PCE::UnitHermiteBasis<T>& b)
00076 {
00077 if (this != &b) {
00078 d = b.d;
00079 basis = b.basis;
00080 norms = b.norms;
00081 }
00082 return *this;
00083 }
00084
00085 template <typename T>
00086 Sacado::PCE::UnitHermiteBasis<T>::
00087 ~UnitHermiteBasis()
00088 {
00089 }
00090
00091 template <typename T>
00092 unsigned int
00093 Sacado::PCE::UnitHermiteBasis<T>::
00094 size() const
00095 {
00096 return d+1;
00097 }
00098
00099 template <typename T>
00100 const std::vector<T>&
00101 Sacado::PCE::UnitHermiteBasis<T>::
00102 norm_squared() const
00103 {
00104 return norms;
00105 }
00106
00107 template <typename T>
00108 T
00109 Sacado::PCE::UnitHermiteBasis<T>::
00110 derivCoeff(unsigned int i) const
00111 {
00112 return std::sqrt(2.0*i);
00113 }
00114
00115 template <typename T>
00116 void
00117 Sacado::PCE::UnitHermiteBasis<T>::
00118 project(const Sacado::PCE::StandardPoly<T>& p, std::vector<T>& coeffs) const
00119 {
00120
00121 for (unsigned int i=0; i<=d; i++)
00122 coeffs[i] = T(0.0);
00123
00124 unsigned int dp = p.degree();
00125 if (dp > d)
00126 dp = d;
00127
00128
00129 if (dp == 0) {
00130 coeffs[0] = p.coeff(0);
00131 return;
00132 }
00133
00134
00135 std::vector<T> h(dp+1,T(0.));
00136
00137 T pi = 4.0*std::atan(1.0);
00138 T piq = std::sqrt(std::sqrt(pi));
00139 T sq2 = std::sqrt(2.0);
00140
00141 coeffs[0] = piq*p.coeff(dp-1);
00142 coeffs[1] = piq/sq2*p.coeff(dp);
00143 unsigned int dc = 1;
00144
00145 for (int k=dp-2; k>=0; --k) {
00146
00147
00148 h[0] = coeffs[1]/sq2 + piq*p.coeff(k);
00149 for (unsigned int i=1; i<=dc-1; i++) {
00150 h[i] = (std::sqrt(T(i))*coeffs[i-1] + std::sqrt(T(i+1))*coeffs[i+1])/sq2;
00151 }
00152 h[dc] = std::sqrt(T(dc))/sq2*coeffs[dc-1];
00153 h[dc+1] = std::sqrt(T(dc+1))/sq2*coeffs[dc];
00154
00155
00156 for (unsigned int i=0; i<=dc+1; i++)
00157 coeffs[i] = h[i];
00158
00159 dc = dc+1;
00160 }
00161 }
00162
00163 template <typename T>
00164 Sacado::PCE::StandardPoly<T>
00165 Sacado::PCE::UnitHermiteBasis<T>::
00166 toStandardBasis(const T coeffs[], unsigned int n) const
00167 {
00168 unsigned int dp = d;
00169 if (n < d+1)
00170 dp = n-1;
00171
00172 StandardPoly<T> p(dp);
00173
00174 for (unsigned int i=0; i<=dp; i++)
00175 p.add(coeffs[i], basis[i], 1.0);
00176
00177 return p;
00178 }
00179
00180 template <typename T>
00181 const Sacado::PCE::StandardPoly<T>&
00182 Sacado::PCE::UnitHermiteBasis<T>::
00183 getBasisPoly(unsigned int i) const
00184 {
00185 return basis[i];
00186 }
00187
00188 template <typename T>
00189 void
00190 Sacado::PCE::UnitHermiteBasis<T>::
00191 print(std::ostream& os) const
00192 {
00193 os << "Hermite basis of degree " << d << ". Basis vectors:\n";
00194 for (unsigned int i=0; i<basis.size(); i++)
00195 os << "\t" << basis[i];
00196 os << "Basis vector norms (squared):\n\t";
00197 for (unsigned int i=0; i<norms.size(); i++)
00198 os << norms[i] << " ";
00199 os << "\n";
00200 }