void YieldPolynomial::computeYieldFunction(int n){ //solves for polynomial that perfectly fits yield curve. Note that this method may have computational difficulties //int n=yield.size(); int m=yield.size(); if(m<n || n<1){ n=m; } Eigen::MatrixXd HoldParameters(n, n); Eigen::VectorXd ThetaEigen(n); Eigen::VectorXd yieldValues(n); Date currDate; int k=0; double tt=0; for(int i=0; i<n; ++i){ //n needs to be greater than 2.. k=i*(m/n); HoldParameters(i, 0)=1; HoldParameters(i, 1)=yield[k].date-currDate; yieldValues(i)=yield[k].value*HoldParameters(i, 1); if(HoldParameters(i, 1)>maxMaturity){ maxMaturity=HoldParameters(i, 1); } tt=HoldParameters(i, 1)*HoldParameters(i, 1); for(int j=2; j<n; ++j){ HoldParameters(i, j)=tt;//pow(HoldParameters(i, 1), j); tt*=HoldParameters(i, 1); } } ThetaEigen=HoldParameters.jacobiSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(yieldValues); theta=Theta(n); for(int i=0; i<n; ++i){ theta[i]=ThetaEigen(i); std::cout<<"Theta: "<<theta[i]<<std::endl; } }
void Gelman_Rubin_diagnostic(TStats **stats_arr, unsigned int N_chains, double *R, unsigned int N) { // Run some basic checks on the input to ensure that G-R statistics can be calculated assert(N_chains > 1); // More than one chain unsigned int N_items_tot = stats_arr[0]->get_N_items(); for(unsigned int i=1; i<N_chains; i++) { assert(stats_arr[i]->get_N_items() == N_items_tot); } // Each chain is of the same length std::vector<double> W(N, 0.); // Mean within-chain variance std::vector<double> B(N, 0.); // Between-chain variance std::vector<double> Theta(N, 0.); // Mean of means (overall mean) // Calculate mean within chain variance and overall mean for(unsigned int i=0; i<N_chains; i++) { for(unsigned int k=0; k<N; k++) { W[k] += stats_arr[i]->cov(k,k); Theta[k] += stats_arr[i]->mean(k); } } for(unsigned int k=0; k<N; k++) { W[k] /= (double)N_chains; Theta[k] /= (double)N_chains; } // Calculate variance between chains double tmp; for(unsigned int i=0; i<N_chains; i++) { for(unsigned int k=0; k<N; k++) { tmp = stats_arr[i]->mean(k) - Theta[k]; B[k] += tmp*tmp; } } for(unsigned int k=0; k<N; k++) { B[k] /= (double)N_chains - 1.; } // Calculate estimated variance for(unsigned int k=0; k<N; k++) { R[k] = 1. - 1./(double)N_items_tot + B[k]/W[k]; } }
VecDoub Actions_HarmonicOscillator::angles(const VecDoub& x, void *params){ VecDoub Theta(3,0); for(int i=0;i<3;i++){ Theta[i] = atan(-x[3+i]/Om[i]/x[i])+(x[i]>0.?PI:0.); if(Theta[i]<0.)Theta[i]+=2.*PI; if(Theta[i]>2.*PI)Theta[i]-=2.*PI; } return Theta; }
void Round (u32 const * const k,u32 * const a,u8 const RC1,u8 const RC2) { a[0] ^= RC1; Theta(k,a); a[0] ^= RC2; Pi1(a); Gamma(a); Pi2(a); } /* Round */
/*==================================================================================*/ void Round (u32 const * const k,u32 * const a,u8 const RC1,u8 const RC2) /*----------------------------------------------------------------------------------*/ /* The round function, common to both encryption and decryption /* - Round constants is added to the rightmost byte of the leftmost 32-bit word (=a0) /*==================================================================================*/ { a[0] ^= RC1; Theta(k,a); a[0] ^= RC2; Pi1(a); Gamma(a); Pi2(a); } /* Round */
void HHV4Vector::CalcCov() { m_cov_manually_set = false; if (P()>0){ //NOTE: only dE is used for Cov calculation! Double_t dp = E()/P()*dE(); // error propagation p=sqrt(e^2-m^2) Double_t dpt = sin(Theta())*dp; m_cov_transversal(0,0) = pow(cos(Phi())*dpt,2); m_cov_transversal(1,1) = pow(sin(Phi())*dpt,2); m_cov_transversal(0,1) = sin(Phi())*cos(Phi())*dpt*dpt; m_cov_transversal(1,0) = sin(Phi())*cos(Phi())*dpt*dpt; } }
SimplePropertySet<string, double> propertylist() { SimplePropertySet<string, double> result; result.add (Property<string, double> ("Option Value", Price() ) ); result.add (Property<string, double> ("Delta",Delta() ) ); result.add (Property<string, double> ("Gamma",Gamma() ) ); result.add (Property<string, double> ("Vega",Vega() ) ); result.add (Property<string, double> ("Vega",Theta() ) ); result.add (Property<string, double> ("Rho",Rho() ) ); result.add (Property<string, double> ("Cost of Carry",Coc() ) ); // Cost of carry cout << "counbt " << result.Count(); return result; }
double SoilWater::MaxExfiltration (const Geometry& geo, const size_t edge, const Soil& soil, const double T) const { const size_t n = geo.edge_other (edge, Geometry::cell_above); const double h0 = h (n); const double K0 = soil.K (n, h0, h_ice (n), T); if (max_exfiltration_gradient > 0.0) return K0 * max_exfiltration_gradient; const double Cw2 = soil.Cw2 (n, h0); const double Theta0 = Theta (n); const double Theta_surf = soil.Theta_res (n); const double delta_Theta = Theta0 - Theta_surf; const double z0 = geo.cell_z (n); // Darcy formulated for Theta between middle of node and soil surface. return - (K0 / Cw2) * (delta_Theta / z0); }
GeometryRefPtr buildTerrain(Vec2f Dimensions, UInt32 XSubdivisions, UInt32 YSubdivisions) { GeoUInt8PropertyRefPtr type = GeoUInt8Property::create(); type->addValue(GL_TRIANGLES); GeoPnt3fPropertyRefPtr pnts = GeoPnt3fProperty ::create(); GeoVec3fPropertyRefPtr norms = GeoVec3fProperty ::create(); Real32 ZScale(8.0); for(UInt32 i(0) ; i<XSubdivisions ; ++i) { for(UInt32 j(0) ; j<YSubdivisions ; ++j) { Real32 Theta(5*3.14159*(static_cast<Real32>(i)/static_cast<Real32>(XSubdivisions))), ThetaNext(5*3.14159*(static_cast<Real32>(i+1)/static_cast<Real32>(XSubdivisions))); // the points of the Tris pnts->addValue(Pnt3f(-Dimensions.x()/2.0+i*(Dimensions.x()/static_cast<Real32>(XSubdivisions)), Dimensions.y()/2.0-j*(Dimensions.y()/static_cast<Real32>(YSubdivisions)), ZScale*osgCos(Theta))); norms->addValue(Vec3f( 0.0,0.0,1.0)); pnts->addValue(Pnt3f(-Dimensions.x()/2.0+i*(Dimensions.x()/static_cast<Real32>(XSubdivisions)), Dimensions.y()/2.0-(j+1)*(Dimensions.y()/static_cast<Real32>(YSubdivisions)), ZScale*osgCos(Theta))); norms->addValue(Vec3f( 0.0,0.0,1.0)); pnts->addValue(Pnt3f(-Dimensions.x()/2.0+(i+1)*(Dimensions.x()/static_cast<Real32>(XSubdivisions)), Dimensions.y()/2.0-j*(Dimensions.y()/static_cast<Real32>(YSubdivisions)), ZScale*osgCos(ThetaNext))); norms->addValue(Vec3f( 0.0,0.0,1.0)); pnts->addValue(Pnt3f(-Dimensions.x()/2.0+i*(Dimensions.x()/static_cast<Real32>(XSubdivisions)), Dimensions.y()/2.0-(j+1)*(Dimensions.y()/static_cast<Real32>(YSubdivisions)), ZScale*osgCos(Theta))); norms->addValue(Vec3f( 0.0,0.0,1.0)); pnts->addValue(Pnt3f(-Dimensions.x()/2.0+(i+1)*(Dimensions.x()/static_cast<Real32>(XSubdivisions)), Dimensions.y()/2.0-(j+1)*(Dimensions.y()/static_cast<Real32>(YSubdivisions)), ZScale*osgCos(ThetaNext))); norms->addValue(Vec3f( 0.0,0.0,1.0)); pnts->addValue(Pnt3f(-Dimensions.x()/2.0+(i+1)*(Dimensions.x()/static_cast<Real32>(XSubdivisions)), Dimensions.y()/2.0-j*(Dimensions.y()/static_cast<Real32>(YSubdivisions)), ZScale*osgCos(ThetaNext))); norms->addValue(Vec3f( 0.0,0.0,1.0)); } } GeoUInt32PropertyUnrecPtr lens = GeoUInt32Property::create(); lens->addValue(pnts->size()); GeometryRefPtr Terrain = Geometry::create(); Terrain->setTypes (type); Terrain->setLengths (lens); Terrain->setPositions(pnts); Terrain->setNormals(norms); calcVertexNormals(Terrain); return Terrain; }
void testEigenMap() { Vector_t theta; theta.setZero(4 * 5); for (int i = 0; i < theta.size(); ++i) theta(i) = i; std::cout << theta << std::endl; Eigen::Map<Matrix_t> Theta(theta.data(), 4, 5); // reshape std::cout << Theta << std::endl; Vector_t theta2(Eigen::Map<Vector_t>(Theta.data(), 5 * 4)); std::cout << theta2 << std::endl; }
void Movement1D::tick (const Soil& soil, SoilWater& soil_water, const SoilHeat& soil_heat, Surface& surface, Groundwater& groundwater, const Time& time, const Weather& weather, const double dt, Treelog& msg) { const size_t edge_size = geo->edge_size (); const size_t cell_size = geo->cell_size (); TREELOG_MODEL (msg); // Cells. std::vector<double> S_sum (cell_size); std::vector<double> h_old (cell_size); std::vector<double> Theta_old (cell_size); std::vector<double> h_ice (cell_size); std::vector<double> h (cell_size); std::vector<double> Theta (cell_size); for (size_t c = 0; c < cell_size; c++) { S_sum[c] = soil_water.S_sum (c); h_old[c] = soil_water.h_old (c); Theta_old[c] = soil_water.Theta_old (c); h_ice[c] = soil_water.h_ice (c); h[c] = soil_water.h (c); Theta[c] = soil_water.Theta (c); } // Edges. std::vector<double> q (edge_size, 0.0); std::vector<double> q_p (edge_size, 0.0); for (size_t e = 0; e < edge_size; e++) { q[e] = soil_water.q_matrix (e); q_p[e] = soil_water.q_tertiary (e); } tick_water (*geo, soil, soil_heat, surface, groundwater, S_sum, h_old, Theta_old, h_ice, h, Theta, q, q_p, dt, msg); soil_water.set_matrix (h, Theta, q); }
// X es la matriz de datos ([m casos] X [n features + BIAS]) // X ya se supone normalizada, y con la columna de BIAS agregada. // Y es la matriz de respuestas ([m casos] X [c categorias posibles]) fmat SGD(const fmat& X, const fmat& Y, double alpha) { int m = X.n_rows; // Filas = casos int n = X.n_cols; // Columnas = features + BIAS int c = Y.n_cols; // Categorias posibles double lambda = 4.0; fmat Theta(n, c); fmat reg(n, c); fmat gradient(n, c); Theta.fill(0.0); int its = m/SGD_N; fmat subX, subY; double loss; for (int i = 0; i < GD_IT; i++) { // SGD. Debería modularizar un poco esto. Quizás con un define. // cout << "iterancion " << i << endl; for (int j = 0; j < its; j++) { subX = X.rows(SGD_N*j, SGD_N*(j+1)-1); subY = Y.rows(SGD_N*j, SGD_N*(j+1)-1); Theta = gdStep(Theta, subX, subY, alpha, lambda); } // Tomo las filas que faltan. subX = X.rows(its*SGD_N, m - 1); subY = Y.rows(its*SGD_N, m - 1); Theta = gdStep(Theta, subX, subY, alpha, lambda); cout << "terminada la iteración: %d" << i; #ifndef NDEBUG if (i % 10 == 0) { loss = logloss(predict(X, Theta), Y); cout << " logloss %G" << loss; } #endif cout << endl; } loss = logloss(predict(X, Theta), Y); cout << "Logloss final: " << loss << endl; return Theta; }
VecDoub Actions_Isochrone::angles(const VecDoub& x, void *params){ VecDoub Sph = conv::CartesianToSphericalPolar(x); VecDoub Theta(3,0); double E=H(x), L_ = L(x), Lz_ = Lz(x); double c=GM/(-2*E)-b; double e=sqrt(1-L_*L_*(1+b/c)/GM/c); double r = Sph[0]; double eta=atan2(r*Sph[3]/sqrt(-2.*E),b+c-sqrt(b*b+r*r)); double OmR=pow(-2*E,1.5)/GM; double Omp=0.5*OmR*(1+L_/sqrt(L_*L_+4*GM*b)); Theta[0]=eta-e*c*sin(eta)/(c+b); double psi = PI/2.; if(fabs(Sph[5])>1e-10) psi=atan2(cos(Sph[2]),-sin(Sph[2])*r*Sph[5]/L_); double a=sqrt((1+e)/(1-e)); double ap=sqrt((1+e+2*b/c)/(1-e+2*b/c)); Theta[2]=psi+Omp*Theta[0]/OmR-F(a,eta)-F(ap,eta)/sqrt(1+4*GM*b/L_/L_); double LR=Lz_/L_; double sinu = LR/sqrt(1.-LR*LR)/tan(Sph[2]); double u = 0; if(sinu>1.) u=.5*PI; else if(sinu<-1.) u = -.5*PI; else u = asin(sinu); if(Sph[5]>0.) u=PI-u; Theta[1]=Sph[1]-u+SIGN(Lz_)*Theta[2]; for(int i=0;i<3;i++){ while(Theta[i]<0.) Theta[i]+=2.*PI; while(Theta[i]>2.*PI) Theta[i]-=2.*PI; } return Theta; }
//EAP estimates used in multipleGroup RcppExport SEXP EAPgroup(SEXP Rlogitemtrace, SEXP Rtabdata, SEXP RTheta, SEXP Rprior, SEXP Rmu, SEXP Rfull, SEXP Rr, SEXP Rncores) { BEGIN_RCPP const int ncores = as<int>(Rncores); const int full = as<int>(Rfull); const vector<int> r = as< vector<int> >(Rr); #ifdef SUPPORT_OPENMP omp_set_num_threads(ncores); #endif const NumericMatrix logitemtrace(Rlogitemtrace); const IntegerMatrix tabdata(Rtabdata); const NumericMatrix Theta(RTheta); const vector<double> prior = as< vector<double> >(Rprior); const vector<double> mu = as< vector<double> >(Rmu); const int n = prior.size(); //nquad const int N = tabdata.nrow(); const int nitems = tabdata.ncol(); const int nfact = Theta.ncol(); vector<double> scores(N * nfact); vector<double> scores2(N * nfact*(nfact + 1)/2); #pragma omp parallel for for(int pat = 0; pat < N; ++pat){ vector<double> L(n, 0.0); for(int j = 0; j < n; ++j){ for(int i = 0; i < nitems; ++i) if(tabdata(pat, i)) L[j] = L[j] + logitemtrace(j, i); } vector<double> thetas(nfact, 0.0); double denom = 0.0; for(int j = 0; j < n; ++j){ L[j] = exp(L[j] + log(prior[j])); denom += L[j]; } for(int k = 0; k < nfact; ++k){ for(int j = 0; j < n; ++j) thetas[k] += Theta(j, k) * L[j] / denom; scores[pat + k*N] = thetas[k]; } int ind = 0; vector<double> thetas2(nfact*(nfact+1)/2, 0.0); for(int i = 0; i < nfact; ++i){ for(int k = 0; k < nfact; ++k){ if(i <= k){ for(int j = 0; j < n; ++j) thetas2[ind] += (Theta(j, i) - thetas[i]) * (Theta(j, k) - thetas[k]) * L[j] / denom; thetas2[ind] += (thetas[i] - mu[i]) * (thetas[k] - mu[k]); scores2[pat + ind*N] = thetas2[ind]; ind += 1; } } } } if(full){ const int NN = std::accumulate(r.begin(), r.end(), 0); NumericMatrix fullscores(NN, nfact); NumericMatrix scoresmat = vec2mat(scores, N, nfact); int ind = 0; for(int pat = 0; pat < N; ++pat){ for(int j = 0; j < r[pat]; ++j){ for(int i = 0; i < nfact; ++i) fullscores(ind, i) = scoresmat(pat, i); ++ind; } } return(fullscores); } List ret; ret["scores"] = vec2mat(scores, N, nfact); ret["scores2"] = vec2mat(scores2, N, nfact*(nfact + 1)/2); return(ret); END_RCPP }
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. }
/** * Computes the value of the threadId-th component of the function * F(t) = (f1(t), ..., fn(t)) and stores it in the memory pointed by f * @param int threadId Identifier of the calling thread. * @param Real x Value of the time in which the system is solved * @param Real* y Initial conditions for the system: a pointer to * a vector whose lenght shall be the same as the * number of equations in the system. * @param Real* f Computed value of the function: a pointer to a * vector whose lenght shall be the same as the * number of equations in the system. * @param Real* data Additional data needed by the function, managed * by the caller. */ void computeComponent(Real x, Real* y, Real* f, Real* data){ Real r, r2, theta, pR, pR2, pTheta, pTheta2, b, b2, q; Real sinT, cosT, sinT2, cosT2; Real _R, D, Z, DZplusR, rho1, rho2, rho3; // Parallelization of the retrieval of the input data (position of the ray, // momenta and constants), storing it as shared variables. Furthermore, // some really useful numbers are computed; namely: the sine and cosine of // theta (and their squares) and the square of the constant b. // Each thread retrieves its data and make the corresponding computations, // except for the thread 2: the corresponging value of this thread should // be ray's phi, but this value is not used in the system; as this thread // is free to do another calculation, it retrieves the constants b,q (not // directly associated with any thread) and compute b**2 r = y[0]; r2 = r*r; theta = y[1]; sinT = sin(theta); cosT = cos(theta); sinT2 = sinT*sinT; cosT2 = cosT*cosT; b = data[0]; q = data[1]; b2 = b*b; pR = y[3]; pTheta = y[4]; // Parallelization of the computation of somec commonly used numbers, also // stored as shared variables; namely: R, D, Theta (that is called Z) and // rho (and its square and cube). These four numbers let one thread free: // it is used in the computation of the squares of the momenta: pR and // pTheta. _R = R(r, r2, b, q); D = Delta(r, r2); Z = Theta(sinT2, cosT2, b2, q); rho1 = rho(r2, cosT2); rho2 = rho1*rho1; rho3 = rho1*rho2; pR2 = pR*pR; pTheta2 = pTheta*pTheta; // Declaration of variables used in the actual computation: dR, dZ, dRho // and dD will store the derivatives of the corresponding functions (with // respect to the corresponding variable in each thread). The sumX values // are used as intermediate steps in the final computations, in order to // ease notation. Real dR, dZ, dRho, dD, sum1, sum2, sum3, sum4, sum5, sum6; // Actual computation: each thread computes its corresponding value in the // system; namely: // Thread 0 -> r // Thread 1 -> theta // Thread 2 -> phi // Thread 3 -> pR // Thread 4 -> pTheta f[0] = D * pR / rho2; f[1] = pTheta / rho2; // Derivatives with respect to b dR = dbR(r, r2, b); dZ = dbTheta(sinT2, cosT2, b); f[2] = - (dR + D*dZ)/(2*D*rho2); // Derivatives with respect to r dRho = drRho(r, r2, cosT2, rho1); dD = drDelta(r); dR = drR(r, r2, b, q); DZplusR = D*Z + _R; sum1 = + dRho*pTheta2; sum2 = + D*pR2*dRho; sum3 = - (DZplusR*dRho / D); sum4 = - (dD*pR2); sum5 = + (dD*Z + dR) / D; sum6 = - (dD*DZplusR / (D*D)); f[3] = (sum1 + sum2 + sum3)/rho3 + (sum4 + sum5 + sum6)/(2*rho2); // Derivatives with respect to theta (called z here) dRho = dzRho(r2, sinT, cosT, cosT2, rho1); dZ = dzTheta(sinT, sinT2, cosT, cosT2, b2); sum1 = + dRho*pTheta2; sum2 = + D*pR2*dRho; sum3 = - (D*Z + _R)*dRho / D; sum4 = + dZ / (2*rho2); f[4] = (sum1 + sum2 + sum3)/rho3 + sum4; }
SEXP e_step_theta(SEXP _W, SEXP _P, SEXP _zeta, SEXP _probz, SEXP _Theta) { // the following parameters are inputs and are not updated NumericMatrix Theta(_Theta); // the following parameters serve both as input, but will be updated in M step as output NumericMatrix W(_W); NumericMatrix P(_P); double zeta = as<double>(_zeta); NumericVector probz(_probz); // extract the dimensions int I = P.nrow(); int S = P.ncol(); int K = W.nrow() / S; int J = probz.size(); double _LOW = 1e-10; // the following quantities are outputs NumericVector b_mean(I); NumericVector Z_mean(J); NumericMatrix W_max(K * S, J); NumericMatrix predZ(I, J); // iterators int i, j, k, s;//, likid; // Intermediate matrices NumericVector TP(I); NumericMatrix TW(I, J); NumericMatrix Zcond(I, J); for(i = 0; i < I; i ++){ TP(i) = 0; for(j = 0; j < J; j ++) TW(i, j) = 0; for(k = 0; k < K; k ++){ for(s = 0; s < S; s ++){ if(Theta(k, i + I * s) > 0){ TP(i) += log(P(i, s)); for(j = 0; j < J; j ++) TW(i, j) += log(W(k + K * s, j)); } } } } for(k = 0; k < K; k ++) for(j = 0; j < J; j ++) for(s = 0; s < S; s ++) W_max(k + K * s, j) = 0; for(j = 0; j < J; j ++) Z_mean(j) = 0; for(i = 0; i < I; i ++){ // b_mean double exp1 = 0; if(zeta > 0) { exp1 = log(zeta) + TP(i); } double exp2 = log(1 - zeta); double maxexp = TW(i, 0); for(j = 1; j < J; j ++) if(maxexp < TW(i, j)) maxexp = TW(i, j); double tmp = 0; for(j = 0; j < J; j ++) tmp += probz[ j ] * exp(TW(i, j) - maxexp); exp2 += log(tmp) + maxexp; if(zeta > 0) { if(exp1 > exp2) b_mean(i) = 1 / (1 + exp(exp2 - exp1)); else b_mean(i) = exp(exp1 - exp2) / (1 + exp(exp1 - exp2)); } else { b_mean(i) = 0; } // predZ double tmpexp[ J ]; for(j = 0; j < J; j ++){ tmpexp[ j ] = log(probz[ j ]); if(TW(i, j) > TP(i) && zeta > 0) tmpexp[ j ] += log((1 - zeta) + zeta * exp(TP(i) - TW(i, j))) + TW(i, j); else tmpexp[ j ] += log((1 - zeta) * exp(TW(i, j) - TP(i)) + zeta) + TP(i); } maxexp = tmpexp[ 0 ]; for(j = 1; j < J; j ++) if(maxexp < tmpexp[ j ]) maxexp = tmpexp[ j ]; double total = 0; for(j = 0; j < J; j ++) total += exp(tmpexp[ j ] - maxexp); for(j = 0; j < J; j ++){ predZ(i, j) = exp(tmpexp[ j ] - maxexp) / total; Z_mean(j) += predZ(i, j); } // Zcond for(j = 0; j < J; j ++){ exp1 = predZ(i, j) - probz(j) * b_mean(i); if(exp1 < _LOW) Zcond(i, j) = _LOW; else if(exp1 >= (1 - _LOW)) Zcond(i, j) = 1 - _LOW; else Zcond(i, j) = exp1; for(k = 0; k < K; k ++) for(s = 0; s < S; s ++){ if(Theta(k, i + I * s) > 0){ W_max(k + K * s, j) += Zcond(i, j); break; } } } } if(zeta > 0) { zeta = 0; for(i = 0; i < I; i ++) zeta += b_mean[ i ]; zeta /= I; if(zeta < _LOW) zeta = _LOW; else if(zeta > 1 - _LOW) zeta = 1 - _LOW; } for(j = 0; j < J; j ++){ Z_mean(j) /= I; if(Z_mean(j) < _LOW) Z_mean(j) = _LOW; else if(Z_mean(j) > 1 - _LOW) Z_mean(j) = 1 - _LOW; } for(k = 0; k < K; k ++) for(j = 0; j < J; j ++){ double total = 0; for(s = 0; s < S; s ++) total += W_max(k + K * s, j); for(s = 0; s < S; s ++){ if(total == 0) W_max(k + K * s, j) = 1 / S; else if(W_max(k + K * s, j) < _LOW * total) W_max(k + K * s, j) = _LOW; else if(W_max(k + K * s, j) > (1 - _LOW) * total) W_max(k + K * s, j) = 1 - _LOW; else W_max(k + K * s, j) /= total; } } Rcpp::List ret = Rcpp::List::create( Rcpp::Named("zeta") = zeta, Rcpp::Named("probz") = Z_mean, Rcpp::Named("W") = W_max, Rcpp::Named("b_prob") = b_mean, Rcpp::Named("Z") = predZ, Rcpp::Named("Zcond") = Zcond ); return(ret); }
Vector<double> graph( string& sensitivity_type, string& property, Vector<double> parameter_range) { curr = &T; // Default x axis is time T if (property == "r") curr = &r; if (property == "sig") curr = &sig; if (property == "K") curr = &K; if (property == "T") curr = &T; if (property == "U") curr = &U; if (property == "b") curr = &b; // Save the value in the 'current' property double memento = (*curr)(); Vector<double> result (parameter_range.Size(), parameter_range.MinIndex()); if (sensitivity_type == "Price") { for (int i = parameter_range.MinIndex(); i <= parameter_range.MaxIndex(); i++) { (*curr)(parameter_range[i]); result[i] = Price(); } } if (sensitivity_type == "Delta") { for (int i = parameter_range.MinIndex(); i <= parameter_range.MaxIndex(); i++) { (*curr)(parameter_range[i]); result[i] = Delta(); } } if (sensitivity_type == "Gamma") { for (int i = parameter_range.MinIndex(); i <= parameter_range.MaxIndex(); i++) { (*curr)(parameter_range[i]); result[i] = Gamma(); } } if (sensitivity_type == "Vega") { for (int i = parameter_range.MinIndex(); i <= parameter_range.MaxIndex(); i++) { (*curr)(parameter_range[i]); result[i] = Vega(); } } if (sensitivity_type == "Theta") { for (int i = parameter_range.MinIndex(); i <= parameter_range.MaxIndex(); i++) { (*curr)(parameter_range[i]); result[i] = Theta(); } } if (sensitivity_type == "Rho") { for (int i = parameter_range.MinIndex(); i <= parameter_range.MaxIndex(); i++) { (*curr)(parameter_range[i]); result[i] = Rho(); } } if (sensitivity_type == "Coc") { for (int i = parameter_range.MinIndex(); i <= parameter_range.MaxIndex(); i++) { (*curr)(parameter_range[i]); result[i] = Coc(); } } // Now restore the old value of the property (*curr)(memento); return result; }
/**************************************************程序入口****************************************************/ int main() { clock_t start,finish; double totaltime; start=clock(); time_t nowTime=time(0); struct tm* nowTimeStruct=localtime(&nowTime);//打印系统时间 // output<<"系统当前时间:"<<1900+nowTimeStruct->tm_year<<"."<<nowTimeStruct->tm_mon+1<<"."<< // nowTimeStruct->tm_mday<<" "<<nowTimeStruct->tm_hour<<":"<<nowTimeStruct->tm_min<<":"<<nowTimeStruct->tm_sec<<endl; try { // output<<">>>>>>>>>>>>>>>>>>>>>>>>>数据区<<<<<<<<<<<<<<<<<<<<"<<endl; define_data(env);//首先初始化全局变量 // output<<">>>>>>>>>>>>>>>>>>>>>>>>>/数据区<<<<<<<<<<<<<<<<<<<"<<endl<<endl; IloInvert(env,B0,B0l,Node-1);//求逆矩阵 //在此创建两种形式的目标函数 IloNumExpr Cost(env);//目标函数 for(IloInt w=0;w<NW;++w) { Cost+=detaPw[w]; } IloObjective min(env,Cost,IloObjective::Sense::Minimize,"min"); IloObjective max(env,Cost,IloObjective::Sense::Maximize,"max"); Master_Model.add(min); // Master_Model.add(IloMaximize(env,Cost));//目标函数二选一 Cost.end(); IloNumExpr expr1(env),expr2(env);//功率平衡约束 for(IloInt i=0;i<NG;++i) { expr1+=detaP[i]; } for(IloInt w=0;w<NW;++w) { expr2+=detaPw[w]; } Master_Model.add(expr1+expr2==0); expr1.end(); expr2.end(); for(IloInt i=0;i<NG;++i)//机组可调节范围 { Master_Model.add(detaP[i]>=Unit[i][1]*u[i]-P1[i]); Master_Model.add(detaP[i]<=Unit[i][2]*u[i]-P1[i]); Master_Model.add(detaP[i]>=-detaa[i]); Master_Model.add(detaP[i]<=detaa[i]); } IloNumExprArray detaP_node(env,Node-1),detaPw_node(env,Node-1);//安全约束,实际上安全约束影响不大 IloNumExprArray Theta(env,Node); for(IloInt b=0;b<Node-1;++b) { detaP_node[b]=IloNumExpr(env); detaPw_node[b]=IloNumExpr(env); IloInt i=0; for(;i<NG;++i) { if(Unit[i][0]==b-1)break; } if(i<NG) { detaP_node[b]+=detaP[i]; } if(Sw[b]>=0) { detaPw_node[b]+=detaPw[ Sw[b] ]; } } for(IloInt b=0;b<Node-1;++b) { Theta[b]=IloNumExpr(env); for(IloInt k=0;k<Node-1;++k) { Theta[b]+=B0l[b][k]*(detaP_node[k]+detaPw_node[k]); } } Theta[Node-1]=IloNumExpr(env); for(IloInt h=0;h<Branch;++h) { IloNumExpr exprTheta(env);//莫明其妙的错误 exprTheta+=(Theta[(IloInt)Info_Branch[h][0]-1]-Theta[(IloInt)Info_Branch[h][1]-1]); Master_Model.add(exprTheta<=Info_Branch[h][3]*(Info_Branch[h][4]-PL[h])); Master_Model.add(exprTheta>=Info_Branch[h][3]*(-Info_Branch[h][4]-PL[h])); exprTheta.end(); //两个相减的节点顺序没有影响么? } Theta.end(); detaP_node.end(); detaPw_node.end(); Master_Cplex.extract(Master_Model); Master_Cplex.solve(); if (Master_Cplex.getStatus() == IloAlgorithm::Infeasible)//输出结果 { output<<"Master Problem Have No Solution"<<endl; goto lable2; } /************************************************************输出显示过程**************************************************/ // output/*<<endl<<"Min:"*/<<Master_Cplex.getObjValue()<<endl; Master_Model.remove(min); Master_Model.add(max); Master_Cplex.extract(Master_Model); Master_Cplex.solve(); if (Master_Cplex.getStatus() == IloAlgorithm::Infeasible)//输出结果 { output<<"Master Problem Have No Solution"<<endl; goto lable2; } output/*<<endl<<"Max:"*/<<Master_Cplex.getObjValue()<<endl<<endl;; // output<<endl<<"常规机组出力调整量:"<<endl; // for(IloInt i=0;i<NG;++i) // { // output<<Master_Cplex.getValue(detaP[i])<<" "; // } // output<<endl<<"风电机组出力调整量:"<<endl; // for(IloInt i=0;i<NW;++i) // { // output<<Master_Cplex.getValue(detaPw[i])<<" "; // } // output<<endl; lable2: Master_Model.end(); Master_Cplex.end(); env.end(); } catch(IloException& ex)//异常捕获 { output<<"Error: "<<ex<<endl; } catch(...) { output<<"Error: Unknown exception caught!" << endl; } finish=clock(); totaltime=(double)(finish-start)/CLOCKS_PER_SEC; output<<"totaltime: "<<totaltime<<"s"<<endl<<endl; output.close(); return 0; }
SEXP MADBayes( SEXP _b, SEXP _clusterLabels, SEXP _Theta, SEXP _Mu, SEXP _D, SEXP _Gamma, SEXP _Y, SEXP _lambdap, SEXP _lambdaw, SEXP _lambda) { // The following values are 1updated in MCMC iterations IntegerVector b(_b); // length I IntegerVector clusterLabels(_clusterLabels); // length I IntegerMatrix Theta(_Theta); // K by I //NumericMatrix W(_W); // KS by I + 1 //NumericMatrix P(_P); // I by S NumericMatrix Mu(_Mu); // N by S IntegerVector D(_D); // Length N, valued in {0, 1, ..., K-1} double lambda = as<double>(_lambda); // The following values are piror parameters and are fixed double lambdap = as<double>(_lambdap); double lambdaw = as<double>(_lambdaw); // The following is the external information. NumericMatrix Gamma(_Gamma); // N*S by I NumericMatrix Y(_Y); // N by I // extract the dimensions int I = b.size(); int S = Mu.ncol(); int K = Theta.nrow(); int N = D.size(); // The following will be computed NumericMatrix W(K * S, I + 1); NumericMatrix P(I, S); // iterators int i, j, k = 0, s = 0, n, i1;//, likid; double loss; double _LOW = 1e-10; int ClusterSize[I + 1]; for(i = 0; i < I + 1; i ++) { ClusterSize[i] = 0; } // Compute J int J = 0; for(i = 0; i < I; i ++) { if(J < clusterLabels[i]) { J = clusterLabels[i]; } ClusterSize[clusterLabels[i]] ++; } J ++; // Update W for(j = 0; j < J; j ++) { for(k = 0; k < K; k ++) { double tmp[S + 1]; tmp[S] = 0; for(s = 0; s < S; s ++) { tmp[s] = _LOW; tmp[S] += tmp[s]; W(s * K + k, j) = 0; } for(i = 0; i < I; i ++) { if(b[i] == 0 && clusterLabels[i] == j) { tmp[Theta(k, i)] ++; tmp[S] ++; } } for(s = 0; s < S; s ++) { W(s * K + k, j) = tmp[s] / tmp[S]; } } } // update P for(i = 0; i < I; i ++) { double tmp[S + 1]; tmp[S] = 0; for(s = 0; s < S; s++) { tmp[s] = _LOW; tmp[S] += _LOW; P(i, s) = 0; } for(k = 0; k < K; k ++) { tmp[Theta(k, i)] ++; tmp[S] ++; } for(s = 0; s < S; s ++) { P(i, s) = tmp[s] / tmp[S]; } } // update b for(i = 0; i < I; i ++) { double tmp = 0; for(k = 0; k < K; k ++) { tmp += 2 * lambdap * (1 - P(i, Theta(k, i))); } for(k = 0; k < K; k ++) { tmp -= 2 * lambdaw * (1 - W(Theta(k, i) * K + k, clusterLabels[i])); } if(tmp < 0) b[i] = 1; else b[i] = 0; } loss = 0; for(i = 0; i < I; i ++) { for(n = 0; n < N; n ++) { k = D[n]; s = Theta(k, i); loss += (Y(n, i) - Mu(n, s) * Gamma(s * N + n, i)) * (Y(n, i) - Mu(n, s) * Gamma(s * N + n, i)); } if(b[i] == 1) { for(k = 0; k < K; k ++) { loss += 2 * lambdap * (1 - P(i, Theta(k, i))); } } else { for(k = 0; k < K; k ++) { loss += 2 * (1 - W(Theta(k, i) * K + k, clusterLabels[i])) * lambdaw; } } } loss += lambda * (J - 1); //printf("b, Loss function = %3.3f, number of clusters = %d\n", loss, J); // update Theta for(i = 0; i < I; i ++) { for(k = 0; k < K; k ++) { double tmp[S]; for(s = 0; s < S; s ++) { // initialize tmp[s] = 0; // for(n = 0; n < N; n ++) { if(D[n] == k) { tmp[s] += (Y(n, i) - Mu(n, s) * Gamma(s * N + n, i)) * (Y(n, i) - Mu(n, s) * Gamma(s * N + n, i)); } } if(b[i] == 1) { tmp[s] += 2 * lambdap * (1 - P(i, s)); } else { tmp[s] += 2 * lambdaw * (1 - W(s * K + k, clusterLabels[i])); } } // Assign new values Theta(k, i) = 0; for(s = 1; s < S; s ++) { if(tmp[s] < tmp[Theta(k, i)]) Theta(k, i) = s; } } } loss = 0; for(i = 0; i < I; i ++) { for(n = 0; n < N; n ++) { k = D[n]; s = Theta(k, i); loss += (Y(n, i) - Mu(n, s) * Gamma(s * N + n, i)) * (Y(n, i) - Mu(n, s) * Gamma(s * N + n, i)); } if(b[i] == 1) { for(k = 0; k < K; k ++) { loss += 2 * lambdap * (1 - P(i, Theta(k, i))); } } else { for(k = 0; k < K; k ++) { loss += 2 * (1 - W(Theta(k, i) * K + k, clusterLabels[i])) * lambdaw; } } } loss += lambda * (J - 1); //printf("theta, Loss function = %3.3f, number of clusters = %d\n", loss, J); //update clusters for(i = 0; i < I; i ++) { // do not update cluster if this is a singleton if(b[i] == 1) continue; int oldState = clusterLabels[i]; ClusterSize[clusterLabels[i]] --; double tmp[J]; double mintmp = lambda;// cost of starting a new cluster int newState = J; for(j = 0; j < J; j ++) { tmp[j] = 0; for(k = 0; k < K; k ++) { tmp[j] += 2 * (1 - W(Theta(k, i) * K + k, j)) * lambdaw; } // assign the minimum cost if(tmp[j] < mintmp) { mintmp = tmp[j]; newState = j; } } clusterLabels[i] = newState; ClusterSize[newState] ++; if(mintmp >= lambda) { // a new cluster is formed if(J != newState) { printf("Error: new state is not J = %d.", J); exit(1); } for(s = 0; s < S; s ++) { for(k = 0; k < K; k ++) { if(Theta(k, i) != s) { W(s * K + k, J) = _LOW; } else { W(s * K + k, J) = 1 - (S - 1) * _LOW; } } } J ++; } if(ClusterSize[oldState] == 0) { // an old cluster should be removed W(_, oldState) = W(_, J - 1); for(k = 0; k < K * S; k ++) { W(k, J - 1) = 0; } for(i1 = 0; i1 < I; i1 ++) { if(clusterLabels[i1] == J - 1) clusterLabels[i1] = oldState; } ClusterSize[oldState] = ClusterSize[J - 1]; ClusterSize[J - 1] = 0; J --; } } loss = 0; for(i = 0; i < I; i ++) { for(n = 0; n < N; n ++) { k = D[n]; s = Theta(k, i); loss += (Y(n, i) - Mu(n, s) * Gamma(s * N + n, i)) * (Y(n, i) - Mu(n, s) * Gamma(s * N + n, i)); } if(b[i] == 1) { for(k = 0; k < K; k ++) { loss += 2 * lambdap * (1 - P(i, Theta(k, i))); } } else { for(k = 0; k < K; k ++) { loss += 2 * (1 - W(Theta(k, i) * K + k, clusterLabels[i])) * lambdaw; } } } loss += lambda * (J - 1); //printf("z, Loss function = %3.3f, number of clusters = %d\n", loss, J); // update mu for(n = 0; n < N; n ++) { double denom = 0, numer = 0; for(i = 0; i < I; i ++) { denom += Gamma(n + s * N, i); numer += Y(n, i); } for(s = 0; s < S; s ++) { Mu(n, s) = numer / denom; } for(s = 0; s < S; s ++) { denom = 0; numer = 0; for(i = 0; i < I; i ++) { if(Theta(D[n], i) == s) { numer += Y(n, i); denom += Gamma(n + s * N, i); } } if(denom > 0) { Mu(n, s) = numer / denom; } } } // calculate the loss function loss = 0; for(i = 0; i < I; i ++) { for(n = 0; n < N; n ++) { k = D[n]; s = Theta(k, i); loss += (Y(n, i) - Mu(n, s) * Gamma(s * N + n, i)) * (Y(n, i) - Mu(n, s) * Gamma(s * N + n, i)); } if(b[i] == 1) { for(k = 0; k < K; k ++) { loss += 2 * lambdap * (1 - P(i, Theta(k, i))); } } else { for(k = 0; k < K; k ++) { loss += 2 * (1 - W(Theta(k, i) * K + k, clusterLabels[i])) * lambdaw; } } } loss += lambda * (J - 1); //printf("Loss function = %3.3f, number of clusters = %d\n", loss, J); Rcpp::List ret = Rcpp::List::create( Rcpp::Named("Theta") = Theta, Rcpp::Named("clusterLabels") = clusterLabels, Rcpp::Named("b") = b, Rcpp::Named("W") = W, Rcpp::Named("P") = P, Rcpp::Named("Mu") = Mu, Rcpp::Named("loss") = loss //,Rcpp::Named("oldlik") = oldlik ); return( ret ); }
int main() { // Set all ranges Range<double> X(Xfrom,Xto); Range<double> T(Yfrom,Yto); // Declare all TwoVarDFunctions TwoVarDFunction<double,double,double> Sigma(*sigma); TwoVarDFunction<double,double,double> Mu(*mu); TwoVarDFunction<double,double,double> Forcing(*forcing); TwoVarDFunction<double,double,double> B(*b); // Declare all AtomicDFunctions AtomicDFunction<double,double> Ic(*IC); // Change from Call<->Put // AtomicDFunction<double,double> Bcr(*BCR_Topper_p11); AtomicDFunction<double,double> Bcr(*BCR);// Change from Call<->Put AtomicDFunction<double,double> Bcl(*BCL);// Change from Call<->Put // Declare the pde ParabolicPDE<double,double,double> pde(X,T,Sigma,Mu,B,Forcing,Ic,Bcl,Bcr); // Declare the finite difference scheme // ParabolicFDM<double,double,double> FDM(pde,XINTERVALS,YINTERVALS,THETA); // V1 int choice = 3; cout << "1) Explicit Euler 2) Implicit Euler 3) Crank Nicolson "; cin >> choice; //OptionType type = AmericanCallType; OptionType type = EuropeanCallType; ParabolicFDM<double,double,double> FDM(pde,XINTERVALS,YINTERVALS,choice, type); // compute option prices FDM.start(); // Retrieve and store option prices Vector <double,long> result = FDM.line(); // Does include ENDS!! /////////////////////////////////////////////////////////// Vector<double, long> xArr = FDM.xarr(); Vector<double, long> tArr = FDM.tarr(); double h = xArr[2] - xArr[1]; double k = tArr[2] - tArr[1]; cout << "h " << h << endl; // Create and fill Delta vector Vector <double,long> DeltaMesh(xArr.Size()-2, xArr.MinIndex()); for (long kk = DeltaMesh.MinIndex(); kk <= DeltaMesh.MaxIndex(); kk++) { DeltaMesh[kk] = xArr[kk+1]; } Vector <double,long> Delta(result.Size()-2,result.MinIndex()); for (long i = Delta.MinIndex(); i <= Delta.MaxIndex(); i++) { Delta[i] = (result[i+1] - result[i])/(h); } print(result); print(Delta); // Create and fill Gamma vector Vector <double,long> GammaMesh(DeltaMesh.Size()-2, DeltaMesh.MinIndex()); for (long p = GammaMesh.MinIndex(); p <= GammaMesh.MaxIndex(); p++) { GammaMesh[p] = DeltaMesh[p+1]; } Vector <double,long> Gamma(Delta.Size()-2, Delta.MinIndex()); for (long n = Gamma.MinIndex(); n <= Gamma.MaxIndex(); n++) { Gamma[n] = (Delta[n+1] - Delta[n])/(h); } /*// Create and fill Theta vector Vector <double,long> ThetaMesh(tArr.Size()-1, tArr.MinIndex()); for (long m = ThetaMesh.MinIndex(); m <= ThetaMesh.MaxIndex(); m++) { ThetaMesh[m] = tArr[m+1]; }*/ long NP1 = FDM.result().MaxRowIndex(); long NP = FDM.result().MaxRowIndex() -1; Vector <double,long> Theta(result.Size(), result.MinIndex()); for (long ii = Theta.MinIndex(); ii <= Theta.MaxIndex(); ii++) { Theta[ii] = -(FDM.result()(NP1, ii) -FDM.result()(NP, ii) )/k; } try { printOneExcel(FDM.xarr(), result, string("Price")); printOneExcel(DeltaMesh, Delta, string("Delta")); printOneExcel(GammaMesh, Gamma, string("Gamma")); printOneExcel(FDM.xarr(), Theta, string("Theta")); } catch(DatasimException& e) { e.print(); ExcelDriver& excel = ExcelDriver::Instance(); excel.MakeVisible(true); long y = 1; excel.printStringInExcel(e.Message(), y, y, string("Err")); list<string> dump; dump.push_back(e.MessageDump()[0]); dump.push_back(e.MessageDump()[1]); dump.push_back(e.MessageDump()[2]); excel.printStringInExcel(dump, 1, 1, string("Err")); return 0; } return 0; }
/**************************************************程序入口****************************************************/ int main() { clock_t start,finish; double totaltime; start=clock(); try { define_data(env);//首先初始化全局变量 IloInvert(env,B0,B0l,Node-1);//求逆矩阵 /*************************************************************主问题目标函数*******************************************************/ IloNumExpr Cost(env); for(IloInt w=0;w<NW;++w) { Cost+=detaPw[w]; } Master_Model.add(IloMinimize(env,Cost)); //Master_Model.add(IloMaximize(env,Cost));//目标函数二先一 Cost.end(); /********************************************************机组出力上下限约束**************************************************/ IloNumExpr expr1(env),expr2(env); for(IloInt i=0;i<NG;++i) { expr1+=detaP[i]; } for(IloInt w=0;w<NW;++w) { expr2+=detaPw[w]; } Master_Model.add(expr1==expr2); expr1.end(); expr2.end(); for(IloInt i=0;i<NG;++i) { Master_Model.add(detaP[i]>=Unit[i][1]*u[i]-P1[i]); Master_Model.add(detaP[i]<=Unit[i][2]*u[i]-P1[i]); Master_Model.add(detaP[i]>=-detaa[i]); Master_Model.add(detaP[i]<=detaa[i]); } IloNumExprArray detaP_node(env,Node-1),detaPw_node(env,Node-1); IloNumExprArray Theta(env,Node); for(IloInt b=0;b<Node-1;++b) { detaP_node[b]=IloNumExpr(env); detaPw_node[b]=IloNumExpr(env); IloInt i=0; for(;i<NG;++i) { if(Unit[i][0]==b-1)break; } if(i<NG) { detaP_node[b]+=detaP[i]; } else { detaP_node[b]+=0; } if(Sw[b]>=0) { detaPw_node[b]+=detaPw[ Sw[b] ]; } else { detaPw_node[b]+=0; } } for(IloInt b=0;b<Node-1;++b) { Theta[b]=IloNumExpr(env); for(IloInt k=0;k<Node-1;++k) { Theta[b]+=B0l[b][k]*(detaP_node[k]+detaPw_node[k]); } } Theta[Node-1]=IloNumExpr(env); for(IloInt h=0;h<Branch;++h) { IloNumExpr exprTheta(env);//莫明其妙的错误 exprTheta+=(Theta[(IloInt)Info_Branch[h][0]-1]-Theta[(IloInt)Info_Branch[h][1]-1]); Master_Model.add(exprTheta<=Info_Branch[h][3]*(Info_Branch[h][4]-PL[h])); Master_Model.add(exprTheta>=Info_Branch[h][3]*(-Info_Branch[h][4]-PL[h])); exprTheta.end(); //两个相减的节点顺序没有影响么? } Theta.end(); detaP_node.end(); detaPw_node.end(); Master_Cplex.extract(Master_Model); Master_Cplex.solve(); if (Master_Cplex.getStatus() == IloAlgorithm::Infeasible)//输出结果 { output<<"Master Problem Have No Solution"<<endl; goto lable2; } /************************************************************输出显示过程**************************************************/ output<<endl<<"Min/Max:"<<Master_Cplex.getObjValue()<<endl; lable2: Master_Model.end(); Master_Cplex.end(); env.end(); } catch(IloException& ex)//异常捕获 { output<<"Error: "<<ex<<endl; } catch(...) { output<<"Error: Unknown exception caught!" << endl; } finish=clock(); totaltime=(double)(finish-start)/CLOCKS_PER_SEC; output<<"totaltime: "<<totaltime<<"s"<<endl<<endl; output.close(); return 0; }
void MovementSolute::secondary_flow (const Geometry& geo, const std::vector<double>& Theta_old, const std::vector<double>& Theta_new, const std::vector<double>& q, const symbol name, const std::vector<double>& S, const std::map<size_t, double>& J_forced, const std::map<size_t, double>& C_border, std::vector<double>& M, std::vector<double>& J, const double dt, Treelog& msg) { const size_t cell_size = geo.cell_size (); const size_t edge_size = geo.edge_size (); // Full timstep left. daisy_assert (dt > 0.0); double time_left = dt; // Initial water content. std::vector<double> Theta (cell_size); for (size_t c = 0; c < cell_size; c++) Theta[c] = Theta_old[c]; // Small timesteps. for (;;) { // Are we done yet? const double min_timestep_factor = 1e-19; if (time_left < 0.1 * min_timestep_factor * dt) break; // Find new timestep. double ddt = time_left; // Limit timestep based on water flux. for (size_t e = 0; e < edge_size; e++) { const int cell = (q[e] > 0.0 ? geo.edge_from (e) : geo.edge_to (e)); if (geo.cell_is_internal (cell) && Theta[cell] > 1e-6 && M[cell] > 0.0) { const double loss_rate = std::fabs (q[e]) * geo.edge_area (e); const double content = Theta[cell] * geo.cell_volume (cell); const double time_to_empty = content / loss_rate; if (time_to_empty < min_timestep_factor * dt) { msg.warning ("Too fast water movement in secondary domain"); ddt = min_timestep_factor * dt; break; } // Go down in timestep while it takes less than two to empty cell. while (time_to_empty < 2.0 * ddt) ddt *= 0.5; } } // Cell source. Must be before transport to avoid negative values. for (size_t c = 0; c < cell_size; c++) M[c] += S[c] * ddt; // Find fluxes using new values (more stable). std::vector<double> dJ (edge_size, -42.42e42); for (size_t e = 0; e < edge_size; e++) { std::map<size_t, double>::const_iterator i = J_forced.find (e); if (i != J_forced.end ()) // Forced flux. { dJ[e] = (*i).second; daisy_assert (std::isfinite (dJ[e])); continue; } const int edge_from = geo.edge_from (e); const int edge_to = geo.edge_to (e); const bool in_flux = q[e] > 0.0; int flux_from = in_flux ? edge_from : edge_to; double C_flux_from = -42.42e42; if (geo.cell_is_internal (flux_from)) // Internal cell, use its concentration. { if (Theta[flux_from] > 1e-6 && M[flux_from] > 0.0) // Positive content in positive water. C_flux_from = M[flux_from] / Theta[flux_from]; else // You can't cut the hair of a bald guy. C_flux_from = 0.0; } else { i = C_border.find (e); if (i != C_border.end ()) // Specified by C_border. C_flux_from = (*i).second; else // Assume no gradient. { const int flux_to = in_flux ? edge_to : edge_from; daisy_assert (geo.cell_is_internal (flux_to)); if (Theta[flux_to] > 1e-6 && M[flux_to] > 0.0) // Positive content in positive water. C_flux_from = M[flux_to] / Theta[flux_to]; else // You can't cut the hair of a bald guy. C_flux_from = 0.0; } } // Convection. daisy_assert (std::isfinite (q[e])); daisy_assert (C_flux_from >= 0.0); dJ[e] = q[e] * C_flux_from; daisy_assert (std::isfinite (dJ[e])); } // Update values for fluxes. for (size_t e = 0; e < edge_size; e++) { const double value = ddt * dJ[e] * geo.edge_area (e); const int from = geo.edge_from (e); if (geo.cell_is_internal (from)) M[from] -= value / geo.cell_volume (from); const int to = geo.edge_to (e); if (geo.cell_is_internal (to)) M[to] += value / geo.cell_volume (to); J[e] += dJ[e] * ddt / dt; } // Update time left. time_left -= ddt; // Interpolate Theta. for (size_t c = 0; c < cell_size; c++) { const double left = time_left / dt; const double done = 1.0 - left; Theta[c] = left * Theta_old[c] + done * Theta_new[c]; } } }
RcppExport SEXP nsem3b(SEXP data, SEXP theta, SEXP Sigma, SEXP modelpar, SEXP control ) { // srand ( time(NULL) ); /* initialize random seed: */ Rcpp::NumericVector Theta(theta); Rcpp::NumericMatrix D(data); unsigned nobs = D.nrow(), k = D.ncol(); mat Data(D.begin(), nobs, k, false); // Avoid copying Rcpp::NumericMatrix V(Sigma); mat S(V.begin(), V.nrow(), V.ncol()); S(0,0) = 1; mat iS = inv(S); double detS = det(S); Rcpp::List Modelpar(modelpar); // Rcpp::IntegerVector _nlatent = Modelpar["nlatent"]; unsigned nlatent = _nlatent[0]; Rcpp::IntegerVector _ny0 = Modelpar["nvar0"]; unsigned ny0 = _ny0[0]; Rcpp::IntegerVector _ny1 = Modelpar["nvar1"]; unsigned ny1 = _ny1[0]; Rcpp::IntegerVector _ny2 = Modelpar["nvar2"]; unsigned ny2 = _ny2[0]; Rcpp::IntegerVector _npred0 = Modelpar["npred0"]; unsigned npred0 = _npred0[0]; Rcpp::IntegerVector _npred1 = Modelpar["npred1"]; unsigned npred1 = _npred1[0]; Rcpp::IntegerVector _npred2 = Modelpar["npred2"]; unsigned npred2 = _npred2[0]; Rcpp::List Control(control); Rcpp::NumericVector _lambda = Control["lambda"]; double lambda = _lambda[0]; Rcpp::NumericVector _niter = Control["niter"]; double niter = _niter[0]; Rcpp::NumericVector _Dtol = Control["Dtol"]; double Dtol = _Dtol[0]; rowvec mu0(ny0), lambda0(ny0); rowvec mu1(ny1), lambda1(ny1); rowvec mu2(ny2), lambda2(ny2); rowvec beta0(npred0); rowvec beta1(npred1); rowvec beta2(npred2); rowvec gamma(2); rowvec gamma2(2); unsigned pos=0; for (unsigned i=0; i<ny0; i++) { mu0(i) = Theta[pos]; pos++; } for (unsigned i=0; i<ny1; i++) { mu1(i) = Theta[pos]; pos++; } for (unsigned i=0; i<ny2; i++) { mu2(i) = Theta[pos]; pos++; } for (unsigned i=0; i<ny0; i++) { lambda0(i) = Theta[pos]; pos++; } lambda1(0) = 1; for (unsigned i=1; i<ny1; i++) { lambda1(i) = Theta[pos]; pos++; } lambda2(0) = 1; for (unsigned i=1; i<ny2; i++) { lambda2(i) = Theta[pos]; pos++; } for (unsigned i=0; i<npred0; i++) { beta0(i) = Theta[pos]; pos++; } for (unsigned i=0; i<npred1; i++) { beta1(i) = Theta[pos]; pos++; } for (unsigned i=0; i<npred2; i++) { beta2(i) = Theta[pos]; pos++; } gamma(0) = Theta[pos]; gamma(1) = Theta[pos+1]; gamma2(0) = Theta[pos+2]; gamma2(1) = Theta[pos+3]; // cerr << "mu0=" << mu0 << endl; // cerr << "mu1=" << mu1 << endl; // cerr << "mu2=" << mu2 << endl; // cerr << "lambda0=" << lambda0 << endl; // cerr << "lambda1=" << lambda1 << endl; // cerr << "lambda2=" << lambda2 << endl; // cerr << "beta0=" << beta0 << endl; // cerr << "beta1=" << beta1 << endl; // cerr << "beta2=" << beta2 << endl; // cerr << "gamma=" << gamma << endl; // cerr << "gamma2=" << gamma2 << endl; mat lap(nobs,4); for (unsigned i=0; i<nobs; i++) { rowvec newlap = laNRb(Data.row(i), iS, detS, mu0, mu1, mu2, lambda0, lambda1, lambda2, beta0,beta1, beta2, gamma, gamma2, Dtol,niter,lambda); lap.row(i) = newlap; } List res; res["indiv"] = lap; res["logLik"] = sum(lap.col(0)) + (3-V.nrow())*log(2.0*datum::pi)*nobs/2; res["norm0"] = (3-V.nrow())*log(2*datum::pi)/2; return res; }
Vec3f CylinderDistribution3D::generate(void) const { Vec3f Result; switch(getSurfaceOrVolume()) { case SURFACE: { std::vector<Real32> Areas; //Min Cap Areas.push_back(0.5*osgAbs(getMaxTheta() - getMinTheta())*(getOuterRadius()*getOuterRadius() - getInnerRadius()*getInnerRadius())); //Max Cap Areas.push_back(Areas.back() + 0.5*osgAbs(getMaxTheta() - getMinTheta())*(getOuterRadius()*getOuterRadius() - getInnerRadius()*getInnerRadius())); //Inner Tube Areas.push_back(Areas.back() + getInnerRadius()*osgAbs(getMaxTheta() - getMinTheta()) * getHeight()); //Outer Tube Areas.push_back(Areas.back() + getOuterRadius()*osgAbs(getMaxTheta() - getMinTheta()) * getHeight()); bool HasTubeSides(osgAbs(getMaxTheta() - getMinTheta()) - 6.283185 < -0.000001); if(HasTubeSides) { //MinTheta Tube Side Areas.push_back(Areas.back() + (getOuterRadius() - getInnerRadius()) * getHeight()); //MaxTheta Tube Side Areas.push_back(Areas.back() + (getOuterRadius() - getInnerRadius()) * getHeight()); } Real32 PickEdge(RandomPoolManager::getRandomReal32(0.0,1.0)); if(PickEdge < Areas[0]/Areas.back()) { //Max Cap Real32 Temp(osgSqrt(RandomPoolManager::getRandomReal32(0.0,1.0))); Real32 Radius(getInnerRadius() + Temp*(getOuterRadius() - getInnerRadius())); Real32 Theta( RandomPoolManager::getRandomReal32(getMinTheta(),getMaxTheta()) ); Result = getCenter().subZero() + (Radius*osgSin(Theta))*getTangent() + (Radius*osgCos(Theta))*getBinormal() + (getHeight()/static_cast<Real32>(2.0))*getNormal(); } else if(PickEdge < Areas[1]/Areas.back()) { //Min Cap Real32 Temp(osgSqrt(RandomPoolManager::getRandomReal32(0.0,1.0))); Real32 Radius(getInnerRadius() + Temp*(getOuterRadius() - getInnerRadius())); Real32 Theta( RandomPoolManager::getRandomReal32(getMinTheta(),getMaxTheta()) ); Result = getCenter().subZero() + (Radius*osgSin(Theta))*getTangent() + (Radius*osgCos(Theta))*getBinormal() + (-getHeight()/static_cast<Real32>(2.0))*getNormal(); } else if(PickEdge < Areas[2]/Areas.back()) { //Inner Tube Real32 Theta( RandomPoolManager::getRandomReal32(getMinTheta(),getMaxTheta()) ); Real32 Height(RandomPoolManager::getRandomReal32(-getHeight()/2.0,getHeight()/2.0)); Result = getCenter().subZero() + getInnerRadius()*osgSin(Theta)*getTangent() + getInnerRadius()*osgCos(Theta)*getBinormal() + Height*getNormal(); } else if(PickEdge < Areas[3]/Areas.back()) { //Outer Tube Real32 Theta( RandomPoolManager::getRandomReal32(getMinTheta(),getMaxTheta()) ); Real32 Height(RandomPoolManager::getRandomReal32(-getHeight()/2.0,getHeight()/2.0)); Result = getCenter().subZero() + getOuterRadius()*osgSin(Theta)*getTangent() + getOuterRadius()*osgCos(Theta)*getBinormal() + Height*getNormal(); } else if(HasTubeSides && PickEdge < Areas[4]/Areas.back()) { //MinTheta Tube Side Real32 Temp(osgSqrt(RandomPoolManager::getRandomReal32(0.0,1.0))); Real32 Radius(getInnerRadius() + Temp*(getOuterRadius() - getInnerRadius())); Real32 Height(RandomPoolManager::getRandomReal32(-getHeight()/2.0,getHeight()/2.0)); Result = getCenter().subZero() + (Radius*osgSin(getMinTheta()))*getTangent() + (Radius*osgCos(getMinTheta()))*getBinormal() + Height*getNormal(); } else if(HasTubeSides && PickEdge < Areas[5]/Areas.back()) { //MaxTheta Tube Side Real32 Temp(osgSqrt(RandomPoolManager::getRandomReal32(0.0,1.0))); Real32 Radius(getInnerRadius() + Temp*(getOuterRadius() - getInnerRadius())); Real32 Height(RandomPoolManager::getRandomReal32(-getHeight()/2.0,getHeight()/2.0)); Result = getCenter().subZero() + (Radius*osgSin(getMaxTheta()))*getTangent() + (Radius*osgCos(getMaxTheta()))*getBinormal() + Height*getNormal(); } else { assert(false && "Should never reach this point"); } break; } case VOLUME: default: { //To get a uniform distribution across the disc get a uniformly distributed allong 0.0 - 1.0 //Then Take the square root of that. This gives a square root distribution from 0.0 - 1.0 //This square root distribution is used for the random radius because the area of a disc is //dependant on the square of the radius, i.e it is a quadratic function Real32 Temp(osgSqrt(RandomPoolManager::getRandomReal32(0.0,1.0))); Real32 Radius(getInnerRadius() + Temp*(getOuterRadius() - getInnerRadius())); Real32 Height(RandomPoolManager::getRandomReal32(-getHeight()/2.0,getHeight()/2.0)); Real32 Theta( RandomPoolManager::getRandomReal32(getMinTheta(),getMaxTheta()) ); Result = getCenter().subZero() + (Radius*osgSin(Theta))*getTangent() + (Radius*osgCos(Theta))*getBinormal() + Height*getNormal(); break; } } return Result; }