void PeriodicConditionLM2D2N::CalculateLocalSystem(MatrixType& rLeftHandSideMatrix, VectorType& rRightHandSideVector, ProcessInfo& rCurrentProcessInfo) { if(rLeftHandSideMatrix.size1() != 6 || rLeftHandSideMatrix.size2() != 6) rLeftHandSideMatrix.resize(6, 6,false); noalias(rLeftHandSideMatrix) = ZeroMatrix(6, 6); if(rRightHandSideVector.size() != 6) rRightHandSideVector.resize(6, false); noalias( rRightHandSideVector ) = ZeroVector(6); // Nodal IDs = [slave ID, master ID] GeometryType& geom = GetGeometry(); // get current values and form the system matrix Vector currentValues(6); currentValues(0) = geom[0].FastGetSolutionStepValue(DISPLACEMENT_X); currentValues(1) = geom[0].FastGetSolutionStepValue(DISPLACEMENT_Y); currentValues(2) = geom[1].FastGetSolutionStepValue(DISPLACEMENT_X); currentValues(3) = geom[1].FastGetSolutionStepValue(DISPLACEMENT_Y); currentValues(4) = geom[0].FastGetSolutionStepValue(DISPLACEMENT_LAGRANGE_X); currentValues(5) = geom[0].FastGetSolutionStepValue(DISPLACEMENT_LAGRANGE_Y); //KRATOS_WATCH(currentValues); rLeftHandSideMatrix(4,0) = 1.0; rLeftHandSideMatrix(4,2) = -1.0; rLeftHandSideMatrix(0,4) = 1.0; rLeftHandSideMatrix(2,4) = -1.0; rLeftHandSideMatrix(5,1) = 1.0; rLeftHandSideMatrix(5,3) = -1.0; rLeftHandSideMatrix(1,5) = 1.0; rLeftHandSideMatrix(3,5) = -1.0; // form residual noalias(rRightHandSideVector) -= prod( rLeftHandSideMatrix, currentValues ); }
void LinearSensor::initialize(const Model& m) { // Call initialize of base class ControlSensor::initialize(m); // consistency checks if (!_matC) { RuntimeException::selfThrow("LinearSensor::initialize - no C matrix was given"); } unsigned int colC = _matC->size(1); unsigned int rowC = _matC->size(0); // What happen here if we have more than one DS ? // This may be unlikely to happen. // _DS = _model->nonSmoothDynamicalSystem()->dynamicalSystemNumber(0); if (colC != _DS->getN()) { RuntimeException::selfThrow(" LinearSensor::initialize - The number of column of the C matrix must be equal to the length of x"); } if (_matD) { unsigned int rowD = _matD->size(0); if (rowC != rowD) { RuntimeException::selfThrow("C and D must have the same number of rows"); } } // --- Get the values --- // -> saved in a matrix data // -> event _storedY.reset(new SiconosVector(rowC)); // (_data[_eSensor])["StoredY"] = storedY; // set the dimension of the output *_storedY = prod(*_matC, *_DSx); }
void CState::makeBoxes(const vec3 systemSize, const double interactionLength) { ivec3 boxIndex; vec3 boxPos; NBoxes = conv_to<ivec>::from(floor(systemSize/interactionLength)); boxDimensions = systemSize/NBoxes; nBoxes = prod(NBoxes); boxes = vector<CBox*>(); boxes.reserve(nBoxes); boxes.resize(nBoxes); // using resize since we aren't using push_back to add items for (int ix = 0; ix < NBoxes(0); ix++) { for (int iy = 0; iy < NBoxes(1); iy++) { for (int iz = 0; iz < NBoxes(2); iz++) { boxIndex << ix << iy << iz; boxPos = boxIndex%boxDimensions; CBox* box = new CBox(nBoxes, boxPos, boxDimensions, boxIndex, NBoxes); boxes[calculate_box_number(boxIndex, NBoxes)] = box; } } } // finding all the neighbouring boxes of each box, taking into account the // periodic boundary conditions for (int i = 0; i < nBoxes; i++) boxes[i]->findNeighbours(systemSize); cout << "box dimensions (MD): " << boxDimensions.t() << " (SI): " << boxDimensions.t()*L0 << "system size (MD): " << systemSize.t() << " (SI): " << systemSize.t()*L0 << "number of boxes : " << nBoxes << endl << endl; }
void CombatCamera::ViewportRay(double screen_x, double screen_y, double out_ray_origin[3], double out_ray_direction[3]) const { Matrix projection(4, 4); std::copy(m_camera.getProjectionMatrix()[0], m_camera.getProjectionMatrix()[0] + 16, projection.data().begin()); Matrix view(4, 4); std::copy(m_camera.getViewMatrix(true)[0], m_camera.getViewMatrix(true)[0] + 16, view.data().begin()); Matrix inverse_vp = Inverse4(prod(projection, view)); double nx = (2.0 * screen_x) - 1.0; double ny = 1.0 - (2.0 * screen_y); Matrix near_point(3, 1); near_point(0, 0) = nx; near_point(1, 0) = ny; near_point(2, 0) = -1.0; // Use mid_point rather than far point to avoid issues with infinite projection Matrix mid_point(3, 1); mid_point(0, 0) = nx; mid_point(1, 0) = ny; mid_point(2, 0) = 0.0; // Get ray origin and ray target on near plane in world space Matrix ray_origin = Matrix4xVector3(inverse_vp, near_point); Matrix ray_target = Matrix4xVector3(inverse_vp, mid_point); Matrix ray_direction = ray_target - ray_origin; ray_direction /= ray_direction(0, 0) * ray_direction(0, 0) + ray_direction(1, 0) * ray_direction(1, 0) + ray_direction(2, 0) * ray_direction(2, 0); std::copy(ray_origin.data().begin(), ray_origin.data().end(), out_ray_origin); std::copy(ray_direction.data().begin(), ray_direction.data().end(), out_ray_direction); }
// Update inverse a1 after row in matrix a has changed // get new row out of array1 newRow // // a1 = old inverse // newRow = new row lRow in new matrix a_new // returns Det(a_old)/Det(a_new) doublevar InverseUpdateRow(Array2 <doublevar> & a1, const Array1 <doublevar> & newRow, const int lRow, const int n) { Array1 <doublevar> & tmpColL(tmp11); tmpColL.Resize(n); Array1 <doublevar> & prod(tmp12); prod.Resize(n); doublevar f=0.0; for(int i=0;i<n;++i) { f += newRow[i]*a1(i,lRow); } f =-1.0/f; for(int j=0;j<n;++j){ prod[j] =0.0; tmpColL[j]=a1(j,lRow); for(int i=0;i<n;++i) { prod[j] += newRow[i]*a1(i,j); } prod[j] *= f; } for(int i=0;i<n;++i) { doublevar & t(tmpColL[i]); for(int j=0;j<n;++j) { a1(i,j) += t*prod[j]; } } f = -f; for(int i=0;i<n;++i) { a1(i,lRow) = f*tmpColL[i]; } return f; }
// This algorithm factors each element a ∈ S over P if P is a base for S; otherwise it proclaims failure. // // Algorithm 21.2 [PDF page 27](http://cr.yp.to/lineartime/dcba-20040404.pdf) // // See [findfactors test](test-findfactors.html) for basic usage. void find_factors(mpz_array *out, mpz_t *s, size_t from, size_t to, mpz_array *p) { mpz_t x, y, z; mpz_array d, q; size_t i, n = to - from; mpz_init(x); array_prod(p, x); mpz_init(y); prod(y, s, from, to); mpz_init(z); ppi(z, x, y); array_init(&d, p->size); array_split(&d, z, p); array_init(&q, p->size); for (i = 0; i < p->used; i++) { if (mpz_cmp(d.array[i], p->array[i]) == 0) array_add(&q, p->array[i]); } if (n == 0) { array_find_factor(out, y, &q); } else { find_factors(out, s, from, to - n/2 - 1, &q); find_factors(out, s, to - n/2, to, &q); } mpz_clear(x); mpz_clear(y); mpz_clear(z); array_clear(&d); array_clear(&q); }
ProbabilityDistribution* StudentTProcessJeffreys::prediction(const vectord &query ) { clock_t start = clock(); double kq = computeSelfCorrelation(query); // vectord kn = computeCrossCorrelation(query); mKernel.computeCrossCorrelation(mData.mX,query,mKn); vectord phi = mMean.getFeatures(query); // vectord v(mKn); inplace_solve(mL,mKn,ublas::lower_tag()); vectord rho = phi - prod(mKn,mKF); // vectord rho(rq); inplace_solve(mL2,rho,ublas::lower_tag()); double yPred = inner_prod(phi,mWML) + inner_prod(mKn,mAlphaF); double sPred = sqrt( mSigma * (kq - inner_prod(mKn,mKn) + inner_prod(rho,rho))); d_->setMeanAndStd(yPred,sPred); return d_; }
void AbstractMaterialLaw<DIM>::ComputeCauchyStress(c_matrix<double,DIM,DIM>& rF, double pressure, c_matrix<double,DIM,DIM>& rSigma) { double detF = Determinant(rF); c_matrix<double,DIM,DIM> C = prod(trans(rF), rF); c_matrix<double,DIM,DIM> invC = Inverse(C); c_matrix<double,DIM,DIM> T; static FourthOrderTensor<DIM,DIM,DIM,DIM> dTdE; // not filled in, made static for efficiency ComputeStressAndStressDerivative(C, invC, pressure, T, dTdE, false); /* * Looping is probably more eficient then doing rSigma = (1/detF)*rF*T*transpose(rF), * which doesn't seem to compile anyway, as rF is a Tensor<2,DIM> and T is a * SymmetricTensor<2,DIM>. */ for (unsigned i=0; i<DIM; i++) { for (unsigned j=0; j<DIM; j++) { rSigma(i,j) = 0.0; for (unsigned M=0; M<DIM; M++) { for (unsigned N=0; N<DIM; N++) { rSigma(i,j) += rF(i,M)*T(M,N)*rF(j,N); } } rSigma(i,j) /= detF; } } }
void SlidingReducedOrderObserver::process() { DEBUG_BEGIN("void SlidingReducedOrderObserver::process()\n"); if (!_pass) { DEBUG_PRINT("First pass \n "); _pass = true; //update the estimate using the first value of y, such that C\hat{x}_0 = y_0 const SiconosVector& y = _sensor->y(); _e->zero(); prod(*_C, *_xHat, *_e); *_e -= y; SiconosVector tmpV(_DS->n()); SimpleMatrix tmpC(*_C); for (unsigned int i = 0; i < _e->size(); ++i) tmpV(i) = (*_e)(i); tmpC.SolveByLeastSquares(tmpV); *(_xHat) -= tmpV; *(_DS->x()) -= tmpV; _DS->initMemory(1); _DS->swapInMemory(); DEBUG_EXPR(_DS->display(););
microseconds NestedExpr::boost_ublas(const Args & args, std::mt19937 & gen) { std::cout << "Test: boost uBLAS "; const NestedExprArgs & cur_args = dynamic_cast<const NestedExprArgs&>(args); uint32_t m = cur_args.matrix_size; uint32_t matr_size = m * m; boost::numeric::ublas::matrix<double> A(m, m), B(m, m), C(m, m), D(m, m), E(m,m); initialize(A.data().begin(), A.data().end(), gen); initialize(B.data().begin(), B.data().end(), gen); initialize(C.data().begin(), C.data().end(), gen); initialize(D.data().begin(), D.data().end(), gen); auto start = std::chrono::high_resolution_clock::now(); noalias(E) = prod( A + B, C - D ); auto end = std::chrono::high_resolution_clock::now(); auto time = std::chrono::duration_cast<std::chrono::microseconds>( end - start); std::cout << time.count() << std::endl; return time; }
static void fftn_c2r(const Rcomplex *z, R_len_t rank, const R_len_t *N, double *res) { SEXP rTrue, cA, dim, Res; R_len_t n = prod(rank, N), i; rTrue = PROTECT(allocVector(LGLSXP, 1)); LOGICAL(rTrue)[0] = 1; cA = PROTECT(allocVector(CPLXSXP, n)); memcpy(COMPLEX(cA), z, sizeof(Rcomplex) * n); dim = PROTECT(allocVector(INTSXP, rank)); memcpy(INTEGER(dim), N, sizeof(R_len_t) * rank); setAttrib(cA, R_DimSymbol, dim); Res = PROTECT(eval(lang3(install("fft"), cA, rTrue), R_GlobalEnv)); /* Return result */ for (i = 0; i < n; ++i) res[i] = COMPLEX(Res)[i].r; /* Unprotect all */ UNPROTECT(4); }
int vp(const my_point &a, const my_point &b, const my_point &c) { double t[12]; std::pair<double, double> tmp; tmp = prod(b.x, c.y); t[0] = tmp.first; t[1] = tmp.second; tmp = prod(-b.x, a.y); t[2] = tmp.first; t[3] = tmp.second; tmp = prod(-a.x, c.y); t[4] = tmp.first; t[5] = tmp.second; tmp = prod(-b.y, c.x); t[6] = tmp.first; t[7] = tmp.second; tmp = prod(b.y, a.x); t[8] = tmp.first; t[9] = tmp.second; tmp = prod(a.y, c.x); t[10] = tmp.first; t[11] = tmp.second; exp_sum(t, t + 2, 2, 2); exp_sum(t + 4, t + 6, 2, 2); exp_sum(t + 8, t + 10, 2, 2); exp_sum(t, t + 4, 4, 4); exp_sum(t, t + 8, 8, 4); for (int i = 11; i >= 0; i--) { if (t[i] > 0) return 1; if (t[i] < 0) return -1; } return 0; }
void PlaneStressJ2::CalculateMaterialResponse(const Vector& StrainVector, const Matrix& DeformationGradient, Vector& StressVector, Matrix& AlgorithmicTangent, const ProcessInfo& CurrentProcessInfo, const Properties& props, const GeometryType& geom, const Vector& ShapeFunctionsValues, bool CalculateStresses, int CalculateTangent, bool SaveInternalVariables) { KRATOS_TRY mE = props.GetValue(YOUNG_MODULUS); mNU = props.GetValue(POISSON_RATIO); msigma_y = props.GetValue(YIELD_STRESS); mH = 0.0; mtheta = 0.0; // double theta = 0.0; //resize output quantities if (StressVector.size() != 3 && CalculateStresses == true) StressVector.resize(3, false); if (AlgorithmicTangent.size1() != 3 && CalculateTangent != 0) AlgorithmicTangent.resize(3, 3, false); array_1d<double, 3 > elastic_strain; noalias(elastic_strain) = StrainVector; noalias(elastic_strain) -= mOldPlasticStrain; // KRATOS_WATCH(StrainVector); // KRATOS_WATCH(mOldPlasticStrain); boost::numeric::ublas::bounded_matrix<double, 3, 3 > C, Cinv, P; CalculateElasticMatrix(C); CalculateInverseElasticMatrix(Cinv); CalculateP(P); // KRATOS_WATCH(C); array_1d<double, 3 > s_trial = prod(C, elastic_strain); array_1d<double, 3 > xi_trial = s_trial; noalias(s_trial) -= mbeta_old; // KRATOS_WATCH(compute_f_trial(xi_trial, malpha_old)); // double fbar2 = fbar_2(0.0, xi_trial); // double fbar_value = sqrt(fbar_2(0.0, xi_trial)); // double r2_value = R_2(0.0, fbar_value, malpha_old); // double aaa = fbar_value - sqrt(r2_value); // KRATOS_WATCH(sqrt(r2_value)); // KRATOS_WATCH(fbar_value); // KRATOS_WATCH(sqrt(r2_value)); // KRATOS_WATCH(aaa); double H1 = (1.0 - mtheta) * mH; //// KRATOS_WATCH(xi_trial); // KRATOS_WATCH(mbeta_old) if (compute_f_trial(xi_trial, malpha_old) < 0) //elastic case { if (CalculateStresses == true) noalias(StressVector) = s_trial; if (CalculateTangent != 0) noalias(AlgorithmicTangent) = C; //note that in this case internal variables are not modified! } else { //algorithm copied identically from the Simo Hughes, BOX3.3, pag 130 double dgamma = ComputeDGamma(xi_trial, malpha_old); double ccc = 0.6666666666666667 * dgamma*H1; // KRATOS_WATCH(dgamma); // KRATOS_WATCH(xi_trial); // KRATOS_WATCH(malpha_old); //calculate XImat //note that here i reuse the C as auxiliary variable as i don't need it anymore boost::numeric::ublas::bounded_matrix<double, 3, 3 > XImat; noalias(C) = Cinv; noalias(C) += (dgamma / (1.0 + ccc)) * P; double detC; InvertMatrix(C, XImat, detC); // KRATOS_WATCH(XImat); array_1d<double, 3 > aux, xi; noalias(aux) = prod(Cinv, xi_trial); noalias(xi) = prod(XImat, aux); xi /= (1.0 + ccc); // KRATOS_WATCH(compute_f_trial(xi, malpha_old)); noalias(mbeta_n1) = mbeta_old; noalias(mbeta_n1) += ccc*xi; array_1d<double, 3 > stress; noalias(stress) = xi; noalias(stress) += mbeta_n1; if (CalculateStresses == true) noalias(StressVector) = s_trial; malpha_current = malpha_old + sqrt(0.6666666666666667) * dgamma * sqrt(fbar_2(dgamma, xi)); //KRATOS_WATCH(StressVector); noalias(aux) = prod(P, xi); noalias(mCurrentPlasticStrain) = mOldPlasticStrain; noalias(mCurrentPlasticStrain) += dgamma*aux; if (CalculateTangent != 0) { noalias(AlgorithmicTangent) = XImat; // //compute tangent // array_1d<double, 3 > XPXi = prod(XImat, aux); // // double K1_n1 = theta*mH; //msigma_y + theta * mH*alpha; // // double K1_n1 = msigma_y + theta * mH*alpha; // double theta1 = 1.0 + 0.6666666666666667 * H1*dgamma; // double theta2 = 1.0 - 0.6666666666666667 * K1_n1*dgamma; // double beta_val = inner_prod(xi, aux); // beta_val *= 0.6666666666666667 * (theta1 / theta2) * (K1_n1 * theta1 + H1 * theta2); // // double denom = inner_prod(aux, XPXi); // denom += beta_val; // denom = sqrt(denom); // XPXi /= denom; // // noalias(AlgorithmicTangent) = XImat; // noalias(AlgorithmicTangent) -= outer_prod(XPXi, XPXi); } //KRATOS_WATCH(algorithmicTangent); // noalias(AlgorithmicTangent) = C; } KRATOS_CATCH("") }
int test_main (int, char *[]) { prod(matrix_3x1(), matrix_3x1()); return 0; }
void UZRectMollerup::tick (const GeometryRect& geo, const std::vector<size_t>& drain_cell, const double drain_water_level, const Soil& soil, SoilWater& soil_water, const SoilHeat& soil_heat, const Surface& surface, const Groundwater& groundwater, const double dt, Treelog& msg) { daisy_assert (K_average.get ()); const size_t edge_size = geo.edge_size (); // number of edges const size_t cell_size = geo.cell_size (); // number of cells // Insert magic here. ublas::vector<double> Theta (cell_size); // water content ublas::vector<double> Theta_previous (cell_size); // at start of small t-step ublas::vector<double> h (cell_size); // matrix pressure ublas::vector<double> h_previous (cell_size); // at start of small timestep ublas::vector<double> h_ice (cell_size); // ublas::vector<double> S (cell_size); // sink term ublas::vector<double> S_vol (cell_size); // sink term #ifdef TEST_OM_DEN_ER_BRUGT ublas::vector<double> S_macro (cell_size); // sink term std::vector<double> S_drain (cell_size, 0.0); // matrix-> macro -> drain flow std::vector<double> S_drain_sum (cell_size, 0.0); // For large timestep const std::vector<double> S_matrix (cell_size, 0.0); // matrix -> macro std::vector<double> S_matrix_sum (cell_size, 0.0); // for large timestep #endif ublas::vector<double> T (cell_size); // temperature ublas::vector<double> Kold (edge_size); // old hydraulic conductivity ublas::vector<double> Ksum (edge_size); // Hansen hydraulic conductivity ublas::vector<double> Kcell (cell_size); // hydraulic conductivity ublas::vector<double> Kold_cell (cell_size); // old hydraulic conductivity ublas::vector<double> Ksum_cell (cell_size); // Hansen hydraulic conductivity ublas::vector<double> h_lysimeter (cell_size); std::vector<bool> active_lysimeter (cell_size); const std::vector<size_t>& edge_above = geo.cell_edges (Geometry::cell_above); const size_t edge_above_size = edge_above.size (); ublas::vector<double> remaining_water (edge_above_size); std::vector<bool> drain_cell_on (drain_cell.size (),false); for (size_t i = 0; i < edge_above_size; i++) { const size_t edge = edge_above[i]; remaining_water (i) = surface.h_top (geo, edge); } ublas::vector<double> q; // Accumulated flux q = ublas::zero_vector<double> (edge_size); ublas::vector<double> dq (edge_size); // Flux in small timestep. dq = ublas::zero_vector<double> (edge_size); //Make Qmat area diagonal matrix //Note: This only needs to be calculated once... ublas::banded_matrix<double> Qmat (cell_size, cell_size, 0, 0); for (int c = 0; c < cell_size; c++) Qmat (c, c) = geo.cell_volume (c); // make vectors for (size_t cell = 0; cell != cell_size ; ++cell) { Theta (cell) = soil_water.Theta (cell); h (cell) = soil_water.h (cell); h_ice (cell) = soil_water.h_ice (cell); S (cell) = soil_water.S_sum (cell); S_vol (cell) = S (cell) * geo.cell_volume (cell); if (use_forced_T) T (cell) = forced_T; else T (cell) = soil_heat.T (cell); h_lysimeter (cell) = geo.zplus (cell) - geo.cell_z (cell); } // Remember old value. Theta_error = Theta; // Start time loop double time_left = dt; // How much of the large time step left. double ddt = dt; // We start with small == large time step. int number_of_time_step_reductions = 0; int iterations_with_this_time_step = 0; int n_small_time_steps = 0; while (time_left > 0.0) { if (ddt > time_left) ddt = time_left; std::ostringstream tmp_ddt; tmp_ddt << "Time t = " << (dt - time_left) << "; ddt = " << ddt << "; steps " << n_small_time_steps << "; time left = " << time_left; Treelog::Open nest (msg, tmp_ddt.str ()); if (n_small_time_steps > 0 && (n_small_time_steps%msg_number_of_small_time_steps) == 0) { msg.touch (); msg.flush (); } n_small_time_steps++; if (n_small_time_steps > max_number_of_small_time_steps) { msg.debug ("Too many small timesteps"); throw "Too many small timesteps"; } // Initialization for each small time step. if (debug > 0) { std::ostringstream tmp; tmp << "h = " << h << "\n"; tmp << "Theta = " << Theta; msg.message (tmp.str ()); } int iterations_used = 0; h_previous = h; Theta_previous = Theta; if (debug == 5) { std::ostringstream tmp; tmp << "Remaining water at start: " << remaining_water; msg.message (tmp.str ()); } ublas::vector<double> h_conv; for (size_t cell = 0; cell != cell_size ; ++cell) active_lysimeter[cell] = h (cell) > h_lysimeter (cell); for (size_t edge = 0; edge != edge_size ; ++edge) { Kold[edge] = find_K_edge (soil, geo, edge, h, h_ice, h_previous, T); Ksum [edge] = 0.0; } std::vector<top_state> state (edge_above.size (), top_undecided); // We try harder with smaller timesteps. const int max_loop_iter = max_iterations * (number_of_time_step_reductions * max_iterations_timestep_reduction_factor + 1); do // Start iteration loop { h_conv = h; iterations_used++; std::ostringstream tmp_conv; tmp_conv << "Convergence " << iterations_used; Treelog::Open nest (msg, tmp_conv.str ()); if (debug == 7) msg.touch (); // Calculate conductivity - The Hansen method for (size_t e = 0; e < edge_size; e++) { Ksum[e] += find_K_edge (soil, geo, e, h, h_ice, h_previous, T); Kedge[e] = (Ksum[e] / (iterations_used + 0.0)+ Kold[e]) / 2.0; } //Initialize diffusive matrix Solver::Matrix diff (cell_size); // diff = ublas::zero_matrix<double> (cell_size, cell_size); diffusion (geo, Kedge, diff); //Initialize gravitational matrix ublas::vector<double> grav (cell_size); //ublass compatibility grav = ublas::zero_vector<double> (cell_size); gravitation (geo, Kedge, grav); // Boundary matrices and vectors ublas::banded_matrix<double> Dm_mat (cell_size, cell_size, 0, 0); // Dir bc Dm_mat = ublas::zero_matrix<double> (cell_size, cell_size); ublas::vector<double> Dm_vec (cell_size); // Dir bc Dm_vec = ublas::zero_vector<double> (cell_size); ublas::vector<double> Gm (cell_size); // Dir bc Gm = ublas::zero_vector<double> (cell_size); ublas::vector<double> B (cell_size); // Neu bc B = ublas::zero_vector<double> (cell_size); lowerboundary (geo, groundwater, active_lysimeter, h, Kedge, dq, Dm_mat, Dm_vec, Gm, B, msg); upperboundary (geo, soil, T, surface, state, remaining_water, h, Kedge, dq, Dm_mat, Dm_vec, Gm, B, ddt, debug, msg, dt); Darcy (geo, Kedge, h, dq); //for calculating drain fluxes //Initialize water capacity matrix ublas::banded_matrix<double> Cw (cell_size, cell_size, 0, 0); for (size_t c = 0; c < cell_size; c++) Cw (c, c) = soil.Cw2 (c, h[c]); std::vector<double> h_std (cell_size); //ublas vector -> std vector std::copy(h.begin (), h.end (), h_std.begin ()); #ifdef TEST_OM_DEN_ER_BRUGT for (size_t cell = 0; cell != cell_size ; ++cell) { S_macro (cell) = (S_matrix[cell] + S_drain[cell]) * geo.cell_volume (cell); } #endif //Initialize sum matrix Solver::Matrix summat (cell_size); noalias (summat) = diff + Dm_mat; //Initialize sum vector ublas::vector<double> sumvec (cell_size); sumvec = grav + B + Gm + Dm_vec - S_vol #ifdef TEST_OM_DEN_ER_BRUGT - S_macro #endif ; // QCw is shorthand for Qmatrix * Cw Solver::Matrix Q_Cw (cell_size); noalias (Q_Cw) = prod (Qmat, Cw); //Initialize A-matrix Solver::Matrix A (cell_size); noalias (A) = (1.0 / ddt) * Q_Cw - summat; // Q_Cw_h is shorthand for Qmatrix * Cw * h const ublas::vector<double> Q_Cw_h = prod (Q_Cw, h); //Initialize b-vector ublas::vector<double> b (cell_size); //b = sumvec + (1.0 / ddt) * (Qmatrix * Cw * h + Qmatrix *(Wxx-Wyy)); b = sumvec + (1.0 / ddt) * (Q_Cw_h + prod (Qmat, Theta_previous-Theta)); // Force active drains to zero h. drain (geo, drain_cell, drain_water_level, h, Theta_previous, Theta, S_vol, #ifdef TEST_OM_DEN_ER_BRUGT S_macro, #endif dq, ddt, drain_cell_on, A, b, debug, msg); try { solver->solve (A, b, h); // Solve Ah=b with regard to h. } catch (const char *const error) { std::ostringstream tmp; tmp << "Could not solve equation system: " << error; msg.warning (tmp.str ()); // Try smaller timestep. iterations_used = max_loop_iter + 100; break; } for (int c=0; c < cell_size; c++) // update Theta Theta (c) = soil.Theta (c, h (c), h_ice (c)); if (debug > 1) { std::ostringstream tmp; tmp << "Time left = " << time_left << ", ddt = " << ddt << ", iteration = " << iterations_used << "\n"; tmp << "B = " << B << "\n"; tmp << "h = " << h << "\n"; tmp << "Theta = " << Theta; msg.message (tmp.str ()); } for (int c=0; c < cell_size; c++) { if (h (c) < min_pressure_potential || h (c) > max_pressure_potential) { std::ostringstream tmp; tmp << "Pressure potential out of realistic range, h[" << c << "] = " << h (c); msg.debug (tmp.str ()); iterations_used = max_loop_iter + 100; break; } } } while (!converges (h_conv, h) && iterations_used <= max_loop_iter); if (iterations_used > max_loop_iter) { number_of_time_step_reductions++; if (number_of_time_step_reductions > max_time_step_reductions) { msg.debug ("Could not find solution"); throw "Could not find solution"; } iterations_with_this_time_step = 0; ddt /= time_step_reduction; h = h_previous; Theta = Theta_previous; } else { // Update dq for new h. ublas::banded_matrix<double> Dm_mat (cell_size, cell_size, 0, 0); // Dir bc Dm_mat = ublas::zero_matrix<double> (cell_size, cell_size); ublas::vector<double> Dm_vec (cell_size); // Dir bc Dm_vec = ublas::zero_vector<double> (cell_size); ublas::vector<double> Gm (cell_size); // Dir bc Gm = ublas::zero_vector<double> (cell_size); ublas::vector<double> B (cell_size); // Neu bc B = ublas::zero_vector<double> (cell_size); lowerboundary (geo, groundwater, active_lysimeter, h, Kedge, dq, Dm_mat, Dm_vec, Gm, B, msg); upperboundary (geo, soil, T, surface, state, remaining_water, h, Kedge, dq, Dm_mat, Dm_vec, Gm, B, ddt, debug, msg, dt); Darcy (geo, Kedge, h, dq); #ifdef TEST_OM_DEN_ER_BRUGT // update macropore flow components for (int c = 0; c < cell_size; c++) { S_drain_sum[c] += S_drain[c] * ddt/dt; S_matrix_sum[c] += S_matrix[c] * ddt/dt; } #endif std::vector<double> h_std_new (cell_size); std::copy(h.begin (), h.end (), h_std_new.begin ()); // Update remaining_water. for (size_t i = 0; i < edge_above.size (); i++) { const int edge = edge_above[i]; const int cell = geo.edge_other (edge, Geometry::cell_above); const double out_sign = (cell == geo.edge_from (edge)) ? 1.0 : -1.0; remaining_water[i] += out_sign * dq (edge) * ddt; daisy_assert (std::isfinite (dq (edge))); } if (debug == 5) { std::ostringstream tmp; tmp << "Remaining water at end: " << remaining_water; msg.message (tmp.str ()); } // Contribution to large time step. daisy_assert (std::isnormal (dt)); daisy_assert (std::isnormal (ddt)); q += dq * ddt / dt; for (size_t e = 0; e < edge_size; e++) { daisy_assert (std::isfinite (dq (e))); daisy_assert (std::isfinite (q (e))); } for (size_t e = 0; e < edge_size; e++) { daisy_assert (std::isfinite (dq (e))); daisy_assert (std::isfinite (q (e))); } time_left -= ddt; iterations_with_this_time_step++; if (iterations_with_this_time_step > time_step_reduction) { number_of_time_step_reductions--; iterations_with_this_time_step = 0; ddt *= time_step_reduction; } } // End of small time step. } // Mass balance. // New = Old - S * dt + q_in * dt - q_out * dt + Error => // 0 = Old - New - S * dt + q_in * dt - q_out * dt + Error Theta_error -= Theta; // Old - New Theta_error -= S * dt; #ifdef TEST_OM_DEN_ER_BRUGT for (size_t c = 0; c < cell_size; c++) Theta_error (c) -= (S_matrix_sum[c] + S_drain_sum[c]) * dt; #endif for (size_t edge = 0; edge != edge_size; ++edge) { const int from = geo.edge_from (edge); const int to = geo.edge_to (edge); const double flux = q (edge) * geo.edge_area (edge) * dt; if (geo.cell_is_internal (from)) Theta_error (from) -= flux / geo.cell_volume (from); if (geo.cell_is_internal (to)) Theta_error (to) += flux / geo.cell_volume (to); } // Find drain sink from mass balance. #ifdef TEST_OM_DEN_ER_BRUGT std::fill(S_drain.begin (), S_drain.end (), 0.0); #else std::vector<double> S_drain (cell_size); #endif for (size_t i = 0; i < drain_cell.size (); i++) { const size_t cell = drain_cell[i]; S_drain[cell] = Theta_error (cell) / dt; Theta_error (cell) -= S_drain[cell] * dt; } if (debug == 2) { double total_error = 0.0; double total_abs_error = 0.0; double max_error = 0.0; int max_cell = -1; for (size_t cell = 0; cell != cell_size; ++cell) { const double volume = geo.cell_volume (cell); const double error = Theta_error (cell); total_error += volume * error; total_abs_error += std::fabs (volume * error); if (std::fabs (error) > std::fabs (max_error)) { max_error = error; max_cell = cell; } } std::ostringstream tmp; tmp << "Total error = " << total_error << " [cm^3], abs = " << total_abs_error << " [cm^3], max = " << max_error << " [] in cell " << max_cell; msg.message (tmp.str ()); } // Make it official. for (size_t cell = 0; cell != cell_size; ++cell) soil_water.set_content (cell, h (cell), Theta (cell)); #ifdef TEST_OM_DEN_ER_BRUGT soil_water.add_tertiary_sink (S_matrix_sum); soil_water.drain (S_drain_sum, msg); #endif for (size_t edge = 0; edge != edge_size; ++edge) { daisy_assert (std::isfinite (q[edge])); soil_water.set_flux (edge, q[edge]); } soil_water.drain (S_drain, msg); // End of large time step. }
double ModelFunction::operator()(const vector< double > &x) const { // NOTE: the constant is not included return inner_prod(x, prod(A_, x))/2.0 + inner_prod(b_, x); }
const vector< double > &ModelFunction::g(const vector< double > &x, vector< double > &g) { g = prod(A_, x) + b_; return g; }
Interval LDB::operator ()(const LDB::ipolynomial_type *poly_ptr, const LDB::additional_var_data *data_ptr ) const { unsigned int data_size = data_ptr->size(); /* Abspalten der linearen Terme. Die Konstante wird den hoeheren Termen zugerechnet. Gleichzeitig werden die hoeheren Terme eingeschlossen. */ Interval rest(0.0); std::vector<Interval> arguments( data_ptr->size() ); for(unsigned int i = 0; i < data_size; i++) if( (*data_ptr)[ i ].operator ->() != 0 ) arguments[ i ] = ((*data_ptr)[ i ])->domain_ - ((*data_ptr)[ i ])->devel_point_; std::vector<Interval> linear_coeffs(data_size, Interval(0.0)); std::vector<unsigned int> var_codes; var_codes.reserve(data_size); //Codes of Vars with linear term. LDB::ipolynomial_type::const_iterator curr = poly_ptr->begin(), last = poly_ptr->end(); while( curr != last ) { if( curr->key().expnt_sum() == 0 ) //Konstanter Term. { rest += curr->value(); } else if( curr->key().expnt_sum() == 1 ) //Linearer Term. { unsigned int i = curr->key().min_var_code(); var_codes.push_back(i-1); linear_coeffs[i-1] = curr->value(); } else //Nonlinear term. { Interval prod(1.0); //Evaluate the current monomial. for(unsigned int i = curr->key().min_var_code(); i <= curr->key().max_var_code(); i++) { unsigned int e = curr->key().expnt_of_var(i); if( e != 0 ) { prod *= power( arguments[i-1], e ); } } //Multiply with coefficient. prod *= curr->value(); //Add enclosure to bound interval. rest += prod; } ++curr; } if( var_codes.size() == 0 ) return rest; //No linear terms in polynomial. So return with enclosure of //higher order terms. /* Lokale Kopien der 'Domains' anlegen, da diese im weiteren Verlauf unter Umstaenden veraendert werden. */ std::vector<Interval> domain_of_max(data_size,Interval(0.0)); std::vector<Interval> domain_of_min(data_size,Interval(0.0)); for(unsigned int i = 0; i < data_size; i++) { if( (*data_ptr)[i].operator ->() ) //There is information. { domain_of_max[i] = domain_of_min[i] = ((*data_ptr)[i])->domain_; } } /* Jetzt beginnt der Algorithmus des LDB range bounders. */ Interval idelta(rest.diam()); for(unsigned int i = 0; i < var_codes.size(); i++) { unsigned int k = var_codes[i]; Interval b = linear_coeffs[k]; idelta += b.diam() * abs( ((*data_ptr)[k])->domain_ - ((*data_ptr)[k])->devel_point_ ); } double delta = idelta.sup(); bool resizing = false; for(unsigned int i = 0; i < var_codes.size(); i++) { unsigned int k = var_codes[i]; double mid_b = linear_coeffs[k].mid(); Interval abs_b = Interval( std::abs(mid_b) ); Interval domain = ((*data_ptr)[k])->domain_; Interval upper = abs_b * domain.diam(); if( upper.inf() > delta ) { Interval tmp = delta / abs_b; if( mid_b > 0 ) { domain_of_min[k] = domain_of_min[k].inf() + Interval(0,tmp.sup()); domain_of_max[k] = domain_of_max[k].sup() - Interval(0,tmp.sup()); } else { domain_of_min[k] = domain_of_min[k].sup() - Interval(0,tmp.sup()); domain_of_max[k] = domain_of_max[k].inf() + Interval(0,tmp.sup()); } resizing = true; } } for(unsigned int i = 0; i < data_size; i++) { if( (*data_ptr)[i].operator ->() ) //There is information. { domain_of_min[i] -= ((*data_ptr)[i])->devel_point_; domain_of_max[i] -= ((*data_ptr)[i])->devel_point_; } } if( resizing ) //Die Domains wurden verändert. { Interval min(0.0),max(0.0); curr = poly_ptr->begin(); while( curr != last ) //Walk trough the polynomial. { Interval prod1(1.0),prod2(1.0); //Evaluate the current monomial. for(unsigned int i = (*curr).key().min_var_code(); i <= (*curr).key().max_var_code(); i++) { unsigned int e = (*curr).key().expnt_of_var(i); if( e != 0 ) { prod1 *= power( domain_of_min[ i - 1 ], e ); prod2 *= power( domain_of_max[ i - 1 ], e ); } } //Multiply with coefficient. prod1 *= (*curr).value(); // <---- Multiply with double value. prod2 *= (*curr).value(); // <---- Multiply with double value. //Add enclosure to interval. min += prod1; max += prod2; ++curr; } return Interval( min.inf(), max.sup() ); } else { for(unsigned int i = 0; i < var_codes.size(); i++) { unsigned int k = var_codes[i]; rest += linear_coeffs[k] * domain_of_min[k]; } return rest; } }
types::ndarray<T,N - 1> prod(types::ndarray<T,N> const& array, long axis) { if(axis<0 || axis >=long(N)) throw types::ValueError("axis out of bounds"); auto shape = array.shape; if(axis==0) { types::array<long, N> shp; shp[0] = 1; std::copy(shape.begin() + 1, shape.end(), shp.begin() + 1); types::ndarray<T,N> out(shp, 1); return std::accumulate(array.begin(), array.end(), *out.begin(), proxy::multiply()); } else { types::array<long, N-1> shp; std::copy(shape.begin(), shape.end() - 1, shp.begin()); types::ndarray<T,N-1> prody(shp, __builtin__::None); std::transform(array.begin(), array.end(), prody.begin(), [=](types::ndarray<T,N-1> const& other) {return prod(other, axis-1);}); return prody; } }
int main (int, const char **) { typedef float ScalarType; //feel free to change this to 'double' if supported by your hardware typedef boost::numeric::ublas::matrix<ScalarType> MatrixType; typedef viennacl::matrix<ScalarType, viennacl::row_major> VCLMatrixType; std::size_t dim_large = 5; std::size_t dim_small = 3; // // Setup ublas objects and fill with data: // MatrixType ublas_A(dim_large, dim_large); MatrixType ublas_B(dim_small, dim_small); MatrixType ublas_C(dim_large, dim_small); MatrixType ublas_D(dim_small, dim_large); for (std::size_t i=0; i<ublas_A.size1(); ++i) for (std::size_t j=0; j<ublas_A.size2(); ++j) ublas_A(i,j) = static_cast<ScalarType>((i+1) + (j+1)*(i+1)); for (std::size_t i=0; i<ublas_B.size1(); ++i) for (std::size_t j=0; j<ublas_B.size2(); ++j) ublas_B(i,j) = static_cast<ScalarType>((i+1) + (j+1)*(i+1)); for (std::size_t i=0; i<ublas_C.size1(); ++i) for (std::size_t j=0; j<ublas_C.size2(); ++j) ublas_C(i,j) = static_cast<ScalarType>((j+2) + (j+1)*(i+1)); for (std::size_t i=0; i<ublas_D.size1(); ++i) for (std::size_t j=0; j<ublas_D.size2(); ++j) ublas_D(i,j) = static_cast<ScalarType>((j+2) + (j+1)*(i+1)); // // Extract submatrices using the ranges in ublas // boost::numeric::ublas::range ublas_r1(0, dim_small); //the first 'dim_small' entries boost::numeric::ublas::range ublas_r2(dim_large - dim_small, dim_large); //the last 'dim_small' entries boost::numeric::ublas::matrix_range<MatrixType> ublas_A_sub1(ublas_A, ublas_r1, ublas_r1); //upper left part of A boost::numeric::ublas::matrix_range<MatrixType> ublas_A_sub2(ublas_A, ublas_r2, ublas_r2); //lower right part of A boost::numeric::ublas::matrix_range<MatrixType> ublas_C_sub(ublas_C, ublas_r1, ublas_r1); //upper left part of C boost::numeric::ublas::matrix_range<MatrixType> ublas_D_sub(ublas_D, ublas_r1, ublas_r1); //upper left part of D // // Setup ViennaCL objects // VCLMatrixType vcl_A(dim_large, dim_large); VCLMatrixType vcl_B(dim_small, dim_small); VCLMatrixType vcl_C(dim_large, dim_small); VCLMatrixType vcl_D(dim_small, dim_large); viennacl::copy(ublas_A, vcl_A); viennacl::copy(ublas_B, vcl_B); viennacl::copy(ublas_C, vcl_C); viennacl::copy(ublas_D, vcl_D); // // Extract submatrices using the ranges in ViennaCL // viennacl::range vcl_r1(0, dim_small); //the first 'dim_small' entries viennacl::range vcl_r2(dim_large - dim_small, dim_large); //the last 'dim_small' entries viennacl::matrix_range<VCLMatrixType> vcl_A_sub1(vcl_A, vcl_r1, vcl_r1); //upper left part of A viennacl::matrix_range<VCLMatrixType> vcl_A_sub2(vcl_A, vcl_r2, vcl_r2); //lower right part of A viennacl::matrix_range<VCLMatrixType> vcl_C_sub(vcl_C, vcl_r1, vcl_r1); //upper left part of C viennacl::matrix_range<VCLMatrixType> vcl_D_sub(vcl_D, vcl_r1, vcl_r1); //upper left part of D // // Copy from ublas to submatrices and back: // ublas_A_sub1 = ublas_B; viennacl::copy(ublas_B, vcl_A_sub1); viennacl::copy(vcl_A_sub1, ublas_B); // // Addition: // // range to range: ublas_A_sub2 += ublas_A_sub2; vcl_A_sub2 += vcl_A_sub2; // range to matrix: ublas_B += ublas_A_sub2; vcl_B += vcl_A_sub2; // // use matrix range with matrix-matrix product: // ublas_A_sub1 += prod(ublas_C_sub, ublas_D_sub); vcl_A_sub1 += viennacl::linalg::prod(vcl_C_sub, vcl_D_sub); // // Print result matrices: // std::cout << "Result ublas: " << ublas_A << std::endl; std::cout << "Result ViennaCL: " << vcl_A << std::endl; // // That's it. // std::cout << "!!!! TUTORIAL COMPLETED SUCCESSFULLY !!!!" << std::endl; return EXIT_SUCCESS; }
void AxisymUpdatedLagrangianElement::FinalizeStepVariables( GeneralVariables & rVariables, const double& rPointNumber ) { //update internal (historical) variables mDeterminantF0[rPointNumber] = rVariables.detF * rVariables.detF0; mDeformationGradientF0[rPointNumber] = prod(rVariables.F, rVariables.F0); }
int main (int, const char **) { typedef double ScalarType; //feel free to change this to 'double' if supported by your hardware typedef boost::numeric::ublas::matrix<ScalarType> MatrixType; typedef boost::numeric::ublas::vector<ScalarType> VectorType; typedef viennacl::matrix<ScalarType, viennacl::column_major> VCLMatrixType; typedef viennacl::vector<ScalarType> VCLVectorType; std::size_t rows = 113; //number of rows in the matrix std::size_t cols = 54; //number of columns // // Create matrices with some data // MatrixType ublas_A(rows, cols); MatrixType Q(rows, rows); MatrixType R(rows, cols); // Some random data with a bit of extra weight on the diagonal for (std::size_t i=0; i<rows; ++i) { for (std::size_t j=0; j<cols; ++j) { ublas_A(i,j) = -1.0 + (i+1)*(j+1) + ( (rand() % 1000) - 500.0) / 1000.0; if (i == j) ublas_A(i,j) += 10.0; R(i,j) = 0.0; } for (std::size_t j=0; j<rows; ++j) Q(i,j) = 0.0; } // keep initial input matrix for comparison MatrixType ublas_A_backup(ublas_A); // // Setup the matrix in ViennaCL: // VCLVectorType dummy(10); VCLMatrixType vcl_A(ublas_A.size1(), ublas_A.size2()); viennacl::copy(ublas_A, vcl_A); // // Compute QR factorization of A. A is overwritten with Householder vectors. Coefficients are returned and a block size of 3 is used. // Note that at the moment the number of columns of A must be divisible by the block size // std::cout << "--- Boost.uBLAS ---" << std::endl; std::vector<ScalarType> ublas_betas = viennacl::linalg::inplace_qr(ublas_A); //computes the QR factorization // // A check for the correct result: // viennacl::linalg::recoverQ(ublas_A, ublas_betas, Q, R); MatrixType ublas_QR = prod(Q, R); double ublas_error = check(ublas_QR, ublas_A_backup); std::cout << "Max rel error (ublas): " << ublas_error << std::endl; // // QR factorization in ViennaCL using Boost.uBLAS for the panel factorization // std::cout << "--- Hybrid (default) ---" << std::endl; viennacl::copy(ublas_A_backup, vcl_A); std::vector<ScalarType> hybrid_betas = viennacl::linalg::inplace_qr(vcl_A); // // A check for the correct result: // viennacl::copy(vcl_A, ublas_A); Q.clear(); R.clear(); viennacl::linalg::recoverQ(ublas_A, hybrid_betas, Q, R); double hybrid_error = check(ublas_QR, ublas_A_backup); std::cout << "Max rel error (hybrid): " << hybrid_error << std::endl; // // That's it. // std::cout << "!!!! TUTORIAL COMPLETED SUCCESSFULLY !!!!" << std::endl; return EXIT_SUCCESS; }
Stokhos::MonoProjPCEBasis<ordinal_type, value_type>:: MonoProjPCEBasis( ordinal_type p, const Stokhos::OrthogPolyApprox<ordinal_type, value_type>& pce, const Stokhos::Quadrature<ordinal_type, value_type>& quad, const Stokhos::Sparse3Tensor<ordinal_type, value_type>& Cijk, bool limit_integration_order_) : RecurrenceBasis<ordinal_type, value_type>("Monomial Projection", p, true), limit_integration_order(limit_integration_order_), pce_sz(pce.basis()->size()), pce_norms(pce.basis()->norm_squared()), a(pce_sz), b(pce_sz), basis_vecs(pce_sz, p+1), new_pce(p+1) { // If the original basis is normalized, we can use the standard QR // factorization. For simplicity, we renormalize the PCE coefficients // for a normalized basis Stokhos::OrthogPolyApprox<ordinal_type, value_type> normalized_pce(pce); for (ordinal_type i=0; i<pce_sz; i++) { pce_norms[i] = std::sqrt(pce_norms[i]); normalized_pce[i] *= pce_norms[i]; } // Evaluate PCE at quad points ordinal_type nqp = quad.size(); Teuchos::Array<value_type> pce_vals(nqp); const Teuchos::Array<value_type>& weights = quad.getQuadWeights(); const Teuchos::Array< Teuchos::Array<value_type> >& quad_points = quad.getQuadPoints(); const Teuchos::Array< Teuchos::Array<value_type> >& basis_values = quad.getBasisAtQuadPoints(); for (ordinal_type i=0; i<nqp; i++) { pce_vals[i] = normalized_pce.evaluate(quad_points[i], basis_values[i]); } // Form Kylov matrix up to order pce_sz matrix_type K(pce_sz, pce_sz); // Compute matrix matrix_type A(pce_sz, pce_sz); typedef Stokhos::Sparse3Tensor<ordinal_type, value_type> Cijk_type; for (typename Cijk_type::k_iterator k_it = Cijk.k_begin(); k_it != Cijk.k_end(); ++k_it) { ordinal_type k = index(k_it); for (typename Cijk_type::kj_iterator j_it = Cijk.j_begin(k_it); j_it != Cijk.j_end(k_it); ++j_it) { ordinal_type j = index(j_it); value_type val = 0; for (typename Cijk_type::kji_iterator i_it = Cijk.i_begin(j_it); i_it != Cijk.i_end(j_it); ++i_it) { ordinal_type i = index(i_it); value_type c = value(i_it) / (pce_norms[j]*pce_norms[k]); val += pce[i]*c; } A(k,j) = val; } } // Each column i is given by projection of the i-th order monomial // onto original basis vector_type u0 = Teuchos::getCol(Teuchos::View, K, 0); u0(0) = 1.0; for (ordinal_type i=1; i<pce_sz; i++) u0(i) = 0.0; for (ordinal_type k=1; k<pce_sz; k++) { vector_type u = Teuchos::getCol(Teuchos::View, K, k); vector_type up = Teuchos::getCol(Teuchos::View, K, k-1); u.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, A, up, 0.0); } /* for (ordinal_type j=0; j<pce_sz; j++) { for (ordinal_type i=0; i<pce_sz; i++) { value_type val = 0.0; for (ordinal_type k=0; k<nqp; k++) val += weights[k]*std::pow(pce_vals[k],j)*basis_values[k][i]; K(i,j) = val; } } */ std::cout << K << std::endl << std::endl; // Compute QR factorization of K ordinal_type ws_size, info; value_type ws_size_query; Teuchos::Array<value_type> tau(pce_sz); Teuchos::LAPACK<ordinal_type,value_type> lapack; lapack.GEQRF(pce_sz, pce_sz, K.values(), K.stride(), &tau[0], &ws_size_query, -1, &info); TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::logic_error, "GEQRF returned value " << info); ws_size = static_cast<ordinal_type>(ws_size_query); Teuchos::Array<value_type> work(ws_size); lapack.GEQRF(pce_sz, pce_sz, K.values(), K.stride(), &tau[0], &work[0], ws_size, &info); TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::logic_error, "GEQRF returned value " << info); // Get Q lapack.ORGQR(pce_sz, pce_sz, pce_sz, K.values(), K.stride(), &tau[0], &ws_size_query, -1, &info); TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::logic_error, "ORGQR returned value " << info); ws_size = static_cast<ordinal_type>(ws_size_query); work.resize(ws_size); lapack.ORGQR(pce_sz, pce_sz, pce_sz, K.values(), K.stride(), &tau[0], &work[0], ws_size, &info); TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::logic_error, "ORGQR returned value " << info); // Get basis vectors for (ordinal_type j=0; j<p+1; j++) for (ordinal_type i=0; i<pce_sz; i++) basis_vecs(i,j) = K(i,j); // Compute T = Q'*A*Q matrix_type prod(pce_sz,pce_sz); prod.multiply(Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, K, A, 0.0); matrix_type T(pce_sz,pce_sz); T.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, prod, K, 0.0); //std::cout << T << std::endl; // Recursion coefficients are diagonal and super diagonal b[0] = 1.0; for (ordinal_type i=0; i<pce_sz-1; i++) { a[i] = T(i,i); b[i+1] = T(i,i+1); } a[pce_sz-1] = T(pce_sz-1,pce_sz-1); // Setup rest of basis this->setup(); // Project original PCE into the new basis vector_type u(pce_sz); for (ordinal_type i=0; i<pce_sz; i++) u[i] = normalized_pce[i]; new_pce.multiply(Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, basis_vecs, u, 0.0); for (ordinal_type i=0; i<=p; i++) new_pce[i] /= this->norms[i]; }
/// get the connected components from an NxN adjacency matrix (1.0 for i-j connected, 0.0 for i-j not connected) std::vector<std::vector<unsigned> > findConnectedComponents(const Matrix& matrix) { double tol = 0.001; std::vector<std::vector<unsigned> > result; unsigned N = matrix.size1(); if (N != matrix.size2()) { return result; } Matrix A(N, N, 0.0); for (unsigned i = 0; i < N; ++i) { A(i,i) = 1.0; // must be self connected if ( abs(matrix(i,i) - 1.0) > tol) { // warn } for (unsigned j = i+1; j < N; ++j) { if (matrix(i,j) < 0) { // warn } else if (matrix(i,j) > tol) { A(i,j) = 1.0; } if (matrix(j,i) < 0) { // warn } else if (matrix(j,i) > tol) { A(j,i) = 1.0; } } } // raise A to the Nth power, maximum distance between two nodes for (unsigned i = 0; i < N; ++i) { A = prod(A,A); } std::set<unsigned> added; for (unsigned i = 0; i < N; ++i) { if (added.find(i) != added.end()) { continue; } std::vector<unsigned> group; group.push_back(i); added.insert(i); for (unsigned j = i+1; j < N; ++j) { if ((A(i,j) > 0) || (A(j,i) > 0)) { group.push_back(j); added.insert(j); } } result.push_back(group); } return result; }
/*--------------------------------------------------------------------------*/ types::Function::ReturnValue sci_prod(types::typed_list &in, int _iRetCount, types::typed_list &out) { types::Double* pDblIn = NULL; types::Double* pDblOut = NULL; types::Polynom* pPolyIn = NULL; types::Polynom* pPolyOut = NULL; int iOrientation = 0; int iOuttype = 1; // 1 = native | 2 = double (type of output value) int* piDimsArray = NULL; if (in.size() < 1 || in.size() > 3) { Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "prod", 1, 3); return types::Function::Error; } if (_iRetCount > 1) { Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), "prod", 1); return types::Function::Error; } bool isCopy = true; /***** get data *****/ switch (in[0]->getType()) { case types::InternalType::ScilabDouble: { pDblIn = in[0]->getAs<types::Double>(); isCopy = false; break; } case types::InternalType::ScilabBool: { pDblIn = getAsDouble(in[0]->getAs<types::Bool>()); iOuttype = 2; break; } case types::InternalType::ScilabPolynom: { pPolyIn = in[0]->getAs<types::Polynom>(); break; } case types::InternalType::ScilabInt8: { pDblIn = getAsDouble(in[0]->getAs<types::Int8>()); break; } case types::InternalType::ScilabInt16: { pDblIn = getAsDouble(in[0]->getAs<types::Int16>()); break; } case types::InternalType::ScilabInt32: { pDblIn = getAsDouble(in[0]->getAs<types::Int32>()); break; } case types::InternalType::ScilabInt64: { pDblIn = getAsDouble(in[0]->getAs<types::Int64>()); break; } case types::InternalType::ScilabUInt8: { pDblIn = getAsDouble(in[0]->getAs<types::UInt8>()); break; } case types::InternalType::ScilabUInt16: { pDblIn = getAsDouble(in[0]->getAs<types::UInt16>()); break; } case types::InternalType::ScilabUInt32: { pDblIn = getAsDouble(in[0]->getAs<types::UInt32>()); break; } case types::InternalType::ScilabUInt64: { pDblIn = getAsDouble(in[0]->getAs<types::UInt64>()); break; } default: { std::wstring wstFuncName = L"%" + in[0]->getShortTypeStr() + L"_prod"; return Overload::call(wstFuncName, in, _iRetCount, out); } } if (in.size() >= 2) { if (in[1]->isDouble()) { types::Double* pDbl = in[1]->getAs<types::Double>(); if (pDbl->isScalar() == false) { if (isCopy && pDblIn) { pDblIn->killMe(); } Scierror(999, _("%s: Wrong value for input argument #%d: A positive scalar expected.\n"), "prod", 2); return types::Function::Error; } iOrientation = static_cast<int>(pDbl->get(0)); if (iOrientation <= 0) { if (isCopy && pDblIn) { pDblIn->killMe(); } Scierror(999, _("%s: Wrong value for input argument #%d: A positive scalar expected.\n"), "prod", 2); return types::Function::Error; } } else if (in[1]->isString()) { types::String* pStr = in[1]->getAs<types::String>(); if (pStr->isScalar() == false) { if (isCopy && pDblIn) { pDblIn->killMe(); } Scierror(999, _("%s: Wrong size for input argument #%d: A scalar string expected.\n"), "prod", 2); return types::Function::Error; } wchar_t* wcsString = pStr->get(0); if (wcscmp(wcsString, L"*") == 0) { iOrientation = 0; } else if (wcscmp(wcsString, L"r") == 0) { iOrientation = 1; } else if (wcscmp(wcsString, L"c") == 0) { iOrientation = 2; } else if (wcscmp(wcsString, L"m") == 0) { int iDims = 0; int* piDimsArray = NULL; if (pDblIn) { iDims = pDblIn->getDims(); piDimsArray = pDblIn->getDimsArray(); } else { iDims = pPolyIn->getDims(); piDimsArray = pPolyIn->getDimsArray(); } // old function was "mtlsel" for (int i = 0; i < iDims; i++) { if (piDimsArray[i] > 1) { iOrientation = i + 1; break; } } } else if ((wcscmp(wcsString, L"native") == 0) && (in.size() == 2)) { iOuttype = 1; } else if ((wcscmp(wcsString, L"double") == 0) && (in.size() == 2)) { iOuttype = 2; } else { const char* pstrExpected = NULL; if (in.size() == 2) { pstrExpected = "\"*\",\"r\",\"c\",\"m\",\"native\",\"double\""; } else { pstrExpected = "\"*\",\"r\",\"c\",\"m\""; } if (isCopy && pDblIn) { pDblIn->killMe(); } Scierror(999, _("%s: Wrong value for input argument #%d: Must be in the set {%s}.\n"), "prod", 2, pstrExpected); return types::Function::Error; } } else { if (isCopy && pDblIn) { pDblIn->killMe(); } Scierror(999, _("%s: Wrong type for input argument #%d: A real matrix or a string expected.\n"), "prod", 2); return types::Function::Error; } } if (in.size() == 3) { if (in[2]->isString() == false) { if (isCopy && pDblIn) { pDblIn->killMe(); } Scierror(999, _("%s: Wrong type for input argument #%d: string expected.\n"), "prod", 3); return types::Function::Error; } types::String* pStr = in[2]->getAs<types::String>(); if (pStr->isScalar() == false) { if (isCopy && pDblIn) { pDblIn->killMe(); } Scierror(999, _("%s: Wrong size for input argument #%d: A scalar string expected.\n"), "prod", 3); return types::Function::Error; } wchar_t* wcsString = pStr->get(0); if (wcscmp(wcsString, L"native") == 0) { iOuttype = 1; } else if (wcscmp(wcsString, L"double") == 0) { iOuttype = 2; } else { if (isCopy && pDblIn) { pDblIn->killMe(); } Scierror(999, _("%s: Wrong value for input argument #%d: %s or %s expected.\n"), "prod", 3, "\"native\"", "\"double\""); return types::Function::Error; } } /***** perform operation *****/ if (pDblIn) { if (pDblIn->isEmpty()) { if (iOrientation == 0) { pDblOut = new types::Double(1); out.push_back(pDblOut); } else { out.push_back(types::Double::Empty()); } if (isCopy) { delete pDblIn; pDblIn = NULL; } return types::Function::OK; } if (iOrientation > pDblIn->getDims()) { if (isCopy) { pDblOut = pDblIn; } else { pDblOut = pDblIn->clone()->getAs<types::Double>(); } } else { pDblOut = prod(pDblIn, iOrientation); if (isCopy) { delete pDblIn; pDblIn = NULL; } } } else if (pPolyIn) { iOuttype = 1; if (iOrientation > pPolyIn->getDims()) { pPolyOut = pPolyIn->clone()->getAs<types::Polynom>(); } else { pPolyOut = prod(pPolyIn, iOrientation); } } /***** set result *****/ if ((iOuttype == 1) && isCopy) { switch (in[0]->getType()) { case types::InternalType::ScilabBool: { types::Bool* pB = new types::Bool(pDblOut->getDims(), pDblOut->getDimsArray()); int* p = pB->get(); double* pd = pDblOut->get(); int size = pB->getSize(); for (int i = 0; i < size; ++i) { p[i] = pd[i] != 0 ? 1 : 0; } out.push_back(pB); break; } case types::InternalType::ScilabPolynom: { out.push_back(pPolyOut); break; } case types::InternalType::ScilabInt8: { out.push_back(toInt<types::Int8>(pDblOut)); break; } case types::InternalType::ScilabInt16: { out.push_back(toInt<types::Int16>(pDblOut)); break; } case types::InternalType::ScilabInt32: { out.push_back(toInt<types::Int32>(pDblOut)); break; } case types::InternalType::ScilabInt64: { out.push_back(toInt<types::Int64>(pDblOut)); break; } case types::InternalType::ScilabUInt8: { out.push_back(toInt<types::UInt8>(pDblOut)); break; } case types::InternalType::ScilabUInt16: { out.push_back(toInt<types::UInt16>(pDblOut)); break; } case types::InternalType::ScilabUInt32: { out.push_back(toInt<types::UInt32>(pDblOut)); break; } case types::InternalType::ScilabUInt64: { out.push_back(toInt<types::UInt64>(pDblOut)); break; } } if (pDblOut) { pDblOut->killMe(); } } else { out.push_back(pDblOut); } return types::Function::OK; }
void UpdatedLagrangianFluid3Dinc::CalculateDampingMatrix(MatrixType& rDampingMatrix, ProcessInfo& rCurrentProcessInfo) { KRATOS_TRY unsigned int number_of_nodes = GetGeometry().size(); unsigned int dim = GetGeometry().WorkingSpaceDimension(); if(rDampingMatrix.size1() != 12) rDampingMatrix.resize(12,12,false); //getting data for the given geometry double current_volume; GeometryUtils::CalculateGeometryData(GetGeometry(), msDN_Dx, msN, current_volume); //getting properties const double& nu = 0.25*(GetGeometry()[0].FastGetSolutionStepValue(VISCOSITY)+ GetGeometry()[1].FastGetSolutionStepValue(VISCOSITY) + GetGeometry()[2].FastGetSolutionStepValue(VISCOSITY)+ GetGeometry()[3].FastGetSolutionStepValue(VISCOSITY)); //double nu = GetProperties()[VISCOSITY]; //double density = GetProperties()[DENSITY]; const double& density = 0.25*(GetGeometry()[0].FastGetSolutionStepValue(DENSITY)+ GetGeometry()[1].FastGetSolutionStepValue(DENSITY) + GetGeometry()[2].FastGetSolutionStepValue(DENSITY)+ GetGeometry()[3].FastGetSolutionStepValue(DENSITY)); //VISCOUS CONTRIBUTION TO THE STIFFNESS MATRIX // rLeftHandSideMatrix += Laplacian * nu; //filling matrix B for(unsigned int i = 0; i<number_of_nodes; i++) { unsigned int start = dim*i; msB(0,start) = msDN_Dx(i,0); msB(1,start+1)= msDN_Dx(i,1); msB(2,start+2)= msDN_Dx(i,2); msB(3,start) = msDN_Dx(i,1); msB(3,start+1) = msDN_Dx(i,0); msB(4,start) = msDN_Dx(i,2); msB(4,start+2) = msDN_Dx(i,0); msB(5,start+1)= msDN_Dx(i,2); msB(5,start+2) = msDN_Dx(i,1); } const double& a = nu*density; //constitutive tensor ms_constitutive_matrix(0,0) = (4.0/3.0)*a; ms_constitutive_matrix(0,1) = -2.0/3.0*a; ms_constitutive_matrix(0,2) = -2.0/3.0*a; ms_constitutive_matrix(0,3) = 0.0; ms_constitutive_matrix(0,4) = 0.0; ms_constitutive_matrix(0,5) = 0.0; ms_constitutive_matrix(1,0) = -2.0/3.0*a; ms_constitutive_matrix(1,1) = 4.0/3.0*a; ms_constitutive_matrix(1,2) = -2.0/3.0*a; ms_constitutive_matrix(1,3) = 0.0; ms_constitutive_matrix(1,4) = 0.0; ms_constitutive_matrix(1,5) = 0.0; ms_constitutive_matrix(2,0) = -2.0/3.0*a; ms_constitutive_matrix(2,1) = -2.0/3.0*a; ms_constitutive_matrix(2,2) = 4.0/3.0*a; ms_constitutive_matrix(2,3) = 0.0; ms_constitutive_matrix(2,4) = 0.0; ms_constitutive_matrix(2,5) = 0.0; ms_constitutive_matrix(3,0) = 0.0; ms_constitutive_matrix(3,1) = 0.0; ms_constitutive_matrix(3,2) = 0.0; ms_constitutive_matrix(3,3) = a; ms_constitutive_matrix(3,4) = 0.0; ms_constitutive_matrix(3,5) = 0.0; ms_constitutive_matrix(4,0) = 0.0; ms_constitutive_matrix(4,1) = 0.0; ms_constitutive_matrix(4,2) = 0.0; ms_constitutive_matrix(4,3) = 0.0; ms_constitutive_matrix(4,4) = a; ms_constitutive_matrix(4,5) = 0.0; ms_constitutive_matrix(5,0) = 0.0; ms_constitutive_matrix(5,1) = 0.0; ms_constitutive_matrix(5,2) = 0.0; ms_constitutive_matrix(5,3) = 0.0; ms_constitutive_matrix(5,4) = 0.0; ms_constitutive_matrix(5,5) = a; //calculating viscous contributions ms_temp = prod( ms_constitutive_matrix , msB); noalias(rDampingMatrix) = prod( trans(msB) , ms_temp); rDampingMatrix *= current_volume; KRATOS_CATCH("") }
T prod(types::ndarray<T,1> const& array, long axis) { if(axis != 0) throw types::ValueError("axis out of bounds"); return prod(array); }
void GrammarParser::parseRightSide(int leftSide) { Production prod(leftSide, m_lex.getSourcePos()); while(m_token == NAME) { const String name = m_lex.getText(); const SourcePosition pos = m_lex.getSourcePos(); next(); const SymbolModifier modifier = parseModifier(); int rightIndex = m_grammar.findSymbol(name); if(rightIndex < 0) { rightIndex = m_grammar.addNonTerminal(name, pos); } else if(m_grammar.isTerminal(rightIndex)) { prod.m_precedence = m_grammar.getSymbol(rightIndex).m_precedence; } prod.m_rightSide.add(RightSideSymbol(rightIndex, modifier)); } if(m_token == PREC) { // %prec specifier next(); switch(m_token) { case NUMBER: { prod.m_precedence = (short)m_lex.getNumber(); next(); } break; case NAME: { const String name = m_lex.getText(); next(); int tokenIndex = m_grammar.findSymbol(name); bool ok = true; if(tokenIndex < 0) { m_lex.error(_T("Unknown symbol in %%prec-clause:%s."), name.cstr()); ok = false; } else if(!m_grammar.isTerminal(tokenIndex)) { m_lex.error(_T("Symbol %s must be terminal in %%prec-clause."), name.cstr()); ok = false; } if(ok) { prod.m_precedence = m_grammar.getSymbol(tokenIndex).m_precedence; } } break; default: m_lex.error(_T("Expected NAME of NUMBER.")); } } if(m_token == LCURL) { const SourcePosition sourcePos = m_lex.getSourcePos(); CompactShortArray usedDollar; m_actionBody = EMPTYSTRING; m_lex.collectBegin(); next(); parseActionBody(sourcePos, usedDollar, prod); if(m_token != RCURL) { m_lex.error(_T("Expected '}'.")); } else { next(); } m_lex.collectEnd(); SourceText tmp; m_lex.getCollected(tmp); prod.m_actionBody.m_sourceText = trim(m_actionBody + tmp.m_sourceText); prod.m_actionBody.m_pos = SourcePositionWithName(m_lex.getAbsoluteFileName(), sourcePos); /* printf("body:<%s> at line %d\n", prod.m_actionBody.m_sourceText.cstr(), prod.m_actionBody.m_lineno); */ } m_grammar.addProduction(prod); }
void osync_mapping_engine_check_conflict(OSyncMappingEngine *engine) { int is_same = 0; GList *e = NULL; osync_trace(TRACE_ENTRY, "%s(%p)", __func__, engine); osync_assert(engine != NULL); if (engine->master != NULL) { osync_trace(TRACE_EXIT, "%s: Already has a master", __func__); return; } if (engine->conflict) { osync_trace(TRACE_INTERNAL, "Detected conflict early"); goto conflict; } for (e = engine->entries; e; e = e->next) { OSyncMappingEntryEngine *leftentry = e->data; OSyncMappingEntryEngine *rightentry = NULL; OSyncChange *leftchange = osync_entry_engine_get_change(leftentry); OSyncChange *rightchange = NULL; GList *n = NULL; osync_trace(TRACE_INTERNAL, "change: %p: %i", leftchange, leftchange ? osync_change_get_changetype(leftchange) : OSYNC_CHANGE_TYPE_UNKNOWN); if (leftchange == NULL) continue; if (osync_change_get_changetype(leftchange) == OSYNC_CHANGE_TYPE_UNKNOWN) continue; osync_mapping_engine_set_master(engine, leftentry); for (n = e->next; n; n = n->next) { rightentry = n->data; rightchange = osync_entry_engine_get_change(rightentry); if (rightchange == NULL) continue; if (osync_change_get_changetype(rightchange) == OSYNC_CHANGE_TYPE_UNKNOWN) continue; if (osync_change_compare(leftchange, rightchange) != OSYNC_CONV_DATA_SAME) { engine->conflict = TRUE; goto conflict; } else { is_same++; } } } conflict: if (engine->conflict) { //conflict, solve conflict osync_trace(TRACE_INTERNAL, "Got conflict for mapping_engine %p", engine); engine->parent->conflicts = g_list_append(engine->parent->conflicts, engine); osync_status_conflict(engine->parent->parent, engine); osync_trace(TRACE_EXIT, "%s: Got conflict", __func__); return; } osync_assert(engine->master); osync_status_update_mapping(engine->parent->parent, engine, OSYNC_MAPPING_EVENT_SOLVED, NULL); if (is_same == prod(g_list_length(engine->entries) - 1)) { GList *e = NULL; osync_trace(TRACE_INTERNAL, "No need to sync. All entries are the same"); for (e = engine->entries; e; e = e->next) { OSyncMappingEntryEngine *entry = e->data; entry->dirty = FALSE; } engine->synced = TRUE; } osync_trace(TRACE_EXIT, "%s: No conflict", __func__); }
/** * We set up a random matrix using Boost.uBLAS and use it to initialize a ViennaCL matrix. * Then we compute the QR factorization directly for the uBLAS matrix as well as the ViennaCL matrix. **/ int main (int, const char **) { typedef double ScalarType; //feel free to change this to 'double' if supported by your hardware typedef boost::numeric::ublas::matrix<ScalarType> MatrixType; typedef viennacl::matrix<ScalarType, viennacl::column_major> VCLMatrixType; std::size_t rows = 113; // number of rows in the matrix std::size_t cols = 54; // number of columns /** * Create uBLAS matrices with some random input data. **/ MatrixType ublas_A(rows, cols); MatrixType Q(rows, rows); MatrixType R(rows, cols); // Some random data with a bit of extra weight on the diagonal for (std::size_t i=0; i<rows; ++i) { for (std::size_t j=0; j<cols; ++j) { ublas_A(i,j) = ScalarType(-1.0) + ScalarType((i+1)*(j+1)) + ScalarType( (rand() % 1000) - 500.0) / ScalarType(1000.0); if (i == j) ublas_A(i,j) += ScalarType(10.0); R(i,j) = 0.0; } for (std::size_t j=0; j<rows; ++j) Q(i,j) = ScalarType(0.0); } // keep initial input matrix for comparison MatrixType ublas_A_backup(ublas_A); /** * Setup the matrix in ViennaCL and copy the data from the uBLAS matrix: **/ VCLMatrixType vcl_A(ublas_A.size1(), ublas_A.size2()); viennacl::copy(ublas_A, vcl_A); /** * <h2>QR Factorization with Boost.uBLAS Matrices</h2> * Compute QR factorization of A. A is overwritten with Householder vectors. Coefficients are returned and a block size of 3 is used. * Note that at the moment the number of columns of A must be divisible by the block size **/ std::cout << "--- Boost.uBLAS ---" << std::endl; std::vector<ScalarType> ublas_betas = viennacl::linalg::inplace_qr(ublas_A); //computes the QR factorization /** * Let us check for the correct result: **/ viennacl::linalg::recoverQ(ublas_A, ublas_betas, Q, R); MatrixType ublas_QR = prod(Q, R); double ublas_error = check(ublas_QR, ublas_A_backup); std::cout << "Maximum relative error (ublas): " << ublas_error << std::endl; /** * <h2>QR Factorization with Boost.uBLAS Matrices</h2> * We now compute the QR factorization from a ViennaCL matrix. Internally it uses Boost.uBLAS for the panel factorization. **/ std::cout << "--- Hybrid (default) ---" << std::endl; viennacl::copy(ublas_A_backup, vcl_A); std::vector<ScalarType> hybrid_betas = viennacl::linalg::inplace_qr(vcl_A); /** * Let us check for the correct result: **/ viennacl::copy(vcl_A, ublas_A); Q.clear(); R.clear(); viennacl::linalg::recoverQ(ublas_A, hybrid_betas, Q, R); double hybrid_error = check(ublas_QR, ublas_A_backup); std::cout << "Maximum relative error (hybrid): " << hybrid_error << std::endl; /** * That's it. Print a success message and exit. **/ std::cout << "!!!! TUTORIAL COMPLETED SUCCESSFULLY !!!!" << std::endl; return EXIT_SUCCESS; }