Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
| Download

📚 The CoCalc Library - books, templates and other resources

Views: 96158
License: OTHER
Kernel: SageMath 8.6

1. Introduction

Notebook for the Public Finance course, UCSC, AY 2018/2019 by Duccio Gamannossi degl' Innocenti. You can find more information on the course here.

What is SageMath?

SageMath is a free open-source mathematics software system licensed under the GPL:

  • Sage is a set of software libraries built on top of Python, a widely used general purpose programming language.

  • SageMath can be used to study elementary and advanced, pure and applied mathematics. Supported by nearly 100 open-source packages, SageMath allows to investigate a variety of topics: algebra, calculus, elementary to very advanced number theory, cryptography, etc..

  • SageMath provides a free alternative to Mathematica, Maple, Matlab and Magma -- it is open source and community driven -- (Some thoughts on that by a Nobel laureate and his twitter feed).

  • More information about SageMath: Tour, Why SageMath, SageMath on twitter.

SageMath in this course

This course's notebooks are meant to integrate the material from the book and the slides:

  • Many of the concepts of the course are presented by means of graphical analysis. The use of interactive graphs should facilitate their understanding.

  • When possible, excercises will be presented on notebooks.

  • The notebook is a tool to engage directly with the concepts presented by the book while leveraging on the computational capabilities of the computer. "Why is this demand curve shaped that way?" - "What would happen to this result by changing that parameter?" - "How is this result derived?" - and many other similar questions can be answered through a notebook so to improve learning.

  • Notebooks provide an opportunity to get used to both coding and math, whose skills are extremely in demand in the job market.

Do you need to code?

No, these notebooks are aimed at providing a clear presentation of the concepts of Public Finance by means of narratives, graphs and math. No coding activity is expected from students. However, directly engaging with the concepts by using the opportunities offered by this format might prove very fruitful for learning and you are more than encoraged to do so.

SageMath interface used in this course - Jupyter notebook

  • Jupyter notebook is a webapp -- i.e., an app that runs through your web browser -- used for generic scientific computing.

  • It allows to use the computational power of your machine to perform symbolic and numerical operations (very handy for those that are not well versed in doing math with pen and paper).

  • The notebook consists of a number of cells that take code from different languages: LaTeX, Markdown, as well as SageMath, Python, R, Julia...

  • The notebook format allows to present an analysis in a plain, albeit thorough, way. This is achieved by including in the same document a description of the analysis that is performed, beautifully typeset mathematical expressions, graphics (even interactive ones) and the mathematical derivation of the results. Here, you can find a gallery of economic-related notebooks, while here you can find an introductory video about notebooks.

  • The notebook is a conveninet interface for the user to provide input to the computer (the front-end). The computer needs then to pass the input to a computational "engine" that actually perform the tasks submitted (the back-end). In order to be able to run notebooks, you need to set up the back-end. There are three possibility to do so: you can run the computations on your laptop by installing SageMath, you can register a free account at Cocalc (more info about CoCalc here), or you may use the service offered by Binder to set up an interactive environment on the fly (it will take 10-30 min since it has to install on the cloud everything you need).

You have opened the notebook, what do you need to do now to display it correctly?

While text and mathematical expressions of the notebooks are usually displayed by default, plots and interactive graphics need to be evaluated every time that the notebook gets opened. So, after opening the notebook of interest using your preferred method (SageMath, CoCalc, Binder), it is important to evaluate all the cells of the notebook. To do so, from the drop-down-menu at the top of the page, select "Kernel\rightarrowRestart & Run All" or simply press the forward button just below the Widgets entry of the menu. As implied by the name, this command will run the whole document (despite being a quick procedure it is not instantaneous, you will need to wait some seconds) ensuring the correct display of the content. If you just want to evaluate a cell, place the cursor in the code-chunk and press Shift+Enter.

Why should SageMath be of interest to you?

  • Because it is a tool that expand your ability to deal with mathematical and computational problems.

  • Because its mix of textual, math, and graphics content that might improve your understanding of concepts.

Sagemath as an operative tool

Your ability to perform basic operations (sum, difference, multiplication, quotient) greatly improved when you were taught how to do them using pen and paper, and even more when you started using a calculator. SageMath brings you a similar ability for a wider array of math problems. For example, what is the second derivative of the function ln(1x2)3x2+2x+1\frac{ln(\frac{1}{x^2})}{3x^2+2x+1}? Answering this question is very hard if you have to do it without pen and paper, prone to mistake otherwise. Conversely, using SageMath you get a fast and reliable solution:

g = (ln(1/(x^2)))/(3*(x^2)+2*x+1) dgdxx=derivative(g, x, x).simplify_full() html("g =" + latex(g) + "\\\\" + "\\frac{d^2g}{dx^2}=" + latex(dgdxx))

A simple utility maximization problem

As an Economics student you will come across countless utility maximization problems.

