Esempio n. 1
0
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;
}
Esempio n. 2
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
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);
}
Esempio n. 3
0
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;
}
Esempio n. 4
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));
}
Esempio n. 5
0
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));
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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);
    }
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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));
  }

}
Esempio n. 10
0
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()));
}
Esempio n. 11
0
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);
    }
}
Esempio n. 12
0
File: ex5.c Progetto: ZJLi2013/petsc
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;
}
Esempio n. 13
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);
}
Esempio n. 14
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);
}
Esempio n. 15
0
void Emitter :: next_step()
{
	movement();
	emission();	
}
Esempio n. 16
0
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);
}
Esempio n. 17
0
File: EM.cpp Progetto: wondek/seqHMM
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);
}
Esempio n. 18
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);
    }
}
Esempio n. 19
0
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)));
}
Esempio n. 20
0
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));
}
Esempio n. 21
0
/* 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;
}
Esempio n. 22
0
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;
};
Esempio n. 23
0
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);
}
Esempio n. 24
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;
    }
}
Esempio n. 25
0
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);
}