/* * Copyright © 2007-2017 Dynare Team * * This file is part of Dynare. * * Dynare is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Dynare is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Dynare. If not, see . */ #include #include #include #include "Interpreter.hh" #define BIG 1.0e+8; #define SMALL 1.0e-5; ///#define DEBUG Interpreter::~Interpreter() { } Interpreter::Interpreter(double *params_arg, double *y_arg, double *ya_arg, double *x_arg, double *steady_y_arg, double *steady_x_arg, double *direction_arg, size_t y_size_arg, size_t nb_row_x_arg, size_t nb_row_xd_arg, int periods_arg, int y_kmin_arg, int y_kmax_arg, int maxit_arg_, double solve_tolf_arg, size_t size_of_direction_arg, double slowc_arg, int y_decal_arg, double markowitz_c_arg, string &filename_arg, int minimal_solving_periods_arg, int stack_solve_algo_arg, int solve_algo_arg, bool global_temporary_terms_arg, bool print_arg, bool print_error_arg, mxArray *GlobalTemporaryTerms_arg, bool steady_state_arg, bool print_it_arg, int col_x_arg, int col_y_arg #ifdef CUDA , const int CUDA_device_arg, cublasHandle_t cublas_handle_arg, cusparseHandle_t cusparse_handle_arg, cusparseMatDescr_t descr_arg #endif ) : dynSparseMatrix(y_size_arg, y_kmin_arg, y_kmax_arg, print_it_arg, steady_state_arg, periods_arg, minimal_solving_periods_arg, slowc_arg #ifdef CUDA , CUDA_device_arg, cublas_handle_arg, cusparse_handle_arg, descr_arg #endif ) { params = params_arg; y = y_arg; ya = ya_arg; x = x_arg; steady_y = steady_y_arg; steady_x = steady_x_arg; direction = direction_arg; //y_size = y_size_arg; nb_row_x = nb_row_x_arg; nb_row_xd = nb_row_xd_arg; periods = periods_arg; //y_kmax = y_kmax_arg; //y_kmin = y_kmin_arg; maxit_ = maxit_arg_; solve_tolf = solve_tolf_arg; size_of_direction = size_of_direction_arg; slowc = slowc_arg; slowc_save = slowc; y_decal = y_decal_arg; markowitz_c = markowitz_c_arg; filename = filename_arg; T = NULL; minimal_solving_periods = minimal_solving_periods_arg; stack_solve_algo = stack_solve_algo_arg; solve_algo = solve_algo_arg; global_temporary_terms = global_temporary_terms_arg; print = print_arg; col_x = col_x_arg; col_y = col_y_arg; GlobalTemporaryTerms = GlobalTemporaryTerms_arg; print_error = print_error_arg; //steady_state = steady_state_arg; print_it = print_it_arg; } void Interpreter::evaluate_a_block(bool initialization) { it_code_type begining; switch (type) { case EVALUATE_FORWARD: if (steady_state) { compute_block_time(0, true, /*block_num, size, steady_state, */ false); if (block >= 0) for (int j = 0; j < size; j++) residual[j] = y[Block_Contain[j].Variable] - ya[Block_Contain[j].Variable]; else for (int j = 0; j < size; j++) residual[Block_Contain[j].Equation] = y[Block_Contain[j].Variable] - ya[Block_Contain[j].Variable]; } else { begining = it_code; for (it_ = y_kmin; it_ < periods+y_kmin; it_++) { it_code = begining; Per_y_ = it_*y_size; compute_block_time(0, true, /*block_num, size, steady_state, */ false); if (block >= 0) for (int j = 0; j < size; j++) residual[it_*size+j] = y[it_*y_size+Block_Contain[j].Variable] - ya[it_*y_size+Block_Contain[j].Variable]; else for (int j = 0; j < size; j++) residual[it_*size+Block_Contain[j].Equation] = y[it_*y_size+Block_Contain[j].Variable] - ya[it_*y_size+Block_Contain[j].Variable]; } } break; case SOLVE_FORWARD_SIMPLE: g1 = static_cast(mxMalloc(size*size*sizeof(double))); test_mxMalloc(g1, __LINE__, __FILE__, __func__, size*size*sizeof(double)); r = static_cast(mxMalloc(size*sizeof(double))); test_mxMalloc(r, __LINE__, __FILE__, __func__, size*sizeof(double)); if (steady_state) { compute_block_time(0, true, /*block_num, size, steady_state,*/ false); if (block < 0) for (int j = 0; j < size; j++) residual[Block_Contain[j].Equation] = r[j]; else for (int j = 0; j < size; j++) residual[j] = r[j]; } else { begining = it_code; for (it_ = y_kmin; it_ < periods+y_kmin; it_++) { it_code = begining; Per_y_ = it_*y_size; compute_block_time(0, true, /*block_num, size, steady_state,*/ false); if (block < 0) for (int j = 0; j < size; j++) residual[Per_y_+Block_Contain[j].Equation] = r[j]; else for (int j = 0; j < size; j++) residual[it_*size+j] = r[j]; } } mxFree(g1); mxFree(r); break; case SOLVE_FORWARD_COMPLETE: if (initialization) { fixe_u(&u, u_count_int, u_count_int); Read_SparseMatrix(bin_base_name, size, 1, 0, 0, false, stack_solve_algo, solve_algo); } #ifdef DEBUG mexPrintf("in SOLVE_FORWARD_COMPLETE r = mxMalloc(%d*sizeof(double))\n", size); #endif r = static_cast(mxMalloc(size*sizeof(double))); test_mxMalloc(r, __LINE__, __FILE__, __func__, size*sizeof(double)); if (steady_state) { compute_block_time(0, true, /*block_num, size, steady_state,*/ false); if (block < 0) for (int j = 0; j < size; j++) residual[Block_Contain[j].Equation] = r[j]; else for (int j = 0; j < size; j++) residual[j] = r[j]; } else { begining = it_code; for (it_ = y_kmin; it_ < periods+y_kmin; it_++) { it_code = begining; Per_y_ = it_*y_size; compute_block_time(0, true, /*block_num, size, steady_state,*/ false); if (block < 0) for (int j = 0; j < size; j++) residual[it_*y_size+Block_Contain[j].Equation] = r[j]; else for (int j = 0; j < size; j++) residual[it_*size+j] = r[j]; } } mxFree(r); break; case EVALUATE_BACKWARD: if (steady_state) { compute_block_time(0, true, /*block_num, size, steady_state,*/ false); if (block >= 0) for (int j = 0; j < size; j++) residual[j] = y[Block_Contain[j].Variable] - ya[Block_Contain[j].Variable]; else for (int j = 0; j < size; j++) residual[Block_Contain[j].Equation] = y[Block_Contain[j].Variable] - ya[Block_Contain[j].Variable]; } else { begining = it_code; for (it_ = periods+y_kmin-1; it_ >= y_kmin; it_--) { it_code = begining; Per_y_ = it_*y_size; compute_block_time(0, true, /*block_num, size, steady_state,*/ false); if (block >= 0) for (int j = 0; j < size; j++) residual[it_*size+j] = y[it_*y_size+Block_Contain[j].Variable] - ya[it_*y_size+Block_Contain[j].Variable]; else for (int j = 0; j < size; j++) residual[it_*size+Block_Contain[j].Equation] = y[it_*y_size+Block_Contain[j].Variable] - ya[it_*y_size+Block_Contain[j].Variable]; } } break; case SOLVE_BACKWARD_SIMPLE: g1 = static_cast(mxMalloc(size*size*sizeof(double))); test_mxMalloc(g1, __LINE__, __FILE__, __func__, size*size*sizeof(double)); r = static_cast(mxMalloc(size*sizeof(double))); test_mxMalloc(r, __LINE__, __FILE__, __func__, size*sizeof(double)); if (steady_state) { compute_block_time(0, true, /*block_num, size, steady_state,*/ false); if (block < 0) for (int j = 0; j < size; j++) residual[Block_Contain[j].Equation] = r[j]; else for (int j = 0; j < size; j++) residual[j] = r[j]; } else { begining = it_code; for (it_ = periods+y_kmin-1; it_ >= y_kmin; it_--) { it_code = begining; Per_y_ = it_*y_size; compute_block_time(0, true, /*block_num, size, steady_state,*/ false); if (block < 0) for (int j = 0; j < size; j++) residual[Per_y_+Block_Contain[j].Equation] = r[j]; else for (int j = 0; j < size; j++) residual[it_*size+j] = r[j]; } } mxFree(g1); mxFree(r); break; case SOLVE_BACKWARD_COMPLETE: if (initialization) { fixe_u(&u, u_count_int, u_count_int); Read_SparseMatrix(bin_base_name, size, 1, 0, 0, false, stack_solve_algo, solve_algo); } r = static_cast(mxMalloc(size*sizeof(double))); test_mxMalloc(r, __LINE__, __FILE__, __func__, size*sizeof(double)); if (steady_state) { compute_block_time(0, true, /*block_num, size, steady_state,*/ false); if (block < 0) for (int j = 0; j < size; j++) residual[Block_Contain[j].Equation] = r[j]; else for (int j = 0; j < size; j++) residual[j] = r[j]; } else { begining = it_code; for (it_ = periods+y_kmin-1; it_ >= y_kmin; it_--) { it_code = begining; Per_y_ = it_*y_size; compute_block_time(0, true, /*block_num, size, steady_state, */ false); if (block < 0) for (int j = 0; j < size; j++) residual[Per_y_+Block_Contain[j].Equation] = r[j]; else for (int j = 0; j < size; j++) residual[it_*size+j] = r[j]; } } mxFree(r); break; case SOLVE_TWO_BOUNDARIES_SIMPLE: case SOLVE_TWO_BOUNDARIES_COMPLETE: if (initialization) { fixe_u(&u, u_count_int, u_count_int); Read_SparseMatrix(bin_base_name, size, periods, y_kmin, y_kmax, true, stack_solve_algo, solve_algo); } u_count = u_count_int*(periods+y_kmax+y_kmin); r = static_cast(mxMalloc(size*sizeof(double))); test_mxMalloc(r, __LINE__, __FILE__, __func__, size*sizeof(double)); begining = it_code; for (it_ = y_kmin; it_ < periods+y_kmin; it_++) { Per_u_ = (it_-y_kmin)*u_count_int; Per_y_ = it_*y_size; it_code = begining; compute_block_time(Per_u_, true, /*block_num, size, steady_state,*/ false); if (block < 0) for (int j = 0; j < size; j++) residual[it_*y_size+Block_Contain[j].Equation] = r[j]; else for (int j = 0; j < size; j++) residual[it_*size+j] = r[j]; } mxFree(r); break; } } int Interpreter::simulate_a_block(vector_table_conditional_local_type vector_table_conditional_local) { it_code_type begining; max_res = 0; max_res_idx = 0; bool cvg; double *y_save; #ifdef DEBUG mexPrintf("simulate_a_block type = %d, periods=%d, y_kmin=%d, y_kmax=%d\n", type, periods, y_kmin, y_kmax); mexEvalString("drawnow;"); #endif switch (type) { case EVALUATE_FORWARD: #ifdef DEBUG mexPrintf("EVALUATE_FORWARD\n"); mexEvalString("drawnow;"); #endif evaluate_over_periods(true); break; case EVALUATE_BACKWARD: #ifdef DEBUG mexPrintf("EVALUATE_BACKWARD\n"); mexEvalString("drawnow;"); #endif evaluate_over_periods(false); break; case SOLVE_FORWARD_SIMPLE: #ifdef DEBUG mexPrintf("SOLVE_FORWARD_SIMPLE size=%d\n", size); mexEvalString("drawnow;"); #endif solve_simple_over_periods(true); break; case SOLVE_BACKWARD_SIMPLE: #ifdef DEBUG mexPrintf("SOLVE_BACKWARD_SIMPLE\n"); mexEvalString("drawnow;"); #endif solve_simple_over_periods(false); break; case SOLVE_FORWARD_COMPLETE: #ifdef DEBUG mexPrintf("SOLVE_FORWARD_COMPLETE\n"); mexEvalString("drawnow;"); #endif if (vector_table_conditional_local.size()) { it_code_type curr_it_code = it_code; evaluate_a_block(true); it_code = curr_it_code; } else { fixe_u(&u, u_count_int, u_count_int); Read_SparseMatrix(bin_base_name, size, 1, 0, 0, false, stack_solve_algo, solve_algo); } start_code = it_code; Per_u_ = 0; Simulate_Newton_One_Boundary(true); mxFree(u); mxFree(index_equa); mxFree(index_vara); memset(direction, 0, size_of_direction); End_Solver(); break; case SOLVE_BACKWARD_COMPLETE: #ifdef DEBUG mexPrintf("SOLVE_BACKWARD_COMPLETE\n"); mexEvalString("drawnow;"); #endif if (vector_table_conditional_local.size()) { it_code_type curr_it_code = it_code; evaluate_a_block(true); it_code = curr_it_code; } else { fixe_u(&u, u_count_int, u_count_int); Read_SparseMatrix(bin_base_name, size, 1, 0, 0, false, stack_solve_algo, solve_algo); } start_code = it_code; Per_u_ = 0; Simulate_Newton_One_Boundary(false); mxFree(index_equa); mxFree(index_vara); memset(direction, 0, size_of_direction); mxFree(u); End_Solver(); break; case SOLVE_TWO_BOUNDARIES_SIMPLE: case SOLVE_TWO_BOUNDARIES_COMPLETE: #ifdef DEBUG mexPrintf("SOLVE_TWO_BOUNDARIES\n"); mexEvalString("drawnow;"); #endif if (steady_state) { mexPrintf("SOLVE_TWO_BOUNDARIES in a steady state model: impossible case\n"); return ERROR_ON_EXIT; } if (vector_table_conditional_local.size()) { it_code_type curr_it_code = it_code; evaluate_a_block(true); it_code = curr_it_code; } else { fixe_u(&u, u_count_int, u_count_int); Read_SparseMatrix(bin_base_name, size, periods, y_kmin, y_kmax, true, stack_solve_algo, solve_algo); } u_count = u_count_int*(periods+y_kmax+y_kmin); r = static_cast(mxMalloc(size*sizeof(double))); test_mxMalloc(r, __LINE__, __FILE__, __func__, size*sizeof(double)); res = static_cast(mxMalloc(size*periods*sizeof(double))); test_mxMalloc(res, __LINE__, __FILE__, __func__, size*periods*sizeof(double)); y_save = static_cast(mxMalloc(y_size*sizeof(double)*(periods+y_kmax+y_kmin))); test_mxMalloc(y_save, __LINE__, __FILE__, __func__, y_size*sizeof(double)*(periods+y_kmax+y_kmin)); start_code = it_code; iter = 0; if (!is_linear) { cvg = false; glambda2 = g0 = very_big; try_at_iteration = 0; int u_count_saved = u_count; while (!(cvg || (iter > maxit_))) { res2 = 0; res1 = 0; max_res = 0; max_res_idx = 0; memcpy(y_save, y, y_size*sizeof(double)*(periods+y_kmax+y_kmin)); if (vector_table_conditional_local.size()) { for (vector_table_conditional_local_type::iterator it1 = vector_table_conditional_local.begin(); it1 != vector_table_conditional_local.end(); it1++) { if (it1->is_cond) { //mexPrintf("y[%d] = %f\n", it1->var_endo + y_kmin * size, y[it1->var_endo + y_kmin * size]); y[it1->var_endo + y_kmin * size] = it1->constrained_value; } } } compute_complete_2b(false, &res1, &res2, &max_res, &max_res_idx); end_code = it_code; if (!(isnan(res1) || isinf(res1))) cvg = (max_res < solve_tolf); if (isnan(res1) || isinf(res1) || (stack_solve_algo == 4 && iter > 0)) memcpy(y, y_save, y_size*sizeof(double)*(periods+y_kmax+y_kmin)); u_count = u_count_saved; int prev_iter = iter; Simulate_Newton_Two_Boundaries(block_num, symbol_table_endo_nbr, y_kmin, y_kmax, size, periods, cvg, minimal_solving_periods, stack_solve_algo, endo_name_length, P_endo_names, vector_table_conditional_local); iter++; if (iter > prev_iter) { g0 = res2; gp0 = -res2; try_at_iteration = 0; slowc_save = slowc; } } if (!cvg) { ostringstream tmp; tmp << " in Solve two boundaries, convergence not achieved in block " << block_num+1 << ", after " << iter << " iterations\n"; throw FatalExceptionHandling(tmp.str()); } } else { res1 = 0; res2 = 0; max_res = 0; max_res_idx = 0; compute_complete_2b(false, &res1, &res2, &max_res, &max_res_idx); end_code = it_code; cvg = false; Simulate_Newton_Two_Boundaries(block_num, symbol_table_endo_nbr, y_kmin, y_kmax, size, periods, cvg, minimal_solving_periods, stack_solve_algo, endo_name_length, P_endo_names, vector_table_conditional_local); max_res = 0; max_res_idx = 0; } it_code = end_code; if (r) mxFree(r); if (y_save) mxFree(y_save); if (u) mxFree(u); if (index_vara) mxFree(index_vara); if (index_equa) mxFree(index_equa); if (res) mxFree(res); memset(direction, 0, size_of_direction); End_Solver(); break; default: ostringstream tmp; tmp << " in simulate_a_block, Unknown type = " << type << "\n"; throw FatalExceptionHandling(tmp.str()); return ERROR_ON_EXIT; } return NO_ERROR_ON_EXIT; } void Interpreter::print_a_block() { it_code_type begining; if (block < 0) mexPrintf("\nBlock %d\n", block_num+1); else mexPrintf("\nBlock %d\n", block+1); mexPrintf("----------\n"); if (steady_state) residual = vector(size); else residual = vector(size*(periods+y_kmin)); bool go_on = true; bool space = false; while (go_on) { if (it_code->first == FENDBLOCK) { go_on = false; it_code++; } else { string s = print_expression(it_code, false, size, block_num, steady_state, Per_u_, it_, it_code, false); if (s == "if (evaluate)" || s == "else") space = false; if (s.length() > 0) { if (space) mexPrintf(" %s\n", s.c_str()); else mexPrintf("%s\n", s.c_str()); mexEvalString("drawnow;"); } if (s == "if (evaluate)" || s == "else") space = true; } } } void Interpreter::ReadCodeFile(string file_name, CodeLoad &code) { if (steady_state) file_name += "/model/bytecode/static"; else file_name += "/model/bytecode/dynamic"; //First read and store in memory the code code_liste = code.get_op_code(file_name); EQN_block_number = code.get_block_number(); if (!code_liste.size()) { ostringstream tmp; tmp << " in compute_blocks, " << file_name << ".cod cannot be opened\n"; throw FatalExceptionHandling(tmp.str()); } if (block >= static_cast(code.get_block_number())) { ostringstream tmp; tmp << " in compute_blocks, input argument block = " << block+1 << " is greater than the number of blocks in the model (" << code.get_block_number() << " see M_.block_structure_stat.block)\n"; throw FatalExceptionHandling(tmp.str()); } } void Interpreter::check_for_controlled_exo_validity(FBEGINBLOCK_ *fb, vector sconstrained_extended_path) { vector exogenous = fb->get_exogenous(); vector endogenous = fb->get_endogenous(); for (vector::iterator it = sconstrained_extended_path.begin(); it != sconstrained_extended_path.end(); it++) { if ((find(endogenous.begin(), endogenous.end(), it->exo_num) != endogenous.end()) && (find(exogenous.begin(), exogenous.end(), it->var_num) == exogenous.end())) { ostringstream tmp; tmp << "\n the conditional forecast involving as constrained variable " << get_variable(SymbolType::endogenous, it->exo_num) << " and as endogenized exogenous " << get_variable(SymbolType::exogenous, it->var_num) << " that do not appear in block=" << Block_Count+1 << ")\n You should not use block in model options\n"; throw FatalExceptionHandling(tmp.str()); } else if ((find(endogenous.begin(), endogenous.end(), it->exo_num) != endogenous.end()) && (find(exogenous.begin(), exogenous.end(), it->var_num) != exogenous.end()) && ((fb->get_type() == EVALUATE_FORWARD) || (fb->get_type() != EVALUATE_BACKWARD))) { ostringstream tmp; tmp << "\n the conditional forecast cannot be implemented for the block=" << Block_Count+1 << ") that has to be evaluated instead to be solved\n You should not use block in model options\n"; throw FatalExceptionHandling(tmp.str()); } else if (find(previous_block_exogenous.begin(), previous_block_exogenous.end(), it->var_num) != previous_block_exogenous.end()) { ostringstream tmp; tmp << "\n the conditional forecast involves in the block " << Block_Count+1 << " the endogenized exogenous " << get_variable(SymbolType::exogenous, it->var_num) << " that appear also in a previous block\n You should not use block in model options\n"; throw FatalExceptionHandling(tmp.str()); } } for (vector::iterator it = exogenous.begin(); it != exogenous.end(); it++) previous_block_exogenous.push_back(*it); } bool Interpreter::MainLoop(string bin_basename, CodeLoad code, bool evaluate, int block, bool last_call, bool constrained, vector sconstrained_extended_path, vector_table_conditional_local_type vector_table_conditional_local) { int var; Block_Count = -1; bool go_on = true; double max_res_local = 0; int max_res_idx_local = 0; if (block < 0) { if (steady_state) residual = vector(y_size); else residual = vector(y_size*(periods+y_kmin)); } while (go_on) { switch (it_code->first) { case FBEGINBLOCK: Block_Count++; #ifdef DEBUG mexPrintf("---------------------------------------------------------\n"); if (block < 0) mexPrintf("FBEGINBLOCK Block_Count=%d\n", Block_Count+1); else mexPrintf("FBEGINBLOCK block=%d\n", block+1); #endif //it's a new block { FBEGINBLOCK_ *fb = static_cast(it_code->second); Block_Contain = fb->get_Block_Contain(); it_code++; if (constrained) check_for_controlled_exo_validity(fb, sconstrained_extended_path); set_block(fb->get_size(), fb->get_type(), file_name, bin_basename, Block_Count, fb->get_is_linear(), fb->get_endo_nbr(), fb->get_Max_Lag(), fb->get_Max_Lead(), fb->get_u_count_int(), block); if (print) print_a_block(); else if (evaluate) { #ifdef DEBUG mexPrintf("jacobian_block=mxCreateDoubleMatrix(%d, %d, mxREAL)\n", fb->get_size(), fb->get_nb_col_jacob()); #endif jacobian_block.push_back(mxCreateDoubleMatrix(fb->get_size(), fb->get_nb_col_jacob(), mxREAL)); if (!steady_state) { #ifdef DEBUG mexPrintf("allocates jacobian_exo_block( %d, %d, mxREAL)\n", fb->get_size(), fb->get_exo_size()); mexPrintf("(0) Allocating Jacobian\n"); #endif jacobian_exo_block.push_back(mxCreateDoubleMatrix(fb->get_size(), fb->get_nb_col_exo_jacob(), mxREAL)); jacobian_det_exo_block.push_back(mxCreateDoubleMatrix(fb->get_size(), fb->get_nb_col_det_exo_jacob(), mxREAL)); jacobian_other_endo_block.push_back(mxCreateDoubleMatrix(fb->get_size(), fb->get_nb_col_other_endo_jacob(), mxREAL)); } if (block >= 0) { if (steady_state) residual = vector(fb->get_size()); else residual = vector(fb->get_size()*(periods+y_kmin)); } evaluate_a_block(true); } else { #ifdef DEBUG mexPrintf("endo in Block_Count=%d, block=%d, type=%d, steady_state=%d, print_it=%d, Block_Count=%d, fb->get_is_linear()=%d, fb->get_endo_nbr()=%d, fb->get_Max_Lag()=%d, fb->get_Max_Lead()=%d, fb->get_u_count_int()=%d\n", Block_Count, fb->get_size(), fb->get_type(), steady_state, print_it, Block_Count, fb->get_is_linear(), fb->get_endo_nbr(), fb->get_Max_Lag(), fb->get_Max_Lead(), fb->get_u_count_int()); #endif bool result; if (sconstrained_extended_path.size()) { //mexPrintf("(1) Allocating Jacobian fb->get_size()=%d fb->get_nb_col_jacob()=%d\n", fb->get_size(), fb->get_nb_col_jacob()); jacobian_block.push_back(mxCreateDoubleMatrix(fb->get_size(), fb->get_nb_col_jacob(), mxREAL)); //mexPrintf("mxGetPr(jacobian_block[block_num])=%x\n",mxGetPr(jacobian_block[0])); jacobian_exo_block.push_back(mxCreateDoubleMatrix(fb->get_size(), fb->get_nb_col_exo_jacob(), mxREAL)); jacobian_det_exo_block.push_back(mxCreateDoubleMatrix(fb->get_size(), fb->get_nb_col_det_exo_jacob(), mxREAL)); jacobian_other_endo_block.push_back(mxCreateDoubleMatrix(fb->get_size(), fb->get_nb_col_other_endo_jacob(), mxREAL)); residual = vector(fb->get_size()*(periods+y_kmin)); result = simulate_a_block(vector_table_conditional_local); mxDestroyArray(jacobian_block.back()); jacobian_block.pop_back(); mxDestroyArray(jacobian_exo_block.back()); jacobian_exo_block.pop_back(); mxDestroyArray(jacobian_det_exo_block.back()); jacobian_det_exo_block.pop_back(); mxDestroyArray(jacobian_other_endo_block.back()); jacobian_other_endo_block.pop_back(); } else result = simulate_a_block(vector_table_conditional_local); //mexPrintf("OKe\n"); if (max_res > max_res_local) { max_res_local = max_res; max_res_idx_local = max_res_idx; } if (result == ERROR_ON_EXIT) return ERROR_ON_EXIT; } if (last_call) delete fb; } if (block >= 0) { go_on = false; } break; case FEND: #ifdef DEBUG mexPrintf("FEND\n"); #endif go_on = false; it_code++; break; case FDIMT: #ifdef DEBUG mexPrintf("FDIMT size=%d\n", static_cast(it_code->second)->get_size()); #endif var = static_cast(it_code->second)->get_size(); if (T) mxFree(T); T = static_cast(mxMalloc(var*(periods+y_kmin+y_kmax)*sizeof(double))); test_mxMalloc(T, __LINE__, __FILE__, __func__, var*(periods+y_kmin+y_kmax)*sizeof(double)); if (block >= 0) { it_code = code_liste.begin() + code.get_begin_block(block); } else it_code++; break; case FDIMST: #ifdef DEBUG mexPrintf("FDIMST size=%d\n", static_cast(it_code->second)->get_size()); #endif var = static_cast(it_code->second)->get_size(); if (T) mxFree(T); if (global_temporary_terms) { if (GlobalTemporaryTerms == NULL) { mexPrintf("GlobalTemporaryTerms is NULL\n"); mexEvalString("drawnow;"); } if (var != static_cast(mxGetNumberOfElements(GlobalTemporaryTerms))) GlobalTemporaryTerms = mxCreateDoubleMatrix(var, 1, mxREAL); T = mxGetPr(GlobalTemporaryTerms); } else { T = static_cast(mxMalloc(var*sizeof(double))); test_mxMalloc(T, __LINE__, __FILE__, __func__, var*sizeof(double)); } if (block >= 0) it_code = code_liste.begin() + code.get_begin_block(block); else it_code++; break; default: ostringstream tmp; tmp << " in compute_blocks, unknown command " << it_code->first << " (block=" << Block_Count << ")\n"; throw FatalExceptionHandling(tmp.str()); } } max_res = max_res_local; max_res_idx = max_res_idx_local; Close_SaveCode(); return true; } string Interpreter::elastic(string str, unsigned int len, bool left) { if (str.length() > len) return str; else { int diff = len - str.length(); if (diff % 2 == 0) { if (left) { //mexPrintf("(1) diff=%d\n",diff); str.insert(str.end(), diff-1, ' '); str.insert(str.begin(), 1, ' '); } else { str.insert(str.end(), diff/2, ' '); str.insert(str.begin(), diff/2, ' '); } } else { if (left) { //mexPrintf("(2) diff=%d\n",diff); str.insert(str.end(), diff-1, ' '); str.insert(str.begin(), 1, ' '); } else { str.insert(str.end(), ceil(diff/2), ' '); str.insert(str.begin(), ceil(diff/2+1), ' '); } } return str; } } bool Interpreter::extended_path(string file_name, string bin_basename, bool evaluate, int block, int &nb_blocks, int nb_periods, vector sextended_path, vector sconstrained_extended_path, vector dates, table_conditional_global_type table_conditional_global) { CodeLoad code; ReadCodeFile(file_name, code); it_code = code_liste.begin(); it_code_type Init_Code = code_liste.begin(); /*size_t size_of_direction = y_size*(periods + y_kmax + y_kmin)*sizeof(double); double *y_save = (double *) mxMalloc(size_of_direction); double *x_save = (double *) mxMalloc((periods + y_kmax + y_kmin) * col_x *sizeof(double));*/ size_t size_of_direction = y_size*col_y*sizeof(double); double *y_save = static_cast(mxMalloc(size_of_direction)); test_mxMalloc(y_save, __LINE__, __FILE__, __func__, size_of_direction); double *x_save = static_cast(mxMalloc(nb_row_x * col_x *sizeof(double))); test_mxMalloc(x_save, __LINE__, __FILE__, __func__, nb_row_x * col_x *sizeof(double)); vector_table_conditional_local_type vector_table_conditional_local; vector_table_conditional_local.clear(); int endo_name_length_l = endo_name_length; for (int j = 0; j < col_x* nb_row_x; j++) { x_save[j] = x[j]; x[j] = 0; } for (int j = 0; j < col_x; j++) x[y_kmin + j * nb_row_x] = x_save[y_kmin + j * nb_row_x]; for (int i = 0; i < y_size * col_y; i++) y_save[i] = y[i]; if (endo_name_length_l < 8) endo_name_length_l = 8; bool old_print_it = print_it; print_it = false; ostringstream res1; res1 << std::scientific << 2.54656875434865131; int real_max_length = res1.str().length(); int date_length = dates[0].length(); int table_length = 2 + date_length + 3 + endo_name_length_l + 3 + real_max_length + 3 + 3 + 2 + 6 + 2; string line; line.insert(line.begin(), table_length, '-'); line.insert(line.length(), "\n"); if (old_print_it) { mexPrintf("\nExtended Path simulation:\n"); mexPrintf("-------------------------\n"); mexPrintf(line.c_str()); string title = "|" + elastic("date", date_length+2, false) + "|" + elastic("variable", endo_name_length_l+2, false) + "|" + elastic("max. value", real_max_length+2, false) + "| iter. |" + elastic("cvg", 5, false) + "|\n"; mexPrintf(title.c_str()); mexPrintf(line.c_str()); } for (int t = 0; t < nb_periods; t++) { nb_blocks = 0; previous_block_exogenous.clear(); if (old_print_it) { mexPrintf("|%s|", elastic(dates[t], date_length+2, false).c_str()); mexEvalString("drawnow;"); } for (vector::const_iterator it = sextended_path.begin(); it != sextended_path.end(); it++) { x[y_kmin + (it->exo_num - 1) * /*(nb_periods + y_kmax + y_kmin)*/ nb_row_x] = it->value[t]; } it_code = Init_Code; vector_table_conditional_local.clear(); if (table_conditional_global.size()) vector_table_conditional_local = table_conditional_global[t]; if (t < nb_periods) MainLoop(bin_basename, code, evaluate, block, false, true, sconstrained_extended_path, vector_table_conditional_local); else MainLoop(bin_basename, code, evaluate, block, true, true, sconstrained_extended_path, vector_table_conditional_local); for (int j = 0; j < y_size; j++) { y_save[j + (t + y_kmin) * y_size] = y[j + y_kmin * y_size]; if (y_kmin > 0) y[j] = y[j + y_kmin * y_size]; } for (int j = 0; j < col_x; j++) { x_save[t + y_kmin + j * nb_row_x] = x[y_kmin + j * nb_row_x]; if (t < nb_periods) x[y_kmin + j * nb_row_x] = x_save[t + 1 + y_kmin + j * nb_row_x]; } if (old_print_it) { ostringstream res, res1; for (unsigned int i = 0; i < endo_name_length; i++) if (P_endo_names[CHAR_LENGTH*(max_res_idx+i*y_size)] != ' ') res << P_endo_names[CHAR_LENGTH*(max_res_idx+i*y_size)]; res1 << std::scientific << max_res; mexPrintf("%s|%s| %4d | x |\n", elastic(res.str(), endo_name_length_l+2, true).c_str(), elastic(res1.str(), real_max_length+2, false).c_str(), iter); mexPrintf(line.c_str()); mexEvalString("drawnow;"); } } print_it = old_print_it; /*for (int j = 0; j < y_size; j++) { for(int k = nb_periods; k < periods; k++) y_save[j + (k + y_kmin) * y_size] = y[ j + ( k - (nb_periods-1) + y_kmin) * y_size]; }*/ for (int i = 0; i < y_size * col_y; i++) y[i] = y_save[i]; for (int j = 0; j < col_x * nb_row_x; j++) x[j] = x_save[j]; if (Init_Code->second) mxFree(Init_Code->second); if (y_save) mxFree(y_save); if (x_save) mxFree(x_save); nb_blocks = Block_Count+1; if (T && !global_temporary_terms) mxFree(T); return true; } bool Interpreter::compute_blocks(string file_name, string bin_basename, bool evaluate, int block, int &nb_blocks) { CodeLoad code; ReadCodeFile(file_name, code); //The big loop on intructions it_code = code_liste.begin(); it_code_type Init_Code = it_code; vector s_plan_junk; vector_table_conditional_local_type vector_table_conditional_local_junk; MainLoop(bin_basename, code, evaluate, block, true, false, s_plan_junk, vector_table_conditional_local_junk); mxFree(Init_Code->second); nb_blocks = Block_Count+1; if (T && !global_temporary_terms) mxFree(T); return true; }