Treffer: A Python-Based Undergraduate Course in Computational Macroeconomics

Title:
A Python-Based Undergraduate Course in Computational Macroeconomics
Language:
English
Source:
Journal of Economic Education. 2022 53(2):126-140.
Availability:
Routledge. Available from: Taylor & Francis, Ltd. 530 Walnut Street Suite 850, Philadelphia, PA 19106. Tel: 800-354-1420; Tel: 215-625-8900; Fax: 215-207-0050; Web site: http://www.tandf.co.uk/journals
Peer Reviewed:
Y
Page Count:
15
Publication Date:
2022
Document Type:
Fachzeitschrift Journal Articles<br />Reports - Descriptive
Education Level:
Higher Education
Postsecondary Education
Geographic Terms:
DOI:
10.1080/00220485.2022.2038322
ISSN:
0022-0485
2152-4068
Entry Date:
2022
Accession Number:
EJ1344530
Database:
ERIC

Weitere Informationen

The author of this article describes a new undergraduate course where students use Python programming for macroeconomic data analysis and modeling. Students develop basic familiarity with dynamic optimization and simulating linear dynamic models, basic stochastic processes, real business cycle models, and New Keynesian business cycle models. Students also gain familiarity with the popular Python libraries NumPy, Matplotlib, and pandas and make extensive use of the Jupyter Notebook. For many students in the course, this is their first experience with computer programming in any language. Feedback from students suggests that, regardless of prior programming experience, they find the course to be valuable, interesting, and enjoyable.

As Provided

AN0156279254;jmd01apr.22;2022Apr14.08:35;v2.2.500

A Python-based undergraduate course in computational macroeconomics 

The author of this article describes a new undergraduate course where students use Python programming for macroeconomic data analysis and modeling. Students develop basic familiarity with dynamic optimization and simulating linear dynamic models, basic stochastic processes, real business cycle models, and New Keynesian business cycle models. Students also gain familiarity with the popular Python libraries NumPy, Matplotlib, and pandas and make extensive use of the Jupyter Notebook. For many students in the course, this is their first experience with computer programming in any language. Feedback from students suggests that, regardless of prior programming experience, they find the course to be valuable, interesting, and enjoyable.

Keywords: Computational techniques; macroeconomics; undergraduate teaching

Computational methods are prominent in macroeconomic research. In fact, computational methods are often the only way to solve and simulate modern macroeconomic models because most simply don't admit paper and pencil solutions.[1] Computational methods are also often essential for economic data management, analysis, and visualization. Furthermore, many jobs in business and finance value computational proficiency. Blumenstyk ([3]) reports evidence that possessing computer programming skills raises the wages of newly graduated liberal arts majors by $14,000 per year. Data analysis and management skills produce a $12,000 annual wage premium.

In this article, I describe a new undergraduate course that I designed and taught at the University of California, Irvine (UCI) in the winter quarters of 2019 and 2020 under the name "Computational Macroeconomics." The course is a Python-based introduction to macroeconomic data analysis and modeling. Students practice downloading and managing publicly available macroeconomic data, computing statistics, preparing data visualizations, simulating linear dynamic models, solving models of dynamic optimization, simulating real business cycle (RBC) and New Keynesian business cycle models, and verbally interpreting computed results. Students also are encouraged to think critically about the RBC modeling approach after reading and discussing papers by Prescott ([25]) and Summers ([29]). Along the way, students gain familiarity with the basics of computer programming and some popular Python libraries like NumPy, and Matplotlib, pandas, and the Jupyter Notebook environment.[2] By the end of the course, students develop deeper macroeconomic intuition, gain experience analyzing and plotting data with Python, practice business cycle modeling, and build programming experience that will hopefully start them on a path of increasing computer proficiency.

The course targets senior economics majors. The prerequisites are differential calculus, intermediate macroeconomics, and one quarter of econometrics.[3] The course presumes no prior computer programming experience, and, in the first week, students get a brief introduction to programming in Python. For many, this is their first meaningful encounter with computer programming. My philosophy is that programming is like cooking. Most people are not going to be professional chefs, and so, reasonably, they learn how to cook as they go, acquiring the skills necessary to execute a desired recipe. Likewise, following a brief introduction to Python basics, additional programming techniques are introduced in each class on an as-needed basis. Students amass examples of working code that they can reference for future applications. Hopefully, the course stimulates their interest in coding and inspires them to continue practicing on their own or in more formal settings.

Others have written on the value and challenges of teaching computational methods for macroeconomics to undergraduates. For example, Solis-Garcia ([27]) and Neumuller, Rothschild, and Weerapana ([24]) write about the value of teaching DSGE methods to undergraduates. But, while those authors focus primarily on whether to teach DSGE methods, this article focuses on how to teach them by (1) describing a course outline, (2) describing how to teach the course effectively with Python and the Jupyter Notebook, and (3) providing resources to other instructors who might want to teach a similar course.

Instructional materials for the course are available in the following GitHub repository:

https://github.com/letsgoexploring/computational-macroeconomics.

The repository contains a set of Jupyter Notebooks for the course organized by class meeting. A Jupyter Notebook is a document that integrates computer code, in this case, Python, with rich text including equations and links. One of the contributions of this article is to describe how to exploit the versatility of Jupyter Notebooks for pedagogical purposes. The course GitHub repository also contains a sample syllabus, lecture slides, and a Python script for removing code from Jupyter Notebooks to make what are essentially electronic worksheets for class and homework assignments.

Why a course in computational macroeconomics?

There are four primary learning objectives for students in Computational Macroeconomics. The first is for them to learn to use the Python programming language to simulate quantitative dynamic macroeconomic models that are foundational for cutting-edge research and policy analysis. These models are often covered rapidly in first-year graduate courses, but in this undergraduate course, topics are developed at a sufficiently relaxed pace for students to have time to build intuition. Also, certain advanced topics like Bellman equations and the details of Taylor approximation methods are carefully avoided. Exercises emphasize visualizing data, simulating models, and providing intuitive explanations of the underlying economic mechanisms. Students leave the course with meaningful exposure to advanced macroeconomic modeling.

The second objective of the course is to practice data analysis and visualization. Students work with macroeconomic data from FRED and datasets that have been prepared specifically for them. The course makes ample use of OLS estimation and summary statistics. Students are frequently asked to construct plots of historical data or data that they have simulated from models. The course emphasizes the importance of creating high-quality, easy-to-read visualizations. Students practice explaining the intuition to the class behind the figures that they produce.

