Beispiel #1
0
static ex tanh_eval(const ex & x)
{
	if (x.info(info_flags::numeric)) {

		// tanh(0) -> 0
		if (x.is_zero())
			return _ex0;

		// tanh(float) -> float
		if (!x.info(info_flags::crational))
			return tanh(ex_to<numeric>(x));

		// tanh() is odd
		if (x.info(info_flags::negative))
			return -tanh(-x);
	}
	
	if ((x/Pi).info(info_flags::numeric) &&
		ex_to<numeric>(x/Pi).real().is_zero())  // tanh(I*x) -> I*tan(x);
		return I*tan(x/I);
	
	if (is_exactly_a<function>(x)) {
		const ex &t = x.op(0);

		// tanh(atanh(x)) -> x
		if (is_ex_the_function(x, atanh))
			return t;

		// tanh(asinh(x)) -> x/sqrt(1+x^2)
		if (is_ex_the_function(x, asinh))
			return t*power(_ex1+power(t,_ex2),_ex_1_2);

		// tanh(acosh(x)) -> sqrt(x-1)*sqrt(x+1)/x
		if (is_ex_the_function(x, acosh))
			return sqrt(t-_ex1)*sqrt(t+_ex1)*power(t,_ex_1);
	}
	
	return tanh(x).hold();
}
Beispiel #2
0
static ex cosh_eval(const ex & x)
{
	if (x.info(info_flags::numeric)) {

		// cosh(0) -> 1
		if (x.is_zero())
			return _ex1;

		// cosh(float) -> float
		if (!x.info(info_flags::crational))
			return cosh(ex_to<numeric>(x));

		// cosh() is even
		if (x.info(info_flags::negative))
			return cosh(-x);
	}
	
	if ((x/Pi).info(info_flags::numeric) &&
		ex_to<numeric>(x/Pi).real().is_zero())  // cosh(I*x) -> cos(x)
		return cos(x/I);
	
	if (is_exactly_a<function>(x)) {
		const ex &t = x.op(0);

		// cosh(acosh(x)) -> x
		if (is_ex_the_function(x, acosh))
			return t;

		// cosh(asinh(x)) -> sqrt(1+x^2)
		if (is_ex_the_function(x, asinh))
			return sqrt(_ex1+power(t,_ex2));

		// cosh(atanh(x)) -> 1/sqrt(1-x^2)
		if (is_ex_the_function(x, atanh))
			return power(_ex1-power(t,_ex2),_ex_1_2);
	}
	
	return cosh(x).hold();
}
Beispiel #3
0
//
//  On return, lags is a GiNac::lst, where each element is a GiNac::lst
//  of length 4 containing {lagsym, variable_index + 1, var, lag_time}
//
void VectorField::convert_delay_to_lagvalue(ex& f, lst &lags)
{
    symbol t(IndependentVariable);
    exset dlist;
    f.find(delay(wild(1),wild(2)),dlist);
    for (exset::const_iterator iter = dlist.begin(); iter != dlist.end(); ++iter) {
        ex delayfunc = *iter;
        ex delayexpr = delayfunc.op(0);
        lst vars = FindVarsInEx(delayexpr);
        ex del = delayfunc.op(1);
        for (lst::const_iterator iter = vars.begin(); iter != vars.end(); ++iter) {
            ostringstream os;
            lst tmp;
            os << lags.nops() + 1;
            symbol lagsym("lag" + os.str());
            int vindex = FindVar(ex_to<symbol>(*iter));
            delayexpr = delayexpr.subs(*iter == lagsym);
            tmp = {lagsym, vindex + 1, *iter, del};
            lags.append(tmp);
        }
        f = f.subs(delayfunc == delayexpr);
    }
}
Beispiel #4
0
bealab::function<double(double)> makefun( const ex& fun, const symbol& x )
{
	FUNCP_CUBA fp;
	ex fun1 = fun.subs( Pi==pi );
	compile_ex( lst(fun1), lst(x), fp );
	return [fp]( double x )
	{
		int ndim  = 1;
		int ncomp = 1;
		double res;
		fp( &ndim, &x, &ncomp, &res );
		return res;
	};
}
Beispiel #5
0
static ex tan_series(const ex &x,
                     const relational &rel,
                     int order,
                     unsigned options)
{
	GINAC_ASSERT(is_a<symbol>(rel.lhs()));
	// method:
	// Taylor series where there is no pole falls back to tan_deriv.
	// On a pole simply expand sin(x)/cos(x).
	const ex x_pt = x.subs(rel, subs_options::no_pattern);
	if (!(2*x_pt/Pi).info(info_flags::odd))
		throw do_taylor();  // caught by function::series()
	// if we got here we have to care for a simple pole
	return (sin(x)/cos(x)).series(rel, order, options);
}
Beispiel #6
0
static ex eta_eval(const ex &x, const ex &y)
{
	// trivial:  eta(x,c) -> 0  if c is real and positive
	if (x.info(info_flags::positive) || y.info(info_flags::positive))
		return _ex0;

	if (x.info(info_flags::numeric) &&	y.info(info_flags::numeric)) {
		// don't call eta_evalf here because it would call Pi.evalf()!
		const numeric nx = ex_to<numeric>(x);
		const numeric ny = ex_to<numeric>(y);
		const numeric nxy = ex_to<numeric>(x*y);
		int cut = 0;
		if (nx.is_real() && nx.is_negative())
			cut -= 4;
		if (ny.is_real() && ny.is_negative())
			cut -= 4;
		if (nxy.is_real() && nxy.is_negative())
			cut += 4;
		return (I/4)*Pi*((csgn(-imag(nx))+1)*(csgn(-imag(ny))+1)*(csgn(imag(nxy))+1)-
		                 (csgn(imag(nx))+1)*(csgn(imag(ny))+1)*(csgn(-imag(nxy))+1)+cut);
	}
	
	return eta(x,y).hold();
}
Beispiel #7
0
static ex eta_evalf(const ex &x, const ex &y)
{
	// It seems like we basically have to replicate the eval function here,
	// since the expression might not be fully evaluated yet.
	if (x.info(info_flags::positive) || y.info(info_flags::positive))
		return _ex0;

	if (x.info(info_flags::numeric) &&	y.info(info_flags::numeric)) {
		const numeric nx = ex_to<numeric>(x);
		const numeric ny = ex_to<numeric>(y);
		const numeric nxy = ex_to<numeric>(x*y);
		int cut = 0;
		if (nx.is_real() && nx.is_negative())
			cut -= 4;
		if (ny.is_real() && ny.is_negative())
			cut -= 4;
		if (nxy.is_real() && nxy.is_negative())
			cut += 4;
		return evalf(I/4*Pi)*((csgn(-imag(nx))+1)*(csgn(-imag(ny))+1)*(csgn(imag(nxy))+1)-
		                      (csgn(imag(nx))+1)*(csgn(imag(ny))+1)*(csgn(-imag(nxy))+1)+cut);
	}

	return eta(x,y).hold();
}
Beispiel #8
0
static ex zeta1_series(const ex& m, const relational& rel, int order, unsigned options)
{
	// use taylor expansion everywhere except at the singularity at 1
	const numeric val = ex_to<numeric>(m.subs(rel, subs_options::no_pattern));
	if (val != 1)
		throw do_taylor();  // caught by function::series()
	// at 1, use the expansion with the stieltjes-constants
	ex ser = 1/(m-1);
	numeric fac = 1;
	for (int n = 0; n <= order; ++n) {
	  fac = fac.mul(n+1);
	  ser += pow(-1, n) * stieltjes(n) * pow(m-1, n) * fac.inverse();
	}
	return ser.series(rel, order, options);
}
Beispiel #9
0
static ex zeta1_evalf(const ex& x, PyObject* parent)
{
        /*
	if (is_exactly_a<lst>(x) && (x.nops()>1)) {

		// multiple zeta value
		const int count = x.nops();
		const lst& xlst = ex_to<lst>(x);
		std::vector<int> r(count);

		// check parameters and convert them
		auto it1 = xlst.begin();
		auto it2 = r.begin();
		do {
			if (!(*it1).info(info_flags::posint)) {
				return zeta(x).hold();
			}
			*it2 = ex_to<numeric>(*it1).to_int();
			it1++;
			it2++;
		} while (it2 != r.end());

		// check for divergence
		if (r[0] == 1) {
			return zeta(x).hold();
		}

		// decide on summation algorithm
		// this is still a bit clumsy
		int limit = 10;
		if ((r[0] < limit) || ((count > 3) && (r[1] < limit/2))) {
			return numeric(zeta_do_sum_Crandall(r));
		} else {
			return numeric(zeta_do_sum_simple(r));
		}
	}*/

	// single zeta value
	if (x == 1) {
		return UnsignedInfinity;
	} else	if (is_exactly_a<numeric>(x)) {
		try {
			return zeta(ex_to<numeric>(x.evalf(0, parent)));
		} catch (const dunno &e) { }
	}

	return zeta(x).hold();
}
Beispiel #10
0
static ex Order_eval(const ex & x)
{
	if (is_exactly_a<numeric>(x)) {
		// O(c) -> O(1) or 0
		if (!x.is_zero())
			return Order(_ex1).hold();
		else
			return _ex0;
	} else if (is_exactly_a<mul>(x)) {
		const mul &m = ex_to<mul>(x);
		// O(c*expr) -> O(expr)
		if (is_exactly_a<numeric>(m.op(m.nops() - 1)))
			return Order(x / m.op(m.nops() - 1)).hold();
	}
	return Order(x).hold();
}
Beispiel #11
0
void
Model_block::add_objective(const ex &obj, const ex &obj_eq, const ex &lambda, int l)
{
    m_obj_var = obj;
    m_obj_eq = obj_eq;
    m_obj_eq_in = obj_eq;
    m_obj_lm_in = lambda;
    if (m_obj_lm_in) {
        m_obj_lm = m_obj_lm_in;
    } else {
        m_obj_lm = ex("lambda__" + m_name + "_" + obj.str(DROP_IDX | DROP_T), 0);
        m_obj_lm = add_idx(m_obj_lm, m_i1);
        m_obj_lm = add_idx(m_obj_lm, m_i2);
        m_redlm.insert(m_obj_lm);
    }
    m_obj_line = l;
}
Beispiel #12
0
static ex zeta2_eval(const ex& m, const ex& s_)
{
	if (is_exactly_a<lst>(s_)) {
		const lst& s = ex_to<lst>(s_);
		for (const auto & elem : s) {
			if ((elem).info(info_flags::positive)) {
				continue;
			}
			return zeta(m, s_).hold();
		}
		return zeta(m);
	} else if (s_.info(info_flags::positive)) {
		return zeta(m);
	}

	return zeta(m, s_).hold();
}
Beispiel #13
0
static void zeta1_print_latex(const ex& m_, const print_context& c)
{
	c.s << "\\zeta(";
	if (is_a<lst>(m_)) {
		const lst& m = ex_to<lst>(m_);
		auto it = m.begin();
		(*it).print(c);
		it++;
		for (; it != m.end(); it++) {
			c.s << ",";
			(*it).print(c);
		}
	} else {
		m_.print(c);
	}
	c.s << ")";
}
Beispiel #14
0
static ex binomial_sym(const ex & x, const numeric & y)
{
	if (y.is_integer()) {
		if (y.is_nonneg_integer()) {
			const unsigned N = y.to_int();
			if (N == 0) return _ex1;
			if (N == 1) return x;
			ex t = x.expand();
			for (unsigned i = 2; i <= N; ++i)
				t = (t * (x + i - y - 1)).expand() / i;
			return t;
		} else
			return _ex0;
	}

	return binomial(x, y).hold();
}
Beispiel #15
0
static void
collect_term(ex_collect_priv_t& ec, const ex& e, const exvector& vars)
{
	if (e.is_zero())
		return;
	static const ex ex1(1);
	exp_vector_t key(vars.size());
	ex pre_coeff = e;
	for (std::size_t i = 0; i < vars.size(); ++i) {
		const int var_i_pow = pre_coeff.degree(vars[i]);
		key[i] = var_i_pow;
		pre_coeff = pre_coeff.coeff(vars[i], var_i_pow);
	}
	auto i = ec.find(key);
	if (i != ec.end())
		i->second += pre_coeff;
	else
		ec.insert(ex_collect_priv_t::value_type(key, pre_coeff));
}
Beispiel #16
0
void VectorField::CheckForDelay(const ex& f)
    {
    lst occurrences;
    if (f.find(delay(wild(1),wild(2)),occurrences))
        {
        IsDelay = true;
        for (lst::const_iterator iter = occurrences.begin(); iter != occurrences.end(); ++iter)
            {
            ex del = iter->op(1);
            AddDelay(del);
            if (del.has(IndVar))
                HasNonconstantDelay = true;  // time-dependent delay
            for (lst::const_iterator viter = varname_list.begin(); viter != varname_list.end(); ++viter)
                {
                if (del.has(*viter))
                    HasNonconstantDelay = true; // state-dependent delay
                }
            }
        }
    }
