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 spread_of_news_model(p, k): assert isinstance(p, const) and isinstance(k, const) #t0 = 4 #t1 = ? #p = .5 * P => P(1 - e^(-k*4)) = .5*P (where t=4) => k = -0.25*ln(0.5) ~= 1.73 => f(t) = P(1 - e^(-1.73*t)) #p1 = .9 * P (p0 and p1 given) #we can now compute t1 #0.9*P = P(1 - e^(-1.73*t)) => t ~= 13.3 #generally #f(t) = P(1-e^(-kt)) we know that f(0) = 0 #where p0 is initial knowing pop at time t0 #and p1 is pop at time t1 #return f(t) #where f(t) = p*(1 - e^(-k*t)) #where k = (1/t0)*ln(p0) #so return p*(1 - e^(( -( (1/t0)*ln(p0) ) )*t)) #if given p0 and t0 #we are given k so: #return p*(1 - e^(-k*t)) return prod( p, plus( 1, prod(const(-1.0), make_e_expr(prod(prod(const(-1), k), make_pwr('t', 1))))))
class Example(object): CONST_A, CONST_B, CONST_C_WITH_UNDERSCORES = const("DASH") CONST_D, CONST_E = const("NUMBER0") CONST_F, CONST_G = const("SAME") N1, N2 = const("NUMBER1") SINGLE = const("DASH")
def maximize_revenue( dmnd_eq, constraint=lambda x: x >= 0): #only works on linear demand eqs rev = incrementPolyPwrs(dmnd_eq, 1) rev_drv = deriv(rev) # print 'eq:',dmnd_eq # print 'rev',rev # print 'rev deriv',rev_drv rev_drv_f = tof(rev_drv) dmnd_f = tof(dmnd_eq) rev_f = tof(rev) # print 'f(20)',dmnd_f(20) # print 'R(20)',rev_f(20) # print 'R`(20)',rev_drv_f(20) xtrm = loc_xtrm_2nd_drv_test(rev) for val in xtrm: # print val[0] # print val[1] x = val[1].get_x().get_val() y = val[1].get_y().get_val() if (val[0] == 'max' and constraint(x)): num_units = const(x) revenue = const(y) price = const(dmnd_f(x)) return (num_units, revenue, price)
def expected_rev_dir(demand_eq, price, price_direction): assert isinstance(price, const) assert isinstance(price_direction, const) assert price_direction.get_val() == 1 or \ price_direction.get_val() == -1 f = tof(demand_eq) p = price.get_val() E_p = demand_elasticity(demand_eq, price).get_val() p1 = p + price_direction.get_val() E_p_1 = demand_elasticity(demand_eq, const(p1)).get_val() #d/dp R(p) = f(p)(1 - E(p)) rprime_0 = f(p) * (1 - E_p) rprime_1 = f(p) * (1 - E_p_1) if rprime_0 > rprime_1: #old higher than new #will go down return const(-1.0) elif rprime_1 > rprime_0: #new higher than old #will go up return const(1.0) else: #will not change return const(0.0)
def find_poly_2_zeros(expr): firstpart = expr.get_elt1() firstpart_1 = firstpart.get_elt1() secondpart = firstpart.get_elt2() aconst = firstpart_1.get_mult1() bconst = secondpart.get_mult1() cconst = expr.get_elt2() a = aconst.get_val() b = bconst.get_val() c = cconst.get_val() #quadratic formula to get zeroes part1 = (b**2) - (4 * a * c) part2 = math.sqrt(part1) negb = b * -1 option1 = negb + part2 option2 = negb - part2 result1 = option1 / (2 * a) result2 = option2 / (2 * a) return const(result1), const(result2)
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(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)) 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)) 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)) else: raise Exception('power_deriv: case 6: ' + str(p))
def nra_ut_13(): #approximate a zero for x^3-3x^2+14x-2 f1 = make_plus(make_pwr('x', 3.0), make_prod(const(-3.0), make_pwr('x', 2.0))) f2 = make_plus(make_prod(const(14.0), make_pwr('x', 1.0)), const(-2.0)) fexpr = make_plus(f1, f2) approx = nra(fexpr, const(1.0), const(1000000)) print(approx)
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 percent_retention_model(lmbda, a): assert isinstance(lmbda, const) assert isinstance(a, const) #r(t) = (100 - a)*e^(-lmda*t) + a return plus( prod(plus(const(100.0), prod(const(-1.0), a)), make_e_expr(prod(prod(const(-1.0), lmbda), make_pwr('t', 1)))), a)
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 nra_ut_14(): #approximate a zero for x^2 - 17x + 14 f1 = make_plus(make_pwr('x', 2.0), make_prod(const(-17.0), make_pwr('x', 1.0))) fexpr = make_plus(f1, const(14.0)) approx = nra(fexpr, const(1.0), const(1000000)) gt = (17 - math.sqrt(233)) / 2 assert (approx - gt) <= .00001 print('Good approximation')
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 spread_of_news_model(p, k): assert isinstance(p, const) and isinstance(k, const) expon = const(-1.0 * k.get_val()) return make_prod( p, make_plus( const(1.0), make_prod(const(-1.0), make_e_expr(make_prod(expon, make_pwr('t', 1.0))))))
def percent_retention_model(lmbda, a): #r(t) = (100-a)e^(-lmbda*t) + a assert isinstance(lmbda, const) assert isinstance(a, const) left = const(100.0 - a.get_val()) right = make_e_expr( make_prod(const(-1.0 * lmbda.get_val()), make_pwr('t', 1.0))) return make_plus(make_prod(left, right), a)
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 problem_02(): demand_expr = make_plus(make_prod(const(-0.001), make_pwr('x', 1.0)), const(2.0)) print(demand_expr) num_units, rev, price = maximize_revenue( demand_expr, constraint=lambda x: 0 <= x <= 1000) print('x = ', num_units.get_val()) print("rev = ", rev.get_val()) print('price = ', price.get_val())
def flattenProduct(prd): while type(prd) == type(prod(const(1),const(2))) and type(prd.get_mult2()) == type(prod(const(1),const(2))) and type(prd.get_mult2().get_mult1()) == type(const(1)) and type(prd.get_mult1()) == type(const(1)): #while left is const and right is product with const in first arg prd = prod(const(prd.get_mult1().get_val()*prd.get_mult2().get_mult1().get_val()),prd.get_mult2().get_mult2())#combine left left = prd.get_mult1() right = prd.get_mult2() if type(right) == type(const(1)) and type(left) == type(const(1)): return const.mult(right,left) return prd
def problem_1_decay(): fex = make_e_expr(make_prod(const(-0.021), make_pwr('x', 1.0))) print(fex) P0 = const(8.0) expr, decay_const = fun1(fex, P0) print("f(x)= ", expr, "lambda=", decay_const) remaining = fun2(expr, 3.0) print("remaining= ", remaining) remaining_after_n_years = fun3(expr, 33.0, 40.0) print("after n years", remaining_after_n_years)
def find_infl_pnts(expr): drv = deriv(expr) drv_2 = deriv(drv) # print 'f`(x) = ', drv # print 'f``(x) = ', drv_2 zeros = None try: zeros = find_poly_1_zeros(drv_2) # print '1st degree poly' except Exception: # print 'not a 1st degree poly' pass try: zeros = find_poly_2_zeros(drv_2) # print '2nd degree poly' except Exception: # print 'not a 2nd degree poly' pass if isinstance(zeros, const): zeros = [zeros] # print 'zeros:' # for z in zeros: # print ':',z.get_val() f = tof(expr) f_dp = tof(drv_2) delta = 0.1 points = [] #will store array of points and if they are max/min #zeros may be None if no inflection points if not zeros == None: for z in zeros: z_val = f(z.get_val()) z_minus = f_dp(z.get_val() - delta) z_plus = f_dp(z.get_val() + delta) if z_minus < 0 and z_plus > 0: points.append(point2d(z, const(z_val))) if z_minus > 0 and z_plus < 0: points.append(point2d(z, const(z_val))) else: return None if points == []: return None else: # print points return points
def maximize_revenue(demand_expr, constraint): priceExpr = demand_expr priceExprFn = tof(priceExpr) revenueExpr = mult_x(priceExpr) extrema = loc_xtrm_1st_drv_test(revenueExpr) for i, j in extrema: if i == "max": x = j.get_x().get_val() if constraint(j.get_x().get_val()): price = priceExprFn(j.get_x().get_val()) max_revenue = price * j.get_x().get_val() return [(const(x)), (const(max_revenue)), (const(price))]
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 riemann_approx(fexpr, a, b, n, pp=0): ''' pp=0 - approximate with reimann midpoint pp=+1 - approximate with reimann right point pp=-1 - approximate with reiman left point ''' assert isinstance(a, const) assert isinstance(b, const) assert isinstance(n, const) area = 0 fex_tof = tof(fexpr) partition = (b.get_val() - a.get_val())/ n.get_val() a = int(a.get_val()) b = int(b.get_val()) if pp == -1: #left riemann for i in np.arange(a, b, partition): area += fex_tof(i)*partition elif pp == 1: #right riemann for i in np.arange(a+partition, b+partition, partition): area += fex_tof(i)*partition elif pp == 0: #midpoint riemann for i in np.arange(a, b, partition): mid = i + (partition/2) area += fex_tof(mid)*partition return const(area)
def incrementPolyPwrs(poly, inc): #handles first and second degree polys (ax^2 + bx + c) or (bx+c) a, b, c = None, None, None try: b, c = get_consts_poly_1(poly) return make_2nd_degree_poly(a=b, b=c, c=const(0.0)) # print '1st degree poly' except Exception: # print 'not a 1st degree poly' try: a, b, c = get_consts_poly_2(poly) return make_3rd_degree_poly(a=a, b=b, c=c, d=const(0.0)) # print '2nd degree poly' except Exception: # print 'not a 2nd degree poly' raise Exception('incrementPolyPwrs: ' + str(poly))
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 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) # find B B = const(((p.get_val() / p0.get_val()) - 1.0) / math.e**(t0.get_val())) x = const(((p.get_val() / p1.get_val()) - 1.0) / B.get_val()) #find k k = const(math.log(x.get_val()) / (-1.0 * p.get_val() * t1.get_val())) #simplify exponent before creating it expon = const(-1.0 * p.get_val() * k.get_val()) bottom = make_plus( make_const(1.0), make_prod(B, make_e_expr(make_prod(expon, make_pwr('t', 1.0))))) return make_quot(p, bottom)
def consumer_surplus(dexpr, a): assert isinstance(a, const) B = const(-1 * tof(dexpr)(a.get_val())) f = make_plus(dexpr, B) surplus = tof(antideriv(f)) return surplus(a.get_val()) - surplus(0)
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 find_poly_1_zeros(expr): firstpart = expr.get_elt1() a = firstpart.get_mult1() b = expr.get_elt2() fex1 = prod(mult1=b, mult2=-1) fex2 = make_quot(1, a) return const(val=prod(mult1=fex1, mult2=fex2))
def newton_raphson(poly_fexpr, g, n): tof_expr = tof(poly_fexpr) deriv_expr = tof(deriv(poly_fexpr)) for i in range(n.get_val()): x = g.get_val() - (tof_expr(g.get_val()) / deriv_expr(g.get_val())) g = const(x) return g