dVector ortogonalizacao(const dVector u, const dVector v) { double escalar = produtoEscalar(u, v) / produtoEscalar(v, v); dVector vetor(u.size()); for(int i = 0;i< u.size();i++)vetor[i]=u[i] - escalar*v[i]; return vetor; }
// Adds the dVector b to the dVector a. a is modified in-place. void RKF45::sum_in_place(dVector& a, const dVector& b) const { assert ( a.size() == b.size() && "To sum two vectors, they must be the same size."); for (unsigned int i = 0; i < a.size(); i++) { a[i] += b[i]; } }
// Adds k*b to the dVector a. k is a scalar. b is a dVector. void RKF45::linear_combination_in_place(dVector& a, double k, const dVector& b) const { assert ( a.size() == b.size() && "To sum two vectors, they must be the same size."); for (unsigned int i = 0; i < a.size(); i++) { a[i] += k*b[i]; } }
// Takes the norm of the difference between two dVectors. double RKF45::norm_difference(const dVector& a, const dVector& b) const { assert ( a.size() == b.size() && "To sum two vectors, they must be the same size."); double output = 0; for (unsigned int i = 0; i < a.size(); i++) { output += (a[i] - b[i]) * (a[i] - b[i]); } return sqrt(output); }
// Adds two dVectors a and b and outputs a new dVector that is their // sum. Assumes that the vectors are the same size. If they're not, // raises an error. dVector RKF45::sum(const dVector& a, const dVector& b) const { assert ( a.size() == b.size() && "To sum two vectors, they must be the same size."); dVector output; int size = a.size(); output.resize(size); for (int i = 0; i < size; i++) { output[i] = a[i] + b[i]; } return output; }
// ---------------------------------------------------------------------- double derivative(int i, const dVector& v, double lattice_spacing) { // A local "num points" variable. Used for simplicity. int num_points = get_num_points(v); assert (0 <= i && i < (int)v.size() && "The ith elemennt must be in the vector"); if ( i % num_points == 0 ) { // We're at the lower boundary of the grid. if (DEBUGGING) { cout << "\tUsing forward difference." << endl; } return forward_difference(i,v,lattice_spacing); } else if (i % num_points == num_points - 1) { // We're at the upper boundary of the grid. if (DEBUGGING) { cout << "\tUsing backward difference." << endl; } return backward_difference(i,v,lattice_spacing); } else { // We're in the middle of the grid. if (DEBUGGING) { cout << "\tUsing centered difference." << endl; } return centered_difference(i,v,lattice_spacing); } }
void Quaternion::set_v(const dVector & v) { if(v.size() == 3) { v_ = v; } else { assert (0 && "Quaternion::set_v: input has a wrong size."); } }
Quaternion::Quaternion(const double angle, const dVector & axis) { if(axis.size() != 3) { assert (0 && "Quaternion::Quaternion, size of axis != 3"); return; } // make sure axis is a unit vector v_ = sin(angle/2) * axis/Norm2(axis); s_ = cos(angle/2); }
// ---------------------------------------------------------------------- // Iterative Function // ---------------------------------------------------------------------- dVector f(double t, const dVector& y, const dVector& optional_args) { // t is not used. But it is required by the integrator. // The optional arguments vector contains the lattice spacing and c^2. double h = optional_args[0]; // h = lattice spacing double c2 = optional_args[1]; // c2 = c^2. // For convenience, get the number of points in the lattice int num_points = get_num_points(y); // The output dVector. Starts empty. dVector output(y.size(),0); // The order of elements in v is s,r,u. So we have the following system: // (d/dt) [s,r,u] = [c^2 (dr/dx), (ds/dx), s] // Fill the output array for (int i = 0; i < num_points; i++) { // Fill the (du/dt) terms with s. // ES: A nicer notation would allow you to write e.g. // "output[i].*s" or "output.*s[i]" (see "member pointers), or // "output[i][s]", or maybe even "s[i]" where "s" is a local // variable defined before the loop. output[get_linear_index_u(i,output)] = get_ith_s(i,y); // Fill the (dr/dt) vectors with (ds/dx). // ES: A nicer notation would allow you to write e.g. // "diff(h,y,i,s)" or "diff(h,y,s,i)" instead. output[get_linear_index_r(i,output)] = derivative_for_s(i,y,h); // Fill the (ds/dt) vectors with c^2(dr/dx). output[get_linear_index_s(i,output)] = c2 * derivative_for_r(i,y,h); } // (du/dt) at the boundary is forced to be zero. Impose this. // ES: What about the boundary conditions for the other fields? output[get_linear_index_s(0,output)] = 0; output[get_linear_index_s(num_points-1,output)] = 0; // That's it. Return the array! return output; }
dVector subtracao(dVector u, dVector v){ dVector retorno(v.size()); for (int i = 0; i < v.size(); i++) retorno[i] = u[i] - v[i]; return retorno; }
dVector soma(dVector u, dVector v){ dVector retorno(v.size()); for (int i = 0; i < v.size(); i++) retorno[i] = u[i] + v[i]; return retorno; }
dVector normalize(dVector v) { double norma = getNorma(v); for(int i = 0;i< v.size();i++) v[i]=v[i]/norma; return v; }
double getNorma(const dVector v) { double retorno = 0; for(int i = 0;i< v.size();i++) retorno+=pow(v[i], 2); return (sqrt(retorno)); }
double produtoEscalar(const dVector u, const dVector v) { double retorno =0; for(int i = 0;i< u.size();i++) retorno+=u[i]*v[i]; return retorno; }
// ---------------------------------------------------------------------- int get_num_points(const dVector& v) { assert ( v.size() % NUM_VAR_TYPES == 0 && "The vector must be for the variables of the system."); return v.size() / 3; }