I am working on the file "Module_1d_linear_regression_gradient.ipynb".
The first task is:
Exercise
Plot with learning rate = 0.001, Epochs = 1000
Plot with learning rate = 0.005, Epochs = 10000
Plot with learning rate = 0.001, Epochs = 50000
Challenges with Simple Gradient Descent
Convexity
In our linear regression problem, there was only one minimum. Our error surface was convex. Regardless of where we started, we would eventually arrive at the absolute minimum. In general, this need not be the case. It’s possible to have a problem with local minima that a gradient search can get stuck in. There are several approaches to mitigate this (e.g., stochastic gradient search).
Performance
We used vanilla gradient descent with a learning rate of 0.001 in the above example, and ran it for 50000 iterations. There are approaches such a line search, that can reduce the number of iterations required and also avoid the overshooting problem with large learning rate.
Convergence
We didn’t talk about how to determine when the search finds a solution. This is typically done by looking for small changes in error iteration-to-iteration (e.g., where the gradient is near zero).
Line Search Gradient Descent
To avoid the problem of setting the learning rate and overshooting, we can adaptively choose the step size
$$ \beta_{i+1} = \beta_{i} - \eta * \nabla E(\beta)$$
First, fix a parameter $ 0 < \gamma < 1$, then start with $\eta = 1$, and while
$$ E(\beta_{i+1}) >  E(\beta) - \frac{\eta}{2} * {||\nabla E(\beta)||}^2 $$
then
$$ \eta = \gamma * \eta $$
Typically, we take $\gamma = [0.1, 0.8] $
Can you write Python code for it?

def gradient_descent_line (eta, epochs, X, y, n):

    gamma = 0.5

    # Set Initial Values
    b = np.asmatrix([[-250],[-50]])
    es = error_term(X,y,b,n)
    b0s, b1s, errors = [], [], []
    b0s.append(b.item(0))
    b1s.append(b.item(1))
    errors.append(es)

    # Run the calculation for those many epochs
    for i in range(epochs):
        es_old = error_term(X,y,b,n)
        g = gradient(X,y,b,n)
        b = b - eta * g
        es = error_term(X,y,b,n)
        #print(e,e_old)
        if es > es_old - eta/2*(g.T*g):
            eta = eta * gamma

        b0s.append(b.item(0))
        b1s.append(b.item(1))
        errors.append(es)

    print('error =', round(errors[-1]), ' b0 =', round(b0s[-1]), 'b1 =', round(b1s[-1]))

    return errors, b0s, b1s


I am working on the file "Module_1d_linear_regression_gradient.ipynb".
The first task is:
Exercise
Try with learning rate = 0.001, Epochs = 1000
Try with learning rate = 0.02, Epochs = 1000
Try with learning rate = 0.001, Epochs = 50000
Plotting Epochs and Learning Rate
Can you write Python code for it?

def plot_gradient_descent(eta, epoch, gradient_func):

    es, b0s, b1s = gradient_func(eta, epoch, X, y, n)

    # Plot the intercept and coefficients
    plt.figure(figsize=(15,6))
    plt.subplot(1, 2, 1)
    #plt.tight_layout()

    # Plot the contour
    cs = plt.contourf(bb0, bb1, Z, cmap=plt.cm.viridis, levels = levels,
                      linewidth=0.3, alpha = 0.5)

    # Plot the intercept and coefficients
    plt.plot(b0s, b1s, '-b', linewidth = 2)
    plt.xlim([-500,2000])
    plt.ylim([-100,100])
    plt.xlabel('Intercept')
    plt.ylabel('Slope')

    # Plot the error rates
    plt.subplot(1, 2, 2)
    plt.plot(np.log10(es))
    plt.ylim([3,10])
    plt.xlabel('Epochs')
    plt.ylabel('log(Error)')

plot_gradient_descent(0.0005, 15, gradient_descent)


I am working on the file "Module_1d_linear_regression_gradient.ipynb".
The first task is:
Let's plot the error term as a 2D plot - as a contour plot and make it more clear.
Can you write Python code for it?

# Get the errors
Z = np.asmatrix(errors).reshape(bb0.shape)

# Get the contour
e_min, e_max = np.min(errors), np.max(errors)
levels = np.logspace(0, np.log10(e_max), 40)

# Plot the contour
fig = plt.figure()
cs = plt.contourf(bb0, bb1, Z, cmap=plt.cm.viridis, levels = levels, linewidth=0.3, alpha = 0.5)
fig.colorbar(cs, shrink=0.5, aspect=5)

plt.xlabel('Intercept')
plt.ylabel('Slope')


I am working on the file "Module_1d_linear_regression_gradient.ipynb".
The first task is:
Lets see the error rate with different Learning Rate and Epochs
Can you write Python code for it?

errors, b0s, b1s = gradient_descent (0.001, 100, X, y, n)


I am working on the file "Module_1d_linear_regression_gradient.ipynb".
The first task is:
Shape of the error term
Lets plot the error term and see that the error surface is CONVEX. And there is one absolute minimum point.
Can you write Python code for it?

# Calculate a range of values for b0 and b1
b0_min, b0_max = -500, 2000
b1_min, b1_max = -100, 100
bb0, bb1 = np.meshgrid(np.arange(b0_min, b0_max, (b0_max - b0_min)/100),
                       np.arange(b1_min, b1_max, (b1_max - b1_min)/100))

# Calculate a mesh of values for b0 and b1 and error term for each
bb = np.c_[bb0.ravel(), bb1.ravel()]
errors = [error_term(X,y,np.asmatrix(i).T,n) for i in bb]

from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.gca(projection='3d')
trisurf = ax.plot_trisurf(bb[:,0], bb[:,1], errors, cmap=plt.cm.viridis, linewidth=0)

ax.view_init(azim=20)
fig.colorbar(trisurf, shrink=0.3, aspect=5)

ax.set_xlabel('Intercept')
ax.set_ylabel('Slope')
ax.set_zlabel("Error")


I am working on the file "Module_1d_linear_regression_gradient.ipynb".
The first task is:
Solving using Sklearn
Can you write Python code for it?

from sklearn import linear_model
from sklearn import metrics

X = pop['kmpl'].values.reshape(-1,1)
y = pop['price']

model = linear_model.LinearRegression(fit_intercept=True)
model.fit(X,y)

model.coef_

beta0 = round(model.intercept_)
beta1 = round(model.coef_[0])
print("b0 = ", beta0, "b1 =", beta1)


I am working on the file "Module_1e_logistic_regression.ipynb".
The first task is:
Cost Function
$$Cost (P(X\beta), y)) =
\begin{cases}
-log(P(X\beta)),  & \text{if $y=1$ } \
-log(1 -P(X\beta)), & \text{if $y =0$}
\end{cases}$$
Can you write Python code for it?

z = np.linspace(0.001, 0.999, 1000)

c1 = -np.log(z)
c2 = -np.log(1-z)

plt.plot(z,c1)
plt.plot(z,c2)
#plt.hlines(0.5, -10,10)
#plt.vlines(0, 0,1)
plt.xlabel('z')
plt.ylabel('Cost')


I am working on the file "Module_2a_Basic_Stat_Metrics.ipynb".
The first task is:
Co-variance
covariance as a measure of the (average) co-variation between two variables, say x and y. Covariance describes both how far the variables are spread out, and the nature of their relationship, Covariance is a measure of how much two variables change together. Compare this to Variance, which is just the range over which one measure (or variable) varies.

Co-variance of mileage of Automatic and Manual Gear Type
Can you write Python code for it?

pd.unique(cars.GearType)

cars_Automatic = cars[cars.GearType==' Automatic'].copy().reset_index()

cars_Manual = cars[cars.GearType==' Manual'].copy().reset_index()

cars_Automatic.head()

cars_Manual.head()

cars_Manual.shape

cars_Automatic.shape


I am working on the file "Module_2a_Basic_Stat_Metrics.ipynb".
The first task is:
Exercise
Can you write Python code for it?

#Display the first 10 records
cars.head(10)

#Display the last 5 records
cars.tail()

#Find the number of rows and columns in the dataset
cars.shape

#What are the column names in the dataset?
cars.columns

#What are the types of those columns ?
cars.dtypes

cars.head()

#How to check if there are null values in any of the columns?

#Hint: use the isnull() function  (how about using sum or values/any with it?)
cars.isnull().sum()


I am working on the file "Module_2a_Basic_Stat_Metrics.ipynb".
The first task is:
How to handle missing values?
Can you write Python code for it?


I am working on the file "Module_2a_Basic_Stat_Metrics.ipynb".
The first task is:
Mean, Median, Variance, Standard Deviation
Mean
arithmetic average of a range of values or quantities, computed by dividing the total of all values by the number of values.
Can you write Python code for it?

#Find mean of price
cars.Price.mean()

#Find mean of Mileage
cars.Mileage.mean()


I am working on the file "Module_2a_Basic_Stat_Metrics.ipynb".
The first task is:
Mode
It is the number which appears most often in a set of numbers.
Find the mode of Type of cars
Can you write Python code for it?

#Let's first find count of each of the car Types
#Hint: use value_counts

cars.Type.value_counts()

#Mode of cars

cars.Type

cars.Type.mode()

cars.head()


I am working on the file "Module_2a_Basic_Stat_Metrics.ipynb".
The first task is:
Using Pandas built-in function
Can you write Python code for it?


I am working on the file "Module_2a_Basic_Stat_Metrics.ipynb".
The first task is:
Variance

Once two statistician of height 4 feet and 5 feet have to cross a river of AVERAGE depth 3 feet. Meanwhile, a third person comes and said, "what are you waiting for? You can easily cross the river"

It's the average distance of the data values from the mean
<img style="float: left;" src="img/variance.png" height="320" width="320">
Find variance of mileage
Can you write Python code for it?


I am working on the file "Module_2c_resampling.ipynb".
The first task is:
Did the conclusion change now?
Effect Size

Because you can't argue with all the fools in the world. It's easier to let them have their way, then trick them when they're not paying attention  - Christopher Paolini

In the first case, how much did the price optimization increase the sales on average?
Can you write Python code for it?


I am working on the file "Module_2c_resampling.ipynb".
The first task is:
Exercise: Repeat the above for 100,000 runs and report the results
Is the result by chance?
What is the justification for shuffling the labels?

Thought process is this: If price optimization had no real effect, then, the sales before optimization would often give more sales than sales after optimization. By shuffling, we are simulating the situation where that happens -  sales before optimization is greater than sales after optimization. If many such trials provide improvements, then, the price optimization has no effect. In statistical terms, the observed difference could have occurred by chance.

Now, to show that the same difference in mean might lead to a different conclusion, let's try the same experiment with a different dataset.
Can you write Python code for it?

before_opt = np.array([230, 210, 190, 240, 350, 170, 180, 240, 330, 270, 210, 230])
after_opt = np.array([310, 180, 190, 240, 220, 240, 160, 410, 130, 320, 290, 210])

print("Mean sales before price optimization:", np.mean(before_opt))
print("Mean sales after price optimization:", np.mean(after_opt))
print("Difference in mean sales:", np.mean(after_opt) - np.mean(before_opt)) #Same as above

shoe_sales = np.array([np.append(np.zeros(before_opt.shape[0]), np.ones(after_opt.shape[0])),
np.append(before_opt, after_opt)], dtype=int)
shoe_sales = shoe_sales.T

experiment_diff_mean = shuffle_experiment(100000)
sns.distplot(experiment_diff_mean, kde=False)

#Finding % of times difference of means is greater than observed
print("Number of times diff in mean greater than observed:", \
            experiment_diff_mean[experiment_diff_mean>=observed_difference].shape[0])
print("% of times diff in mean greater than observed:", \
        experiment_diff_mean[experiment_diff_mean>=observed_difference].shape[0]/float(experiment_diff_mean.shape[0])*100)


I am working on the file "Module_2c_resampling.ipynb".
The first task is:
On average, the sales after optimization is more than the sales before optimization. But is the difference legit? Could it be due to chance?
Classical Method : We could cover this method later on. This entails doing a t-test
Hacker's Method : Let's see if we can provide a hacker's perspective to this problem, similar to what we did in the previous notebook.
Can you write Python code for it?

#Step 1: Create the dataset. Let's give Label 0 to before_opt and Label 1 to after_opt

#Learn about the following three functions

?np.append

?np.zeros

?np.ones

shoe_sales = np.array([np.append(np.zeros(before_opt.shape[0]), np.ones(after_opt.shape[0])),
np.append(before_opt, after_opt)], dtype=int)

print("Shape:", shoe_sales.shape)
print("Data:", "\n", shoe_sales)

shoe_sales = shoe_sales.T
print("Shape:",shoe_sales.shape)
print("Data:", "\n", shoe_sales)

#This is the approach we are going to take
#We are going to randomly shuffle the labels. Then compute the mean between the two groups.
#Find the % of times when the difference between the means computed is greater than what we observed above
#If the % of times is less than 5%, we would make the call that the improvements are real

np.random.shuffle(shoe_sales)

shoe_sales

experiment_label = np.random.randint(0,2,shoe_sales.shape[0])

experiment_label

experiment_data = np.array([experiment_label, shoe_sales[:,1]])
experiment_data = experiment_data.T
print(experiment_data)

experiment_diff_mean =  experiment_data[experiment_data[:,0]==1].mean() \
                        - experiment_data[experiment_data[:,0]==0].mean()

experiment_diff_mean

#Like the previous notebook, let's repeat this experiment 100 and then 100000 times

def shuffle_experiment(number_of_times):
    experiment_diff_mean = np.empty([number_of_times,1])
    for times in np.arange(number_of_times):
        experiment_label = np.random.randint(0,2,shoe_sales.shape[0])
        experiment_data = np.array([experiment_label, shoe_sales[:,1]]).T
        experiment_diff_mean[times] =  experiment_data[experiment_data[:,0]==1].mean() \
                        - experiment_data[experiment_data[:,0]==0].mean()
    return experiment_diff_mean

experiment_diff_mean = shuffle_experiment(100)

