Go to the documentation of this file.00001 #include <iostream>
00002 #include "rz_poly.h"
00003
00004 using namespace std;
00005 using namespace magfieldparam;
00006
00007
00008 rz_poly::rz_poly(int N)
00009 {
00010 int nz, nr = 0, nv, nt;
00011 poly_term v3;
00012
00013 if (N < 2) N = 2;
00014 data.reserve(N);
00015
00016 v3.coeff = 1.;
00017 v3.np[0] = 0;
00018 v3.np[1] = 1;
00019
00020 data.push_back(poly_vect(1, v3));
00021
00022 for (int m = 2; m <=N; ++m) {
00023 nz = m;
00024 nr = 0;
00025 nv = 0;
00026 v3.coeff = 1./m;
00027 v3.np[0] = nr;
00028 v3.np[1] = nz;
00029
00030 nt = (m + 2) / 2;
00031 poly_vect v3x(nt, v3);
00032
00033 while (nz >= 2) {
00034 nz -= 2;
00035 nr += 2;
00036 nv += 1;
00037 v3x[nv].coeff = -v3x[nv-1].coeff*(nz+1)*(nz+2)/(nr*nr);
00038 v3x[nv].np[0] = nr;
00039 v3x[nv].np[1] = nz;
00040 }
00041 data.push_back(v3x);
00042 }
00043 max_nr = nr+1;
00044 max_nz = N +1;
00045 r_pow = new double [max_nr];
00046 z_pow = new double [max_nz];
00047 fill(r_pow, r_pow+max_nr, 1.);
00048 fill(z_pow, z_pow+max_nz, 1.);
00049
00050 n_active = data.size();
00051 is_off = new bool [n_active];
00052 fill(is_off, is_off+n_active, false);
00053 }
00054
00055
00056 rz_poly::rz_poly(const rz_poly& S)
00057 {
00058 data = S.data;
00059 max_nr = S.max_nr;
00060 max_nz = S.max_nz;
00061 n_active = S.n_active;
00062
00063 if (max_nr) {
00064 r_pow = new double [max_nr];
00065 copy(S.r_pow, S.r_pow+max_nr, r_pow);
00066 } else r_pow = 0;
00067
00068 if (max_nz) {
00069 z_pow = new double [max_nz];
00070 copy(S.z_pow, S.z_pow+max_nz, z_pow);
00071 } else z_pow = 0;
00072
00073 if (S.is_off) {
00074 is_off = new bool [data.size()];
00075 copy(S.is_off, S.is_off+data.size(), is_off);
00076 } else is_off = 0;
00077 }
00078
00079
00080 rz_poly::~rz_poly()
00081 {
00082 if (is_off) delete [] is_off;
00083 if (r_pow) delete [] r_pow;
00084 if (z_pow) delete [] z_pow;
00085 }
00086
00087
00088 void rz_poly::SetOFF(int npoly)
00089 {
00090 if ((npoly < 0) || (npoly >= (int)data.size())) return;
00091 if (is_off[npoly]) return;
00092 is_off[npoly] = true;
00093 --n_active;
00094 }
00095
00096
00097 void rz_poly::SetON(int npoly)
00098 {
00099 if ((npoly < 0) || (npoly >= (int)data.size())) return;
00100 if (is_off[npoly]) {
00101 is_off[npoly] = false;
00102 ++n_active;
00103 }
00104 }
00105
00106
00107 void rz_poly::Print()
00108 {
00109 if (!data.size()) {
00110 cout << "The \"rz_poly\" object is NOT initialized!" << endl;
00111 return;
00112 }
00113
00114 for (unsigned int ip = 0; ip < data.size(); ++ip) {
00115 cout << "Polynomial " << ip << " (size=" << data[ip].size() << ", status=";
00116 if (is_off[ip]) cout << "OFF):" << endl;
00117 else cout << "ON):" << endl;
00118 for (unsigned int it = 0; it < data[ip].size(); ++it) {
00119 cout << "\tnr=" << data[ip][it].np[0]
00120 << "\tnz=" << data[ip][it].np[1]
00121 << "\tcoeff=" << data[ip][it].coeff
00122 << endl;
00123 }
00124 }
00125 }
00126
00127
00128 rz_poly rz_poly::Diff(int nvar, bool keep_empty)
00129 {
00130
00131
00132
00133
00134
00135 poly_term v3;
00136 rz_poly p_out;
00137 p_out.data.reserve(data.size());
00138
00139 bool *tmp_mask = new bool [data.size()];
00140 unsigned int ind_tmp = 0;
00141 int tmp_act = 0;
00142
00143 for (unsigned int ip = 0; ip < data.size(); ++ip) {
00144 poly_vect v3x;
00145 v3x.reserve(data[ip].size());
00146 for (unsigned int it = 0; it < data[ip].size(); ++it) {
00147 v3 = data[ip][it];
00148 v3.coeff = data[ip][it].coeff * data[ip][it].np[nvar];
00149 if (v3.coeff != 0) {
00150 v3.np[nvar] = data[ip][it].np[nvar] - 1;
00151 v3x.push_back(v3);
00152 }
00153 }
00154 if (v3x.size() || keep_empty) {
00155 v3x.resize(v3x.size());
00156 p_out.data.push_back(v3x);
00157 tmp_mask[ind_tmp] = is_off[ip];
00158 ++ind_tmp;
00159 if (! is_off[ip]) ++tmp_act;
00160 }
00161 }
00162
00163 p_out.data.resize(p_out.data.size());
00164 p_out.max_nr = max_nr;
00165 p_out.max_nz = max_nz;
00166
00167 if (nvar == 0) --p_out.max_nr; else --p_out.max_nz;
00168
00169 p_out.r_pow = new double [p_out.max_nr];
00170 copy(r_pow, r_pow+p_out.max_nr, p_out.r_pow);
00171 p_out.z_pow = new double [p_out.max_nz];
00172 copy(z_pow, z_pow+p_out.max_nz, p_out.z_pow);
00173
00174 p_out.n_active = tmp_act;
00175 p_out.is_off = new bool [p_out.data.size()];
00176 copy(tmp_mask, tmp_mask+p_out.data.size(), p_out.is_off);
00177
00178 delete [] tmp_mask;
00179
00180 return p_out;
00181 }
00182
00183
00184 rz_poly rz_poly::Int(int nvar)
00185 {
00186
00187
00188 rz_poly p_out;
00189 p_out.data = data;
00190 for (unsigned int ip = 0; ip < data.size(); ++ip) {
00191 for (unsigned int it = 0; it < data[ip].size(); ++it) {
00192 p_out.data[ip][it].coeff /= ++p_out.data[ip][it].np[nvar];
00193 }
00194 }
00195
00196 p_out.max_nr = max_nr;
00197 p_out.max_nz = max_nz;
00198
00199 if (nvar == 0) ++p_out.max_nr; else ++p_out.max_nz;
00200
00201 p_out.r_pow = new double [p_out.max_nr];
00202 copy(r_pow, r_pow+max_nr, p_out.r_pow);
00203 p_out.z_pow = new double [p_out.max_nz];
00204 copy(z_pow, z_pow+max_nz, p_out.z_pow);
00205
00206 if (nvar == 0) p_out.r_pow[max_nr] = p_out.r_pow[max_nr-1] * r_pow[1];
00207 else p_out.z_pow[max_nz] = p_out.z_pow[max_nz-1] * z_pow[1];
00208
00209 p_out.n_active = n_active;
00210 p_out.is_off = new bool [data.size()];
00211 copy(is_off, is_off+data.size(), p_out.is_off);
00212
00213 return p_out;
00214 }
00215
00216
00217 rz_poly& rz_poly::operator*=(double C)
00218 {
00219
00220
00221 for (unsigned int ip = 0; ip < data.size(); ++ip) {
00222 if (is_off[ip]) continue;
00223 for (unsigned int it = 0; it < data[ip].size(); ++it) {
00224 data[ip][it].coeff *= C;
00225 }
00226 }
00227 return *this;
00228 }
00229
00230
00231 rz_poly& rz_poly::operator*=(double *C)
00232 {
00233
00234
00235 for (unsigned int ip = 0; ip < data.size(); ++ip) {
00236 if (is_off[ip]) continue;
00237 for (unsigned int it = 0; it < data[ip].size(); ++it) {
00238 data[ip][it].coeff *= *C;
00239 }
00240 ++C;
00241 }
00242 return *this;
00243 }
00244
00245
00246 double rz_poly::GetSVal(double r, double z, double *C)
00247 {
00248
00249
00250 if (r_pow == 0) return 0.;
00251
00252 double term, rez = 0.;
00253 int ip, it;
00254
00255 if (r != r_pow[1]) for (ip = 1; ip < max_nr; ++ip) r_pow[ip] = r*r_pow[ip-1];
00256 if (z != z_pow[1]) for (ip = 1; ip < max_nz; ++ip) z_pow[ip] = z*z_pow[ip-1];
00257
00258 for (ip = 0; ip < (int)data.size(); ++ip) {
00259 if (is_off[ip]) continue;
00260 term = 0.;
00261 for (it = 0; it < (int)data[ip].size(); ++it) {
00262 term += data[ip][it].coeff
00263 * r_pow[data[ip][it].np[0]]
00264 * z_pow[data[ip][it].np[1]];
00265 }
00266 rez += *C * term;
00267 ++C;
00268 }
00269
00270 return rez;
00271 }
00272
00273
00274 double *rz_poly::GetVVal(double r, double z, double *rez_out)
00275 {
00276
00277
00278
00279
00280
00281 if (r_pow == 0) return 0;
00282
00283 double term;
00284 int ip, it;
00285
00286 double *rez;
00287 if (rez_out) rez = rez_out;
00288 else rez = new double [n_active];
00289
00290 double *pnt = rez;
00291
00292 if (r != r_pow[1]) for (ip = 1; ip < max_nr; ++ip) r_pow[ip] = r*r_pow[ip-1];
00293 if (z != z_pow[1]) for (ip = 1; ip < max_nz; ++ip) z_pow[ip] = z*z_pow[ip-1];
00294
00295 for (ip = 0; ip < (int)data.size(); ++ip) {
00296 if (is_off[ip]) continue;
00297 term = 0.;
00298 for (it = 0; it < (int)data[ip].size(); ++it) {
00299 term += data[ip][it].coeff
00300 * r_pow[data[ip][it].np[0]]
00301 * z_pow[data[ip][it].np[1]];
00302 }
00303 *pnt = term;
00304 ++pnt;
00305 }
00306
00307 return rez;
00308 }
00309
00310
00311 double *rz_poly::Expand(double *C)
00312 {
00313
00314
00315
00316
00317 double *rez = new double [data.size()];
00318 for (int ip = 0; ip < (int)data.size(); ++ip) {
00319 if (is_off[ip]) rez[ip] = 0.;
00320 else {
00321 rez[ip] = *C;
00322 ++C;
00323 }
00324 }
00325 return rez;
00326 }
00327