# Homework 2

**Instructions:** Complete the notebook below. Download the completed notebook in HTML format. Upload assignment using Canvas.

**Due:** Jan. 19 at **2pm**.

## Exercise: NumPy Arrays

Follow the instructions in the following cells.


```python
# Import numpy
import numpy as np
```


```python
# Use the 'np.arange()' function to create a variable called 'numbers1' that stores the integers 
# 1 through (and including) 10
numbers1 = np.arange(1,11)

# Print the value of 'numbers1'
print(numbers1)
```

    [ 1  2  3  4  5  6  7  8  9 10]



```python
# Use the 'np.arange()' function to create a variable called 'numbers2' that stores the numbers 
# 0 through (and including) 1 with a step increment of 0.01
step =0.01
numbers2 = np.arange(0,1+step,step)

# Print the value of 'numbers2'
print(numbers2)
```

    [0.   0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 0.1  0.11 0.12 0.13
     0.14 0.15 0.16 0.17 0.18 0.19 0.2  0.21 0.22 0.23 0.24 0.25 0.26 0.27
     0.28 0.29 0.3  0.31 0.32 0.33 0.34 0.35 0.36 0.37 0.38 0.39 0.4  0.41
     0.42 0.43 0.44 0.45 0.46 0.47 0.48 0.49 0.5  0.51 0.52 0.53 0.54 0.55
     0.56 0.57 0.58 0.59 0.6  0.61 0.62 0.63 0.64 0.65 0.66 0.67 0.68 0.69
     0.7  0.71 0.72 0.73 0.74 0.75 0.76 0.77 0.78 0.79 0.8  0.81 0.82 0.83
     0.84 0.85 0.86 0.87 0.88 0.89 0.9  0.91 0.92 0.93 0.94 0.95 0.96 0.97
     0.98 0.99 1.  ]



```python
# Print the 5th value of 'numbers2'. (Remember that the index starts counting at 0)
print(numbers2[4])
```

    0.04



```python
# Print the last value of 'numbers2'.
print(numbers2[-1])
```

    1.0



```python
# Print the first 12 values of 'numbers2'.
print(numbers2[:12])
```

    [0.   0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 0.1  0.11]



```python
# Print the last 12 values of 'numbers2'.
print(numbers2[-12:])
```

    [0.89 0.9  0.91 0.92 0.93 0.94 0.95 0.96 0.97 0.98 0.99 1.  ]



```python
# Use the 'np.zeros()' function to create a variable called 'zeros' that is an array of 20 zeros
zeros = np.zeros(20)

# Print the value of 'zeros'
print(zeros)
```

    [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]



```python
# Change the second value of 'zeros' to 1 and print 
zeros[1] = 1

# Print the value of 'zeros'
print(zeros)
```

    [0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]


## Exercise: Random Numbers

Follow the instructions in the following cells.


```python
# Set the seed of NumPy's random number generator to 126
np.random.seed(126)

# Create a variable called 'epsilon' that is an array containing 25 draws from
# a normal distribution with mean 4 and standard deviation 2
epsilon = np.random.normal(loc=4,scale=2,size=25)

# Print the value of epsilon
print(epsilon)
```

    [ 2.67538919  6.80573472  2.82000233  4.20989426  4.16082178 -1.647651
      5.03812875  5.01159741  4.39492279  3.85680303  6.91478091  0.0854267
      7.02367775  3.94735082  2.48401748  7.02291824  6.25058482  5.57263063
      1.67321674  4.54716569  6.58060317  5.30662456  1.16478298  3.95415024
      3.56110405]



```python
# Print the mean of 'epsilon'
print(np.mean(epsilon))
```

    4.136587121846035



```python
# Print the standard deviation of 'epsilon'
print(np.std(epsilon))
```

    2.182193135563433


## Exercise: The Cobb-Douglas Production Function

The Cobb-Douglas production function can be written in per worker terms as :
  \begin{align}
  y & = A k^{\alpha},
  \end{align}
where $y$ denotes output per worker, $k$ denotes capital per worker, and $A$ denotes total factor productivity or technology.

### Part (a)

On a single axis: plot the Cobb-Douglas production for $A$ = 0.8, 1, 1.2, and 1.4 with $\alpha$ = 0.35 and $k$ ranging from 0 to 10. Each line should have a different color. Your plot must have a title and axis labels. The plot should also contain a legend that clearly indicates which line is associated with which value of $A$ and does not cover the plotted lines.


```python
# Import the pyplot module from Matplotlib as plt
import matplotlib.pyplot as plt

# Select the Matlplotlib style sheet to use (Optional)
plt.style.use('classic')

# Use the '%matplotlib inline' magic command to ensure that Matplotlib plots are displayed in the Notebook
%matplotlib inline
```