experiment_diff_mean[:10]

sns.distplot(experiment_diff_mean, kde=False)

#Finding % of times difference of means is greater than observed
print("Data: Difference in mean greater than observed:", \
      ...


I am working on the file "Module_2c_resampling.ipynb".
The first task is:
Would business feel comfortable spending millions of dollars if the increase is going to be just 1.75%. Does it make sense? Maybe yes - if margins are thin and any increase is considered good. But if the returns from the price optimization module does not let the company break even, it makes no sense to take that path.

Someone tells you the result is statistically significant. The first question you should ask?

How large is the effect?
To answer such a question, we will make use of the concept confidence interval
In plain english, confidence interval is the range of values the measurement metric is going to take.
An example would be: 90% of the times, the increase in average sales (before and after price optimization) would be within the bucket 3.4 and 6.7 (These numbers are illustrative. We will derive those numbers below)
What is the hacker's way of doing it? We will do the following steps:

From actual sales data, we sample the data with repetition (separately for before and after) - sample size will be the same as the original
Find the differences between the mean of the two samples.
Repeat steps 1 and 2 , say 100,000 times.
Sort the differences. For getting 90% interval, take the 5% and 95% number. That range gives you the 90% confidence interval on the mean.
This process of generating the samples is called bootstrapping
Can you write Python code for it?

#Load the data
before_opt = np.array([23, 21, 19, 24, 35, 17, 18, 24, 33, 27, 21, 23])
after_opt = np.array([31, 28, 19, 24, 32, 27, 16, 41, 23, 32, 29, 33])

#generate a uniform random sample
random_before_opt = np.random.choice(before_opt, size=before_opt.size, replace=True)

print("Actual sample before optimization:", before_opt)
print("Bootstrapped sample before optimization: ", random_before_opt)

print("Mean for actual sample:", np.mean(before_opt))
print("Mean for bootstrapped sample:", np.mean(random_before_opt))

random_after_opt = np.random.choice(after_opt, size=after_opt.size, replace=True)
print("Actual sample after optimization:", after_opt)
print("Bootstrapped sample after optimization: ", random_after_opt)
print("Mean for actual sample:", np.mean(after_opt))
print("Mean for bootstrapped sample:", np.mean(random_after_opt))

print("Difference in means of actual samples:", np.mean(after_opt) - np.mean(before_opt))
print("Difference in means of bootstrapped samples:", np.mean(random_after_opt) - np.mean(random_before_opt))

#Like always, we will repeat this experiment 100,000 times.

def bootstrap_experiment(number_of_times):
    mean_difference = np.empty([number_of_times,1])
    for times in np.arange(number_of_times):
        random_before_opt = np.random.choice(before_opt, size=before_opt.size, replace=True)
        random_after_opt = np.random.choice(after_opt, size=after_opt.size, replace=True)
        mean_difference[times] = np.mean(random_after_opt) - np.mean(random_before_opt)
    return mean_difference

mean_difference = bootstrap_experiment(100000)
sns.distplot(mean_difference, kde=False)

mean_difference = np.sort(mean_difference, axis=0)

mean_difference #Sorted difference

np.percentile(mean_difference, [5,95])


I am working on the file "Module_2d_Distributions.ipynb".
The first task is:
Question If you randomly select a car, what is the probability, with equal chances of selecting any of the make available in our dataset, that the mileage will be greater than 25?
Can you write Python code for it?


I am working on the file "Module_2d_Distributions.ipynb".
The first task is:
Standard Error
It is a measure of how far the estimate to be off, on average. More technically, it is the standard deviation of the sampling distribution of a statistic(mostly the mean). Please do not confuse it with standard deviation. Standard deviation is a measure of the variability of the observed quantity. Standard error, on the other hand, describes variability of the estimate.
To illustrate this, let's do the following.
Not all the make and models are available in our dataset. Also, we had to impute some of the values.
Let's say that a leading automobile magazine did an extensive survey and printed that the mean mileage is 22.7.
Compute standard deviation and standard error for the mean for our dataset
Can you write Python code for it?

cars.head()

#Mean and standard deviation of car's mileage
print(" Sample Mean:", cars.Mileage.mean(), "\n", "Sample Standard Deviation:", cars.Mileage.std())

print(" Max Mileage:", cars.Mileage.max(), "\n", "Min Mileage:", cars.Mileage.min())


I am working on the file "Module_2d_Distributions.ipynb".
The first task is:
Using scipy to use distribution
Can you write Python code for it?

from scipy import stats
import scipy as sp
import numpy as np
import matplotlib as mpl
from matplotlib import pyplot as plt
%matplotlib inline

#Generate random numbers that are normally distributed
random_normal = sp.randn(100)
plt.scatter(range(100), random_normal)

print "mean:", random_normal.mean(), " variance:", random_normal.var()

#Create a normal distribution with mean 2.5 and standard deviation 1.7

n = stats.norm(loc=2.5, scale=1.7)

#Generate random number from that distribution
n.rvs()

#for the above normal distribution, what is the pdf at 0.3?
n.pdf(0.3)

#Binomial distribution with `p` = 0.4 and number of trials as 15

stats.binom.pmf(range(15), 10, 0.4)


I am working on the file "Module_2d_Distributions.ipynb".
The first task is:
We'll follow the same procedures we did in the resampling.ipynb.  We will bootstrap samples from actual observed data 10,000 times and compute difference between sample mean and actual mean. Find root mean squared error to get standard error
Can you write Python code for it?

def squared_error(bootstrap_sample, actual_mean):
    return np.square(bootstrap_sample.mean() - actual_mean)

def experiment_for_computing_standard_error(observed_mileage, number_of_times, actual_mean):
    bootstrap_mean = np.empty([number_of_times, 1], dtype=np.int32)
    bootstrap_sample = np.random.choice(observed_mileage, size=[observed_mileage.size, number_of_times], replace=True)
    bootstrap_squared_error = np.apply_along_axis(squared_error, 1, bootstrap_sample, actual_mean)
    return np.sqrt(bootstrap_squared_error.mean())

#Standard error of the estimate for mean
experiment_for_computing_standard_error(np.array(cars.Mileage), 10, 22.7)


I am working on the file "Module_2e_HypothesisTesting.ipynb".
The first task is:
Effect Size
Can you write Python code for it?

print("Effect size:", cars_Manual.Mileage.mean() - cars_Automatic.Mileage.mean())


I am working on the file "Module_2e_HypothesisTesting.ipynb".
The first task is:
Exercise
Can you write Python code for it?

#Confidence interval on the mean of automatic cars


#Mean and standard deviation of Automatic Cars

#Confidence interval on the mean of manual cars
stats.norm.interval(0.95, loc=cars_Manual.Mileage.mean(), scale = cars_Manual.Mileage.std()/np.sqrt(len(cars_Manual)))


I am working on the file "Module_2e_HypothesisTesting.ipynb".
The first task is:
Null Hypothesis: Mean prices aren't significantly different
Perform t-test and determine the p-value.
Can you write Python code for it?


I am working on the file "Module_2f_ABTesting.ipynb".
The first task is:
Co-variance
covariance as a measure of the (average) co-variation between two variables, say x and y. Covariance describes both how far the variables are spread out, and the nature of their relationship, Covariance is a measure of how much two variables change together. Compare this to Variance, which is just the range over which one measure (or variable) varies.

Can you write Python code for it?

#Find the covariance of the sales
#Use the cov function

print("Before Campaign:")
print(shoes_before.cov())
print()
print("During Campaign:")
print(shoes_during.cov())
print()
print("After Campaign:")
print(shoes_after.cov())


I am working on the file "Module_2f_ABTesting.ipynb".
The first task is:
Correlation
Extent to which two or more variables fluctuate together. A positive correlation indicates the extent to which those variables increase or decrease in parallel; a negative correlation indicates the extent to which one variable increases as the other decreases.

Can you write Python code for it?

import seaborn as sns

sns.jointplot(x= "UA101", y ="UA102", data=shoes_before)

sns.jointplot(x= "UA101", y ="UA102", data=shoes_during)

#Find correlation between sales
print("Before Campaign:")
print(shoes_before.corr())
print()
print("During Campaign:")
print(shoes_during.corr())
print()
print("After Campaign:")
print(shoes_after.corr())


I am working on the file "Module_2f_ABTesting.ipynb".
The first task is:
Correlation != Causation
correlation between two variables does not necessarily imply that one causes the other.
<img style="float: left;" src="img/correlation_not_causation.gif" height="570" width="570">
Can you write Python code for it?

#Let's do some analysis on UA101 now

#Find difference between mean sales before and after the campaign

np.mean(shoes_after.UA101) - np.mean(shoes_before.UA101)


I am working on the file "Module_2f_ABTesting.ipynb".
The first task is:
Hypothesis Testing
(We are covering, what is referred to as, frequentist method of Hypothesis testing)
We would like to know if the effects we see in the sample(observed data) are likely to occur in the population.
The way classical hypothesis testing works is by conducting a statistical test to answer the following question:

Given the sample and an effect, what is the probability of seeing that effect just by chance?

Here are the steps on how we would do this

Define null hypothesis
Compute test statistic
Compute p-value
Interpret the result

If p-value is very low(most often than now, below 0.05), the effect is considered statistically significant. That means that effect is unlikely to have occured by chance. The inference? The effect is likely to be seen in the population too.
This process is very similar to the proof by contradiction paradigm. We first assume that the effect is false. That's the null hypothesis. Next step is to compute the probability of obtaining that effect (the p-value). If p-value is very low(<0.05 as a rule of thumb), we reject the null hypothesis.
Can you write Python code for it?

import numpy as np
import pandas as pd
from scipy import stats
import matplotlib as mpl
%matplotlib inline

import seaborn as sns
sns.set(color_codes=True)

#Mean of sales before campaign
shoes_before.UA101.mean()

#Confidence interval on the mean of sales before campaign
stats.norm.interval(0.95, loc=shoes_before.UA101.mean(),
scale = shoes_before.UA101.std()/np.sqrt(len(shoes_before)))

#Find 80% Confidence interval

#Find mean and 95% CI on mean of sales after campaign
print(shoes_after.UA101.mean())
stats.norm.interval(0.95, loc=shoes_after.UA101.mean(),
scale = shoes_after.UA101.std()/np.sqrt(len(shoes_after)))

#What does confidence interval mean?

#Effect size

print("Effect size:", shoes_after.UA101.mean()
      - shoes_before.UA101.mean() )


I am working on the file "Module_2f_ABTesting.ipynb".
The first task is:
Null Hypothesis: Mean sales aren't significantly different
Perform t-test and determine the p-value.
Can you write Python code for it?


I am working on the file "Module_2f_ABTesting.ipynb".
The first task is:
On average, the sales after campaign is more than the sales before campaign. But is the difference legit? Could it be due to chance?
Classical Method : t-test
Hacker's Method : provided in notebook 2c
Effect Size

Because you can't argue with all the fools in the world. It's easier to let them have their way, then trick them when they're not paying attention  - Christopher Paolini
Can you write Python code for it?

#Find %increase in mean sales
(np.mean(shoes_after.UA101) - np.mean(shoes_before.UA101))/np.mean(shoes_after.UA101) * 100


I am working on the file "Module_2f_ABTesting.ipynb".
The first task is:
p-value is the probability that the effective size was by chance. And here, p-value is almost 0.
Conclusion: The sales difference is significant.
Assumption of t-test
One assumption is that the data used came from a normal distribution.
<br>
There's a Shapiro-Wilk test to test for normality. If p-value is less than 0.05, then there's a low chance that the distribution is normal.
Can you write Python code for it?


I am working on the file "Module_2g_HackerStats.ipynb".
The first task is:
A/B Testing
The shoe company, after a month of sales, got endorsed by the current MVP of NBA.
The sales for the second month after lunch, and the first month after endorsement is as follows:
[64, 60, 52, 51, 49, 71, 71, 68, 56, 43, 71, 61, 43, 47, 40, 42, 42, 42, 54, 45, 59, 44, 64, 63, 59, 40, 55, 61, 57, 63]
Did the endorsement impact the sales positively?
Can you write Python code for it?

# Load 2nd month sales data
sales_2 = np.array([64, 60, 52, 51, 69, 71, 71, 68, 56, 63, 71, 61, 63, 67, 60, 62, 72,
       42, 54, 45, 59, 44, 64, 63, 59, 40, 55, 61, 57, 63])

# find mean of sales_2
np.mean(sales_2)

# The difference between the two means:
shoe_sales_diff = np.mean(sales_2) - np.mean(sales_1)
shoe_sales_diff

# So, sales improved, on average, by 2.53 shoes. But is it statistically significant?


I am working on the file "Module_2g_HackerStats.ipynb".
The first task is:
But the above is based on one sample. How do I get an estimate for the population?
Resampling/Bootstrapping
Can you write Python code for it?

# Let's create a bootstrap sample - we will use np.random.choice

?np.random.choice

#create a bootstrap sample from sales_1
sample_1 = np.random.choice(sales_1, 30)

sample_1

#mean of sample_1
np.mean(sample_1)

# Now, let's write a function that returns mean of n bootstrap samples

def bootstrap_sample_mean(input, num_samples):
    """
      Function that generates bootstrap sample, computes its mean and return the array

      Arguments:
         input : the input array for which bootstrap sample has to be generated
         num_samples: num of times the sample has to be generated

      output:
         bootstrap_mean : This returns the mean of each of the bootstrap sample as a numpy array

    """

    bootstrap_mean = np.zeros([num_samples, 1])

    for i in np.arange(num_samples):
        sample = np.random.choice(input, input.shape[0])
        bootstrap_mean[i] = np.mean(sample)

    return bootstrap_mean

bootstrap_mean = bootstrap_sample_mean(sales_1, 5)

sns.distplot(bootstrap_mean, kde=False)

#What is the variability around this estimate?
# this is referred to as standard error of the estimate

np.std(bootstrap_mean)

# Of course, this is small sample. So, generate it for a number of samples (say: 100k).
# Report the estimate and standard error

# Mean

# Standard Error

# Bonus - this is how the standard error is obtained using scipy

from scipy import stats
stats.sem(sales_1)


I am working on the file "Module_2g_HackerStats.ipynb".
The first task is:
Does 4.4% make sense for the business?
Confidence interval
Confidence interval is the range of values the measurement metric is going to take.
An example would be: 90% of the times, the increase in average sales (before and after endorsement) would be within the bucket  3.4 and 6.7 (These numbers are illustrative. We will derive those numbers below)
What is the hacker's way of doing it? We will do the following steps:

From actual sales data, we sample the data with repetition (separately for before and after) - sample size will be the same as the original
Find the differences between the mean of the two samples.
Repeat the above two steps, say 100,000 times.
Sort the differences. For getting 90% interval, take the 5% and 95% number. That range gives you the 90% confidence interval on the mean.

Does this process sound familiar ?
Can you write Python code for it?

# Function to generate mean difference for many bootstrap samples

def mean_diff_bootstrap(before_sales, after_sales, num_times):
    """
      Function that computes the difference between the groups on a bootstrap sample and return the mean difference array

      arguments:
         before_sales: sales before the campaign
         after_sales : sales after the campaign
         num_times: number of times to run the bootstrap sample

      output:
        mean_diff : This returns the mean differene of each of the bootstrap groups as a numpy array

    """

    mean_diff = np.zeros([num_times, 1])

    for i in np.arange(num_times):

        bootstrap_before = np.random.choice(before_sales, before_sales.shape[0])
        bootstrap_after = np.random.choice(after_sales, after_sales.shape[0])
        bootstrap_mean_diff = np.mean(bootstrap_after) - np.mean(bootstrap_before)

        mean_diff[i] = bootstrap_mean_diff

    return mean_diff

mean_diff_bootstrap_experiment = mean_diff_bootstrap(sales_2, sales_1, 50)

#Let's plot this

sns.distplot(mean_diff_bootstrap_experiment, kde=False)

mean_diff_bootstrap_experiment_sorted = np.sort(mean_diff_bootstrap_experiment, axis=0)

np.percentile(mean_diff_bootstrap_experiment_sorted, [5, 95])


I am working on the file "Module_3a_linear_algebra_eigenvectors.ipynb".
The first task is:
3 x 3 Matrix
Let us write it in the form
$$ Ax = \lambda x $$
$$ \begin{bmatrix}1 & 1 & 1 \ 3 & 8 & 1 \ 5 & -4 & 3\end{bmatrix}\begin{bmatrix} x \y \ z\end{bmatrix}= \lambda \begin{bmatrix} x\ y \ x \end{bmatrix} $$
Can you write Python code for it?


I am working on the file "Module_3b_principal_component_analysis.ipynb".
The first task is:
Calculate the Covariance Matrix
Can you write Python code for it?

cov_mat_2var = np.cov(X_std.T)

cov_mat_2var


I am working on the file "Module_3b_principal_component_analysis.ipynb".
The first task is:
Eigendecomposition - Computing Eigenvectors and Eigenvalues
Can you write Python code for it?

mean_vec = np.mean(X_std, axis=0)
cov_mat = (X_std - mean_vec).T.dot((X_std - mean_vec)) / (X_std.shape[0]-1)
print('Covariance matrix \n%s' %cov_mat)

# Doing this directly using np.cov
print('NumPy covariance matrix: \n%s' %np.cov(X_std.T))

cov_mat = np.cov(X_std.T)
eig_vals, eig_vecs = np.linalg.eig(cov_mat)

print('Eigenvectors \n%s' %eig_vecs)
print('\nEigenvalues \n%s' %eig_vals)


I am working on the file "Module_3b_principal_component_analysis.ipynb".
The first task is:
Explained Variance
The explained variance tells us how much information (variance) can be attributed to each of the principal components.
Can you write Python code for it?

tot = sum(eig_vals)
var_exp = [(i / tot)*100 for i in sorted(eig_vals, reverse=True)]
cum_var_exp = np.cumsum(var_exp)

plt.bar(range(4), var_exp, alpha=0.5, align='center',
            label='individual explained variance')
plt.step(range(4), cum_var_exp, where='mid',
             label='cumulative explained variance')
plt.ylabel('Explained variance ratio')
plt.xlabel('Principal components')
plt.legend(loc='best')
plt.tight_layout()


I am working on the file "Module_3b_principal_component_analysis.ipynb".
The first task is:
From 2 Dimension to 1 Dimension
Let us generate a two variable data set - $a,b$
$$ b = 50 + 3a + \epsilon$$
Can you write Python code for it?

np.random.seed(123)

a = np.arange(12, 56, 0.5)
e = np.random.normal(0, 100, a.size)
b = 500 + 20*a + e

X = np.c_[a,b]

def plot2var (m, xlabel, ylabel):
    x = m[:,0]
    y = m[:,1]
    fig, ax = plt.subplots(figsize=(6, 6))
    plt.scatter(x, y, s = 40, alpha = 0.8)
    sns.rugplot(x, color="m", ax=ax)
    sns.rugplot(y, color="m", vertical=True, ax=ax)

    plt.xlabel(xlabel)
    plt.ylabel(ylabel)

plot2var(X, 'a', 'b')


I am working on the file "Module_3b_principal_component_analysis.ipynb".
The first task is:
From 784 Dimensions to 2 Dimensions
Can you write Python code for it?

digits = pd.read_csv('data/digits.csv')

digits.head()

digits.shape

digitsX = digits.iloc[:,1:785]

digitsX.head()

pca = PCA(n_components=2)

pca.fit(digitsX)

digits_trans = pca.transform(digitsX)

digits_trans

plt.scatter(digits_trans[:,0], digits_trans[:,1], c = digits.num,
            s = 20, alpha = 0.8, cmap = plt.cm.viridis)
plt.xlabel('Principal Component 1')
plt.ylabel('Principal Component 2')


I am working on the file "Module_3b_principal_component_analysis.ipynb".
The first task is:
How do you select which 2 axis to choose?
Sorting the Eigenvalues and Eigenvectors
In order to decide which eigenvector(s) can dropped without losing too much information for the construction of lower-dimensional subspace, we need to inspect the corresponding eigenvalues: The eigenvectors with the lowest eigenvalues bear the least information about the distribution of the data; those are the ones can be dropped.
Can you write Python code for it?

# Make a list of (eigenvalue, eigenvector) tuples
eig_pairs = [(np.abs(eig_vals[i]), eig_vecs[:,i]) for i in range(len(eig_vals))]

# Sort the (eigenvalue, eigenvector) tuples from high to low
eig_pairs.sort(key=lambda x: x[0], reverse=True)

# Visually confirm that the list is correctly sorted by decreasing eigenvalues
print('Eigenvalues in descending order:')
for i in eig_pairs:
    print(i[0])


I am working on the file "Module_3b_principal_component_analysis.ipynb".
The first task is:
Preprocessing - brand, price, kmpl, bhp
Can you write Python code for it?

pop = pop.drop(['model'], axis = 1)

from sklearn import preprocessing
le = preprocessing.LabelEncoder()
df = pop.apply(le.fit_transform)

df.head()

g = sns.PairGrid(df, hue = 'type')
g.map_diag(plt.hist)
g.map_offdiag(plt.scatter, alpha = 0.8)


I am working on the file "Module_3b_principal_component_analysis.ipynb".
The first task is:
Projection Matrix
Let us project our orginal values to see the new results
Can you write Python code for it?

eigen_vec_2var

X_std.T.shape

eigen_vec_2var.shape

X_proj = eigen_vec_2var.dot(X_std.T)

plot2var_eigen(X_proj.T, 'pca1' ,'pca2')


I am working on the file "Module_3b_principal_component_analysis.ipynb".
The first task is:
Projection Matrix
The “projection matrix” is just a matrix of our concatenated top k eigenvectors. Here, we are reducing the 4-dimensional feature space to a 2-dimensional feature subspace, by choosing the “top 2” eigenvectors with the highest eigenvalues to construct our $n×k$-dimensional eigenvector matrix $W$.
Can you write Python code for it?

matrix_w = np.hstack((eig_pairs[0][1].reshape(4,1),
                      eig_pairs[1][1].reshape(4,1)))

print('Matrix W:\n', matrix_w)

X_proj = X_std.dot(matrix_w)

fig, ax = plt.subplots(figsize=(6, 6))
plt.scatter(X_proj[:,0], X_proj[:,1], c = df.type, s = 100, cmap = plt.cm.viridis)
plt.xlabel('Principal Component 1')
plt.ylabel('Principal Component 2')


I am working on the file "Module_3b_principal_component_analysis.ipynb".
The first task is:
So our eigen vectors and eigen values are:
$$ \lambda_1 = 1.93, \lambda_2 = 0.09 $$
$$ \vec{v_1} = \begin{bmatrix} 0.707 \ -0.707\end{bmatrix} $$
$$ \vec{v_2} = \begin{bmatrix}  0.707 \  0.707\end{bmatrix} $$
These are orthogonal to each other. Let us plots to see these eigen vectors
Can you write Python code for it?

def plot2var_eigen (m, xlabel, ylabel):
    x = m[:,0]
    y = m[:,1]
    fig, ax = plt.subplots(figsize=(6, 6))
    plt.scatter(x, y, s = 40, alpha = 0.8)
    sns.rugplot(x, color="m", ax=ax)
    sns.rugplot(y, color="m", vertical=True, ax=ax)

    cov_mat = np.cov(m.T)
    eigen_val, eigen_vec = np.linalg.eig(cov_mat)

    plt.quiver(eigen_vec[0, 0], eigen_vec[0, 1], angles='xy', scale_units='xy', scale=1, color='brown')
    plt.quiver(eigen_vec[1, 0], eigen_vec[1, 1], angles='xy', scale_units='xy', scale=1, color='brown')

    plt.xlabel(xlabel)
    plt.ylabel(ylabel)

    plt.xlim(-3,3)
    plt.ylim(-3,3)

plot2var_eigen(X_std, 'a' ,'b')


I am working on the file "Module_3b_principal_component_analysis.ipynb".
The first task is:
Standardizing
Can you write Python code for it?

X = df.iloc[:,:4]

from sklearn.preprocessing import StandardScaler
X_std = StandardScaler().fit_transform(X)


I am working on the file "Module_3b_principal_component_analysis.ipynb".
The first task is:
Using PCA from SKlearn
Can you write Python code for it?

from sklearn.decomposition import PCA

pca = PCA(n_components=2)

pca.fit(X_std)

X_pca_proj = pca.transform(X_std)

plot2var_std(X_pca_proj, 'pca1', 'pca2')

pca.explained_variance_


I am working on the file "Modules+and+Packages.ipynb".
The first task is:
Import with renaming
We can import a module by renaming it as follows:
Can you write Python code for it?


I am working on the file "Modules+and+Packages.ipynb".
The first task is:
Module Functions
Can you write Python code for it?

print(dir(os))

import math
print(math.__doc__)
math.__name__


I am working on the file "Modules+and+Packages.ipynb".
The first task is:
Module Search Path
While importing a module python looks for a definition at various places and in the following order.

First it looks for a built-in module
Looks at the current directory
PYTHONPATH ( environment variable with a list of directory )
Installation dependent default directory
Can you write Python code for it?


I am working on the file "Modules+and+Packages.ipynb".
The first task is:
Packages
A package is just a way of collecting related modules together within a single tree-like hierarchy.
Like we organise the files in directories, Python has packages for directories and modules for files. Similar, as a directory can contain sub-directories and files, a python package can have sub-package and modules.
A directory must contain a file named __init.py in order for python to consider the directory as a package. This file can be empty but in general it is used for initialisation code for that package.
The following are different ways of importing the packages.

import <package name>
import <package name>.<module name>
from <package name> import <module name>
Can you write Python code for it?

# examples
import math
from math import pi
print(pi)


I am working on the file "Modules+and+Packages.ipynb".
The first task is:
Reloading a Module
Python loads modules only once even though you try to import it multiple times. But if the module is changed for some reasons and you want to reload the module you can use the .reload() function inside the 'imp' module.
Can you write Python code for it?

# my_module.py
# print('This code got executed')

# import imp
# import my_module
# This code got executed
# import my_module
# import my_module
# imp.reload(my_module)


I am working on the file "Modules+and+Packages.ipynb".
The first task is:
To import all definitions from the module just specify '*' as below. Please note that this not a good practice as it can lead to duplicate definitions for an identifier.
Can you write Python code for it?


I am working on the file "Modules+and+Packages.ipynb".
The first task is:
User Defined Module
Can you write Python code for it?

# save the following code as example.py
def add(a,b):
    return a+b

# now you can import example.py
# import example
# example.add(5,4)


I am working on the file "Modules+and+Packages.ipynb".
The first task is:
from...import statement
We can import specific names from am module without importing the full module.
Can you write Python code for it?

from math import pi
print(pi) # please note the dot operator is not required


I am working on the file "Modules/DataImport.ipynb".
The first task is:
Data
we fetch three data series, the ECB deposit facility, the ECB lending facility, and the ECB marginal lending facility using the fetch method that takes as parameter the series key (see below and explanation for the skip_end parameter)
Can you write Python code for it?

ei = di.ECBDataImport()
deposit = ei.fetch(bm.get('deposit', 'key'), skip_end=10)
lending = ei.fetch(bm.get('lending', 'key'))
lending_marg = ei.fetch(bm.get('lending_marg', 'key'))


I am working on the file "Modules/DataImport.ipynb".
The first task is:
Testing
Bookmarks
that's a little side project, which is to create a file containing bookmarks for interesting series in the ECB database; it uses the PDataFrame class defined above.
Note that the following lines can generally be commented out: the whole idea here is that the bookmarks are kept in persistant storage (here the file ECB_DataSeries.csv) so one only has to execute bm.set() once to add a new bookmark (provided the csv file is being moved around with this note book)
Can you write Python code for it?

#pdf.PDataFrame.create('DataImport.csv', ('key', 'description'))
#bm = pdf.PDataFrame('DataImport.csv')
#bm.set('deposit', ('ILM.W.U2.C.L022.U2.EUR', 'current usage of the deposit facility'))
#bm.set('lending', ('ILM.M.U2.C.A05B.U2.EUR', 'current aggregate usage of major lending facilities'))
#bm.set('lending_marg', ('ILM.W.U2.C.A055.U2.EUR', 'current usage of the marginal lending facility')


I am working on the file "Modules/DataImport.ipynb".
The first task is:
The time information is in a funny format eg (eg, "2008w21"). So we then reformat the datatables into something that can be plotted, ie a float. For this we have the static method data_table that takes the data and a reformatting function for the time. Normally it returns a 2-tuple, the first component being the time-tuple, the second component being the value-tuple
If desired, additionally an interpolation function can be return as the third component. This is necessary if we want to do operations on series that are not based on the same time values. We see this in the last line below: le[2] is the interpolation function for the lending, and it is applied to dp[0] which are the time values for the deposit function. Now the two series are on the same basis and can hence be substracted (note that in fetch() we needed the skip_end parameter, because the available deposit data series goes further than the available lending series, which makes the interpolation fail).
Can you write Python code for it?

unit = 1000000
dp = ei.data_table(deposit, ei.time_reformat1, unit)
le = ei.data_table(lending, ei.time_reformat2, unit, True)
lm = ei.data_table(lending_marg, ei.time_reformat1, unit)
diff = le[2](dp[0]) - dp[1]


I am working on the file "Modules/DataImport.ipynb".
The first task is:
We now can plot the data series. Note that that would not have been that trivial to do in Excel because one of the data series is monthly, the other one is weekly
Can you write Python code for it?

plot(le[0], le[1])
plot(lm[0], lm[1])
plot(dp[0], dp[1])

plot(dp[0], diff)


I am working on the file "Modules/DataImport.ipynb".
The first task is:
just to check what bookmarks we have defined...
Can you write Python code for it?

bm = pdf.PDataFrame('DataImport.csv')
bm._df


I am working on the file "Modules/DataImport.ipynb".
The first task is:
module PDataFrame
that's a little side project that creates persistent data frames
Can you write Python code for it?

#!wget https://www.dropbox.com/s//PDataFrame.py -O PDataFrame.py
import PDataFrame as pdf
#help('PDataFrame')


I am working on the file "Modules/DataImport.ipynb".
The first task is:
the dataset returned contains a number of additonal info items, for example a description
Can you write Python code for it?


I am working on the file "Modules/PDataFrame.ipynb".
The first task is:
The PDataFrame class provides a persistant data frame (it is saved to a csv file on the disk). This is useful to collect information in iPython notebooks without having to add it into the notebooks itself. Use cases

Bookmarks - a notebook might rely on a number of different URL's eg to download different data series; those URL's can be stored in the notebook, but if there are too many of them then it might be cleaner to save them in a separate (and transferable!) bookmarks file

Results - when running various analysis / simulations (eg by changing the initial conditions) one might want to keep track of the results; again a PDataFrame might be a good target for that

Example: Bookmarks
create a persistant data frame (run only once; will erase all data otherwise!)
Can you write Python code for it?


I am working on the file "Modules/PDataFrame.ipynb".
The first task is:
df() returns the underlying dataframe
Can you write Python code for it?

bm = pdf.PDataFrame('PDataFrame.csv')
bm.df()


I am working on the file "Modules/PDataFrame.ipynb".
The first task is:
enter data into the dataframe; this code only has to be run once, ie it can be removed afterwards; it can be run more than once without issue though, as long as the keys don't change the contents is simply overwritten
Can you write Python code for it?

bm = pdf.PDataFrame('PDataFrame.csv')
bm.set('deposit', ('ILM.W.U2.C.L022.U2.EUR', 'current usage of the deposit facility'))
bm.set('lending', ('ILM.M.U2.C.A05B.U2.EUR', 'current aggregate usage of major lending facilities'))
bm.set('lending_marg', ('ILM.W.U2.C.A055.U2.EUR', 'current usage of the marginal lending facility'))
bm.set('another_one', ('NA.NA', 'lorem ipsum'))


I am working on the file "Modules/PDataFrame.ipynb".
The first task is:
rows can be deleted using delete
Can you write Python code for it?

bm.delete('another_one')

bm = pdf.PDataFrame('PDataFrame.csv')
bm.df()


I am working on the file "Modulo1/.ipynb_checkpoints/Clase4_OsciladorArmonico-checkpoint.ipynb".
The first task is:
Condiciones iniciales
Realmente lo que se tiene que resolver es,
\begin{equation}
\theta(t) = \theta(0) \cos(\omega_{0} t) + \frac{\dot{\theta}(0)}{\omega_{0}} \sin(\omega_{0} t)
\end{equation}

Actividad. Modificar el programa anterior para incorporar las condiciones iniciales.
Can you write Python code for it?

# Solución:
def theta_t():

    return

def pendulo_simple(t = 0):
    fig = plt.figure(figsize = (5,5))
    ax = fig.add_subplot(1, 1, 1)
    x = 2 * np.sin(theta_t( , t))
    y =  - 2 * np.cos(theta_t(, t))
    ax.plot(x, y, 'ko', ms = 10)
    ax.plot([0], [0], 'rD')
    ax.plot([0, x ], [0, y], 'k-', lw = 1)
    ax.set_xlim(xmin = -2.2, xmax = 2.2)
    ax.set_ylim(ymin = -2.2, ymax = .2)
    fig.canvas.draw()
interact_manual(pendulo_simple, t = (0, 10,.01));


I am working on the file "Modulo1/.ipynb_checkpoints/Clase4_OsciladorArmonico-checkpoint.ipynb".
The first task is:
La opción de arriba generalmente será lenta, así que lo recomendable es usar interact_manual.
Can you write Python code for it?

def masa_resorte(t = 0):
    A, B, w0 = .5, .1, .5                            # Parámetros
    x = A*np.cos(w0*t)+B*np.sin(w0*t)                # Función de posición

    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1)
    ax.plot(x, [0],  'ko', ms = 10)
    ax.set_xlim(xmin = -0.6, xmax = .6)
    ax.axvline(x=0, color = 'r')
    ax.axhline(y=0, color = 'grey', lw = 1)
    fig.canvas.draw()

