2.5
Hand calculation
金利, interest, r = 0.1
キャッシュフロー流列, a cash flow stream, cfs = (x0, x1, ... , x19)
ただし、xi = x = 500,000($)(i = 0, ... , 19)
この賞金の現在価値, presesnt value of this prize, PVは、次式となる。
PV = x0 + x1/(1+r) + ... + x19/(1 + r)19 = x + x / (1 + r) + ... + x / (1 + r)19 = x(1 + 1 / (1 + r) + ... + 1 / (1 + r)19) = x((1 + r) / r)(1 - 1 / (1 + r)20) = 500,000((1 + 0.1) / 0.1)(1 - 1 / (1 + 0.1)20) ∴PV = 4,682,460($)
Python 3
by formula (2.2)
(2019-08-15)
公式(2.2)を用いてPython 3で解く。
code
# 2.5.formula2.2.py
# 2019-08-15
# input
r = 0.1
x = 500e3
# calculate with formula (2.2) in the text
pv = x + x / (1 + r) ** 1 + x / (1 + r) ** 2 + x / (1 + r) ** 3 \
+ x / (1 + r) ** 4 + x / (1 + r) ** 5 + x / (1 + r) ** 6 \
+ x / (1 + r) ** 7 + x / (1 + r) ** 8 + x / (1 + r) ** 9 \
+ x / (1 + r) ** 10 + x / (1 + r) ** 11 + x / (1 + r) ** 12 \
+ x / (1 + r) ** 13 + x / (1 + r) ** 14 + x / (1 + r) ** 15 \
+ x / (1 + r) ** 16 + x / (1 + r) ** 17 + x / (1 + r) ** 18 \
+ x / (1 + r) ** 19
# output
print('2.5.formula2.2.py')
print('r= ', r)
print('x= ', x)
print('pv of cfs= ', round(pv))
# eof
output
2.5.formula2.2.py r= 0.1 x= 500000.0 pv of cfs= 4682460
for 文
(2019-08-15, 2019-08-31, 2023-03-05)
計算方針 Python3のfor文を用いて解く。
計算手順 各x[i]に対する現在価値x[i]/(1+r)k[i]を計算し、各現在価値を累計することを i を 0 から 19 まで変化させて行いキャッシュフロー流列の現在価値pvを計算する。
code
# 2.5.for.py
# 2023-03-05
# function
def pv1(x, k, r): # text, p.26
pv1 = 0
n = range(len(x))
for i in n:
pv1 = pv1 + x[i] / (1 + r) ** k[i]
return pv1
# input
cf = 500e3
x = [cf, cf, cf, cf, cf, cf, cf, cf, cf, cf, \
cf, cf, cf, cf, cf, cf, cf, cf, cf, cf]
k = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, \
10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
r = 0.1
# calcuration
pv = pv1(x, k, r)
# output
print('2.5.for.py')
print('x= ', x)
print('k=', k)
print('pv of x= ', round(pv))
# eof
output
2.5.for.py
x= [500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0]
k= [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
pv of x= 4682460
for文 その2
(2019-08-31)
計算方針 Python 3のfor文を用いて現在価値pvを算出する。
計算手順 リストcfsの要素cfs[i]からその要素の現在価値cfs[i]/(1+r)iを計算し
要素の現在価値を累計することを全データ繰り返すことでキャッシュフロー流列の現在価値pvを計算する。
(リストcfsのインデクスは関数enumerateで用意した。)
(2023-03-05)
期の数は、陽に用意する計算方法に変更する。ここにあった 2.5for2.py は削除した。
リスト内包
(2019-08-15, 2023-03-05)
計算方針 Python 3のリスト内包を用いて現在価値pvを算出する。
計算手順 リストxとkから各要素をx[i]/(1+r)k[i]とするリストをリスト内包により作成し、
作成したリストの要素の合計を関数sumで算出し、それをキャッシュフロー流列の現在価値pvとする。
(enumerateで期の数を用意せずに、期の数(k)を陽に用意した。)
注 リスト内包の内包について
リスト内包の内包は、集合の内包的記法の内包を使用しているのではないか。(追記 2022-12-24)
出典
リスト内包表記 →
Pythonチュートリアル 5.1.3 リストの内包表記
集合の内包的記法 → 松坂和夫:集合・位相入門、岩波書店、2018、p.5。
code
# 2.5.lc.py
# 2023-03-05
# x : cash flow stream
# k : number of periods
# r : interest rate
# pv : present value
# function
def pv3(x, k, r): # text, p.26
return sum([x / (1 + r) ** k for x, k in zip(x, k)]) # リスト内包
# input
cf = 500e3
x = [cf, cf, cf, cf, cf, cf, cf, cf, cf, cf, \
cf, cf, cf, cf, cf, cf, cf, cf, cf, cf]
k = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, \
10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
r = 0.1
# calculation
pv = pv3(x, k, r)
# output
print('2.5.lc.py')
print('x=', x)
print('k=', k)
print('r=', r)
print('pv of x=', round(pv))
# eof
output
2.5.lc.py
x= [500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0]
k= [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
r= 0.1
pv of x= 4682460
ジェネレータ式
(2019-08-15, 2023-03-05)
計算方針 Python 3のジェネレータ式を用いて現在価値pvを算出する。
計算手順 リスト x と k から各要素をx[i]/(1+r)k[i]とするものをジェネレータ式により作成し、それら要素の合計を関数sumで算出し、それをキャッシュフロー流列の現在価値pvとする。
(enumerateで期の数を用意せずに、期の数(k)を陽に用意した。)
code
# 2.5.ge.py
# 2023-03-05
# cf : cash flow
# x : cash flow stream
# r : interest rate
# pv : present value
# function
def pv2(x, k, r): # text, p.26
return sum(x / (1 + r) ** k for x, k in zip(x, k)) # generator
# input
cf = 500e3
x = [cf, cf, cf, cf, cf, cf, cf, cf, cf, cf, \
cf, cf, cf, cf, cf, cf, cf, cf, cf, cf]
k = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, \
10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
r = 0.1
# calculation
pv = pv2(x, k, r)
# output
print('2.5.ge.py')
print('x=', x)
print('k=', k)
print('r= ', r)
print('pv of cfs=', round(pv))
# eof
output
2.5.ge.py
x= [500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0]
k= [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
r= 0.1
pv of cfs= 4682460
関数map
(2019-08-15)
計算方針 Python 3の関数mapを用いて現在価値pvを算出する。
計算手順 リストcfsのインデクスを要素とするリストiを作成し、
リストcfsとリストiの各要素から
無名関数 x/(1+r)iで
リストcfsの各要素の現在価値を要素とするmap objectを関数mapで作成し、
そのmap objectの要素の合計を関数sumで算出し、
それをキャッシュフロー流列cfsの現在価値pvとする。
code
# 2.5.map.py
# 2019-08-15
# input
r = 0.1
cfs = [5e5, 5e5, 5e5, 5e5, 5e5, 5e5, 5e5, 5e5, 5e5, 5e5, \
5e5, 5e5, 5e5, 5e5, 5e5, 5e5, 5e5, 5e5, 5e5, 5e5]
i = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, \
10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
# calculate
pv = sum(map(lambda x, i: x / (1 + r) ** i, cfs, i)) # 関数map
# output
print('2.5.map.py')
print('r= ', r)
print('i= ', i)
print('cfs= ',cfs)
print('pv of cfs= ', round(pv))
# eof
output
2.5.map.py
r= 0.1
i= [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
cfs= [500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0, 500000.0]
pv of cfs= 4682460
関数starmap
(2019-08-31)
計算方針 Python 3のモジュールitertoolsの関数starmapを用いて現在価値pvを算出する。
計算手順 リストcfsの要素とそのインデクスとから
無名関数 x/(1+r)iで
リストcfsの各要素の現在価値を要素とするmap objectを関数starmapで作成し、
そのmap objectの要素の合計を関数sumで算出し、
それをキャッシュフロー流列cfsの現在価値pvとする。リストcfsのインデクスは関数enumerateで用意した。
(2023-03-05) enumerateを使うの止めるため、2.5.starmap.py は削除した。
計算方針の違いについて
(2019-09-01, 2023-03-05)
上のリスト内包、ジェネレータ式、関数map、関数starmapは、いずれも次のように考えている。
データ1(キャッシュフロー流列x)を
データ2(キャッシュフローの現在価値の列)に変換(リスト内包等)し、
データ2(キャッシュフローの現在価値の列)の要素の合計を
データ1(キャッシュフロー流列x)の現在価値として求める。
すなわち、「データからデータへの変換」で考えている。
他方、for文、while文は、いずれも次のように考えている。
キャッシュフローの現在価値を計算しその現在価値を累計することを、
データの数だけ「繰り返す」ことで、
キャッシュフロー流列の現在価値を求める。
すなわち、「手続的」に考えている。
備考
この違いは、次のコラムを読んで書いた。
Kahuaプロジェクト、プログラミングGauche、オライリージャパン、2008、pp.88-92、コラム 「Lisp脳」の謎に迫る-Schemeプログラマの発想。
Pyton3 with numpy
(added on 2016-11-18, revised on 2019-09-14.)
code
# 2.5.np.py
# -*- coding: Shift_JIS -*- # change encoding(Shift_JIS) for your environment
# 2016-11-18
# $Id: 2.5.html 1.32 2023/03/05 09:01:10 s Exp $
#
import numpy as np
# r : interest rate
# i : index
# cfs : cash flow stream
# pv : present value
# input
r = 0.1
i = np.array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
cfs = np.array([5e5, 5e5, 5e5, 5e5, 5e5, 5e5, 5e5, 5e5, 5e5, 5e5,
5e5, 5e5, 5e5, 5e5, 5e5, 5e5, 5e5, 5e5, 5e5, 5e5])
# calculate
pv = sum(cfs / (1 + r) ** i)
# output
print('2.5.np.py')
print('r =', r)
print('cfs= ', cfs)
print('pv = ', round(pv))
# end of program
output
2.5.np.py
r = 0.1
cfs= [500000. 500000. 500000. 500000. 500000. 500000. 500000. 500000. 500000. 500000. 500000. 500000. 500000. 500000. 500000. 500000. 500000. 500000. 500000. 500000.]
pv = 4682460.0
Gauche code
(revised on 2015-03-29, 2016-02-21, 2019-09-11, 2019-09-14, 2023-03-05.)
code
;;; 2.5.scm
;;; 2023-03-05
(define (main args)
; x : cash flow stream
; k : number of periods
; r : interest rate
; pv : present value
; function
(define sum (lambda (x) (fold + 0 x)))
(define (pv4 x k r) ; text, p.26. using map
(sum (map (lambda (x k) (/ x (expt (+ 1 r) k))) x k)))
; input
(define cf 500e3)
(define x (list cf cf cf cf cf cf cf cf cf cf
cf cf cf cf cf cf cf cf cf cf))
(define k (list 0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19))
(define r 0.1)
; calcuration
(define pv (pv4 x k r))
; output
(print "2.5.scm")
(print "x= " x)
(print "k= " k)
(print "r= " r)
(print "pv = " (x->integer pv))
0)
;;; end
output
2.5.scm
x= (500000.0 500000.0 500000.0 500000.0 500000.0 500000.0 500000.0 500000.0 500000.0 500000.0 500000.0 500000.0 500000.0 500000.0 500000.0 500000.0 500000.0 500000.0 500000.0 500000.0)
k= (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19)
r= 0.1
pv = 4682460
history
revised on 2009-11-01, 2011-11-02, 2014-02-11, 2015-03-29, 2015-04-11,
2016-02-07, 2016-02-21, 2016-09-28.
2016-09-28 Fortran, Gauche, Javascript codes moved to linked files.
2016-11-18 Python 3 code with numpy added.
2018-01-03 XHTML1.0 changed to HTML5.
2018-06-03 charset shift-jis to utf-8.
2019-08-15 codes using for statement, generator expression and function map added.
2019-08-31 codes using for statement(part 2), function starmap added.
2019-09-01 計算方針の違いについて added.
2019-09-10 JavaScript code using map added.
2019-09-11 JavaScript code using map for node.js added.
2019-09-14 Gauche code , Python3 with numpy & fortran code revised.
2021-02-14 move history.
2022-12-24 add リスト内包の内包について.
2023-01-14 move Fortran code to 2.5part4, remove Javascript codes.
2023-03-05 revise 2.5.for.py. delete 2.5.for2.py. revise 2.5.lc.py. revise 2.5.ge.py. delete 2.5.starmap.py. revise 2.5.scm.