Third, students should develop stronger macroeconomic intuition. They do so by managing and analyzing macroeconomic data, by working with models and simulating them, and by reading articles and discussing debates. Students discuss the Lucas ([19]) critique, and they read a debate between Edward Prescott ([25]) and Lawrence Summers ([29]) about the merits of RBC modeling. The course explores a New Keynesian model and that is related back to the IS-MP-AS model that most of them will have learned in intermediate macroeconomics.

The final objective of the course is to teach students Python programming skills, specifically, and computer proficiency more generally. The course presumes no prior coding experience, and students learn to code like many economists do: by acquiring skills as needed to solve specific problems. I share with the class how programming is fundamental to my research and administrative productivity. Hopefully, the experience develops the students' confidence, inspires them to continue developing programming skills, and ultimately makes them more productive and marketable when they graduate.

In 2018, the Journal of Economic Education published a collection of articles on whether dynamic stochastic general equilibrium (DSGE) models should be taught in undergraduate economics courses.[4] Solis-Garcia ([27]) makes the case in favor, arguing that a DSGE-based macroeconomics course brings capable undergraduate students to the macroeconomics research frontier, provides them with marketable programming experience, and prepares them for the content that they will find in PhD programs. Strongly against the proposition, Setterfield ([26]) argues that DSGE methods should not be taught to undergraduates. According to Setterfield, "the purpose of undergraduate macro is less about getting the theory exactly right than it is about basic concepts, terminology, and how policy affects the economy" (238). The purpose is undermined, he argues, when students are taught business cycle models with no or limited role for macroeconomic policy.

Taking the middle road in the symposium, Neumuller, Rothschild, and Weerapana ([24]) argue that because DSGE modeling is part of mainstream macroeconomic research, undergraduates should be introduced to DSGE models, but in a way that builds a "conceptual bridge" between the macroeconomics research frontier and the more intuitive, Keynesian-inspired models of the standard intermediate macroeconomics curriculum. For them, the ideal bridge makes clear to students why DSGE modeling has value and what are the costs and benefits of alternative approaches to macroeconomic modeling. Crucially, they emphasize that it would be inappropriate to send students a message that what they had already learned about macroeconomics is wrong.

In the spirit of Neumuller, Rothschild, and Weerapana, the course described in this article is a complement to, not a substitute for, a strong, traditional intermediate macroeconomics foundation. DSGE modeling is presented as only one part of a set of broader topics intended to collectively promote a deeper understanding of macroeconomics. The course is an opportunity for students to try something new, get a different perspective on some of the ideas that they've been learning in other undergraduate courses, and, hopefully, get excited about programming, data analysis, and macroeconomic modeling.

Why Python?

The course could, with a similar effect, be based on a different computer program. Matlab is a natural alternative. However, Python offers several advantages. First, Python is free to obtain, so students won't have to worry about buying software licenses in order to apply what they learn in the course. Second, Python is becoming more popular within economics and many other fields.[5] Third, Python is versatile. There is an abundance of high-quality third-party libraries that can be easily and freely installed from the Python Package Index (PyPI) repository that add functionality to a basic Python installation. By the end of the course, students will have experience with a program that is free, versatile, and increasingly used in economics, finance, and many other applications.[6]

There are many options for installing a Python environment for scientific computing. I use Anaconda and recommend that students do, too.[7] Anaconda is a Python package manager, a Python data science distribution, and a collection of over 1,500 open-source Python packages, including ones used in this course: Matplotlib, NumPy, SciPy, pandas, and statsmodels. Anaconda is fast and easy to install, and its package manager ensures that all installed Python package versions are compatible.

Just like there are many ways to get a Python installation, there are even more options for choosing a development environment. In addition to Python and a base set of Python packages, an Anaconda installation also includes a few other programs, including the Jupyter Notebook. The Jupyter Notebook is a Web-browser environment that allows for a mixture of Python and HTML partitioned into cells. Notebooks can be exported to HTML and other portable formats for easy sharing. From a pedagogical perspective, the Jupyter Notebook is a fantastic tool, and the "Course Overview" section describes how to make use of the Jupyter Notebook in class.

Who takes the course?

Students in my winter 2019 and 2020 courses completed pre- and post-quarter surveys. Between the two courses, there were 90 students; 40 in 2019 and 50 in 2020. The surveys were not anonymous and were independent of the university's official course evaluation system. Completing the surveys was optional, but all 90 students completed both. The pre-quarter survey asked them to provide a little information about their backgrounds. Seventy-eight percent of the students were in their fourth year, 11 percent were third-year students, 9 percent were fifth-year students, and the remaining students were in their second year. All were in one of the three economics majors that UCI offers (Quantitative Economics, Business Economics, and Economics), and several were double-majoring in Mathematics, Data Science, Education Sciences, Computer Science, Biological Sciences, Political Sciences, Biomedical Engineering, and/or Psychology.

The pre-quarter survey indicated that students had a strong desire to learn computing skills and that, in general, they entered the class with limited programming experience. More than half of the class (59%) had never taken a college-level computer programming course, and, as shown in figure 1, about 19 percent of the students indicated that they were not even moderately familiar with any programming languages. Figure 2 shows students' self-reported assessment of computer programming proficiency using the NIH Competencies Proficiency Scale.[8] Eighty-eight percent reported proficiency at novice or below. Given the students' advanced standing in their degree programs, it is unlikely that they would have obtained programming experience as undergraduates in other settings.

Graph: Figure 1. Programming languages for which students had prior experience. Percentage of students responding that they are at least "moderately familiar" with each language. "Other" includes Microsoft Visual Basic, Mathematica, and EViews.

Graph: Figure 2. Student pre-course programming proficiency. Student self-assessment of computer programming proficiency. Options were (from least to most): No experience, fundamental awareness, novice, intermediate, advanced, expert. 90% reported proficiency at novice or below.

Course overview

The course design reflects my particular interests, the students' experience with economics and programming, and the constraints of teaching on a quarter system. Other instructors would choose to omit some topics and emphasize others. Alternative topic ideas that would still adequately introduce students to advanced macroeconomic concepts and provide them with coding experience are discussed. Also, suggestions are given for how the course might be expanded into a semester-long course.

Course structure