interact_manual(masa_resorte, t = (0, 50,.01));


I am working on the file "Modulo1/.ipynb_checkpoints/Clase4_OsciladorArmonico-checkpoint.ipynb".
The first task is:
Y esta es la librería con todas las funciones matemáticas necesarias.
Can you write Python code for it?

import numpy as np

# Definición de funciones a graficar
A, B, w0 = .5, .1, .5                            # Parámetros
t = np.linspace(0, 50, 100)                      # Creamos vector de tiempo de 0 a 50 con 100 puntos
x = A*np.cos(w0*t)+B*np.sin(w0*t)                # Función de posición
dx = w0*(-A*np.sin(w0*t)+B*np.cos(w0*t))         # Función de velocidad

# Gráfico
plt.figure(figsize = (7, 4))                     # Ventana de gráfica con tamaño
plt.plot(t, x, '-', lw = 1, ms = 4,
         label = '$x(t)$')                       # Explicación
plt.plot(t, dx, 'ro-', lw = 1, ms = 4,
         label = r'$\dot{x(t)}$')
plt.xlabel('$t$', fontsize = 20)                 # Etiqueta eje x
plt.show()

# Colores, etiquetas y otros formatos

plt.figure(figsize = (7, 4))
plt.scatter(t, x, lw = 0, c = 'red',
            label = '$x(t)$')           # Gráfica con puntos
