diff --git a/matlab/cherrypick.m b/matlab/cherrypick.m index 85bfe6af4e01de4f3b182c7e617c732b69b50c71..9e1727b88381fdb6c02d3f43822e39c2c9b83e46 100644 --- a/matlab/cherrypick.m +++ b/matlab/cherrypick.m @@ -73,134 +73,143 @@ plist = {}; elist = {}; xlist = {}; -for i=1:length(eqtags) - rhs = []; - lhs = []; - % Get equation number. - eqnum = get_equation_number_by_tag(eqtags{i}, M_); - % Get the original equation. - [LHS, RHS] = get_lhs_and_rhs(eqtags{i}, M_, true, json); - % Get the parameters, endogenous and exogenous variables in the current equation. - [pnames, ~, xnames] = get_variables_and_parameters_in_equation(LHS, RHS, M_); - lhs_expression = LHS; - LHS = get_variables_and_parameters_in_expression(LHS); - enames = LHS; - if length(LHS)>1 - error('Expressions with more than one variable on the LHS are not allowed.') - end - LHS = LHS{1}; - if isrename - [variable_has_to_be_renamed, id] = ismember(eqnum, [rename{:,1}]); - if variable_has_to_be_renamed - TMP = strsplit(rename{id,2}, ','); - for j=1:length(TMP) - tmp = strsplit(TMP{j}, '->'); - lhs_expression = exactstrrep(lhs_expression, tmp{1}, tmp{2}); - RHS = exactstrrep(RHS, tmp{1}, tmp{2}); - rep = strcmp(tmp{1}, enames); - if any(rep) - enames(rep) = tmp(2); +try + for i=1:length(eqtags) + rhs = []; + lhs = []; + % Get equation number. + eqnum = get_equation_number_by_tag(eqtags{i}, M_); + % Get the original equation. + [LHS, RHS] = get_lhs_and_rhs(eqtags{i}, M_, true, json); + % Get the parameters, endogenous and exogenous variables in the current equation. + [pnames, ~, xnames] = get_variables_and_parameters_in_equation(LHS, RHS, M_); + lhs_expression = LHS; + LHS = get_variables_and_parameters_in_expression(LHS); + enames = LHS; + if length(LHS)>1 + error('Expressions with more than one variable on the LHS are not allowed.') + end + LHS = LHS{1}; + if isrename + [variable_has_to_be_renamed, id] = ismember(eqnum, [rename{:,1}]); + if variable_has_to_be_renamed + TMP = strsplit(rename{id,2}, ','); + for j=1:length(TMP) + tmp = strsplit(TMP{j}, '->'); + lhs_expression = exactstrrep(lhs_expression, tmp{1}, tmp{2}); + RHS = exactstrrep(RHS, tmp{1}, tmp{2}); + rep = strcmp(tmp{1}, enames); + if any(rep) + enames(rep) = tmp(2); + end + rep = strcmp(tmp{1}, xnames); + if any(rep) + xnames(rep) = tmp(2); + end end - rep = strcmp(tmp{1}, xnames); - if any(rep) - xnames(rep) = tmp(2); + end + end + % Remove residual from equation if required. + if noresids + exogenous_variables_to_be_removed = ~ismember(xnames, M_.simulation_exo_names); + if any(exogenous_variables_to_be_removed) + switch sum(exogenous_variables_to_be_removed) + case 1 + RHS = regexprep(RHS, sprintf('\\ *\\+\\ *%s', xnames{exogenous_variables_to_be_removed}), ''); + RHS = regexprep(RHS, sprintf('%s', xnames{exogenous_variables_to_be_removed}), ''); + case 0 + % Nothing to do. + otherwise + error('Cannot remove more than one exogenous variable in an equation (%s).', eqtags{i}) end + xnames = setdiff(xnames, xnames{exogenous_variables_to_be_removed}); end end - end - % Remove residual from equation if required. - if noresids - exogenous_variables_to_be_removed = ~ismember(xnames, M_.simulation_exo_names); - if any(exogenous_variables_to_be_removed) - switch sum(exogenous_variables_to_be_removed) - case 1 - RHS = regexprep(RHS, sprintf('\\ *\\+\\ *%s', xnames{exogenous_variables_to_be_removed}), ''); - RHS = regexprep(RHS, sprintf('%s', xnames{exogenous_variables_to_be_removed}), ''); - case 0 - % Nothing to do. - otherwise - error('Cannot remove more than one exogenous variable in an equation (%s).', eqtags{i}) + % Unroll expectation terms if any. + isvar = regexp(RHS, 'var_expectation\(model_name = (?<name>\w+)\)', 'names'); + ispac = regexp(RHS, 'pac_expectation\(model_name = (?<name>\w+)\)', 'names'); + if ~isempty(isvar) + rhs = write_expectations(eqtags{i}, isvar.name, 'var'); + lhs = sprintf('%s_VE', eqtags{i}); + RHS = strrep(RHS, sprintf('var_expectation(model_name = %s)', isvar.name), lhs); + end + if ~isempty(ispac) + [rhs, growthneutralitycorrection] = write_expectations(eqtags{i}, ispac.name, 'pac'); + lhs = sprintf('%s_PE', eqtags{i}); + RHS = strrep(RHS, sprintf('pac_expectation(model_name = %s)', ispac.name), lhs); + if ~isempty(growthneutralitycorrection) + RHS = sprintf('%s + %s', RHS, growthneutralitycorrection); end - xnames = setdiff(xnames, xnames{exogenous_variables_to_be_removed}); end - end - % Unroll expectation terms if any. - isvar = regexp(RHS, 'var_expectation\(model_name = (?<name>\w+)\)', 'names'); - ispac = regexp(RHS, 'pac_expectation\(model_name = (?<name>\w+)\)', 'names'); - if ~isempty(isvar) - rhs = write_expectations(eqtags{i}, isvar.name, 'var'); - lhs = sprintf('%s_VE', eqtags{i}); - RHS = strrep(RHS, sprintf('var_expectation(model_name = %s)', isvar.name), lhs); - end - if ~isempty(ispac) - [rhs, growthneutralitycorrection] = write_expectations(eqtags{i}, ispac.name, 'pac'); - lhs = sprintf('%s_PE', eqtags{i}); - RHS = strrep(RHS, sprintf('pac_expectation(model_name = %s)', ispac.name), lhs); - if ~isempty(growthneutralitycorrection) - RHS = sprintf('%s + %s', RHS, growthneutralitycorrection); + % Print equation for unrolled PAC/VAR-expectation and update + % list of parameters and endogenous variables (if any). + if ~isempty(rhs) + % Note that the call to get_variables_and_parameters_in_equation() + % will not return the lhs variable in expectation_enames since + % the name is created on the fly and is not a member of M_.endo_names. + expectation_pnames = get_variables_and_parameters_in_equation('', rhs, M_); + expectation_enames = get_variables_and_parameters_in_expression(lhs); + expectation_xnames = get_variables_and_parameters_in_expression(rhs); + pnames = union(pnames, expectation_pnames); + xnames = union(xnames, setdiff(expectation_xnames, expectation_pnames)); + enames = union(enames, expectation_enames); + fprintf(fid, '[name=''%s'']\n', lhs); + fprintf(fid, '%s = %s;\n\n', lhs, rhs); + else + pRHS = get_variables_and_parameters_in_equation('', RHS, M_); + xRHS = get_variables_and_parameters_in_expression(RHS); + xnames = union(xnames, setdiff(xRHS, pRHS)); + pnames = union(pnames, pRHS); end - end - % Print equation for unrolled PAC/VAR-expectation and update - % list of parameters and endogenous variables (if any). - if ~isempty(rhs) - % Note that the call to get_variables_and_parameters_in_equation() - % will not return the lhs variable in expectation_enames since - % the name is created on the fly and is not a member of M_.endo_names. - expectation_pnames = get_variables_and_parameters_in_equation('', rhs, M_); - expectation_enames = get_variables_and_parameters_in_expression(lhs); - expectation_xnames = get_variables_and_parameters_in_expression(rhs); - pnames = union(pnames, expectation_pnames); - xnames = union(xnames, setdiff(expectation_xnames, expectation_pnames)); - enames = union(enames, expectation_enames); - fprintf(fid, '[name=''%s'']\n', lhs); - fprintf(fid, '%s = %s;\n\n', lhs, rhs); - else - pRHS = get_variables_and_parameters_in_equation('', RHS, M_); - xRHS = get_variables_and_parameters_in_expression(RHS); - xnames = union(xnames, setdiff(xRHS, pRHS)); - pnames = union(pnames, pRHS); - end - % Update pnames, enames and xnames if PAC with growth neutrality correction. - if ~isempty(ispac) && ~isempty(growthneutralitycorrection) - [growthneutralitycorrection_pnames, ... + % Update pnames, enames and xnames if PAC with growth neutrality correction. + if ~isempty(ispac) && ~isempty(growthneutralitycorrection) + [growthneutralitycorrection_pnames, ... growthneutralitycorrection_enames, ... growthneutralitycorrection_xnames] = get_variables_and_parameters_in_equation('', growthneutralitycorrection, M_); - if ~isempty(growthneutralitycorrection_pnames) - pnames = union(pnames, growthneutralitycorrection_pnames); - end - if ~isempty(growthneutralitycorrection_enames) - xnames = union(xnames, growthneutralitycorrection_enames); - end - if ~isempty(growthneutralitycorrection_xnames) - xnames = union(xnames, growthneutralitycorrection_xnames); - end - end - % Print tags - if iscell(json.model) - tfields = fieldnames(json.model{eqnum}.tags); - tags = sprintf('%s=''%s''', tfields{1}, json.model{eqnum}.tags.(tfields{1})); - for j=2:length(tfields) - if ~isempty(json.model{eqnum}.tags.(tfields{j})) - tags = sprintf('%s, %s=''%s''', tags, tfields{j}, json.model{eqnum}.tags.(tfields{j})); + if ~isempty(growthneutralitycorrection_pnames) + pnames = union(pnames, growthneutralitycorrection_pnames); + end + if ~isempty(growthneutralitycorrection_enames) + xnames = union(xnames, growthneutralitycorrection_enames); + end + if ~isempty(growthneutralitycorrection_xnames) + xnames = union(xnames, growthneutralitycorrection_xnames); end end - else - tfields = fieldnames(json.model.tags); - tags = sprintf('%s=''%s''', tfields{1}, json.model.tags.(tfields{1})); - for j=2:length(tfields) - if ~isempty(json.model.tags.(tfields{j})) - tags = sprintf('%s, %s=''%s''', tags, tfields{j}, json.model.tags.(tfields{j})); + % Print tags + if iscell(json.model) + tfields = fieldnames(json.model{eqnum}.tags); + tags = sprintf('%s=''%s''', tfields{1}, json.model{eqnum}.tags.(tfields{1})); + for j=2:length(tfields) + if ~isempty(json.model{eqnum}.tags.(tfields{j})) + tags = sprintf('%s, %s=''%s''', tags, tfields{j}, json.model{eqnum}.tags.(tfields{j})); + end + end + else + tfields = fieldnames(json.model.tags); + tags = sprintf('%s=''%s''', tfields{1}, json.model.tags.(tfields{1})); + for j=2:length(tfields) + if ~isempty(json.model.tags.(tfields{j})) + tags = sprintf('%s, %s=''%s''', tags, tfields{j}, json.model.tags.(tfields{j})); + end end end + fprintf(fid, '[%s]\n', tags); + % Print equation. + fprintf(fid, '%s = %s;\n\n', lhs_expression, RHS); + % Update lists of parameters, endogenous variables and exogenous variables. + plist = union(plist, pnames); + elist = union(elist, enames); + xlist = union(xlist, xnames); end - fprintf(fid, '[%s]\n', tags); - % Print equation. - fprintf(fid, '%s = %s;\n\n', lhs_expression, RHS); - % Update lists of parameters, endogenous variables and exogenous variables. - plist = union(plist, pnames); - elist = union(elist, enames); - xlist = union(xlist, xnames); +catch e + fclose(fid); + fprintf(2, '%s\n', e.message) + fprintf(2, 'Delete ''%s'' file.\n', sprintf('%s/model.inc', outfold)) + delete(sprintf('%s/model.inc', outfold)) + return end + fclose(fid); % Export parameters