UCI is on the quarter system, so the course lasts for 11 weeks: 10 weeks of regular class instruction and a final exam in the 11th week. During the first 10 weeks, each week consists of two 80-minute lecture sessions and one 50-minute "discussion section," during which students typically work on problems for credit. All meetings—lecture and discussion—are held in a computer lab. I use a hands-on instructional approach, emphasizing continual learning-by-doing.

Lecture format

A typical lecture is based on a prepared Jupyter Notebook. A Jupyter Notebook is a document that integrates computer code, in this case, Python, with rich text, including equations and links. The Notebook is a nice instructional tool because it allows an instructor to write notes and instructions in HTML that students can read in advance and then complete the Notebook together with their instructor in class. See figure 3 for examples of blank and complete Notebooks. On the left is the blank Notebook that is distributed in advance, and on the right is the completed Notebook with code and results.

Graph: Figure 3. Example of a Jupyter Notebook. On the left is a blank Notebook provided to students in advance of lecture. On the right is the Notebook with code and output that was completed in class.

Making a blank notebook would be tedious. I have prepared a Python script that parses completed Notebooks and removes code, images, and results, and leaves unaltered HTML, code comments, and code that has been marked with appropriate comment text.[9] To prepare a Notebook for class, construct the complete Notebook, run the script, and then a blank Notebook that can be shared with students before class is available, and the completed one is still available to be shared after class.

In general, a lecture starts with a short description of an economic problem to be solved, followed by the instructor walking the students through coding examples related to the problem. Typically, a couple of times per class, students get a short problem to work themselves. These take about 10 minutes each. The instructor moves around the room, helping students with their errors, and encourages students with coding experience to help their neighbors. In the post-quarter survey, a majority of students indicated that they prefer to meet in a computer lab instead of a traditional classroom because they can get immediate help from the instructor or their peers if their code doesn't work.

Discussion section format

In addition to the two 80-minute lecture sessions per week, there is a 50-minute "discussion section," during which students work on one or more programming problems to be submitted by the end of the class for credit. The problems are based on the new material covered during the previous lecture. Students are encouraged to work together, but each must submit their own work. Discussion assignments are not available on the public GitHub repository but are available to other instructors by request.

Week 8 is a little different. Following a section on simulating RBC models, students are asked to read Edward Prescott's ([25]) and Lawrence Summers' ([29]) articles in the Federal Reserve Bank of Minneapolis Quarterly Review. In the discussion section that week, the class discusses some of Summers' criticisms of Prescott's RBC modeling approach. Students submit answers to questions designed to help them think through the issues in the papers. The goal is to help the students to think a little bit more carefully about the assumptions underlying the RBC models and to prepare them for the transition to the New Keynesian modeling framework.

Homework

Students receive weekly graded homework assignments. Homework assignments are distributed as Jupyter Notebooks that contain instructions but no code. As mentioned, a convenient feature of the Notebook is that it can be exported to HTML and viewed as a Web document. Canvas allows students to upload assignments in HTML format, so it's easy to manage, review, and grade submissions. Homework assignments are available to other instructors on request.

Final projects

At the end of the quarter, students are assigned to groups of five. Each group is given a variation of an RBC model and a set of instructions about what they are to do with the model. For example, one group might be assigned an RBC model with capital adjustment costs and another an RBC model with stochastic government consumption. In all cases, the groups have to derive a new set of equilibrium conditions. In some cases, they are asked to download data from FRED to calibrate parameters that are novel to their respective models. In other cases, they are asked to compute several counterfactual impulse response simulations with different values of a key parameter. In all cases, the groups produce a 10- to 15-minute presentation of their results to be delivered during the last week of class. Groups submit their presentation slides and Jupyter Notebooks with code used to generate results. Final project assignment instructions are available to other instructors on request.

In the final project, students bring together many of the skills that they learn during the quarter and apply them to produce something meaningful. The purpose of the presentation component is to help students see programming as a means to an end. They use Python to simulate their respective models and to produce visualizations that they include in their presentations. A lot of students seem to have anxiety about the final project because they are generally averse to giving presentations and, understandably, they are not confident working with RBC models. But in my experience, students rise to the challenge and produce high-quality final project assignments and presentations.

Course topics

Table 1 contains a list of the topics covered in each lecture. The 10-week course is roughly divided into three 3-week blocks of instruction and a final week of group project presentations. In the first 3-week block, students learn the basics of Python programming. In the second, they learn how to simulate dynamic models. In the third, they analyze business cycle data and simulate business cycle models.

Table 1. Outline of topics. List of topics covered in each lecture.

<table><thead><tr><td>Class #</td><td>Topic(s)</td></tr></thead><tbody valign="top"><tr><td char=".">1</td><td>Introduction to course and the Jupyter Notebook. Short coding examples.</td></tr><tr><td char=".">2</td><td>Python basics. Built-in functions, error messages, built-in object types, math.</td></tr><tr><td char=".">3</td><td>NumPy module. Math, arrays, and random number generation.</td></tr><tr><td char=".">4</td><td>Plotting with the Matplotlib module.</td></tr><tr><td char=".">5</td><td>Data management with the pandas module.</td></tr><tr><td char=".">6</td><td>Statistics with statsmodels module.</td></tr><tr><td char=".">7</td><td>Simulate linear first-order and linear higher-order difference equations.</td></tr><tr><td char=".">8</td><td>Simulate nonlinear first-order difference equations and systems of difference equations. Solow growth model.</td></tr><tr><td char=".">9</td><td>Introduction to business cycle data.</td></tr><tr><td char=".">10</td><td>White noise and AR(1) processes.</td></tr><tr><td char=".">11</td><td>Introduction to dynamic optimization: A two-period cake-eating problem.</td></tr><tr><td char=".">12</td><td>The linearsolve module.</td></tr><tr><td char=".">13</td><td>Introduction to real business cycle modeling.</td></tr><tr><td char=".">14</td><td>Prescott's (<xref ref-type="bibr" rid="bibr25">1986</xref>) Real Business Cycle Model: Impulse responses.</td></tr><tr><td char=".">15</td><td>Prescott's (<xref ref-type="bibr" rid="bibr25">1986</xref>) Real Business Cycle Model II: Stochastic simulation.</td></tr><tr><td char=".">16</td><td>Introduction to New Keynesian Business Cycle Modeling.</td></tr><tr><td char=".">17</td><td>New Keynesian Business Cycle Modeling: Impulse responses.</td></tr><tr><td char=".">18</td><td>New Keynesian Business Cycle Modeling: Stochastic simulation.</td></tr><tr><td char=".">19</td><td>Group project presentations.</td></tr><tr><td char=".">20</td><td>Group project presentations.</td></tr></tbody></table>