plt.plot(t, x, 'r-', lw = 1)            # Grafica normal
plt.scatter(t, dx, lw = 0, c = 'b',
            label = r'$\frac{dx}{dt}$') # Con la r, los backslash se tratan como un literal, no como un escape
plt.plot(t, dx, 'b-', lw = 1)
plt.xlabel('$t$', fontsize = 20)
plt.legend(loc = 'best')                # Leyenda con las etiquetas de las gráficas
plt.show()


I am working on the file "Modulo1/.ipynb_checkpoints/Clase4_OsciladorArmonico-checkpoint.ipynb".
The first task is:
_Esta es la librería con todas las instrucciones para realizar gráficos. _
Can you write Python code for it?

import matplotlib.pyplot as plt

import matplotlib as mpl
label_size = 14
mpl.rcParams['xtick.labelsize'] = label_size
mpl.rcParams['ytick.labelsize'] = label_size


I am working on the file "Modulo1/.ipynb_checkpoints/Clase5_OsciladorAmortiguado-checkpoint.ipynb".
The first task is:
$yy$ es una matriz de 2000 filas y 2 columnas.
La primer columna de $yy$ corresponde a $y_1$.
La segunda columna de $yy$ corresponde a $y_2$.

¿Cómo extraemos los resultados $y_1$ y $y_2$ independientemente?
Can you write Python code for it?

## Una forma
#yy1 = yy[:,1]                                   # tome de yy todas las filas (:) y la primer columna
#yy2 = yy[:,2]                                   # tome de yy todas las filas (:) y la segunda columna

# Otra forma (más compacta)
yy1, yy2 = yy.T                                 # transponemos la matriz yy y extraemos los resultados.

# Comandos para hacer los números de los ejes más grandes
import matplotlib as mpl
label_size = 14
mpl.rcParams['xtick.labelsize'] = label_size
mpl.rcParams['ytick.labelsize'] = label_size

# Graficamos
plt.plot(tt, yy1, c = 'r', label="Posicion")
plt.plot(tt, yy2, c = 'k', label="Velocidad")
plt.legend(loc = 'best', prop={'size': 14})
plt.xlabel('$t$', fontsize = 14)
plt.ylabel('$y_1$, $y_2$', fontsize = 14)
plt.show()

# Frecuencia natural
omega0 = k/m
# Graficamos el espacio fase
plt.figure(figsize = (6,6))
plt.scatter(yy1, yy2/omega0, lw = 0, s = 3, cmap = 'viridis', c = yy1)
plt.show()


I am working on the file "Modulo1/.ipynb_checkpoints/Clase5_OsciladorAmortiguado-checkpoint.ipynb".
The first task is:
Dependiendo de los parámetros, 3 tipos de soluciones
Teníamos
\begin{equation}
m\frac{d^2 x}{dt^2} + c\frac{dx}{dt} + kx = 0
\end{equation}
si recordamos que $\omega_0 ^2 = \frac{k}{m}$ y definimos $\frac{c}{m}\equiv 2\Gamma$, tendremos
\begin{equation}
\frac{d^2 x}{dt^2} + 2\Gamma \frac{dx}{dt}+ \omega_0^2 x = 0
\end{equation}
Subamortiguado
Si $\omega_0^2 > \Gamma^2$ se tiene movimiento oscilatorio subamortiguado.
Can you write Python code for it?

omega0 = k/m
Gamma = B/(2*m)

omega0**2, Gamma**2

omega0**2 > Gamma**2


I am working on the file "Modulo1/.ipynb_checkpoints/Clase5_OsciladorAmortiguado-checkpoint.ipynb".
The first task is:
En resumen, se tiene entonces:
Can you write Python code for it?

fig, ((ax1, ax2, ax3), (ax4, ax5, ax6)) = plt.subplots(2, 3, sharex='col',
                                                       sharey='row',figsize =(10,6))
ax1.plot(tt, yy1, c = 'k')
ax1.set_title('Amortiguado', fontsize = 14)
ax1.set_ylabel('Posición', fontsize = 14)
ax2.plot(tt, yy1s, c = 'b')
ax2.set_title('Sobreamortiguado', fontsize = 14)
ax3.plot(tt, yy1c, c = 'r')
ax3.set_title('Crítico', fontsize = 16)
ax4.plot(tt, yy2, c = 'k')
ax4.set_ylabel('Velocidad', fontsize = 14)
ax4.set_xlabel('tiempo', fontsize = 14)
ax5.plot(tt, yy2s, c = 'b')
ax5.set_xlabel('tiempo', fontsize = 14)
ax6.plot(tt, yy2c, c = 'r')
ax6.set_xlabel('tiempo', fontsize = 14)
plt.show()


I am working on the file "Modulo1/.ipynb_checkpoints/Clase5_OsciladorAmortiguado-checkpoint.ipynb".
The first task is:
Entonces, el primer caso que ya habíamos presentado corresponde a movimiento amortiguado.
Can you write Python code for it?

plt.figure()
plt.plot(tt, yy1, c = 'r', label="Posicion")
plt.plot(tt, yy2, c = 'k', label="Velocidad")
plt.legend(loc = 'best', prop={'size': 14})
plt.xlabel('t', fontsize = 14)
plt.show()


I am working on the file "Modulo1/.ipynb_checkpoints/Clase5_OsciladorAmortiguado-checkpoint.ipynb".
The first task is:
Sobreamortiguado
Si $\omega_0^2 < \Gamma^2$ se tiene movimiento oscilatorio sobreamortiguado.
Can you write Python code for it?

k = .1 # Constante del muelle
m = 1.0   # Masa
B = .5 # Constante de amortiguación

omega0 = k/m
Gamma = B/(2*m)

omega0**2, Gamma**2

omega0**2 < Gamma**2

y0 = [0.6, 0.4]
tt = np.arange(0, 20, .01)
yy = odeint(armonico, y0, tt)

yy1s, yy2s = yy.T  # extraer posición y velocidad.

plt.plot(tt, yy1s, c = 'r', label="Posicion")
plt.plot(tt, yy2s, c = 'k', label="Velocidad")
plt.legend(loc = 'best', prop={'size': 14})
plt.xlabel('tiempo', fontsize = 14)
plt.show()


I am working on the file "Modulo1/Clase4_OsciladorArmonico.ipynb".
The first task is:
Condiciones iniciales
Realmente lo que se tiene que resolver es,
\begin{equation}
\theta(t) = \theta(0) \cos(\omega_{0} t) + \frac{\dot{\theta}(0)}{\omega_{0}} \sin(\omega_{0} t)
\end{equation}