Let's see how one simple example can be tackled using SageMath. We want to find the optimal consumption of coffe for a student at UCSC. As we know, the coffe price is p=.6p=.6 euro. We are considering a particular student who feels awful before her first coffe in the morning, enjoy less and less every additional coffe and starts shaking due to caffeine when taking more than five. Then, we could model her utility from coffee as U(z)=5zz2U(z)=5z - z^2. The problem of our student is then to maximize her objective function F(z,p)=5zz2zpF(z,p) = 5z - z^2 - zp where zz is the number of coffes consumed.

The first step in the analysis is to define the Utility function and the Objective function function:

U(z) = 5*z-z^2 F(z, p) = 5*z-z^2 - (z*p) html("U(z)=" + latex(U(z)) + "\\\\" + "F(z,p)=" + latex(F(z, p)))

We might want to explore the problem visually, so to have a better idea about it.

p=.6 plot([U(z), p*z, F(z,p)], (z, 0, 5), axes_labels=['$z$','$F(z)$'], legend_label = ["Utility from consumption", "Cost of consumption", "Objective function"])
Image in a Jupyter notebook

From the graph we can see that the optimal quantity of good, zz^* is around 22. We can then compute the FOCFOC, equate it to zero and solve for zz to identify precisely the optimal quantity.

FOC = derivative(F(z, p), z) html(latex(solve(FOC == 0, z)[0]))

So it is z=115=2.2z^*=\frac{11}{5}=2.2. So it seems that our student of interest will usually get a couple coffe, which sounds about right. We already know from the plot that the FOCFOC is identifying a maximum, but we can express it more concisely by reporting the SOCSOC:

SOC = derivative(F(z, p), z, z) html("SOC=" + latex(SOC) + "<0")

The problem here presented is neat and simple for illustrative purposes, but it can be easily extended to more complex questions, e.g more complex utility functions (e.g., someone who does not enjoy that much a daily coffe but that binges heavily before exams), multi-goods maximization problems (e.g., coffe and croissant), etc.. The main points I am trying to make are that solving this kind of problems using SageMath is straightforward, when something is unclear you can explore the problem visually and it is easy to scale from small, understandable problems to more complex ones.

A simple example of an interactive visualization

SageMath might also be usefult to improve your understanding of mathematical concepts by allowing you to explore them thoroughly. In your calculus course you should have already come across the Taylor series f^(x;x0,n)=n=0f(n)(x0)n!(xx0)n\hat{f}(x; x_0, n)=\sum_{n=0}^{\infty}\frac{f^{(n)}(x_0)}{n!}(x-x_0)^n and its use to approximate functions. Should you still be missing something about it, we can use the notebook to plot its graphical representation to make things clearer. We will try to see how the Taylor series approximation behaves for the function f(x)=x5f(x)=x^5 nearby the point x0=1x_0=1. To do so, we write a short script that takes as input the order nn of the Taylor series and that outputs the plot of the original function f(x)=x5f(x)=x^5, the plot of its Taylor series approximation f^(x;x0,n)\hat{f}(x; x_0, n) along with the algebraic form of the two:

#import the library needed to adjust plot fonts import matplotlib as mpl #increse font size to improve readability mpl.rcParams['font.size'] = 12. #define the point upon which perform the Taylor expansion x0 = 1 #define the function f(x) f(x) = x^5 #compute the plot of the function f(x) p_1 = plot(f(x),-1, 5, thickness=2, legend_label = '$'+'f(x) ='+ latex(f(x))+'$') #compute the plot of the point {x0, f(x0)} dot = point((x0,f(x=x0)), pointsize=80, rgbcolor=(1,0,0)) #calling @interact to allow functions and plot to be dependent on some interactive inputs from the user @interact #create a slider from 1 to 10 to be used by the user to define the value of the Taylor order n def _(n=[1..10]): #compute the Taylor expansion of function f(x) relative to variable x, at point x0, of order n ft = f.taylor(x,x0,n) #compute the plot of the Taylor expansion of function f(x) pt = plot(ft, (x, -1, 5), color='green', thickness=2, legend_label = '$\hat{f}(x; x_0, n)$') #show the algebraic expression of f(x) pretty_print(html('$f(x)\;=\;%s$'%latex(f(x)))) #show the algebraic expression of the Taylor expansion of function f(x) pretty_print(html('$\hat{f}(x; x_0, n)=\hat{f}(x;%s;%s)\;=\;%s+\mathcal{O}(x^{%s})$'%(x0,n,latex(ft.expand()),n+1))) #creates P_tot, a plot combining the plots of f(x), its Taylor expansion and the point {x0, f(x0)} P_tot = dot + p_1 + pt #defines the legend of the P_tot plot P_tot.set_legend_options(handlelength=2, borderaxespad = 0, labelspacing =.05, bbox_to_anchor=(1.05, 1), loc=2) #shows the P_tot plot show(P_tot, ymin = -.5, ymax = 3, figsize=[6,4])

