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; }
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; }