Actividad. Modificar el programa anterior para incorporar las condiciones iniciales.
Can you write Python code for it?

# Solución:
def theta_t(theta_0,dtheta_0,g,l,t):
    omega_0 = np.sqrt(g/l)
    return theta_0 * np.cos(omega_0 * t) + dtheta_0/omega_0 * np.sin(omega_0 * t)

def pendulo_simple(t = 0):
    fig = plt.figure(figsize = (5,5))
    ax = fig.add_subplot(1, 1, 1)
    x = 2 * np.sin(theta_t(.1, -.1, 9.8, 2, t))
    y =  - 2 * np.cos(theta_t(.1, -.1, 9.8, 2, t))
    ax.plot(x, y, 'ko', ms = 10)
    ax.plot([0], [0], 'rD')
    ax.plot([0, x ], [0, y], 'k-', lw = 1)
    ax.set_xlim(xmin = -2.2, xmax = 2.2)
    ax.set_ylim(ymin = -2.2, ymax = .2)
    fig.canvas.draw()
interact_manual(pendulo_simple, t = (0, 10,.01));


I am working on the file "Modulo1/Clase4_OsciladorArmonico.ipynb".
The first task is:
Estos colores, son el default de matplotlib, sin embargo existe otra librería dedicada, entre otras cosas, a la presentación de gráficos.
Can you write Python code for it?

import seaborn as sns
sns.set(style='ticks', palette='Set2')

frecuencias = np.array([.1, .2 , .5, .6])
plt.figure(figsize = (7, 4))
for w0 in frecuencias:
    x = A*np.cos(w0*t)+B*np.sin(w0*t)
    plt.plot(t, x, 'o-',
             label = '$\omega_0 = %s$'%w0)   # Etiqueta cada gráfica con frecuencia correspondiente (conversion float a string)
plt.xlabel('$t$', fontsize = 16)
plt.ylabel('$x(t)$', fontsize = 16)
plt.title('Oscilaciones', fontsize = 16)
plt.legend(loc='center left', bbox_to_anchor=(1.05, 0.5), prop={'size': 10})
plt.show()


I am working on the file "Modulo1/Clase4_OsciladorArmonico.ipynb".
The first task is:
La opción de arriba generalmente será lenta, así que lo recomendable es usar interact_manual.
Can you write Python code for it?


I am working on the file "Modulo1/Clase4_OsciladorArmonico.ipynb".
The first task is:
Los sistemas mas sencillos a estudiar en oscilaciones son el sistema masa-resorte y el péndulo simple.

\begin{align}
\frac{d^2 x}{dt^2} +  \omega_{0}^2 x &= 0, \quad \omega_{0} = \sqrt{\frac{k}{m}}\notag\
\frac{d^2 \theta}{dt^2} + \omega_{0}^{2}\, \theta &= 0, \quad\mbox{donde}\quad \omega_{0}^2 = \frac{g}{l}
\end{align}

Sistema masa-resorte
La solución a este sistema masa-resorte se explica en términos de la segunda ley de Newton. Para este caso, si la masa permanece constante y solo consideramos la dirección en $x$. Entonces,
\begin{equation}
F = m \frac{d^2x}{dt^2}.
\end{equation}
¿Cuál es la fuerza?  Ley de Hooke!
\begin{equation}
F = -k x, \quad k > 0.
\end{equation}
Vemos que la fuerza se opone al desplazamiento y su intensidad es proporcional al mismo.  Y $k$ es la constante elástica o recuperadora del resorte.
Entonces, un modelo del sistema masa-resorte está descrito por la siguiente ecuación diferencial:
\begin{equation}
\frac{d^2x}{dt^2} + \frac{k}{m}x = 0,
\end{equation}
cuya solución se escribe como
\begin{equation}
x(t) = A \cos(\omega_{o} t) + B \sin(\omega_{o} t)
\end{equation}
Y su primera derivada (velocidad) sería
\begin{equation}
\frac{dx(t)}{dt} = \omega_{0}[- A \sin(\omega_{0} t) + B\cos(\omega_{0}t)]
\end{equation}
 Ver en el tablero que significa solución de la ecuación diferencial.
¿Cómo se ven las gráficas de $x$ vs $t$ y $\frac{dx}{dt}$ vs $t$?
Esta instrucción es para que las gráficas aparezcan dentro de este entorno.
Can you write Python code for it?


I am working on the file "Modulo1/Clase4_OsciladorArmonico.ipynb".
The first task is:
Multiples condiciones iniciales
Can you write Python code for it?

k = 3  #constante elástica [N]/[m]
m = 1 # [kg]
omega_0 = np.sqrt(k/m)

t = np.linspace(0, 50, 50)

x_0s = np.array([.7, .5, .25, .1])
dx_0s = np.array([.2, .1, .05, .01])
cmaps = np.array(['viridis', 'inferno', 'magma', 'plasma'])

plt.figure(figsize = (6, 6))
for indx, x_0 in enumerate(x_0s):
    x_t = x_0 *np.cos(omega_0 *t) + (dx_0s[indx]/omega_0) * np.sin(omega_0 *t)
    dx_t = -omega_0 * x_0 * np.sin(omega_0 * t) + dx_0s[indx] * np.cos(omega_0 * t)
    plt.scatter(x_t,  dx_t/omega_0, cmap = cmaps[indx],
                c = dx_t, s = 10,
                lw = 0)
    plt.xlabel('$x(t)$', fontsize = 18)
    plt.ylabel('$\dot{x}(t)/\omega_0$', fontsize = 18)
    #plt.legend(loc='center left', bbox_to_anchor=(1.05, 0.5))


I am working on the file "Modulo1/Clase4_OsciladorArmonico.ipynb".
The first task is:
Plano fase  $(x, \frac{dx}{dt})$
La posición y velocidad para el sistema masa-resorte se escriben como:
\begin{align}
x(t) &= x(0) \cos(\omega_{o} t) + \frac{\dot{x}(0)}{\omega_{0}} \sin(\omega_{o} t)\
\dot{x}(t) &= -\omega_{0}x(0) \sin(\omega_{0} t) + \dot{x}(0)\cos(\omega_{0}t)]
\end{align}
Can you write Python code for it?

k = 3  #constante elástica [N]/[m]
m = 1 # [kg]
omega_0 = np.sqrt(k/m)
x_0 = .5
dx_0 = .1

t = np.linspace(0, 50, 300)

x_t = x_0 *np.cos(omega_0 *t) + (dx_0/omega_0) * np.sin(omega_0 *t)
dx_t = -omega_0 * x_0 * np.sin(omega_0 * t) + dx_0 * np.cos(omega_0 * t)

plt.figure(figsize = (7, 4))
plt.plot(t, x_t, label = '$x(t)$', lw = 1)
#plt.plot(t, dx_t, label = '$\dot{x}(t)$', lw = 1)
plt.plot(t, dx_t/omega_0, label = '$\dot{x}(t)$', lw = 1)  # Mostrar que al escalar, la amplitud queda igual
plt.legend(loc='center left', bbox_to_anchor=(1.01, 0.5), prop={'size': 14})
plt.xlabel('$t$', fontsize = 18)
plt.show()

plt.figure(figsize = (5, 5))
plt.plot(x_t, dx_t/omega_0, 'ro', ms = 2)
plt.xlabel('$x(t)$', fontsize = 18)
plt.ylabel('$\dot{x}(t)/\omega_0$', fontsize = 18)
plt.show()

plt.figure(figsize = (5, 5))
plt.scatter(x_t, dx_t/omega_0, cmap = 'viridis', c = -dx_t, s = 8, lw = 0)
plt.xlabel('$x(t)$', fontsize = 18)
plt.ylabel('$\dot{x}(t)/\omega_0$', fontsize = 18)
plt.show()


I am working on the file "Modulo1/Clase4_OsciladorArmonico.ipynb".
The first task is:
Péndulo simple
Ahora, si fijamos nuestra atención al movimiento de un péndulo simple (oscilaciones pequeñas), la ecuación diferencial a resolver tiene la misma forma:
\begin{equation}
\frac{d^2 \theta}{dt^2} + \omega_{0}^{2}\, \theta = 0, \quad\mbox{donde}\quad \omega_{0}^2 = \frac{g}{l}.
\end{equation}
La diferencia más evidente es como hemos definido a $\omega_{0}$. Esto quiere decir que,
\begin{equation}
\theta(t) = A\cos(\omega_{0} t) + B\sin(\omega_{0}t)
\end{equation}
Si graficamos la ecuación de arriba vamos a encontrar un comportamiento muy similar al ya discutido anteriormente. Es por ello que ahora veremos el movimiento en el plano $xy$. Es decir,
\begin{align}
x &= l \sin(\theta), \quad
y = l \cos(\theta)
\end{align}
Can you write Python code for it?

# Podemos definir una función que nos entregue theta dados los parámetros y el tiempo
def theta_t(a, b, g, l, t):
    omega_0 = np.sqrt(g/l)
    return a * np.cos(omega_0 * t) + b * np.sin(omega_0 * t)

# Hacemos un gráfico interactivo del péndulo

def pendulo_simple(t = 0):
    fig = plt.figure(figsize = (5,5))
    ax = fig.add_subplot(1, 1, 1)
    x = 2 * np.sin(theta_t(.4, .6, 9.8, 2, t))
    y =  - 2 * np.cos(theta_t(.4, .6, 9.8, 2, t))
    ax.plot(x, y, 'ko', ms = 10)
    ax.plot([0], [0], 'rD')
    ax.plot([0, x ], [0, y], 'k-', lw = 1)
    ax.set_xlim(xmin = -2.2, xmax = 2.2)
    ax.set_ylim(ymin = -2.2, ymax = .2)
    fig.canvas.draw()

interact_manual(pendulo_simple, t = (0, 10,.01));


I am working on the file "Modulo1/Clase4_OsciladorArmonico.ipynb".
The first task is:
Y si consideramos un conjunto de frecuencias de oscilación, entonces
Can you write Python code for it?

frecuencias = np.array([.1, .2 , .5, .6])   # Vector de diferentes frecuencias
plt.figure(figsize = (7, 4))                # Ventana de gráfica con tamaño

# Graficamos para cada frecuencia
for w0 in frecuencias:
    x = A*np.cos(w0*t)+B*np.sin(w0*t)
    plt.plot(t, x, '*-')
plt.xlabel('$t$', fontsize = 16)            # Etiqueta eje x
plt.ylabel('$x(t)$', fontsize = 16)         # Etiqueta eje y
plt.title('Oscilaciones', fontsize = 16)    # Título de la gráfica
plt.show()


I am working on the file "Modulo1/Clase5_OsciladorAmortiguado.ipynb".
The first task is:
$yy$ es una matriz de 2000 filas y 2 columnas.
La primer columna de $yy$ corresponde a $y_1$.
La segunda columna de $yy$ corresponde a $y_2$.

¿Cómo extraemos los resultados $y_1$ y $y_2$ independientemente?
Can you write Python code for it?

## Una forma
#yy1 = yy[:,0]                                   # tome de yy todas las filas (:) y la primer columna
#yy2 = yy[:,1]                                   # tome de yy todas las filas (:) y la segunda columna

# Otra forma (más compacta)
yy1, yy2 = yy.T                                 # transponemos la matriz yy y extraemos los resultados.

# Comandos para hacer los números de los ejes más grandes
import matplotlib as mpl
label_size = 14
mpl.rcParams['xtick.labelsize'] = label_size
mpl.rcParams['ytick.labelsize'] = label_size

# Graficamos
plt.plot(tt, yy1, c = 'r', label="Posicion")
plt.plot(tt, yy2, c = 'k', label="Velocidad")
plt.legend(loc = 'best', prop={'size': 14})
plt.xlabel('$t$', fontsize = 14)
plt.ylabel('$y_1$, $y_2$', fontsize = 14)
plt.show()

# Frecuencia natural
omega0 = k/m
# Graficamos el espacio fase
plt.figure(figsize = (6,6))
plt.scatter(yy1, yy2/omega0, lw = 0, s = 3, cmap = 'viridis', c = yy1)
plt.show()


I am working on the file "Modulo1/Clase5_OsciladorAmortiguado.ipynb".
The first task is:
Amortiguamiento crítico
Si $\omega_0^2 = \Gamma^2$ se tiene movimiento críticamente amortiguado.
Can you write Python code for it?

k = np.sqrt(.0625) # Constante del muelle
m = 1.0   # Masa
B = .5 # Constante de amortiguación

omega0 = k/m
Gamma = B/(2*m)

omega0**2, Gamma**2

omega0**2 == Gamma**2

y0 = [0.6, 0.4]
tt = np.arange(0, 20, .01)
yy = odeint(armonico, y0, tt)

yy1c, yy2c = yy.T  # extraer posición y velocidad.

plt.plot(tt, yy1c, c = 'r', label="Posicion")
plt.plot(tt, yy2c, c = 'k', label="Velocidad")
plt.legend(loc = 'best',prop={'size': 14})
plt.xlabel('tiempo', fontsize = 14)
plt.show()


I am working on the file "Modulo1/Clase5_OsciladorAmortiguado.ipynb".
The first task is:
Dependiendo de los parámetros, 3 tipos de soluciones
Teníamos
\begin{equation}
m\frac{d^2 x}{dt^2} + c\frac{dx}{dt} + kx = 0
\end{equation}
si recordamos que $\omega_0 ^2 = \frac{k}{m}$ y definimos $\frac{c}{m}\equiv 2\Gamma$, tendremos
\begin{equation}
\frac{d^2 x}{dt^2} + 2\Gamma \frac{dx}{dt}+ \omega_0^2 x = 0
\end{equation}
Subamortiguado
Si $\omega_0^2 > \Gamma^2$ se tiene movimiento oscilatorio subamortiguado.
Can you write Python code for it?


I am working on the file "Modulo1/Clase5_OsciladorAmortiguado.ipynb".
The first task is:
En resumen, se tiene entonces:
Can you write Python code for it?


