contents

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.