Block 1: Python basics

The first 3-week block is dedicated to building basic Python proficiency and introducing specific programming techniques and Python functionality that students will use in the remainder of the course. Emphasis is on practicality. Through a combination of in-class examples and guided homework questions, students learn by example. Where possible, students are given explanations for why tasks in Python are done a certain way or what is happening behind the scenes when they execute their code. But the primary goal is to give them a collection of examples that they can rely on and modify later to fit their needs in the course.

In the first four classes, students learn the basics of the Jupyter Notebook environment and learn about Python variable types, built-in functions, how to interpret error messages, how to work with NumPy arrays, and how to make simple graphs with Matplotlib. Students are assigned the chapter "Introduction to Programming" from Stachurski's ([28]) book to be read the first week because it is an excellent, concise introduction to programming in general and Python in particular. Students are also directed to books available electronically from the campus library for additional resources.

In the third week, students are introduced to pandas and statmodels. pandas is a powerful tool for managing data, and statsmodels provides statistics functionality. In Class 5, students work with cross-country money growth and inflation data for over 170 countries. They use pandas to import the data, sort the data, and compute and interpret summary statistics. Then, they replicate an updated version of Chart 1 from McCandless and Weber ([22]).

In Class 6, statsmodels is introduced. In this class, students work with data from the Penn World Tables. As class motivation, students are presented with figure 4 from Jones and Romer ([15]), depicting the positive and striking correlation between GDP per capita and total factor productivity (TFP) across countries. Students are given data on GDP per capita, human capital per capita, and physical capital per capita for a large sample of countries. They use the data to compute TFP for each country. Then, they use statsmodels to estimate a linear regression model of log TFP on log GDP. The results are discussed in class.

Graph: Figure 4. The linearsolve Python module. Example of how to approximate, solve, and simulate an RBC model with linearsolve.

Block 2: Introduction to dynamic modeling

In the second 3-week block, the class begins developing theoretical tools for model simulation. Topics include simulating linear difference equations (Class 7) and simulating nonlinear difference equations (Class 8). The Solow model is used as an application here because (1) students have already encountered it in their intermediate theory courses, and (2) it provides a nice introduction to RBC modeling.

In Class 9, students are taught how to measure business cycle fluctuations. Students are given a dataset with aggregate U.S. data on GDP, consumption, investment, and trends of each statistic, computed using an HP filter. Students use the data to compute the business cycle components of each quantity in the data, i.e., log deviations of each quantity from trend. They make plots of the computed series and compute and interpret summary statistics of the business cycle data, including standard deviations of each series and correlations. They learn that the goal is to develop a model to explain the patterns in the data.

Next, students learn about white noise and AR(1) processes in Class 10. Generating random numbers is easy with NumPy, and students simulate the processes. The students estimate an AR(1) model of the business cycle component of TFP for the United States. They find that an AR(1) model fits the data well and that the coefficient on lagged TFP is estimated to be around 0.7, so TFP fluctuations are evidently highly persistent.

In Class 11, students are introduced to dynamic optimization by studying a cake-eating problem.[10] First, they are presented with a two-period model and then shown how to solve for the optimal consumption plan. Students discuss the intuition with the instructor and are then asked to solve a three-period problem on their own.

Finally, in Class 12, students are introduced to linearsolve, a Python module for computing linear approximations to and simulations of DSGE models. I wrote linearsolve specifically for this course, and it is described in more detail in the "Linearsolve" section below. Applications in Class 12 include using linearsolve to simulate an AR(1) process and to compute a stochastic simulation of the Solow growth model. This concludes the tool-building part of the course.

Block 3: Business cycle modeling

Having worked with the cake-eating model in Class 11 and presenting an application of the problem in a discussion section, Class 13 begins the look at RBC modeling. Students are shown slides containing results from a simulated stochastic Solow growth model. In Class 9, they learned about the properties of business cycle data. In this class, students see that (1) the stochastic Solow model does a "reasonably" good job of explaining output and consumption fluctuations in the United States and that (2) the stochastic Solow model substantially under-predicts the volatility of investment. Also, students see that the Solow model predicts a perfect correlation of consumption and investment with output.

Next, students are presented with an RBC model of a centralized economy that is basically that of Brock and Mirman ([4]). They learn how to set up the problem and derive the household's first-order conditions. The important parts of this exercise are (1) writing the problem and understanding the economic decision, (2) deriving the first-order conditions, collecting all equilibrium conditions and verifying that the number of equations matches the number of endogenous variables, and (3) identifying which variables are endogenous and which are exogenous. Other instructors (e.g., Solis-Garcia [27]) want students to learn solution techniques like value function iteration, but in my experience, teaching solution techniques to undergraduates is costly. It takes too long to teach them competence and does not give them a generalizable skill. The Linearsolve Python module requires students to write Python code based on the equations of the RBC model and does the advanced and time-saving work of model approximation and solution.

The result of Class 13 is for students to generate on their computer screens a set of impulse response plots following a technology shock in the RBC model. With assistance from the instructor, students analyze the generated figure. Students are helped to relate the image to what they know about the tradeoff between consumption and saving. Because they have already practiced simulating AR(1) processes, they know the TFP part of the simulation's source. The rest of the impulse response plots are interpreted by appealing to the model's equilibrium conditions and intuition. First, students are asked to consider what happens to the endogenous variables in the period of the TFP shock. More TFP leads to more output, making more resources available for consumption and investment. Then, looking beyond the period of the shock, students are asked to consider questions that will help them understand the dynamics: Why does consumption continue to rise after period 5? Because the TFP shock causes the capital stock to grow. Why is output still above the steady state in period 25, but TFP has essentially returned to zero? Because the economy accumulated capital. This is one of the key pieces of intuition: the household in the RBC model uses capital accumulation to store the temporary benefits of a productivity increase.

In the discussion section following Class 14, students use linearsolve to generate a stochastic simulation of the RBC model without labor. They compute summary statistics and find that the RBC model without labor does a little better than the stochastic Solow model in that it generates a significantly higher variance of investment and a lower correlation of investment with GDP. However, the model still drastically under-predicts consumption and GDP volatility, and the predicted correlations of the endogenous variables could be improved.