I am working on the file "Modulo1/Clase5_OsciladorAmortiguado.ipynb".
The first task is:
Entonces, el primer caso que ya habíamos presentado corresponde a movimiento amortiguado.
Can you write Python code for it?


I am working on the file "Modulo1/Clase5_OsciladorAmortiguado.ipynb".
The first task is:
Sobreamortiguado
Si $\omega_0^2 < \Gamma^2$ se tiene movimiento oscilatorio sobreamortiguado.
Can you write Python code for it?


I am working on the file "Modulo1/Clase7_ModeloAhorro.ipynb".
The first task is:
Como se esperaba, el capital en el $k-$ésimo periodo $C_k=C_0(1+ki)$ crece linealmente con $k$.
Capitalización por interés compuesto
El capital que genera el interés simple permanece constante todo el tiempo de duración de la inversión. En cambio, el que produce el interés compuesto en un periodo se convierte en capital en el siguiente periodo. Esto es, el interés generado al final de un periodo se reinvierte para el siguiente periodo para también producir interés.
Suponga que se tiene un capital inicial $C_0$, y se va a ceder el uso de este capital por un periodo de tiempo determinado a una tasa de interés $i$. El capital que se obtiene al final del primer periodo $C_1$ se puede calcular por
$$C_1=C_0(1+i).$$
Si la anterior suma se vuelve a ceder a la misma tasa de interés, al final del periodo dos el capital $C_2$ es
$$C_2=C_1(1+i)=C_0(1+i)^2.$$
Si se repite el anterior proceso $k$ veces, el capital al final del $k-$ésimo periodo $C_k$ es
$$C_k=C_{k-1}(1+i)=C_0(1+i)^k.$$
Referencia:
- https://es.wikipedia.org/wiki/Inter%C3%A9s_compuesto.

Ejemplo. Suponga que se tiene un capital de \$10000 MXN, el cual se pone en un fondo de inversión que paga una tasa de interés del 0.8% mensual.
Si se tiene una meta de ahorro de \$11000 MXN sin inversiones adicionales, ¿cuántos meses se debería dejar invertido el dinero?
Muestre una gráfica que ilustre la situación.
Can you write Python code for it?

def interes_compuesto(C_0, meta, i):
    # Despejamos k
    k = np.ceil(np.log(meta/C_0)/np.log(1+i))
    k = k.astype(int)
    C_k = C_0*(1+i)**k                      # Cálculo del capital al final del periodo k
    C_k = round(C_k,2)                      # Redondeo con dos cifras decimales
    # Vector de periodos
    kk = np.linspace(0,k,k+1)
    # Vector de capitales por periodo
    CC = C_0*(1+i)**kk
    # Gráfico
    plt.figure(num=1); plt.clf()            # Figura 1, borrar lo que contenga
    plt.plot(kk, CC,'*',linewidth=3.0)      # Se grafica la evolución de los capitales
    plt.plot(kk,meta*np.ones(k+1),'--k')    # Se grafica la meta
    plt.xlabel('k')                         # Etiqueta eje x
    plt.ylabel('C_k')                       # Etiqueta eje y
    plt.grid(True)                          # Malla en la gráfica
    plt.show()                              # Mostrar la figura
    print("El número de periodos que se debe dejar invertido el dinero para llegar a la meta de ", meta," es ", k,
          ". Al final del periodo ", k,", el capital es ", C_k, ".", sep="")

interact_manual(interes_compuesto, C_0=fixed(10000), meta=(10000,12000,100), i=fixed(0.008));


I am working on the file "Modulo1/Clase7_ModeloAhorro.ipynb".
The first task is:
El capital en el $k-$ésimo periodo $C_k=C_0(1+i)^k$ crece de manera exponencial con $k$.

Actividad.
- Modificar el código anterior para dejar fija la meta de ahorro y variar la tasa de interés compuesta.

Capitalización continua de intereses
La capitalización continua se considera un tipo de capitalización compuesta, en la que a cada instante de tiempo $t$ se se capitalizan los intereses. Es decir, la frecuencia de capitalización es infinita (o, equivalentemente, el periodo de capitalización tiende a cero).
Suponga que se tiene un capital inicial $C_0$, y que el capital acumulado en el tiempo $t$ es $C(t)$. Queremos saber cuanto será el capital pasado un periodo de tiempo $\Delta t$, dado que la tasa de interés efectiva para este periodo de tiempo es $i$. De acuerdo a lo anterior tenemos
$$C(t+\Delta t)=C(t)(1+i)=C(t)(1+r\Delta t),$$
donde $r=\frac{i}{\Delta t}$ es la tasa de interés instantánea. Manipulando la anterior expresión, obtenemos
$$\frac{\log(C(t+\Delta t))-\log(C(t))}{\Delta t}=\frac{\log((1+r\Delta t))}{\Delta t}.$$
Haciendo $\Delta t\to 0$, obtenemos la siguiente ecuación diferencial
$$\frac{d C(t)}{dt}=r\; C(t),$$
sujeta a la condición inicial (monto o capital inicial) $C(0)=C_0$.
La anterior, es una ecuación diferencial lineal de primer orden, para la cual se puede calcular la solución analítica.
Can you write Python code for it?

# Librería de cálculo simbólico
import sympy as sym

# Para imprimir en formato TeX
from sympy import init_printing; init_printing(use_latex='mathjax')

# Símbolos t(para el tiempo) y r(para el interés instantáneo)
#t, r = sym.symbols('t r')
# Otra forma de hacer lo anterior
sym.var('t r')

C = sym.Function('C')

eqn = sym.Eq(sym.Derivative(C(t),t) - r*C(t), 0) # Ecuación diferencial
display(eqn) # Mostrar ecuación
sym.dsolve(eqn, C(t)) # Resolver


I am working on the file "Modulo1/Clase7_ModeloAhorro.ipynb".
The first task is:
Una gráfica que nos permite ilustrar la situación anterior se puede realizar de la siguiente manera.
Can you write Python code for it?

# Librerías para gráficos
import matplotlib.pyplot as plt
# Para que se muestren las gráficas en la misma ventana
%matplotlib inline
# Librería para widgets de jupyter
from ipywidgets import *

def interes_simple(C_0, meta, i):
    # Despejamos k
    k = np.ceil((meta/C_0 - 1)/i)           # Notar el uso de la función ceil
    k = k.astype(int)                       # Conversión a entero
    C_k = C_0*(1+k*i)                       # Cálculo del capital al final del periodo k
    C_k = round(C_k, 2)                     # Redondeo con dos cifras decimales
    # Vector de periodos
    kk = np.linspace(0,k,k+1)
    # Vector de capitales por periodo
    CC = C_0*(1+kk*i)
    # Gráfico
    plt.figure(num=1); plt.clf()            # Figura 1, borrar lo que contenga
    plt.plot(kk, CC,'*',linewidth=3.0)      # Se grafica la evolución de los capitales
    plt.plot(kk,meta*np.ones(k+1),'--k')    # Se grafica la meta
    plt.xlabel('k')                         # Etiqueta eje x
    plt.ylabel('C_k')                       # Etiqueta eje y
    plt.grid(True)                          # Malla en la gráfica
    plt.show()                              # Mostrar la figura
    print("El número de periodos que se debe dejar invertido el dinero para llegar a la meta de ", meta," es ", k,
          ". Al final del periodo ", k,", el capital es ", C_k, ".", sep="")

interact_manual(interes_simple, C_0=fixed(10000), meta=(10000,12000,100), i=fixed(0.008));


I am working on the file "Modulo1/Clase7_ModeloAhorro.ipynb".
The first task is:
Ver que lo anterior es una aproximación continua del modelo discreto de interés continuo cuando la frecuencia de capitalización tiende a infinito

Tabla de abonos
Como aplicación importante del concepto de interés compuesto se encuentra la creación de un modelo de cuenta de ahorro.
Referencia:
- Vidaurri Aguirre, Héctor Manuel. Ingeniería económica básica, ISBN: 978-607-519-017-4. (Disponible en biblioteca)
- http://pbpython.com/amortization-model.html
Can you write Python code for it?

# Librería de análisis de datos
import pandas as pd
# Librería para manipulación de fechas
from datetime import date

# Datos para la cuenta de ahorro
Tasa_interes = 0.1
Anos = 2
Abonos_ano = 12
Inicial = 10000
Meta = 100000
fecha_inicio = (date(2018,1,31))

# Cálculo de abonos mensuales iguales para llegar a la meta de ahorro en el tiempo deseado
Abono = (Tasa_interes/Abonos_ano)*(Meta - Inicial*(1+Tasa_interes/Abonos_ano)**(Anos*Abonos_ano))/((1+Tasa_interes/Abonos_ano)**(Anos*Abonos_ano)-1)

# Rango de fechas en la tabla
rng = pd.date_range(fecha_inicio, periods=Anos*Abonos_ano, freq='MS')
rng.name = "Fecha del abono"

# Columnas de abonos y extracto de cuenta en las fechas respectivas
df = pd.DataFrame(index=rng,columns=['Abono', 'Balance'], dtype='float')

# Para poner el indice con los periodos y no con las fechas
df.reset_index(inplace=True)
df.index += 1
df.index.name = "Periodo"  # Columna correspondiente al periodo

# Los abonos son iguales
df["Abono"] = Abono

# Vector indizador de los periodos de los abonos
index_vector = np.arange(1,len(rng)+1)
# Extracto de la cuenta mes a mes
df["Balance"] = Inicial*(1+Tasa_interes/Abonos_ano)**index_vector+Abono*(((1+Tasa_interes/Abonos_ano)**index_vector-1)/(Tasa_interes/Abonos_ano))

# Redondear con dos cifras decimales
df = df.round(2)
df

# La siguiente solución es también válida. Sin embargo, evitar el uso de 'for'

#df.loc[1, "Balance"] = Inicial*(1+Tasa_interes/Abonos_ano)**1 + df.loc[1, "Abono"]

#for i in range(2, len(df)+1):
#    # Get the previous balance as well as current payments
#    prev_balance = df.loc[i-1, "Balance"]

#    df.loc[i, "Balance"] = prev_balance*(1+Tasa_interes/Abonos_ano)**1 + df.loc[i, "Abono"]

df.plot()


I am working on the file "Modulo1/Clase7_ModeloAhorro.ipynb".
The first task is:
con $C_1=C_0$.
La equivalencia entre la tasa de interés compuesta $i$ y la tasa de interés instantánea $r$ viene dada por
$$e^r=1+i.$$

¿Cómo podemos calcular la solución numérica?
Can you write Python code for it?

# Librerías para integración numérica
from scipy.integrate import odeint

# Modelo de capitalización continua
def cap_continua(C, t, r):
    return r * C

def interes_continuo(C_0, meta, r):
    # Despejamos t
    t = np.log(meta/C_0)/r
    # Vector de periodos
    tt = np.linspace(0,t,100)
    # Vector de capitales por periodo
    CC = odeint(cap_continua, C_0, tt, args = (r,))
    # Gráfico
    plt.figure(num=1); plt.clf()                # Figura 1, borrar lo que contenga
    plt.plot(tt, CC,'-',linewidth=3.0)          # Se grafica la evolución de los capitales
    plt.plot(tt,meta*np.ones(len(tt)),'--k')    # Se grafica la meta
    plt.xlabel('t')                             # Etiqueta eje x
    plt.ylabel('C(t)')                          # Etiqueta eje y
    plt.grid(True)                              # Malla en la gráfica
    plt.show()                                  # Mostrar la figura

interact_manual(interes_continuo, C_0=fixed(10000), meta=(10000,20000,100), r=fixed(np.log(1+i)));


I am working on the file "Modulo1/Clase8_MembranaCircular.ipynb".
The first task is:
Ahhh! el integrando es cero, entonces este termino también es cero.
\begin{equation}
u(r,\theta, t) = \sum_{k = 1}^{\infty} a_{0k}J_{0}(\lambda_{0k} r)\cos{(v\lambda_{0k}t)}
\end{equation}
Can you write Python code for it?


I am working on the file "Modulo1/Clase8_MembranaCircular.ipynb".
The first task is:
Ahora $b_{nk}$.
Can you write Python code for it?

integrand_b = f * sym.besselj(n, lamb(n,k) * r) * sym.sin(n *theta) * r
integrand_b

bnk = sym.Integral(integrand_b, (r, 0, 1), (theta, 0, 2*sym.pi))
bnk

solution_bnk = bnk.doit()
solution_bnk


I am working on the file "Modulo1/Clase8_MembranaCircular.ipynb".
The first task is:
Ahora, tal vez nos interesaría conocer el comportamiento de la membrana cuando sumamos sobre un conjunto de modos $k$. Es decir,
$$u(r,\theta, t){n} =\sum{k = 1}u(r,\theta, t){nk} =  \sum{k = 1}J_{n}(\lambda_{nk} r)\,\cos(n\theta)\,\cos(\lambda_{nk} v t) $$
La manera usual de hacer esto es considerar la suma en series de Fourier, es decir a esta suma le falta un coeficiente $A_{nk}$, pero por simplicidad aquí no vamos a considerar este término.
Una posible función para realizar esto sería,
Can you write Python code for it?

def tambor_n_allk(n, r_max, v, nk_zeros, t):
    r = np.r_[0:r_max:100j]
    angle = np.r_[0:2*np.pi:200j]
    ceros = special.jn_zeros(0, nk_zeros)
    lamb = ceros[0]
    u0 = np.array([special.jn(n, lamb* var_r) * np.cos(n * angle)
                  * np.cos(lamb * v * t) for var_r in r])
    for cero in range(1, nk_zeros):
        lamb = ceros[cero]
        u = np.array([special.jn(n, lamb* var_r) * np.cos(n * angle)
                 * np.cos(lamb * v * t) for var_r in r])
        u0 += u
    x = np.array([var_r * np.cos(angle) for var_r in r])
    y = np.array([var_r * np.sin(angle) for var_r in r])
    return x, y, u0