```python
# Set capital share (alpha)
alpha = 0.35

# Create an array of capital values
k = np.arange(0,10,0.001)

# Plot production function for each of the given values for A

def cobbDouglas(A,k,alpha):
    '''Returns the value of the production function A*k**alpha
    
    Args:
        A (float):          TFP or productivity value
        k (NumPy ndarray):  Array of capital values
        alpha (float):      Capital share in production
     
     Returns:
         NumPy series
     '''
    return A*k**alpha


for A in [0.8,1,1.2,1.4]:
    plt.plot(k,cobbDouglas(A,k,alpha),lw=3,alpha = 0.65,label='$A='+str(A)+'$')

# Add x- and y-axis labels
plt.xlabel('capital')
plt.ylabel('output')
# Add a title to the plot
plt.title('Cobb-Douglas production function')
# Create a legend
plt.legend(loc='lower right')
# Add a grid
plt.grid(True)
```

**Question**

1. *Briefly* explain in words how increasing $A$ affects the shape of the production function.

**Answer**

1. Increasing $A$ increases the height of the the production function at every value of capital except for 0 so increasing $A$ increases the steepness of the production function. <!-- answer -->

### Part (b)

On a single axis: plot the Cobb-Douglas production for $\alpha$ = 0.1, 0.2, 0.3, 0.4, and 0.5 with $A$ = 1 and $k$ ranging from 0 to 10. Each line should have a different color. Your plot must have a title and axis labels. The plot should also contain a legend that clearly indicates which line is associated with which value of $\alpha$ and does not cover the plotted lines.


```python
# Set TFP (A)
A = 1

# Plot production function for each of the given values for alpha
for alpha in [0.1,0.2,0.3,0.4,0.5]:
    plt.plot(k,cobbDouglas(A,k,alpha),lw=3,alpha = 0.65,label='$\\alpha='+str(alpha)+'$')

# Add x- and y-axis labels
plt.xlabel('capital')
plt.ylabel('output')
# Add a title to the plot
plt.title('Cobb-Douglas production function')
# Create a legend
plt.legend(ncol=3,loc='lower right')
# Add a grid
plt.grid(True)
```

**Question**

1. *Briefly* explain in words how increasing $\alpha$ affects the shape of the production function.

**Answer**

1. Increasing $\alpha$ reduces the curvature of the production function for capital between 0 and 1 and increases the steepness of the production function for capital greater than 1. <!-- answer -->

### Exercise: The Cardioid

The cardioid is a shape described by the parametric equations:

  \begin{align}
  x & = a(2\cos \theta - \cos 2\theta), \\
  y & = a(2\sin \theta - \sin 2\theta).
  \end{align}
  
Construct a well-labeled graph of the cardiod for $a=4$ and $\theta$ in $[0,2\pi]$. Your plot must have a title and axis labels.


```python
# Construct data for x and y
a = 4
theta = np.arange(0,2*np.pi,0.001)
x = a*(2*np.cos(theta) - np.cos(2*theta))
y = a*(2*np.sin(theta) - np.sin(2*theta))

# Plot y against x
plt.plot(x,y,lw=3,alpha=0.65)

# Create x-axis label
plt.xlabel('x')

# Create y-axis label
plt.ylabel('y')

# Create title for plot
plt.title('Cardioid')

# Add a grid to the plot
plt.grid()
```

## Exercise: Unconstrained optimization

Consider the quadratic function:
    
\begin{align}
f(x) & = -7x^2 + 930x + 30
\end{align}
    
You will use analytic (i.e., pencil and paper) and numerical methods to find the the value of $x$ that maximizes $f(x)$. Another name for $x$ that maximizes $f(x)$ is the *argument of the maximum* value $f(x)$.

### Part (a): Analytic solution

Use standard calculus methods to solve for the value of $x$ that maximizes $f(x)$ to **five decimal places**. Use your answer to complete the sentence in the next cell.

 The value of $x$ that maximizes $f(x)$ is: 

### Part (b):  Numerical solution

In the cells below, you will use NumPy to try to compute the argument of the maximum of $f(x)$.


```python
# Use np.arange to create a variable called 'x' that is equal to the numbers 0 through 100 
# with a spacing between numbers of 0.1
x = np.arange(0,100,0.1)

# Create a variable called 'f' that equals f(x) at each value of the array 'x' just defined
f = -7*x**2 + 930*x + 30

# Use np.argmax to create a variable called xstar equal to the value of 'x' that maximizes the function f(x).
xstar = x[np.argmax(f)]

# Print the value of xstar
print(xstar)
```

    66.4



```python
# Use np.arange to create a variable called 'x' that is equal to the numbers 0 through 100 
# with a spacing between numbers of 0.001
x = np.arange(0,100,0.001)

# Create a variable called 'f' that equals f(x) at each value of the array 'x' just defined
f = -7*x**2 + 930*x + 30

# Use np.argmax to create a variable called xstar equal to the value of 'x' that maximizes the function f(x).
xstar = x[np.argmax(f)]

# Print the value of xstar
print(xstar)
```

    66.429