Beispiel #17
0
static ex log_expand(const ex & arg, unsigned options)
{
	if ((options & expand_options::expand_transcendental)
		&& is_exactly_a<mul>(arg) && !arg.info(info_flags::indefinite)) {
		exvector sumseq;
		exvector prodseq;
		sumseq.reserve(arg.nops());
		prodseq.reserve(arg.nops());
		bool possign=true;

		// searching for positive/negative factors
		for (const_iterator i = arg.begin(); i != arg.end(); ++i) {
			ex e;
			if (options & expand_options::expand_function_args)
				e=i->expand(options);
			else
				e=*i;
			if (e.info(info_flags::positive))
				sumseq.push_back(log(e));
			else if (e.info(info_flags::negative)) {
				sumseq.push_back(log(-e));
				possign = !possign;
			} else
				prodseq.push_back(e);
		}

		if (sumseq.size() > 0) {
			ex newarg;
			if (options & expand_options::expand_function_args)
				newarg=((possign?_ex1:_ex_1)*mul(prodseq)).expand(options);
			else {
				newarg=(possign?_ex1:_ex_1)*mul(prodseq);
				ex_to<basic>(newarg).setflag(status_flags::purely_indefinite);
			}
			return add(sumseq)+log(newarg);
		} else {
			if (!(options & expand_options::expand_function_args))
				ex_to<basic>(arg).setflag(status_flags::purely_indefinite);
		}
	}

	if (options & expand_options::expand_function_args)
		return log(arg.expand(options)).hold();
	else
		return log(arg).hold();
}
Beispiel #18
0
static ex atan_series(const ex &arg,
                      const relational &rel,
                      int order,
                      unsigned options)
{
	GINAC_ASSERT(is_a<symbol>(rel.lhs()));
	// method:
	// Taylor series where there is no pole or cut falls back to atan_deriv.
	// There are two branch cuts, one runnig from I up the imaginary axis and
	// one running from -I down the imaginary axis.  The points I and -I are
	// poles.
	// On the branch cuts and the poles series expand
	//     (log(1+I*x)-log(1-I*x))/(2*I)
	// instead.
	const ex arg_pt = arg.subs(rel, subs_options::no_pattern);
	if (!(I*arg_pt).info(info_flags::real))
		throw do_taylor();     // Re(x) != 0
	if ((I*arg_pt).info(info_flags::real) && abs(I*arg_pt)<_ex1)
		throw do_taylor();     // Re(x) == 0, but abs(x)<1
	// care for the poles, using the defining formula for atan()...
	if (arg_pt.is_equal(I) || arg_pt.is_equal(-I))
		return ((log(1+I*arg)-log(1-I*arg))/(2*I)).series(rel, order, options);
	if (!(options & series_options::suppress_branchcut)) {
		// method:
		// This is the branch cut: assemble the primitive series manually and
		// then add the corresponding complex step function.
		const symbol &s = ex_to<symbol>(rel.lhs());
		const ex &point = rel.rhs();
		const symbol foo;
		const ex replarg = series(atan(arg), s==foo, order).subs(foo==point, subs_options::no_pattern);
		ex Order0correction = replarg.op(0)+csgn(arg)*Pi*_ex_1_2;
		if ((I*arg_pt)<_ex0)
			Order0correction += log((I*arg_pt+_ex_1)/(I*arg_pt+_ex1))*I*_ex_1_2;
		else
			Order0correction += log((I*arg_pt+_ex1)/(I*arg_pt+_ex_1))*I*_ex1_2;
		epvector seq;
		if (order > 0) {
			seq.reserve(2);
			seq.push_back(expair(Order0correction, _ex0));
		}
		seq.push_back(expair(Order(_ex1), order));
		return series(replarg - pseries(rel, std::move(seq)), rel, order);
	}
	throw do_taylor();
}
Beispiel #19
0
void compile_ex(const ex& expr, const symbol& sym1, const symbol& sym2, FUNCP_2P& fp, const std::string filename)
{
	symbol x("x"), y("y");
	ex expr_with_xy = expr.subs(lst(sym1==x, sym2==y));

	std::ofstream ofs;
	std::string unique_filename = filename;
	global_excompiler.create_src_file(unique_filename, ofs);

	ofs << "double compiled_ex(double x, double y)" << std::endl;
	ofs << "{" << std::endl;
	ofs << "double res = ";
	expr_with_xy.print(GiNaC::print_csrc_double(ofs));
	ofs << ";" << std::endl;
	ofs << "return(res); " << std::endl;
	ofs << "}" << std::endl;

	ofs.close();

	global_excompiler.compile_src_file(unique_filename, filename.empty());
	// This is not standard compliant! ... no conversion between
	// pointer-to-functions and pointer-to-objects ...
	fp = (FUNCP_2P) global_excompiler.link_so_file(unique_filename+".so", filename.empty());
}
Beispiel #20
0
static ex atanh_eval(const ex & x)
{
	if (x.info(info_flags::numeric)) {

		// atanh(0) -> 0
		if (x.is_zero())
			return _ex0;

		// atanh({+|-}1) -> throw
		if (x.is_equal(_ex1) || x.is_equal(_ex_1))
			throw (pole_error("atanh_eval(): logarithmic pole",0));

		// atanh(float) -> float
		if (!x.info(info_flags::crational))
			return atanh(ex_to<numeric>(x));

		// atanh() is odd
		if (x.info(info_flags::negative))
			return -atanh(-x);
	}
	
	return atanh(x).hold();
}
Beispiel #21
0
void VectorField::Delay2ODE_ConvertAndExtend(ex& f, int N, int p)
    {
    lst dlist;
    f.find(delay(wild(1),wild(2)),dlist);
    // dlist is now a ginac lst of expressions of the form delay(delayexpr,del)
    for (lst::const_iterator diter = dlist.begin(); diter != dlist.end(); ++diter)
        {
        // diter points to a ginac expression of the form delay(delayexpr,del).
        ex delayfunc = *diter;
        symbol tmpsymbol;
        ex lag = delayfunc.op(1);
        ex hist = delayfunc.op(0);
        Delay2ODE_ConvertExprToDefHist(hist);
        string delayed_var_name;
        ostringstream os_N_over_delta;
        os_N_over_delta << "(" << N << "/(" << lag << "))";
        string N_over_delta = os_N_over_delta.str();
        for (int k = 0; k < N; ++k)
            {
            if (p == 1)
                {
                string vstr1, prev_vstr1;
                ostringstream os;
                os << k+1;
                vstr1 = tmpsymbol.get_name() + "_1_" + os.str();
                os.str("");
                os << k;
                prev_vstr1 = tmpsymbol.get_name() + "_1_" + os.str();
                //
                StateVariable *var = new StateVariable(vstr1);
                ostringstream os_varformula;
                os_varformula << N_over_delta << "*(";
                if (k == 0)
                    os_varformula << delayfunc.op(0);
                else
                    os_varformula << prev_vstr1;
                os_varformula << " - " << vstr1 << ")";
                var->Formula(os_varformula.str());
                ostringstream os_vardefic;
                os_vardefic << hist.subs(IndVar==-(k+1)*lag/N);
                var->DefaultInitialCondition(os_vardefic.str());
                AddStateVariable(var);
                if (k == N-1)
                    delayed_var_name = var->Name();
                }
            else if (p == 2)
                {
                string vstr1,vstr2, prev_vstr1;
                ostringstream os;
                os << k+1;
                vstr1 = tmpsymbol.get_name() + "_1_" + os.str();
                vstr2 = tmpsymbol.get_name() + "_2_" + os.str();
                os.str("");
                os << k;
                prev_vstr1 = tmpsymbol.get_name() + "_1_" + os.str();
                //
                StateVariable *var = new StateVariable(vstr1);
                var->Formula(vstr2);
                ostringstream os_vardefic;
                os_vardefic << hist.subs(IndVar==-(k+1)*lag/N);
                var->DefaultInitialCondition(os_vardefic.str());
                AddStateVariable(var);
                if (k == N-1)
                    delayed_var_name = var->Name();
                //
                var = new StateVariable(vstr2);
                ostringstream os_varformula;
                os_varformula << "2*" << N_over_delta << "*";
                os_varformula << "( -" << vstr2 << " + " << N_over_delta << "*";
                os_varformula << "(";
                if (k == 0)
                    os_varformula << delayfunc.op(0);
                else
                    os_varformula << prev_vstr1;
                os_varformula << " - " << vstr1 << "))";
                var->Formula(os_varformula.str());
                ex icderiv = hist.diff(IndVar);
                ostringstream os_vardefic_deriv;
                os_vardefic_deriv << icderiv.subs(IndVar==-(k+1)*lag/N);
                var->DefaultInitialCondition(os_vardefic_deriv.str());
                AddStateVariable(var);
                }
            else // p == 3
                {
                string vstr1,vstr2,vstr3, prev_vstr1;
                ostringstream os;
                os << k+1;
                vstr1 = tmpsymbol.get_name() + "_1_" + os.str();
                vstr2 = tmpsymbol.get_name() + "_2_" + os.str();
                vstr3 = tmpsymbol.get_name() + "_3_" + os.str();
                os.str("");
                os << k;
                prev_vstr1 = tmpsymbol.get_name() + "_1_" + os.str();
                //
                StateVariable *var = new StateVariable(vstr1);
                var->Formula(vstr2);
                ostringstream os_vardefic;
                os_vardefic << hist.subs(IndVar==-(k+1)*lag/N);
                var->DefaultInitialCondition(os_vardefic.str());
                AddStateVariable(var);
                if (k == N-1)
                    delayed_var_name = var->Name();
                //
                var = new StateVariable(vstr2);
                var->Formula(vstr3);
                ex icderiv = hist.diff(IndVar);
                ostringstream os_vardefic_deriv;
                os_vardefic_deriv << icderiv.subs(IndVar==-(k+1)*lag/N);
                var->DefaultInitialCondition(os_vardefic_deriv.str());
                AddStateVariable(var);
                //
                var = new StateVariable(vstr3);
                ostringstream os_varformula;
                os_varformula << N_over_delta << "*";
                os_varformula << "(-3*" << vstr3;
                os_varformula << " - 6*" << N_over_delta << "*";
                os_varformula << "(" << vstr2 << " - " << N_over_delta << "*";
                os_varformula << "(";
                if (k == 0)
                    os_varformula << delayfunc.op(0);
                else
                    os_varformula << prev_vstr1;
                os_varformula << " - " << vstr1 << ")))";
                var->Formula(os_varformula.str());
                ex icderiv2 = icderiv.diff(IndVar);
                ostringstream os_vardefic_deriv2;
                os_vardefic_deriv2 << icderiv2.subs(IndVar==-(k+1)*lag/N);
                var->DefaultInitialCondition(os_vardefic_deriv2.str());
                AddStateVariable(var);
                }                    
            } // end k loop
        symbol s(delayed_var_name);
        f = f.subs(delayfunc == s);
        } // end dlist loop
    }
