1 /* 2 Qalculate (library) 3 4 Copyright (C) 2003-2007, 2008, 2016-2019 Hanna Knutsson (hanna.knutsson@protonmail.com) 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2 of the License, or 9 (at your option) any later version. 10 */ 11 12 #ifndef MATHSTRUCTURE_SUPPORT_H 13 #define MATHSTRUCTURE_SUPPORT_H 14 15 #include "support.h" 16 17 #include "MathStructure.h" 18 19 #define SWAP_CHILDREN(i1, i2) {MathStructure *swap_mstruct = v_subs[v_order[i1]]; v_subs[v_order[i1]] = v_subs[v_order[i2]]; v_subs[v_order[i2]] = swap_mstruct;} 20 #define CHILD_TO_FRONT(i) v_order.insert(v_order.begin(), v_order[i]); v_order.erase(v_order.begin() + (i + 1)); 21 #define SET_CHILD_MAP(i) setToChild(i + 1, true); 22 #define SET_MAP(o) set(o, true); 23 #define SET_MAP_NOCOPY(o) set_nocopy(o, true); 24 #define MERGE_APPROX_AND_PREC(o) if(!b_approx && o.isApproximate()) b_approx = true; if(o.precision() > 0 && (i_precision < 1 || o.precision() < i_precision)) i_precision = o.precision(); 25 #define CHILD_UPDATED(i) if(!b_approx && CHILD(i).isApproximate()) b_approx = true; if(CHILD(i).precision() > 0 && (i_precision < 1 || CHILD(i).precision() < i_precision)) i_precision = CHILD(i).precision(); 26 #define CHILDREN_UPDATED for(size_t child_i = 0; child_i < SIZE; child_i++) {if(!b_approx && CHILD(child_i).isApproximate()) b_approx = true; if(CHILD(child_i).precision() > 0 && (i_precision < 1 || CHILD(child_i).precision() < i_precision)) i_precision = CHILD(child_i).precision();} 27 28 #define APPEND(o) v_order.push_back(v_subs.size()); v_subs.push_back(new MathStructure(o)); if(!b_approx && o.isApproximate()) b_approx = true; if(o.precision() > 0 && (i_precision < 1 || o.precision() < i_precision)) i_precision = o.precision(); 29 #define APPEND_NEW(o) {v_order.push_back(v_subs.size()); MathStructure *m_append_new = new MathStructure(o); v_subs.push_back(m_append_new); if(!b_approx && m_append_new->isApproximate()) b_approx = true; if(m_append_new->precision() > 0 && (i_precision < 1 || m_append_new->precision() < i_precision)) i_precision = m_append_new->precision();} 30 #define APPEND_COPY(o) v_order.push_back(v_subs.size()); v_subs.push_back(new MathStructure(*(o))); if(!b_approx && (o)->isApproximate()) b_approx = true; if((o)->precision() > 0 && (i_precision < 1 || (o)->precision() < i_precision)) i_precision = (o)->precision(); 31 #define APPEND_POINTER(o) v_order.push_back(v_subs.size()); v_subs.push_back(o); if(!b_approx && (o)->isApproximate()) b_approx = true; if((o)->precision() > 0 && (i_precision < 1 || (o)->precision() < i_precision)) i_precision = (o)->precision(); 32 #define APPEND_REF(o) v_order.push_back(v_subs.size()); v_subs.push_back(o); (o)->ref(); if(!b_approx && (o)->isApproximate()) b_approx = true; if((o)->precision() > 0 && (i_precision < 1 || (o)->precision() < i_precision)) i_precision = (o)->precision(); 33 #define PREPEND(o) v_order.insert(v_order.begin(), v_subs.size()); v_subs.push_back(new MathStructure(o)); if(!b_approx && o.isApproximate()) b_approx = true; if(o.precision() > 0 && (i_precision < 1 || o.precision() < i_precision)) i_precision = o.precision(); 34 #define PREPEND_REF(o) v_order.insert(v_order.begin(), v_subs.size()); v_subs.push_back(o); (o)->ref(); if(!b_approx && (o)->isApproximate()) b_approx = true; if((o)->precision() > 0 && (i_precision < 1 || (o)->precision() < i_precision)) i_precision = (o)->precision(); 35 #define INSERT_REF(o, i) v_order.insert(v_order.begin() + i, v_subs.size()); v_subs.push_back(o); (o)->ref(); if(!b_approx && (o)->isApproximate()) b_approx = true; if((o)->precision() > 0 && (i_precision < 1 || (o)->precision() < i_precision)) i_precision = (o)->precision(); 36 #define CLEAR v_order.clear(); for(size_t i = 0; i < v_subs.size(); i++) {v_subs[i]->unref();} v_subs.clear(); 37 //#define REDUCE(v_size) for(size_t v_index = v_size; v_index < v_order.size(); v_index++) {v_subs[v_order[v_index]]->unref(); v_subs.erase(v_subs.begin() + v_order[v_index]);} v_order.resize(v_size); 38 #define REDUCE(v_size) {std::vector<size_t> v_tmp; v_tmp.resize(SIZE, 0); for(size_t v_index = v_size; v_index < v_order.size(); v_index++) {v_subs[v_order[v_index]]->unref(); v_subs[v_order[v_index]] = NULL; v_tmp[v_order[v_index]] = 1;} v_order.resize(v_size); for(std::vector<MathStructure*>::iterator v_it = v_subs.begin(); v_it != v_subs.end();) {if(*v_it == NULL) v_it = v_subs.erase(v_it); else ++v_it;} size_t i_change = 0; for(size_t v_index = 0; v_index < v_tmp.size(); v_index++) {if(v_tmp[v_index] == 1) i_change++; v_tmp[v_index] = i_change;} for(size_t v_index = 0; v_index < v_order.size(); v_index++) v_order[v_index] -= v_tmp[v_index];} 39 #define CHILD(v_index) (*v_subs[v_order[v_index]]) 40 #define SIZE v_order.size() 41 #define LAST (*v_subs[v_order[v_order.size() - 1]]) 42 #define ERASE(v_index) v_subs[v_order[v_index]]->unref(); v_subs.erase(v_subs.begin() + v_order[v_index]); for(size_t v_index2 = 0; v_index2 < v_order.size(); v_index2++) {if(v_order[v_index2] > v_order[v_index]) v_order[v_index2]--;} v_order.erase(v_order.begin() + (v_index)); 43 44 #define IS_REAL(o) (o.isNumber() && o.number().isReal()) 45 #define IS_RATIONAL(o) (o.isNumber() && o.number().isRational()) 46 47 #define IS_A_SYMBOL(o) ((o.isSymbolic() || o.isVariable() || o.isFunction()) && o.representsScalar()) 48 49 #define POWER_CLEAN(o) if(o[1].isOne()) {o.setToChild(1);} else if(o[1].isZero()) {o.set(1, 1, 0);} 50 51 #define VALID_ROOT(o) (o.size() == 2 && o[1].isNumber() && o[1].number().isInteger() && o[1].number().isPositive()) 52 #define THIS_VALID_ROOT (SIZE == 2 && CHILD(1).isNumber() && CHILD(1).number().isInteger() && CHILD(1).number().isPositive()) 53 54 #define FUNCTION_PROTECTED(evalops, id) (evalops.protected_function != NULL && evalops.protected_function == CALCULATOR->getFunctionById(id)) 55 56 void printRecursive(const MathStructure &mstruct); 57 58 std::string format_and_print(const MathStructure &mstruct); 59 60 struct sym_desc { 61 MathStructure sym; 62 Number deg_a; 63 Number deg_b; 64 Number ldeg_a; 65 Number ldeg_b; 66 Number max_deg; 67 size_t max_lcnops; 68 bool operator<(const sym_desc &x) const; 69 }; 70 typedef std::vector<sym_desc> sym_desc_vec; 71 72 bool polynomial_long_division(const MathStructure &mnum, const MathStructure &mden, const MathStructure &xvar_pre, MathStructure &mquotient, MathStructure &mrem, const EvaluationOptions &eo, bool check_args = false, bool for_newtonraphson = false); 73 void integer_content(const MathStructure &mpoly, Number &icontent); 74 bool interpolate(const MathStructure &gamma, const Number &xi, const MathStructure &xvar, MathStructure &minterp, const EvaluationOptions &eo); 75 bool get_first_symbol(const MathStructure &mpoly, MathStructure &xvar); 76 bool divide_in_z(const MathStructure &mnum, const MathStructure &mden, MathStructure &mquotient, const sym_desc_vec &sym_stats, size_t var_i, const EvaluationOptions &eo); 77 bool prem(const MathStructure &mnum, const MathStructure &mden, const MathStructure &xvar, MathStructure &mrem, const EvaluationOptions &eo, bool check_args = true); 78 bool sr_gcd(const MathStructure &m1, const MathStructure &m2, MathStructure &mgcd, const sym_desc_vec &sym_stats, size_t var_i, const EvaluationOptions &eo); 79 void polynomial_smod(const MathStructure &mpoly, const Number &xi, MathStructure &msmod, const EvaluationOptions &eo, MathStructure *mparent = NULL, size_t index_smod = 0); 80 bool heur_gcd(const MathStructure &m1, const MathStructure &m2, MathStructure &mgcd, const EvaluationOptions &eo, MathStructure *ca, MathStructure *cb, const sym_desc_vec &sym_stats, size_t var_i); 81 void add_symbol(const MathStructure &mpoly, sym_desc_vec &v); 82 void collect_symbols(const MathStructure &mpoly, sym_desc_vec &v); 83 void add_symbol(const MathStructure &mpoly, std::vector<MathStructure> &v); 84 void collect_symbols(const MathStructure &mpoly, std::vector<MathStructure> &v); 85 void get_symbol_stats(const MathStructure &m1, const MathStructure &m2, sym_desc_vec &v); 86 bool sqrfree(MathStructure &mpoly, const EvaluationOptions &eo); 87 bool sqrfree(MathStructure &mpoly, const std::vector<MathStructure> &symbols, const EvaluationOptions &eo); 88 bool simplify_functions(MathStructure &mstruct, const EvaluationOptions &eo, const EvaluationOptions &feo, const MathStructure &x_var = m_undefined); 89 bool factorize_find_multiplier(const MathStructure &mstruct, MathStructure &mnew, MathStructure &factor_mstruct, bool only_units = false); 90 bool is_unit_multiexp(const MathStructure &mstruct); 91 bool has_approximate_relation_to_base(Unit *u, bool do_intervals = true); 92 bool contains_approximate_relation_to_base(const MathStructure &m, bool do_intervals = true); 93 bool contains_diff_for(const MathStructure &m, const MathStructure &x_var); 94 bool separate_unit_vars(MathStructure &m, const EvaluationOptions &eo, bool only_approximate, bool dry_run = false); 95 void lcm_of_coefficients_denominators(const MathStructure &e, Number &nlcm); 96 void multiply_lcm(const MathStructure &e, const Number &lcm, MathStructure &mmul, const EvaluationOptions &eo); 97 bool do_simplification(MathStructure &mstruct, const EvaluationOptions &eo, bool combine_divisions = true, bool only_gcd = false, bool combine_only = false, bool recursive = true, bool limit_size = false, int i_run = 1); 98 bool warn_about_assumed_not_value(const MathStructure &mstruct, const MathStructure &mvalue, const EvaluationOptions &eo); 99 bool warn_about_denominators_assumed_nonzero(const MathStructure &mstruct, const EvaluationOptions &eo); 100 bool warn_about_denominators_assumed_nonzero_or_positive(const MathStructure &mstruct, const MathStructure &mstruct2, const EvaluationOptions &eo); 101 bool warn_about_denominators_assumed_nonzero_llgg(const MathStructure &mstruct, const MathStructure &mstruct2, const MathStructure &mstruct3, const EvaluationOptions &eo); 102 bool is_differentiable(const MathStructure &m); 103 int test_comparisons(const MathStructure &msave, MathStructure &mthis, const MathStructure &x_var, const EvaluationOptions &eo, bool sub = false, int alt = 0); 104 bool replace_function(MathStructure &m, MathFunction *f1, MathFunction *f2, const EvaluationOptions &eo); 105 bool replace_intervals_f(MathStructure &mstruct); 106 bool replace_f_interval(MathStructure &mstruct, const EvaluationOptions &eo); 107 bool fix_intervals(MathStructure &mstruct, const EvaluationOptions &eo, bool *failed = NULL, long int min_precision = 2, bool function_middle = false); 108 bool set_uncertainty(MathStructure &mstruct, MathStructure &munc, const EvaluationOptions &eo = default_evaluation_options, bool do_eval = false); 109 bool create_interval(MathStructure &mstruct, const MathStructure &m1, const MathStructure &m2); 110 bool combine_powers(MathStructure &m, const MathStructure &x_var, const EvaluationOptions &eo); 111 bool contains_angle_unit(const MathStructure &m, const ParseOptions &po); 112 bool has_predominately_negative_sign(const MathStructure &mstruct); 113 void negate_struct(MathStructure &mstruct); 114 bool test_eval(MathStructure &mtest, const EvaluationOptions &eo); 115 bool has_interval_unknowns(MathStructure &m); 116 bool flattenMultiplication(MathStructure &mstruct); 117 void idm1(const MathStructure &mnum, bool &bfrac, bool &bint); 118 void idm2(const MathStructure &mnum, bool &bfrac, bool &bint, Number &nr); 119 int idm3(MathStructure &mnum, Number &nr, bool expand); 120 bool combination_factorize(MathStructure &mstruct); 121 bool replace_interval_unknowns(MathStructure &m, bool do_assumptions = false); 122 bool remove_rad_unit(MathStructure &m, const EvaluationOptions &eo, bool top = true); 123 int contains_ass_intval(const MathStructure &m); 124 int compare_check_incompability(MathStructure *mtest); 125 bool calculate_nondifferentiable_functions(MathStructure &m, const EvaluationOptions &eo, bool recursive = true, bool do_unformat = true, int i_type = 0); 126 bool function_differentiable(MathFunction *o_function); 127 bool montecarlo(const MathStructure &minteg, Number &nvalue, const MathStructure &x_var, const EvaluationOptions &eo, Number a, Number b, Number n); 128 bool romberg(const MathStructure &minteg, Number &nvalue, const MathStructure &x_var, const EvaluationOptions &eo, Number a, Number b, long int max_steps = -1, long int min_steps = 6, bool safety_measures = true); 129 bool sync_approximate_units(MathStructure &m, const EvaluationOptions &feo, std::vector<KnownVariable*> *vars = NULL, std::vector<MathStructure> *uncs = NULL, bool do_intervals = true); 130 void fix_to_struct(MathStructure &m); 131 int has_information_unit(const MathStructure &m, bool top = true); 132 133 void print_dual(const MathStructure &mresult, const std::string &original_expression, const MathStructure &mparse, MathStructure &mexact, std::string &result_str, std::vector<std::string> &results_v, PrintOptions &po, const EvaluationOptions &evalops, AutomaticFractionFormat auto_frac, AutomaticApproximation auto_approx, bool cplx_angle = false, bool *exact_cmp = NULL, bool b_parsed = true, bool format = false, int colorize = 0, int tagtype = TAG_TYPE_HTML, int max_length = -1); 134 void calculate_dual_exact(MathStructure &mstruct_exact, MathStructure *mstruct, const std::string &original_expression, const MathStructure *parsed_mstruct, EvaluationOptions &evalops, AutomaticApproximation auto_approx, int msecs = 0, int max_size = 10); 135 136 #endif 137 138