在 Python 中实现差分(非微分)方程
Implementing difference (NOT differential) equations in Python
我正在尝试在 Python 中实现差分方程。这些采用 yn+1 = a * yn + b 的形式,给定 y0 其中y0 是初始值,它会迭代——意思是
y1 = a * y0 + b,
y2 = a * y1 + b,
...
一个示例问题(来自我的微积分class)是这样的:
假设您借了 60,000 美元的贷款,并计划以 1.2% 的利率每月偿还 700 美元。 5年后还剩多少? yn+1 = 1.1 * yn - 700, y0 = 60,000
我理解 Python 中的递归,例如,
i = 0
while i < 20:
i = i+1
但我不确定当下一次迭代需要上一次的值时如何处理它。
您的任务的常规循环如下所示:
loan = 60000
annualinterest = 1.2/100
monthlyinterest = annualinterest/12
monthlyfactor = 1+monthlyinterest
monthlypackback = 700
for month in range(5*12):
loan = loan * monthlyfactor - monthlypackback
print(month+1, "{0:.2f}".format(loan))
请注意,monthlyinterest
可能会出于多种原因进行讨论,这些原因与编程无关:
a) 这可能取决于计算利息的时间,即每月的哪一天。那可能是在付款之前或之后。
b) 将年利率除以 12 对银行来说更好。它也可以计算为 1.012 的 12 次方根。
现在,上面是一个直接的循环。它与递归无关。但是可以转化为递归调用:
def recursive(loan, annualinterestPercentage, monthlyPayback, months):
if months == 0:
return loan
annualinterest = annualinterestPercentage / 100
monthlyinterest = annualinterest / 12
monthlyfactor = 1 + monthlyinterest
return recursive(loan * monthlyfactor - monthlyPayback, annualinterestPercentage, monthlyPayback, months - 1)
关键是:
a) 递归调用需要退出条件。我把它放在一开始。这里的退出条件是剩余月份达到0时。
b) 函数 recursive()
调用自身,希望带有一个指向退出条件的参数。这里是 month-1
.
你这样称呼它:
print(recursive(60000, 1.2, 700, 60))
def calc1():
S=60000
x=0.012
y=5*12
Pmt=700
r=1+(x/12)
Ln = S
for k in range(1, y+1):
Ln=(Ln*r)-Pmt
print (Ln)
结果:20444.98 美元
或使用定义为 sum of geometric progression
的代数
Ln= S * ry - Pmt * ((1-ry) / (1-r)) = $20444.98
抱歉,MathJax 不支持 Whosebug。
通常情况下,您可以通过存储一个包含计算得出的最后一个值的变量,然后用您的起始值作为种子来实现这一点。例如:
y = 60000
while True:
y = .1 * y - 700
当然,您必须确定何时停止以及如何处理这些值。你当然想打印它们:
y = 60000
while True:
y = .1 * y - 700
print(y)
但你可能只想做 100 次或更多次而不是永远:
y = 60000
for i in range(12*5):
y = .1 * y - 700
print("%d: %f" % (i,y))
您可能还想存储它们以备后用,因此请将它们放在一个数组中:
y = 60000
results=[]
for i in range(12*5):
y = .1 * y - 700
results.append(y)
print(results)
代码
按照你的要求使用递归:
def loan_calculator(y, payments, interest, monthly, period, counter=0, amount_left=[]):
# y -> starting loan (60,000)
# payments -> paying 0/month
# interest -> Interest rate on loan (yearly)
# monthly -> boolean, if monthly or yearly
# period -> how many years
# counter -> number of payments made
# amount_left -> after each payment how much is left to pay
if monthly:
period *= 12
interest /= (12*100)
# stopping condition:
if counter == period:
return y, amount_left
else:
y = (1+interest)*y - payments
amount_left.append(y)
counter += 1
return loan_calculator(y, 700, 1.2, True, 5, counter)
final_payment, all_payments = loan_calculator(6e4, 700, 1.2, True, 5)
print(all_payments)
print(final_payment)
输出
[59359.99999999999, 58719.359999999986, 58078.07935999998, 57436.15743935997, 56793.59359679933, 5615
0.38719039612, 55506.53757758651, 54862.04411516409, 54216.90615927925, 53571.12306543852, 52924.6941
88503956, 52277.618882692455, 51629.896501575146, 50981.52639807671, 50332.50792447478, 49682.8404323
9925, 49032.52327283165, 48381.555796104476, 47729.937351900575, 47077.66728925247, 46424.74495654172
, 45771.16970149826, 45116.94087119975, 44462.05781207095, 43806.51986988301, 43150.32638975289, 4249
3.476716142635, 41835.970192858775, 41177.80616305163, 40518.98396921468, 39859.50295318389, 39199.36
245613707, 38538.561818593196, 37877.100380411786, 37214.97748079219, 36552.192458272984, 35888.74465
0731256, 35224.633395381985, 34559.858028777366, 33894.41788680614, 33228.31230469295, 32561.54061699
7634, 31894.102157614627, 31225.996259772237, 30557.222256032004, 29887.779478288034, 29217.667257766
32, 28546.884925024082, 27875.431809949103, 27203.30724175905, 26530.510549000803, 25857.0410595498,
25182.898100609345, 24508.080998709953, 23832.58907970866, 23156.421668788367, 22479.578090457155, 21
802.057668547608, 21123.859726216153, 20444.983585942366] # This is a list of payments you owe each month
20444.983585942366 # This is your final payment
我正在尝试在 Python 中实现差分方程。这些采用 yn+1 = a * yn + b 的形式,给定 y0 其中y0 是初始值,它会迭代——意思是
y1 = a * y0 + b,
y2 = a * y1 + b,
...
一个示例问题(来自我的微积分class)是这样的: 假设您借了 60,000 美元的贷款,并计划以 1.2% 的利率每月偿还 700 美元。 5年后还剩多少? yn+1 = 1.1 * yn - 700, y0 = 60,000
我理解 Python 中的递归,例如,
i = 0
while i < 20:
i = i+1
但我不确定当下一次迭代需要上一次的值时如何处理它。
您的任务的常规循环如下所示:
loan = 60000
annualinterest = 1.2/100
monthlyinterest = annualinterest/12
monthlyfactor = 1+monthlyinterest
monthlypackback = 700
for month in range(5*12):
loan = loan * monthlyfactor - monthlypackback
print(month+1, "{0:.2f}".format(loan))
请注意,monthlyinterest
可能会出于多种原因进行讨论,这些原因与编程无关:
a) 这可能取决于计算利息的时间,即每月的哪一天。那可能是在付款之前或之后。
b) 将年利率除以 12 对银行来说更好。它也可以计算为 1.012 的 12 次方根。
现在,上面是一个直接的循环。它与递归无关。但是可以转化为递归调用:
def recursive(loan, annualinterestPercentage, monthlyPayback, months):
if months == 0:
return loan
annualinterest = annualinterestPercentage / 100
monthlyinterest = annualinterest / 12
monthlyfactor = 1 + monthlyinterest
return recursive(loan * monthlyfactor - monthlyPayback, annualinterestPercentage, monthlyPayback, months - 1)
关键是:
a) 递归调用需要退出条件。我把它放在一开始。这里的退出条件是剩余月份达到0时。
b) 函数 recursive()
调用自身,希望带有一个指向退出条件的参数。这里是 month-1
.
你这样称呼它:
print(recursive(60000, 1.2, 700, 60))
def calc1():
S=60000
x=0.012
y=5*12
Pmt=700
r=1+(x/12)
Ln = S
for k in range(1, y+1):
Ln=(Ln*r)-Pmt
print (Ln)
结果:20444.98 美元
或使用定义为 sum of geometric progression
的代数Ln= S * ry - Pmt * ((1-ry) / (1-r)) = $20444.98
抱歉,MathJax 不支持 Whosebug。
通常情况下,您可以通过存储一个包含计算得出的最后一个值的变量,然后用您的起始值作为种子来实现这一点。例如:
y = 60000
while True:
y = .1 * y - 700
当然,您必须确定何时停止以及如何处理这些值。你当然想打印它们:
y = 60000
while True:
y = .1 * y - 700
print(y)
但你可能只想做 100 次或更多次而不是永远:
y = 60000
for i in range(12*5):
y = .1 * y - 700
print("%d: %f" % (i,y))
您可能还想存储它们以备后用,因此请将它们放在一个数组中:
y = 60000
results=[]
for i in range(12*5):
y = .1 * y - 700
results.append(y)
print(results)
代码
按照你的要求使用递归:
def loan_calculator(y, payments, interest, monthly, period, counter=0, amount_left=[]):
# y -> starting loan (60,000)
# payments -> paying 0/month
# interest -> Interest rate on loan (yearly)
# monthly -> boolean, if monthly or yearly
# period -> how many years
# counter -> number of payments made
# amount_left -> after each payment how much is left to pay
if monthly:
period *= 12
interest /= (12*100)
# stopping condition:
if counter == period:
return y, amount_left
else:
y = (1+interest)*y - payments
amount_left.append(y)
counter += 1
return loan_calculator(y, 700, 1.2, True, 5, counter)
final_payment, all_payments = loan_calculator(6e4, 700, 1.2, True, 5)
print(all_payments)
print(final_payment)
输出
[59359.99999999999, 58719.359999999986, 58078.07935999998, 57436.15743935997, 56793.59359679933, 5615
0.38719039612, 55506.53757758651, 54862.04411516409, 54216.90615927925, 53571.12306543852, 52924.6941
88503956, 52277.618882692455, 51629.896501575146, 50981.52639807671, 50332.50792447478, 49682.8404323
9925, 49032.52327283165, 48381.555796104476, 47729.937351900575, 47077.66728925247, 46424.74495654172
, 45771.16970149826, 45116.94087119975, 44462.05781207095, 43806.51986988301, 43150.32638975289, 4249
3.476716142635, 41835.970192858775, 41177.80616305163, 40518.98396921468, 39859.50295318389, 39199.36
245613707, 38538.561818593196, 37877.100380411786, 37214.97748079219, 36552.192458272984, 35888.74465
0731256, 35224.633395381985, 34559.858028777366, 33894.41788680614, 33228.31230469295, 32561.54061699
7634, 31894.102157614627, 31225.996259772237, 30557.222256032004, 29887.779478288034, 29217.667257766
32, 28546.884925024082, 27875.431809949103, 27203.30724175905, 26530.510549000803, 25857.0410595498,
25182.898100609345, 24508.080998709953, 23832.58907970866, 23156.421668788367, 22479.578090457155, 21
802.057668547608, 21123.859726216153, 20444.983585942366] # This is a list of payments you owe each month
20444.983585942366 # This is your final payment