(57)【特許請求の範囲】
【請求項１】
配列Ｆに対して別の配列Ａの要素を加算するときに、その加算要素の位置を決定する中間配列ｉｎｄｅｘが存在し、
【数１】
0003845711.tif 000006
の式であって、Ｉは１からＮ（ここで、Ｎは２以上の任意の整数）までの範囲を全て昇順に網羅する上記式により表される間接アドレス参照を含む加算をベクトル計算機上で高速処理する方法において、
配列Ｆ、Ａ及びｉｎｄｅｘが記憶手段に設けられており、
（１）配列Ｆと同じ同じ大きさの作業配列をＬ個（ここで、Ｌは２以上の整数）を前記記憶手段に設けるステップであって、そのＬ個の作業配列をＷ（Ｉ，Ｊ）の２次元表記で表し、Ｗの１次元目の大きさは配列Ｆの大きさに一致し、２次元目の大きさがＬであり、且つその作業配列Ｗの全要素に０をセットするステップと、
（２）配列Ａの要素と作業配列Ｗの要素とを用いて、
【数２】
0003845711.tif 000007
（ここで、modは剰余を計算する関数である。）で表される式に基づいてＩについて１からＮまで順に計算して、その結果を対応する作業配列Ｗに格納するステップと、
（３）作業配列Ｗと同じサイズでｓｔａｍｐ（ｓ1，ｓ2）の２次元表記で表される配列ｓｔａｍｐを前記記憶手段に設けるステップと、
（４）配列ｓｔａｍｐにおけるstamp(index(I),mod(I-1,L)+1)に対してＩの値を格納するステップと、
（５）Ｉを１からＮまで変化させて、stamp(index(I),mod(I-1,L)+1)がＩと一致するか否かを判定するステップと、
（６）ステップ（５）での判定でstamp(index(I),mod(I-1,L)+1)がＩと一致しないＩがＮ′個（ここで、Ｎ′は１以上の整数）存在する場合、その一致しないＩのリストを生成し且つ要素数Ｎ′の配列ｌｉｓｔとして前記記憶手段に格納するステップと、
（７）配列Ａの要素と作業配列Ｗの要素とを用いて、
【数３】
0003845711.tif 000008
（ここで、modは剰余を計算する関数である。）で表される式に基づいてlist(I)について１からＮ′まで順に計算して、その結果を対応する作業配列Ｗに格納するステップと、
（８）配列ｓｔａｍｐにおけるstamp(index(list(I)),mod(list(I)-1,L)+1)に対してＩの値を格納するステップと、
（９）Ｉを１からＮまで変化させて、stamp(index(list(I)),mod(list(I)-1,L)+1)がＩと一致するか否かを判定するステップと、
（１０）ステップ（９）での判定でstamp(index(list(I)),mod(list(I)-1,L)+1)がＩと一致しないＩが存在する場合、その一致しないＩのリストを配列ｌｉｓｔに格納するステップと、
（１１）ステップ（９）での判定でstamp(index(list(I)),mod(list(I)-1,L)+1)がＩと一致しないＩが存在しなくなるまで、ステップ（７）からステップ（１０）までを繰り返すステップと、
（１２）ステップ（５）での判定でstamp(index(I),mod(I-1,L)+1)がＩと一致しないＩが存在しない場合、又はステップ（９）での判定でstamp(index(list(I)),mod(list(I)-1,L)+1)がＩと一致しないＩが存在しない場合に、処理を終了するステップと
を備える方法。
【請求項２】
配列Ｆに対して別の配列Ａの要素を加算するときに、その加算要素の位置を決定する中間配列ｉｎｄｅｘが存在し、
【数４】
0003845711.tif 000009
の式であって、Ｉは１からＮ（ここで、Ｎは２以上の任意の整数）までの範囲を全て昇順に網羅する上記式により表される間接アドレス参照を含む加算を高速処理するベクトル計算機において、
配列Ｆ、Ａ及びｉｎｄｅｘを格納する記憶手段と、
前記記憶手段には、配列Ｆと同じ同じ大きさの作業配列をＬ個（ここで、Ｌは２以上の整数）が設けられており、そのＬ個の作業配列をＷ（Ｉ，Ｊ）の２次元表記で表し、Ｗの１次元目の大きさは配列Ｆの大きさに一致し、２次元目の大きさがＬであり、且つその作業配列Ｗの全要素が０をセットされており、
更に前記記憶手段には、作業配列Ｗと同じサイズでｓｔａｍｐ（ｓ1，ｓ2）の２次元表記で表される配列ｓｔａｍｐが設けられており、
（１）配列Ａの要素と作業配列Ｗの要素とを用いて、
【数５】
0003845711.tif 000010
（ここで、modは剰余を計算する関数である。）で表される式に基づいて計算して、その結果を対応する作業配列Ｗに格納し、
（２）配列ｓｔａｍｐにおけるstamp(index(I),mod(I-1,L)+1)に対してＩの値を格納し、
（３）第１の判定において、Ｉを１からＮまで変化させて、stamp(index(I),mod(I-1,L)+1)がＩと一致するか否かを判定し、
（４）第１の判定でstamp(index(I),mod(I-1,L)+1)がＩと一致しないＩがＮ′個（ここで、Ｎ′は１以上の整数）存在する場合、その一致しないＩのリストを生成し且つ要素数Ｎ′の配列ｌｉｓｔとして前記記憶手段に格納し、
（５）配列Ａの要素と作業配列Ｗの要素とを用いて、
【数６】
0003845711.tif 000011
（ここで、modは剰余を計算する関数である。）で表される式に基づいてlist(I)について１からＮ′まで順に計算して、その結果を対応する作業配列Ｗに格納し、
（６）配列ｓｔａｍｐにおけるstamp(index(list(I)),mod(list(I)-1,L)+1)に対してＩの値を格納し、
（７）第２の判定において、Ｉを１からＮまで変化させて、stamp(index(list(I)),mod(list(I)-1,L)+1)がＩと一致するか否かを判定し、
（８）第２の判定でstamp(index(list(I)),mod(list(I)-1,L)+1)がＩと一致しないＩが存在する場合、その一致しないＩのリストを配列ｌｉｓｔに格納し、
（９）第２の判定でstamp(index(list(I)),mod(list(I)-1,L)+1)がＩと一致しないＩが存在しなくなるまで、上記（７）から（１０）までの処理を繰り返し、
（１０）第１の判定でstamp(index(I),mod(I-1,L)+1)がＩと一致しないＩが存在しない場合、又は第２の判定でstamp(index(list(I)),mod(list(I)-1,L)+1)がＩと一致しないＩが存在しない場合に、処理を終了する演算制御手段を備えるベクトル計算機。
【請求項３】
配列Ｆに対して別の配列Ａの要素を加算するときに、その加算要素の位置を決定する中間配列ｉｎｄｅｘが存在し、
【数７】
0003845711.tif 000012
の式であって、Ｉは１からＮ（ここで、Ｎは２以上の任意の整数）までの範囲を全て昇順に網羅する上記式により表される間接アドレス参照を含む加算をベクトル計算機上で上で高速処理するためのプログラムにおいて、
前記ベクトル計算機に、
（１）配列Ｆと同じ同じ大きさの作業配列をＬ個（ここで、Ｌは２以上の整数）を記憶手段に生成する手順であって、そのＬ個の作業配列をＷ（Ｉ，Ｊ）の２次元表記で表し、Ｗの１次元目の大きさは配列Ｆの大きさに一致し、２次元目の大きさがＬであり、且つその作業配列Ｗの全要素に０をセットする手順と、
（２）配列Ａの要素と作業配列Ｗの要素とを用いて、
【数８】
0003845711.tif 000013
（ここで、modは剰余を計算する関数である。）で表される式に基づいてＩについて１からＮまで順に計算して、その結果を対応する作業配列Ｗに格納する手順と、
（３）作業配列Ｗと同じサイズでｓｔａｍｐ（ｓ1，ｓ2）の２次元表記で表される配列ｓｔａｍｐを前記記憶手段に生成する手順と、
（４）配列ｓｔａｍｐにおけるstamp(index(I),mod(I-1,L)+1)に対してＩの値を格納する手順と、
（５）Ｉを１からＮまで変化させて、stamp(index(I),mod(I-1,L)+1)がＩと一致するか否かを判定する手順と、
（６）手順（５）での判定でstamp(index(I),mod(I-1,L)+1)がＩと一致しないＩがＮ′個（ここで、Ｎ′は１以上の整数）存在する場合、その一致しないＩのリストを生成し且つ要素数Ｎ′の配列ｌｉｓｔとして前記記憶手段に格納し、
（７）配列Ａの要素と作業配列Ｗの要素とを用いて、
【数９】
0003845711.tif 000014
（ここで、modは剰余を計算する関数である。）で表される式に基づいてlist(I)について１からＮ′まで順に計算して、その結果を対応する作業配列Ｗに格納する手順と、
（８）配列ｓｔａｍｐにおけるstamp(index(list(I)),mod(list(I)-1,L)+1)に対してＩの値を格納する手順と、
（９）Ｉを１からＮまで変化させて、stamp(index(list(I)),mod(list(I)-1,L)+1)がＩと一致するか否かを判定する手順と、
（１０）手順（９）での判定でstamp(index(list(I)),mod(list(I)-1,L)+1)がＩと一致しないＩが存在する場合、その一致しないＩのリストを配列ｌｉｓｔに格納する手順と、
（１１）手順（９）での判定でstamp(index(list(I)),mod(list(I)-1,L)+1)がＩと一致しないＩが存在しなくなるまで、手順（７）から手順（１０）までを繰り返す手順と、
（１２）手順（５）での判定でstamp(index(I),mod(I-1,L)+1)がＩと一致しないＩが存在しない場合、又は手順（９）での判定でstamp(index(list(I)),mod(list(I)-1,L)+1)がＩと一致しないＩが存在しない場合に、処理を終了する手順とを実行させるためのプログラム。
【発明の詳細な説明】
【０００１】
【発明の属する技術分野】
本発明は、科学技術計算において用いられる数値シミュレーションを高速化するものであり、具体的にはベクトル計算機上での間接アドレス参照を含む加算の高速処理方法、プログラム及びそれを用いたベクトル計算機に関する。特に、本発明は、それが対象とする間接アドレス参照による加算を含む問題をベクトル計算機を用いて計算する場合に有効である。対象となる問題は、科学技術計算では極めて広範囲に存在する。
【０００２】
【従来の技術】
最初に従来のベクトル計算機における間接アドレス参照による加算を含む問題について説明する。配列Ｆに対して別の配列Ａの要素を加算するときに、その加算要素の位置を決定する中間配列ｉｎｄｅｘが存在し、次の式の様に加算がなされる場合を想定する。
【０００３】
【数１０】
F(index(I)):=F(index(I))+A(I)        （１）
ここで、Ｉは１からＮ（Ｎは２以上の整数）までの範囲を全て昇順（Ｉ＝１，２，３，…，Ｎ）に網羅する。Ｆの様に中間配列ｉｎｄｅｘを媒介して配列の値を参照することを一般に間接アドレス参照と呼ぶ。
【０００４】
式（１）が登場する代表的な例として、
（１）バケッツソートにおけるヒストグラム計算
（２）粒子問題における粒子の場への寄与計算
（３）積分計算一般
などがあげられる。（２）の例において、ＰＩＣ（Ｐａｒｔｉｃｌｅ−Ｉｎ−Ｃｅｌｌ）法を用いる粒子問題ではこの計算をＣｈａｒｇｅ  Ｄｅｐｏｓｉｔと呼び、粒子相互間の作用を場を経由して計算する際に用いられる。式（１）を回帰式と呼ぶこともあるが、本明細書においてはＰＩＣ法でのＣｈａｒｇｅ  Ｄｅｐｏｓｉｔに由来させてｄｅｐｏｓｉｔ式とも呼ぶ。多粒子系の問題ではｄｅｐｏｓｉｔ式の計算コストが極めて大きく、その高速化が常に望まれている。
【０００５】
強力な計算能力を有するベクトル計算機では、これまでの手法によるベクトル処理では次に説明するようにアドレス衝突の問題が避けられないため、一般的には不可能であった。ただし、間接アドレスのリストの内容に重複がないなどの特殊な条件下のもとでのみ、コンパイラに対して指示を行い強制ベクトル処理をすることができていた。
【０００６】
今、ベクトル計算機上での式（１）の計算をＩに対して１からＮの順に行うとき、ベクトル計算機の計算システム内部にはＫ個単位で同時に計算する演算機構があり、式（１）の計算もＫ個同時に処理される。今、Ｋ＝４でｉｎｄｅｘの値が１，１，１，１であるとすると、まず演算機構が持つ記憶装置（レジスタ）にＦ（ｉｎｄｅｘ（１）），Ｆ（ｉｎｄｅｘ（２）），Ｆ（ｉｎｄｅｘ（３）），Ｆ（ｉｎｄｅｘ（４））が主記憶装置（以下「メモリ」）から読み込まれる。つまり、｛Ｆ（１），Ｆ（１），Ｆ（１），Ｆ（１）｝がレジスタに格納されている。次にＡの値がＫ個同時に加算される、つまり演算の結果、レジスタの値は｛Ｆ（１）＋Ａ（１），Ｆ（１）＋Ａ（２），Ｆ（１）＋Ａ（３），Ｆ（１）＋Ａ（４）｝となる。次に、このレジスタの内容がメモリに戻されるのであるが、それぞれの要素がその並び順にメモリＦ（ｉｎｄｅｘ（１）），Ｆ（ｉｎｄｅｘ（２）），Ｆ（ｉｎｄｅｘ（３）），Ｆ（ｉｎｄｅｘ（４））に記録されるため、ｉｎｄｅｘの値が一致する部分、つまりＦ（１）には最後に記録されたＦ（１）＋Ａ（４）が書き込まれることになる。
【０００７】
本来この式の計算意味上、計算結果は、Ｆ（１）にＦ（１）＋Ａ（１）＋Ａ（２）＋Ａ（３）＋Ａ（４）の値が格納されなくてはならない。従って、ベクトル計算機上での式（１）の計算は計算結果不正を伴うものであり、計算結果を正しくするための別の計算手法を導入する必要がある。
【０００８】
その１つとして、１次元の加算対象配列に対して、投機的なベクトル処理を行い、加算結果の不正となる項を検出し、再度同様の処理を繰り返す方式、いわゆるＲｅｔｒｙアルゴリズムが提案されている。これは、結果不正のリスクをも含めて、Ｆに対して直接のアドレスを利用して加算ベクトル処理を行い、結果不正項の修正を行うものである。例えば、下記文献を参照されたい。
【０００９】
Ａｂｅ，Ｙ．：Ｐｒｅｓｅｎｔ  Ｓｔａｔｕｓ  ｏｆ  Ｃｏｍｐｕｔｅｒ  Ｓｉｍｕｌａｔｉｏｎ  ａｔ  ＩＰＰ，  Ｐｒｏｃｅｅｄｉｎｇ  ｏｆ  Ｓｕｐｅｒｃｏｍｐｕｔｉｎｇ  ８８，Ｖｏｌ．ＩＩ，ｐ．７２（１９８８）、及び
村井均、末松謙二、妹尾義樹：共有メモリ型並列計算機上の高速整数ソーティングアルゴリズム、情報処理学会論文誌，Ｖｏｌ．３９，Ｎｏ．６，ｐ．１５９５（１９９８）。
【００１０】
また、プログラムの積極的な変更によりアドレス衝突を避ける方法として、配列Ｆに対して人工的なインデックス拡張を施すＷｏｒｋ  Ｖｅｃｔｏｒアルゴリズム（又は止まり木法）が提案されている（Ｎｉｓｈｉｇｕｃｈｉ，Ａ．，Ｏｒｉｉ，Ｓ．  ａｎｄ  Ｙａｂｅ，Ｔ．：Ｖｅｃｔｏｒ  Ｃａｌｃｕｌａｔｉｏｎｏｆ  Ｐａｒｔｉｃｌｅ  Ｃｏｄｅ，Ｊｏｕｒｎａｌ  ｏｆ  Ｃｏｍｐｕｔａｉｏｎａｌ  Ｐｈｙｓｉｃｓ，Ｖｏｌ．６１，ｐ．５１９（１９８５）参照）。これは、Ｋ個の作業領域（配列ｗ（１：ｍ，１：Ｋ）を用意し、ベクトル長Ｋにストリップマイニングされた上記式（１）に対してｉｎｄｅｘ（ｉ）の形の単純なアドレス指定を、（ｉｎｄｅｘ（ｉ），ｊ）の様に次元拡張しアドレスの一致を完全に回避する方法である。つまり、２次元作業配列を導入し、アドレスの衝突を完全に回避する手法である。
【００１１】
【発明が解決しようとする課題】
Ｗｏｒｋ  Ｖｅｃｔｏｒアルゴリズム（又は止まり木法）は、ベクトル処理の単位となるベクトル長と拡張次元を一致させる方式であるため、加算不正項は発生しないが十分な性能を得るためには使用する作業配列の大きさが非常に大きくならざるを得なかった。
【００１２】
一方、Ｒｅｔｒｙアルゴリズムは、Ｗｏｒｋ  Ｖｅｃｔｏｒアルゴリズム（又は止まり木法）に比べて必要とするメモリ量が少量で、更に間接アドレス参照が疎らなときには性能を発揮することがソーティング問題（上記（１）の例）への適用実験によって示されている（上記村井らの文献参照）。しかしながら、ｉｎｄｅｘの分布がある範囲に集中する際にはスカラ計算よりも遅くなるという欠点を有するため、極めて特異な問題では有効でない。また、結果不正項の出現は、ｉｎｄｅｘの値の重複度に依存しており、重複度が高くなった際に再試行加算の回数が増大し、性能劣化の原因となっていた。
【００１３】
村松、望月らの報告では、分子軌道計算における積分式が式（１）の形をしている場合、回避できない頻度で起こるｉｎｄｅｘ値（キー）の衝突のためＲｅｔｒｙアルゴリズムが有効でないことが示されている。また、Ｗｏｒｋ  Ｖｅｃｔｏｒアルゴリズムは有効な手法であるが、メモリ使用率が現実的な大規模問題への適用の障壁となることも併せて報告されている。詳細には、村松昌幸、望月祐志、与倉徹一、平原幸男、今村俊幸：相対論的分子軌道コードＤＩＲＡＣにおけるＤＨＦ計算のベクトル化，情処研報，Ｖｏｌ．２００１，Ｎｏ．４９，ｐ．４３（２００１）を参照されたい。
【００１４】
まとめると、Ｗｏｒｋ  Ｖｅｃｔｏｒアルゴリズム（又は止まり木法）は、加算不正項は発生しないが十分な性能を得るためには使用する作業配列の大きさが非常に大きくならざるを得なく、また、Ｒｅｔｒｙアルゴリズムでは、投機的なベクトル処理が１次元配列に対してであったため加算の不正の原因となるアドレスの衝突が頻発していた。
【００１５】
本発明の課題は、ベクトル計算機上での間接アドレス参照を含む加算において計算誤りを回避し、また大きな作業配列を用いないで且つアドレスの衝突の頻度を緩和して加算を高速に行うことにある。
【００１６】
【課題を解決するための手段】
上記課題は、配列Ｆに対して別の配列Ａの要素を加算するときに、その加算要素の位置を決定する中間配列ｉｎｄｅｘが存在し、
【００１７】
【数１１】
F(index(I)):=F(index(I))+A(I)
の式であって、Ｉは１からＮ（ここで、Ｎは２以上の任意の整数）までの範囲を全て昇順に網羅する上記式により表される間接アドレス参照を含む加算をベクトル計算機上で高速処理する方法において、
配列Ｆ、Ａ及びｉｎｄｅｘが記憶手段に設けられており、
（１）配列Ｆと同じ同じ大きさの作業配列をＬ個（ここで、Ｌは２以上の整数）を前記記憶手段に設けるステップであって、そのＬ個の作業配列をＷ（Ｉ，Ｊ）の２次元表記で表し、Ｗの１次元目の大きさは配列Ｆの大きさに一致し、２次元目の大きさがＬであり、且つその作業配列Ｗの全要素に０をセットするステップと、
（２）配列Ａの要素と作業配列Ｗの要素とを用いて、
【００１８】
【数１２】
W(index(I),mod(I-1,L)+1:=W(index(I),mod(I-1,L)+1)+A(I)
（ここで、modは剰余を計算する関数である。）で表される式に基づいてＩについて１からＮまで順に計算して、その結果を対応する作業配列Ｗに格納するステップと、
（３）作業配列Ｗと同じサイズでｓｔａｍｐ（ｓ1，ｓ2）の２次元表記で表される配列ｓｔａｍｐを前記記憶手段に設けるステップと、
（４）配列ｓｔａｍｐにおけるstamp(index(I),mod(I-1,L)+1)に対してＩの値を格納するステップと、
（５）Ｉを１からＮまで変化させて、stamp(index(I),mod(I-1,L)+1)がＩと一致するか否かを判定するステップと、
（６）ステップ（５）での判定でstamp(index(I),mod(I-1,L)+1)がＩと一致しないＩがＮ′個（ここで、Ｎ′は１以上の整数）存在する場合、その一致しないＩのリストを生成し且つ要素数Ｎ′の配列ｌｉｓｔとして前記記憶手段に格納するステップと、
（７）配列Ａの要素と作業配列Ｗの要素とを用いて、
【００１９】
【数１３】
0003845711.tif 000002
（ここで、modは剰余を計算する関数である。）で表される式に基づいてlist(I)について１からＮ′まで順に計算して、その結果を対応する作業配列Ｗに格納するステップと、
（８）配列ｓｔａｍｐにおけるstamp(index(list(I)),mod(list(I)-1,L)+1)に対してＩの値を格納するステップと、
（９）Ｉを１からＮまで変化させて、stamp(index(list(I)),mod(list(I)-1,L)+1)がＩと一致するか否かを判定するステップと、
（１０）ステップ（９）での判定でstamp(index(list(I)),mod(list(I)-1,L)+1)がＩと一致しないＩが存在する場合、その一致しないＩのリストを配列ｌｉｓｔに格納するステップと、
（１１）ステップ（９）での判定でstamp(index(list(I)),mod(list(I)-1,L)+1)がＩと一致しないＩが存在しなくなるまで、ステップ（７）からステップ（１０）までを繰り返すステップと、
（１２）ステップ（５）での判定でstamp(index(I),mod(I-1,L)+1)がＩと一致しないＩが存在しない場合、又はステップ（９）での判定でstamp(index(list(I)),mod(list(I)-1,L)+1)がＩと一致しないＩが存在しない場合に、処理を終了するステップとを備える本発明の方法及びベクトル計算機により実行されるプログラムにより解決される。
【００２０】
上記課題はまた、配列Ｆに対して別の配列Ａの要素を加算するときに、その加算要素の位置を決定する中間配列ｉｎｄｅｘが存在し、
【００２１】
【数１４】
F(index(I)):=F(index(I))+A(I)
の式であって、Ｉは１からＮ（ここで、Ｎは２以上の任意の整数）までの範囲を全て昇順に網羅する上記式により表される間接アドレス参照を含む加算を高速処理するベクトル計算機において、
配列Ｆ、Ａ及びｉｎｄｅｘを格納する記憶手段と、
前記記憶手段には、配列Ｆと同じ同じ大きさの作業配列をＬ個（ここで、Ｌは２以上の整数）が設けられており、そのＬ個の作業配列をＷ（Ｉ，Ｊ）の２次元表記で表し、Ｗの１次元目の大きさは配列Ｆの大きさに一致し、２次元目の大きさがＬであり、且つその作業配列Ｗの全要素が０をセットされており、
更に前記記憶手段には、作業配列Ｗと同じサイズでｓｔａｍｐ（ｓ1，ｓ2）の２次元表記で表される配列ｓｔａｍｐが設けられており、
（１）配列Ａの要素と作業配列Ｗの要素とを用いて、
【００２２】
【数１５】
W(index(I),mod(I-1,L)+1:=W(index(I),mod(I-1,L)+1)+A(I)
（ここで、modは剰余を計算する関数である。）で表される式に基づいて計算して、その結果を対応する作業配列Ｗに格納し、
（２）配列ｓｔａｍｐにおけるstamp(index(I),mod(I-1,L)+1)に対してＩの値を格納し、
（３）第１の判定において、Ｉを１からＮまで変化させて、stamp(index(I),mod(I-1,L)+1)がＩと一致するか否かを判定し、
（４）第１の判定でstamp(index(I),mod(I-1,L)+1)がＩと一致しないＩがＮ′個（ここで、Ｎ′は１以上の整数）存在する場合、その一致しないＩのリストを生成し且つ要素数Ｎ′の配列ｌｉｓｔとして前記記憶手段に格納し、
（５）配列Ａの要素と作業配列Ｗの要素とを用いて、
【００２３】
【数１６】
0003845711.tif 000003
（ここで、modは剰余を計算する関数である。）で表される式に基づいてlist(I)について１からＮ′まで順に計算して、その結果を対応する作業配列Ｗに格納し、
（６）配列ｓｔａｍｐにおけるstamp(index(list(I)),mod(list(I)-1,L)+1)に対してＩの値を格納し、
（７）第２の判定において、Ｉを１からＮまで変化させて、stamp(index(list(I)),mod(list(I)-1,L)+1)がＩと一致するか否かを判定し、
（８）第２の判定でstamp(index(list(I)),mod(list(I)-1,L)+1)がＩと一致しないＩが存在する場合、その一致しないＩのリストを配列ｌｉｓｔに格納し、
（９）第２の判定でstamp(index(list(I)),mod(list(I)-1,L)+1)がＩと一致しないＩが存在しなくなるまで、上記（７）から（１０）までの処理を繰り返し、
（１０）第１の判定でstamp(index(I),mod(I-1,L)+1)がＩと一致しないＩが存在しない場合、又は第２の判定でstamp(index(list(I)),mod(list(I)-1,L)+1)がＩと一致しないＩが存在しない場合に、処理を終了する演算制御手段を備える本発明のベクトル計算機により解決される。
【００２４】
従って、２次元に拡張した作業配列を導入し、その拡張した作業配列のサイズによる剰余項を用いて作業配列の場所を指定し加算を実施することにより、ベクトル処理による加算結果の不正となる項の数が減少する。
【００２５】
また、作業配列と同型の２次元作業配列を用意し、そして上記の剰余項を用いて作業配列の場所指定による加算結果がメモリに反映されたかを検出し、その検出された項に対して結果不正項がなくなるまで同様の加算処理が繰り返し進行される。
【００２６】
そして、投機的なベクトル処理の対象となる配列を２次元配列にすることで、アドレスの衝突の頻度を緩和している。
【００２７】
【発明の実施の形態】
初めに、従来の技術の欄におけるｄｅｐｏｓｉｔ式（１）が、表１に示されるプログラムで記述されるものとする。
【００２８】
【表１】
0003845711.tif 000004
【００２９】
ここで、ｎは加算要素（配列ａ）の総数、ｍはｆの定義域の上限であり、配列ｉｎｄｅｘの値域も［１：ｍ］に一致していると仮定する（ｎ，ｍ≧１）。また、配列ｉｎｄｅｘの値をキーと呼び、本明細書中ではこのキーが取り得る値の総数をｉｎｄｅｘの分布と呼び、またその総数を記号ｌ（アルファベットＬの小文字）で表す。ｌはｉｎｄｅｘ値の重複の平均値を意味しており、密度の逆数（ｍ／ｄｅｎｓｉｔｙ）に対応すると考えてよく、即ちインデックスの重複度合いと考えることができる。ベクトル処理をする際の、ハードウエア・ベクトル・レジスタ長は、ＮVと記述すると共に、プログラム中にベクトルを表現するために表記「／／」を使用する。特に、ｎからｍまでの要素を持つベクトルを／ｎ：ｍ／で表す。更に、ｄｅｐｏｓｉｔ式（１）の計算性能として、ｎをプログラム実行時間で割った値、つまり単位時間（秒）当たり加算可能な要素数を用い、ＥＰＳ（Ｅｌｅｍｅｎｔｓ  Ｐｅｒ  Ｓｅｃｏｎｄ）と表記する。
【００３０】
次に、従来の技術の欄におけるｄｅｐｏｓｉｔ式（１）の本発明による処理概念を説明する。配列Ｆと同じ大きさの作業配列をＬ個（Ｌは２以上の整数）を用意し、それをここではＷ（Ｉ，Ｊ）の様に２次元表記でもって記述することにする。但し、Ｗの１次元目の大きさはＦの大きさに一致し、２次元目の大きさはＬである。
【００３１】
予めＷの全要素に０をセットしておく。
次に、
【００３２】
【数１７】
W(index(I),mod(I-1,L)+1:=W(index(I),mod(I-1,L)+1)+A(I)        （２）
で表される式を実行する。ここで、ｍｏｄは剰余を計算する関数である。説明のための例示としてＬ＝３の時を想定する。なお、本発明は、Ｌは３に限定されず、２以上の任意の数を取りうる。レジスタには、｛Ａ（１），Ａ（２），Ａ（３），Ａ（４）｝が格納され、メモリへの書き込みで、Ｗ（１，１）にＡ（４）、Ｗ（１，２）にＡ（２）、Ｗ（１，３）にＡ（３）がそれぞれ記録される。次に、Ｗの１次元部分がｐである全ての総和とＦ（ｐ）の要素の加算を行い、Ｆ（ｐ）に格納する。つまり、次式
【００３３】
【数１８】
F(p):=F(p)+W(p,1)+W(p,2)+W(p,3)
の計算を実施する。
【００３４】
この結果、配列Ｆには、｛Ｆ（１）＋Ａ（２）＋Ａ（３）＋Ａ（４），Ｆ（２），Ｆ（３），Ｆ（４）｝が計算結果として記録される。この値は、もともとの計算式の意味を考えると、正しい値を示していない。
【００３５】
正しい値は、｛Ｆ（１）＋Ａ（１）＋Ａ（２）＋Ａ（３）＋Ａ（４），Ｆ（２），Ｆ（３），Ｆ（４）｝であるべきなので、先に示した結果不正が生じている。この結果不正を次に示す様に検出する。Ｗと同じサイズの配列ｓｔａｍｐを用意する。配列ｓｔａｍｐをｓｔａｍｐ（ｓ1，ｓ2）の２次元表記で表す。
【００３６】
【数１９】
W(index(I),mod(I-1,L)+1:=W(index(I),mod(I-1,L)+1)+A(I)        （２）
の加算処理を行うのに引き続き、stamp(index(I),mod(I-1,L)+1)に対してＩの値を代入する。この代入操作は一旦レジスタにデータが格納された後にメモリに書き込まれるため、stamp(index(I),mod(I-1,L)+1)がＩと一致した項のみが正しい加算処理の値を反映していることになる。従って、Ｉを１からＮまで変化させ、stamp(index(I),mod(I-1,L)+1)がＩでないＩのリストを作成し、そのリストに対応する加算を再定義する。つまり、作成された新しいリストをｌｉｓｔ、その要素数をＮ′とすると、
【００３７】
【数２０】
F(index(list(I))):=F(index(list(I)))+A(list(I))
の計算式を１からＮ′まで順に正しく行えばよい。この計算式は、元の問題のＩの表記をｌｉｓｔ（Ｉ）に置き換えたものであり、メモリからレジスタへの読み込み・書き込みの際に、変数ｌｉｓｔの値を間接的に参照する処理が追加されるのみで、主要な処理は上で述べたものが利用できる。つまり、上記手法を再帰的に実行することで、結果不正の項を全て加算し、正しい値を結果に反映させることができる。
【００３８】
具体的な処理として、式（２）におけるＩをｌｉｓｔ（Ｉ）に置き換えて、stamp(index(list(I)),mod(list(I)-1,L)+1)がＩと一致しないＩが存在しなくなるまで、繰り返し計算する。
【００３９】
図１に、本発明による結果不正項の訂正の概念を示す。図１において、上段には計算過程が、下段には結果不正項を検出する過程がそれぞれ示されている。点線で囲まれた部分が、Ｒｅｔｒｙアルゴリズム使用の前提であるベクトル計算機のレジスタからメモリへの書き込み動作の特性部分を示すものである。図１中のリスト・ベクトルｉｎｄｅｘ（）の網掛け部分が結果正常となる部分であり、ｆ（ｌ）への書き込み成功数は３となる。一方、結果不正の積み残しの数は１となっている。なお、本発明の手法は、ＲｅｔｒｙアルゴリズムとＷｏｒｋ  Ｖｅｃｔｏｒアルゴリズムの中間に位置することから、本発明のアルゴリズムをＲｅｔｒｙ−ＷＶアルゴリズムとも本明細書で呼ぶ。表２に本発明のＲｅｔｒｙ−ＷＶアルゴリズムの一例を示す。
【００４０】
【表２】
0003845711.tif 000005
【００４１】
次に、本発明の理解を容易にするため、図２から図１２を参照して具体的数値を用いて説明するが、この説明は単なる例示であって本発明を限定するものではない。なお、図２から図１２に示される処理はベクトル計算機の演算制御装置（図示せず）により実行される。
【００４２】
図２の（０）に示されるように、配列ｆ及びａ、及び中間配列ｉｎｄｅｘがメモリに設けられていて、配列ｆの要素数ｍが４であり、配列ａ及び中間配列ｉｎｄｅｘの要素数ｎが４であり、初期状態として各配列の要素に図示ようなような数値が格納されているとする。最初に、配列ｆと同じ大きさ、即ち大きさが４の作業配列をＬ＝３、即ち３個メモリに予め形成する。この作業配列をｗ（Ｉ，Ｊ）の２次元表記で表す。ここで、Ｉは１から４までの値をとり、Ｊは１から３までの値を取る。作業配列ｗの各要素は、図２の（０）に示されるように初期状態として０が格納されている。次いで、作業配列ｗと同じサイズの配列ｓｔａｍｐをメモリに予め形成しておく。この配列ｓｔａｍｐをｓｔａｍｐ（ｓ1，ｓ2）の２次元表記で表す。なお、配列ｓｔａｍｐの各要素の値は初期状態としては任意の数でよく、図２の（０）の配列ｓｔａｍｐの各要素に示されるｘは任意の数を表すことを意味する。
【００４３】
次いで、図２の（１）に示されるように、配列ｉｎｄｅｘの各要素がその並び順に、予め設けられている可変長のレジスタ１に読み込まれる。
図３の（２）に示されるように、拡張アドレスの計算が行われる。即ち、予め設けられている可変長のレジスタ２にｗの２次元目を表す値がＩ＝１，２，３（一般形式では、１，２，…，Ｌ）の昇順繰り返しの形で格納される。この例では、図示のように、レジスタ２の上から下の位置に１，２，３，１と格納される。次に、レジスタ１及びレジスタ２において位置が対応する各要素を用いて、図示のようにｗ（Ｉ，Ｊ）の２次元アドレスを生成し、レジスタ１に格納する。
【００４４】
次いで、図３の（３）に示されるように、作業配列の間接アドレスの読み込みが行われる。即ち、レジスタ１の各要素が表すｗ（Ｉ，Ｊ）の２次元アドレスに対応する作業配列ｗの要素が順に読み出されて、図示のようにレジスタ２にその順に格納される。
【００４５】
図４の（４）に示されるように、配列ａ（）の読み込みが行われる。即ち、配列ａ（）の各要素が順に読み出されて、予め設けられている可変長のレジスタ３に図示のように格納される。
【００４６】
次いで、図４の（５）に示されるように、作業配列と配列ａ（）の加算が行われる。即ち、ステップ（３）でレジスタ２に読み込まれた作業配列ｗの要素とステップ（４）でレジスタ３に読み込まれた配列ａ（）の要素とを対応する位置同士で加算して、図示のようにレジスタ２に格納する。
【００４７】
次いで、図５の（６）に示されるように、加算結果の作業配列ｗへの間接アドレス書き込みが行われる。即ち、レジスタ１の要素と位置的に対応するレジスタ２の要素を、レジスタ１のその要素が表すｗの２次元アドレスの位置に順に格納する。従って、最初にレジスタ２の一番上の「１」がｗ（１，１）に格納され、次いでレジスタ２の上から２番目の「３」がｗ（１，２）に格納され、そしてレジスタ２の上から３番目の「５」がｗ（１，３）に格納される。そして更に、レジスタ２の最後の「７」が、既に「１」を格納しているｗ（１，１）に図示のように格納、即ち上書きされる。つまり、ｗ（１，１）の要素は「７」となり、レジスタ２の「１」は結果的にｗに書き込まれないことになる。
【００４８】
図５の（７）に示されるように、加算結果の確認準備及びオーダー書き込みが行われる。即ち、レジスタ２に格納されている要素数までの数、即ちここでは４までの数１，２，３，４が昇順でレジスタ２に図示のように格納される。次いで、レジスタ１の要素が表すｓｔａｍｐの２次元アドレスにその要素に対応するレジスタ２の要素を読み出して書き込む。従って、最初にレジスタ２の一番上の「１」がｓｔａｍｐ（１，１）に格納され、次いでレジスタ２の上から２番目の「２」がｓｔａｍｐ（１，２）に格納され、そしてレジスタ２の上から３番目の「３」がｓｔａｍｐ（１，３）に格納される。そして更に、レジスタ２の最後の「４」が、既に「１」を格納しているｓｔａｍｐ（１，１）に図示のように格納、即ち上書きされる。つまり、ｓｔａｍｐ（１，１）の要素は「４」となり、レジスタ２の「１」は結果的にｓｔａｍｐに書き込まれないことになる。
【００４９】
次いで、図６の（８）に示されるように、加算結果の確認／書き込み結果の読み込みが行われる。即ち、レジスタ１の要素が表すｓｔａｍｐの２次元アドレスに格納された要素が順に読み出されてレジスタ３に読み込まれる。従って、レジスタ３の一番上にはｓｔａｍｐ（１，１）の要素「４」が、レジスタ３の上から２番目にはｓｔａｍｐ（１，２）の要素「２」が、レジスタ３の上から３番目にはｓｔａｍｐ（１，３）の要素「３」が、レジスタ３の最後にはｓｔａｍｐ（１，１）の要素「４」が、図示のように読み込まれる。
【００５０】
図６の（９）に示されるように、加算結果の確認及び結果不正項の検出が行われる。即ち、レジスタ３の各要素とレジスタ２の各要素とが、位置が対応する同士で比較され、一致・不一致が判定され、判定結果が図示のようにレジスタ３に格納される。図示の例では、×が不一致を、○が一致を表す。不一致を表すレジスタ３の要素に位置的に対応するレジスタ２の要素を、予めメモリに設けられている可変長の配列ｌｉｓｔ（）に、検出された結果不正項として格納する。ここでは、図示のように、レジスタ２の１番上の要素「１」のみが不一致であるので、ｌｉｓｔ（）の１番目に格納されている。なお、不一致の要素が複数ある場合には、レジスタ２に格納されている並び順にｌｉｓｔ（）に詰めて格納される。また、後述するように、不一致の要素がない場合には、ｌｉｓｔ（）への書き込みは行われず、ｌｉｓｔ（）は「空（から）」の状態にしておく。
【００５１】
次いで、全てのレジスタをクリアする。
図７の（１０）に示されるように、再試行のため配列ｌｉｓｔの読み込みが行われる。即ち、図示のように、ｌｉｓｔ（）の各要素をレジスタ２に順に読み込む。
【００５２】
次いで、図７の（１１）に示されるように、中間配列ｉｎｄｅｘの間接アドレス読み込みが行われる。即ち、レジスタ２の要素が表すｉｎｄｅｘ（）の位置の要素がレジスタ１に順に読み込まれる。
【００５３】
そして、ｌｉｓｔ（）が生成されなくなる、即ちｌｉｓｔ（）が「空（から）」の状態になるまで、ステップ（２）から再試行を繰り返す。以下、ステップ（２）から（８）までと類似の再試行については、ＩＩを各ステップの先頭に付して説明する。
【００５４】
図７のステップ（１１）に引き続いて、図８のＩＩ−（２）に示されるように拡張アドレスの計算が行われる。即ち、図３のステップ（２）と同様にして、レジスタ２にｗの２次元目を表す値がＩ＝１，２，３（一般形式では、１，２，…，Ｌ）の昇順繰り返しの形で格納される。ここでは、レジスタ１の要素が１個であるので、図示のように、レジスタ２に１だけが格納される。次に、レジスタ１及びレジスタ２において位置が対応する各要素を用いて、図示のようにｗ（１，１）の２次元アドレスを生成し、レジスタ１に格納する。
【００５５】
次いで、図８のＩＩ−（３）に示されるように、作業配列の間接アドレスの読み込みが行われる。図３のステップ（３）と同様にして、レジスタ１の要素が表すｗ（１，１）の２次元アドレスに対応する作業配列ｗの要素「７」が読み出されて、レジスタ２に格納される。
【００５６】
図９のＩＩ−（４）に示されるように、配列ａ（）の読み込みが行われる。即ち、図４のステップ（４）と同様にして、レジスタ２の要素数（ここでは１）だけ順に配列ａ（）の各要素が読み出されるので、レジスタ３には図示のように「１」だけが格納される。
【００５７】
次いで、図９のＩＩ−（５）に示されるように、作業配列と配列ａ（）の加算が行われる。即ち、図４のステップ（５）と同様にして、ステップＩＩ−（３）でレジスタ２に読み込まれた作業配列ｗの要素（ここでは、「７」のみ）とステップＩＩ−（４）でレジスタ３に読み込まれた配列ａ（）の要素（ここでは「１」のみ）とを対応する位置同士で加算して、「８」を図示のようにレジスタ２に格納する。
【００５８】
次いで、図１０のＩＩ−（６）に示されるように、加算結果の作業配列ｗへの間接アドレス書き込みが行われる。即ち、図５のステップ（６）と同様にして、レジスタ１の要素と位置的に対応するレジスタ２の要素を、レジスタ１のその要素が表すｗの２次元アドレスの位置に順に格納する。従って、ここではレジスタ２の「８」がｗ（１，１）に格納される。それにより、前回の計算で加算されなったａ（１）の「１」が加算されたことになる。
【００５９】
図１０のＩＩ−（７）に示されるように、加算結果の確認準備及びオーダー書き込みが行われる。即ち、図５の（７）と同様にして、レジスタ２に格納されている要素数までの数、即ちここでは１までの数１が昇順でレジスタ２に図示のように格納される。次いで、レジスタ１の要素が表すｓｔａｍｐの２次元アドレスにその要素に対応するレジスタ２の要素を読み出して書き込む。従って、レジスタ２の「１」がｓｔａｍｐ（１，１）に格納される。
【００６０】
次いで、図１１のＩＩ−（８）に示されるように、加算結果の確認／書き込み結果の読み込みが行われる。即ち、図６のステップ（８）と同様にして、レジスタ１の要素が表すｓｔａｍｐの２次元アドレス（ここでは（１，１）だけ）に格納された要素が順に読み出されてレジスタ３に読み込まれる。従って、レジスタ３の一番上にｓｔａｍｐ（１，１）の要素「１」が、図示のように読み込まれる。
【００６１】
図１１のＩＩ−（９）に示されるように、加算結果の確認及び結果不正項の検出が行われる。即ち、図６のステップ（９）と同様にして、レジスタ３の要素「１」とレジスタ２の要素「１」とが比較され、一致・不一致が判定され、「一致」の判定結果が図示のようにレジスタ３に格納される。ここでは、「不一致」の要素が１つもないので、ｌｉｓｔ（）への書き込みは行われず、ｌｉｓｔ（）はクリアされて「空（から）」の状態にする。
【００６２】
ｌｉｓｔ（）が生成されない状態となったので、処理は図１２のステップ（１２）に進められる。ステップ（１２）において、作業配列ｗの総和計算が行われる。即ち、配列ｆの各要素をレジスタ１に、作業配列ｗの第１列目の各要素をレジスタ２に、作業配列ｗの第２列目の各要素をレジスタ３に、作業配列ｗの第３列目の各要素を予め設けられているレジスタ４に、それぞれ読み込む。そして、図示のように、各レジスタの位置的に対応する要素同士をそれぞれ加算してレジスタ１に格納する。
【００６３】
次いで、図１２の（１３）に示されるように、レジスタ１の各要素を配列ｆに格納する。なお、本発明は、ステップ（１２）及び（１３）では、配列ｆ及び作業配列ｗの各要素を直接用いて位置的に対応する各要素を加算して配列ｆに格納してもよく、要は、配列ｆ及び作業配列ｗの位置的に対応する各要素を加算した結果が配列ｆに格納されればよい。
【００６４】
本発明を用いた場合の性能測定結果を以下に示す。測定時の条件として、配列Ｆのサイズを２14（＝１６，３８４）、加算要素数を２21（＝２，０９７，１５２）とした。ｉｎｄｅｘの分布（ｌ）を２のべき乗で変化させたときの、ＥＰＳ値（１秒当たりの加算可能要素数）をプロットした結果を図１３から図１４に示す。中間配列ｉｎｄｅｘの値は、ＮＰＢ（ＮＡＳ  Ｐａｒａｌｌｅｌ  Ｂｅｎｃｈｍａｒｋ）（Ｂａｉｌｅｙ，Ｄ．，Ｈａｒｒｉｓ，Ｔ．，Ｓａｐｈｉｒ，Ｗ．，Ｗｉｊｎｇａａｒｔ，Ｒ．，Ｗｏｏ，Ａ．，  ａｎｄ  Ｙａｒｒｏｗ，Ｍ．：ＮＡＳ  Ｐａｒａｌｌｅｌ  Ｂｅｎｃｈｍａｒｋｓ  ２．０，Ｔｅｃｈｎｉｃａｌ  Ｒｅｐｏｒｔ  ＮＡＳ−９５−０２０，（１９９５）参照）に含まれる問題ＩＳの疑似乱数生成ルーチンを用いて生成している。ＩＳ同様、連続する４個の一様乱数数列の平均をｉｎｄｅｘの値とした。なお、加算要素ａ（：）の値が性能を左右しないようにするためこの実験では簡単化して全て１としている。この設定により、この実験は、問題ＩＳと本質的に同一ヒストグラム計算を行うのと同等といえる。
【００６５】
それぞれのグラフには、Ｋ＝１６のＷｏｒｋ  Ｖｅｃｔｏｒアルゴリズム、Ｋ＝６４のＷｏｒｋ  Ｖｅｃｔｏｒアルゴリズム、Ｒｅｔｒｙアルゴリズム、本発明のＭａｓｋｉｎｇアルゴリズムの結果を示してある。ここで、各曲線の見出し部分の（）内に示した値がＫの値である。なお、Ｋ＝１６は、一般的な大規模アプリケーションで取得可能な作業配列の上限であり、Ｋ＝６４は、通常要求される性能を発揮する作業域の例である。
【００６６】
図１３は、ベクトル計算機ＳＸ−４（日本電気社製）での実験結果を示している。ＳＸ−４は比較的短いベクトル・レジスタ（ＮV＝２５６）を搭載するベクトル計算機である。間接アドレス方式のロード−ストアも高速の部類に入る。
【００６７】
図１４は、ベクトル計算機ＶＰＰ５０００（富士通社製）での実験結果を示している。対象機は、長ベクトル・レジスタを搭載し、且つ間接アドレス方式のロード−ストアが高速なベクトル計算機である。
【００６８】
キー・インデックスの数「ｌ」、即ちインデックスの重複度合いが、図１３では約２０から約１０００の間で、また図１４では約９０以上の範囲で本発明のＲｅｔｒｙ−ＷＶアルゴリズムは従来のＷｏｒｋ  Ｖｅｃｔｏｒアルゴリズム及びＲｅｔｒｙアルゴリズムより高い性能を示していることが判る。
【００６９】
【発明の効果】
従来のＲｅｔｒｙ手法では、作業配列Ｗを導入することなく、Ｆのまま加算並びに結果不正項の修正を行っていて、Ｆに直接加算処理を行うため、ｉｎｄｅｘの値によって（実際にはｉｎｄｅｘの値の重複度に応じて）結果不正が多く発生していたが、本発明では２次元に拡張した作業配列Ｗとその加算位置の算出式(index(I),mod(I-1,L)+1)によってその不正の発生を削減することができる。また、本発明の方式では、従来法と比較して、アドレスの衝突頻度が減少、即ち結果不正の頻出度を削減できるため、不正項の再処理回数が減少し、結果的に全体の処理時間が短縮でき、高速な加算処理が実現できる。
【図面の簡単な説明】
【図１】図１は、本発明による結果不正項の訂正の概念を示す。
【図２】図２は、本発明による処理を説明するための処理フロー例の部分である。
【図３】図３は、本発明による処理を説明するための処理フロー例の部分である。
【図４】図４は、本発明による処理を説明するための処理フロー例の部分である。
【図５】図５は、本発明による処理を説明するための処理フロー例の部分である。
【図６】図６は、本発明による処理を説明するための処理フロー例の部分である。
【図７】図７は、本発明による処理を説明するための処理フロー例の部分である。
【図８】図８は、本発明による処理を説明するための処理フロー例の部分である。
【図９】図９は、本発明による処理を説明するための処理フロー例の部分である。
【図１０】図１０は、本発明による処理を説明するための処理フロー例の部分である。
【図１１】図１１は、本発明による処理を説明するための処理フロー例の部分である。
【図１２】図１２は、本発明による処理を説明するための処理フロー例の部分である。
【図１３】図１３は、本発明を用いた場合の性能測定結果の一例を示す図である。
【図１４】図１４は、本発明を用いた場合の性能測定結果の一例を示す図である。
【図１】
0003845711.tif 000015
【図２】
0003845711.tif 000016
【図３】
0003845711.tif 000017
【図４】
0003845711.tif 000018
【図５】
0003845711.tif 000019
【図６】
0003845711.tif 000020
【図７】
0003845711.tif 000021
【図８】
0003845711.tif 000022
【図９】
0003845711.tif 000023
【図１０】
0003845711.tif 000024
【図１１】
0003845711.tif 000025
【図１２】
0003845711.tif 000026
【図１３】
0003845711.tif 000027
【図１４】
0003845711.tif 000028