def pwr_deriv(p): assert isinstance(p, pwr) b = p.get_base() d = p.get_deg() if isinstance(b, var): if isinstance(d, const): return prod(make_const(d.get_val()), pwr(b, make_const(d.get_val()-1))) else: raise Exception('pwr_deriv: case 1: ' + str(p)) if isinstance(b, pwr): # think this is (x^2 (^3)) if isinstance(d, const): return prod(b.get_base(), prod(b.get_deg(), const)) else: raise Exception('pwr_deriv: case 2: ' + str(p)) elif isinstance(b, plus): # (x+2)^3 if isinstance(d, const): return prod(d, pwr(b, d.get_val()-1)) else: raise Exception('pwr_deriv: case 3: ' + str(p)) elif isinstance(b, prod):#(3x)^2 => (2*3*x)^(2-1) if isinstance(d, const): pwr( prod(d, prod(b.get_mult1(), b.get_mult2())), d.get_val()-1) else: raise Exception('pwr_deriv: case 4: ' + str(p)) else: raise Exception('power_deriv: case 5: ' + str(p))
def make_e_expr(d): if isinstance(d, float): return pwr(base=make_const(math.e), deg=const(val=d)) elif isinstance(d, const): return pwr(base=make_const(math.e), deg=d) elif isinstance(d, pwr) or isinstance(d, plus) or \ isinstance(d, prod) or isinstance(d, quot): return pwr(base=make_const(math.e), deg=d) else: raise Exception('make_e_expr: case 1: ' + str(d))
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 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 spread_of_news_model(p, k): assert isinstance(p, const) and isinstance(k, const) expr = prod( p, plus(make_const(-1.0), pwr(math.e, prod(make_const(-1.73), var("t"))))) return expr
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 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 percent_retention_model(lmbda, a): assert isinstance(lmbda, const) assert isinstance(a, const) expr = plus( prod(plus(100, prod(a, const(-1.0))), pwr(math.e, prod(lmbda, prod(const(-1.0), var("t"))))), a) return expr
def prod_deriv(p): assert isinstance(p, prod) m1 = p.get_mult1() # 6 m2 = p.get_mult2() # x^3 if isinstance(m1, const): if isinstance(m2, const): return const(0) elif isinstance(m2, pwr): # 6*(x^3)=> 6*3*(x^(3-1)) # 3x^1 becomes (1*3)x^0 => simplified is 3 if isinstance(m2.get_deg(), const) and m2.get_deg().get_val() == 1: return m1 else: # get 6 * 3 simplifiedAlt1 = const(m1.get_val() * m2.get_deg().get_val()) # get x^3-1 simplifiedExp = const(m2.get_deg().get_val() - 1) alt2 = pwr(m2.get_base(), simplifiedExp) return prod(simplifiedAlt1, alt2) elif isinstance(m2, plus): # 3*(x+1) if isinstance(deriv(m2), const): return const(0) else: return prod(m1, deriv(m2)) elif isinstance(m2, prod): # 4*(3x) if isinstance(deriv(m2), const): return const(0) else: return prod(m1, deriv(m2)) else: raise Exception('prod_deriv: case 0' + str(p)) elif isinstance(m1, plus): if isinstance(m2, const): # (x+1)*3 if isinstance(deriv(m2), const): return const(0) else: return prod(m1, deriv(m2)) else: raise Exception('prod_deriv: case 1:' + str(p)) elif isinstance(m1, pwr): if isinstance(m2, const): # (x^2)*3 => (2x^1)*3 if isinstance(deriv(m2), const): return const(0) else: return prod(deriv(m1), m2) else: raise Exception('prod_deriv: case 2:' + str(p)) elif isinstance(m1, prod): if isinstance(m2, const): #(3x)*4 if isinstance(deriv(m2), const): return const(0) else: return prod(deriv(m1), m2) else: return prod(m1, deriv(m2)) else: raise Exception('prod_deriv: case 4:' + str(p))
def tumor_volume_change(m, c, k): assert isinstance(m, const) assert isinstance(c, const) assert isinstance(k, const) yt = prod(const(k.get_val() * math.pi), pwr('r', 3.0)) dydt = dydt_given_x_dxdt(yt, m, const(-1 * c.get_val())) return dydt
def pwr_deriv(p): assert isinstance(p, pwr) b = p.get_base() d = p.get_deg() if isinstance(b, var): #if base is a variable (ie x^2) if isinstance(d, const): #no 2^x garbage if d.get_val() == 0.0:#x^0 return make_const(0.0) neg1 = make_const(-1.0) new_d = const.add(const_flatten(d),neg1) if new_d.get_val() == 0.0:#TODO: Handle something like x^0 is already 1 # return d # print 'here' return const(1.0) return flattenProduct(prod(mult1=d,mult2=pwr(b,new_d))) else: raise Exception('pwr_deriv: case 1: ' + str(p)) elif is_valid_non_const_expr(b):#base is an expression ie: (x + 2)^2 or (2x)^2 etc if isinstance(d, const): if d.get_val() == 0.0: return make_const(0.0) neg1 = make_const(-1.0) new_d = d.add(const_flatten(d),neg1) if new_d.get_val() == 0.0:#TODO: Handle something like x^0 is already 1 return deriv(b) return flattenProduct(prod(mult1=flattenProduct(prod(mult1=d, mult2=pwr(b,new_d))), mult2=deriv(b))) else: raise Exception('pwr_deriv: case 2: ' + str(p)) elif isConstE(b): if isinstance(d, const): #f`(e^c) == 0, where c is a constant return make_const(0.0) elif is_valid_non_const_expr(d): #base is an expression ie: (x + 2)^2 or (2x)^2 etc # d/dx(e^f(x)) = f`(x)*e^f(x) return flattenProduct(prod( deriv(d), p )) #where d is f`(x) and p is e^f(x), ie the original expression else: raise Exception('pwr_deriv: case 4: ' + str(p)) elif isinstance(b, const) and isinstance(d, const): return make_const(0.0)# d/dx(c^c) = 0 else: raise Exception('power_deriv: case 3: ' + str(p) + ' --type-- ' + str(type(b)))
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 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 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 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 pwr_deriv(p): assert isinstance(p, pwr) b = p.get_base() d = p.get_deg() if isinstance(b, const): if isinstance(d, pwr): #e^(x^1) return p elif isinstance(d, prod):#85 *e^(-0.5 *t) => 85 *-0.5 *e^(-0.5 *t) return prod(p, deriv(d)) #e^(2x) if isinstance(b, var): if isinstance(d, const): return prod(d, pwr(b, const(d.get_val()-1))) elif isinstance(d, plus): return prod(d, pwr(b, const(d.get_val()-1))) else: raise Exception('pwr_deriv: case 1: ' + str(p)) if isinstance(b, pwr): # think this is (x^2 (^3)) if isinstance(d, const): return prod(b.get_base(), prod(b.get_deg(), const)) elif isinstance(d, pwr):#e^(x^1) return p else: raise Exception('pwr_deriv: case 2: ' + str(p)) elif isinstance(b, plus): # (x+2)^3 if isinstance(d, const): return prod(d, pwr(b, const(d.get_val()-1))) else: raise Exception('pwr_deriv: case 3: ' + str(p)) elif isinstance(b, prod):#(3x)^2 => (2*3*x)^(2-1) if isinstance(d, const): pwr( prod(d, prod(b.get_mult1(), b.get_mult2())), const(d.get_val()-1)) else: raise Exception('pwr_deriv: case 4: ' + str(p)) elif isinstance(b, quot): if isinstance(d, const): #b*d * deriv(quot)^d-1 return prod(prod(d, pwr(b, const(d.get_val()-1))) ,deriv(b)) else: raise Exception('power_deriv: case 5: ' + str(p)) elif isinstance(b, ln):#(lnx)^5 return prod(prod(d, pwr(b, const(d.get_val() - 1))), deriv(b)) else: raise Exception('power_deriv: case 6: ' + str(p))
def pwr_deriv(p): #takes a pwr object takes the derivative of the #the base by using lots of recursion assert isinstance(p, pwr) b = p.get_base() d = p.get_deg() if isinstance(b, var): # if isinstance(d, const): newDeg = d.get_val() newDeg = newDeg - 1 if newDeg < 0: return make_const(0) else: newReuslt = pwr(b, const(newDeg)) finalProduct = prod(const(newDeg + 1), newReuslt) return finalProduct else: raise Exception('pwr_deriv: case 1: ' + str(p)) if isinstance( b, pwr ): #takes another pwr object and take the derivavtive recursively if isinstance(d, const): newB = deriv(b) newDeg = d.get_val() - 1 p = pwr(b, const(newDeg)) newPart = prod(const(newDeg + 1), p) finalResult = prod(newPart, newB) return finalResult else: raise Exception('pwr_deriv: case 2: ' + str(p)) elif isinstance( b, plus): #takes plus object and computes the derivative recursively if isinstance(d, const): leftSide = b.get_elt1() rightSide = b.get_elt2() newDeg = d.get_val() - 1 p = pwr(b, const(newDeg)) p = prod(const(newDeg + 1), p) newLeftSide = deriv(leftSide) newRightSide = deriv(rightSide) newPart = plus(newLeftSide, newRightSide) finalResult = prod(p, newPart) return finalResult else: raise Exception('pwr_deriv: case 3: ' + str(p)) elif isinstance( b, prod ): #takes a prod objects and computes the derivative recursively if isinstance(d, const): newDeg = d.get_val() - 1 p = pwr(b, const(newDeg)) p = prod(const(newDeg + 1), p) b = prod_deriv(b) finalResult = prod(p, b) return finalResult else: raise Exception('pwr_deriv: case 4: ' + str(p)) elif isinstance(b, quot): if isinstance(d, const): newDeg = d.get_val() - 1 p = pwr(b, const(newDeg)) p = prod(const(newDeg + 1), p) b = deriv(b) finalResult = prod(p, b) return finalResult else: raise Exception('pwr deriv: case 5: ' + str(p)) elif isinstance(b, const): #if the base is a constant then #that base must be e and the deriv #will be computed recusively if b.get_val() == math.e: if isinstance(d, const): return make_const(0) else: degDeriv = deriv(d) finalProduct = make_prod(p, degDeriv) return finalProduct else: raise Exception('power deriv: case 6:' + str(p)) elif isinstance(b, ln): if isinstance(d, const): newDeg = d.get_val() - 1 p = pwr(b, const(newDeg)) p = prod(const(newDeg + 1), p) b = deriv(b) finalResult = prod(p, b) return finalResult else: raise Exception('power_deriv: case 7: ' + str(p))
def make_pwr(var_name, d): return pwr(base=var(name=var_name), deg=const(val=d))
def prod_deriv(p): assert isinstance(p, prod) m1 = p.get_mult1() # 6 m2 = p.get_mult2() # x^3 if isinstance(m1, const): if isinstance(m2, const): return const(0) elif isinstance(m2, pwr): # 6*(x^3)=> 6*3*(x^(3-1)) # get 6 * 3 alt1 = prod(m1, m2.get_deg()) # get x^3-1 alt2 = pwr(m2.get_base(), plus(m2.get_deg(), const(-1))) return prod(alt1, alt2) elif isinstance(m2, plus): # 3*(x+1) if isinstance(deriv(m2), const): return const(0) else: return prod(m1, deriv(m2)) elif isinstance(m2, prod): # 4*(3x) if isinstance(deriv(m2), const): return const(0) else: return prod(m1, deriv(m2)) else: raise Exception('prod_deriv: case 0' + str(p)) elif isinstance(m1, plus): if isinstance(m2, const): # (x+1)*3 if isinstance(deriv(m2), const): return const(0) else: return prod(m1, deriv(m2)) elif isinstance(m2, pwr): # (1+x)*(2^3) pass elif isinstance(m2, plus): # (1+x)*(x+3) pass elif isinstance(m2, prod): # (3+x)*(2x) pass else: raise Exception('prod_deriv: case 1:' + str(p)) elif isinstance(m1, pwr): if isinstance(m2, const): # (x^2)*3 => (2x^1)*3 if isinstance(deriv(m2), const): return const(0) else: return prod(deriv(m1), m2) elif isinstance(m2, pwr): pass elif isinstance(m2, plus): pass elif isinstance(m2. prod): pass else: raise Exception('prod_deriv: case 2:' + str(p)) elif isinstance(m1, prod): if isinstance(m2, const):#(3x)*4 if isinstance(deriv(m2), const): return const(0) else: return prod(deriv(m1), m2) elif isinstance(m2, pwr): pass elif isinstance(m2, plus): pass elif isinstance(m2, prod): pass # if isinstance(deriv(m2), const): # return const(0) # else: # return prod(deriv(m1), m2) else: raise Exception('prod_deriv: case 3:' + str(p)) else: raise Exception('prod_deriv: case 4:' + str(p))
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_pwr(var_name, d): assert isinstance(d, int) or isinstance(d, float) return pwr(base=maker.make_var(var_name), deg=maker.make_const(d))
def make_pwr_expr(expr, deg): return pwr(base=expr, deg=const(val=deg))
def quot_deriv(q): num = q.get_num() denom = q.get_denom() newexpr = prod(mult1=num,mult2=pwr(base=denom,deg=make_const(-1.0))) return deriv(newexpr)
def quotToProd(expr): assert isinstance(expr, quot), 'must be a quot' num = expr.get_num() denom = expr.get_denom() p = prod(num,pwr(denom,const(-1.0))) return p
def make_pwr_expr(expr, deg): if isinstance(deg, const): return pwr(base=expr, deg=deg) else: return pwr(base=expr, deg=const(val=deg))