In Classes 14 and 15, the class starts replicating the results of Prescott ([25]), including simulated data in his Figure 3 and the correlations in his Table 2. Prescott's model is basically what the class has already been working with, except it allows for an endogenous labor choice. Students will compute and interpret impulse responses from the model. In Class 15, the class examines how changing the autocorrelation of the TFP process changes the persistence of a shock to TFP and the shapes of the impulse responses of other variables, too. The goal is to emphasize one of the benefits of computational methods: it's easy to do counterfactual simulations to see how parameterizations affect results.

Class 15 concludes with a comparison of statistics computed from the simulated RBC model with statistics from U.S. business cycle data. Students see that, relative to the RBC model without labor, Prescott's RBC model produces GDP and investment volatility that is closer to what is observed in the data. Students are invited to be critical and to observe that there is still room for improvement. Predicted correlations of variables with GDP are still too low, and so is consumption volatility. But the model seems to do well, considering its relative simplicity.

In the discussion section following Class 15, the RBC section is wrapped up with a discussion of the arguments in Summers' ([29]) critique of Prescott's RBC modeling approach. Summers offers a nice, concise critique of the RBC approach by arguing that the chosen parameter values for Prescott's simulation are suspect ("big loose tent flapping in the wind," [p. 24]), that Prescott doesn't provide support for why one should believe that technology has fluctuated as substantially as Prescott suggests, that Prescott doesn't explain whether his model can predict price movements (e.g., wages or interest rates), and finally that Prescott's model completely disregards the substantial market failures that accompany business cycle downturns.

The primary reason for including Summers' article in the course is that it nicely bridges the RBC framework with the New Keynesian framework that the class takes up next. It's good for the students to get some sense of the evolution of thought in business cycle theory and that while the New Keynesian framework offers a different perspective from RBC models on the source of fluctuations and the role of monetary policy, there is continuity in that the approaches are based on micro-founded models with rational expectations. A secondary reason for including Summers' article is for its example as a piece of persuasive writing. The critiques are strong, the tone is confident, and the language is clear and colorful.

The final three class sessions are devoted to developing a New Keynesian business cycle model. The New Keynesian IS curve is motivated with a presentation of a simple intertemporal optimization model of saving in an endowment economy. The Euler equation in the model is the IS equation. Students see that the IS equation in the New Keynesian model is analogous to the Euler equation in the RBC models that they've already considered. Hopefully, they see that even though the class has moved beyond the RBC framework, they are not starting from scratch.

The model is closed with a New Keynesian Phillips curve (NKPC) and a Taylor-type (1993) monetary policy rule. The intuition behind the NKPC is discussed, but the equation is not derived from first principles in class. However, optional notes on the derivation of the NKPC are made available for interested students.

There are two reasons for including the New Keynesian model in the course. First, after discussing with the class some of the drawbacks of the RBC modeling approach, it's appropriate to present students with an alternative perspective that addresses at least some of Summers' comments to show students that doing so doesn't require throwing out everything from the RBC modeling approach. Second, many popular intermediate macroeconomics and money and banking textbooks include a version of the New Keynesian-flavored IS-MP-AD model.[11] This is a nice time to introduce a quantitative model that is related to what the students would have seen in intermediate macroeconomics or money and banking.[12]

As with the RBC simulation, the emphasis is on interpreting equilibrium conditions, constructing visualizations of impulse responses to shocks, and making visualizations of stochastic simulations, and this occupies Classes 17 and 18. To finalize instruction, Class 18 concludes with an observation that many contemporary business cycle models combine elements of RBC and New Keynesian models and therefore fall under what Goodfriend and King ([11]) call the New Neoclassical Synthesis (NNS). Students are presented with the equilibrium conditions in an NNS model that combines Prescott's RBC model with a New Keynesian Phillips curve (NKPC) arising from monopolistically competitive firms facing sticky prices. Students are given the code to simulate the model and are led through an analysis of the impulse responses generated by the model. The point is to demonstrate a larger-scale model that integrates the appealing features of the two models that they learned during the quarter and to give them a sense of how macroeconomic models evolve.

Tradeoffs

The hardest choices to make in designing this course were in how to structure the beginning of the course. The first 3-week block is dedicated to basic topics in Python programming. There is a tradeoff between time spent developing a student's foundation in Python and time in pursuit of topics in economics. There is also a tradeoff between teaching to students who have no coding experience and those who are intermediate or advanced Python users. Topics that aren't necessary for later course content are ruthlessly excluded, including, regrettably, some basic elements of Python programming.[13] Novices in the class are strongly encouraged to do themselves a favor and review at least one of the introductory Python books on the course syllabus and work through the examples.

Tradeoffs in course design persist beyond the first 3-week block. However, the decision early on to lead students toward a certain proficiency in business cycle modeling implied the rough path of topics that would need to be covered. There would not be time to pursue other macroeconomic models, like endogenous growth models or search-and-matching models of unemployment, or to cover empirical applications like forecasting or VAR estimation. Any of these alternative topics would be interesting to students and could provide great value.

Finally, in deciding how to teach RBC and New Keynesian modeling, choices were made about how to present the modeling problems and how to describe the problem that the linearsolve routine solves. For example, the formulation of the RBC model is deliberately chosen so that it can be expressed as an unconstrained optimization problem, and the transversality condition is sidestepped entirely. When describing what linearsolve does, the class is directed to the Euler equation and shown how it implies that consumption at date

Graph

<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mi>t</mi></math> depends on expected consumption at date

Graph

<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mi>t</mi><mo>+</mo><mn>1</mn></math> , which depends on expected consumption at date

Graph

<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mi>t</mi><mo>+</mo><mn>2</mn></math> , and so on, and that solving this problem is not computationally trivial. Time spent on the details of solving linear rational expectations models would build neither economic intuition nor a particularly practical skill for most students, so the topic is bypassed.

Alternative topic ideas

The course content reflects my interests and the time constraints of the quarter system. Here are some thoughts on what topics could be added to extend the course to the additional five weeks of a semester. First, it would be nice to include an endogenous growth model for the class to simulate. Jones ([14]) presents a computable endogenous growth model in his intermediate textbook. Second, in the RBC section of the course, more time could be spent on some extensions to the RBC model, including things like capital adjustment costs or shocks to government purchases. As it is, these topics are included only among final project topics, but it would be better to have class time to teach and discuss them. Third, in the New Keynesian section of the course, some additional time would allow for a review of the evidence for the NKPC and monetary policy rules. It would be nice to cover Taylor's ([30]) paper and to give students an exercise to replicate and update his figure 1. Fourth, covering optimal discretionary monetary policy as described in Clarida, Galí, and Gertler ([8]) would be a nice application of the New Keynesian model.

