std::vector<std::shared_ptr<Material>> ModelLoader::loadMaterials(const aiScene* scene, std::map<std::string, std::shared_ptr<Texture>> textures) { std::vector<std::shared_ptr<Material>> output; for (unsigned int materialIndex = 0; materialIndex < scene->mNumMaterials; ++materialIndex) { std::shared_ptr<BasicLightingMaterial> currentGeneratedMaterial(std::make_shared<BasicLightingMaterial>()); const aiMaterial *material = scene->mMaterials[materialIndex]; aiColor4D aiDiffuse; aiColor4D aiSpecular; aiColor4D aiAmbient; aiColor4D aiEmission; glm::vec4 diffuse(1.0f, 1.0f, 1.0f, 1.0f); glm::vec4 specular(0.0f, 0.0f, 0.0f, 0.0f); glm::vec4 ambient(0.0f, 0.0f, 0.0f, 1.0f); glm::vec4 emission(0.0f, 0.0f, 0.0f, 0.0f); float shininess; float shininessStrength; unsigned int max = 1; aiString texturePath; std::shared_ptr<Texture> texture(std::make_shared<Texture>()); if (AI_SUCCESS == aiGetMaterialColor(material, AI_MATKEY_COLOR_DIFFUSE, &aiDiffuse)) { diffuse = aiColor4DToGlmVec4(aiDiffuse); } if (AI_SUCCESS == aiGetMaterialColor(material, AI_MATKEY_COLOR_SPECULAR, &aiSpecular)) { specular = aiColor4DToGlmVec4(aiSpecular); } if (AI_SUCCESS == aiGetMaterialColor(material, AI_MATKEY_COLOR_AMBIENT, &aiAmbient)) { ambient = aiColor4DToGlmVec4(aiAmbient); } if (AI_SUCCESS == aiGetMaterialColor(material, AI_MATKEY_COLOR_EMISSIVE, &aiEmission)) { emission = aiColor4DToGlmVec4(aiEmission); } aiGetMaterialFloatArray(material, AI_MATKEY_SHININESS, &shininess, &max); aiGetMaterialFloatArray(material, AI_MATKEY_SHININESS_STRENGTH, &shininessStrength, &max); shininess *= shininessStrength; if (AI_SUCCESS == material->GetTexture(aiTextureType_DIFFUSE, 0, &texturePath)) { std::string path(texturePath.data); texture = textures[path]; } currentGeneratedMaterial->setDiffuse(diffuse); currentGeneratedMaterial->setSpecular(specular); currentGeneratedMaterial->setAmbient(ambient); currentGeneratedMaterial->setEmission(emission); currentGeneratedMaterial->setShininess(shininess); currentGeneratedMaterial->setTexture(texture); output.push_back(currentGeneratedMaterial); } return output; }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RenderStateMaterial_FF::applyOpenGL(OpenGLContext* oglContext) const { Color4f ambient(m_ambient, m_alpha); Color4f diffuse(m_diffuse, m_alpha); Color4f emission(m_emission, m_alpha); Color4f specular(m_specular, m_alpha); CVF_ASSERT(ambient.isValid()); CVF_ASSERT(diffuse.isValid()); CVF_ASSERT(emission.isValid()); CVF_ASSERT(specular.isValid()); CVF_ASSERT(Math::valueInRange(m_shininess, 0.0f, 128.0f)); if (m_enableColorMaterial) { glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glEnable(GL_COLOR_MATERIAL); } else { glDisable(GL_COLOR_MATERIAL); } glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient.ptr()); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse.ptr()); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular.ptr()); glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emission.ptr()); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, m_shininess); // Try this to be nice if lighting is off glColor3fv(diffuse.ptr()); CVF_CHECK_OGL(oglContext); }
int main(int argc, char **argv) { int c; bool debug_mode = false; bool verbose_mode = false; while ((c = getopt(argc, argv, "dv")) != -1) { switch (c) { case 'd': debug_mode = true; break; case 'v': verbose_mode = true; break; default: /* '?' */ fprintf(stderr, "Anvendelse: %s [-d] [-v]\n", argv[0]); exit(1); } } lineno = 1; if (verbose_mode) { fprintf(stderr, "Leksikalsk og syntaktisk analyse udføres ...\n"); } int parse = yyparse(); if (parse != 0) { fprintf(stderr, "Der opstod en fejl under den leksikalske eller syntaktiske analyse.\n"); return 1; } if (verbose_mode) { fprintf(stderr, "Leksikalsk og syntaktisk analyse blev udført.\n"); } if (debug_mode) { fprintf(stderr, "Pæn udskrift efter leksikalsk og syntaktisk analyse:\n"); prettyMAIN(theprogram); } if (verbose_mode) { fprintf(stderr, "Semantisk analyse udføres ...\n"); } SymbolTable *mscope = initSymbolTable(); int traversalerr = traversal(theprogram, mscope); if (traversalerr != 0) { fprintf(stderr, "Der opstod i alt %d fejl under den semantiske analyse.\n", traversalerr); return 1; } if (verbose_mode) { fprintf(stderr, "Semantisk analyse blev udført.\n"); } if (debug_mode) { dumpsymbol(theprogram, mscope); } if (verbose_mode) { fprintf(stderr, "Kodegenerering udføres ...\n"); } LINKED_LIST *l = generateCode(theprogram, mscope); l = registerAllocation(l); if (verbose_mode) { fprintf(stderr, "Kodegenerering blev udført.\n"); } emission(l); return 0; }
RcppExport SEXP trans_loop(SEXP likelihood_forward_backward,SEXP time_diffs_list, SEXP eigen_decomp_list, SEXP obs_data_list, SEXP emission_list, SEXP exact_time_ranks_list,SEXP the_state_size,SEXP absorb_state,SEXP ij_indices,SEXP time_dep_emission){ arma::imat state_pairs=Rcpp::as<arma::imat>(ij_indices); int num_state_pairs=state_pairs.n_rows; Rcpp::List llfb(likelihood_forward_backward); Rcpp::List time_diff(time_diffs_list); Rcpp::List eigen_list(eigen_decomp_list); Rcpp::List obsdata_list(obs_data_list); Rcpp::List emission(emission_list); Rcpp::List exact_time_ranks(exact_time_ranks_list); bool time_dep=Rcpp::as<bool>(time_dep_emission); int state_size=Rcpp::as<int>(the_state_size); int num_subjects=eigen_list.size(); arma::cube expected_trans_array=arma::zeros<arma::cube>(state_size,state_size,num_subjects); for(int i=0; i<num_state_pairs; i++){ for(int k=0; k<num_subjects;k++){ Rcpp::List indivEigen=Rcpp::as<Rcpp::List>(eigen_list[k]); arma::vec indivTime=Rcpp::as<arma::vec>(time_diff[k]); arma::icolvec obsdata=Rcpp::as<arma::icolvec>(obsdata_list[k]); Rcpp::List indivLLFB=Rcpp::as<Rcpp::List>(llfb[k]); arma::mat logalpha=Rcpp::as<arma::mat>(indivLLFB["logalpha"]); arma::mat logbeta=Rcpp::as<arma::mat>(indivLLFB["logbeta"]); double LL=Rcpp::as<double>(indivLLFB["LL"]); int size=indivTime.n_elem; std::vector<arma::mat> joint_means_trans(size); arma::mat regist_matrix=arma::zeros<arma::mat>(state_size,state_size); regist_matrix(state_pairs(i,0)-1,state_pairs(i,1)-1)=1; for(int l=0; l<size;l++){ joint_means_trans[l]=joint_mean_markov_jumps_cpp(indivEigen,regist_matrix, indivTime(l)); } if(Rf_isNull(exact_time_ranks[k])==0){ int exact_time_index=Rcpp::as<int>(exact_time_ranks[k])-2; arma::ivec the_absorb_state=Rcpp::as<arma::ivec>(absorb_state); int start_state=state_pairs(i,0); int end_state=state_pairs(i,1); joint_means_trans[exact_time_index]=exact_trans(joint_means_trans,indivEigen,indivTime(exact_time_index),the_absorb_state, start_state,end_state,exact_time_index); } if(time_dep==false){ arma::mat indivEmission=Rcpp::as<arma::mat>(emission[k]); expected_trans_array(state_pairs(i,0)-1,state_pairs(i,1)-1,k)=get_mean_cpp(joint_means_trans,obsdata, logalpha, logbeta, LL, indivEmission); }else{ Rcpp::List indivEmissionList=Rcpp::as<Rcpp::List>(emission[k]); expected_trans_array(state_pairs(i,0)-1,state_pairs(i,1)-1,k)=get_mean_cpp_time_dep_emission(joint_means_trans,obsdata, logalpha, logbeta, LL, indivEmissionList); } } } return(Rcpp::wrap(expected_trans_array)); }
List viterbi(const arma::mat& transition, NumericVector emissionArray, const arma::vec& init, IntegerVector obsArray) { IntegerVector eDims = emissionArray.attr("dim"); //m,p,r IntegerVector oDims = obsArray.attr("dim"); //k,n,r arma::cube emission(emissionArray.begin(), eDims[0], eDims[1], eDims[2], false, true); arma::icube obs(obsArray.begin(), oDims[0], oDims[1], oDims[2], false, true); arma::umat q(obs.n_slices, obs.n_cols); arma::vec logp(obs.n_slices); arma::mat delta(emission.n_rows, obs.n_cols); arma::umat phi(emission.n_rows, obs.n_cols); for (unsigned int k = 0; k < obs.n_slices; k++) { delta.col(0) = init; for (unsigned int r = 0; r < emission.n_slices; r++) { delta.col(0) += emission.slice(r).col(obs(r, 0, k)); } phi.col(0).zeros(); for (unsigned int t = 1; t < obs.n_cols; t++) { for (unsigned int j = 0; j < emission.n_rows; j++) { (delta.col(t - 1) + transition.col(j)).max(phi(j, t)); delta(j, t) = delta(phi(j, t), t - 1) + transition(phi(j, t), j); for (unsigned int r = 0; r < emission.n_slices; r++) { delta(j, t) += emission(j, obs(r, t, k), r); } } } delta.col(obs.n_cols - 1).max(q(k, obs.n_cols - 1)); for (int t = (obs.n_cols - 2); t >= 0; t--) { q(k, t) = phi(q(k, t + 1), t + 1); } logp(k) = delta.col(obs.n_cols - 1).max(); } return List::create(Named("q") = wrap(q), Named("logp") = wrap(logp)); }
Tcolor TrayTracer::radianceWithExplicitLight(Tray ray,int reflectLevel) { if(reflectLevel <= 0) return Tcolor(0,0,0); Tcolor finalColor(0,0,0); auto result = scene()->intersect(ray); if (result.geometry()) { auto material = result.geometry ()->material (); if(!material) return finalColor; Tcolor selfColor = material->sampleSelfColor (); //**********Emission. auto emissionColor = selfColor*material->emission (); //reflect Tcolor reflectColor; auto allLights = scene()->getLightList(); for(int i =0;i<allLights.size ();i++) { TexplicitLight * light = allLights[i]; if(!light->isVisible (result.pos (),scene())) continue; //get the irradiance from the explicit light source. auto lightDir = light->getDir (result.pos ()); auto lightRadiance = light->getIrradiance (result.pos (),result.normal (),scene()); reflectColor += lightRadiance * material->BRDF (-ray.direction (),-lightDir,result.normal ()); } //ideal specular radiance from other object. if(material->reflectiveness () > 0) { // get the ideal specular ray. auto reflectVec = reflect(ray.direction (),result.normal ()); auto reflectRay = Tray(result.pos (),reflectVec); auto idealSpecularRadiance = radianceWithExplicitLight(reflectRay,reflectLevel - 1); reflectColor +=idealSpecularRadiance * material->BRDF (-ray.direction (),reflectVec,result.normal ()); } //render euqation. finalColor = emissionColor+ selfColor*reflectColor*material->reflectiveness (); } return finalColor; }
void CalcButs::submission(QString str){ if (str == "Reset"){ emit reset(); } else if (str == "C"){ emit C(); } else if (str == "="){ emit eq(); } else if (str == "0" || str == "1" || str == "2" || str == "3" || str == "4" ||str == "5" || str == "6" || str == "7" || str == "8" || str == "9" || (complex && str == ".") || str == "+" || str == "-" || str == "*" || (field && str == "/") || str == "^" || str == "(" || (complex && str == "i") || str == "x" || str == ")"){ emit emission(str); } }
int MaceWindow::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QMainWindow::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { switch (_id) { case 0: emission((*reinterpret_cast< QString(*)>(_a[1]))); break; case 1: give_info((*reinterpret_cast< QString(*)>(_a[1]))); break; case 2: newFile(); break; case 3: load(); break; case 4: save(); break; case 5: saveFileAs(); break; default: ; } _id -= 6; } return _id; }
List forwardbackward(const arma::mat& transition, NumericVector emissionArray, const arma::vec& init, IntegerVector obsArray, bool forwardonly, int threads) { IntegerVector eDims = emissionArray.attr("dim"); //m,p,r IntegerVector oDims = obsArray.attr("dim"); //k,n,r arma::cube emission(emissionArray.begin(), eDims[0], eDims[1], eDims[2], false, true); arma::icube obs(obsArray.begin(), oDims[0], oDims[1], oDims[2], false, true); arma::cube alpha(emission.n_rows, obs.n_cols, obs.n_slices); //m,n,k arma::mat scales(obs.n_cols, obs.n_slices); //n,k internalForward(transition, emission, init, obs, alpha, scales, threads); if(!scales.is_finite()) { Rcpp::stop("Scaling factors contain non-finite values. \n Check the model or try using the log-space version of the algorithm."); } double min_sf = scales.min(); if (min_sf < 1e-150) { Rcpp::warning("Smallest scaling factor was %e, results can be numerically unstable.", min_sf); } if (forwardonly) { return List::create(Named("forward_probs") = wrap(alpha), Named("scaling_factors") = wrap(scales)); } else { arma::cube beta(emission.n_rows, obs.n_cols, obs.n_slices); //m,n,k internalBackward(transition, emission, obs, beta, scales, threads); if(!beta.is_finite()) { Rcpp::stop("Backward probabilities contain non-finite values. Check the model or try using the log-space version of the algorithm."); } return List::create(Named("forward_probs") = wrap(alpha), Named("backward_probs") = wrap(beta), Named("scaling_factors") = wrap(scales)); } }
CalcButs::CalcButs(int h, int w, int fs, QTextEdit *e, QWidget *parent): width(w), height(h), fontsize(fs), edit(e), QGridLayout(parent) { this->setHorizontalSpacing(0); this->setVerticalSpacing(0); butC = new StringButton("C",height, 2*width+1, fontsize); butReset = new StringButton("Reset",height, 2*width+1, fontsize); but0 = new StringButton("0", height, width, fontsize); but1 = new StringButton("1", height, width, fontsize); but2 = new StringButton("2", height, width, fontsize); but3 = new StringButton("3", height, width, fontsize); but4 = new StringButton("4", height, width, fontsize); but5 = new StringButton("5", height, width, fontsize); but6 = new StringButton("6", height, width, fontsize); but7 = new StringButton("7", height, width, fontsize); but8 = new StringButton("8", height, width, fontsize); but9 = new StringButton("9", height, width, fontsize); butPlus = new StringButton("+",height, width, fontsize); butMinus = new StringButton("-", height, width, fontsize); butTimes = new StringButton("*", height, width, fontsize); butDiv = new StringButton("/", height, width, fontsize); butDot = new StringButton(".", height, width, fontsize); butEq = new StringButton("=", height, width, fontsize); butBrackOpen = new StringButton("(", height, width, fontsize); butx = new StringButton("x", height, width, fontsize); buti = new StringButton("i", height, width, fontsize); butBrackClose = new StringButton(")", height, width, fontsize); butPower = new StringButton("^", height, width, fontsize); this->addWidget(butC,0,0,1, 2); this->addWidget(butReset,0,2,1, 2); this->addWidget(but7,1,0,1, 1); this->addWidget(but8,1,1,1, 1); this->addWidget(but9,1,2,1, 1); this->addWidget(butDiv,1,3,1, 1); this->addWidget(but4,2,0,1, 1); this->addWidget(but5,2,1,1, 1); this->addWidget(but6,2,2,1, 1); this->addWidget(butTimes,2,3,1, 1); this->addWidget(but1,3,0,1, 1); this->addWidget(but2,3,1,1, 1); this->addWidget(but3,3,2,1, 1); this->addWidget(butMinus,3,3,1, 1); this->addWidget(but0,4,0,1, 1); this->addWidget(butDot,4,1,1, 1); this->addWidget(butEq,4,2,1, 1); this->addWidget(butPlus,4,3,1, 1); this->addWidget(butPower,0,5,1, 1); this->addWidget(butBrackOpen,1,5,1, 1); this->addWidget(butBrackClose,2,5,1, 1); this->addWidget(butx,3,5,1, 1); this->addWidget(buti,4,5,1, 1); field = true; complex = true; QObject::connect(this->but0,SIGNAL(sig_string(QString)),this,SLOT(submission(QString))); QObject::connect(this->but1,SIGNAL(sig_string(QString)),this,SLOT(submission(QString))); QObject::connect(this->but2,SIGNAL(sig_string(QString)),this,SLOT(submission(QString))); QObject::connect(this->but3,SIGNAL(sig_string(QString)),this,SLOT(submission(QString))); QObject::connect(this->but4,SIGNAL(sig_string(QString)),this,SLOT(submission(QString))); QObject::connect(this->but5,SIGNAL(sig_string(QString)),this,SLOT(submission(QString))); QObject::connect(this->but6,SIGNAL(sig_string(QString)),this,SLOT(submission(QString))); QObject::connect(this->but7,SIGNAL(sig_string(QString)),this,SLOT(submission(QString))); QObject::connect(this->but8,SIGNAL(sig_string(QString)),this,SLOT(submission(QString))); QObject::connect(this->but9,SIGNAL(sig_string(QString)),this,SLOT(submission(QString))); QObject::connect(this->butPlus,SIGNAL(sig_string(QString)),this,SLOT(submission(QString))); QObject::connect(this->butMinus,SIGNAL(sig_string(QString)),this,SLOT(submission(QString))); QObject::connect(this->butTimes,SIGNAL(sig_string(QString)),this,SLOT(submission(QString))); QObject::connect(this->butDiv,SIGNAL(sig_string(QString)),this,SLOT(submission(QString))); QObject::connect(this->butDot,SIGNAL(sig_string(QString)),this,SLOT(submission(QString))); QObject::connect(this->butEq,SIGNAL(sig_string(QString)),this,SLOT(submission(QString))); QObject::connect(this->butBrackOpen,SIGNAL(sig_string(QString)),this,SLOT(submission(QString))); QObject::connect(this->butx,SIGNAL(sig_string(QString)),this,SLOT(submission(QString))); QObject::connect(this->buti,SIGNAL(sig_string(QString)),this,SLOT(submission(QString))); QObject::connect(this->butBrackClose,SIGNAL(sig_string(QString)),this,SLOT(submission(QString))); QObject::connect(this->butPower,SIGNAL(sig_string(QString)),this,SLOT(submission(QString))); QObject::connect(this->butC,SIGNAL(sig_string(QString)),this,SLOT(submission(QString))); QObject::connect(this->butReset,SIGNAL(sig_string(QString)),this,SLOT(submission(QString))); QObject::connect(this,SIGNAL(emission(QString)),edit,SLOT(insertPlainText(QString))); QObject::connect(this,SIGNAL(C()),edit,SLOT(C())); QObject::connect(this,SIGNAL(eq()),edit,SLOT(eq())); }
void LightTracer::traceSample(PathSampleGenerator &sampler) { float lightPdf; const Primitive *light = chooseLightAdjoint(sampler, lightPdf); const Medium *medium = light->extMedium().get(); PositionSample point; if (!light->samplePosition(sampler, point)) return; DirectionSample direction; if (!light->sampleDirection(sampler, point, direction)) return; sampler.advancePath(); Vec3f throughput(point.weight/lightPdf); LensSample splat; if (_settings.minBounces == 0 && !light->isInfinite() && _scene->cam().sampleDirect(point.p, sampler, splat)) { Ray shadowRay(point.p, splat.d); shadowRay.setFarT(splat.dist); Vec3f transmission = generalizedShadowRay(shadowRay, medium, nullptr, 0); if (transmission != 0.0f) { Vec3f value = throughput*transmission*splat.weight *light->evalDirectionalEmission(point, DirectionSample(splat.d)); _splatBuffer->splatFiltered(splat.pixel, value); } } sampler.advancePath(); Ray ray(point.p, direction.d); throughput *= direction.weight; VolumeScatterEvent volumeEvent; SurfaceScatterEvent surfaceEvent; IntersectionTemporary data; IntersectionInfo info; Medium::MediumState state; state.reset(); Vec3f emission(0.0f); int bounce = 0; bool wasSpecular = true; bool didHit = _scene->intersect(ray, data, info); while ((didHit || medium) && bounce < _settings.maxBounces - 1) { bool hitSurface = true; if (medium) { volumeEvent = VolumeScatterEvent(&sampler, throughput, ray.pos(), ray.dir(), ray.farT()); if (!medium->sampleDistance(volumeEvent, state)) break; throughput *= volumeEvent.weight; volumeEvent.weight = Vec3f(1.0f); hitSurface = volumeEvent.t == volumeEvent.maxT; if (hitSurface && !didHit) break; } if (hitSurface) { surfaceEvent = makeLocalScatterEvent(data, info, ray, &sampler); Vec3f weight; Vec2f pixel; if (surfaceLensSample(_scene->cam(), surfaceEvent, medium, bounce + 1, ray, weight, pixel)) _splatBuffer->splatFiltered(pixel, weight*throughput); if (!handleSurface(surfaceEvent, data, info, medium, bounce, true, false, ray, throughput, emission, wasSpecular, state)) break; } else { volumeEvent.p += volumeEvent.t*volumeEvent.wi; Vec3f weight; Vec2f pixel; if (volumeLensSample(_scene->cam(), volumeEvent, medium, bounce + 1, ray, weight, pixel)) _splatBuffer->splatFiltered(pixel, weight*throughput); if (!handleVolume(volumeEvent, medium, bounce, true, false, ray, throughput, emission, wasSpecular, state)) break; } if (throughput.max() == 0.0f) break; if (std::isnan(ray.dir().sum() + ray.pos().sum())) break; if (std::isnan(throughput.sum())) break; sampler.advancePath(); bounce++; if (bounce < _settings.maxBounces) didHit = _scene->intersect(ray, data, info); } }
int main(int argc,char **argv) { PetscErrorCode ierr; int time; /* amount of loops */ struct in put; PetscScalar rh; /* relative humidity */ PetscScalar x; /* memory varialbe for relative humidity calculation */ PetscScalar deep_grnd_temp; /* temperature of ground under top soil surface layer */ PetscScalar emma; /* absorption-emission constant for air */ PetscScalar pressure1 = 101300; /* surface pressure */ PetscScalar mixratio; /* mixing ratio */ PetscScalar airtemp; /* temperature of air near boundary layer inversion */ PetscScalar dewtemp; /* dew point temperature */ PetscScalar sfctemp; /* temperature at surface */ PetscScalar pwat; /* total column precipitable water */ PetscScalar cloudTemp; /* temperature at base of cloud */ AppCtx user; /* user-defined work context */ MonitorCtx usermonitor; /* user-defined monitor context */ PetscMPIInt rank,size; TS ts; SNES snes; DM da; Vec T,rhs; /* solution vector */ Mat J; /* Jacobian matrix */ PetscReal ftime,dt; PetscInt steps,dof = 5; PetscBool use_coloring = PETSC_TRUE; MatFDColoring matfdcoloring = 0; PetscBool monitor_off = PETSC_FALSE; PetscInitialize(&argc,&argv,(char*)0,help); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); /* Inputs */ readinput(&put); sfctemp = put.Ts; dewtemp = put.Td; cloudTemp = put.Tc; airtemp = put.Ta; pwat = put.pwt; if (!rank) PetscPrintf(PETSC_COMM_SELF,"Initial Temperature = %g\n",sfctemp); /* input surface temperature */ deep_grnd_temp = sfctemp - 10; /* set underlying ground layer temperature */ emma = emission(pwat); /* accounts for radiative effects of water vapor */ /* Converts from Fahrenheit to Celsuis */ sfctemp = fahr_to_cel(sfctemp); airtemp = fahr_to_cel(airtemp); dewtemp = fahr_to_cel(dewtemp); cloudTemp = fahr_to_cel(cloudTemp); deep_grnd_temp = fahr_to_cel(deep_grnd_temp); /* Converts from Celsius to Kelvin */ sfctemp += 273; airtemp += 273; dewtemp += 273; cloudTemp += 273; deep_grnd_temp += 273; /* Calculates initial relative humidity */ x = calcmixingr(dewtemp,pressure1); mixratio = calcmixingr(sfctemp,pressure1); rh = (x/mixratio)*100; if (!rank) printf("Initial RH = %.1f percent\n\n",rh); /* prints initial relative humidity */ time = 3600*put.time; /* sets amount of timesteps to run model */ /* Configure PETSc TS solver */ /*------------------------------------------*/ /* Create grid */ ierr = DMDACreate2d(PETSC_COMM_WORLD,DMDA_BOUNDARY_PERIODIC,DMDA_BOUNDARY_PERIODIC,DMDA_STENCIL_STAR,-20,-20, PETSC_DECIDE,PETSC_DECIDE,dof,1,NULL,NULL,&da);CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(da, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0);CHKERRQ(ierr); /* Define output window for each variable of interest */ ierr = DMDASetFieldName(da,0,"Ts");CHKERRQ(ierr); ierr = DMDASetFieldName(da,1,"Ta");CHKERRQ(ierr); ierr = DMDASetFieldName(da,2,"u");CHKERRQ(ierr); ierr = DMDASetFieldName(da,3,"v");CHKERRQ(ierr); ierr = DMDASetFieldName(da,4,"p");CHKERRQ(ierr); /* set values for appctx */ user.da = da; user.Ts = sfctemp; user.fract = put.fr; /* fraction of sky covered by clouds */ user.dewtemp = dewtemp; /* dew point temperature (mositure in air) */ user.csoil = 2000000; /* heat constant for layer */ user.dzlay = 0.08; /* thickness of top soil layer */ user.emma = emma; /* emission parameter */ user.wind = put.wnd; /* wind spped */ user.pressure1 = pressure1; /* sea level pressure */ user.airtemp = airtemp; /* temperature of air near boundar layer inversion */ user.Tc = cloudTemp; /* temperature at base of lowest cloud layer */ user.init = put.init; /* user chosen initiation scenario */ user.lat = 70*0.0174532; /* converts latitude degrees to latitude in radians */ user.deep_grnd_temp = deep_grnd_temp; /* temp in lowest ground layer */ /* set values for MonitorCtx */ usermonitor.drawcontours = PETSC_FALSE; ierr = PetscOptionsHasName(NULL,"-drawcontours",&usermonitor.drawcontours);CHKERRQ(ierr); if (usermonitor.drawcontours) { PetscReal bounds[] = {1000.0,-1000., -1000.,-1000., 1000.,-1000., 1000.,-1000., 1000,-1000, 100700,100800}; ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD,0,0,0,0,300,300,&usermonitor.drawviewer);CHKERRQ(ierr); ierr = PetscViewerDrawSetBounds(usermonitor.drawviewer,dof,bounds);CHKERRQ(ierr); } usermonitor.interval = 1; ierr = PetscOptionsGetInt(NULL,"-monitor_interval",&usermonitor.interval,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Extract global vectors from DA; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCreateGlobalVector(da,&T);CHKERRQ(ierr); ierr = VecDuplicate(T,&rhs);CHKERRQ(ierr); /* r: vector to put the computed right hand side */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetType(ts,TSBEULER);CHKERRQ(ierr); ierr = TSSetRHSFunction(ts,rhs,RhsFunc,&user);CHKERRQ(ierr); /* Set Jacobian evaluation routine - use coloring to compute finite difference Jacobian efficiently */ ierr = DMSetMatType(da,MATAIJ);CHKERRQ(ierr); ierr = DMCreateMatrix(da,&J);CHKERRQ(ierr); ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); if (use_coloring) { ISColoring iscoloring; ierr = DMCreateColoring(da,IS_COLORING_GLOBAL,&iscoloring);CHKERRQ(ierr); ierr = MatFDColoringCreate(J,iscoloring,&matfdcoloring);CHKERRQ(ierr); ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); ierr = MatFDColoringSetUp(J,iscoloring,matfdcoloring);CHKERRQ(ierr); ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))SNESTSFormFunction,ts);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,J,J,SNESComputeJacobianDefaultColor,matfdcoloring);CHKERRQ(ierr); } else { ierr = SNESSetJacobian(snes,J,J,SNESComputeJacobianDefault,NULL);CHKERRQ(ierr); } /* Define what to print for ts_monitor option */ ierr = PetscOptionsHasName(NULL,"-monitor_off",&monitor_off);CHKERRQ(ierr); if (!monitor_off) { ierr = TSMonitorSet(ts,Monitor,&usermonitor,NULL);CHKERRQ(ierr); } ierr = FormInitialSolution(da,T,&user);CHKERRQ(ierr); dt = TIMESTEP; /* initial time step */ ftime = TIMESTEP*time; if (!rank) printf("time %d, ftime %g hour, TIMESTEP %g\n",time,ftime/3600,dt); ierr = TSSetInitialTimeStep(ts,0.0,dt);CHKERRQ(ierr); ierr = TSSetDuration(ts,time,ftime);CHKERRQ(ierr); ierr = TSSetSolution(ts,T);CHKERRQ(ierr); ierr = TSSetDM(ts,da);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,T);CHKERRQ(ierr); ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr); if (!rank) PetscPrintf(PETSC_COMM_WORLD,"Solution T after %g hours %d steps\n",ftime/3600,steps); if (matfdcoloring) {ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);} if (usermonitor.drawcontours) { ierr = PetscViewerDestroy(&usermonitor.drawviewer);CHKERRQ(ierr); } ierr = MatDestroy(&J);CHKERRQ(ierr); ierr = VecDestroy(&T);CHKERRQ(ierr); ierr = VecDestroy(&rhs);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); PetscFinalize(); return 0; }
// [[Rcpp::export]] Rcpp::List EMx(const arma::mat& transition_, const arma::cube& emission_, const arma::vec& init_, const arma::ucube& obs, const arma::uvec& nSymbols, const arma::mat& coef_, const arma::mat& X, const arma::uvec& numberOfStates, int itermax, double tol, int trace, unsigned int threads) { // Make sure we don't alter the original vec/mat/cube // needed for cube, in future maybe in other cases as well arma::cube emission(emission_); arma::mat transition(transition_); arma::vec init(init_); arma::mat coef(coef_); coef.col(0).zeros(); arma::mat weights = exp(X * coef).t(); if (!weights.is_finite()) { return Rcpp::List::create(Rcpp::Named("error") = 3); } weights.each_row() /= sum(weights, 0); arma::mat initk(emission.n_rows, obs.n_slices); for (unsigned int k = 0; k < obs.n_slices; k++) { initk.col(k) = init % reparma(weights.col(k), numberOfStates); } // // //EM-algorithm begins // double change = tol + 1.0; int iter = 0; arma::uvec cumsumstate = arma::cumsum(numberOfStates); double sumlogLik_new = 0; double sumlogLik = -1e150; while ((change > tol) & (iter < itermax)) { iter++; arma::mat ksii(emission.n_rows, emission.n_rows, arma::fill::zeros); arma::cube gamma(emission.n_rows, emission.n_cols, emission.n_slices, arma::fill::zeros); arma::vec delta(emission.n_rows, arma::fill::zeros); arma::mat bsi(emission.n_rows, obs.n_slices); sumlogLik_new = 0; double max_sf = 1; unsigned int error_code = 0; #pragma omp parallel for if(obs.n_slices >= threads) schedule(static) reduction(+:sumlogLik_new) num_threads(threads) \ default(shared) //shared(bsi, initk, transition, obs, emission, delta, ksii, gamma, nSymbols, error_code, max_sf, arma::fill::zeros) for (unsigned int k = 0; k < obs.n_slices; k++) { if (error_code == 0) { arma::mat alpha(emission.n_rows, obs.n_cols); //m,n,k arma::vec scales(obs.n_cols); arma::sp_mat sp_trans(transition); uvForward(sp_trans.t(), emission, initk.col(k), obs.slice(k), alpha, scales); arma::mat beta(emission.n_rows, obs.n_cols); //m,n,k uvBackward(sp_trans, emission, obs.slice(k), beta, scales); sumlogLik_new -= arma::sum(log(scales)); arma::mat ksii_k(emission.n_rows, emission.n_rows, arma::fill::zeros); arma::cube gamma_k(emission.n_rows, emission.n_cols, emission.n_slices, arma::fill::zeros); arma::vec delta_k(emission.n_rows); delta_k = alpha.col(0) % beta.col(0) / scales(0); for (unsigned int i = 0; i < emission.n_rows; i++) { for (unsigned int j = 0; j < emission.n_rows; j++) { if (transition(i, j) > 0.0) { for (unsigned int t = 0; t < (obs.n_cols - 1); t++) { double tmp = alpha(i, t) * transition(i, j) * beta(j, t + 1); for (unsigned int r = 0; r < obs.n_rows; r++) { tmp *= emission(j, obs(r, t + 1, k), r); } ksii_k(i, j) += tmp; } } } } for (unsigned int r = 0; r < emission.n_slices; r++) { for (unsigned int l = 0; l < nSymbols(r); l++) { for (unsigned int i = 0; i < emission.n_rows; i++) { if (emission(i, l, r) > 0.0) { for (unsigned int t = 0; t < obs.n_cols; t++) { if (l == (obs(r, t, k))) { double tmp = alpha(i, t) * beta(i, t) / scales(t); gamma_k(i, l, r) += tmp; } } } } } } for (unsigned int j = 0; j < emission.n_rows; j++) { bsi(j, k) = beta(j, 0) * initk(j, k); } #pragma omp critical { if(!scales.is_finite()) { error_code = 1; } if(!beta.is_finite()) { error_code = 2; } max_sf = std::min(max_sf, scales.max()); delta += delta_k; ksii += ksii_k; gamma += gamma_k; } } } if(error_code == 1) { return Rcpp::List::create(Rcpp::Named("error") = 1); } if(error_code == 2) { return Rcpp::List::create(Rcpp::Named("error") = 2); } if (max_sf > 1e150) { Rcpp::warning("Largest scaling factor was %e, results can be numerically unstable.", max_sf); } change = (sumlogLik_new - sumlogLik) / (std::abs(sumlogLik) + 0.1); sumlogLik = sumlogLik_new; if (trace > 0) { if(iter == 0) { Rcpp::Rcout << "Log-likelihood of initial model: " << sumlogLik << std::endl; } else { if (trace > 1) { Rcpp::Rcout << "iter: " << iter; Rcpp::Rcout << " logLik: " << sumlogLik; Rcpp::Rcout << " relative change: " << change << std::endl; } } } if (change > tol) { unsigned int error = optCoef(weights, obs, emission, bsi, coef, X, cumsumstate, numberOfStates, trace); if (error != 0) { return Rcpp::List::create(Rcpp::Named("error") = error); } if (obs.n_cols > 1) { ksii.each_col() /= sum(ksii, 1); transition = ksii; } for (unsigned int r = 0; r < emission.n_slices; r++) { gamma.slice(r).cols(0, nSymbols(r) - 1).each_col() /= sum( gamma.slice(r).cols(0, nSymbols(r) - 1), 1); emission.slice(r).cols(0, nSymbols(r) - 1) = gamma.slice(r).cols(0, nSymbols(r) - 1); } for (unsigned int i = 0; i < numberOfStates.n_elem; i++) { delta.subvec(cumsumstate(i) - numberOfStates(i), cumsumstate(i) - 1) /= arma::as_scalar( arma::accu(delta.subvec(cumsumstate(i) - numberOfStates(i), cumsumstate(i) - 1))); } init = delta; for (unsigned int k = 0; k < obs.n_slices; k++) { initk.col(k) = init % reparma(weights.col(k), numberOfStates); } } } if (trace > 0) { if (iter == itermax) { Rcpp::Rcout << "EM algorithm stopped after reaching the maximum number of " << iter << " iterations." << std::endl; } else { Rcpp::Rcout << "EM algorithm stopped after reaching the relative change of " << change; Rcpp::Rcout << " after " << iter << " iterations." << std::endl; } Rcpp::Rcout << "Final log-likelihood: " << sumlogLik << std::endl; } return Rcpp::List::create(Rcpp::Named("coefficients") = Rcpp::wrap(coef), Rcpp::Named("initialProbs") = Rcpp::wrap(init), Rcpp::Named("transitionMatrix") = Rcpp::wrap(transition), Rcpp::Named("emissionArray") = Rcpp::wrap(emission), Rcpp::Named("logLik") = sumlogLik, Rcpp::Named("iterations") = iter, Rcpp::Named("change") = change, Rcpp::Named("error") = 0); }
Tcolor TrayTracer::radiancePathTracer(Tray ray, int reflectLevel) { if(reflectLevel <=0) return Tcolor(0,0,0); auto result = scene()->intersect(ray); if (result.geometry()) { auto material = result.geometry ()->material (); auto emissionColor = material->sampleSelfColor () * material->emission (); auto reflectColor = Tcolor(0,0,0); switch(material->getType ()) { case Tmaterial::MaterialType::Mirror://ideal specular object. { auto reflectVec = reflect(ray.direction (),result.normal ()); auto reflectRay = Tray(result.pos (),reflectVec); auto idealSpecularRadiance = radiancePathTracer(reflectRay,reflectLevel - 1); reflectColor +=idealSpecularRadiance * material->BRDF (-ray.direction (),reflectVec,result.normal ()); } break; case Tmaterial::MaterialType::Light://ideal emission object. { reflectColor = Tcolor(0,0,0); } break; case Tmaterial::MaterialType::BlinnPhong: { } break; case Tmaterial::MaterialType::Diffuse: { Tvector nl; if(Tvector::dotProduct (result.normal (),ray.direction ())<0) { nl = result.normal (); }else { nl = result.normal ().negatived(); } double r1=2*TbaseMath::PI*TbaseMath::randF (); double r2=TbaseMath::randF (); double r2s=sqrt(r2); Tvector w=nl; Tvector u; if(fabs(w.x())>0.1) { u = Tvector(0,1,0); }else { u = Tvector(1,0,0); } u = Tvector::crossProduct (u,w); u.normalize (); Tvector v=Tvector::crossProduct (w,u); Tvector dir = (u*cos(r1)*r2s + v*sin(r1)*r2s + w*sqrt(1-r2)).normalized(); reflectColor = radiancePathTracer(Tray(result.pos (),dir),reflectLevel - 1); } break; } return emissionColor + material->selfColor () * reflectColor * material->reflectiveness (); } return Tcolor(0,0,0); }
void Emitter :: next_step() { movement(); emission(); }
List EM(const arma::mat& transition_, const arma::cube& emission_, const arma::vec& init_, const arma::ucube& obs, const arma::uvec& nSymbols, int itermax, double tol, int trace, unsigned int threads) { // Make sure we don't alter the original vec/mat/cube // needed for cube, in future maybe in other cases as well arma::cube emission(emission_); arma::mat transition(transition_); arma::vec init(init_); // EM-algorithm begins double change = tol + 1.0; int iter = -1; //for backward compatibility double sumlogLik_new = 0; double sumlogLik = -1e150; //sum(ll); while ((change > tol) & (iter < itermax)) { iter++; arma::mat ksii(emission.n_rows, emission.n_rows, arma::fill::zeros); arma::cube gamma(emission.n_rows, emission.n_cols, emission.n_slices, arma::fill::zeros); arma::vec delta(emission.n_rows, arma::fill::zeros); sumlogLik_new = 0; double max_sf = 1; unsigned int error_code = 0; #pragma omp parallel for if(obs.n_slices>=threads) schedule(static) reduction(+:sumlogLik_new) num_threads(threads) \ default(none) shared(init, transition, obs, emission, delta, ksii, gamma, nSymbols, error_code, max_sf) for (unsigned int k = 0; k < obs.n_slices; k++) { arma::mat alpha(emission.n_rows, obs.n_cols); //m,n,k arma::vec scales(obs.n_cols); arma::sp_mat sp_trans(transition); uvForward(sp_trans.t(), emission, init, obs.slice(k), alpha, scales); arma::mat beta(emission.n_rows, obs.n_cols); //m,n,k uvBackward(sp_trans, emission, obs.slice(k), beta, scales); sumlogLik_new -= arma::sum(log(scales)); arma::mat ksii_k(emission.n_rows, emission.n_rows, arma::fill::zeros); arma::cube gamma_k(emission.n_rows, emission.n_cols, emission.n_slices, arma::fill::zeros); arma::vec delta_k(emission.n_rows); delta_k = alpha.col(0) % beta.col(0); if (obs.n_cols > 1) { for (unsigned int j = 0; j < emission.n_rows; j++) { for (unsigned int i = 0; i < emission.n_rows; i++) { if (transition(i, j) > 0.0) { for (unsigned int t = 0; t < (obs.n_cols - 1); t++) { double tmp = alpha(i, t) * transition(i, j) * beta(j, t + 1) * scales(t + 1); for (unsigned int r = 0; r < obs.n_rows; r++) { tmp *= emission(j, obs(r, t + 1, k), r); } ksii_k(i, j) += tmp; } } } } } for (unsigned int r = 0; r < emission.n_slices; r++) { for (unsigned int l = 0; l < nSymbols(r); l++) { for (unsigned int i = 0; i < emission.n_rows; i++) { if (emission(i, l, r) > 0.0) { for (unsigned int t = 0; t < obs.n_cols; t++) { if (l == (obs(r, t, k))) { gamma_k(i, l, r) += alpha(i, t) * beta(i, t); } } } } } } #pragma omp critical { if(!scales.is_finite()) { error_code = 1; } if(!beta.is_finite()) { error_code = 2; } max_sf = std::min(max_sf, scales.max()); delta += delta_k; ksii += ksii_k; gamma += gamma_k; } } if(error_code == 1) { return List::create(Named("error") = 1); } if(error_code == 2) { return List::create(Named("error") = 2); } if (max_sf > 1e150) { Rcpp::warning("Largest scaling factor was %e, results can be numerically unstable.", max_sf); } change = (sumlogLik_new - sumlogLik) / (std::abs(sumlogLik) + 0.1); sumlogLik = sumlogLik_new; if (trace > 0) { if(iter == 1) { Rcout << "Log-likelihood of initial model: " << sumlogLik << std::endl; } else { if (trace > 1) { Rcout << "iter: " << iter; Rcout << " logLik: " << sumlogLik; Rcout << " relative change: " << change << std::endl; } } } if (change > tol) { if (obs.n_cols > 1) { ksii.each_col() /= sum(ksii, 1); transition = ksii; } for (unsigned int r = 0; r < emission.n_slices; r++) { gamma.slice(r).cols(0, nSymbols(r) - 1).each_col() /= sum( gamma.slice(r).cols(0, nSymbols(r) - 1), 1); emission.slice(r).cols(0, nSymbols(r) - 1) = gamma.slice(r).cols(0, nSymbols(r) - 1); } delta /= arma::as_scalar(arma::accu(delta)); init = delta; } // internalForward(transition, emission, init, obs, alpha, scales, threads); // if(!scales.is_finite()) { // return List::create(Named("error") = 1); // } // internalBackward(transition, emission, obs, beta, scales, threads); // if(!beta.is_finite()) { // return List::create(Named("error") = 2); // } // double min_sf = scales.min(); // if (min_sf < 1e-150) { // Rcpp::warning("Smallest scaling factor was %e, results can be numerically unstable.", min_sf); // } // // ll = sum(log(scales)); //double tmp = sum(ll); } if (trace > 0) { if (iter == itermax) { Rcpp::Rcout << "EM algorithm stopped after reaching the maximum number of " << iter << " iterations." << std::endl; } else { Rcpp::Rcout << "EM algorithm stopped after reaching the relative change of " << change; Rcpp::Rcout << " after " << iter << " iterations." << std::endl; } Rcpp::Rcout << "Final log-likelihood: " << sumlogLik << std::endl; } return List::create(Named("initialProbs") = wrap(init), Named("transitionMatrix") = wrap(transition), Named("emissionArray") = wrap(emission), Named("logLik") = sumlogLik, Named("iterations") = iter, Named("change") = change, Named("error") = 0); }
List EM(NumericVector transitionMatrix, NumericVector emissionArray, NumericVector initialProbs, IntegerVector obsArray, const arma::ivec& nSymbols, int itermax, double tol, int trace, int threads) { IntegerVector eDims = emissionArray.attr("dim"); //m,p,r IntegerVector oDims = obsArray.attr("dim"); //k,n,r arma::cube emission(emissionArray.begin(), eDims[0], eDims[1], eDims[2], true); arma::icube obs(obsArray.begin(), oDims[0], oDims[1], oDims[2], false, true); arma::vec init(initialProbs.begin(), emission.n_rows, true); arma::mat transition(transitionMatrix.begin(), emission.n_rows, emission.n_rows, true); arma::cube alpha(emission.n_rows, obs.n_cols, obs.n_slices); //m,n,k arma::cube beta(emission.n_rows, obs.n_cols, obs.n_slices); //m,n,k arma::mat scales(obs.n_cols, obs.n_slices); internalForward(transition, emission, init, obs, alpha, scales, threads); if(!scales.is_finite()) { return List::create(Named("error") = 1); } double min_sf = scales.min(); if (min_sf < 1e-150) { Rcpp::warning("Smallest scaling factor was %e, results can be numerically unstable.", min_sf); } internalBackward(transition, emission, obs, beta, scales, threads); if(!beta.is_finite()) { return List::create(Named("error") = 2); } arma::rowvec ll = arma::sum(log(scales)); double sumlogLik = sum(ll); if (trace > 0) { Rcout << "Log-likelihood of initial model: " << sumlogLik << std::endl; } // // //EM-algorithm begins // double change = tol + 1.0; int iter = 0; while ((change > tol) & (iter < itermax)) { iter++; arma::mat ksii(emission.n_rows, emission.n_rows, arma::fill::zeros); arma::cube gamma(emission.n_rows, emission.n_cols, emission.n_slices, arma::fill::zeros); arma::vec delta(emission.n_rows, arma::fill::zeros); for (unsigned int k = 0; k < obs.n_slices; k++) { delta += alpha.slice(k).col(0) % beta.slice(k).col(0); } #pragma omp parallel for if(obs.n_slices>=threads) schedule(static) num_threads(threads) \ default(none) shared(transition, obs, alpha, beta, scales, \ emission, ksii, gamma, nSymbols) for (int k = 0; k < obs.n_slices; k++) { if (obs.n_cols > 1) { for (unsigned int j = 0; j < emission.n_rows; j++) { for (unsigned int i = 0; i < emission.n_rows; i++) { if (transition(i, j) > 0.0) { for (unsigned int t = 0; t < (obs.n_cols - 1); t++) { double tmp = alpha(i, t, k) * transition(i, j) * beta(j, t + 1, k) / scales(t + 1, k); for (unsigned int r = 0; r < obs.n_rows; r++) { tmp *= emission(j, obs(r, t + 1, k), r); } #pragma omp atomic ksii(i, j) += tmp; } } } } } for (unsigned int r = 0; r < emission.n_slices; r++) { for (int l = 0; l < nSymbols(r); l++) { for (unsigned int i = 0; i < emission.n_rows; i++) { if (emission(i, l, r) > 0.0) { for (unsigned int t = 0; t < obs.n_cols; t++) { if (l == (obs(r, t, k))) { #pragma omp atomic gamma(i, l, r) += alpha(i, t, k) * beta(i, t, k); } } } } } } } if (obs.n_cols > 1) { ksii.each_col() /= sum(ksii, 1); transition = ksii; } for (unsigned int r = 0; r < emission.n_slices; r++) { gamma.slice(r).cols(0, nSymbols(r) - 1).each_col() /= sum( gamma.slice(r).cols(0, nSymbols(r) - 1), 1); emission.slice(r).cols(0, nSymbols(r) - 1) = gamma.slice(r).cols(0, nSymbols(r) - 1); } delta /= arma::as_scalar(arma::accu(delta)); init = delta; internalForward(transition, emission, init, obs, alpha, scales, threads); if(!scales.is_finite()) { return List::create(Named("error") = 1); } internalBackward(transition, emission, obs, beta, scales, threads); if(!beta.is_finite()) { return List::create(Named("error") = 2); } double min_sf = scales.min(); if (min_sf < 1e-150) { Rcpp::warning("Smallest scaling factor was %e, results can be numerically unstable.", min_sf); } ll = sum(log(scales)); double tmp = sum(ll); change = (tmp - sumlogLik) / (std::abs(sumlogLik) + 0.1); sumlogLik = tmp; if (trace > 1) { Rcout << "iter: " << iter; Rcout << " logLik: " << sumlogLik; Rcout << " relative change: " << change << std::endl; } } if (trace > 0) { if (iter == itermax) { Rcpp::Rcout << "EM algorithm stopped after reaching the maximum number of " << iter << " iterations." << std::endl; } else { Rcpp::Rcout << "EM algorithm stopped after reaching the relative change of " << change; Rcpp::Rcout << " after " << iter << " iterations." << std::endl; } Rcpp::Rcout << "Final log-likelihood: " << sumlogLik << std::endl; } return List::create(Named("initialProbs") = wrap(init), Named("transitionMatrix") = wrap(transition), Named("emissionArray") = wrap(emission), Named("logLik") = sumlogLik, Named("iterations") = iter, Named("change") = change, Named("error") = 0); }
void PhotonTracer::tracePhoton(SurfacePhotonRange &surfaceRange, VolumePhotonRange &volumeRange, PathSampleGenerator &sampler) { float lightPdf; const Primitive *light = chooseLightAdjoint(sampler, lightPdf); PositionSample point; if (!light->samplePosition(sampler, point)) return; DirectionSample direction; if (!light->sampleDirection(sampler, point, direction)) return; sampler.advancePath(); Ray ray(point.p, direction.d); Vec3f throughput(point.weight*direction.weight/lightPdf); SurfaceScatterEvent event; IntersectionTemporary data; IntersectionInfo info; Medium::MediumState state; state.reset(); Vec3f emission(0.0f); const Medium *medium = nullptr; // TODO: Media int bounce = 0; bool wasSpecular = true; bool hitSurface = true; bool didHit = _scene->intersect(ray, data, info); while ((didHit || medium) && bounce < _settings.maxBounces - 1) { if (medium) { MediumSample mediumSample; if (!medium->sampleDistance(sampler, ray, state, mediumSample)) break; throughput *= mediumSample.weight; hitSurface = mediumSample.exited; if (!hitSurface) { if (!volumeRange.full()) { VolumePhoton &p = volumeRange.addPhoton(); p.pos = mediumSample.p; p.dir = ray.dir(); p.power = throughput; } PhaseSample phaseSample; if (!mediumSample.phase->sample(sampler, ray.dir(), phaseSample)) break; ray = ray.scatter(mediumSample.p, phaseSample.w, 0.0f); ray.setPrimaryRay(false); throughput *= phaseSample.weight; } } if (hitSurface) { if (!info.bsdf->lobes().isPureSpecular() && !surfaceRange.full()) { Photon &p = surfaceRange.addPhoton(); p.pos = info.p; p.dir = ray.dir(); p.power = throughput*std::abs(info.Ns.dot(ray.dir())/info.Ng.dot(ray.dir())); } } if (volumeRange.full() && surfaceRange.full()) break; if (hitSurface) { event = makeLocalScatterEvent(data, info, ray, &sampler); if (!handleSurface(event, data, info, medium, bounce, true, false, ray, throughput, emission, wasSpecular, state)) break; } if (throughput.max() == 0.0f) break; if (std::isnan(ray.dir().sum() + ray.pos().sum())) break; if (std::isnan(throughput.sum())) break; sampler.advancePath(); bounce++; if (bounce < _settings.maxBounces) didHit = _scene->intersect(ray, data, info); } }
List objectivex(const arma::mat& transition, NumericVector emissionArray, const arma::vec& init, IntegerVector obsArray, const arma::imat& ANZ, IntegerVector emissNZ, const arma::ivec& INZ, const arma::ivec& nSymbols, const arma::mat& coef, const arma::mat& X, arma::ivec& numberOfStates, int threads) { IntegerVector eDims = emissionArray.attr("dim"); //m,p,r IntegerVector oDims = obsArray.attr("dim"); //k,n,r arma::cube emission(emissionArray.begin(), eDims[0], eDims[1], eDims[2], false, true); arma::icube obs(obsArray.begin(), oDims[0], oDims[1], oDims[2], false, true); arma::icube BNZ(emissNZ.begin(), emission.n_rows, emission.n_cols - 1, emission.n_slices, false, true); unsigned int q = coef.n_rows; arma::vec grad( arma::accu(ANZ) + arma::accu(BNZ) + arma::accu(INZ) + (numberOfStates.n_elem- 1) * q, arma::fill::zeros); arma::mat weights = exp(X * coef).t(); if (!weights.is_finite()) { grad.fill(-arma::math::inf()); return List::create(Named("objective") = arma::math::inf(), Named("gradient") = wrap(grad)); } weights.each_row() /= sum(weights, 0); arma::mat initk(emission.n_rows, obs.n_slices); for (unsigned int k = 0; k < obs.n_slices; k++) { initk.col(k) = init % reparma(weights.col(k), numberOfStates); } arma::cube alpha(emission.n_rows, obs.n_cols, obs.n_slices); //m,n,k arma::cube beta(emission.n_rows, obs.n_cols, obs.n_slices); //m,n,k arma::mat scales(obs.n_cols, obs.n_slices); //m,n,k arma::sp_mat sp_trans(transition); internalForwardx(sp_trans.t(), emission, initk, obs, alpha, scales, threads); if (!scales.is_finite()) { grad.fill(-arma::math::inf()); return List::create(Named("objective") = arma::math::inf(), Named("gradient") = wrap(grad)); } internalBackwardx(sp_trans, emission, obs, beta, scales, threads); if (!beta.is_finite()) { grad.fill(-arma::math::inf()); return List::create(Named("objective") = arma::math::inf(), Named("gradient") = wrap(grad)); } arma::ivec cumsumstate = arma::cumsum(numberOfStates); arma::mat gradmat( arma::accu(ANZ) + arma::accu(BNZ) + arma::accu(INZ) + (numberOfStates.n_elem- 1) * q, obs.n_slices, arma::fill::zeros); #pragma omp parallel for if(obs.n_slices >= threads) schedule(static) num_threads(threads) \ default(none) shared(q, alpha, beta, scales, gradmat, nSymbols, ANZ, BNZ, INZ, \ numberOfStates, cumsumstate, obs, init, initk, X, weights, transition, emission) for (int k = 0; k < obs.n_slices; k++) { int countgrad = 0; // transitionMatrix if (arma::accu(ANZ) > 0) { for (int jj = 0; jj < numberOfStates.n_elem; jj++) { arma::vec gradArow(numberOfStates(jj)); arma::mat gradA(numberOfStates(jj), numberOfStates(jj)); int ind_jj = cumsumstate(jj) - numberOfStates(jj); for (int i = 0; i < numberOfStates(jj); i++) { arma::uvec ind = arma::find(ANZ.row(ind_jj + i).subvec(ind_jj, cumsumstate(jj) - 1)); if (ind.n_elem > 0) { gradArow.zeros(); gradA.eye(); gradA.each_row() -= transition.row(ind_jj + i).subvec(ind_jj, cumsumstate(jj) - 1); gradA.each_col() %= transition.row(ind_jj + i).subvec(ind_jj, cumsumstate(jj) - 1).t(); for (int j = 0; j < numberOfStates(jj); j++) { for (unsigned int t = 0; t < (obs.n_cols - 1); t++) { double tmp = alpha(ind_jj + i, t, k); for (unsigned int r = 0; r < obs.n_rows; r++) { tmp *= emission(ind_jj + j, obs(r, t + 1, k), r); } gradArow(j) += tmp * beta(ind_jj + j, t + 1, k) / scales(t + 1, k); } } gradArow = gradA * gradArow; gradmat.col(k).subvec(countgrad, countgrad + ind.n_elem - 1) = gradArow.rows(ind); countgrad += ind.n_elem; } } } } if (arma::accu(BNZ) > 0) { // emissionMatrix for (unsigned int r = 0; r < obs.n_rows; r++) { arma::vec gradBrow(nSymbols(r)); arma::mat gradB(nSymbols(r), nSymbols(r)); for (unsigned int i = 0; i < emission.n_rows; i++) { arma::uvec ind = arma::find(BNZ.slice(r).row(i)); if (ind.n_elem > 0) { gradBrow.zeros(); gradB.eye(); gradB.each_row() -= emission.slice(r).row(i).subvec(0, nSymbols(r) - 1); gradB.each_col() %= emission.slice(r).row(i).subvec(0, nSymbols(r) - 1).t(); for (int j = 0; j < nSymbols(r); j++) { if (obs(r, 0, k) == j) { double tmp = initk(i, k); for (unsigned int r2 = 0; r2 < obs.n_rows; r2++) { if (r2 != r) { tmp *= emission(i, obs(r2, 0, k), r2); } } gradBrow(j) += tmp * beta(i, 0, k) / scales(0, k); } for (unsigned int t = 0; t < (obs.n_cols - 1); t++) { if (obs(r, t + 1, k) == j) { double tmp = beta(i, t + 1, k) / scales(t + 1, k); for (unsigned int r2 = 0; r2 < obs.n_rows; r2++) { if (r2 != r) { tmp *= emission(i, obs(r2, t + 1, k), r2); } } gradBrow(j) += arma::dot(alpha.slice(k).col(t), transition.col(i)) * tmp; } } } gradBrow = gradB * gradBrow; gradmat.col(k).subvec(countgrad, countgrad + ind.n_elem - 1) = gradBrow.rows(ind); countgrad += ind.n_elem; } } } } if (arma::accu(INZ) > 0) { for (int i = 0; i < numberOfStates.n_elem; i++) { int ind_i = cumsumstate(i) - numberOfStates(i); arma::uvec ind = arma::find( INZ.subvec(ind_i, cumsumstate(i) - 1)); if (ind.n_elem > 0) { arma::vec gradIrow(numberOfStates(i), arma::fill::zeros); for (int j = 0; j < numberOfStates(i); j++) { double tmp = weights(i, k); for (unsigned int r = 0; r < obs.n_rows; r++) { tmp *= emission(ind_i + j, obs(r, 0, k), r); } gradIrow(j) += tmp * beta(ind_i + j, 0, k) / scales(0, k); } arma::mat gradI(numberOfStates(i), numberOfStates(i), arma::fill::zeros); gradI.eye(); gradI.each_row() -= init.subvec(ind_i, cumsumstate(i) - 1).t(); gradI.each_col() %= init.subvec(ind_i, cumsumstate(i) - 1); gradIrow = gradI * gradIrow; gradmat.col(k).subvec(countgrad, countgrad + ind.n_elem - 1) = gradIrow.rows(ind); countgrad += ind.n_elem; } } } for (int jj = 1; jj < numberOfStates.n_elem; jj++) { int ind_jj = (cumsumstate(jj) - numberOfStates(jj)); for (int j = 0; j < emission.n_rows; j++) { double tmp = 1.0; for (unsigned int r = 0; r < obs.n_rows; r++) { tmp *= emission(j, obs(r, 0, k), r); } if ((j >= ind_jj) & (j < cumsumstate(jj))) { gradmat.col(k).subvec(countgrad + q * (jj - 1), countgrad + q * jj - 1) += tmp * beta(j, 0, k) / scales(0, k) * initk(j, k) * X.row(k).t() * (1.0 - weights(jj, k)); } else { gradmat.col(k).subvec(countgrad + q * (jj - 1), countgrad + q * jj - 1) -= tmp * beta(j, 0, k) / scales(0, k) * initk(j, k) * X.row(k).t() * weights(jj, k); } } } } return List::create(Named("objective") = -arma::accu(log(scales)), Named("gradient") = wrap(-sum(gradmat, 1))); }
List objective(const arma::mat& transition, NumericVector emissionArray, const arma::vec& init, IntegerVector obsArray, const arma::imat& ANZ, IntegerVector emissNZ, const arma::ivec& INZ, const arma::ivec& nSymbols, int threads) { IntegerVector eDims = emissionArray.attr("dim"); //m,p,r IntegerVector oDims = obsArray.attr("dim"); //k,n,r arma::cube emission(emissionArray.begin(), eDims[0], eDims[1], eDims[2], false, true); arma::icube obs(obsArray.begin(), oDims[0], oDims[1], oDims[2], false, true); arma::icube BNZ(emissNZ.begin(), emission.n_rows, emission.n_cols - 1, emission.n_slices, false, true); arma::vec grad(arma::accu(ANZ) + arma::accu(BNZ) + arma::accu(INZ), arma::fill::zeros); // arma::cube alpha(emission.n_rows, obs.n_cols, obs.n_slices); //m,n,k // arma::cube beta(emission.n_rows, obs.n_cols, obs.n_slices); //m,n,k // arma::mat scales(obs.n_cols, obs.n_slices); //m,n,k // // internalForward(transition, emission, init, obs, alpha, scales, threads); // if (!scales.is_finite()) { // grad.fill(-arma::math::inf()); // return List::create(Named("objective") = arma::math::inf(), Named("gradient") = wrap(grad)); // } // // internalBackward(transition, emission, obs, beta, scales, threads); // if (!beta.is_finite()) { // grad.fill(-arma::math::inf()); // return List::create(Named("objective") = arma::math::inf(), Named("gradient") = wrap(grad)); // } //use this instead of local vectors with grad += grad_k;, uses more memory but gives bit-identical results //arma::mat gradmat(arma::accu(ANZ) + arma::accu(BNZ) + arma::accu(INZ), obs.n_slices); unsigned int error = 0; double ll = 0; #pragma omp parallel for if(obs.n_slices >= threads) schedule(static) reduction(+:ll) num_threads(threads) \ default(none) shared(grad, nSymbols, ANZ, BNZ, INZ, obs, init, transition, emission, error) for (int k = 0; k < obs.n_slices; k++) { if (error == 0) { arma::mat alpha(emission.n_rows, obs.n_cols); //m,n arma::vec scales(obs.n_cols); //n arma::sp_mat sp_trans(transition); uvForward(sp_trans.t(), emission, init, obs.slice(k), alpha, scales); arma::mat beta(emission.n_rows, obs.n_cols); //m,n uvBackward(sp_trans, emission, obs.slice(k), beta, scales); int countgrad = 0; arma::vec grad_k(grad.n_elem, arma::fill::zeros); // transitionMatrix arma::vec gradArow(emission.n_rows); arma::mat gradA(emission.n_rows, emission.n_rows); for (unsigned int i = 0; i < emission.n_rows; i++) { arma::uvec ind = arma::find(ANZ.row(i)); if (ind.n_elem > 0) { gradArow.zeros(); gradA.eye(); gradA.each_row() -= transition.row(i); gradA.each_col() %= transition.row(i).t(); for (unsigned int t = 0; t < (obs.n_cols - 1); t++) { for (unsigned int j = 0; j < emission.n_rows; j++) { double tmp = 1.0; for (unsigned int r = 0; r < obs.n_rows; r++) { tmp *= emission(j, obs(r, t + 1, k), r); } gradArow(j) += alpha(i, t) * tmp * beta(j, t + 1) / scales(t + 1); } } gradArow = gradA * gradArow; grad_k.subvec(countgrad, countgrad + ind.n_elem - 1) = gradArow.rows(ind); countgrad += ind.n_elem; } } // emissionMatrix for (unsigned int r = 0; r < obs.n_rows; r++) { arma::vec gradBrow(nSymbols(r)); arma::mat gradB(nSymbols(r), nSymbols(r)); for (unsigned int i = 0; i < emission.n_rows; i++) { arma::uvec ind = arma::find(BNZ.slice(r).row(i)); if (ind.n_elem > 0) { gradBrow.zeros(); gradB.eye(); gradB.each_row() -= emission.slice(r).row(i).subvec(0, nSymbols(r) - 1); gradB.each_col() %= emission.slice(r).row(i).subvec(0, nSymbols(r) - 1).t(); for (int j = 0; j < nSymbols(r); j++) { if (obs(r, 0, k) == j) { double tmp = 1.0; for (unsigned int r2 = 0; r2 < obs.n_rows; r2++) { if (r2 != r) { tmp *= emission(i, obs(r2, 0, k), r2); } } gradBrow(j) += init(i) * tmp * beta(i, 0) / scales(0); } for (unsigned int t = 0; t < (obs.n_cols - 1); t++) { if (obs(r, t + 1, k) == j) { double tmp = 1.0; for (unsigned int r2 = 0; r2 < obs.n_rows; r2++) { if (r2 != r) { tmp *= emission(i, obs(r2, t + 1, k), r2); } } gradBrow(j) += arma::dot(alpha.col(t), transition.col(i)) * tmp * beta(i, t + 1) / scales(t + 1); } } } gradBrow = gradB * gradBrow; grad_k.subvec(countgrad, countgrad + ind.n_elem - 1) = gradBrow.rows(ind); countgrad += ind.n_elem; } } } // InitProbs arma::uvec ind = arma::find(INZ); if (ind.n_elem > 0) { arma::vec gradIrow(emission.n_rows); arma::mat gradI(emission.n_rows, emission.n_rows); gradIrow.zeros(); gradI.zeros(); gradI.eye(); gradI.each_row() -= init.t(); gradI.each_col() %= init; for (unsigned int j = 0; j < emission.n_rows; j++) { double tmp = 1.0; for (unsigned int r = 0; r < obs.n_rows; r++) { tmp *= emission(j, obs(r, 0, k), r); } gradIrow(j) += tmp * beta(j, 0) / scales(0); } gradIrow = gradI * gradIrow; grad_k.subvec(countgrad, countgrad + ind.n_elem - 1) = gradIrow.rows(ind); countgrad += ind.n_elem; } if (!scales.is_finite() || !beta.is_finite()) { #pragma omp atomic error++; } else { ll += arma::sum(log(scales)); #pragma omp critical grad += grad_k; // gradmat.col(k) = grad_k; } // for (unsigned int ii = 0; ii < grad_k.n_elem; ii++) { // #pragma omp atomic // grad(ii) += grad_k(ii); // } } } if(error > 0){ ll = -arma::math::inf(); grad.fill(-arma::math::inf()); } // } else { // grad = sum(gradmat, 1); // } return List::create(Named("objective") = -ll, Named("gradient") = wrap(-grad)); }
/* virtual */ MStatus pnTriangles::bind(const MDrawRequest& request, M3dView& view) // // Description: // This bind demonstrates the usage of internal material // and texture properties. This shader must be connected // to the "hardwareShader" attribute of a lambert derived // shader. // { // Setup the view view.beginGL(); glPushAttrib( GL_ALL_ATTRIB_BITS ); glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); MColor diffuse(1.0F, 1.0F, 0.0F, 1.0F); MColor specular(1.0F, 1.0F, 1.0F, 1.0F); MColor emission(0.0F, 0.0F, 0.0F, 1.0F); MColor ambient(0.2F, 0.2F, 0.2F, 1.0F); // Get the diffuse and specular colors // float shininess; bool hasTransparency = false; MMaterial material = request.material(); fInTexturedMode = material.materialIsTextured(); // Setting this to true will get the default "green" material back // since it will try and evaluate this shader, which internally // Maya does not understand -> thus giving the "green" material back bool useInternalMaterialSetting = false; if (!useInternalMaterialSetting) { material.getEmission( emission ); material.getSpecular( specular ); shininess = 13.0; } material.getHasTransparency( hasTransparency ); if (!fInTexturedMode) { if (!fTestVertexProgram && !useInternalMaterialSetting) material.getDiffuse( diffuse ); } // In textured mode. Diffuse material is always white // for texture blends else { if (!useInternalMaterialSetting) diffuse.r = diffuse.g = diffuse.b = diffuse.a = 1.0; } // Use a vertex program to set up shading // if (fTestVertexProgram) { bindVertexProgram(diffuse, specular, emission, ambient); } else if (fTestFragmentProgram) { bindFragmentProgram(); } // Don't use a vertex program to set up shading // else { // Set up the material state // glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT); glColor4fv(&ambient.r); if (fInTexturedMode) { glEnable( GL_TEXTURE_2D ); MDrawData drawData = request.drawData(); material.applyTexture( view, drawData ); float scaleS, scaleT, translateS, translateT, rotate; material.getTextureTransformation(scaleS, scaleT, translateS, translateT, rotate); rotate = DEG_TO_RAD(-rotate); float c = cosf(rotate); float s = sinf(rotate); translateS += ((c+s)/2.0F); translateT += ((c-s)/2.0F); glMatrixMode(GL_TEXTURE); glPushMatrix(); glLoadIdentity(); if(scaleS != 1.0f || scaleT != 1.0f) glScalef(1.0f/scaleS, 1.0f/scaleT, 1.0f); if(translateS != 0.0f || translateT != 0.0f) glTranslatef(0.5f-translateS, 0.5f-translateT, 0.0f); else glTranslatef(0.5f, 0.5f, 0.0f); if(rotate != 0.0f) glRotatef(-rotate, 0.0f, 0.0f, 1.0f); glMatrixMode(GL_MODELVIEW); } if (!useInternalMaterialSetting) { glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); glColor4fv(&diffuse.r); glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR); glColor4fv(&specular.r); glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION); glColor4fv(&emission.r); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess); } else { const MDagPath dagPath = request.multiPath(); material.evaluateMaterial( view, dagPath ); material.setMaterial(dagPath, hasTransparency); } } // Do PN triangles in hardware, or do nothing // if LOD = 0 if (fExtensionSupported[kPNTriangesEXT] || (fSubdivisions == 0)) { if (fSubdivisions != 0) { glEnable( GL_PN_TRIANGLES_ATI ); // Set point mode // if (fPointMode == kPointLinear) glPNTrianglesiATI( GL_PN_TRIANGLES_POINT_MODE_ATI, GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI); else glPNTrianglesiATI( GL_PN_TRIANGLES_POINT_MODE_ATI, GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI); // Set normal mode // if (fNormalMode == kNormalLinear) glPNTrianglesiATI( GL_PN_TRIANGLES_NORMAL_MODE_ATI, GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI); else glPNTrianglesiATI( GL_PN_TRIANGLES_NORMAL_MODE_ATI, GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI); // Set tessellation level // glPNTrianglesiATI( GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI, fSubdivisions ); } } view.endGL(); return MS::kSuccess; }
cube emissionfromdatacube(cube datacube) { // construct the G(T) using CHIANTI tables int ng=datacube.readngrid(); int nvars=5; // G(T), width, vx, vy, vz // take the last 3 from datacube cube emission(nvars, ng); tgrid grid=datacube.readgrid(); emission.setgrid(grid); emission.settype(emisscube); // copy velocity vectors for (int i=2; i<nvars; i++) { tphysvar velcomp=datacube.readvar(i); emission.setvar(i,velcomp); }; tphysvar logrho = log10(datacube.readvar(0)); tphysvar T = datacube.readvar(1); tphysvar logT = log10(T); // writearray(logT,"empty"); string ion="";// better to be aia for AIA tables this will be checked for correct table [DY] double lambda0=.0; double atweight=1; cube gofttab=readgoftfromchianti(chiantifile,ion,lambda0,atweight); // fit the G(T) function to the data points tphysvar fittedgoft=goft(logT,logrho,gofttab); // calculate the line width at each data point tphysvar fittedwidth=linefwhm(T,lambda0,atweight); // calculate the maximum of the emission profile at each grid point // The emission in the CHIANTItables is calculated with the sun_coronal.abund file // There are 2 cases: // - we are doing spectroscopic calculations: the fittedemission should normalised with the alphaconst, and if a different abundance is used, we should renormalise to the new abundance // - we are doing intensity calculations (for e.g. AIA): the tables are already in the correct units, and the fittedemission needs to only be multiplied with 1. double normaliseconst=1.; double abundratio=1.; if (lambda_pixel>1) // for spectroscopic study { cout << "This code is configured to do spectroscopic modelling" << endl; // tphysvar fittedwidth=linefwhm(T,lambda0,atweight); normaliseconst=1./alphaconst; if (abundfile != string("/empty")) { ifstream abundfilestream (abundfile); cout << "Reading abundances from " << abundfile << "... " << flush; double abundnew=abundfromchianti(abundfilestream, ion); cout << "Done!" << endl << flush; istringstream standardabundfile (______chiantitables_sun_coronal_abund_string); double abundold=abundfromchianti(standardabundfile,ion); abundratio=abundnew/abundold; } } if (lambda_pixel==1) // for imaging study { if (atoi(ion.c_str())!=int(lambda0+0.5)) {// check if it is AIA GOFT table cout << "GOFT table is not correct!" << endl; exit(EXIT_FAILURE); } fittedwidth=T/T;// =1.0 } // Spectral modelling: ne^2 [cm^-3] * G(ne,Te) [erg cm^3 s^1] = emis [erg cm^-3 s^-1] // for integration *[cm] [D.Y 12 Nov 2014] // AIA modelling: Temperature response function K(ne,Te)[cm^5 DN S^-1]*ne[cm^-3]=emis [DN cm^-1 s^-1]; // for integration *[cm] [D.Y 12 Nov 20 // cout << "normaliseconst" <<normaliseconst << endl; // cout << "abundratio"<<abundratio<<endl; tphysvar fittedemission=normaliseconst*abundratio*pow(10.,2.*logrho)*fittedgoft; fittedemission=fittedemission/fittedwidth; // load the emission and width into the emission-cube variable emission.setvar(0,fittedemission); emission.setvar(1,fittedwidth); return emission; };
int main(int argc, char **argv) { int k, j, kmax; proxel *currproxel; double val, z, valhpm, vallpm; int s, tau1k, tau2k; /* initialise the simulation */ root[0] = NULL; root[1] = NULL; eerror = 0.0; totcnt = 0; maxccp = 0; double tmax = ENDTIME; dt = DELTA; e = EMISSION; if (e) { printf("Using Symbol Emission...\n\n"); } else { printf("No Symbol Emission...\n\n"); } kmax = (int)floor(tmax / dt + 0.5); TAUMAX = kmax; /* initialize the solution vector for each time step */ for (k = 0; k < 3; k++) { y[k] = malloc(sizeof(double) * (kmax + 2)); for (j = 0; j < kmax + 2; j++) y[k][j] = 0.0; } if (e) { for (k = 0; k < 3; k++) { /* rows */ em[k] = malloc(sizeof(double) * 2); for (j = 0; j < 2; j++) { /* cols */ em[k][j] = 0.0; } } em[HPM][WP] = 0.95; em[HPM][DP] = 0.05; em[LPM][WP] = 0.8; em[LPM][DP] = 0.2; printf("Emission Matrix:\nHPM->WP: %11.10f\nHPM->DP: %11.10f\nLPM->WP: %11.10f\nLPM->DP: %11.10f\n\n", em[HPM][WP], em[HPM][DP], em[LPM][WP], em[LPM][DP]); /* initialize the emission sum vector */ for (k = 0; k < 2; k++) { /* cols */ emsum[k] = malloc(sizeof(double) * (kmax + 2)); for (j = 0; j < kmax + 2; j++) { emsum[k][j] = 0.0; } } /* initialize the emission sequence */ emsequence = malloc(sizeof(int) * (kmax + 2)); for (k = 1; k < kmax + 2; ++k) { if (k % 2 == 0) { emsequence[k] = WP; } else { emsequence[k] = DP; } emsequence[k] = WP; } printemissionsequence(kmax); /* initialize the most likely paths */ for (k = 0; k < 5; k++) { empaths[k] = malloc(sizeof(int) * (kmax + 2)); for (j = 0; j < kmax + 2; j++) empaths[k][j] = 0; } } /* set initial proxel */ addproxel(HPM, 0, 0, 1.0); /* first loop: iteration over all time steps*/ /* current model time is k*dt */ for (k = 1; k < kmax + 2; k++) { /* print progress information if (k % 100 == 0) { printf("Step %d\n", k); printf("Size of tree %d\n", size(root[sw])); } */ sw = 1 - sw; /* second loop: iterating over all proxels of a time step */ while (root[1 - sw] != NULL) { totcnt++; currproxel = getproxel(); while ((currproxel->val < MINPROB) && (root[1 - sw] != NULL)) { val = currproxel->val; eerror += val; currproxel = getproxel(); } val = currproxel->val; tau1k = currproxel->tau1k; tau2k = currproxel->tau2k; s = currproxel->s; y[s][k - 1] += val; /* create child proxels */ switch (s) { case HPM: /* probability to overheat the machine */ z = dt * overheat(tau1k*dt); if (z < 1.0) { if (e) { vallpm = emission(k, s, LPM, val*z, emsequence[k]); valhpm = emission(k, s, HPM, val*(1 - z), emsequence[k]); } else { vallpm = val*z; valhpm = val*(1 - z); } addproxel(LPM, 0, 0, vallpm); addproxel(HPM, tau1k + 1, 0, valhpm); } else { if (e) { vallpm = emission(k, s, LPM, val, emsequence[k]); } else { vallpm = val; } addproxel(LPM, 0, 0, vallpm); } break; case LPM: /* probability to cooldown the machine */ z = dt * cooldown(tau1k*dt); if (z < 1.0) { if (e) { valhpm = emission(k, s, HPM, val*z, emsequence[k]); vallpm = emission(k, s, LPM, val*(1 - z), emsequence[k]); } else { valhpm = val*z; vallpm = val*(1 - z); } addproxel(HPM, 0, 0, valhpm); addproxel(LPM, tau1k + 1, 0, vallpm); } else { if (e) { valhpm = emission(k, s, HPM, val, emsequence[k]); } else { valhpm = val; } addproxel(HPM, 0, 0, valhpm); } break; default: printf("something went wrong!"); break; } } } /* printf("\n"); printtree(root[sw]); printf("\n"); */ plotsolution(kmax); printf("Tree Size = %d\n", size(root[sw])); printf("Proxels (Max Concurrent) = %d\n", maxccp); printf("Proxels (Total) = %d\n", totcnt); printf("Leafs (Total) = %i\n", countleafs(root[sw])); printf("Accumulated Error = %7.5le\n", eerror); printf("\n"); // last carriage return before exit return(0); }
bool PathVertex::sampleNextVertex(const TraceableScene &scene, TraceBase &tracer, TraceState &state, bool adjoint, PathVertex *prev, PathEdge *prevEdge, PathVertex &next, PathEdge &nextEdge) { Vec3f weight; float pdf; switch (_type) { case EmitterVertex: { EmitterRecord &record = _record.emitter; if (_sampler.emitter->isInfinite()) { weight = record.point.weight; pdf = record.point.pdf; } else { if (!_sampler.emitter->sampleDirection(state.sampler, record.point, record.direction)) return false; weight = record.direction.weight; pdf = record.direction.pdf; } state.ray = Ray(record.point.p, record.direction.d); break; } case CameraVertex: { CameraRecord &record = _record.camera; if (!_sampler.camera->sampleDirection(state.sampler, record.point, record.pixel, record.direction)) return false; weight = record.direction.weight; pdf = record.direction.pdf; state.ray = Ray(record.point.p, record.direction.d); state.ray.setPrimaryRay(true); break; } case SurfaceVertex: { SurfaceRecord &record = _record.surface; if (record.info.primitive->isInfinite()) return false; Vec3f scatterWeight(1.0f); Vec3f emission(0.0f); bool scattered = tracer.handleSurface(record.event, record.data, record.info, state.medium, state.bounce, adjoint, false, state.ray, scatterWeight, emission, state.wasSpecular, state.mediumState); if (!scattered) return false; if (record.event.sampledLobe.isForward()) prev->_pdfBackward = record.event.pdf; else prev->_pdfBackward = _sampler.bsdf->pdf(record.event.makeFlippedQuery()); _dirac = record.event.sampledLobe.isPureSpecular(); _forward = record.event.sampledLobe.isForward(); // Technically, we could connect to these kinds of vertices (e.g. BSDF with transparency), // but this creates so much headache for back-propagating the PDFs that we're just not // going to bother if (_forward) _connectable = false; weight = record.event.weight; pdf = record.event.pdf; break; } case MediumVertex: { MediumRecord &record = _record.medium; if (!record.mediumSample.phase->sample(state.sampler, state.ray.dir(), record.phaseSample)) return false; prev->_pdfBackward = record.mediumSample.phase->pdf(-record.phaseSample.w, -state.ray.dir()); state.ray = state.ray.scatter(record.mediumSample.p, record.phaseSample.w, 0.0f); state.ray.setPrimaryRay(false); weight = record.phaseSample.weight; pdf = record.phaseSample.pdf; break; } default: return false; } SurfaceRecord surfaceRecord; bool didHit = scene.intersect(state.ray, surfaceRecord.data, surfaceRecord.info); bool hitSurface; float edgePdfForward; float edgePdfBackward; MediumRecord mediumRecord; if (state.medium) { if (!state.medium->sampleDistance(state.sampler, state.ray, state.mediumState, mediumRecord.mediumSample)) return false; if (mediumRecord.mediumSample.t < 1e-6f) return false; hitSurface = mediumRecord.mediumSample.exited; edgePdfForward = mediumRecord.mediumSample.pdf; Ray reverseRay(mediumRecord.mediumSample.p, -state.ray.dir(), 0.0f, mediumRecord.mediumSample.t); edgePdfBackward = state.medium->pdf(state.sampler, reverseRay, onSurface()); weight *= mediumRecord.mediumSample.weight; if (hitSurface && !didHit) return false; } else { hitSurface = true; edgePdfForward = 1.0f; edgePdfBackward = 1.0f; } if (!hitSurface) { mediumRecord.wi = state.ray.dir(); next = PathVertex(mediumRecord.mediumSample.phase, mediumRecord, _throughput*weight); next._medium = state.medium; state.bounce++; nextEdge = PathEdge(*this, next, edgePdfForward, edgePdfBackward); next._pdfForward = pdf; return true; } else if (didHit) { surfaceRecord.event = tracer.makeLocalScatterEvent(surfaceRecord.data, surfaceRecord.info, state.ray, &state.sampler); next = PathVertex(surfaceRecord.info.bsdf, surfaceRecord, _throughput*weight); next._medium = state.medium; next.pointerFixup(); state.bounce++; nextEdge = PathEdge(*this, next, edgePdfForward, edgePdfBackward); next._pdfForward = pdf; return true; } else if (!adjoint && scene.intersectInfinites(state.ray, surfaceRecord.data, surfaceRecord.info)) { next = PathVertex(surfaceRecord.info.bsdf, surfaceRecord, _throughput*weight); next._medium = state.medium; state.bounce++; nextEdge = PathEdge(state.ray.dir(), 1.0f, 1.0f, edgePdfForward, edgePdfBackward); next._pdfForward = pdf; return true; } else { return false; } }
List log_EMx(const arma::mat& transition_, const arma::cube& emission_, const arma::vec& init_, const arma::ucube& obs, const arma::uvec& nSymbols, const arma::mat& coef_, const arma::mat& X, const arma::uvec& numberOfStates, int itermax, double tol, int trace, unsigned int threads) { // Make sure we don't alter the original vec/mat/cube // needed for cube, in future maybe in other cases as well arma::cube emission = log(emission_); arma::mat transition = log(transition_); arma::vec init = log(init_); arma::mat coef(coef_); coef.col(0).zeros(); arma::mat weights = exp(X * coef).t(); if (!weights.is_finite()) { return List::create(Named("error") = 3); } weights.each_row() /= sum(weights, 0); weights = log(weights); arma::mat initk(emission.n_rows, obs.n_slices); for (unsigned int k = 0; k < obs.n_slices; k++) { initk.col(k) = init + reparma(weights.col(k), numberOfStates); } arma::cube alpha(emission.n_rows, obs.n_cols, obs.n_slices); //m,n,k arma::cube beta(emission.n_rows, obs.n_cols, obs.n_slices); //m,n,k log_internalForwardx(transition, emission, initk, obs, alpha, threads); log_internalBackward(transition, emission, obs, beta, threads); arma::vec ll(obs.n_slices); #pragma omp parallel for if(obs.n_slices >= threads) schedule(static) num_threads(threads) \ default(none) shared(obs, alpha, ll) for (unsigned int k = 0; k < obs.n_slices; k++) { ll(k) = logSumExp(alpha.slice(k).col(obs.n_cols - 1)); } double sumlogLik = sum(ll); if (trace > 0) { Rcout << "Log-likelihood of initial model: " << sumlogLik << std::endl; } // // //EM-algorithm begins // double change = tol + 1.0; int iter = 0; arma::uvec cumsumstate = cumsum(numberOfStates); while ((change > tol) & (iter < itermax)) { iter++; arma::mat ksii(emission.n_rows, emission.n_rows, arma::fill::zeros); arma::cube gamma(emission.n_rows, emission.n_cols, emission.n_slices, arma::fill::zeros); arma::vec delta(emission.n_rows, arma::fill::zeros); for (unsigned int k = 0; k < obs.n_slices; k++) { delta += exp(alpha.slice(k).col(0) + beta.slice(k).col(0) - ll(k)); } #pragma omp parallel for if(obs.n_slices>=threads) schedule(static) num_threads(threads) \ default(none) shared(transition, obs, ll, alpha, beta, emission, ksii, gamma, nSymbols) for (unsigned int k = 0; k < obs.n_slices; k++) { if (obs.n_cols > 1) { for (unsigned int j = 0; j < emission.n_rows; j++) { for (unsigned int i = 0; i < emission.n_rows; i++) { if (transition(i, j) > -arma::datum::inf) { arma::vec tmpnm1(obs.n_cols - 1); for (unsigned int t = 0; t < (obs.n_cols - 1); t++) { tmpnm1(t) = alpha(i, t, k) + transition(i, j) + beta(j, t + 1, k); for (unsigned int r = 0; r < obs.n_rows; r++) { tmpnm1(t) += emission(j, obs(r, t + 1, k), r); } } #pragma omp atomic ksii(i, j) += exp(logSumExp(tmpnm1) - ll(k)); } } } } for (unsigned int r = 0; r < emission.n_slices; r++) { for (unsigned int l = 0; l < nSymbols[r]; l++) { for (unsigned int i = 0; i < emission.n_rows; i++) { if (emission(i, l, r) > -arma::datum::inf) { arma::vec tmpn(obs.n_cols); for (unsigned int t = 0; t < obs.n_cols; t++) { if (l == (obs(r, t, k))) { tmpn(t) = alpha(i, t, k) + beta(i, t, k); } else tmpn(t) = -arma::datum::inf; } #pragma omp atomic gamma(i, l, r) += exp(logSumExp(tmpn) - ll(k)); } } } } } unsigned int error = log_optCoef(weights, obs, emission, initk, beta, ll, coef, X, cumsumstate, numberOfStates, trace); if (error != 0) { return List::create(Named("error") = error); } if (obs.n_cols > 1) { ksii.each_col() /= sum(ksii, 1); transition = log(ksii); } for (unsigned int r = 0; r < emission.n_slices; r++) { gamma.slice(r).cols(0, nSymbols(r) - 1).each_col() /= sum( gamma.slice(r).cols(0, nSymbols(r) - 1), 1); emission.slice(r).cols(0, nSymbols(r) - 1) = log(gamma.slice(r).cols(0, nSymbols(r) - 1)); } for (unsigned int i = 0; i < numberOfStates.n_elem; i++) { delta.subvec(cumsumstate(i) - numberOfStates(i), cumsumstate(i) - 1) /= arma::as_scalar( arma::accu(delta.subvec(cumsumstate(i) - numberOfStates(i), cumsumstate(i) - 1))); } init = log(delta); for (unsigned int k = 0; k < obs.n_slices; k++) { initk.col(k) = init + reparma(weights.col(k), numberOfStates); } log_internalForwardx(transition, emission, initk, obs, alpha, threads); log_internalBackward(transition, emission, obs, beta, threads); for (unsigned int k = 0; k < obs.n_slices; k++) { ll(k) = logSumExp(alpha.slice(k).col(obs.n_cols - 1)); } double tmp = sum(ll); change = (tmp - sumlogLik) / (std::abs(sumlogLik) + 0.1); sumlogLik = tmp; if (!arma::is_finite(sumlogLik)) { return List::create(Named("error") = 6); } if (trace > 1) { Rcout << "iter: " << iter; Rcout << " logLik: " << sumlogLik; Rcout << " relative change: " << change << std::endl; } } if (trace > 0) { if (iter == itermax) { Rcpp::Rcout << "EM algorithm stopped after reaching the maximum number of " << iter << " iterations." << std::endl; } else { Rcpp::Rcout << "EM algorithm stopped after reaching the relative change of " << change; Rcpp::Rcout << " after " << iter << " iterations." << std::endl; } Rcpp::Rcout << "Final log-likelihood: " << sumlogLik << std::endl; } return List::create(Named("coefficients") = wrap(coef), Named("initialProbs") = wrap(exp(init)), Named("transitionMatrix") = wrap(exp(transition)), Named("emissionArray") = wrap(exp(emission)), Named("logLik") = sumlogLik, Named("iterations") = iter, Named("change") = change, Named("error") = 0); }