def tambor_n(t = 0, n = 0):
    fig = plt.figure(figsize = (6,5))
    ax = fig.add_subplot(1, 1, 1)
    x, y, u = tambor_n_allk(n, 1, 1, 15, t)
    im = ax.pcolor(x, y, u, cmap = 'viridis')
    ax.set_xlim(xmin = -1.1, xmax = 1.1)
    ax.set_ylim(ymin = -1.1, ymax = 1.1)
    plt.colorbar(im)
    plt.axis('off')
    fig.canvas.draw()
interact_manual(tambor_n, t = (0, 15,.01), n = (0, 10, 1));


I am working on the file "Modulo1/Clase8_MembranaCircular.ipynb".
The first task is:
Ahora, veamos como lucen todos demás modos de vibración $(n,k)$.
Can you write Python code for it?

def tambor_nk(t = 0, n = 0, kth=0):
    fig = plt.figure(figsize = (6,5))
    ax = fig.add_subplot(1, 1, 1)
    x, y, u = tambor(n, 1, 1, kth, 15, t)
    im = ax.pcolor(x, y, u, cmap = 'viridis')
    ax.set_xlim(xmin = -1.1, xmax = 1.1)
    ax.set_ylim(ymin = -1.1, ymax = 1.1)
    plt.colorbar(im)
    plt.axis('off')
    fig.canvas.draw()
interact_manual(tambor_nk, t = (0, 15,.01), n = (0, 10, 1), kth = (0, 10, 1));


I am working on the file "Modulo1/Clase8_MembranaCircular.ipynb".
The first task is:
Dado que la rapidez inicial es cero, entonces $a^{}_{nk} = b^{}_{nk} = 0$, y la solución para el desplazamiento en el tiempo es simplemente,
\begin{equation}
u(r,\theta, t) = \sum_{n=0}^{\infty}\sum_{k = 1}^{\infty}J_{n}(\lambda_{nk} r)(a_{nk}\cos{n\theta} + b_{nk}\sin{n\theta})\cos{(v\lambda_{nk}t)}
\end{equation}
Entonces, solo será necesario encontrar $a_{nk}$ y $b_{nk}$.
\begin{align}
a_{0k} &= \frac{1}{\pi a^2 J_{1}^{2}(\alpha_{0k})}\int_{0}^{2\pi}\int_{0}^{a}\; f(r,\theta)\, J_{0}(\lambda_{0k}r)\, r \, dr \, d\theta\
a_{nk} &= \frac{2}{\pi a^2 J_{n+1}^{2}(\alpha_{nk})}\int_{0}^{2\pi}\int_{0}^{a}\; f(r,\theta)\, J_{n}(\lambda_{nk}r)\cos(n\theta)\, r \, dr \, d\theta\
b_{nk} &= \frac{2}{\pi a^2 J_{n+1}^{2}(\alpha_{nk})}\int_{0}^{2\pi}\int_{0}^{a}\; f(r,\theta)\, J_{n}(\lambda_{nk}r)\sin(n\theta)\, r \, dr \, d\theta
\end{align}
Para resolver estas integrales haremos uso de SymPy.
Iniciemos con $a_{nk}$.
Can you write Python code for it?

# Para imprimir con fotmato LaTeX
from sympy import init_printing; init_printing(use_latex='mathjax')
import sympy as sym

sym.var('r theta', real = True)
#r, theta, k  = sym.symbols('r theta k')
r, theta

sym.var('n k', positive = True, integer=True)
#n, k = sym.symbols('n k', positive = True, integer=True)
n, k

def lamb(n,k):
    return sym.Symbol('lambda_%s%s'%(n,k), positive = True, real = True)

lamb(0,k)

f = 1 - r**4; f

integrand = f * sym.besselj(n, lamb(n,k) * r) * sym.cos(n *theta) * r
integrand

ank = sym.Integral(integrand, (r, 0, 1), (theta, 0, 2*sym.pi))
ank

solution_ank = ank.doit()
solution_ank


I am working on the file "Modulo1/Clase8_MembranaCircular.ipynb".
The first task is:
Entonces para cualquier $n>0$ no se tiene contribución.
Evaluamos entonces $a_{0k}$.
Can you write Python code for it?

integ = lambda n: f * sym.besselj(n, lamb(n,k) * r) * sym.cos(n*theta) * r

integ(0)

a0k = sym.Integral(integ(0), (r, 0, 1), (theta, 0, 2*sym.pi))
a0k

solution_a0k = a0k.doit()
solution_a0k

a0k_solution = solution_a0k/(sym.pi*sym.besselj(1, lamb(0,k))**2)
a0k_solution

sym.simplify(a0k_sol)


I am working on the file "Modulo1/Clase8_MembranaCircular.ipynb".
The first task is:
Entonces para cualquier $n>0$ no se tiene contribución.
Segundo caso $n=0$
Can you write Python code for it?

integ = lambda n: f * sym.besselj(n, lamb(n,k) * r) * sym.cos(n*theta) * r

integ(0)

a0k = sym.Integral(integ(0), (r, 0, 1), (theta, 0, 2*sym.pi))
a0k

a0k_solution = a0k.doit()
a0k_solution

a0k_sol = 1/(sym.pi*sym.besselj(1, lamb(0,k))**2)*a0k_solution
a0k_sol

sym.simplify(a0k_sol)


I am working on the file "Modulo1/Clase8_MembranaCircular.ipynb".
The first task is:
Entonces, por ejemplo si $n = 1$, $a = 1$, $v = 1$,  $k = 1$ y $t= 0$. Este sería el modo de vibración $(n,k)\rightarrow (1,1)$.
Can you write Python code for it?

x, y, u = tambor(1, 1, 1, 0, 15, 0)

plt.figure(figsize = (6, 5))
plt.pcolor(x, y, u, cmap = 'viridis')
plt.axis('off')
plt.colorbar()
plt.show()


I am working on the file "Modulo1/Clase8_MembranaCircular.ipynb".
The first task is:
Fíjise bien, la condición inicial en $t = 0$, se cumple para la  solución encontrada.
Tarea

Problema 1. Suponga que $a = 1$, $v = 1$ y que las condiciones iniciales son:

$$ f(r,\theta) = (1- r^4)\cos(\theta)\quad\quad g(r,\theta) = 0$$

Problema 2. uponga que $a = 2$, $v = 1$ y que las condiciones iniciales son:
$$ f(r,\theta) = 0 \quad\quad g(r,\theta) = r^2(2- r)\sin^8\left(\frac{\theta}{2}\right)$$

Fin Modulo 1
Versión antigua (Lo único que tal vez sirva de algo, son los programas)
Tal vez sirvan de algo para sus tareas.
Entonces, primero veamos algunos modos normales del sistema. Por ejemplo(demasiado simplificado),
$$u(r,\theta, t){nk} = J{n}(\lambda_{nk} r)\,\cos(n\theta)\,\cos(\lambda_{nk} v t)$$
La siguiente función se aplica caso simplificado.
Can you write Python code for it?

def tambor(n, r_max, v, kth_zero, nt, t):
    r = np.r_[0:r_max:100j]
    angle = np.r_[0:2*np.pi:200j]
    ceros = special.jn_zeros(0, nt)
    lamb = ceros[kth_zero]
    u = np.array([special.jn(n, lamb* var_r) * np.cos(n * angle)
                 * np.cos(lamb * v * t) for var_r in r])
    x = np.array([var_r * np.cos(angle) for var_r in r])
    y = np.array([var_r * np.sin(angle) for var_r in r])
    return x, y, u


I am working on the file "Modulo1/Clase8_MembranaCircular.ipynb".
The first task is:
Por último, nos queda el caso cuando sumamos sobre todos los modos $n$. Es decir,
Can you write Python code for it?

def order_n(n, ceros, nk_zeros, angle, v, r, t):
    lamb = ceros[0]
    u0 = np.array([special.jn(n, lamb* var_r) * np.cos(n * angle)
                      * np.cos(lamb * v * t) for var_r in r])
    for cero in range(1, nk_zeros):
        lamb = ceros[cero]
        u = np.array([special.jn(n, lamb* var_r) * np.cos(n * angle)
                     * np.cos(lamb * v * t) for var_r in r])
        u0 += u
    return u0

def tambor(orden_n, r_max, v, nk_zeros, t):
    r = np.r_[0:r_max:100j]
    angle = np.r_[0:2*np.pi:100j]
    ceros = special.jn_zeros(0, nk_zeros)
    u0 = order_n(0, ceros, nk_zeros,  angle, v, r, t)
    for n in range(1, orden_n):
        u = order_n(n, ceros, nk_zeros, angle, v, r, t)
        u0 += u
    x = np.array([var_r * np.cos(angle) for var_r in r])
    y = np.array([var_r * np.sin(angle) for var_r in r])
    return x, y, u0

x, y, u = tambor(10, 1, 1, 5, 5)

plt.figure(figsize = (5, 5))
plt.pcolor(x, y, u, cmap = 'inferno')
plt.axis('on')
plt.show()


I am working on the file "Modulo1/Clase8_MembranaCircular.ipynb".
The first task is:
Primero vamos a programar para algún modo $k$.
Can you write Python code for it?

def a0k_sym(lambd):
    solucion = (-8*special.jn(0, lambd)/lambd**2
    +32*special.jn(1, lambd)/lambd**3 +
     64*special.jn(0, lambd)/lambd**4 -
        128*special.jn(1, lambd)/lambd**5)/special.jn(1, lambd)**2
    return solucion

def tambor(v, kth_zero, nt, t):
    r = np.r_[0:1:100j]
    angle = np.r_[0:2*np.pi:200j]
    ceros = special.jn_zeros(0, nt)
    lambd = ceros[kth_zero]
    u_r = a0k_sym(lambd)*special.jn(0, lambd * r) * np.cos(lambd * v * t)
    u = np.array([np.full(len(angle), u_rs) for u_rs in u_r])
    x = np.array([var_r * np.cos(angle) for var_r in r])
    y = np.array([var_r * np.sin(angle) for var_r in r])
    return x, y, u

x1, y1, u1 = tambor(1, 0, 15, 7)

plt.figure(figsize = (6, 5))
plt.pcolor(x1 , y1 , u1, cmap = 'viridis')
plt.axis('off')
plt.colorbar()
plt.show()

def tambor_nk(t = 0, kth=0):
    fig = plt.figure(figsize = (6,5))
    ax = fig.add_subplot(1, 1, 1)
    x, y, u = tambor(1, kth, 50, t)
    im = ax.pcolor(x, y, u, cmap = 'viridis')
    ax.set_xlim(xmin = -1.1, xmax = 1.1)
    ax.set_ylim(ymin = -1.1, ymax = 1.1)
    plt.colorbar(im)
    plt.axis('off')
    fig.canvas.draw()
interact_manual(tambor_nk, t = (0, 15,.01), n = (0, 10, 1), kth = (0, 10, 1));

def tambor_nk(t = 0, kth=0):
    fig = plt.figure(figsize = (6,5))
    ax = fig.add_subplot(1, 1, 1)
    x, y, u = tambor(1, kth, 50, t)
    im = ax.pcolor(x, y, u, cmap = 'viridis', vmax = 1.2, vmin = -1.2)
    ax.set_xlim(xmin = -1.1, xmax = 1.1)
    ax.set_ylim(ymin = -1.1, ymax = 1.1)
    plt.colorbar(im)
    plt.axis('off')
    fig.canvas.draw()
interact(tambor_nk, t = (0, 15,.01), n = (0, 10, 1), kth = (0, 10, 1));


def a0k_sym(lambd):
    solucion = 2*(-4*special.jn(0, lambd)/lambd**2
    +16*special.jn(1, lambd)/lambd**3 +
     32*special.jn(0, lambd)/lambd**4 -
        64*special.jn(1, lambd)/lambd**5)/special.jn(1, lambd)**2
    return solucion

def tambor(v, kth_zero, nt, t):
    r = np.r_[0:1:100j]
    angle = np.r_[0:2*np.pi:200j]
    ceros = special.jn_zeros(0, nt)
    lambd = ceros[kth_zero]
    u_r = a0k_sym(lambd)*special.jn(0, lambd * r) * np.cos(lambd * v * t)
    u = np.array([np.full(len(angle), u_rs) for u_rs in u_r])
    x = np.array([var_r * np.cos(angle) for var_r in r])
    y = np.array([var_r * np.sin(angle) for var_r in r])
    return x, y, u

x1, y1, u1 = tambor(1, 0, 15, 7)

plt.figure(figsize = (6, 5))
plt.pcolor(x1 , y1 , u1, cmap = 'viridis')
plt.axis('off')
plt.colorbar()
plt.show()

def tambor_nk(t = 0, kth=0):
    fig = plt.figure(figsize = (6,5))
    ax = fig.add_subplot(1, 1, 1)
    x, y, u = tambor(1, kth, 50, t)
    im = ax.pcolor(x, y, u, cmap = 'viridis')
    ax.set_xlim(xmin = -1.1, xmax = 1.1)
    ax.set_ylim(ymin = -1.1, ymax = 1.1)
    plt.colorbar(im)
    plt.axis('off')
    fig.canvas.draw()
interact_manual(tambor_nk, t = (0, 15,.01), kth = (0, 10, 1));


I am working on the file "Modulo1/Clase8_MembranaCircular.ipynb".
The first task is:
Y ahora, la solución completa.
No podemos sumar infinitos términos. Pero sí tantos como queramos...
Can you write Python code for it?

def tambor_n_allk(v, nk_zeros, t):
    r = np.linspace(0, 1, 100)
    angle = np.linspace(0, 2*np.pi, 200)
    ceros = special.jn_zeros(0, nk_zeros)
    lambd = ceros[0]
    u_r = a0k_sym(lambd)*special.jn(0, lambd * r) * np.cos(lambd * v * t)
    u0 = np.array([np.full(len(angle), u_rs) for u_rs in u_r])
    for cero in range(1, nk_zeros):
        lambd = ceros[cero]
        u_r = a0k_sym(lambd)*special.jn(0, lambd * r) * np.cos(lambd * v * t)
        u = np.array([np.full(len(angle), u_rs) for u_rs in u_r])
        u0 += u
    x = np.array([var_r * np.cos(angle) for var_r in r])
    y = np.array([var_r * np.sin(angle) for var_r in r])
    return x, y, u0