Crucial to this code is the row ft=f.taylor(x,x0,n) that defines the function ft as the Taylor expansion of the function f(x) relative to the variable x, at the point x0 using an order of the polynomial nn equal to the variable n. This function computes the Taylor series algebraic expression n=0f(n)(x0)n!(xx0)n\sum_{n=0}^{\infty}\frac{f^{(n)}(x_0)}{n!}(x-x_0)^{n} and gives us the solution (that you can find displayed at the top of the graph).

As we can see, when the degree of the Taylor polynomial rises, it approaches the correct function (the green line stays "more" on top of the blue line"). In our case the approximation improves until the order of the Taylor series gets to n=5n=5 and then it becomes exact (indeed, a Taylor expansion of the fifth order entails a polynomial of the fifth degree, so the perfect approximation of a x5x^5 should not come as a surprise).

This visualization provides us with a characterization of the Taylor expansion that is complementary to its algebraic formulation and that may be easier to grasp for some.

Now that we have a better understanding of the Taylor expansion, we could ask how our approximation would perform with a more complex function, let's say f(x)=exsin(x)f(x)=e^{-x}\sin(x).

We just need to change our f(x) = x^5 in the code to be f_2(x) = sin(x)*e^(-x) and play again with the graph.

#import the library needed to adjust plot fonts import matplotlib as mpl #increse font size to improve readability mpl.rcParams['font.size'] = 12. #define the point upon which perform the Taylor expansion x0 = 1 #define the function f_2(x) f_2(x) = sin(x)*e^(-x) #compute the plot of the function f_2(x) p_2 = plot(f_2(x),-1, 5, thickness=2, legend_label = '$'+'f(x) ='+ latex(f_2(x))+'$') #compute the plot of the point {x0, f_2(x0)} dot_2 = point((x0,f_2(x=x0)), pointsize=80, rgbcolor=(1,0,0)) #calling @interact to allow functions and plot to be dependent on some interactive inputs from the user @interact #create a slider from 1 to 10 to be used by the user to define the value of the Taylor order n def _(n=[1..10]): #compute the Taylor expansion of function f_2(x) relative to variable x, at point x0, of order n ft_2 = f_2.taylor(x,x0,n) #compute the plot of the Taylor expansion of function f_2(x) pt_2 = plot(ft_2, (x, -1, 5), color='green', thickness=2, legend_label = '$\hat{f}(x; x_0, n)$') #show the algebraic expression of f_2(x) pretty_print(html('$f(x)\;=\;%s$'%latex(f_2(x)))) #show the algebraic expression of the Taylor expansion of function f_2(x) pretty_print(html('$\hat{f}(x; x_0, n)=\hat{f}(x;%s;%s)\;=\;%s+\mathcal{O}(x^{%s})$'%(x0,n,latex(ft_2),n+1))) #creates P_tot_2, a plot combining the plots of f_2(x), its Taylor expansion and the point {x0, f_2(x0)} P_tot_2 = dot_2 + p_2 + pt_2 #defines the legend of the P_tot_2 plot P_tot_2.set_legend_options(handlelength=2, borderaxespad = 0, labelspacing =.05, bbox_to_anchor=(1.05, 1), loc=2) #shows the P_tot_2 plot show(P_tot_2, ymin = -.5, ymax = 3, figsize=[6,4])

In this case we can see that the approximation does not become exact even if a polynomial of 10th degree is used. Indeed, it really seems to be impossible to express exactly the function f(x)=exsin(x)f(x)=e^{-x}\sin(x) with a Taylor series made up of a finite number of polynomials.

The graph presented conveys lots of information that, upon closer inspection, might be uncovered. For example, it might be of interest to know when the approximated results are close to the true ones and, probably even more important, for which values of xx we should not trust the approximation. In other terms, we might want to identify an interval around x0x_0 where we know our approximation is reliable and how this interval varies with the order of the Taylor series. To do so, look for the values of xx where the blue and the green line overlaps. We can see that, when n=2n=2, our approximation is reliable only very close to x0x_0 while using n=10n=10 delivers a pretty good approximation for x[1,3]x \in [-1, 3]. Clearly, this is a very rough way to characterize our "reliable bounds", to do better, however, we would need to get back to the algebraic expressions (any idea about the next steps?).

Conclusion

Tinkering with the mathematical expressions and their plots is meant to be useful to deepen your understanding of the concepts that will be presented. Perform the course excercises through the notebook is meant to provide a more clear and complete presentation, reducing to the minimum the possibility of losing some steps in the derivation of the results. Moreover, modifying the code allows you to ask question to the models, test if you correctly understood their implications, see if results are robust to changes and so on. This process is meant to foster your ability to think critically about the material of this course.

Furthermore, getting accustomed with coding, so to be able to leverage the computational capabilities offered by computers to perform analysis, is a skill worth knowing and that is getting increasingly rewarded in the job market.

If you find any mistake or error in these notebooks or you have an idea for an interesting extension to a notebook, let me know (even better, first try to implement it yourself, it is a good exercise and also your colleagues may benefit from that).