def __new__(cls, f, limits, exprs): f = sympify(f) limits = sympify(limits) exprs = sympify(exprs) if not (type(exprs) == Tuple and len(exprs) == 3): # exprs is not of form (a0, an, bn) # Converts the expression to fourier form c, e = exprs.as_coeff_add() rexpr = c + Add(*[TR10(i) for i in e]) a0, exp_ls = rexpr.expand(trig=False, power_base=False, power_exp=False, log=False).as_coeff_add() x = limits[0] L = abs(limits[2] - limits[1]) / 2 a = Wild('a', properties=[lambda k: k.is_Integer, lambda k: k is not S.Zero, ]) b = Wild('b', properties=[lambda k: x not in k.free_symbols, ]) an = dict() bn = dict() # separates the coefficients of sin and cos terms in dictionaries an, and bn for p in exp_ls: t = p.match(b * cos(a * (pi / L) * x)) q = p.match(b * sin(a * (pi / L) * x)) if t: an[t[a]] = t[b] + an.get(t[a], S.Zero) elif q: bn[q[a]] = q[b] + bn.get(q[a], S.Zero) else: a0 += p exprs = Tuple(a0, an, bn) return Expr.__new__(cls, f, limits, exprs)
def finite_check(f, x, L): def check_fx(exprs, x): return x not in exprs.free_symbols def check_sincos(expr, x, L): if type(expr) == sin or type(expr) == cos: sincos_args = expr.args[0] if sincos_args.match(a * (pi / L) * x + b) is not None: return True else: return False expr = sincos_to_sum(TR2(TR1(f))) res_expr = S.Zero add_coeff = expr.as_coeff_add() res_expr += add_coeff[0] a = Wild('a', properties=[ lambda k: k.is_Integer, lambda k: k != S.Zero, ]) b = Wild('b', properties=[ lambda k: x not in k.free_symbols or k == S.Zero, ]) for s in add_coeff[1]: mul_coeffs = s.as_coeff_mul()[1] for t in mul_coeffs: if not (check_fx(t, x) or check_sincos(t, x, L)): return False, f res_expr += TR10(s) return True, res_expr.collect( [sin(a * (pi / L) * x), cos(a * (pi / L) * x)])
def _trig_optimizer(expr): return TR10(TR8(expr))