Of course, some instructors may prefer to go more in-depth on any of the topics that have been proposed so far, and others may wish to include entirely different topics and methods. For example, as mentioned, Solis-Garcia teaches value function iteration in his course at Macalester College. Another opportunity is the Diamond-Mortensen-Pissarides (DMP) model of unemployment. Bhattacharya, Jackson, and Jenkins ([2]) describe how to teach the DMP model to undergraduates. They provide a model that can be computed as easily as the Solow model and data that can be used in empirical exercises on the Web site for their paper.[14] Additionally, the course could be modified to include forecasting and VAR methods, both of which could be taught with the statsmodels Python module.

Finally, in some cases, it may be worthwhile to require a programming prerequisite. At UCI, enrollment constraints in even introductory computer science courses make it infeasible to require that students take a programming course in advance. But at schools where it's an option, adding the prerequisite would free up time on the course schedule.

Linearsolve

Solving dynamic stochastic macroeconomic models requires computational techniques that are too advanced for undergraduates, and so I have written a Python module called linearsolve, available to any Python user via the Python Package Index, that computes log-linear approximations to DSGE models, computes the solutions to the approximated models using the Klein ([17]) solution algorithm, and produces customizable simulations.[15] Among a few other inputs, the user supplies a Python function that returns the equilibrium conditions solved for zero and with expectations operators and exogenous shocks dropped. Pedagogically, the program is useful because it requires that students properly enter equilibrium conditions as Python code so that they practice economics and Python at the same time. Furthermore, linearsolve returns simulated data so students still have to use the output of the program to produce graphs and statistics.

For an example of how to use linearsolve, consider the equilibrium conditions for a centralized RBC model with log utility and no labor supply:

Graph

<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mfrac><mrow><mn>1</mn></mrow><mrow><msub><mrow><mi mathvariant="normal">C</mi></mrow><mrow><mi mathvariant="normal">t</mi></mrow></msub></mrow></mfrac><mi mathvariant="normal" /><mo>=</mo><mi mathvariant="normal" /><mi mathvariant="normal">&#946;</mi><msub><mrow><mi mathvariant="normal">E</mi></mrow><mrow><mi mathvariant="normal">t</mi></mrow></msub><mo stretchy="true">[</mo><mrow><mfrac><mrow><mi mathvariant="normal">&#945;</mi><msub><mrow><mi mathvariant="normal">A</mi></mrow><mrow><mi mathvariant="normal">t</mi><mo>+</mo><mn>1</mn></mrow></msub><mi mathvariant="normal" /><msubsup><mrow><mi mathvariant="normal">K</mi></mrow><mrow><mi mathvariant="normal">t</mi><mo>+</mo><mn>1</mn></mrow><mrow><mi mathvariant="normal">&#945;</mi><mo>&#8722;</mo><mn>1</mn></mrow></msubsup><mi mathvariant="normal" /><mo>+</mo><mi mathvariant="normal" /><mn>1</mn><mi mathvariant="normal" /><mo>&#8722;</mo><mi mathvariant="normal" /><mi mathvariant="normal">&#948;</mi></mrow><mrow><msub><mrow><mi mathvariant="normal">C</mi></mrow><mrow><mi mathvariant="normal">t</mi><mo>+</mo><mn>1</mn></mrow></msub></mrow></mfrac></mrow><mo stretchy="true">]</mo></math> (1)

Graph

<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><msub><mrow><mi>C</mi></mrow><mrow><mi>t</mi></mrow></msub><mo>+</mo><msub><mrow><mi>K</mi></mrow><mrow><mi>t</mi><mo>+</mo><mn>1</mn></mrow></msub><mo>=</mo><msub><mrow><mi>A</mi></mrow><mrow><mi>t</mi></mrow></msub><msubsup><mrow><mi>K</mi></mrow><mrow><mi>t</mi></mrow><mrow><mi mathvariant="normal">&#945;</mi></mrow></msubsup><mo>+</mo><mo stretchy="true">(</mo><mrow><mn>1</mn><mo>&#8722;</mo><mi mathvariant="normal">&#948;</mi></mrow><mo stretchy="true">)</mo><msub><mrow><mi>K</mi></mrow><mrow><mi>t</mi></mrow></msub></math> (2)

Graph

<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mrow><mi mathvariant="normal">log</mi></mrow><mo>&#8289;</mo><mrow><msub><mrow><mi>A</mi></mrow><mrow><mi>t</mi><mo>+</mo><mn>1</mn></mrow></msub></mrow></mrow><mo>=</mo><msub><mrow><mi>&#961;</mi></mrow><mrow><mi>A</mi></mrow></msub><mrow><mrow><mi mathvariant="normal">log</mi></mrow><mo>&#8289;</mo><mrow><msub><mrow><mi>A</mi></mrow><mrow><mi>t</mi></mrow></msub></mrow></mrow><mo>+</mo><msub><mrow><mi>&#1013;</mi></mrow><mrow><mi>t</mi><mo>+</mo><mn>1</mn></mrow></msub><mo>.</mo></math> (3)

Here,

Graph

<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><msub><mrow><mi>C</mi></mrow><mrow><mi>t</mi></mrow></msub></math> is consumption,

Graph

<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><msub><mrow><mi>K</mi></mrow><mrow><mi>t</mi></mrow></msub></math> is capital,

Graph

<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><msub><mrow><mi>A</mi></mrow><mrow><mi>t</mi></mrow></msub></math> is total factor productivity (TFP), and

Graph

<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><msub><mrow><mi>&#1013;</mi></mrow><mrow><mi>t</mi><mo>+</mo><mn>1</mn></mrow></msub></math> is an exogenous shock to period

Graph

<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mi>t</mi><mo>+</mo><mn>1</mn></math> TFP. Equation (1) is the Euler equation for the representative household, Eq. (2) is the resource constraint for the economy, and Eq. (3) is the law of motion for TFP. A solution to the system of Eqs. (1)–(3) expresses

Graph

<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><msub><mrow><mi>C</mi></mrow><mrow><mi>t</mi></mrow></msub></math> ,

Graph

<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><msub><mrow><mi>K</mi></mrow><mrow><mi>t</mi><mo>+</mo><mn>1</mn></mrow></msub></math> , and

Graph