def tambor_0(t = 0):
    fig = plt.figure(figsize = (6,5))
    ax = fig.add_subplot(1, 1, 1)
    x, y, u = tambor_n_allk(1, 15, t)
    im = ax.pcolor(x, y, u, cmap = 'viridis')
    ax.set_xlim(xmin = -1.1, xmax = 1.1)
    ax.set_ylim(ymin = -1.1, ymax = 1.1)
    plt.colorbar(im)
    plt.axis('off')
    fig.canvas.draw()
interact_manual(tambor_0, t = (0, 15,.01));


I am working on the file "Modulo1/Clase8_MembranaCircular.ipynb".
The first task is:
Y para $b_{nk}$
Can you write Python code for it?

integrand_b = f * sym.besselj(n, lamb(n,k) * r) * sym.sin(n *theta) * r
integrand_b

bnk = sym.Integral(integrand_b, (r, 0, 1), (theta, 0, 2*sym.pi))
bnk

solution_b = bnk.doit()
solution_b


I am working on the file "Modulo1/Clase9_Repaso1(Mod.1).ipynb".
The first task is:
Con estas condiciones iniciales, evidenciamos que las ovejas se extinguen y que los conejos alcanzan su máxima capacidad de población.
Can you write Python code for it?

# tercer condición inicial
x0 = [1.5, 1]
tt = np.linspace(0, 10, 100)
xx = odeint(lotka_volterra, x0, tt)
x1 = xx[:, 0]
x2 = xx[:, 1]

# Graficas
plt.figure(figsize=(10,5))

plt.subplot(1,2,1)
plt.plot(tt, x1, '*g', label = 'conejos $x_1$')
plt.plot(tt, x2, '--r', label = 'ovejas $x_2$')
plt.grid()
plt.legend(loc = 'best')
plt.xlabel('$t$')
plt.ylabel('Población')

plt.subplot(1,2,2)
plt.plot(x1, x2, 'b', label = '(conejos,ovejas)')
plt.plot(x1[0], x2[0], 'oy', lw = 3, label = 'inicial')
plt.plot(x1[-1], x2[-1], 'ok', lw = 3, label = 'final')
plt.grid()
plt.legend(loc = 'best')
plt.xlabel('$x_1$ (conejos)')
plt.ylabel('$x_2$ (ovejas)')

plt.show()


# cuarta condición inicial
x0 = [1, 1.5]
tt = np.linspace(0, 10, 100)
xx = odeint(lotka_volterra, x0, tt)
x1 = xx[:, 0]
x2 = xx[:, 1]

# Graficas
plt.figure(figsize=(10,5))

plt.subplot(1,2,1)
plt.plot(tt, x1, '*g', label = 'conejos $x_1$')
plt.plot(tt, x2, '--r', label = 'ovejas $x_2$')
plt.grid()
plt.legend(loc = 'best')
plt.xlabel('$t$')
plt.ylabel('Población')

plt.subplot(1,2,2)
plt.plot(x1, x2, 'b', label = '(conejos,ovejas)')
plt.plot(x1[0], x2[0], 'oy', lw = 3, label = 'inicial')
plt.plot(x1[-1], x2[-1], 'ok', lw = 3, label = 'final')
plt.grid()
plt.legend(loc = 'best')
plt.xlabel('$x_1$ (conejos)')
plt.ylabel('$x_2$ (ovejas)')

plt.show()


I am working on the file "Modulo1/Clase9_Repaso1(Mod.1).ipynb".
The first task is:
Con estas condiciones iniciales, evidenciamos que los conejos se extinguen y que las ovejas alcanzan su máxima capacidad de población.
Can you write Python code for it?

# cuarta condición inicial
x0 = [1, 1]
tt = np.linspace(0, 10, 100)
xx = odeint(lotka_volterra, x0, tt)
x1 = xx[:, 0]
x2 = xx[:, 1]

# Graficas
plt.figure(figsize=(10,5))

plt.subplot(1,2,1)
plt.plot(tt, x1, '*g', label = 'conejos $x_1$')
plt.plot(tt, x2, '--r', label = 'ovejas $x_2$')
plt.grid()
plt.legend(loc = 'best')
plt.xlabel('$t$')
plt.ylabel('Población')

plt.subplot(1,2,2)
plt.plot(x1, x2, 'b', label = '(conejos,ovejas)')
plt.plot(x1[0], x2[0], 'oy', lw = 3, label = 'inicial')
plt.plot(x1[-1], x2[-1], 'ok', lw = 3, label = 'final')
plt.grid()
plt.legend(loc = 'best')
plt.xlabel('$x_1$ (conejos)')
plt.ylabel('$x_2$ (ovejas)')

plt.show()


I am working on the file "Modulo1/Clase9_Repaso1(Mod.1).ipynb".
The first task is:
Con estas condiciones, la solución numérica nos muestra que la población tiende a su capacidad máxima cuando $t\to\infty$.
Can you write Python code for it?

# Numeral 3
plt.figure(figsize=(6,4))
for r in np.arange(-1,1.1,0.5):
    xx = odeint(logistica, x0, tt)
    plt.plot(tt, xx, linewidth = 3, label = 'r=%f'%r)

plt.xlabel('Tiempo $t$')
plt.ylabel('Poblacion $x(t)$')
plt.legend(loc='center left', bbox_to_anchor=(1.05,0.5))
plt.grid()

plt.show()


I am working on the file "Modulo1/Clase9_Repaso1(Mod.1).ipynb".
The first task is:
De la gráfica podemos inferir que la población crece hasta su capacidad máxima para $r>0$, se extingue para $r<0$ y permanece constante para $r=0$.

Ejemplo 2. Conejos vs. Ovejas.
Imaginemos que en un mismo ecosistema se encuentran conejos y ovejas. Supongamos, además, que ambas compiten por el mismo alimento (hierba) y que la cantidad total de alimento es limitada. Se ignoran otros factores como depredadores, efectos de temporada (estaciones), y otras fuentes de comida. El modelo de competición entre dos especies Lotka-Volterra nos sirve para describir este fenómeno.
Dos fenómenos importantes:
- Cada especie crecería hasta su capacidad máxima en ausencia de la otra especie. Esto se puede modelar con la ecuación logística para cada especie. Los conejos tienen una habilidad soprendente para reproducirse, entonces comparativamente deberían crecer más.
- Cuando conejos y ovejas se encuentran, empieza la competencia. Algunas veces los conejos comen, pero las ovejas (al ser más grandes) ganarán el derecho a la comida la mayoría de las veces. Supondremos que dichos conflictos se dan a una tasa proporcional al tamaño de cada población (si hay dos veces más ovejas, la probabilidad de que un conejo encuentre a una oveja será el doble). Supondremos que dicha competencia disminuirá la tasa de crecimiento para cada especie, y el efecto será mayor para los conejos.
Con las consideraciones anteriores, un modelo específico es:
\begin{align}
\frac{dx_1}{dt} &= x_1(3-x_1-2x_2)\
\frac{dx_2}{dt} &= x_2(2-x_2-x_1),
\end{align}
donde $x_1(t)\geq 0$ es la población de conejos al instante $t$ y $x_2(t)\geq 0$ es la población de ovejas al instante $t$. Definimos $x=\left[x_1\quad x_2\right]^T$.
Esta selección de coeficientes se tiene para recrear el escenario descrito. Sin embargo, este modelo se puede utilizar para estudiar competición entre especies en general y los coeficientes cambiarán en cada caso.
Simule el sistema para cada una de las siguientes condiciones iniciales. Para cada caso, obtenga gráficas de $x_1$ vs. $t$, $x_2$...
Can you write Python code for it?

# importar librerías
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint

# definimos modelo lotka volterra
def lotka_volterra(x, t):
    x1 = x[0]
    x2 = x[1]
    return [x1*(3-x1-2*x2), x2*(2-x2-x1)]

# primer condición inicial
x0 = [0.5, 1]
tt = np.linspace(0, 10, 100)
# solucion numerica
xx = odeint(lotka_volterra, x0, tt)

xx.shape

x1 = xx[:, 0]
x2 = xx[:, 1]

# Graficas
plt.figure(figsize=(10,5))

plt.subplot(1,2,1)
plt.plot(tt, x1, '*g', label = 'conejos $x_1$')
plt.plot(tt, x2, '--r', label = 'ovejas $x_2$')
plt.grid()
plt.legend(loc = 'best')
plt.xlabel('$t$')
plt.ylabel('Población')

plt.subplot(1,2,2)
plt.plot(x1, x2, 'b', label = '(conejos,ovejas)')
plt.plot(x1[0], x2[0], 'oy', lw = 3, label = 'inicial')
plt.plot(x1[-1], x2[-1], 'ok', lw = 3, label = 'final')
plt.grid()
plt.legend(loc = 'best')
plt.xlabel('$x_1$ (conejos)')
plt.ylabel('$x_2$ (ovejas)')

plt.show()


I am working on the file "Modulo2/.ipynb_checkpoints/Clase10_IntroMontecarlo-checkpoint.ipynb".
The first task is:
Actividad. Graficar, en una misma ventana de gráficos, al menos ocho caminatas aleatorias de 100 pasos.
Can you write Python code for it?


I am working on the file "Modulo2/.ipynb_checkpoints/Clase11_SimulacionMontecarlo-checkpoint.ipynb".
The first task is:
Ejemplo
Ahora recapitulemos el ejemplo básico del apostador.
Referencia:
- https://pythonprogramming.net/monte-carlo-simulator-python/
Supongamos que estamos en un casino especial, donde el usuario puede tirar un dado metafórico que puede dar como resultado del número uno (1) al número cien (100).
Si el usuario tira cualquier número entre 1 y 50, el casino gana. Si el usuario tira cualquier número entre 51 y 99, el usuario gana. Si el usuario tira 100, pierde.
Con esto, el casino mantiene un margen del 1\%, el cual es mucho más pequeño que el margen típico en casinos, al igual que el margen de mercado cuando se incorporan costos por transacción.
Por ejemplo, Scottrade cobra \$7 USD por transacción. Si se invierten \$1000 USD por acción, esto significa que tienes que pagar \$7 USD para entrar, y \$7 USD para salir, para un total de \$14 USD.
Esto pone el margen en 1.4\%. Esto significa, que a largo plazo, las ganancias tienen que ser mayores a 1.4\% en promedio, de otra manera se estará perdiendo dinero. Aunque este porcentaje es pequeño, las probabilidades ya están en contra. La comercialización de acciones es un juego 50/50, especialmente en el corto plazo.
De nuevo, con nuestro ejemplo en mente, 1-50, la casa gana. 51-99 el usuario gana. Un 100 significa que la casa gana.
Ahora, comencemos. Primero tenemos que crear nuestro dado.
Can you write Python code for it?

# Explorar función randint de la librería random y crear una función que simule la tirada de un dado

# Tirar el dado 100 veces para comprobar que nuestra función si trabaja correctamente


I am working on the file "Modulo2/.ipynb_checkpoints/Clase16_ProbabilidadPrecio-Umbral-checkpoint.ipynb".
The first task is:
3. Proyección de precios de cierre
Por tanto, para calcular los precios, tenemos:
$$\begin{align}
p_i&=p_{i-1}\exp(r_i)\
p_{i+1}&=p_i\exp(r_{i+1})=p_{i-1}\exp(r_i)\exp(r_{i+1})=p_{i-1}\exp(r_i+r_{i+1})\
&\vdots\
p_{i+k}&=p_{i-1}\exp(r_i+\cdots+r_{i+k}).
\end{align}$$
Si hacemos $i=0$ en la última ecuación, tenemos que $p_{k}=p_{-1}\exp(r_0+\cdots+r_{k})$, donde $p_{-1}$ es el último precio reportado en el 2016.
Can you write Python code for it?

# Función de proyección de precios

# Proyección de precios y concatenación con precios de 2016

# Gráfico


I am working on the file "Modulo2/.ipynb_checkpoints/Clase16_ProbabilidadPrecio-Umbral-checkpoint.ipynb".
The first task is:
4. Probabilidad Precio-Umbral
Ya que tenemos muchos escenarios de precios proyectados, podemos ver varias cosas. Por ejemplo, ¿cuál es la probabilidad de que el precio de cierre sobrepase algún valor umbral en algún momento?
Can you write Python code for it?

K = 65
dates = pd.date_range('20170101',periods=ndays)
strike = pd.DataFrame({'Strike':K*np.ones(ndays)},index=dates)
simul = pd.concat([closes.T,simdata.T,strike.T]).T
simul.plot(figsize=(8,6),legend=False);

strike = pd.DataFrame(K*np.ones(ndays*ntraj).reshape((ndays,ntraj)),index=dates)
count = simdata>strike
prob = count.T.sum()/ntraj
prob.plot(figsize=(8,6),legend=False);

((K-closes.iloc[-1,:])/closes.iloc[-1,:]).values


I am working on the file "Modulo2/.ipynb_checkpoints/Clase16_ProbabilidadPrecio-Umbral-checkpoint.ipynb".
The first task is:
Habiendo caracterizado los rendimientos diarios como una variable aleatoria normal con la media y la varianza muestral obtenida de los datos del 2016, podemos generar números aleatorios con estas características para simular el comportamiento de los precios de cierre de las acciones en el 2017 (hay un supuesto de que las cosas no cambiarán fundamentalmente).
Sin embargo, cada simulación que hagamos nos conducirá a distintos resultados (los precios siguen evolucionando aleatoriamente). Entonces, lo que haremos es simular varios escenarios para así ver alguna tendencia y tomar decisiones.
Hagamos una una función que simule varios escenarios de rendimientos diarios rendimientos diarios y que devuelva un dataframe con esta simulación.
Can you write Python code for it?

# Función que simula varios escenarios de rendimientos diarios

# Simulamos 100 escenarios para todoo el 2017