import%20marimo%0A%0A__generated_with%20%3D%20%220.11.20%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20import%20os%0A%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20import%20matplotlib.ticker%20as%20mtick%0A%20%20%20%20from%20matplotlib.ticker%20import%20FuncFormatter%0A%20%20%20%20import%20plotly.graph_objects%20as%20go%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20sympy%20as%20sm%0A%20%20%20%20from%20itertools%20import%20cycle%0A%20%20%20%20import%20pandas%20as%20pd%0A%20%20%20%20import%20statsmodels.api%20as%20stats%0A%0A%20%20%20%20np.random.seed(10)%0A%0A%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20os.chdir(%22assets%2Farticles%2Fnotebooks%22)%0A%20%20%20%20except%3A%0A%20%20%20%20%20%20%20%20pass%0A%0A%20%20%20%20def%20display_iframe(path%3Astr)%3A%0A%20%20%20%20%20%20%20%20%23%20Read%20the%20saved%20Plotly%20HTML%20file%0A%20%20%20%20%20%20%20%20with%20open(path%2C%20%22r%22)%20as%20f%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20html_content%20%3D%20f.read()%0A%0A%20%20%20%20%20%20%20%20%23%20Display%20it%20in%20Jupyter%20Notebook%0A%20%20%20%20%20%20%20%20return%20mo.iframe(html_content%2Cheight%3D'500px')%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20FuncFormatter%2C%0A%20%20%20%20%20%20%20%20cycle%2C%0A%20%20%20%20%20%20%20%20display_iframe%2C%0A%20%20%20%20%20%20%20%20go%2C%0A%20%20%20%20%20%20%20%20mo%2C%0A%20%20%20%20%20%20%20%20mtick%2C%0A%20%20%20%20%20%20%20%20np%2C%0A%20%20%20%20%20%20%20%20os%2C%0A%20%20%20%20%20%20%20%20pd%2C%0A%20%20%20%20%20%20%20%20plt%2C%0A%20%20%20%20%20%20%20%20sm%2C%0A%20%20%20%20%20%20%20%20stats%2C%0A%20%20%20%20)%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%20%20%20%20%23%20Optimization%2C%20Newton's%20Method%2C%20%26%20Profit%20Maximization%3A%20Part%203%20-%20Applied%20Profit%20Maximization%0A%20%20%20%20%20%20%20%20%3Ccenter%3E%20**Learn%20how%20to%20apply%20optimization%20%26%20econometric%20techniques%20to%20solve%20an%20applied%20profit%20maximization%20problem**%20%3C%2Fcenter%3E%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%20%20%20%20%23%23%20Introduction%0A%0A%20%20%20%20%20%20%20%20%3E%20This%20article%20is%20the%203rd%2C%20and%20final%2C%20in%20a%203%20part%20series.%20In%20the%20%3Ca%20href%3D%22%2Farticles%2Fnm1%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3E1st%20part%3C%2Fa%3E%2C%20we%20studied%20basic%20optimization%20theory.%20Then%2C%20in%20%3Ca%20href%3D%22%2Farticles%2Fnm1%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3Ept.%202%3C%2Fa%3E%2C%20we%20extended%20this%20theory%20to%20constrained%20optimization%20problems.%20Now%2C%20in%20pt.%203%2C%20we%20will%20apply%20the%20optimization%20theory%20covered%2C%20as%20well%20as%20econometric%20and%20economic%20theory%2C%20to%20solve%20a%20profit%20maximization%20problem.%0A%0A%0A%20%20%20%20%20%20%20%20Suppose%2C%20as%20a%20data%20scientist%20working%20for%20your%20company%2C%20you%20are%20tasked%20with%20estimating%20the%20optimal%20amount%20of%20money%20to%20allocate%20towards%20different%20advertising%20channels%20that%20will%20maximize%20the%20overall%20profit%20of%20a%20certain%20product%20line.%20Furthermore%2C%20suppose%20you%20are%20given%20constraints%20on%20these%20allocation%20decisions%2C%20such%20as%20the%20maximum%20total%20spend%20you%20have%20to%20allocate%20and%2For%20minimum%20amounts%20that%20have%20to%20spent%20in%20certain%20channels.%20In%20this%20article%2C%20we%20are%20going%20to%20combine%20the%20optimization%20theory%20covered%20in%20part%201%20and%20part%202%20of%20this%20series%2C%20along%20with%20additional%20economic%20and%20econometric%20theory%20to%20tackle%20a%20theoretical%20profit%20maximization%20problem%20of%20this%20sorts%20%E2%80%94%20which%20we%20will%20flesh%20out%20in%20more%20detail%20in%20this%20article.%0A%0A%20%20%20%20%20%20%20%20The%20goal%20of%20this%20article%20is%20to%20tie%20together%20what%20we%20have%20learned%20thus%20far%20and%20my%20hope%20is%20to%20motivate%20and%20inspire%20readers%20on%20how%20to%20incorporate%20these%20techniques%20into%20an%20applied%20setting.%20It%20is%20not%20meant%20to%20be%20a%20comprehensive%20solution%20to%20the%20problem%20covered%20as%20nuances%20and%20idiosyncrasies%20can%2C%20of%20course%2C%20complicate%20theoretical%20examples.%20Furthermore%2C%20many%20of%20the%20techniques%20covered%20have%20much%20more%20optimized%20implementations%20in%20python%20via%20packages%20such%20as%20%5Bpyomo%5D(https%3A%2F%2Fwww.pyomo.org%2F)%2C%20%5BSciPy%5D(https%3A%2F%2Fdocs.scipy.org%2Fdoc%2Fscipy%2Ftutorial%2Foptimize.html)%2C%20etc.%20Nevertheless%2C%20I%20hope%20to%20provide%20a%20strong%20framework%20for%20constructing%20applied%20optimization%20problems.%20Let%E2%80%99s%20dive%20into%20it!%0A%0A%20%20%20%20%20%20%20%20%23%23%20Optimization%20Theory%20-%20Parts%201%20%26%202%20Recap%0A%20%20%20%20%20%20%20%20%3E%20**Brief%20Recap%3A**%20In%20part%201%2C%20we%20covered%20basic%20optimization%20theory%20%E2%80%94%20including%201)%20setting%20up%20and%20solving%20a%20simple%20single%20variable%20optimization%20problem%20analytically%2C%202)%20iterative%20optimization%20schemes%20%E2%80%94%20namely%2C%20gradient%20descent%20%26%20Newton%E2%80%99s%20Method%2C%20and%203)%20implementing%20Newton%E2%80%99s%20method%20by%20hand%20and%20in%20python%20for%20a%20multi-dimensional%20optimization%20problem.%20In%20part%202%2C%20we%20covered%20constrained%20optimization%20theory%20%E2%80%94%20including%201)%20incorporating%20equality%20constraints%20and%202)%20incorporating%20inequality%20constraints%20into%20our%20optimization%20problems%20and%20solving%20them%20via%20Newton%E2%80%99s%20Method.%20This%20article%20is%20designed%20to%20be%20accessible%20for%20those%20who%20are%20already%20familiar%20with%20the%20content%20covered%20in%20part%201%20and%20part%202.%0A%0A%20%20%20%20%20%20%20%20A%20mathematical%20optimization%20problem%20can%20be%20formulated%20abstractly%20as%20follows%3A%0A%0A%20%20%20%20%20%20%20%20%24%24%0A%20%20%20%20%20%20%20%20%5Cbegin%7Bequation%7D%0A%20%20%20%20%20%20%20%20%5Cbegin%7Baligned%7D%0A%20%20%20%20%20%20%20%20%5Cmin_%7B%5Cmathbf%7Bx%7D%7D%20%5Cquad%26%20f(%5Cmathbf%7Bx%7D)%2C%20%5Cmathbf%7Bx%7D%3D%5Bx_1%2Cx_2%2C%5Cdots%2Cx_n%5D%5ET%20%5Cin%20%5Cmathbb%7BR%7D%5En%20%5C%5C%0A%20%20%20%20%20%20%20%20%5Ctext%7Bsubject%20to%7D%20%5Cquad%26%20g_j(%5Cmathbf%7Bx%7D)%20%5Cle%200%2C%20j%3D1%2C2%2C%5Cdots%2Cm%20%5C%5C%0A%20%20%20%20%20%20%20%20%26%20h_j(%5Cmathbf%7Bx%7D)%20%3D%200%2C%20j%3D1%2C2%2C%5Cdots%2Cr%20%0A%20%20%20%20%20%20%20%20%5Cend%7Baligned%7D%0A%20%20%20%20%20%20%20%20%5Ctag%7B1%7D%0A%20%20%20%20%20%20%20%20%5Cend%7Bequation%7D%0A%20%20%20%20%20%20%20%20%24%24%0A%0A%20%20%20%20%20%20%20%20where%20we%20choose%20real%20values%20of%20the%20vector%20%24%5Cmathbf%7Bx%7D%24%20that%20minimize%20the%20objective%20function%20%24f(x)%24%20(or%20maximize%20%24-f(x)%24)%20subject%20to%20the%20inequality%20constraints%20%24g(x)%24%20and%20equality%20constraints%20%24h(x)%24.%20In%20part%202%2C%20we%20discussed%20how%20to%20incorporate%20these%20constraints%20directly%20into%20our%20optimization%20problem.%20Notably%2C%20using%20Lagrange%20Multipliers%20and%20Logarithmic%20Barrier%20functions%20we%20can%20construct%20a%20new%20objective%20function%20%24%5Cmathcal%7BO%7D(%5Cmathbf%7Bx%7D%2C%20%5CLambda%2C%20%5Crho)%24%3A%0A%0A%20%20%20%20%20%20%20%20%24%24%0A%20%20%20%20%20%20%20%20%5Cbegin%7Bequation%7D%0A%20%20%20%20%20%20%20%20%5Cbegin%7Baligned%7D%0A%20%20%20%20%20%20%20%20%5Cmathcal%7BO%7D%0A%20%20%20%20%20%20%20%20(%5Cmathbf%7Bx%7D%2C%5CLambda%2C%5Crho)%20%26%3D%20f(%5Cmathbf%7Bx%7D)%20%2B%20%5Csum%5Er_%7Bj%3D1%7D%5Clambda_jh_j(%5Cmathbf%7Bx%7D)-%20%5Crho%5Csum%5Em_%7Bj%3D1%7D%5Clog(c_j(%5Cmathbf%7Bx%7D))%2C%20%5C%5C%0A%20%20%20%20%20%20%20%20%5Cmathbf%7Bx%7D%26%3D%5Bx_1%2Cx_2%2C%5Cdots%2Cx_n%5D%20%5C%5C%5B6pt%5D%0A%20%20%20%20%20%20%20%20%5CLambda%20%26%3D%20%5B%5Clambda_1%2C%5Clambda_2%2C%5Cdots%2C%5Clambda_r%5D%20%5C%5C%5B6pt%5D%0A%20%20%20%20%20%20%20%20c_j(%5Cmathbf%7Bx%7D)%20%26%3D%20%5Cbegin%7Bcases%7D%20%0A%20%20%20%20%20%20%20%20g_j(%5Cmathbf%7Bx%7D)%2C%20%26%20g_j(%5Cmathbf%7Bx%7D)%20%5Cgeq%200%20%5C%5C%0A%20%20%20%20%20%20%20%20-g_j(%5Cmathbf%7Bx%7D)%2C%20%26%20g_j(%5Cmathbf%7Bx%7D)%20%3C%200%0A%20%20%20%20%20%20%20%20%5Cend%7Bcases%7D%0A%20%20%20%20%20%20%20%20%5Cend%7Baligned%7D%0A%20%20%20%20%20%20%20%20%5Ctag%7B2%7D%0A%20%20%20%20%20%20%20%20%5Cend%7Bequation%7D%0A%20%20%20%20%20%20%20%20%24%24%0A%0A%20%20%20%20%20%20%20%20where%20%24%5CLambda%24%20is%20the%20vector%20of%20Lagrange%20multipliers%20associated%20with%20each%20equality%20constraints%20%24h(x)%24%20and%20%24%5Crho%24%20is%20the%20barrier%20parameter%20associated%20with%20all%20of%20the%20inequality%20constraints%20%24g(x)%24.%20We%20can%20then%20solve%20this%20new%20objective%20function%20iterating%20by%20choose%20a%20starting%20value%20%24%5Crho%24%20(note%20that%20large%20functional%20values%20of%20the%20objective%20function%20will%20require%20much%20larger%20starting%20values%20of%20%24%5Crho%24%20to%20scale%20the%20penalization)%2C%20optimize%20the%20new%20objective%20function%20evaluated%20at%20%24%5Crho%24%20using%20Newton%E2%80%99s%20method%20iterative%20scheme%2C%20then%20update%20%24%5Crho%24%20by%20slowly%20decreasing%20it%20(%24%5Crho%20%5Crightarrow%200%24)%2C%20and%20repeat%20until%20convergence%20%E2%80%94%20where%20Newton%E2%80%99s%20Method%20iterative%20scheme%20is%20as%20follows%3A%0A%0A%20%20%20%20%20%20%20%20%24%24%0A%20%20%20%20%20%20%20%20%5Cbegin%7Bequation%7D%0A%20%20%20%20%20%20%20%20%5Cmathbf%7Bx%7D_%7Bk%2B1%7D%20%3D%20%5Cmathbf%7Bx%7D_k%20-%5Cmathbf%7BH%7D%5E%7B-1%7D(%5Cmathbf%7Bx%7D_k)%5Cnabla%20f(%5Cmathbf%7Bx%7D_k)%0A%20%20%20%20%20%20%20%20%5Ctag%7B3%7D%0A%20%20%20%20%20%20%20%20%5Cend%7Bequation%7D%0A%20%20%20%20%20%20%20%20%24%24%0A%0A%20%20%20%20%20%20%20%20where%20%24%5Cmathbf%7BH%7D(%5Cmathbf%7Bx%7D)%24%20and%20%24%5Cnabla%20f(x)%24%20denote%20the%20Hessian%20and%20gradient%20of%20our%20objective%20function%20%24%5Cmathcal%7BO%7D(%5Cmathbf%7Bx%7D%2C%20%5CLambda%2C%20%5Crho)%24%2C%20respectively.%20Convergence%20is%20obtained%20when%20we%20reach%20convergence%20across%20one%20or%20more%20of%20the%20following%20criteria%3A%0A%0A%20%20%20%20%20%20%20%20%24%24%0A%20%20%20%20%20%20%20%20%5Cbegin%7Bequation%7D%0A%20%20%20%20%20%20%20%20%5Cbegin%7Baligned%7D%0A%20%20%20%20%20%20%20%20%26%5Ctext%7BCriteria%201%3A%20%7D%20%5ClVert%20%5Cmathbf%7Bx%7D_k%20-%20%5Cmathbf%7Bx%7D_%7Bk-1%7D%20%5CrVert%20%3C%20%5Cepsilon_1%20%5C%5C%5B6pt%5D%0A%20%20%20%20%20%20%20%20%26%5Ctext%7BCriteria%202%3A%20%7D%20%5Clvert%20f(%5Cmathbf%7Bx%7D_k)%20-%20f(%5Cmathbf%7Bx%7D_%7Bk-1%7D)%20%5Crvert%20%3C%20%5Cepsilon_2%0A%20%20%20%20%20%20%20%20%5Cend%7Baligned%7D%0A%20%20%20%20%20%20%20%20%5Ctag%7B4%7D%0A%20%20%20%20%20%20%20%20%5Cend%7Bequation%7D%0A%20%20%20%20%20%20%20%20%24%24%0A%0A%20%20%20%20%20%20%20%20In%20python%2C%20utilizing%20%5BSymPy%5D(https%3A%2F%2Fwww.sympy.org%2Fen%2Findex.html)%2C%20we%20have%204%20functions.%20A%20function%20that%20obtains%20the%20gradient%20of%20our%20SymPy%20function%2C%20the%20Hessian%20of%20our%20SymPy%20function%2C%20solves%20unconstrained%20optimization%20problem%20via%20Newton%E2%80%99s%20method%2C%20and%20solves%20a%20constrained%20optimization%20problem%20via%20Newton%E2%80%99s%20method%20according%20to%20the%20generalization%20eq.%20(2).%0A%0A%20%20%20%20%20%20%20%20To%20solve%20a%20constrained%20optimization%20problem%2C%20we%20can%20run%20the%20following%20code%20(Make%20sure%20starting%20values%20are%20in%20the%20feasible%20range%20of%20inequality%20constraints!)%3A%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(np%2C%20sm)%3A%0A%20%20%20%20%23%20Functions%20constructed%20in%20Part%201%20%2B%20Part%202%0A%0A%20%20%20%20def%20get_gradient(%0A%20%20%20%20%20%20%20%20function%3A%20sm.Expr%2C%0A%20%20%20%20%20%20%20%20symbols%3A%20list%5Bsm.Symbol%5D%2C%0A%20%20%20%20%20%20%20%20x0%3A%20dict%5Bsm.Symbol%2C%20float%5D%2C%20%20%23%20Add%20x0%20as%20argument%0A%20%20%20%20)%20-%3E%20np.ndarray%3A%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20%20%20%20%20Calculate%20the%20gradient%20of%20a%20function%20at%20a%20given%20point.%0A%0A%20%20%20%20%20%20%20%20Args%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20function%20(sm.Expr)%3A%20The%20function%20to%20calculate%20the%20gradient%20of.%0A%20%20%20%20%20%20%20%20%20%20%20%20symbols%20(list%5Bsm.Symbol%5D)%3A%20The%20symbols%20representing%20the%20variables%20in%20the%20function.%0A%20%20%20%20%20%20%20%20%20%20%20%20x0%20(dict%5Bsm.Symbol%2C%20float%5D)%3A%20The%20point%20at%20which%20to%20calculate%20the%20gradient.%0A%0A%20%20%20%20%20%20%20%20Returns%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20numpy.ndarray%3A%20The%20gradient%20of%20the%20function%20at%20the%20given%20point.%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20%20%20%20%20d1%20%3D%20%7B%7D%0A%20%20%20%20%20%20%20%20gradient%20%3D%20np.array(%5B%5D)%0A%0A%20%20%20%20%20%20%20%20for%20i%20in%20symbols%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20d1%5Bi%5D%20%3D%20sm.diff(function%2C%20i%2C%201).evalf(subs%3Dx0)%20%20%23%20add%20evalf%20method%0A%20%20%20%20%20%20%20%20%20%20%20%20gradient%20%3D%20np.append(gradient%2C%20d1%5Bi%5D)%0A%0A%20%20%20%20%20%20%20%20return%20gradient.astype(np.float64)%20%20%23%20Change%20data%20type%20to%20float%0A%0A%20%20%20%20def%20get_hessian(%0A%20%20%20%20%20%20%20%20function%3A%20sm.Expr%2C%0A%20%20%20%20%20%20%20%20symbols%3A%20list%5Bsm.Symbol%5D%2C%0A%20%20%20%20%20%20%20%20x0%3A%20dict%5Bsm.Symbol%2C%20float%5D%2C%0A%20%20%20%20)%20-%3E%20np.ndarray%3A%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20%20%20%20%20Calculate%20the%20Hessian%20matrix%20of%20a%20function%20at%20a%20given%20point.%0A%0A%20%20%20%20%20%20%20%20Args%3A%0A%20%20%20%20%20%20%20%20function%20(sm.Expr)%3A%20The%20function%20for%20which%20the%20Hessian%20matrix%20is%20calculated.%0A%20%20%20%20%20%20%20%20symbols%20(list%5Bsm.Symbol%5D)%3A%20The%20list%20of%20symbols%20used%20in%20the%20function.%0A%20%20%20%20%20%20%20%20x0%20(dict%5Bsm.Symbol%2C%20float%5D)%3A%20The%20point%20at%20which%20the%20Hessian%20matrix%20is%20evaluated.%0A%0A%20%20%20%20%20%20%20%20Returns%3A%0A%20%20%20%20%20%20%20%20numpy.ndarray%3A%20The%20Hessian%20matrix%20of%20the%20function%20at%20the%20given%20point.%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20%20%20%20%20d2%20%3D%20%7B%7D%0A%20%20%20%20%20%20%20%20hessian%20%3D%20np.array(%5B%5D)%0A%0A%20%20%20%20%20%20%20%20for%20i%20in%20symbols%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20j%20in%20symbols%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20d2%5Bf%22%7Bi%7D%7Bj%7D%22%5D%20%3D%20sm.diff(function%2C%20i%2C%20j).evalf(subs%3Dx0)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20hessian%20%3D%20np.append(hessian%2C%20d2%5Bf%22%7Bi%7D%7Bj%7D%22%5D)%0A%0A%20%20%20%20%20%20%20%20hessian%20%3D%20np.array(np.array_split(hessian%2C%20len(symbols)))%0A%0A%20%20%20%20%20%20%20%20return%20hessian.astype(np.float64)%0A%0A%20%20%20%20def%20newtons_method(%0A%20%20%20%20%20%20%20%20function%3A%20sm.Expr%2C%0A%20%20%20%20%20%20%20%20symbols%3A%20list%5Bsm.Symbol%5D%2C%0A%20%20%20%20%20%20%20%20x0%3A%20dict%5Bsm.Symbol%2C%20float%5D%2C%0A%20%20%20%20%20%20%20%20iterations%3A%20int%20%3D%20100%2C%0A%20%20%20%20%20%20%20%20tolerance%3A%20float%20%3D%2010e-5%2C%0A%20%20%20%20%20%20%20%20verbose%3A%20int%20%3D%201%2C%0A%20%20%20%20)%20-%3E%20dict%5Bsm.Symbol%2C%20float%5D%20or%20None%3A%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20%20%20%20%20Perform%20Newton's%20method%20to%20find%20the%20solution%20to%20the%20optimization%20problem.%0A%0A%20%20%20%20%20%20%20%20Args%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20function%20(sm.Expr)%3A%20The%20objective%20function%20to%20be%20optimized.%0A%20%20%20%20%20%20%20%20%20%20%20%20symbols%20(list%5Bsm.Symbol%5D)%3A%20The%20symbols%20used%20in%20the%20objective%20function.%0A%20%20%20%20%20%20%20%20%20%20%20%20x0%20(dict%5Bsm.Symbol%2C%20float%5D)%3A%20The%20initial%20values%20for%20the%20symbols.%0A%20%20%20%20%20%20%20%20%20%20%20%20iterations%20(int%2C%20optional)%3A%20The%20maximum%20number%20of%20iterations.%20Defaults%20to%20100.%0A%20%20%20%20%20%20%20%20%20%20%20%20tolerance%20(float%2C%20optional)%3A%20Threshold%20for%20determining%20convergence.%0A%20%20%20%20%20%20%20%20%20%20%20%20verbose%20(int%2C%20optional)%3A%20Control%20verbosity%20of%20output.%200%20is%20no%20output%2C%201%20is%20full%20output.%0A%0A%20%20%20%20%20%20%20%20Returns%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20dict%5Bsm.Symbol%2C%20float%5D%20or%20None%3A%20The%20solution%20to%20the%20optimization%20problem%2C%20or%20None%20if%20no%20solution%20is%20found.%0A%20%20%20%20%20%20%20%20%22%22%22%0A%0A%20%20%20%20%20%20%20%20x_star%20%3D%20%7B%7D%0A%20%20%20%20%20%20%20%20x_star%5B0%5D%20%3D%20np.array(list(x0.values()))%0A%0A%20%20%20%20%20%20%20%20if%20verbose%20!%3D%200%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20print(f%22Starting%20Values%3A%20%7Bx_star%5B0%5D%7D%22)%0A%0A%20%20%20%20%20%20%20%20for%20i%20in%20range(iterations)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20gradient%20%3D%20get_gradient(function%2C%20symbols%2C%20dict(zip(x0.keys()%2C%20x_star%5Bi%5D)))%0A%20%20%20%20%20%20%20%20%20%20%20%20hessian%20%3D%20get_hessian(function%2C%20symbols%2C%20dict(zip(x0.keys()%2C%20x_star%5Bi%5D)))%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20x_star%5Bi%20%2B%201%5D%20%3D%20x_star%5Bi%5D.T%20-%20np.linalg.inv(hessian)%20%40%20gradient.T%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20np.linalg.norm(x_star%5Bi%20%2B%201%5D%20-%20x_star%5Bi%5D)%20%3C%20tolerance%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20solution%20%3D%20dict(zip(x0.keys()%2C%20%5Bfloat(x)%20for%20x%20in%20x_star%5Bi%20%2B%201%5D%5D))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20verbose%20!%3D%200%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f%22%5CnConvergence%20Achieved%20(%7Bi%2B1%7D%20iterations)%3A%20Solution%20%3D%20%7Bsolution%7D%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20solution%20%3D%20None%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20verbose%20!%3D%200%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(f%22Step%20%7Bi%2B1%7D%3A%20%7Bx_star%5Bi%2B1%5D%7D%22)%0A%0A%20%20%20%20%20%20%20%20return%20solution%0A%0A%20%20%20%20def%20constrained_newtons_method(%0A%20%20%20%20%20%20%20%20function%3A%20sm.Expr%2C%0A%20%20%20%20%20%20%20%20symbols%3A%20list%5Bsm.Symbol%5D%2C%0A%20%20%20%20%20%20%20%20x0%3A%20dict%5Bsm.Symbol%2C%20float%5D%2C%0A%20%20%20%20%20%20%20%20rho_steps%3A%20int%20%3D%20100%2C%0A%20%20%20%20%20%20%20%20discount_rate%3A%20float%20%3D%200.9%2C%0A%20%20%20%20%20%20%20%20newton_method_iterations%3A%20int%20%3D%20100%2C%0A%20%20%20%20%20%20%20%20tolerance%3A%20float%20%3D%2010e-5%2C%0A%20%20%20%20)%20-%3E%20dict%5Bsm.Symbol%2C%20float%5D%20%7C%20None%3A%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20%20%20%20%20Performs%20constrained%20Newton's%20method%20to%20find%20the%20optimal%20solution%20of%20a%20function%20subject%20to%20constraints.%0A%0A%20%20%20%20%20%20%20%20Args%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20function%20(sm.Expr)%3A%20The%20function%20to%20optimize.%0A%20%20%20%20%20%20%20%20%20%20%20%20symbols%20(list%5Bsm.Symbol%5D)%3A%20The%20symbols%20used%20in%20the%20function.%0A%20%20%20%20%20%20%20%20%20%20%20%20x0%20(dict%5Bsm.Symbol%2C%20float%5D)%3A%20The%20initial%20values%20for%20the%20symbols.%0A%20%20%20%20%20%20%20%20%20%20%20%20rho_steps%20(int%2C%20optional)%3A%20The%20number%20of%20steps%20to%20update%20rho.%20Defaults%20to%20100.%0A%20%20%20%20%20%20%20%20%20%20%20%20discount_rate%20(float%2C%20optional)%3A%20The%20scalar%20to%20discount%20rho%20by%20at%20each%20step.%20Default%20is%200.9.%0A%20%20%20%20%20%20%20%20%20%20%20%20newton_method_iterations%20(int%2C%20optional)%3A%20The%20maximum%20number%20of%20iterations%20in%20Newton%20Method%20internal%20loop.%20Defaults%20to%20100.%0A%20%20%20%20%20%20%20%20%20%20%20%20tolerance%20(float%2C%20optional)%3A%20Threshold%20for%20determining%20convergence.%0A%0A%20%20%20%20%20%20%20%20Returns%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20dict%5Bsm.Symbol%2C%20float%5D%20or%20None%3A%20The%20optimal%20solution%20if%20convergence%20is%20achieved%2C%20otherwise%20None.%0A%20%20%20%20%20%20%20%20%22%22%22%0A%0A%20%20%20%20%20%20%20%20rho%20%3D%20list(x0.keys())%5B-1%5D%0A%20%20%20%20%20%20%20%20optimal_solutions%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20optimal_solutions.append(x0)%0A%0A%20%20%20%20%20%20%20%20for%20step%20in%20range(rho_steps)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20step%20%25%2010%20%3D%3D%200%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(%22%5Cn%22%20%2B%20%22%3D%3D%3D%22%20*%2020)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(f%22Step%20%7Bstep%7D%20w%2F%20rho%3D%7Boptimal_solutions%5Bstep%5D%5Brho%5D%7D%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(%22%3D%3D%3D%22%20*%2020%20%2B%20%22%5Cn%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(f%22Current%20solution%3A%20%7Boptimal_solutions%5Bstep%5D%7D%22)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20function_eval%20%3D%20function.evalf(subs%3D%7Brho%3A%20optimal_solutions%5Bstep%5D%5Brho%5D%7D)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20values%20%3D%20optimal_solutions%5Bstep%5D.copy()%0A%20%20%20%20%20%20%20%20%20%20%20%20del%20values%5Brho%5D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20optimal_solution%20%3D%20newtons_method(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20function_eval%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20symbols%5B%3A-1%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20values%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20iterations%3Dnewton_method_iterations%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tolerance%3Dtolerance%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20verbose%3D0%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20optimal_solutions.append(optimal_solution)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Check%20for%20overall%20convergence%0A%20%20%20%20%20%20%20%20%20%20%20%20current_solution%20%3D%20np.array(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5Bv%20for%20k%2C%20v%20in%20optimal_solutions%5Bstep%5D.items()%20if%20k%20!%3D%20rho%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20previous_solution%20%3D%20np.array(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5Bv%20for%20k%2C%20v%20in%20optimal_solutions%5Bstep%20-%201%5D.items()%20if%20k%20!%3D%20rho%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20np.linalg.norm(current_solution%20-%20previous_solution)%20%3C%20tolerance%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20overall_solution%20%3D%20optimal_solutions%5Bstep%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20del%20overall_solution%5Brho%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f%22%5Cn%20Overall%20Convergence%20Achieved%20(%7Bstep%7D%20steps)%3A%20Solution%20%3D%20%7Boverall_solution%7D%5Cn%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20overall_solution%20%3D%20None%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Update%20rho%0A%20%20%20%20%20%20%20%20%20%20%20%20optimal_solutions%5Bstep%20%2B%201%5D%5Brho%5D%20%3D%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20discount_rate%20*%20optimal_solutions%5Bstep%5D%5Brho%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20return%20overall_solution%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20constrained_newtons_method%2C%0A%20%20%20%20%20%20%20%20get_gradient%2C%0A%20%20%20%20%20%20%20%20get_hessian%2C%0A%20%20%20%20%20%20%20%20newtons_method%2C%0A%20%20%20%20)%0A%0A%0A%40app.cell%0Adef%20_(constrained_newtons_method%2C%20sm)%3A%0A%20%20%20%20def%20combined_rosenbrocks()%3A%0A%20%20%20%20%20%20%20%20x%2C%20y%2C%20%CE%BB%2C%20%CF%81%20%3D%20sm.symbols(%22x%20y%20%CE%BB%20%CF%81%22)%0A%0A%20%20%20%20%20%20%20%20%23%20f(x)%3A%20100*(y-x**2)**2%20%2B%20(1-x)**2%0A%20%20%20%20%20%20%20%20%23%20h(x)%3A%20x**2%20-%20y%20%3D%202%0A%20%20%20%20%20%20%20%20%23%20g_1(x)%3A%20x%20%3C%3D%200%0A%20%20%20%20%20%20%20%20%23%20g_2(x)%20y%20%3E%3D%203%0A%0A%20%20%20%20%20%20%20%20combined_objective%20%3D%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20100%20*%20(y%20-%20x**2)%20**%202%0A%20%20%20%20%20%20%20%20%20%20%20%20%2B%20(1%20-%20x)%20**%202%0A%20%20%20%20%20%20%20%20%20%20%20%20%2B%20%CE%BB%20*%20(x**2%20-%20y%20-%202)%0A%20%20%20%20%20%20%20%20%20%20%20%20-%20%CF%81%20*%20sm.log((-x)%20*%20(y%20-%203))%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20Gamma%20%3D%20%5Bx%2C%20y%2C%20%CE%BB%2C%20%CF%81%5D%20%20%23%20Function%20requires%20last%20symbol%20to%20be%20%CF%81!%0A%20%20%20%20%20%20%20%20Gamma0%20%3D%20%7Bx%3A%20-15%2C%20y%3A%2015%2C%20%CE%BB%3A%200%2C%20%CF%81%3A%2010%7D%0A%0A%20%20%20%20%20%20%20%20return%20constrained_newtons_method(combined_objective%2C%20Gamma%2C%20Gamma0)%0A%0A%20%20%20%20_%20%3D%20combined_rosenbrocks()%0A%20%20%20%20return%20(combined_rosenbrocks%2C)%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%20%20%20%20If%20the%20material%20above%20felt%20foreign%20or%20you%20need%20a%20more%20rigorous%20recap%2C%20then%20I%20recommend%20taking%20a%20look%20at%20part%201%20and%20part%202%20of%20this%20series%20which%20will%20provide%20a%20more%20in-depth%20survey%20of%20the%20material%20above.%20For%20the%20remainder%20of%20this%20article%2C%20we%20will%20first%20discuss%20basic%20profit%20maximization%20%26%20econometric%20theory%20and%20then%20move%20into%20solving%20the%20theoretical%20example.%0A%0A%20%20%20%20%20%20%20%20%23%23%20Applied%20Profit%20Maximization%0A%0A%20%20%20%20%20%20%20%20%3E%20**Problem%3A**%20Suppose%20we%20have%20a%20%24100%2C000%20advertising%20budget%20and%20all%20of%20it%20must%20be%20spent.%20We%20are%20tasked%20with%20choosing%20the%20optimal%20amount%20of%20this%20budget%20to%20allocate%20towards%20two%20types%20of%20advertisement%20channels%20(digital%20ads%20and%20television%20ads)%20that%20maximize%20the%20overall%20profit%20for%20a%20particular%20product%20line.%20Furthermore%2C%20suppose%20that%20we%20must%20allocate%20at%20a%20minimum%20of%20%2420k%20to%20television%20advertising%20and%20%2410k%20to%20digital%20advertising.%0A%0A%20%20%20%20%20%20%20%20%23%23%23%20Theoretical%20Formulation%0A%0A%20%20%20%20%20%20%20%20Let's%20now%20mathematically%20formulate%20the%20profit%20maximization%20problem%20we%20seek%20to%20solve%3A%0A%0A%20%20%20%20%20%20%20%20%24%24%0A%20%20%20%20%20%20%20%20%5Cbegin%7Bequation%7D%0A%20%20%20%20%20%20%20%20%5Cbegin%7Baligned%7D%0A%20%20%20%20%20%20%20%20%5Cmin_%7B%5Cdelta%2C%5Ctau%7D%20%5Cquad%26%20-%5Cpi(%5Cdelta%2C%5Ctau%2C%5Ccdot)%20%5C%5C%0A%20%20%20%20%20%20%20%20%5Ctext%7Bsubject%20to%7D%20%5Cquad%26%20%5Ctextbf%7BBudget%20Constraint%3A%20%7D%20%5Cdelta%20%2B%20%5Ctau%20%3D%20%5Ctext%7B%5C%24100%2C000%7D%20%5C%5C%0A%20%20%20%20%20%20%20%20%26%5Ctextbf%7BMinimum%20Requirements%3A%20%7D%20%5Cdelta%20%5Cge%20%5Ctext%7B%5C%2410%2C000%7D%2C%20%5Ctext%7B%20%7D%20%5Ctau%20%5Cge%20%5Ctext%7B%5C%2420%2C000%7D%20%5C%5C%0A%20%20%20%20%20%20%20%20%5Cend%7Baligned%7D%0A%20%20%20%20%20%20%20%20%5Ctag%7B5%7D%0A%20%20%20%20%20%20%20%20%5Cend%7Bequation%7D%0A%20%20%20%20%20%20%20%20%24%24%0A%0A%20%20%20%20%20%20%20%20where%20%24%5Cpi(%5Ccdot)%24%20denotes%20the%20profit%20function%2C%20%24%5Cdelta%24%20denotes%20digital%20ad%20spend%2C%20%24%5Ctau%24%20denotes%20television%20ad%20spend%2C%20and%20%24(%5Ccdot)%24%20is%20a%20placeholder%20for%20additional%20variables.%20Note%20that%20we%20are%20minimizing%20the%20negative%20of%20%24%5Cpi(%5Ccdot)%24%20which%20is%20equivalent%20to%20maximizing%20%24%5Cpi(%5Ccdot)%24.%20The%20profit%20function%20is%20defined%20as%20follows%3A%0A%0A%20%20%20%20%20%20%20%20%24%24%0A%20%20%20%20%20%20%20%20%5Cbegin%7Bequation%7D%0A%20%20%20%20%20%20%20%20%5Cbegin%7Baligned%7D%0A%20%20%20%20%20%20%20%20%5Cpi(%5Cdelta%2C%5Ctau%2C%5Ccdot)%20%26%3D%20%5Ctext%7BRevenue%7D-%5Ctext%7BCost%7D%20%5C%5C%20%0A%20%20%20%20%20%20%20%20%26%3D%20p%5Ctimes%20q(%5Cdelta%2C%5Ctau%2C%5Ccdot)-%5Cmathcal%7BC%7D%5Cbigl%5Bq(%5Cdelta%2C%5Ctau%2C%5Ccdot)%2C%5Cdelta%2C%5Ctau%5Cbigr%5D%0A%20%20%20%20%20%20%20%20%5Cend%7Baligned%7D%0A%20%20%20%20%20%20%20%20%5Ctag%7B6%7D%0A%20%20%20%20%20%20%20%20%5Cend%7Bequation%7D%0A%20%20%20%20%20%20%20%20%24%24%0A%0A%20%20%20%20%20%20%20%20where%20%24p%24%20denotes%20the%20price%2C%20%24q(%5Cdelta%2C%20%5Ctau%2C%20%5Ccdot)%24%20denotes%20the%20quantity%20demanded%20function%2C%20and%20%24%5Cmathcal%7BC%7D(q(%5Ccdot)%2C%20%5Cdelta%2C%20%5Ctau)%24%20denotes%20the%20cost%20function%20which%2C%20intuitively%2C%20is%20a%20direct%20function%20of%20the%20quantity%20(if%20we%20make%20more%20it%20will%20cost%20more%20to%20produce)%20and%20how%20much%20we%20spend%20on%20advertising.%20The%20cost%20function%20can%20also%20take%20on%20additional%20inputs%2C%20but%20for%20the%20sake%20of%20demonstration%20we%20will%20keep%20it%20as%20a%20function%20of%20quantity%20and%20advertising%20costs.%20Notice%20that%20our%20choices%20of%20%24%5Cdelta%24%20and%20%24%5Ctau%24%20impact%20the%20profit%20function%20directly%20through%20their%20impact%20of%20quantity%20demanded%20and%20the%20cost%20function.%20In%20order%20to%20add%20tractability%20to%20our%20optimization%20problem%2C%20we%20will%20need%20to%20use%20econometric%20techniques%20to%20estimate%20our%20quantity%20function.%20Once%20we%20have%20specified%20our%20cost%20function%20and%20estimated%20the%20quantity%20function%2C%20we%20can%20then%20solve%20our%20optimization%20problem%20as%20follows%3A%0A%0A%20%20%20%20%20%20%20%20%24%24%0A%20%20%20%20%20%20%20%20%5Cbegin%7Bequation%7D%0A%20%20%20%20%20%20%20%20%5Cbegin%7Baligned%7D%0A%20%20%20%20%20%20%20%20%5Cmin_%7B%5Cdelta%2C%5Ctau%7D%20%5Cquad%26%20-%20%5Cleft%5C%7B%20p%5Ctimes%20%5Chat%7Bq%7D(%5Cdelta%2C%5Ctau%2C%5Ccdot)-%5Cmathcal%7BC%7D%5Cbigl%5B%5Chat%7Bq%7D(%5Cdelta%2C%5Ctau%2C%5Ccdot)%2C%5Cdelta%2C%5Ctau%5Cbigr%5D%20%5Cright%5C%7D%20%5C%5C%0A%20%20%20%20%20%20%20%20%5Ctext%7Bsubject%20to%7D%20%5Cquad%26%20%5Ctextbf%7BBudget%20Constraint%3A%20%7D%20%5Cdelta%20%2B%20%5Ctau%20%3D%20%5Ctext%7B%5C%24100%2C000%7D%20%5C%5C%0A%20%20%20%20%20%20%20%20%26%5Ctextbf%7BMinimum%20Requirements%3A%20%7D%20%5Cdelta%20%5Cge%20%5Ctext%7B%5C%2410%2C000%7D%2C%20%5Ctext%7B%20%7D%20%5Ctau%20%5Cge%20%5Ctext%7B%5C%2420%2C000%7D%20%5C%5C%0A%20%20%20%20%20%20%20%20%5Cend%7Baligned%7D%0A%20%20%20%20%20%20%20%20%5Ctag%7B7%7D%0A%20%20%20%20%20%20%20%20%5Cend%7Bequation%7D%0A%20%20%20%20%20%20%20%20%24%24%0A%0A%20%20%20%20%20%20%20%20where%20%24%5Chat%7Bq%7D%24%20is%20our%20estimated%20econometric%20model%20for%20quantity%20demanded.%20Before%20we%20lay%20out%20the%20econometric%20specification%20of%20our%20quantity%20model%2C%20it%20is%20necessary%20that%20we%20discuss%20an%20important%20note%20regarding%20the%20required%20assumptions%20for%20this%20optimization%20problem%20to%20prove%20tractable.%20It%20is%20imperative%20that%20we%20obtain%20the%20causal%20estimates%20of%20digital%20and%20television%20advertising%20on%20the%20quantity%20demanded.%20In%20the%20economists%20jargon%2C%20digital%20and%20television%20advertising%20need%20be%20exogenous%20in%20the%20econometric%20model.%20That%20is%2C%20they%20are%20uncorrelated%20with%20the%20error%20in%20the%20model.%20Exogeneity%20can%20be%20achieved%20in%20two%20ways%3A%201)%20We%20have%20the%20correct%20structural%20specification%20of%20the%20econometric%20model%20for%20the%20impact%20of%20digital%20and%20television%20advertising%20on%20quantity%20demanded%20(i.e.%2C%20we%20include%20all%20of%20the%20relevant%20variables%20that%20are%20correlated%20with%20both%20quantity%20demanded%20and%20digital%20%26%20television%20advertising%20spend)%20or%202)%20We%20have%20random%20variation%20of%20digital%20%26%20television%20advertising%20spend%20(this%20can%20be%20achieved%20from%20randomly%20varying%20spend%20over%20time%20to%20see%20how%20demand%20responds).%0A%0A%20%20%20%20%20%20%20%20Intuitively%2C%20exogeneity%20is%20required%20because%20it%20is%20necessary%20to%20capture%20the%20causal%20impact%20of%20changing%20advertising%20spend%20%E2%80%94%20that%20is%2C%20what%20will%20happen%2C%20on%20average%2C%20if%20we%20change%20the%20values%20of%20the%20advertising%20spend.%20If%20the%20effect%20we%20estimate%20is%20not%20causal%20then%20the%20changes%20we%20make%20in%20advertising%20spend%20will%20not%20correspond%20to%20the%20true%20change%20in%20quantity%20demanded.%20Note%20the%20model%20need%20not%20make%20the%20best%20predictions%20for%20quantity%20demanded%2C%20but%20rather%20accurately%20capture%20the%20causal%20relationship.%20%0A%0A%20%20%20%20%20%20%20%20Let%E2%80%99s%20now%20suppose%20we%20specify%20the%20following%20econometric%20model%20for%20quantity%20demanded%20indexed%20by%20time%20t%3A%0A%0A%20%20%20%20%20%20%20%20%24%24%0A%20%20%20%20%20%20%20%20%5Cbegin%7Bequation%7D%0A%20%20%20%20%20%20%20%20q_t(%5Cdelta%2C%5Ctau%2C%5Ccdot)%3D%5Calpha%2B%5Cbeta%5Cln(%5Cdelta_t)%2B%5Cgamma%5Cln(%5Ctau_t)%2B%5Cphi_1q_%7Bt-1%7D%2B%5Cphi_2q_%7Bt-2%7D%2B%5Cmathcal%7BS%7D_t%2B%5Cmathbf%7B%20X%7D_t%5COmega%2B%5Cepsilon%0A%20%20%20%20%20%20%20%20%5Ctag%7B8%7D%0A%20%20%20%20%20%20%20%20%5Cend%7Bequation%7D%0A%20%20%20%20%20%20%20%20%24%24%0A%0A%20%20%20%20%20%20%20%20where%20%24%5Cbeta%24%20and%20%24%5Cgamma%24%20are%20the%20estimates%20of%20the%20impact%20of%20the%20natural%20log%20of%20digital%20ad%20spend%2C%20%24%5Cdelta%24%2C%20and%20television%20ad%20spend%2C%20%24%5Ctau%24%2C%20respectively.%20Additionally%2C%20%24%5Calpha%24%20is%20our%20intercept%2C%20%24%5Cphi_1%24%20and%20%24%5Cphi_2%24%20are%20estimates%20of%20the%20autoregressive%20components%20of%20quantity%20demanded%2C%20%24%5Cmathcal%7BS%7D%24%20denotes%20seasonality%2C%20%24%5Cmathbf%7BX%7D%24%20is%20the%20set%20of%20all%20relevant%20covariates%20and%20lagged%20covariates%20along%20with%20the%20matrix%20of%20their%20coefficient%20estimates%20%24%5COmega%24%2C%20and%20%24%5Cepsilon%24%20is%20the%20error%20term.%20Furthermore%2C%20assume%20that%20digital%20and%20television%20advertising%20satisfy%20the%20exogeneity%20assumption%20conditional%20on%20%24%5Cmathbf%7BX%7D%24%2C%20%24%5Cmathcal%7BS%7D%24%2C%20and%20the%20autoregressive%20components%20within%20our%20model.%20That%20is%2C%0A%0A%20%20%20%20%20%20%20%20%24%24%0A%20%20%20%20%20%20%20%20%5Cbegin%7Bequation%7D%0A%20%20%20%20%20%20%20%20%5Cmathrm%7BCov%7D%5B%5Cln(%5Cdelta)%2C%5Cepsilon%7C%7B%5Cbf%20X%7D%2C%5Cmathcal%7BS%7D%2Cq_%7Bt-1%7D%2Cq_%7Bt-2%7D%5D%3D%5Cmathrm%7BCov%7D%5B%5Cln(%7B%5Ctau%7D)%2C%5Cepsilon%7C%7B%5Cbf%20X%7D%2C%5Cmathcal%7BS%7D%2Cq_%7Bt-1%7D%2Cq_%7Bt-2%7D%5D%3D0%0A%20%20%20%20%20%20%20%20%5Ctag%7B9%7D%0A%20%20%20%20%20%20%20%20%5Cend%7Bequation%7D%0A%20%20%20%20%20%20%20%20%24%24%0A%0A%20%20%20%20%20%20%20%20Why%20the%20natural%20log%20of%20digital%20and%20television%20ad%20spend%20you%20may%20ask%3F%20This%20is%20by%20no%20means%20a%20required%20nor%20a%20definitive%20decision%20in%20this%20context%2C%20but%20I%20am%20seeking%20to%20demonstrate%20how%20variable%20transformations%20can%20capture%20hypotheses%20about%20the%20relationship%20between%20our%20choice%20variables%20and%20the%20outcomes%20of%20interest.%20In%20our%20case%2C%20suppose%20we%20hypothesize%20that%20the%20impact%20on%20ad%20spend%20increases%20sharply%20initially%2C%20but%20gradually%20levels%20out%20(e.g.%2C%20saturation%20effects%20or%20the%20law%20of%20diminishing%20returns).%20This%20is%20exactly%20what%20the%20logarithm%20transformation%20will%20allow%20us%20to%20model.%20Observe%3A%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo%2C%20np%2C%20plt)%3A%0A%20%20%20%20def%20saturation_plot()%3A%0A%20%20%20%20%20%20%20%20fig%2C%20ax%20%3D%20plt.subplots(dpi%3D125)%0A%0A%20%20%20%20%20%20%20%20x%20%3D%20np.linspace(5%2C%201000%2C%201000)%0A%0A%20%20%20%20%20%20%20%20y%20%3D%20np.log(x)%0A%0A%20%20%20%20%20%20%20%20ax.spines%5B%22right%22%5D.set_color(%22none%22)%0A%20%20%20%20%20%20%20%20ax.spines%5B%22top%22%5D.set_color(%22none%22)%0A%0A%20%20%20%20%20%20%20%20plt.tick_params(%0A%20%20%20%20%20%20%20%20%20%20%20%20axis%3D%22x%22%2C%20which%3D%22both%22%2C%20bottom%3DFalse%2C%20top%3DFalse%2C%20labelbottom%3DFalse%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20plt.tick_params(%0A%20%20%20%20%20%20%20%20%20%20%20%20axis%3D%22y%22%2C%20which%3D%22both%22%2C%20bottom%3DFalse%2C%20top%3DFalse%2C%20left%3DFalse%2C%20labelleft%3DFalse%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20plt.plot(x%2C%20y%2C%20color%3D%22g%22)%0A%20%20%20%20%20%20%20%20plt.xlabel(%22Digital%20Advertising%22%2C%20size%3D%22large%22)%0A%20%20%20%20%20%20%20%20plt.ylabel(%22Quantity%20Demanded%22%2C%20size%3D%22large%22)%0A%0A%20%20%20%20%20%20%20%20plt.savefig(%22data%2Fsaturation_plot.webp%22%2C%20format%3D%22webp%22%2C%20dpi%3D300%2C%20bbox_inches%3D%22tight%22)%0A%0A%20%20%20%20saturation_plot()%0A%20%20%20%20mo.image(%22data%2Fsaturation_plot.webp%22%2C%20height%3D500).center()%0A%20%20%20%20return%20(saturation_plot%2C)%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%20%20%20%20Note%20that%20the%20cost%20functional%20form%20is%20generally%20known%20in%20advance.%20Thus%2C%20let%E2%80%99s%20specify%20the%20functional%20form%20of%20our%20cost%20function%3A%0A%0A%20%20%20%20%20%20%20%20%24%24%0A%20%20%20%20%20%20%20%20%5Cbegin%7Bequation%7D%0A%20%20%20%20%20%20%20%20%5Cmathcal%7BC%7D%5Cbigl%5Bq(%5Cdelta%2C%5Ctau%2C%5Ccdot)%2C%5Cdelta%2C%5Ctau%5Cbigr%5D%3Dq(%5Cdelta%2C%5Ctau%2C%5Ccdot)%5Ctimes%5Cbigl%5B%5Czeta-%5Ctext%7Bdiscount%7D%5Ctimes%20q(%5Cdelta%2C%5Ctau%2C%5Ccdot)%5Cbigr%5D%20%2B%20%5Cdelta%2B%5Ctau%0A%20%20%20%20%20%20%20%20%5Ctag%7B10%7D%0A%20%20%20%20%20%20%20%20%5Cend%7Bequation%7D%0A%20%20%20%20%20%20%20%20%24%24%0A%0A%20%20%20%20%20%20%20%20Here%20we%20can%20see%20that%20we%20have%20a%20cost%20%24%5Czeta%24%20associated%20with%20each%20unit%20produced%20and%20this%20cost%20is%20discounted%20as%20we%20produce%20more%20(think%20a%20discount%20for%20larger%20contracts%20or%20%5Beconomies%20of%20scale%5D(https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FEconomies_of_scale)).%20We%20also%20simply%20sum%20digital%20ad%20spend%20and%20television%20ad%20spend%20into%20our%20total%20cost.%0A%0A%20%20%20%20%20%20%20%20Now%20that%20we%20have%20developed%20the%20theoretical%20basis%20for%20our%20econometric%20profit%20maximization%20problem%2C%20let%E2%80%99s%20simulate%20some%20data%20and%20take%20this%20to%20python!%0A%0A%20%20%20%20%20%20%20%20%23%23%23%20Optional%3A%20Data%20Simulation%0A%0A%20%20%20%20%20%20%20%20Note%20this%20section%20can%20be%20skipped%20without%20any%20loss%20of%20the%20primary%20content.%0A%0A%20%20%20%20%20%20%20%20Let%E2%80%99s%20first%20simulate%20monthly%20data%20over%2010%20years%20for%20quantity%20demanded%2C%20where%20the%20following%20variables%20included%20are%20as%20follows%20%3A%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(cycle%2C%20np%2C%20pd)%3A%0A%20%20%20%20df%20%3D%20pd.DataFrame()%0A%0A%20%20%20%20%23%23%20Digital%20Advertising%20-%20ln(%CE%B4)%0A%20%20%20%20df%5B%22log_digital_advertising%22%5D%20%3D%20np.log(%0A%20%20%20%20%20%20%20%20np.random.normal(loc%3D50000%2C%20scale%3D15000%2C%20size%3D120).round()%0A%20%20%20%20)%0A%0A%20%20%20%20%23%23%20Television%20Advertising%20-%20ln(%CF%84)%0A%20%20%20%20df%5B%22log_television_advertising%22%5D%20%3D%20np.log(%0A%20%20%20%20%20%20%20%20np.random.normal(loc%3D50000%2C%20scale%3D15000%2C%20size%3D120).round()%0A%20%20%20%20)%0A%0A%20%20%20%20%23%23%20Matrix%20X%20of%20covariates%0A%0A%20%20%20%20%23%20Lag%20Digital%20Advertising%0A%20%20%20%20df%5B%22log_digital_advertising_lag1%22%5D%20%3D%20df%5B%22log_digital_advertising%22%5D.shift(1)%0A%20%20%20%20df%5B%22log_digital_advertising_lag2%22%5D%20%3D%20df%5B%22log_digital_advertising%22%5D.shift(2)%0A%0A%20%20%20%20%23%20Lag%20Television%20Advertising%0A%20%20%20%20df%5B%22log_television_advertising_lag1%22%5D%20%3D%20df%5B%22log_television_advertising%22%5D.shift(1)%0A%20%20%20%20df%5B%22log_television_advertising_lag2%22%5D%20%3D%20df%5B%22log_television_advertising%22%5D.shift(2)%0A%0A%20%20%20%20%23%20Price%0A%20%20%20%20df%5B%22price%22%5D%20%3D%20np.random.normal(loc%3D180%2C%20scale%3D15%2C%20size%3D120).round()%0A%20%20%20%20df%5B%22price_lag1%22%5D%20%3D%20df%5B%22price%22%5D.shift(1)%0A%20%20%20%20df%5B%22price_lag2%22%5D%20%3D%20df%5B%22price%22%5D.shift(2)%0A%0A%20%20%20%20%23%20Competitor%20Price%0A%20%20%20%20df%5B%22comp_price%22%5D%20%3D%20np.random.normal(loc%3D120%2C%20scale%3D15%2C%20size%3D120).round()%0A%20%20%20%20df%5B%22comp_price_lag1%22%5D%20%3D%20df%5B%22comp_price%22%5D.shift(1)%0A%20%20%20%20df%5B%22comp_price_lag2%22%5D%20%3D%20df%5B%22comp_price%22%5D.shift(2)%0A%0A%20%20%20%20%23%20Seasonality%0A%20%20%20%20months%20%3D%20cycle(%0A%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Jan%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Feb%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Mar%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Apr%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22May%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22June%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22July%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Aug%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Sep%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Oct%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Nov%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Dec%22%2C%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20)%0A%20%20%20%20df%5B%22months%22%5D%20%3D%20%5Bnext(months)%20for%20m%20in%20range(len(df))%5D%0A%0A%20%20%20%20one_hot%20%3D%20pd.get_dummies(df%5B%22months%22%5D%2C%20dtype%3Dint)%0A%20%20%20%20one_hot%20%3D%20one_hot%5B%0A%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Jan%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Feb%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Mar%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Apr%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22May%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22June%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22July%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Aug%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Sep%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Oct%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Nov%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Dec%22%2C%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%5D%0A%20%20%20%20df%20%3D%20df.join(one_hot).drop(%22months%22%2C%20axis%3D1)%0A%0A%20%20%20%20%23%23%20Constant%0A%20%20%20%20df%5B%22constant%22%5D%20%3D%201%0A%0A%20%20%20%20%23%20Drop%20NaN%20(Two%20lags)%0A%20%20%20%20df%20%3D%20df.dropna()%0A%20%20%20%20return%20df%2C%20months%2C%20one_hot%0A%0A%0A%40app.cell%0Adef%20_(df)%3A%0A%20%20%20%20df%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22Note%20that%20we%20include%20lag%20variables%20because%20it%20is%20highly%20plausible%20that%20today%E2%80%99s%20quantity%20demanded%20is%20a%20function%20of%20lagged%20values%20for%20many%20of%20the%20variables.%20We%20also%20control%20for%20seasonality%20effects%20by%20incorporation%20dummy%20variables%20for%20each%20month%20(this%20is%20one%20of%20many%20ways%20to%20incorporate%20seasonality%20into%20the%20model).%20We%20then%20specify%20the%20parameters%20associated%20with%20each%20variable%20as%20(note%20that%20these%20parameters%20are%20specified%20in%20the%20same%20order%20as%20the%20columns%20of%20the%20dataframe!)%3A%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(np)%3A%0A%20%20%20%20params%20%3D%20np.array(%0A%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%2010_000%2C%20%20%23%20%CE%B2%0A%20%20%20%20%20%20%20%20%20%20%20%205_000%2C%20%20%23%20%CE%B3%0A%20%20%20%20%20%20%20%20%20%20%20%202_000%2C%20%20%23%20%CE%A9%0A%20%20%20%20%20%20%20%20%20%20%20%201_000%2C%20%20%23%20%CE%A9%0A%20%20%20%20%20%20%20%20%20%20%20%203_000%2C%20%20%23%20%CE%A9%0A%20%20%20%20%20%20%20%20%20%20%20%201_000%2C%20%20%23%20%CE%A9%0A%20%20%20%20%20%20%20%20%20%20%20%20-1_000%2C%20%20%23%20%CE%A9%0A%20%20%20%20%20%20%20%20%20%20%20%20-500%2C%20%20%23%20%CE%A9%0A%20%20%20%20%20%20%20%20%20%20%20%20-100%2C%20%20%23%20%CE%A9%0A%20%20%20%20%20%20%20%20%20%20%20%20500%2C%20%20%23%20%CE%A9%0A%20%20%20%20%20%20%20%20%20%20%20%20300%2C%20%20%23%20%CE%A9%0A%20%20%20%20%20%20%20%20%20%20%20%20100%2C%20%20%23%20%CE%A9%0A%20%20%20%20%20%20%20%20%20%20%20%2025_000%2C%20%20%23%20S%0A%20%20%20%20%20%20%20%20%20%20%20%2015_000%2C%20%20%23%20S%0A%20%20%20%20%20%20%20%20%20%20%20%2015_000%2C%20%20%23%20S%0A%20%20%20%20%20%20%20%20%20%20%20%2010_000%2C%20%20%23%20S%0A%20%20%20%20%20%20%20%20%20%20%20%2010_000%2C%20%20%23%20S%0A%20%20%20%20%20%20%20%20%20%20%20%2010_000%2C%20%20%23%20S%0A%20%20%20%20%20%20%20%20%20%20%20%2015_000%2C%20%20%23%20S%0A%20%20%20%20%20%20%20%20%20%20%20%2015_000%2C%20%20%23%20S%0A%20%20%20%20%20%20%20%20%20%20%20%2025_000%2C%20%20%23%20S%0A%20%20%20%20%20%20%20%20%20%20%20%2035_000%2C%20%20%23%20S%0A%20%20%20%20%20%20%20%20%20%20%20%2035_000%2C%20%20%23%20S%0A%20%20%20%20%20%20%20%20%20%20%20%2040_000%2C%20%20%23%20S%0A%20%20%20%20%20%20%20%20%20%20%20%2050_000%2C%20%20%23%20%CE%B1%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20)%0A%20%20%20%20return%20(params%2C)%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%20%20%20%20We%20can%20then%20simulate%20our%20econometric%20specification%20(eq.%208)%20of%20quantity%20demanded%20by%20running%20%60quantity_demanded%20%3D%20np.array(df)%20%40%20params%60.%20However%2C%20note%20that%20we%20are%20missing%20the%20autoregressive%20components%2C%20thus%20we%20also%20want%20quantity%20demanded%20to%20follow%20an%20autoregressive%20process%20as%20mentioned%20above.%20That%20is%2C%20quantity%20demanded%20is%20also%20a%20function%20of%20its%20own%20lagged%20values.%20We%20include%202%20lags%20here%20(AR(2)%20process)%20with%20respective%20coefficients%20%24%5Cphi_1%24%20and%20%24%5Cphi_2%24.%20Note%2C%20we%20can%20simulate%20this%20with%20initial%20conditions%20%24q_0%24%20and%20%24q_%7B-1%7D%24%20via%20the%20following%20system%3A%0A%0A%20%20%20%20%20%20%20%20%24%24%0A%20%20%20%20%20%20%20%20%5Cbegin%7Bequation%7D%0A%20%20%20%20%20%20%20%20%5Cbegin%7Baligned%7D%0A%20%20%20%20%20%20%20%20%5Cbegin%7Bbmatrix%7D%20%0A%20%20%20%20%20%20%20%20q_1%20%5C%5C%0A%20%20%20%20%20%20%20%20q_2%20%5C%5C%0A%20%20%20%20%20%20%20%20q_3%20%5C%5C%0A%20%20%20%20%20%20%20%20q_4%20%5C%5C%0A%20%20%20%20%20%20%20%20%5Cvdots%20%5C%5C%0A%20%20%20%20%20%20%20%20q_t%0A%20%20%20%20%20%20%20%20%5Cend%7Bbmatrix%7D%0A%20%20%20%20%20%20%20%20%3D%0A%20%20%20%20%20%20%20%20%5Cbegin%7Bbmatrix%7D%20%0A%20%20%20%20%20%20%20%201%20%26%200%20%26%200%20%26%20%200%20%26%20%5Cdots%20%26%200%20%26%200%20%26%200%20%5C%5C%0A%20%20%20%20%20%20%20%20-%5Cphi_1%20%26%201%20%26%200%20%26%200%20%26%20%5Cdots%20%26%200%20%26%200%20%26%200%20%5C%5C%0A%20%20%20%20%20%20%20%20-%5Cphi_2%20%26%20-%5Cphi_1%20%26%201%20%26%200%20%26%20%5Cdots%20%26%200%20%26%200%20%26%200%20%5C%5C%0A%20%20%20%20%20%20%20%200%20%26%20-%5Cphi_2%20%26%20-%5Cphi_1%20%26%201%20%26%20%20%5Cdots%20%26%200%20%26%200%20%26%200%20%5C%5C%0A%20%20%20%20%20%20%20%20%5Cvdots%20%26%20%5Cvdots%20%26%20%5Cvdots%20%26%20%5Cvdots%20%26%20%5Cdots%20%26%20%5Cvdots%20%26%20%5Cvdots%20%26%20%5Cvdots%5C%5C%0A%20%20%20%20%20%20%20%200%20%26%200%20%26%200%20%26%200%20%26%20%5Cdots%20%26%20-%5Cphi_2%20%26%20-%5Cphi_1%20%26%201%0A%20%20%20%20%20%20%20%20%5Cend%7Bbmatrix%7D%5E%7B-1%7D%0A%20%20%20%20%20%20%20%20%5Cbegin%7Bbmatrix%7D%0A%20%20%20%20%20%20%20%20%5Calpha%2B%5Cbeta%5Cln(%5Cdelta_1)%2B%5Cgamma%5Cln(%5Ctau_1)%2B%5Cmathbf%7BX%7D_1%5Cmathbf%7B%5COmega%7D%2B%5Cepsilon_1%20%2B%20(%5Cphi_1q_0%2B%5Cphi_2q_%7B-1%7D)%20%20%5C%5C%0A%20%20%20%20%20%20%20%20%5Calpha%2B%5Cbeta%5Cln(%5Cdelta_2)%2B%5Cgamma%5Cln(%5Ctau_2)%2B%5Cmathbf%7BX%7D_2%5Cmathbf%7B%5COmega%7D%2B%5Cepsilon_2%20%2B%20(%5Cphi_2q_0)%20%5C%5C%0A%20%20%20%20%20%20%20%20%5Calpha%2B%5Cbeta%5Cln(%5Cdelta_3)%2B%5Cgamma%5Cln(%5Ctau_3)%2B%5Cmathbf%7BX%7D_3%5Cmathbf%7B%5COmega%7D%2B%5Cepsilon_3%20%5C%5C%20%0A%20%20%20%20%20%20%20%20%5Calpha%2B%5Cbeta%5Cln(%5Cdelta_4)%2B%5Cgamma%5Cln(%5Ctau_4)%2B%5Cmathbf%7BX%7D_4%5Cmathbf%7B%5COmega%7D%2B%5Cepsilon_4%20%5C%5C%0A%20%20%20%20%20%20%20%20%5Cvdots%20%5C%5C%0A%20%20%20%20%20%20%20%20%5Calpha%2B%5Cbeta%5Cln(%5Cdelta_t)%2B%5Cgamma%5Cln(%5Ctau_t)%2B%5Cmathbf%7BX%7D_t%5Cmathbf%7B%5COmega%7D%2B%5Cepsilon_t%20%5C%5C%0A%20%20%20%20%20%20%20%20%5Cend%7Bbmatrix%7D%0A%20%20%20%20%20%20%20%20%5Cend%7Baligned%7D%0A%20%20%20%20%20%20%20%20%5Ctag%7B11%7D%0A%20%20%20%20%20%20%20%20%5Cend%7Bequation%7D%0A%20%20%20%20%20%20%20%20%24%24%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df%2C%20np%2C%20params)%3A%0A%20%20%20%20def%20quantity_ar2_process(T%2C%20%CF%951%2C%20%CF%952%2C%20q0%2C%20q_1%2C%20%CF%B5%2C%20df%2C%20params)%3A%0A%20%20%20%20%20%20%20%20%CE%A6%20%3D%20np.identity(T)%20%20%23%20The%20T%20x%20T%20identity%20matrix%0A%0A%20%20%20%20%20%20%20%20for%20i%20in%20range(T)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20i%20-%201%20%3E%3D%200%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%CE%A6%5Bi%2C%20i%20-%201%5D%20%3D%20-%CF%951%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20i%20-%202%20%3E%3D%200%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%CE%A6%5Bi%2C%20i%20-%202%5D%20%3D%20-%CF%952%0A%0A%20%20%20%20%20%20%20%20B%20%3D%20np.array(df)%20%40%20params%20%2B%20%CF%B5%0A%0A%20%20%20%20%20%20%20%20B%5B0%5D%20%3D%20B%5B0%5D%20%2B%20%CF%951%20*%20q0%20%2B%20%CF%952%20*%20q_1%0A%20%20%20%20%20%20%20%20B%5B1%5D%20%3D%20B%5B1%5D%20%2B%20%CF%952%20*%20q0%0A%0A%20%20%20%20%20%20%20%20return%20np.linalg.inv(%CE%A6)%20%40%20B%0A%0A%20%20%20%20%23%23%20Quantity%20Demand%20AR(2)%20component%20process%0A%0A%20%20%20%20%23%20Parameters%0A%20%20%20%20T%20%3D%20118%20%20%23%20Time%20periods%20less%20two%20lags%0A%20%20%20%20%CF%951%20%3D%200.3%20%20%23%20Lag%201%20coefficient%20(%CF%951)%0A%20%20%20%20%CF%952%20%3D%200.05%20%20%23%20Lag%202%20coefficient%20(%CF%952)%0A%20%20%20%20q_1%20%3D%20250_000%20%20%23%20Initial%20Condition%20q_-1%0A%20%20%20%20q0%20%3D%20300_000%20%20%23%20Initial%20Condition%20q_0%0A%20%20%20%20%CF%B5%20%3D%20np.random.normal(0%2C%205000%2C%20size%3DT)%20%20%23%20Random%20Error%20(%CF%B5)%0A%0A%20%20%20%20quantity_demanded_ar%20%3D%20quantity_ar2_process(T%2C%20%CF%951%2C%20%CF%952%2C%20q0%2C%20q_1%2C%20%CF%B5%2C%20df%2C%20params)%0A%0A%20%20%20%20%23%20Quantity_demanded%20target%20variable%0A%20%20%20%20df%5B%22quantity_demanded%22%5D%20%3D%20quantity_demanded_ar%0A%0A%20%20%20%20%23%20Additional%20covariates%20of%20lagged%20quantity%20demanded%0A%20%20%20%20df%5B%22quantity_demanded_lag1%22%5D%20%3D%20df%5B%22quantity_demanded%22%5D.shift(1)%0A%20%20%20%20df%5B%22quantity_demanded_lag2%22%5D%20%3D%20df%5B%22quantity_demanded%22%5D.shift(2)%0A%20%20%20%20return%20T%2C%20q0%2C%20q_1%2C%20quantity_ar2_process%2C%20quantity_demanded_ar%2C%20%CE%B5%2C%20%CF%861%2C%20%CF%862%0A%0A%0A%40app.cell%0Adef%20_(df)%3A%0A%20%20%20%20df%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%20%20%20%20%23%23%23%20Econometric%20Estimation%20%26%20Profit%20Maximization%0A%0A%20%20%20%20%20%20%20%20Let%E2%80%99s%20first%20use%20our%20framework%20in%20eq.%20(2)%20to%20transform%20our%20constrained%20optimization%20problem%20in%20eq.%20(7)%20to%20one%20in%20which%20we%20can%20solve%20utilizing%20our%20function%20%60constrained_newton_method()%60%20as%20done%20above%3A%0A%0A%0A%20%20%20%20%20%20%20%20%24%24%0A%20%20%20%20%20%20%20%20%5Cbegin%7Bequation%7D%0A%20%20%20%20%20%20%20%20%5Cbegin%7Baligned%7D%0A%20%20%20%20%20%20%20%20%5Cmathcal%7BO%7D(%5Cdelta%2C%5Ctau%2C%5Clambda%2C%5Crho)%3D%20-%5CBigl%5C%7B%20p%5Ctimes%20%5Chat%7Bq%7D(%5Cdelta%2C%5Ctau%2C%5Ccdot)-%5Cmathcal%7BC%7D%5Cbigl%5B%5Chat%7Bq%7D(%5Cdelta%2C%5Ctau%2C%5Ccdot)%2C%5Cdelta%2C%5Ctau%5Cbigr%5D%20%5CBigr%5C%7D%20%5C%5C%0A%20%20%20%20%20%20%20%20%2B%5Clambda(%5Cdelta%2B%5Ctau-%5Ctext%7B100%2C000%7D)%20%5C%5C%0A%20%20%20%20%20%20%20%20-%5Crho%5Clog%5Cbigl%5B(%5Ctau-%5Ctext%7B20%2C000%7D)(%5Cdelta-%5Ctext%7B10%2C000%7D)%5Cbigr%5D%0A%20%20%20%20%20%20%20%20%5Cend%7Baligned%7D%0A%20%20%20%20%20%20%20%20%5Ctag%7B12%7D%0A%20%20%20%20%20%20%20%20%5Cend%7Bequation%7D%0A%20%20%20%20%20%20%20%20%24%24%0A%0A%20%20%20%20%20%20%20%20As%20discussed%20before%2C%20we%20need%20to%20estimate%20our%20quantity%20demanded%2C%20%24%5Chat%7Bq%7D%24.%20Let%E2%80%99s%20take%20a%20look%20at%20what%20our%20quantity%20demanded%20looks%20like%20over%20the%2010%20years%20simulated%3A%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(T%2C%20mo%2C%20mtick%2C%20np%2C%20plt%2C%20quantity_demanded_ar)%3A%0A%20%20%20%20def%20quantity_demanded_plot()%3A%0A%20%20%20%20%20%20%20%20fig%2C%20ax%20%3D%20plt.subplots(dpi%3D125)%0A%0A%20%20%20%20%20%20%20%20fmt%20%3D%20%22%7Bx%3A%2C.0f%7D%22%0A%20%20%20%20%20%20%20%20tick%20%3D%20mtick.StrMethodFormatter(fmt)%0A%20%20%20%20%20%20%20%20ax.yaxis.set_major_formatter(tick)%0A%0A%20%20%20%20%20%20%20%20ax.spines%5B%22right%22%5D.set_color(%22none%22)%0A%20%20%20%20%20%20%20%20ax.spines%5B%22top%22%5D.set_color(%22none%22)%0A%20%20%20%20%20%20%20%20%23%20ax.spines%5B'bottom'%5D.set_color('none')%0A%20%20%20%20%20%20%20%20%23%20ax.spines%5B'bottom'%5D.set_position(('data'%2Cavg_demand))%0A%0A%20%20%20%20%20%20%20%20plt.tick_params(%0A%20%20%20%20%20%20%20%20%20%20%20%20axis%3D%22x%22%2C%20which%3D%22both%22%2C%20bottom%3DFalse%2C%20top%3DFalse%2C%20labelbottom%3DFalse%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20for%20i%20in%20range(0%2C%20108%2C%2012)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20line%20%3D%20108%20-%20i%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.axvline(x%3Dline%2C%20color%3D%22r%22%2C%20linestyle%3D%22--%22%2C%20alpha%3D0.2)%0A%0A%20%20%20%20%20%20%20%20%23%20ax.axhline(y%3Davg_demand%2C%20color%3D'black'%2C%20linewidth%3D0.2)%0A%0A%20%20%20%20%20%20%20%20plt.plot(np.arange(T)%20%2B%201%2C%20quantity_demanded_ar%2C%20color%3D%22g%22)%0A%20%20%20%20%20%20%20%20plt.xlabel(%22Years%22%2C%20size%3D%22large%22)%0A%20%20%20%20%20%20%20%20plt.ylabel(%22Quantity%20Demanded%22%2C%20size%3D%22large%22)%0A%0A%20%20%20%20%20%20%20%20plt.savefig(%22data%2Fquantity_demanded_plot.webp%22%2C%20format%3D%22webp%22%2C%20dpi%3D300%2C%20bbox_inches%3D%22tight%22)%0A%0A%20%20%20%20quantity_demanded_plot()%0A%20%20%20%20mo.image(%22data%2Fquantity_demanded_plot.webp%22%2C%20height%3D500).center()%0A%20%20%20%20return%20(quantity_demanded_plot%2C)%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22We%20can%20clearly%20see%20some%20seasonality%20occurring%20towards%20the%20end%20of%20the%20years%20and%20it%20appears%20we%20are%20dealing%20with%20a%20%5Bstationary%20process%5D(https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FStationary_process)%20(this%20is%20all%20by%20construction).%20Now%20suppose%20that%20we%20have%20the%20following%20observed%20variables%3A%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(df)%3A%0A%20%20%20%20list(df.columns)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%20%20%20%20where%2C%20in%20eq.%208%2C%20our%20econometric%20specification%2C%20quantity_demanded%20is%20our%20outcome%20%24q%24%2C%20log_digital_advertising%20is%20our%20%24%5Cln(%5Cdelta)%24%2C%20log_television_advertising%20is%20our%20%24%5Cln(%5Ctau)%24%2C%20constant%20is%20our%20%24%CE%B1%24%2C%20quantity_demanded_lag1%20%26%20quantity_demanded_lag2%20are%20our%20autoregressive%20components%20%24q_%7Bt-1%7D%24%20%26%20%24q_%7Bt-2%7D%24%2C%20and%20the%20remainder%20are%20our%20additional%20covariates%20%24%5Cmathbf%7BX%7D%24%20including%20seasonality%20%24%5Cmathcal%7BS%7D%24.%0A%0A%20%20%20%20%20%20%20%20Now%2C%20with%20this%20data%2C%20we%20seek%20to%20estimate%20our%20econometric%20specification%20in%20eq.%208.%20We%20can%20estimate%20this%20structural%20model%20using%20OLS.%20For%20this%20we%20will%20use%20%5Bstatsmodels%5D(https%3A%2F%2Fwww.statsmodels.org%2Fstable%2Findex.html%23).%20%0A%0A%20%20%20%20%20%20%20%20%3E%20A%20great%20exercise%20would%20be%20to%20solve%20the%20linear%20regression%20using%20the%20Gradient%20Descent%20ot%20Newton%E2%80%99s%20method%20code%20we%20have%20constructed%20and%20compare%20the%20results%20to%20statsmodels.%20Hint%3A%20the%20objective%20in%20a%20linear%20regression%20is%20to%20minimize%20the%20Residual%20Sum%20of%20Squares.%20Note%20that%20the%20code%20we%20have%20written%20is%20by%20no%20means%20an%20efficient%20approach%20to%20solving%20a%20linear%20regression%2C%20but%20this%20is%20more%20oriented%20towards%20illustrating%20optimization%20theory%20in%20a%20model%20fitting%20(regression)%20context.%20Code%20for%20this%20will%20be%20provided%20at%20the%20end%20of%20the%20article!%0A%0A%20%20%20%20%20%20%20%20Note%20that%20we%20drop%20the%20first%202%20observations%20as%20these%20are%20our%20first%20two%20lags%20and%20we%20drop%20July%20as%20a%20reference%20month%3A%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df%2C%20stats)%3A%0A%20%20%20%20%23%23%20Fit%20Econometric%20model%20using%20OLS%0A%20%20%20%20df_mod%20%3D%20df%5B2%3A%5D%20%20%23%20Drop%20first%20two%20lagged%20values%0A%0A%20%20%20%20y%20%3D%20df_mod%5B%22quantity_demanded%22%5D%0A%20%20%20%20X%20%3D%20df_mod.drop(%5B%22quantity_demanded%22%2C%20%22July%22%5D%2C%20axis%3D1)%0A%0A%20%20%20%20mod%20%3D%20stats.OLS(y%2C%20X)%0A%20%20%20%20results%20%3D%20mod.fit()%0A%0A%20%20%20%20print(results.summary())%0A%20%20%20%20return%20X%2C%20df_mod%2C%20mod%2C%20results%2C%20y%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%20%20%20%20Now%20we%20have%20our%20estimated%20econometric%20specification%20for%20quantity%20demanded!%20A%20few%20observations%3A%0A%0A%20%20%20%20%20%20%20%201.%20An%20increase%20in%20log%20digital%20ad%20spend%20and%20log%20television%20ad%20spend%20are%20associated%20with%20an%20increase%20in%20quantity%20demand%0A%20%20%20%20%20%20%20%202.%20An%20increase%20price%20is%20associated%20with%20a%20decrease%20in%20quantity%20demand%20(this%20is%20expected%20behavior)%0A%20%20%20%20%20%20%20%203.%20We%20see%20clear%20seasonality%20with%20increasing%20demand%20during%20Sep-Dec%2C%20this%20is%20consistent%20with%20our%20time%20series%20above%0A%20%20%20%20%20%20%20%204.%20We%20see%20that%20the%20first%20lag%20of%20quantity%20demanded%20is%20predictive%20of%20the%20present%2C%20in%20favor%20of%20autoregressive%20process%0A%0A%20%20%20%20%20%20%20%20%3E%20The%20results%20above%20can%20be%20verified%20and%20compared%20with%20the%20data%20construction%20above%20in%20the%20data%20simulation%20section%0A%0A%20%20%20%20%20%20%20%20Let%E2%80%99s%20now%20specify%20our%20symbolic%20variables%20for%20our%20optimization%20problem%20(%24%5Cdelta%24%2C%20%24%5Ctau%24%2C%20%24%5Clambda%24%2C%20and%20%24%5Crho%24)%2C%20the%20values%20of%20our%20present%20variables%20at%20time%20%24t%24%2C%20and%20grab%20the%20lagged%20values%20from%20our%20data.%20We%20can%20then%20obtain%20%24%5Chat%7Bq%7D(%5Cdelta%2C%20%5Ctau)%24%20at%20a%20point%20in%20time%3A%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df%2C%20np%2C%20results%2C%20sm)%3A%0A%20%20%20%20%23%20Build%20Symbolic%20Functions%20with%20all%20variables%20in%20function%0A%20%20%20%20%CE%B4%2C%20%CF%84%2C%20%CE%BB%2C%20%CF%81%20%3D%20sm.symbols(%22%CE%B4%20%CF%84%20%CE%BB%20%CF%81%22)%0A%0A%20%20%20%20%23%23%20Values%20of%20current%20variables%0A%20%20%20%20price%20%3D%20180%0A%20%20%20%20comp_price%20%3D%20120%0A%20%20%20%20Jan%20%3D%201%0A%0A%20%20%20%20%23%23%20Obtain%20Lagged%20Values%0A%20%20%20%20log_digital_advertising_lag1%20%3D%20df%5B%22log_digital_advertising%22%5D.iloc%5B-1%5D%0A%20%20%20%20log_digital_advertising_lag2%20%3D%20df%5B%22log_digital_advertising%22%5D.iloc%5B-2%5D%0A%20%20%20%20log_television_advertising_lag1%20%3D%20df%5B%22log_television_advertising%22%5D.iloc%5B-1%5D%0A%20%20%20%20log_television_advertising_lag2%20%3D%20df%5B%22log_television_advertising%22%5D.iloc%5B-2%5D%0A%20%20%20%20price_lag1%20%3D%20df%5B%22price%22%5D.iloc%5B-1%5D%0A%20%20%20%20price_lag2%20%3D%20df%5B%22price%22%5D.iloc%5B-2%5D%0A%20%20%20%20comp_price_lag1%20%3D%20df%5B%22comp_price%22%5D.iloc%5B-1%5D%0A%20%20%20%20comp_price_lag2%20%3D%20df%5B%22comp_price%22%5D.iloc%5B-2%5D%0A%20%20%20%20quantity_demanded_lag1%20%3D%20df%5B%22quantity_demanded%22%5D.iloc%5B-1%5D%0A%20%20%20%20quantity_demanded_lag2%20%3D%20df%5B%22quantity_demanded%22%5D.iloc%5B-2%5D%0A%0A%20%20%20%20variables%20%3D%20%5B%0A%20%20%20%20%20%20%20%20sm.log(%CE%B4)%2C%0A%20%20%20%20%20%20%20%20sm.log(%CF%84)%2C%0A%20%20%20%20%20%20%20%20log_digital_advertising_lag1%2C%0A%20%20%20%20%20%20%20%20log_digital_advertising_lag2%2C%0A%20%20%20%20%20%20%20%20log_television_advertising_lag1%2C%0A%20%20%20%20%20%20%20%20log_television_advertising_lag2%2C%0A%20%20%20%20%20%20%20%20price%2C%0A%20%20%20%20%20%20%20%20price_lag1%2C%0A%20%20%20%20%20%20%20%20price_lag2%2C%0A%20%20%20%20%20%20%20%20comp_price%2C%0A%20%20%20%20%20%20%20%20comp_price_lag1%2C%0A%20%20%20%20%20%20%20%20comp_price_lag2%2C%0A%20%20%20%20%20%20%20%20Jan%2C%0A%20%20%20%20%20%20%20%200%2C%0A%20%20%20%20%20%20%20%200%2C%0A%20%20%20%20%20%20%20%200%2C%0A%20%20%20%20%20%20%20%200%2C%0A%20%20%20%20%20%20%20%200%2C%0A%20%20%20%20%20%20%20%200%2C%0A%20%20%20%20%20%20%20%200%2C%0A%20%20%20%20%20%20%20%200%2C%0A%20%20%20%20%20%20%20%200%2C%0A%20%20%20%20%20%20%20%200%2C%20%20%23%20All%20Months%20less%20July%0A%20%20%20%20%20%20%20%201%2C%20%20%23%20Constant%0A%20%20%20%20%20%20%20%20quantity_demanded_lag1%2C%0A%20%20%20%20%20%20%20%20quantity_demanded_lag2%2C%0A%20%20%20%20%5D%0A%0A%20%20%20%20%23%20Quantity%20Demanded%0A%20%20%20%20quantity_demanded%20%3D%20(np.array(%5Bvariables%5D)%20%40%20np.array(results.params))%5B%0A%20%20%20%20%20%20%20%200%0A%20%20%20%20%5D%20%20%23%20params%20from%20ols%20model%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20Jan%2C%0A%20%20%20%20%20%20%20%20comp_price%2C%0A%20%20%20%20%20%20%20%20comp_price_lag1%2C%0A%20%20%20%20%20%20%20%20comp_price_lag2%2C%0A%20%20%20%20%20%20%20%20log_digital_advertising_lag1%2C%0A%20%20%20%20%20%20%20%20log_digital_advertising_lag2%2C%0A%20%20%20%20%20%20%20%20log_television_advertising_lag1%2C%0A%20%20%20%20%20%20%20%20log_television_advertising_lag2%2C%0A%20%20%20%20%20%20%20%20price%2C%0A%20%20%20%20%20%20%20%20price_lag1%2C%0A%20%20%20%20%20%20%20%20price_lag2%2C%0A%20%20%20%20%20%20%20%20quantity_demanded%2C%0A%20%20%20%20%20%20%20%20quantity_demanded_lag1%2C%0A%20%20%20%20%20%20%20%20quantity_demanded_lag2%2C%0A%20%20%20%20%20%20%20%20variables%2C%0A%20%20%20%20%20%20%20%20%CE%B4%2C%0A%20%20%20%20%20%20%20%20%CE%BB%2C%0A%20%20%20%20%20%20%20%20%CF%81%2C%0A%20%20%20%20%20%20%20%20%CF%84%2C%0A%20%20%20%20)%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%24%5Chat%7Bq%7D(%5Cdelta%2C%5Ctau%2C%5Ccdot)%20%3D%2010071.2795746647*%5Clog(%CE%B4)%20%2B%206219.99261508067*%5Clog(%CF%84)%20%2B%2021336.8117838209%24%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22Now%20we%20can%20construct%20our%20revenue%2C%20cost%2C%20and%20put%20them%20together%20to%20construct%20our%20profit%20function.%20Here%20our%20cost%20to%20produce%20each%20unit%20is%20%24140%20base%20and%20is%20discounted%20by%20%240.0001%20for%20each%20additional%20unit%20produced%3A%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(price%2C%20quantity_demanded%2C%20%CE%B4%2C%20%CF%84)%3A%0A%20%20%20%20Revenue%20%3D%20price%20*%20quantity_demanded%0A%20%20%20%20Cost%20%3D%20quantity_demanded%20*%20(140%20-%200.0001%20*%20quantity_demanded)%20%2B%20%CF%84%20%2B%20%CE%B4%0A%20%20%20%20profit%20%3D%20Revenue%20-%20Cost%0A%20%20%20%20return%20Cost%2C%20Revenue%2C%20profit%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%24%5Cpi(%5Cdelta%2C%5Ctau%2C%5Ccdot)%20%3D%20-%CE%B4%20-%20%CF%84%20-%20(-1.00712795746647*%5Clog(%CE%B4)%20-%200.621999261508067*%5Clog(%CF%84)%20%2B%20137.866318821618)*(10071.2795746647*%5Clog(%CE%B4)%20%2B%206219.99261508067*%5Clog(%CF%84)%20%2B%2021336.8117838209)%20%2B%201812830.32343965*%5Clog(%CE%B4)%20%2B%201119598.67071452*%5Clog(%CF%84)%20%2B%203840626.12108775%24%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22Plotting%20our%20profit%20as%20a%20function%20of%20digital%20ad%20spend%20and%20television%20ad%20spend%2C%20%24%CF%80(%5Cdelta%2C%20%5Ctau)%24%3A%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(go%2C%20mo%2C%20np%2C%20profit%2C%20%CE%B4%2C%20%CF%84)%3A%0A%20%20%20%20def%20profit_function_viz_3d()%3A%0A%20%20%20%20%20%20%20%20def%20log(x)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20np.log(x)%0A%0A%20%20%20%20%20%20%20%20%23%20Create%20meshgrid%20for%20surface%0A%20%20%20%20%20%20%20%20%CE%B4_vals%20%3D%20np.linspace(0.01%2C%20100000%2C%20100)%0A%20%20%20%20%20%20%20%20%CF%84_vals%20%3D%20np.linspace(0.01%2C%20100000%2C%20100)%0A%20%20%20%20%20%20%20%20%CE%B4_mesh%2C%20%CF%84_mesh%20%3D%20np.meshgrid(%CE%B4_vals%2C%20%CF%84_vals)%0A%0A%20%20%20%20%20%20%20%20def%20profit_fn(%CE%B4%2C%20%CF%84)%3A%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20(-%CE%B4%20-%20%CF%84%20-%20%0A%20%20%20%20%20%20%20%20%20%20%20%20(-1.00712795746647%20*%20log(%CE%B4)%20-%200.621999261508067%20*%20log(%CF%84)%20%2B%20137.866318821618)%20*%20%0A%20%20%20%20%20%20%20%20%20%20%20%20(10071.2795746647%20*%20log(%CE%B4)%20%2B%206219.99261508067%20*%20log(%CF%84)%20%2B%2021336.8117838209)%20%2B%20%0A%20%20%20%20%20%20%20%20%20%20%20%201812830.32343965%20*%20log(%CE%B4)%20%2B%201119598.67071452%20*%20log(%CF%84)%20%2B%203840626.12108775)%0A%0A%20%20%20%20%20%20%20%20%23%20Calculate%20profit%20values%0A%20%20%20%20%20%20%20%20profit_vals%20%3D%20profit_fn(%CE%B4_mesh%2C%20%CF%84_mesh)%0A%0A%20%20%20%20%20%20%20%20%23%20Create%20surface%20plot%0A%20%20%20%20%20%20%20%20surface%20%3D%20go.Surface(%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3D%CE%B4_mesh.tolist()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3D%CF%84_mesh.tolist()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20z%3Dprofit_vals.tolist()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20colorscale%3D'plasma'%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D'Profit%20Surface'%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20colorbar%3Ddict(x%3D-0.15)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20showlegend%3DTrue%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20%23%20Create%20budget%20constraint%20line%0A%20%20%20%20%20%20%20%20budget_x%20%3D%20np.linspace(0.01%2C%2099_999%2C%20100)%0A%20%20%20%20%20%20%20%20budget_y%20%3D%20100000%20-%20budget_x%0A%20%20%20%20%20%20%20%20budget_z%20%3D%20profit_fn(budget_x%2C%20budget_y)%0A%0A%20%20%20%20%20%20%20%20budget_line%20%3D%20go.Scatter3d(%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3Dbudget_x.tolist()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3Dbudget_y.tolist()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20z%3Dbudget_z.tolist()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mode%3D'lines'%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20line%3Ddict(color%3D'green'%2C%20width%3D5)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D'Budget%20Constraint'%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20%23%20Create%20minimum%20constraints%0A%20%20%20%20%20%20%20%20min_%CE%B4_x%20%3D%20np.ones(100)%20*%2010000%0A%20%20%20%20%20%20%20%20min_%CE%B4_y%20%3D%20np.linspace(0.01%2C%20100000%2C%20100)%0A%20%20%20%20%20%20%20%20min_%CE%B4_z%20%3D%20profit_fn(min_%CE%B4_x%2Cmin_%CE%B4_y)%0A%0A%20%20%20%20%20%20%20%20min_%CE%B4_line%20%3D%20go.Scatter3d(%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3Dmin_%CE%B4_x.tolist()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3Dmin_%CE%B4_y.tolist()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20z%3Dmin_%CE%B4_z.tolist()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mode%3D'lines'%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20line%3Ddict(color%3D'red'%2C%20width%3D5)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D'Min%20Digital%20Ad%20Spend'%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20min_%CF%84_x%20%3D%20np.linspace(0.01%2C%20100000%2C%20100)%0A%20%20%20%20%20%20%20%20min_%CF%84_y%20%3D%20np.ones(100)%20*%2020000%0A%20%20%20%20%20%20%20%20min_%CF%84_z%20%3D%20profit_fn(min_%CF%84_x%2Cmin_%CF%84_y)%0A%0A%20%20%20%20%20%20%20%20min_%CF%84_line%20%3D%20go.Scatter3d(%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3Dmin_%CF%84_x.tolist()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3Dmin_%CF%84_y.tolist()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20z%3Dmin_%CF%84_z.tolist()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mode%3D'lines'%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20line%3Ddict(color%3D'blue'%2C%20width%3D5)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D'Min%20TV%20Ad%20Spend'%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20%23%20Add%20optimal%20point%0A%20%20%20%20%20%20%20%20optimal_z%20%3D%20float(profit.evalf(subs%3D%7B%CE%B4%3A%2061820%2C%20%CF%84%3A%2038180%7D))%0A%20%20%20%20%20%20%20%20optimal_point%20%3D%20go.Scatter3d(%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3D%5B61820%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3D%5B38180%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20z%3D%5Boptimal_z%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mode%3D'markers'%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20marker%3Ddict(size%3D6%2C%20color%3D'green')%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D'Optimal%20Point'%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20%23%20Create%20figure%0A%20%20%20%20%20%20%20%20fig%20%3D%20go.Figure(data%3D%5Bsurface%2C%20budget_line%2C%20min_%CE%B4_line%2C%20min_%CF%84_line%2C%20optimal_point%5D)%0A%0A%20%20%20%20%20%20%20%20%23%20Update%20layout%0A%20%20%20%20%20%20%20%20fig.update_layout(%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D'Profit%20Function%20with%20Constraints'%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20scene%20%3D%20dict(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20xaxis_title%3D'Digital%20Ad%20Spend%20(%CE%B4)'%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20yaxis_title%3D'TV%20Ad%20Spend%20(%CF%84)'%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20zaxis_title%3D'Profit%20(%CF%80)'%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20camera%3Ddict(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20eye%3Ddict(x%3D1.5%2C%20y%3D1.5%2C%20z%3D1.5)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20showlegend%3DTrue%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20%23%20Save%20the%20figure%0A%20%20%20%20%20%20%20%20fig.write_html(%22data%2Fprofit_function_3d.html%22)%0A%20%20%20%20%20%20%20%20fig.write_image('data%2Fprofit_function_3d.webp'%2C%20format%3D'webp'%2C%20scale%3D5)%0A%0A%20%20%20%20profit_function_viz_3d()%0A%20%20%20%20mo.image(%22data%2Fprofit_function_3d.webp%22%2C%20height%3D500).center()%0A%20%20%20%20%23%20display_iframe(%22data%2Fprofit_function_3d.html%22)%0A%20%20%20%20return%20(profit_function_viz_3d%2C)%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%5BView%20Interactive%20Plotly%20Graph%5D(%2Farticles%2Fnotebooks%2Fdata%2Fprofit_function_3d.html)%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo%2C%20np%2C%20plt)%3A%0A%20%20%20%20def%20profit_function_viz_contour()%3A%0A%20%20%20%20%20%20%20%20def%20log(x)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20np.log(x)%0A%0A%20%20%20%20%20%20%20%20def%20profit(%CE%B4%2C%20%CF%84)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20profit_function%20%3D%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20-%CE%B4%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20-%20%CF%84%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20-%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20-1.00712795746647%20*%20log(%CE%B4)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20-%200.621999261508067%20*%20log(%CF%84)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2B%20138.264406731209%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2010071.2795746647%20*%20log(%CE%B4)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2B%206219.99261508067%20*%20log(%CF%84)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2B%2017355.9326879056%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2B%201812830.32343965%20*%20log(%CE%B4)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2B%201119598.67071452%20*%20log(%CF%84)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2B%203124067.88382301%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20profit_function%0A%0A%20%20%20%20%20%20%20%20%23%20Define%20the%20grid%0A%20%20%20%20%20%20%20%20%CE%B4%20%3D%20np.linspace(0.01%2C%20100000%2C%201000)%0A%20%20%20%20%20%20%20%20%CF%84%20%3D%20np.linspace(0.01%2C%20100000%2C%201000)%0A%20%20%20%20%20%20%20%20X%2C%20Y%20%3D%20np.meshgrid(%CE%B4%2C%20%CF%84)%0A%20%20%20%20%20%20%20%20Z%20%3D%20profit(X%2C%20Y)%0A%0A%20%20%20%20%20%20%20%20%23%20Define%20constraints%0A%20%20%20%20%20%20%20%20x_constraint%20%3D%20np.linspace(0%2C%20100_000%2C%20500)%0A%20%20%20%20%20%20%20%20y_constraint%20%3D%20100_000%20-%20x_constraint%0A%0A%20%20%20%20%20%20%20%20%23%20Plot%20contours%20of%20profit%20function%0A%20%20%20%20%20%20%20%20plt.figure(dpi%3D125)%0A%20%20%20%20%20%20%20%20contour%20%3D%20plt.contour(X%2C%20Y%2C%20Z%2C%20levels%3D100%2C%20cmap%3D%22plasma%22)%0A%20%20%20%20%20%20%20%20plt.colorbar(contour)%0A%0A%20%20%20%20%20%20%20%20plt.plot(%0A%20%20%20%20%20%20%20%20%20%20%20%20x_constraint%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y_constraint%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22green%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20linestyle%3D%22--%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20linewidth%3D1%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20label%3Dr%22Constraint%3A%20%24%5Cdelta%20%2B%20%5Ctau%20%3D%20100%2C000%24%22%2C%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20%23%20%23%20Mark%20the%20optimization%20points%0A%20%20%20%20%20%20%20%20plt.scatter(%0A%20%20%20%20%20%20%20%20%20%20%20%2061819.54%2C%0A%20%20%20%20%20%20%20%20%20%20%20%2038180.46%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22green%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20marker%3D%22o%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20s%3D100%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20label%3D%22Constrained%20Optimum%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20zorder%3D3%2C%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20%23%20Plot%20constraint%20lines%0A%20%20%20%20%20%20%20%20plt.axvline(%0A%20%20%20%20%20%20%20%20%20%20%20%2010_000%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22black%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20linestyle%3D%22-%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20linewidth%3D1%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20label%3Dr%22Constraint%3A%20%24%5Cdelta%20%5Cgeq%2010%2C000%24%22%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20plt.axhline(%0A%20%20%20%20%20%20%20%20%20%20%20%2020_000%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22black%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20linestyle%3D%22--%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20linewidth%3D1%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20label%3Dr%22Constraint%3A%20%24%5Ctau%20%5Cgeq%2020%2C000%24%22%2C%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20%23%20Shade%20infeasible%20regions%20in%20gray%0A%20%20%20%20%20%20%20%20plt.fill_betweenx(%0A%20%20%20%20%20%20%20%20%20%20%20%20%CF%84%2C%200%2C%2010_000%2C%20color%3D%22gray%22%2C%20alpha%3D0.5%0A%20%20%20%20%20%20%20%20)%20%20%23%20Shade%20region%20where%20x%20%3E%200%0A%20%20%20%20%20%20%20%20plt.fill_between(%0A%20%20%20%20%20%20%20%20%20%20%20%20%CE%B4%2C%200%2C%2020_000%2C%20color%3D%22gray%22%2C%20alpha%3D0.5%0A%20%20%20%20%20%20%20%20)%20%20%23%20Shade%20region%20where%20y%20%3C%203%0A%0A%20%20%20%20%20%20%20%20%23%20Labels%20and%20legend%0A%20%20%20%20%20%20%20%20plt.xlabel(r%22%24%5Cdelta%24%22)%0A%20%20%20%20%20%20%20%20plt.ylabel(r%22%24%5Ctau%24%22)%0A%20%20%20%20%20%20%20%20plt.title(%22Contour%20Representation%22)%0A%20%20%20%20%20%20%20%20plt.legend(loc%3D%22lower%20center%22%2C%20bbox_to_anchor%3D(0.5%2C%20-0.4))%0A%20%20%20%20%20%20%20%20plt.savefig(%22data%2Fprofit_function_viz_contour.webp%22%2C%20format%3D%22webp%22%2C%20dpi%3D300%2C%20bbox_inches%3D'tight')%0A%0A%20%20%20%20profit_function_viz_contour()%0A%20%20%20%20mo.image(%22data%2Fprofit_function_viz_contour.webp%22%2C%20height%3D500).center()%0A%20%20%20%20return%20(profit_function_viz_contour%2C)%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22Let%E2%80%99s%20now%20solve%20our%20optimization%20problem%20as%20formulated%20in%20eq.%2012%20via%20python%20using%20the%20optimization%20theory%20that%20we%20have%20learned%20from%20part%201%20and%20part%202%20of%20this%20series.%20_Note%20that%20the%20extremely%20high%20value%20of%20%24%5Crho%24%20is%20to%20account%20for%20the%20fact%20that%20the%20values%20of%20our%20objective%20function%20are%20extremely%20large%20thus%20we%20need%20to%20make%20sure%20penalization%20is%20large%20enough%20to%20avoid%20%E2%80%9Cjumping%E2%80%9D%20out%20of%20constraints%20-%20we%20could%20normalize%20values%20for%20more%20stability._%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(constrained_newtons_method%2C%20profit%2C%20sm%2C%20%CE%B4%2C%20%CE%BB%2C%20%CF%81%2C%20%CF%84)%3A%0A%20%20%20%20def%20profit_max()%3A%0A%20%20%20%20%20%20%20%20objective%20%3D%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20-profit%20%2B%20%CE%BB%20*%20(%CF%84%20%2B%20%CE%B4%20-%20100_000)%20-%20%CF%81%20*%20sm.log((%CF%84%20-%2020_000)%20*%20(%CE%B4%20-%2010_000))%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20symbols%20%3D%20%5B%CE%B4%2C%20%CF%84%2C%20%CE%BB%2C%20%CF%81%5D%0A%20%20%20%20%20%20%20%20x0%20%3D%20%7B%CE%B4%3A%2020_000%2C%20%CF%84%3A%2080_000%2C%20%CE%BB%3A%200%2C%20%CF%81%3A%20100_000%7D%0A%0A%20%20%20%20%20%20%20%20return%20constrained_newtons_method(objective%2C%20symbols%2C%20x0%2C%20rho_steps%3D1000)%0A%0A%20%20%20%20optimums%20%3D%20profit_max()%0A%20%20%20%20return%20optimums%2C%20profit_max%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22Thus%2C%20our%20solution%20is%20to%20spend%20~61%2C800%20on%20digital%20ad%20spend%20and%20~38%2C200%20on%20television%20ad%20spend.%20These%20values%20correspond%20to%3A%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(Cost%2C%20Revenue%2C%20optimums%2C%20quantity_demanded%2C%20%CE%B4%2C%20%CF%84)%3A%0A%20%20%20%20digital_ad%20%3D%20optimums%5B%CE%B4%5D%0A%20%20%20%20television_ad%20%3D%20optimums%5B%CF%84%5D%0A%0A%20%20%20%20quantity_val%20%3D%20quantity_demanded.evalf(subs%3D%7B%CE%B4%3A%20digital_ad%2C%20%CF%84%3A%20television_ad%7D)%0A%20%20%20%20revenue_val%20%3D%20Revenue.evalf(subs%3D%7B%CE%B4%3A%20digital_ad%2C%20%CF%84%3A%20television_ad%7D)%0A%20%20%20%20cost_val%20%3D%20Cost.evalf(subs%3D%7B%CE%B4%3A%20digital_ad%2C%20%CF%84%3A%20television_ad%7D)%0A%20%20%20%20profit_val%20%3D%20revenue_val%20-%20cost_val%0A%0A%20%20%20%20print(f%22Quantity%3A%20%7Bint(quantity_val)%3A%2C%7D%22)%0A%20%20%20%20print(f%22Total%20Revenue%3A%20%24%7Bround(revenue_val%2C2)%3A%2C%7D%22)%0A%20%20%20%20print(f%22Total%20Cost%3A%20%24%7Bround(cost_val%2C2)%3A%2C%7D%22)%0A%20%20%20%20print(f%22Profit%3A%20%24%7Bround(profit_val%2C2)%3A%2C%7D%22)%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20cost_val%2C%0A%20%20%20%20%20%20%20%20digital_ad%2C%0A%20%20%20%20%20%20%20%20profit_val%2C%0A%20%20%20%20%20%20%20%20quantity_val%2C%0A%20%20%20%20%20%20%20%20revenue_val%2C%0A%20%20%20%20%20%20%20%20television_ad%2C%0A%20%20%20%20)%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%20%20%20%20%23%23%20Conclusion%0A%0A%20%20%20%20%20%20%20%20The%20profit%20maximization%20problem%20in%20this%20final%20article%20was%20by%20no%20means%20meant%20to%20be%20an%20entirely%20comprehensive%20solution.%20In%20fact%2C%20we%20did%20not%20need%20to%20even%20use%20Newton%E2%80%99s%20Method%20for%20such%20a%20simple%20optimization%20problem!%20But%2C%20as%20optimization%20problems%20increase%20in%20complexity%20and%20dimensionality%2C%20which%20is%20quite%20common%20in%20the%20real%20world%2C%20these%20tools%20become%20increasingly%20relevant.%20The%20goal%20was%20to%20take%20what%20we%20have%20learned%20in%20part%201%20and%20part%202%20of%20this%20series%20and%20take%20a%20fun%20exploration%20into%20one%20of%20infinitely%20many%20applications%20of%20optimization%20theory.%0A%0A%20%20%20%20%20%20%20%20If%20you%20have%20made%20it%20up%20to%20this%20point%2C%20thank%20you%20for%20taking%20time%20out%20of%20your%20day%20to%20read%20my%20article%20and%20I%20want%20to%20extend%20an%20extra%20thank%20you%20to%20those%20individuals%20that%20have%20read%20through%20all%203%20parts%20of%20this%20series.%20I%20hope%20at%20this%20point%20you%20feel%20very%20comfortable%20with%20basic%20multi-dimensional%20optimization%20theory%20and%20extensions%20involving%20constraints%20on%20the%20objective%20function.%20As%20always%2C%20I%20hope%20you%20have%20enjoyed%20reading%20this%20as%20much%20as%20I%20enjoyed%20writing%20it.%20Please%20let%20me%20know%20what%20you%20thought%20of%20this%20article%20and%20the%20series%20as%20whole!%0A%0A%20%20%20%20%20%20%20%20%23%23%20Bonus%20-%20Numerical%20and%20Analytical%20Solutions%20to%20Linear%20Regression%0A%0A%20%20%20%20%20%20%20%20As%20promised%20above%2C%20this%20section%20will%20provide%20code%20for%20solving%20the%20linear%20regression%20problem%20above%20utilizing%20Newton's%20method%20and%20we%20will%20compare%20this%20result%20to%20the%20analytical%20closed-form%20solution%20%26%20statsmodels%20directly.%20This%20exercise%20will%20provide%20a%20very%20elegant%20connection%20between%20model%20fitting%2C%20optimization%2C%20%26%20different%20techniques%20for%20doing%20this!%20Recall%20that%20the%20objective%20for%20solving%20the%20linear%20regression%20is%20to%20minimize%20the%20%5BResidual%20Sum%20of%20Squares%5D(https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FResidual_sum_of_squares).%20That%20is%2C%20in%20terms%20of%20matrices%2C%0A%0A%20%20%20%20%20%20%20%20%24%24%0A%20%20%20%20%20%20%20%20%5Cbegin%7Bequation%7D%0A%20%20%20%20%20%20%20%20%5Cmin_%7B%5Cbeta%7D%20%20(y-%5Cmathbf%7BX%7D%5Cbeta)%5ET(y-%5Cmathbf%7BX%7D%5Cbeta)%0A%20%20%20%20%20%20%20%20%5Ctag%7BA1%7D%0A%20%20%20%20%20%20%20%20%5Cend%7Bequation%7D%0A%20%20%20%20%20%20%20%20%24%24%0A%0A%20%20%20%20%20%20%20%20Thus%2C%20using%20our%20Newton%20method%20function%20and%20framework%2C%20we%20have%3A%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df_mod%2C%20newtons_method%2C%20np%2C%20pd%2C%20sm)%3A%0A%20%20%20%20def%20ols_newtons_method(input_df%3A%20pd.DataFrame)%3A%0A%20%20%20%20%20%20%20%20%23%20Pull%20all%20variables%20in%20X%20and%20create%20them%20as%20SymPy%20symbols%0A%20%20%20%20%20%20%20%20variablez%20%3D%20list(input_df.drop(%5B%22quantity_demanded%22%2C%20%22July%22%5D%2C%20axis%3D1).columns)%0A%20%20%20%20%20%20%20%20symbols%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20for%20i%20in%20variablez%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20i%20%3D%20sm.symbols(f%22%7Bi%7D%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20symbols.append(i)%0A%0A%20%20%20%20%20%20%20%20%23%20Create%20vectors%20and%20matrices%20of%20outcome%20(y)%2C%20covariates%20(X)%2C%20and%20parameters(%CE%B2)%0A%20%20%20%20%20%20%20%20y%20%3D%20np.array(input_df%5B%22quantity_demanded%22%5D)%0A%20%20%20%20%20%20%20%20X%20%3D%20np.array(input_df.drop(%5B%22quantity_demanded%22%2C%20%22July%22%5D%2C%20axis%3D1))%0A%20%20%20%20%20%20%20%20%CE%B2%20%3D%20np.array(symbols)%0A%0A%20%20%20%20%20%20%20%20%23%20Specify%20objective%20function%20and%20starting%20values%0A%20%20%20%20%20%20%20%20objective%20%3D%20(y%20-%20X%20%40%20%CE%B2).T%20%40%20(y%20-%20X%20%40%20%CE%B2)%20%20%23%20Residual%20Sum%20of%20Squares%0A%20%20%20%20%20%20%20%20%CE%B2_0%20%3D%20dict(zip(symbols%2C%20%5B0%5D%20*%20len(symbols)))%0A%0A%20%20%20%20%20%20%20%20return%20newtons_method(objective%2C%20symbols%2C%20%CE%B2_0)%0A%0A%20%20%20%20%CE%B2_numerical%20%3D%20ols_newtons_method(df_mod)%0A%20%20%20%20return%20ols_newtons_method%2C%20%CE%B2_numerical%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%20%20%20%20Next%20we%20will%20compute%20the%20analytical%20solution.%20That%20is%2C%20if%20we%20take%20the%20derivative%20of%20eq.%20A1%20and%20set%20it%20equal%20to%20zero%20and%20solve%20for%20%24%5Cbeta%24%2C%20we%20obtain%3A%0A%0A%20%20%20%20%20%20%20%20%24%24%0A%20%20%20%20%20%20%20%20%5Cbegin%7Bequation%7D%0A%20%20%20%20%20%20%20%20%5Cbeta%5E*%20%3D%20(X%5ETX)%5E%7B-1%7DX%5ETy%20%0A%20%20%20%20%20%20%20%20%5Ctag%7BA2%7D%0A%20%20%20%20%20%20%20%20%5Cend%7Bequation%7D%0A%20%20%20%20%20%20%20%20%24%24%0A%0A%20%20%20%20%20%20%20%20Coding%20this%2C%20we%20have%20(we%20also%20provide%20analytical%20standard%20errors%20to%20compare%20to%20statsmodels%2C%20see%20the%20%5BOLS%20wiki%20page%5D(https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FOrdinary_least_squares%23Estimation)%20if%20you%20are%20interested)%3A%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df_mod%2C%20np%2C%20pd)%3A%0A%20%20%20%20def%20ols_analytical(input_df%3A%20pd.DataFrame)%3A%0A%20%20%20%20%20%20%20%20y%20%3D%20np.array(input_df%5B%22quantity_demanded%22%5D)%0A%20%20%20%20%20%20%20%20X%20%3D%20np.array(input_df.drop(%5B%22quantity_demanded%22%2C%20%22July%22%5D%2C%20axis%3D1))%0A%0A%20%20%20%20%20%20%20%20%23%20OLS%20Analytical%20Solution%0A%20%20%20%20%20%20%20%20%CE%B2_analytical%20%3D%20np.linalg.inv(X.T%20%40%20X)%20%40%20X.T%20%40%20y%0A%0A%20%20%20%20%20%20%20%20%23%20Compute%20standard%20errors%0A%20%20%20%20%20%20%20%20df_residuals%20%3D%20len(X)%20-%20len(%CE%B2_analytical)%0A%20%20%20%20%20%20%20%20%CF%832%20%3D%20(%0A%20%20%20%20%20%20%20%20%20%20%20%201%20%2F%20df_residuals%20*%20((y%20-%20X%20%40%20%CE%B2_analytical).T%20%40%20(y%20-%20X%20%40%20%CE%B2_analytical))%0A%20%20%20%20%20%20%20%20)%20%20%23%20MSE%0A%20%20%20%20%20%20%20%20%CE%A3%20%3D%20%CF%832%20*%20np.linalg.inv(X.T%20%40%20X)%0A%20%20%20%20%20%20%20%20standard_errors%20%3D%20np.sqrt(np.diag(%CE%A3))%0A%0A%20%20%20%20%20%20%20%20return%20%CE%B2_analytical%2C%20standard_errors%0A%0A%20%20%20%20%CE%B2_analytical%2C%20standard_errors%20%3D%20ols_analytical(df_mod)%0A%20%20%20%20return%20ols_analytical%2C%20standard_errors%2C%20%CE%B2_analytical%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22Now%2C%20comparing%20all%20these%20results%3A%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(df_mod%2C%20pd%2C%20results%2C%20standard_errors%2C%20%CE%B2_analytical%2C%20%CE%B2_numerical)%3A%0A%20%20%20%20ols_results%20%3D%20pd.DataFrame()%0A%0A%20%20%20%20ols_results%5B%22variable%22%5D%20%3D%20list(%0A%20%20%20%20%20%20%20%20df_mod.drop(%5B%22quantity_demanded%22%2C%20%22July%22%5D%2C%20axis%3D1).columns%0A%20%20%20%20)%0A%20%20%20%20ols_results%5B%22%CE%B2_numerical%22%5D%20%3D%20list(%CE%B2_numerical.values())%0A%20%20%20%20ols_results%5B%22%CE%B2_analytical%22%5D%20%3D%20%CE%B2_analytical%0A%20%20%20%20ols_results%5B%22std_err_analytical%22%5D%20%3D%20standard_errors%0A%20%20%20%20ols_results%5B%22%CE%B2_statsmodels%22%5D%20%3D%20list(results.params)%20%20%23%20from%20statsmodels%20code%20above%0A%20%20%20%20ols_results%5B%22std_err_statsmodels%22%5D%20%3D%20list(%0A%20%20%20%20%20%20%20%20results.bse%0A%20%20%20%20)%20%20%23%20from%20statsmodels%20code%20above%0A%20%20%20%20ols_results%20%3D%20ols_results.set_index(%22variable%22)%0A%0A%20%20%20%20ols_results%0A%20%20%20%20return%20(ols_results%2C)%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%20%20%20%20%3Cdiv%20style%3D%22text-align%3A%20center%3B%20font-size%3A%2024px%3B%22%3E%E2%9D%96%E2%9D%96%E2%9D%96%3C%2Fdiv%3E%0A%0A%20%20%20%20%20%20%20%20%3Ccenter%3E%0A%20%20%20%20%20%20%20%20Access%20all%20the%20code%20via%20this%20Marimo%20Notebook%20or%20my%20%5BGitHub%20Repo%5D(https%3A%2F%2Fgithub.com%2Fjakepenzak%2Fblog-posts)%0A%0A%20%20%20%20%20%20%20%20I%20appreciate%20you%20reading%20my%20post!%20My%20posts%20primarily%20explore%20real-world%20and%20theoretical%20applications%20of%20econometric%20and%20statistical%2Fmachine%20learning%20techniques%2C%20but%20also%20whatever%20I%20am%20currently%20interested%20in%20or%20learning%20%F0%9F%98%81.%20At%20the%20end%20of%20the%20day%2C%20I%20write%20to%20learn!%20I%20hope%20to%20make%20complex%20topics%20slightly%20more%20accessible%20to%20all.%0A%20%20%20%20%20%20%20%20%3C%2Fcenter%3E%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
a77b19a4a5ff533ea49f682d5d58399f6720160f820e762020293683757e33d7