```python
# Use np.arange to create a variable called 'x' that is equal to the numbers 0 through *50*
# with a spacing between numbers of 0.001
x = np.arange(0,50,0.001)

# Create a variable called 'f' that equals f(x) at each value of the array 'x' just defined
f = -7*x**2 + 930*x + 30

# Use np.argmax to create a variable called xstar equal to the value of 'x' that maximizes the function f(x).
xstar = x[np.argmax(f)]

# Print the value of xstar
print(xstar)
```

    49.999


### Part (c): Evaluation

Provide answers to the follow questions in the next cell.

**Questions**

1. How did the choice of step size in the array `x` affect the accuracy of the computed results in the first two cells of Part (b)?

2. What do you think is the drawback to decreasing the stepsize in `x`?

3. In the previous cell, why did NumPy return value for `xstar` that is so different from the solution you derived in Part (a)?

**Answers**

1. Choosing a smaller step size creates a finer grid of points for which the function $f$ is calculated and therefore the accuracy is improved with a smaller step size. <!-- answer -->
2. A smaller step size means that the variable `x` will have more elements and so storing the variable and using it in computations will use more memory and will slow and/or crash the program. <!-- answer -->
3. The range of values in the variable `x` doesn't include $x^*$. <!-- answer -->

## Exercise: Utility Maximization

Recall the two good utility maximization problem from microeconomics. Let $x$ and $y$ denote the amount of two goods that a person consumes. The person receives utility from consumption given by:
  \begin{align}
  u(x,y) & = x^{\alpha}y^{\beta} 
  \end{align}
The person has income $M$ to spend on the two goods and the price of the goods are $p_x$ and $p_y$. The consumer's budget constraint is:
  \begin{align}
  M & = p_x x + p_y y
  \end{align}
Suppose that $M = 100$, $\alpha=0.25$, $\beta=0.75$, $p_x = 1$. and $p_y = 0.5$. The consumer's problem is to maximize their utility subject to the budget constraint. While this problem can easily be solved by hand, we're going to use a computational approach. You can also solve the problem by hand to verify your solution.

### Part (a)

Use the budget constraint to solve for $y$ in terms of $x$, $p_x$, $p_y$, and $M$. Use the result to write the consumer's utility as a function of $x$ only. Create a variable called `x` equal to an array of values from 0 to 80 with step size equal to 0.001 and a variable called `utility` equal to the consumer's utility. Plot the consumer's utility against $x$.


```python
# Assign values to the constants alpha, beta, M, px, py
alpha = 0.25
beta = 0.75
M = 100
px=1
py=0.5

# Create an array of x values
x = np.arange(0,80,0.001)

# Create an array of utility values
utility = x**alpha*((M-px*x)/py)**beta

# Plot utility against x.
plt.plot(x,utility,lw=3,alpha=0.65)

# x- and y-axis labels
plt.xlabel('x')
plt.ylabel('utility')

# Title
plt.title('u[x,y(x)]')

# Add grid
plt.grid()
```

### Part (b)

The NumPy function `np.max()` returns the highest value in an array and `np.argmax()` returns the index of the highest value. Print the highest value and index of the highest value of `utility`.


```python
print('highest utility value         :',np.max(utility))
print('index of highest utility value:',np.argmax(utility))
```

    highest utility value         : 95.84146563694088
    index of highest utility value: 25000


### Part (c)

Use the index of the highest value of utility to find the value in `x` with the same index and store value in a new variable called `xstar`. Print the value of `xstar`.


```python
# Create variable 'xstar' equal to value in 'x' that maximizes utility
xstar = x[np.argmax(utility)]

# Print value of 'xstar'
print('xstar:',xstar)
```

    xstar: 25.0


### Part (d)

Use the budget constraint to the find the implied utility-maximizing vaue of $y$ and store this in a variable called `ystar`. Print `ystar`.


```python
# Create variable 'ystar' equal to value in 'y' that maximizes utility
ystar = M/py - px*xstar/py

# Print value of 'xstar'
print('ystar:',ystar)
```

    ystar: 150.0


da04479aefc505069818130fb24e376bd4d84149
ipynb
Jupyter Notebook
Homework Notebooks/Econ126_Winter2021_Homework_02.ipynb
letsgoexploring/econ126
05f50d2392dd1c7c38b14950cb8d7eff7ff775ee
MIT
2020-12-12T16:28:44.000Z
2021-02-24T12:11:04.000Z
Homework Notebooks/Econ126_Winter2021_Homework_02.ipynb
letsgoexploring/econ126
05f50d2392dd1c7c38b14950cb8d7eff7ff775ee
MIT
2019-04-29T08:50:41.000Z
2019-04-29T08:51:05.000Z
Homework Notebooks/Econ126_Winter2021_Homework_02.ipynb
letsgoexploring/econ126
05f50d2392dd1c7c38b14950cb8d7eff7ff775ee
MIT
2019-03-08T18:49:19.000Z
2022-03-07T23:27:16.000Z
Qwen/Qwen-72B
1. YES
2. YES