Beispiel #22
0
/** 
 * Exact polynomial division of a, b \in Z_p[x_0, \ldots, x_n]
 * It doesn't check whether the inputs are proper polynomials, so be careful
 * of what you pass in.
 *  
 * @param a  first multivariate polynomial (dividend)
 * @param b  second multivariate polynomial (divisor)
 * @param q  quotient (returned)
 * @param var variables X iterator to first element of vector of symbols
 *
 * @return "true" when exact division succeeds (the quotient is returned in
 *          q), "false" otherwise.
 * @note @a p = 0 means the base ring is Z
 */
bool divide_in_z_p(const ex &a, const ex &b, ex &q, const exvector& vars, const long p)
{
	static const ex _ex1(1);
	if (b.is_zero())
		throw(std::overflow_error("divide_in_z: division by zero"));
	if (b.is_equal(_ex1)) {
		q = a;
		return true;
	}
	if (is_exactly_a<numeric>(a)) {
		if (is_exactly_a<numeric>(b)) {
			// p == 0 means division in Z
			if (p == 0) {
				const numeric tmp = ex_to<numeric>(a/b);
				if (tmp.is_integer()) {
					q = tmp;
					return true;
				} else
					return false;
			} else {
				q = (a*recip(ex_to<numeric>(b), p)).smod(numeric(p));
				return true;
			}
		} else
			return false;
	}
	if (a.is_equal(b)) {
		q = _ex1;
		return true;
	}

	// Main symbol
	const ex &x = vars.back();

	// Compare degrees
	int adeg = a.degree(x), bdeg = b.degree(x);
	if (bdeg > adeg)
		return false;

	// Polynomial long division (recursive)
	ex r = a.expand();
	if (r.is_zero())
		return true;
	int rdeg = adeg;
	ex eb = b.expand();
	ex blcoeff = eb.coeff(x, bdeg);
	exvector v;
	v.reserve(std::max(rdeg - bdeg + 1, 0));
	exvector rest_vars(vars);
	rest_vars.pop_back();
	while (rdeg >= bdeg) {
		ex term, rcoeff = r.coeff(x, rdeg);
		if (!divide_in_z_p(rcoeff, blcoeff, term, rest_vars, p))
			break;
		term = (term*power(x, rdeg - bdeg)).expand();
		v.push_back(term);
		r = (r - term*eb).expand();
		if (p != 0)
			r = r.smod(numeric(p));
		if (r.is_zero()) {
			q = (new add(v))->setflag(status_flags::dynallocated);
			return true;
		}
		rdeg = r.degree(x);
	}
	return false;
}
Beispiel #23
0
static ex log_imag_part(const ex & x)
{
	if (x.info(info_flags::nonnegative))
		return 0;
	return atan2(GiNaC::imag_part(x), GiNaC::real_part(x));
}
Beispiel #24
0
static ex atan2_eval(const ex & y, const ex & x)
{
	if (y.is_zero()) {

		// atan2(0, 0) -> 0
		if (x.is_zero())
			return _ex0;

		// atan2(0, x), x real and positive -> 0
		if (x.info(info_flags::positive))
			return _ex0;

		// atan2(0, x), x real and negative -> Pi
		if (x.info(info_flags::negative))
			return Pi;
	}

	if (x.is_zero()) {

		// atan2(y, 0), y real and positive -> Pi/2
		if (y.info(info_flags::positive))
			return _ex1_2*Pi;

		// atan2(y, 0), y real and negative -> -Pi/2
		if (y.info(info_flags::negative))
			return _ex_1_2*Pi;
	}

	if (y.is_equal(x)) {

		// atan2(y, y), y real and positive -> Pi/4
		if (y.info(info_flags::positive))
			return _ex1_4*Pi;

		// atan2(y, y), y real and negative -> -3/4*Pi
		if (y.info(info_flags::negative))
			return numeric(-3, 4)*Pi;
	}

	if (y.is_equal(-x)) {

		// atan2(y, -y), y real and positive -> 3*Pi/4
		if (y.info(info_flags::positive))
			return numeric(3, 4)*Pi;

		// atan2(y, -y), y real and negative -> -Pi/4
		if (y.info(info_flags::negative))
			return _ex_1_4*Pi;
	}

	// atan2(float, float) -> float
	if (is_a<numeric>(y) && !y.info(info_flags::crational) &&
	    is_a<numeric>(x) && !x.info(info_flags::crational))
		return atan(ex_to<numeric>(y), ex_to<numeric>(x));

	// atan2(real, real) -> atan(y/x) +/- Pi
	if (y.info(info_flags::real) && x.info(info_flags::real)) {
		if (x.info(info_flags::positive))
			return atan(y/x);

		if (x.info(info_flags::negative)) {
			if (y.info(info_flags::positive))
				return atan(y/x)+Pi;
			if (y.info(info_flags::negative))
				return atan(y/x)-Pi;
		}
	}

	return atan2(y, x).hold();
}    
Beispiel #25
0
static ex sin_conjugate(const ex & x)
{
	// conjugate(sin(x))==sin(conjugate(x))
	return sin(x.conjugate());
}
Beispiel #26
0
static ex tan_conjugate(const ex & x)
{
	// conjugate(tan(x))==tan(conjugate(x))
	return tan(x.conjugate());
}
Beispiel #27
0
static ex cos_eval(const ex & x)
{
	// cos(n/d*Pi) -> { all known non-nested radicals }
	const ex SixtyExOverPi = _ex60*x/Pi;
	ex sign = _ex1;
	if (SixtyExOverPi.info(info_flags::integer)) {
		numeric z = mod(ex_to<numeric>(SixtyExOverPi),*_num120_p);
		if (z>=*_num60_p) {
			// wrap to interval [0, Pi)
			z = *_num120_p-z;
		}
		if (z>=*_num30_p) {
			// wrap to interval [0, Pi/2)
			z = *_num60_p-z;
			sign = _ex_1;
		}
		if (z.is_equal(*_num0_p))  // cos(0)       -> 1
			return sign;
		if (z.is_equal(*_num5_p))  // cos(Pi/12)   -> sqrt(6)/4*(1+sqrt(3)/3)
			return sign*_ex1_4*sqrt(_ex6)*(_ex1+_ex1_3*sqrt(_ex3));
		if (z.is_equal(*_num10_p)) // cos(Pi/6)    -> sqrt(3)/2
			return sign*_ex1_2*sqrt(_ex3);
		if (z.is_equal(*_num12_p)) // cos(Pi/5)    -> sqrt(5)/4+1/4
			return sign*(_ex1_4*sqrt(_ex5)+_ex1_4);
		if (z.is_equal(*_num15_p)) // cos(Pi/4)    -> sqrt(2)/2
			return sign*_ex1_2*sqrt(_ex2);
		if (z.is_equal(*_num20_p)) // cos(Pi/3)    -> 1/2
			return sign*_ex1_2;
		if (z.is_equal(*_num24_p)) // cos(2/5*Pi)  -> sqrt(5)/4-1/4x
			return sign*(_ex1_4*sqrt(_ex5)+_ex_1_4);
		if (z.is_equal(*_num25_p)) // cos(5/12*Pi) -> sqrt(6)/4*(1-sqrt(3)/3)
			return sign*_ex1_4*sqrt(_ex6)*(_ex1+_ex_1_3*sqrt(_ex3));
		if (z.is_equal(*_num30_p)) // cos(Pi/2)    -> 0
			return _ex0;
	}

	if (is_exactly_a<function>(x)) {
		const ex &t = x.op(0);

		// cos(acos(x)) -> x
		if (is_ex_the_function(x, acos))
			return t;

		// cos(asin(x)) -> sqrt(1-x^2)
		if (is_ex_the_function(x, asin))
			return sqrt(_ex1-power(t,_ex2));

		// cos(atan(x)) -> 1/sqrt(1+x^2)
		if (is_ex_the_function(x, atan))
			return power(_ex1+power(t,_ex2),_ex_1_2);
	}
	
	// cos(float) -> float
	if (x.info(info_flags::numeric) && !x.info(info_flags::crational))
		return cos(ex_to<numeric>(x));
	
	// cos() is even
	if (x.info(info_flags::negative))
		return cos(-x);
	
	return cos(x).hold();
}
Beispiel #28
0
static ex cos_conjugate(const ex & x)
{
	// conjugate(cos(x))==cos(conjugate(x))
	return cos(x.conjugate());
}
Beispiel #29
0
void g_tilde_1_deri_print(const ex & arg, const print_context & c)
{
  c.s << "gtilde_deri("; arg.print(c); c.s << ")";
}
Beispiel #30
0
static ex log_real_part(const ex & x)
{
	if (x.info(info_flags::nonnegative))
		return log(x).hold();
	return log(abs(x));
}