def plant_growth_model(m, t1, x1, t2, x2): assert isinstance(m, const) and isinstance(t1, const) assert isinstance(x1, const) and isinstance(x2, const) assert isinstance(x2, const) #B,M,k #M is 1000 (maximum population) #B is 9 (which is (M-x1)/x1) #k is 0.00037 (which is (ln((m-x2)/(x2*B))/(-M*(t2-t1))) ) #f(t) = M / (1+B*e^(-Mkt) #or f(t) = m / (1+((m-x1)/x1)*e^(-Mkt)) return quot( m, plus( const(1.0), prod( quot(plus(m, prod(const(-1.0), x1)), x1), make_e_expr( prod( prod( prod(const(-1.0), m), quot( ln( plus(m, prod(const(-1.0), x2)), prod( x2, quot(plus(m, prod(const(-1.0), x1)), x1))), prod(prod(const(-1.0), m), plus(t2, prod(const(-1.0), t1))))), make_pwr('t', 1))))))
def spread_of_disease_model(p, t0, p0, t1, p1): assert isinstance(p, const) and isinstance(t0, const) assert isinstance(p0, const) and isinstance(t1, const) #f(t) = P/(1+B*e^(-c*t)) #p = 500,000 #let t0 = 0 such that f(t0) = f(0) #this would make t1 = delta_t #where delta_t = t1 - t0 #f(0) = p0 = 200 = 500,000/(1+B*e^0) = 500,000/(1+B) => B = 2499 #generally: B = (p-p0)/p0 #f(1) = p1 = 500 = 500,000/(1+2499*e^(-c*1)) => c = .92 #generally: c = -ln((p-p1)/(p1*B))/t #so we get f(t) = p/(1+((p-p0)/p0)*e^(-(-ln((p-p1)/(p1*((p-p0)/p0))))*t)) #or f(t) = p/(1+((p-p0)/p0)*e^((ln((p-p1)/(p1*((p-p0)/p0)))/(t1-t0)*t)) #return f(t) return quot( p, plus( const(1.0), prod( quot(plus(p, prod(const(-1.0), p0)), p0), make_e_expr( ln( prod( quot( quot( plus(p, prod(const(-1.0), p1)), prod( p1, quot(plus(p, prod(const(-1.0), p0)), p0))), plus(t1, prod(const(-1.0), t0))), make_pwr('t', 1)))))))
def ln_deriv(expr): assert isinstance(expr,ln) lnexpression = expr.get_expr() if isinstance(lnexpression,const): return const(0) elif isinstance(lnexpression,absv): return quot(const(1),lnexpression.get_expr()) else: return prod(quot(const(1), lnexpression), deriv(lnexpression))
def antideriv(i): ## CASE 1: i is a constant if isinstance(i, const): #3 => 3x^1 return prod(i, make_pwr('x', 1.0)) ## CASE 2: i is a pwr elif isinstance(i, pwr): #x^d => 1/(d+1) * x^(d+1) b = i.get_base() d = i.get_deg() ## CASE 2.1: b is var and d is constant. if isinstance(b, var) and isinstance(d, const): if d.get_val() == -1: return make_ln(make_absv(pwr(b, const(1.0)))) else: r = const(d.get_val() + 1.0) return prod(quot(const(1.0), r), pwr(b, r)) ## CASE 2.2: b is e elif is_e_const(b): # e^(kx) => 1/k * e(kx) if isinstance(d, prod): k = d.get_mult1() return prod(quot(const(1.0), k), i) else: raise Exception('antideriv: unknown case') # ## CASE 2.3: b is a sum elif isinstance(b, plus): #(1+x)^-3 r = const(d.get_val() + 1.0) if isinstance(d, const) and d.get_val() == -1: return make_ln(make_absv(b)) elif isinstance(b.get_elt1(), prod): #(3x+2)^4 => 1/3 * anti( if isinstance(d, const) and d.get_val() < 0: return prod(quot(const(-1.0), b.get_elt1().get_mult1()), pwr(b, r)) else: return prod( quot(const(1.0), prod(b.get_elt1().get_mult1(), r)), pwr(b, r)) else: return prod(quot(const(1.0), r), pwr(b, r)) else: raise Exception('antideriv: unknown case') ### CASE 3: i is a sum, i.e., a plus object. elif isinstance(i, plus): return plus(antideriv(i.get_elt1()), antideriv(i.get_elt2())) ### CASE 4: is is a product, i.e., prod object, ### where the 1st element is a constant. elif isinstance(i, prod): return prod(i.get_mult1(), antideriv(i.get_mult2())) else: raise Exception('antideriv: unknown case')
def ln_deriv(p): #ln[g(x)] = 1/g(x) * g'(x) assert isinstance(p, ln) g = p.get_expr() if isinstance(g, prod): m1 = g.get_mult1() m2 = g.get_mult2() #(x)(x+1) #ln(x) + ln(x+1) if isinstance(m1, pwr) and isinstance(m2, pwr): return plus(quot(prod(m1.get_deg(), deriv(m1.get_base())), m1.get_base()), quot(prod(m2.get_deg(), deriv(m2.get_base())), m2.get_base())) return plus(ln_deriv(make_ln(m1)), ln_deriv(make_ln(m2))) else: return prod(quot(const(1.0), g), deriv(g))
def quot_deriv(p):# f/g = (gf'-fg')/g^2 quotient rule assert isinstance(p, quot) f = p.get_num() g = p.get_denom() if isinstance(f, const) and isinstance(g, const): return const(0) else: return quot(plus(prod(g, deriv(f)), prod(const(-1),prod(f, deriv(g)))), pwr(g, const(2.0)))
def find_growth_model(p0, t, n): assert isinstance(p0, const) assert isinstance(t, const) assert isinstance(n, const) #p0 is C #n is k #t is t return prod(p0, make_e_expr(prod(quot(ln(n), t), make_pwr('t', 1))))
def solve_pdeq(k1, k2): assert isinstance(k1, const) assert isinstance(k2, const) #k1*y` = k2*y #y` = (k2/k1) * y #let k2/k1 = k #y` = k*y #therefore y = C*e^(kt) and y` = k*C*e^(kt) or y` = (k2/k1)*C*e^(kt) #I am going to let C = 1/k #so we get: #return e^((k2/k1)*x) # return prod(quot(k2,k1), make_e_expr(prod(quot(k2,k1),make_pwr('x',1.0)))) #C = 1 return make_e_expr(prod(quot(k2, k1), make_pwr('x', 1.0))) #C = 1/k
def quot_deriv(expr): #recursively compute the derivatvie of a quotient assert isinstance(expr, quot) numerator = expr.get_num() denominator = expr.get_denom() numeratorPrime = deriv(numerator) denominatorPrime = deriv(denominator) element1 = prod(denominator, numeratorPrime) element2 = prod(numerator, denominatorPrime) element3 = prod(make_const(-1.0), element2) element4 = plus(element1, element3) element5 = pwr(denominator, make_const(2.0)) exprPrime = quot(element4, element5) return exprPrime
def spread_of_disease_model(p, t0, p0, t1, p1): assert isinstance(p, const) and isinstance(t0, const) assert isinstance(p0, const) and isinstance(t1, const) B = p.get_val() / (1 + p0.get_val()) B_const = make_const(B) c = prod( const(-1.0), quot(plus(quot(p, p1), prod(const(1.0), const(-1.0)), B_const), t1)) c_const = make_const(c) expr = quot( p, plus( const(1.0), prod(B_const, pwr(math.e, pwr(prod(const(-1.0), prod(c_const, var("t")))))))) return expr
def max_norman_window_area(p): assert isinstance(p, const) hexpr = quot(plus(plus(p,prod(const(-2.0),'r')), prod(prod(np.pi,'r'), const(-1.0)))/const(2.0)) area = plus(prod(const(0.5), prod(np.pi, pwr('r', const(2.0)))), prod(prod(const(2.0),'r'), hexpr)) area_deriv = deriv(area) zeroes = find_poly_2_zeros(area_deriv) ans = area(zeroes) return max(ans)
def pwr_deriv(p): assert isinstance(p, pwr) b = p.get_base() d = p.get_deg() #this assumes ever contact that comes in is e if isinstance(b,const): if b.get_val() == math.e: return prod(mult1=p,mult2=deriv(d)) else: return d if isinstance(b, var): if isinstance(d, const): if d.get_val() - 1.0 == 0: return const(1) else: return pwr(prod(d,b), const(d.get_val() - 1.0)) else: raise Exception('pwr_deriv: case 1: ' + str(p)) if isinstance(b, pwr): if isinstance(d, const): basederiv = deriv(b) return prod(basederiv, pwr(prod(b,d), const(d.get_val() - 1))) else: raise Exception('pwr_deriv: case 2: ' + str(p)) elif isinstance(b, plus): if isinstance(d, const): basederiv = deriv(b) return prod(basederiv, pwr(prod(b,d), const(d.get_val()- 1.0))) else: raise Exception('pwr_deriv: case 3: ' + str(p)) elif isinstance(b, prod): if isinstance(d, const): basederiv = deriv(b) return prod(basederiv,pwr(prod(b,d), const(d.get_val() - 1))) else: raise Exception('pwr_deriv: case 4: ' + str(p)) elif isinstance(b, ln): if isinstance(d, const): temp = d.get_val() return prod(mult1=prod(mult1=d,mult2=pwr(base=b,deg=const(temp - 1))), mult2=prod(mult1=(quot(num=1.0,denom=b.get_expr())),mult2=deriv(b.get_expr()))) else: raise Exception('pwr_deriv: case 5: ' + str(p))
def mult_x(expr): #1/12x^2 - 10x + 300 if isinstance(expr, plus): if isinstance(expr.get_elt2(), const): return plus(mult_x(expr.get_elt1()), prod(expr.get_elt2(), make_pwr('x', 1.0))) else: return plus(mult_x(expr.get_elt1()), mult_x(expr.get_elt2())) elif isinstance(expr, pwr): if isinstance(expr.get_deg(), const): return pwr(expr.get_base(), const(expr.get_deg().get_val()+1)) else: return pwr(mult_x(expr.get_base()), mult_x(expr.get_deg())) elif isinstance(expr, prod): return prod(mult_x(expr.get_mult1()), mult_x(expr.get_mult2())) elif isinstance(expr, quot): return quot(mult_x(expr.get_num()), mult_x(expr.get_denom())) else: return expr
def plant_growth_model(m, t1, x1, t2, x2): assert isinstance(m, const) and isinstance(t1, const) assert isinstance(x1, const) and isinstance(x2, const) assert isinstance(x2, const) b = (m.get_val() / x1.get_val()) - 1 k = (np.log(((m.get_val() / x2.get_val()) - 1.0) / b)) / (-1 * m.get_val() * t2.get_val()) expr = quot( m, plus( const(1.0), prod( const(b), make_e_expr( prod(const(m.get_val() * -1), prod(const(k), pwr(var("t"), const(1.0)))))))) return expr
def ln_deriv(expr): assert isinstance(expr, ln) inner = expr.get_expr() #f`(ln(g(x))) = g`(x)/g(x) return quot(deriv(inner) , inner)
def antideriv(i): ## CASE 1: i is a constant if isinstance(i, const): return prod(i, make_pwr('x', 1.0)) ## CASE 2: i is a pwr elif isinstance(i, pwr): b = i.get_base() d = i.get_deg() ## CASE 2.1: b is var and d is constant. if isinstance(b, var) and isinstance(d, const): #(b^(d+1))/(d+1) if d.get_val() == -1.0: return ln(make_pwr('x', 1.0)) return quot(pwr(b, const(d.get_val() + 1.0)), const(d.get_val() + 1.0)) ## CASE 2.2: b is e elif is_e_const(b): if isinstance(d, const) or isinstance(d, pwr) or isinstance( d, var) or isinstance(d, prod): if isinstance(d, const): return prod(const(b.get_value()**d.getvalue()), var('x')) elif isinstance(d, var): #e^x return i elif isinstance(d, pwr) and d.get_deg() == 1.0: #e^x^1 return i elif isinstance(d, prod): left = d.get_mult1() right = d.get_mult2() if isinstance(left, var) or (isinstance( left, pwr) and left.get_deg().get_val() == 1.0): # e^xa == e^ax => (1/a) * e^ax return prod(quot(const(1.0), right), i) elif isinstance(right, var) or (isinstance( right, pwr) and right.get_deg().get_val() == 1.0): # e^ax => (1/a) * e^ax return prod(quot(const(1.0), left), i) else: raise Exception('e^(unknown expression)') else: raise Exception( 'antideriv: unknown case -- did not implement substitution' ) ## CASE 2.3: b is a sum elif isinstance(b, plus): #(x+y)^d => ((x+y)^(d+1))/(d+1) if isinstance(d, const): if d.get_val() == -1.0: return prod(pwr(deriv(b), const(d.get_val() + 1.0)), ln(b)) # return prod(pwr(deriv(b),const(d.get_val()+1.0)) , quot(make_pwr_expr(b,const(d.get_val()+1.0)),const(d.get_val()+1.0))) else: # return prod(pwr(deriv(b),const(d.get_val()+1.0)) , quot(make_pwr_expr(b,const(d.get_val()+1.0)),const(d.get_val()+1.0))) # return prod(make_pwr_expr(prod(deriv(b),const(d.get_val()+1.0)), -1.0) , quot(make_pwr_expr(b,const(d.get_val()+1.0)),const(d.get_val()+1.0))) # formula from this page (https://www.quora.com/How-do-I-find-anti-derivative-of-ax+b-2) return prod( make_pwr_expr(prod(deriv(b), const(d.get_val() + 1.0)), -1.0), make_pwr_expr(b, const(d.get_val() + 1.0))) else: raise Exception('antideriv: unknown case') else: raise Exception('antideriv: unknown case') ### CASE 3: i is a sum, i.e., a plus object. elif isinstance(i, plus): # S(n+m) => S(n) + S(m) return plus(antideriv(i.get_elt1()), antideriv(i.get_elt2())) ### CASE 4: is is a product, i.e., prod object, ### where the 1st element is a constant. elif isinstance(i, prod): left = i.get_mult1() right = i.get_mult2() if isinstance(left, const): return prod(left, antideriv(right)) elif isinstance(right, const): return prod(right, antideriv(left)) else: raise Exception( 'antideriv: unknown case -- did not implement special rules (like substitution)' ) else: raise Exception('antideriv: unknown case' + str(type(i)) + str(i))
def make_quot(nexpr, dexpr): return quot(num=nexpr, denom=dexpr)