かれこれ20年になるがWindows時代になってF-BASICが有料になったのでこうなった。一言でいえばINV関数は便利、行列計算が1個ずつなのが難点、データの入出力もMAT文で読み込むときは行の最後にコンマをつけないといけない(らしい)。
私の勉強不足もあるかもしれないが、スカイライン図とか描画系となると、やはり強い。DBASIC(Decimal BASICなのでこう略している)の強さは計算しながら図で確認できるところだ。
テキストの出力は遅く感じるけど、なにより言語の習得が圧倒的に楽。
講談社BlueBacksの木村良夫『パソコンを遊ぶ簡単プログラミング』1冊あれば習得できて数学も楽しめる。図が必須のシステム制御とかシステムダイナミックス的なこともできる。sampleコードの結構多いし、充実している。
下のコードは
内生344部門、粗付加価値10、需要50の395×395のデータを読み込んで逆行列を求め、横軸に算出額構成比、縦軸に産出乗数(レオンチェフ逆行列の列和)をとったグラフを描画するもの。
産業部門の規模と乗数を視覚化すれば、経済効果は高いが規模の小さい部門と、経済効果は低いが規模の大きな部門を視覚的に比較できるので、経済効果の誘発係数のみで議論する愚をさけることができる。
例えば、麦のように経済効果が高くても、経済規模が小さいような部門をどう評価するか。議論の出発点にはなるし、なぜ経済効果が高いのかという投入構造(費用構成)にまで議論を拡張できる。創始者のレオンチェフはなくなったが、産業連関分析の可能性はまだまだある。ちなみに三角化チャートの図も簡単にかけるし、ユニットストラクチャーも簡単に計算描画できる。取り出したい部門だけ描画するなど自由度も高いのがこの言語のいいところだ。
LET n1=355
LET n2=395
LET n=344
LET nn=50
LET nnn=50
LET mm=10
LET mmm=10
dim datax(n1,n2)
DIM xi(n,n),v(mmm,n),f(n,nnn),m(n),x(n)
DIM a(n,n),mr(n),mc(n,n),mcv(n)
dim ii(n,n),xa(n,n),cb(n,n),sd(n),ob(n,n),ia(n,n)
rem **************** label ****************
DIM w$(n1),wv$(mmm),wfd$(n1)
OPEN #1:NAME "label_demand.txt"
FOR i=1 TO nnn
INPUT #1:wfd$(i)
NEXT i
CLOSE #1
OPEN #1:NAME "label344.txt"
FOR i=1 TO n1
INPUT #1:w$(i)
next i
CLOSE #1
FOR i=1 TO mmm
LET wv$(i)=w$(n1-mmm+i)
NEXT i
REM **************** data(単位:百万円) ****************
LET f$="2005_okinawa_344.txt"
OPEN #1:NAME f$
MAT INPUT #1:datax
CLOSE #1
FOR i=1 TO n
for j=1 to n
LET xi(i,j)=datax(i,j)
next j
next i
REM MAT PRINT xi
for i=1 to n
LET x(i)=datax(n1,i)
NEXT i
REM MAT PRINT x
FOR i=1 TO n
for j=1 to nnn
LET f(i,j)=datax(i,n+1+j)
next j
next i
print "f"
REM MAT PRINT f
for i=1 to mmm
for j=1 to n
LET v(i,j)=datax(n+1+i,j)
next j
NEXT i
REM print "v"
rem FOR i=1 TO mmm
REM PRINT wv$(i),
REM FOR j=1 TO n
REM PRINT v(i,j),
REM NEXT j
REM PRINT
rem NEXT i
REM MAT PRINT v
rem STOP
REM **************** 移輸入計383,384(344) ************
LET importv=383
REM LET transpv=96
FOR i=1 TO n
REM PRINT (i),w$(i),datax(i,importv),datax(i,importv+1)
LET m(i)=datax(i,importv)+datax(i,importv+1)
next i
for k=1 to n
LET m(k)=-1*m(k)
next k
CLOSE #1
PRINT "m"
REM FOR i=1 TO n
REM PRINT m(i)
REM next i
REM mat print m
for k=1 to n
for kk=1 to n
if x(kk)<>0 then LET a(k,kk)=xi(k,kk)/x(kk) else LET a(k,kk)=0
next kk
next k
print "input coefficient a(i,j)"
REM mat print a
FOR i=1 TO n
REM PRINT w$(i),
FOR j=1 TO n
REM PRINT a(i,j),
NEXT j
REM PRINT
NEXT i
REM **************** 最終需要:地域内需要合計 ************
LET fdemand=360
for k=1 to n
LET mr(k)=m(k)/(datax(k,fdemand))
REM 移輸入額>域内需要(定義的にあり得んと思うがとりあえず対策(^^;
IF mr(k)>1 THEN LET mr(k)=1
LET mcv(k)=1-mr(k)
REM PRINT k,mr(k),mcv(k),datax(k,fdemand),m(k),w$(k)
NEXT k
print "移輸入率(mr)"
REM mat print mr
FOR k=1 TO n
for kk=1 to n
if k=kk then LET mc(k,kk)=1-mr(k)
IF mc(k,kk)<0 k="" kk="" let="" mc="" p="" then=""> NEXT kk
NEXT k
print "自給率(I-M)"
REM print mc
PRINT "自給率(ベクトル)mcv"
rem MAT PRINT mcv
REM FOR i=1 TO n
REM PRINT i,w$(i),mcv(i)
REM NEXT i
REM print "leontief inverse matrix"
mat ii=idn(n,n)
mat ia=ii-a
mat cb=inv(ia)
REM MAT PRINT cb
PRINT "出力の制御"
mat xa=mc*a
mat xa=ii-xa
REM mat print xa
mat ob=inv(xa)
REM print "inverse matrix 1/(I-(I-M)A)"
REM mat print ob
rem print "cb ob diagonal"
REM FOR i=1 TO n
REM PRINT cb(i,i),ob(i,i),cb(i,i)-ob(i,i)
REM NEXT i
REM **********************************************************
REM ************** 以上基本計算ルーチン ********************
REM ******************* 産出乗数 ************************
REM **********************************************************
REM 産出乗数、産出額構成比 x(i) -> cpx(i)
REM 横軸を需要や所得に変更して分析するのも可
REM
DIM multiple(n),cpx(n),multiplex(n)
FOR j=1 TO n
LET summ=0
LET summx=0
FOR i=1 TO n
LET summ=summ+ob(i,j)
LET multiple(j)=summ
LET summx=summx+cb(i,j)
LET multiplex(j)=summx
NEXT i
PRINT j,multiple(j),multiplex(j),multiplex(j)-multiple(j),w$(j)
NEXT j
REM 構成比に用いる項目生産額:x(i)=datax(i,n1) ; 域内最終需要:datax(i,359),域内総需要(i,360),総生産(i,395)
REM 構成比は移輸出、移輸入、貿易の絶対額{移輸出+移輸入(絶対値)}でも面白い
LET s=0
FOR i=1 TO n
REM s=s+x(i)
REM PRINT s
LET s=s+datax(i,395)
NEXT i
REM PRINT s
PRINT "部門名 輸入内生化型産出乗数 輸入外生化型算出乗数 構成比 面積"
FOR i=1 TO n
REM cpx(i)=100*x(i)/s
LET cpx(i)=100*datax(i,395)/s
PRINT USING "#### " : i ;
PRINT multiple(i),multiplex(i),cpx(i),100*multiple(i)*cpx(i),w$(i)
NEXT i
!'**********************************
dim sum(n)
LET maxn=0
FOR i=1 TO n
IF multiple(i)>=maxn THEN LET maxn=multiple(i)
NEXT i
REM ******************************************
REM ************* 部門数選択 *************
REM startsector、endsector:描画開始―終了部門
REM ******************************************
DIM dcpx(n),dmultiple(n),dmultiplex(n)
LET startsector=1
LET endsector=60
LET newn=endsector-startsector
FOR i=startsector TO endsector
LET dcpx(i+1-startsector)=cpx(i)
LET dmultiple(i+1-startsector)=multiple(i)
LET dmultiplex(i+1-startsector)=multiplex(i)
NEXT i
LET n=newn
FOR i=1 TO n
LET cpx(i)=dcpx(i)
LET multiple(i)=dmultiple(i)
LET multiplex(i)=dmultiplex(i)
NEXT i
LET s=0
FOR i=1 TO n
LET s=s+dcpx(i)
NEXT i
FOR i=1 TO n
LET cpx(i)=100*dcpx(i)/s
NEXT i
PRINT "maxn : ",maxn
REM LET maxn=4
REM ************** sect Window ***************
REM ******* SET WINDOW left,right ,bottom,top
rem ************** 縦横軸補正 ****************
LET botm=-1
LET upper=6
REM *************** 右、左 *******************
LET leftax=-2
LET rightax=100
SET WINDOW leftax,rightax+2,botm-0.5,maxn+upper
PLOT LINES:leftax,0;rightax+2,0
PLOT TEXT ,AT 70,maxn+1:"Leontief Multiplier Chart : "
PLOT TEXT ,AT 70,maxn+2:f$
dim dx(n)
LET s=0
for i=1 to n
LET s=s+cpx(i)
LET dx(i)=s
next i
dim pdot(n),edot(n)
LET s=0
for i=1 to n
LET pdot(i)=dx(i)-(cpx(i)/1.6)
next i
dim numa(n),numb(n)
for i=1 to n step 2
LET numa(i)=i
LET numb(i)=i+1
REM print numa(i),numb(i)
next i
LET s=0
for i=1 to n
LET s=s+100/n
LET edot(i)=s-50/n
IF i=numa(i) THEN PLOT TEXT ,AT edot(i)-0.5,0.8*botm:STR$(i+startsector) ELSE PLOT TEXT ,AT edot(i)-0.6,botm:STR$(i+startsector)
next i
SET LINE style 1
SET LINE WIDTH 1
SET LINE COLOR 1
for i=1 to n
if i=numa(i) then plot lines:pdot(i),0;edot(i),0.5*botm else plot lines:pdot(i),0;edot(i),0.5*botm;edot(i),0.7*botm
next i
REM INPUT PROMPT "dum=":dummy
REM ************** revised ***************
REM prtxt Box内に表示する構成比の下限値、文字の表示位置 -> y:yst
SET LINE STYLE 1
SET LINE WIDTH 1
SET LINE COLOR 5
REM FOR i=1 TO n
REM PRINT i,cpx(i),dx(i),pdot(i),edot(i)
REM NEXT i
LET prtxt=1.4
LET yst=0.5
FOR i=1 TO n
IF cpx(i)>=prtxt THEN PLOT TEXT ,AT dx(i)-prtxt*cpx(i)/2, multiple(i) :STR$(i+startsector)
NEXT i
rem *************** sector code ****************
REM 上の線:産出乗数の描画:輸入外生(標準乗数)
REM 必要が無ければこの線は描画しない
LET sss=0
SET LINE STYLE 3
SET LINE WIDTH 1
SET LINE COLOR 4
plot 0,0;
FOR i=1 TO n
PLOT LINES:sss,multiplex(i);
LET sss=sss+cpx(i)
PLOT LINES:sss,multiplex(i);
plot lines:sss,0;
LET sum(i)=sss
NEXT i
REM 上の線:産出乗数の描画:輸入内生(自給率調整乗数)
LET sss=0
SET LINE STYLE 1
SET LINE WIDTH 1
SET LINE COLOR 1
plot 0,0;
for i=1 to n
PLOT LINES:sss,multiple(i);
LET sss=sss+cpx(i)
PLOT LINES:sss,multiple(i);
plot lines:sss,0;
LET sum(i)=sss
NEXT i
REM ゼロの線:赤
PLOT LINES
SET LINE STYLE 1
SET LINE WIDTH 2
SET LINE COLOR 4
PLOT LINES:leftax,0;rightax+2,0
REM 1の基線:青
PLOT LINES
SET LINE STYLE 3
SET LINE WIDTH 1
SET LINE COLOR 2
PLOT LINES:leftax,1;rightax+2,1
END
0>
0 件のコメント:
コメントを投稿