<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><msub><mrow><mi>A</mi></mrow><mrow><mi>t</mi><mo>+</mo><mn>1</mn></mrow></msub></math> as functions of

Graph

<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><msub><mrow><mi>K</mi></mrow><mrow><mi>t</mi></mrow></msub></math> ,

Graph

<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><msub><mrow><mi>A</mi></mrow><mrow><mi>t</mi></mrow></msub></math> and the exogenous shock

Graph

<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><msub><mrow><mi>&#1013;</mi></mrow><mrow><mi>t</mi><mo>+</mo><mn>1</mn></mrow></msub></math> . For a positive depreciation rate, i.e.,

Graph

<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mi mathvariant="normal">&#948;</mi><mo>&#62;</mo><mn>0</mn></math> , the system has no closed-form solution for

Graph

<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><msub><mrow><mi>C</mi></mrow><mrow><mi>t</mi></mrow></msub></math> ,

Graph

<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><msub><mrow><mi>K</mi></mrow><mrow><mi>t</mi><mo>+</mo><mn>1</mn></mrow></msub></math> , and

Graph

<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><msub><mrow><mi>A</mi></mrow><mrow><mi>t</mi><mo>+</mo><mn>1</mn></mrow></msub></math> .

Figure 4 depicts how to use linearsolve to compute impulse responses to the TFP shock in the example model. After importing necessary libraries, parameter values are inputted and stored in a variable called parameters. Then the function equilibrium_equations() is defined by the user to return the equilibrium conditions solved for zero. Next, the variable model is initialized to store all relevant elements of the model, including the parameter values, the equilibrium conditions, and the number of state variables. The function model.ss() computes the nonstochastic steady state of the model and the function model.approximate_and_solve() -computes the log-linear approximation, and then the solution to the log-linear system. Finally, the function model.impulse() computes a custom impulse response simulation.

The example illustrates an advantage of using Python with linearsolve over Matlab with Dynare. Dynare has its own distinct syntax for.mod files, so using Dynare requires coding in both Dynare and Matlab. But as the example shows, a DSGE model can be simulated with linearsolve using Python code exclusively so students can spend more time deriving first-order conditions and interpreting simulation results.

For more examples of how to use linearsolve, please see the documentation:

https://www.briancjenkins.com/linearsolve/docs/build/html/index.html

How to get started with Python

Instructors with no Python experience who would like to learn have a lot of options. The abundance of online and print resources may be overwhelming, and so here are suggestions for how to get started. These suggestions mirror the advice that I give to my students.

First, install Python by downloading and installing Anaconda.[16] After installation, open the Anaconda Navigator application and use it to open the Jupyter Notebook. The Jupyter Notebook will open in the default Web browser. Use the Jupyter Notebook window to navigate through the computer's directories to a suitable place to start a new coding project. Next, click "New" in the top right of the window and select "Python 3" from the drop-down menu. A new tab will open with Python running in the browser, ready to execute Python code. Press "Shift-Enter" to execute a code cell in the Jupyter Notebook. Learn more about the Jupyter Notebook interface from the "Help" menu in the Notebook or by consulting the Jupyter Notebook documentation.[17]

Now start writing and running code. Good beginner resources for Python programming include Hall and Stacy ([12]) and Cannon ([6]) and the chapter "Introduction to Programming" from Stachurski's ([28]) book. Hilpisch ([13]) is aimed at readers with at least some programming experience but has excellent practical examples of Python basics and applications of numerical and statistical methods to finance. For more examples specific to economics, check out the resources at QuantEcon, particularly the lectures "Python Programming for Economics and Finance," "Quantitative Economics with Python," and "Advanced Quantitative Economics with Python."<sups>18</sups> Also, working through the first six lectures of the course described in this article will provide examples in Python basics, NumPy arrays and functions for numerical analysis, pandas for data management, and Matplotlib for plotting.

Conclusion

Designing and teaching Computational Macroeconomics has been a wonderful experience. The content is valuable and has been well-received by students. Indeed, one student who took the course in winter 2019 described the course as a "game-changer" in an interview with an online campus publication (Byrd [5]). The student's sentiment was echoed by others in the (nonconfidential) post-quarter survey. Enthusiasm for the course suggests that students would welcome more deliberate and unified inclusion of computational methods included in other courses. While computational methods are not, strictly speaking, economics, they are nonetheless important to economics. To the extent that many economists are practitioners, they can provide great value to their students at low cost by giving them skills that will transfer to other disciplines and activities while also enhancing their economics education.

Acknowledgments

The author thanks Douglas Dalenberg, Michael Darden, John Duffy, Rey Hernández-Julián, and two anonymous referees for thoughtful comments and former students Viola Chen, Andrew Miller, Svati Proctor, and William Proctor for working through early versions of the course content.

Footnotes

1 Judd (1997) provides an excellent argument for the value of computational methods in economics by drawing comparisons with applications in the physical sciences. The following books are excellent references on solving, simulating, and estimating macroeconomic models: Canova (2007), Stachurski (2009), DeJong and Dave (2012), McCandless (2008), and Ljungqvist and Sargent (2018).

2 For undergraduate programs that do not have a calculus prerequisite for intermediate economics, the course content requiring calculus could be replaced with alternative topics. Possible alternatives are suggested at the end of the "Alternative Topic Ideas" section.

3 "The Macro Pedagogy Debate: Teaching DSGE to Undergraduates Symposium," JEE, Issue 3, 2018. Articles in the symposium include: Colander (2018), Solis-Garcia ([27]), Setterfield ([26]), and Neumuller, Rothschild, and Weerapana ([24]).

4 See, for example, the economics-oriented Python resources and examples at QuantEcon: https://quantecon.org/.

5 Dynare is a popular and widely used software for simulating DSGE models that runs on top of Matlab or Octave. Some readers will wonder why the course wasn't structured to use Dynare. One reason is my preference for Python over Matlab. Another reason is that Dynare uses a Dynare-specific syntax. Dynare is convenient because the user enters equilibrium conditions in a symbolic format and then Dynare parses the equations. But because the user isn't programming in the fundamental language (e.g., Matlab), they also aren't practicing the fundamental language. For pedagogical reasons, I would prefer to have the course based entirely on one language and so would not use Dynare in the course even if Matlab were used.

6 Anaconda download link: https://www.anaconda.com/products/individual.

7 https://hr.nih.gov/working-nih/competencies/competencies-proficiency-scale.

