Example #1
0
double NeuralNetwork::estimateLikelihood(const cv::Mat &x, const cv::Mat &y,
                                         const cv::Mat &W, cv::Mat &b,
                                         const cv::Mat &input_gate1,
                                         const cv::Mat &input_gate2,
                                         const cv::Mat &h2o,
                                         BackwardPropogationModule* bpm) {
    if (bpm != NULL) {
        bpm->grad_h2o = cv::Mat::zeros(h2o.rows, h2o.cols, CV_64F);
    }
    std::vector<cv::Mat> cur_h(layers_amount_ + 1,
                               cv::Mat::zeros(rnn_size_, 1, CV_64F));
    std::vector<cv::Mat> prev_h(layers_amount_ + 1,
                               cv::Mat::zeros(rnn_size_, 1, CV_64F));
    std::vector<cv::Mat> cur_c(layers_amount_ + 1,
                               cv::Mat::zeros(rnn_size_, 1, CV_64F));
    std::vector<cv::Mat> prev_c(layers_amount_ + 1,
                               cv::Mat::zeros(rnn_size_, 1, CV_64F));
    cv::Mat input_gate = input_gate1;
    bool need_to_output = false;
    int output_idx = 0;
    double res = 0.0;
    SymbolManager* symb_manager = SymbolManager::getInstance();
    for (int i = 0; i < x.rows - 1; ++i) {
        int col_inp;
        if (need_to_output)
            col_inp = symb_manager->getIndexOfOutput(x.at<double>(i, 0));
        else
            col_inp = x.at<double>(i, 0);
        cur_h[0] = input_gate.col(x.at<double>(i, 0) - 1).clone();
        for (size_t j = 1; j < layers_amount_ + 1; ++j) {
            cv::Mat arg(2 * rnn_size_, 1, CV_64F);
            for (int h = 0; h < rnn_size_; ++h)
                arg.at<double>(h, 0) = cur_h[j - 1].at<double>(h, 0);
            for (int h = 0; h < rnn_size_; ++h)
                arg.at<double>(h + rnn_size_, 0) = prev_h[j].at<double>(h, 0);
            cv::Mat out = W * arg + b;
            for (int h = 0; h < 3 * rnn_size_; ++h)
                out.at<double>(h, 0) = sigmoid(out.at<double>(h, 0));
            for (int h = 3 * rnn_size_; h < 4 * rnn_size_; ++h)
                out.at<double>(h, 0) = tanh(out.at<double>(h, 0));
            cv::Mat in(rnn_size_, 1, CV_64F), g(rnn_size_, 1, CV_64F),
                    f(rnn_size_, 1, CV_64F), o(rnn_size_, 1, CV_64F);
            for (int h = 0; h < 4 * rnn_size_; ++h) {
                if (h / rnn_size_ == 0)
                    in.at<double>(h % rnn_size_, 0) = out.at<double>(h, 0);
                else if (h / rnn_size_ == 1)
                    f.at<double>(h % rnn_size_, 0) = out.at<double>(h, 0);
                else if (h / rnn_size_ == 2)
                    o.at<double>(h % rnn_size_, 0) = out.at<double>(h, 0);
                else if (h / rnn_size_ == 0)
                    g.at<double>(h % rnn_size_, 0) = out.at<double>(h, 0);
            }
            cur_c[j] = f.mul(prev_c[j]) + in.mul(g);
            cv::Mat smoothed_c(rnn_size_, 1, CV_64F);
            for (int h = 0; h < rnn_size_; ++h)
                smoothed_c.at<double>(h, 0) = tanh(cur_c[j].at<double>(h, 0));
            cur_h[j] = o.mul(smoothed_c);
        }
        if (std::abs(x.at<double>(i, 0) -
                     symb_manager->getIndexOfSymbol('@')) < 1E-6) {
            need_to_output = true;
            input_gate = input_gate2;
        }
        if (need_to_output) {
            cv::Mat output = h2o * cur_h[cur_h.size() - 1];
            if (bpm != NULL) {
                double output_denom = 0.0;
                for (int j = 0; j < output.rows; ++j)
                    output_denom += exp(output.at<double>(j, 0));
                double h2o_output_nom = exp(output.at<double>(symb_manager->getIndexOfOutput(
                                                    y.at<double>(output_idx, 0)),0));
                for (int j = 0; j < rnn_size_; ++j) {
                    bpm->grad_h2o.at<double>(symb_manager->getIndexOfOutput(
                                                 y.at<double>(output_idx, 0)), j) +=
                            cur_h[cur_h.size() - 1].at<double>(j, 0) * h2o_output_nom / output_denom -
                                cur_h[cur_h.size() - 1].at<double>(j, 0);
                }
            }
            vectorToDistribution(output);
            double prob = output.at<double>(symb_manager->getIndexOfOutput(
                                                y.at<double>(output_idx, 0)), 0);
            res -= log(prob);
            output_idx++;
        }
    }
    return res;
}
Example #2
0
int main(int argc, char* argv[])
{
  // Load the mesh.
  Mesh basemesh;
  H2DReader mloader;
  mloader.load("GAMM-channel.mesh", &basemesh);

  // Initialize the meshes.
  Mesh mesh_flow, mesh_concentration;
  mesh_flow.copy(&basemesh);
  mesh_concentration.copy(&basemesh);

  for(unsigned int i = 0; i < INIT_REF_NUM_CONCENTRATION; i++)
    mesh_concentration.refine_all_elements();

  mesh_concentration.refine_towards_boundary(BDY_DIRICHLET_CONCENTRATION, INIT_REF_NUM_CONCENTRATION_BDY);
  mesh_flow.refine_towards_boundary(BDY_DIRICHLET_CONCENTRATION, INIT_REF_NUM_CONCENTRATION_BDY);

  for(unsigned int i = 0; i < INIT_REF_NUM_FLOW; i++)
    mesh_flow.refine_all_elements();

  // Initialize boundary condition types and spaces with default shapesets.
  // For the concentration.
  EssentialBCs bcs_concentration;
  
  bcs_concentration.add_boundary_condition(new ConcentrationTimedepEssentialBC(BDY_DIRICHLET_CONCENTRATION, CONCENTRATION_EXT, CONCENTRATION_EXT_STARTUP_TIME));
  bcs_concentration.add_boundary_condition(new ConcentrationTimedepEssentialBC(BDY_SOLID_WALL_TOP, 0.0, CONCENTRATION_EXT_STARTUP_TIME));
  
  L2Space space_rho(&mesh_flow, P_INIT_FLOW);
  L2Space space_rho_v_x(&mesh_flow, P_INIT_FLOW);
  L2Space space_rho_v_y(&mesh_flow, P_INIT_FLOW);
  L2Space space_e(&mesh_flow, P_INIT_FLOW);
  // Space for concentration.
  H1Space space_c(&mesh_concentration, &bcs_concentration, P_INIT_CONCENTRATION);

  int ndof = Space::get_num_dofs(Hermes::vector<Space*>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e, &space_c));
  info("ndof: %d", ndof);

  // Initialize solutions, set initial conditions.
  InitialSolutionEulerDensity prev_rho(&mesh_flow, RHO_EXT);
  InitialSolutionEulerDensityVelX prev_rho_v_x(&mesh_flow, RHO_EXT * V1_EXT);
  InitialSolutionEulerDensityVelY prev_rho_v_y(&mesh_flow, RHO_EXT * V2_EXT);
  InitialSolutionEulerDensityEnergy prev_e(&mesh_flow, QuantityCalculator::calc_energy(RHO_EXT, RHO_EXT * V1_EXT, RHO_EXT * V2_EXT, P_EXT, KAPPA));
  InitialSolutionConcentration prev_c(&mesh_concentration, 0.0);

  // Numerical flux.
  OsherSolomonNumericalFlux num_flux(KAPPA);

  // Initialize weak formulation.
  EulerEquationsWeakFormSemiImplicitCoupled wf(&num_flux, KAPPA, RHO_EXT, V1_EXT, V2_EXT, P_EXT, BDY_SOLID_WALL_BOTTOM,
    BDY_SOLID_WALL_TOP, BDY_INLET, BDY_OUTLET, BDY_NATURAL_CONCENTRATION, &prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e, &prev_c, EPSILON, (P_INIT_FLOW == 0));
  
  wf.set_time_step(time_step);

  // Initialize the FE problem.
  DiscreteProblem dp(&wf, Hermes::vector<Space*>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e, &space_c));

  // If the FE problem is in fact a FV problem.
  //if(P_INIT == 0) dp.set_fvm();  

  // Filters for visualization of Mach number, pressure and entropy.
  MachNumberFilter Mach_number(Hermes::vector<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA);
  PressureFilter pressure(Hermes::vector<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA);
  EntropyFilter entropy(Hermes::vector<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA, RHO_EXT, P_EXT);

  /*
  ScalarView pressure_view("Pressure", new WinGeom(0, 0, 600, 300));
  ScalarView Mach_number_view("Mach number", new WinGeom(700, 0, 600, 300));
  ScalarView entropy_production_view("Entropy estimate", new WinGeom(0, 400, 600, 300));
  ScalarView s5("Concentration", new WinGeom(700, 400, 600, 300));
  */
  
  ScalarView s1("1", new WinGeom(0, 0, 600, 300));
  ScalarView s2("2", new WinGeom(700, 0, 600, 300));
  ScalarView s3("3", new WinGeom(0, 400, 600, 300));
  ScalarView s4("4", new WinGeom(700, 400, 600, 300));
  ScalarView s5("Concentration", new WinGeom(350, 200, 600, 300));

  // Set up the solver, matrix, and rhs according to the solver selection.
  SparseMatrix* matrix = create_matrix(matrix_solver);
  Vector* rhs = create_vector(matrix_solver);
  Solver* solver = create_linear_solver(matrix_solver, matrix, rhs);

  // Set up CFL calculation class.
  CFLCalculation CFL(CFL_NUMBER, KAPPA);

  // Set up Advection-Diffusion-Equation stability calculation class.
  ADEStabilityCalculation ADES(ADVECTION_STABILITY_CONSTANT, DIFFUSION_STABILITY_CONSTANT, EPSILON);

  int iteration = 0; double t = 0;
  for(t = 0.0; t < 100.0; t += time_step) {
    info("---- Time step %d, time %3.5f.", iteration++, t);

    // Set the current time step.
    wf.set_time_step(time_step);
    Space::update_essential_bc_values(&space_c, t);

    // Assemble stiffness matrix and rhs.
    info("Assembling the stiffness matrix and right-hand side vector.");
    dp.assemble(matrix, rhs);

    // Solve the matrix problem.
    info("Solving the matrix problem.");
    scalar* solution_vector = NULL;
    if(solver->solve()) {
      solution_vector = solver->get_solution();
      Solution::vector_to_solutions(solution_vector, Hermes::vector<Space *>(&space_rho, &space_rho_v_x, 
      &space_rho_v_y, &space_e, &space_c), Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e, &prev_c));
    }
    else
    error ("Matrix solver failed.\n");

    if(SHOCK_CAPTURING) {
      DiscontinuityDetector discontinuity_detector(Hermes::vector<Space *>(&space_rho, &space_rho_v_x, 
        &space_rho_v_y, &space_e), Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));

      std::set<int> discontinuous_elements = discontinuity_detector.get_discontinuous_element_ids(DISCONTINUITY_DETECTOR_PARAM);

      FluxLimiter flux_limiter(solution_vector, Hermes::vector<Space *>(&space_rho, &space_rho_v_x, 
        &space_rho_v_y, &space_e), Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));

      flux_limiter.limit_according_to_detector(discontinuous_elements);
    }

    util_time_step = time_step;

    CFL.calculate_semi_implicit(Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), &mesh_flow, util_time_step);

    time_step = util_time_step;

    ADES.calculate(Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y), &mesh_concentration, util_time_step);

    if(util_time_step < time_step)
      time_step = util_time_step;

    // Visualization.
    if((iteration - 1) % EVERY_NTH_STEP == 0) {
      // Hermes visualization.
      if(HERMES_VISUALIZATION) {
        /*
        Mach_number.reinit();
        pressure.reinit();
        entropy.reinit();
        pressure_view.show(&pressure);
        entropy_production_view.show(&entropy);
        Mach_number_view.show(&Mach_number);
        s5.show(&prev_c);
        */
        s1.show(&prev_rho);
        s2.show(&prev_rho_v_x);
        s3.show(&prev_rho_v_y);
        s4.show(&prev_e);
        s5.show(&prev_c);
        /*
        s1.save_numbered_screenshot("density%i.bmp", iteration, true);
        s2.save_numbered_screenshot("density_v_x%i.bmp", iteration, true);
        s3.save_numbered_screenshot("density_v_y%i.bmp", iteration, true);
        s4.save_numbered_screenshot("energy%i.bmp", iteration, true);
        s5.save_numbered_screenshot("concentration%i.bmp", iteration, true);
        */
        //s5.wait_for_close();
        
      }
      // Output solution in VTK format.
      if(VTK_VISUALIZATION) {
        pressure.reinit();
        Mach_number.reinit();
        Linearizer lin;
        char filename[40];
        sprintf(filename, "pressure-%i.vtk", iteration - 1);
        lin.save_solution_vtk(&pressure, filename, "Pressure", false);
        sprintf(filename, "pressure-3D-%i.vtk", iteration - 1);
        lin.save_solution_vtk(&pressure, filename, "Pressure", true);
        sprintf(filename, "Mach number-%i.vtk", iteration - 1);
        lin.save_solution_vtk(&Mach_number, filename, "MachNumber", false);
        sprintf(filename, "Mach number-3D-%i.vtk", iteration - 1);
        lin.save_solution_vtk(&Mach_number, filename, "MachNumber", true);
        sprintf(filename, "Concentration-%i.vtk", iteration - 1);
        lin.save_solution_vtk(&prev_c, filename, "Concentration", true);
        sprintf(filename, "Concentration-3D-%i.vtk", iteration - 1);
        lin.save_solution_vtk(&prev_c, filename, "Concentration", true);
 
      }
    }
  }
  
  /*
  pressure_view.close();
  entropy_production_view.close();
  Mach_number_view.close();
  s5.close();
  */
  
  s1.close();
  s2.close();
  s3.close();
  s4.close();
  s5.close();

  return 0;
}