8 File name is make_blank_notebooks.py; available on the course GitHub page.

9 See the second chapter of Adda and Cooper ([1]) for a formal treatment of the cake-eating problem and extensions.

Examples include Mishkin ([23]), Mankiw ([20]), and Jones ([14]).

Mankiw's intermediate macroeconomics textbook has a nice quantitative model that students can simulate with spreadsheet software. To make the model tractable, he assumes a static IS relationship between the real rate and output, and that agents have adaptive expectations.

For example, not all of the built-in Python types, including tuples, ranges, and dictionaries are covered, and only a limited introduction to lists is provided.

https://www.briancjenkins.com/dmp-model/.

Chapter 3 of DeJong and Dave ([10]) discusses how to construct a log-linearization of a DSGE model, and Chapter 4 discusses solution techniques including Klein's.

See note 7.

https://jupyter-notebook.readthedocs.io/en/stable/notebook.html.

See note 5.

This article has been republished with minor changes. These changes do not impact the academic content of the article.

References

Adda, J., and R. W. Cooper. 2003. Dynamic economics. Cambridge, MA : MIT Press.

Bhattacharya, A., P. Jackson, and B. C. Jenkins. 2018. Revisiting unemployment in intermediate macroeconomics: A new approach for teaching Diamond-Mortensen-Pissarides. Journal of Economic Education 49 (1): 22 – 37. doi: 10.1080/00220485.2017.1397574.

Blumenstyk, G. 2016. Liberal-arts majors have plenty of job prospects, if they have some specific skills, too. The Chronicle of Higher Education, June 9. https://www.chronicle.com/article/liberal-arts-majors-have-plenty-of-job-prospects-if-they-have-some-specific-skills-too/. (accessed September 16, 2020).

Brock, W. A., and L. J. Mirman. 1972. Optimal economic growth and uncertainty: The discounted case. Journal of Economic Theory 4 (3): 479 – 513. doi: 10.1016/0022-0531(72)90135-4.

Byrd, C. 2019. Pantsuit generation. Irvine, CA: University of California, Irvine, School of Social Sciences. https://www.socsci.uci.edu/newsevents/news/2019/2019-05-28-pantsuit-gen.php. Accessed September 16, 2020.

Cannon, J. 2020. Python programming for beginners. London, KY : J. Frank Publishing.

Canova, F. 2007. Methods for applied macroeconomic research. Princeton, NJ : Princeton University Press.

Clarida, R., J. Galí, and M. Gertler. 1999. The science of monetary policy: A New Keynesian perspective. Journal of Economic Literature 37 (4): 1661 – 707. doi: 10.1257/jel.37.4.1661.

Colander, D. 2018. Teaching DSGE to undergraduates symposium: Introduction. Journal of Economic Education 49 (3): 224 – 25. doi: 10.1080/00220485.2018.1464989.

DeJong, D. N., and C. Dave. 2012. Structural macroeconometrics. 2nd ed. Princeton, NJ : Princeton University Press.

Goodfriend, M., and R. King. 1997. The New Neoclassical Synthesis and the role of monetary policy. In NBER macroeconomics annual, ed. B. S. Bernanke and J. Rotemberg, Vol. 12, 231 – 83. Cambridge, MA : MIT Press. doi: 10.1086/654336.

Hall, T., and J.-P. Stacy. 2009. Python 3 for absolute beginners. New York : Apress.

Hilpisch, Y. 2019. Python for finance. 2nd ed. Sebastopol, CA : O'Reilly Media, Inc.

Jones, C. I. 2020. Macroeconomics. 5th ed. New York : W.W. Norton & Company.

Jones, C. I., and P. M. Romer. 2010. The new Kaldor facts: Ideas, institutions, population, and human capital. American Economic Journal: Macroeconomics 2 (1): 224 – 45. doi: 10.1257/mac.2.1.224.

Judd, K. L. 1997. Computational economics and economic theory: Substitutes or complements? Journal of Economic Dynamics and Control 21 (6): 907 – 42. doi: 10.1016/S0165-1889(97)00010-9.

Klein, P. 2000. Using the generalized Schur form to solve a multivariate linear rational expectations model. Journal of Economic Dynamics and Control 24 (10): 1405 – 23. doi: 10.1016/S0165-1889(99)00045-7.

Ljungqvist, L., and T. J. Sargent. 2018. Recursive macroeconomic theory. 4th ed. Cambridge, MA : MIT Press.

Lucas, R. E. 1976. Econometric policy evaluation: A critique. Carnegie-Rochester Conference Series on Public Policy 1 : 19 – 46. doi: 10.1016/S0167-2231(76)80003-6.

Mankiw, N. G. 2019. Macroeconomics. 10th ed. New York : Worth Publishers.

McCandless, G. 2008. The ABCs of RBCs. Cambridge, MA : Harvard University Press.

McCandless, G. T., and W. E. Weber. 1995. Some monetary facts. Federal Reserve Bank of Minneapolis Quarterly Review, Summer, 2 – 11.

Mishkin, F. S. 2019. The economics of money, banking, and financial markets. 12th ed. New York : Pearson.

Neumuller, S., C. Rothschild, and A. Weerapana. 2018. Bridging the gap between undergraduate and graduate macroeconomics. Journal of Economic Education 49 (3): 242 – 51. doi: 10.1080/00220485.2018.1464990.

Prescott, E. C. 1986. Theory ahead of business cycle measurement. Federal Reserve Bank of Minneapolis Quarterly Review, Fall, 9 – 22.

Setterfield, M. 2018. Maybe you can, but perhaps you shouldn't! Saving undergraduate macroeconomics from DSGE modeling. Journal of Economic Education 49 (3): 237 – 41. doi: 10.1080/00220485.2018.1464991.

Solis-Garcia, M. 2018. Yes we can! Teaching DSGE models to undergraduate students. Journal of Economic Education 49 (3): 226 – 36. doi: 10.1080/00220485.2018.1464987.

Stachurski, J. 2009. Economic dynamics. Cambridge, MA : MIT Press.

Summers, L. H. 1986. Some skeptical observations on real business cycle theory. Federal Reserve Bank of Minneapolis Quarterly Review Fall, 23 – 27.

Taylor, J. B. 1993. Discretion versus policy rules in practice. Carnegie-Rochester Conference Series on Public Policy 39 : 195 – 214. doi: 10.1016/0167-2231(93)90009-L.

By Brian C. Jenkins

Reported by Author