東京理科大学 infoserv[更新日]1999.11.10


問9 次の Fortran プログラムの説明及びプログラムを読んで, 設問に答えよ。

〔プログラムの説明〕

数値計算の分野で行列を扱う問題においては,計算量及び主記憶使用量は行列の 大きさに依存して増大する。ここでは,ゼロの要素が多い疎行列の一つである帯行列に 対して,値がゼロの要素を省略して記憶する方法を考える。

このプログラムは,帯行列の帯幅を求め,各行ごとに帯幅部分のデータを配列に 格納し,その内容を出力する。ここで,帯行列とは,図 1 のように対角要素付近に 非ゼロ要素が分布している正方行列である。

 


           図1 入力データ例

(1) 非ゼロ要素が対角要素付近に分布している帯行列を,配列 wa に入力する。 プログラムでは,絶対値が 10−6 以上の要素を非ゼロ要素と判定する。

(2) 行列の帯幅を求める。
 row 番目の行に対して,

 左端から第 row−1 列までを調べて, 最初の非ゼロ要素の列番号を kl とする。

 右端から第 row+1 列までを調べて, 最初の非ゼロ要素の列番号を kr とする。

 row−kl と kr−row の大きい方を length とする。

こうして得られたすべての行における length の中の最大値を 2 倍して 1 を 加えた値が帯幅である。例えば,図 1 に示す帯行列の 3 行目は,row=3,kl=1, kr=5 であり,row−kl=2,kr−row=2 となる。この帯行列の場合,すべての行に おける
length の中の最大値は 2 なので,帯幅は 5 となる。

(3) 帯幅分の要素を格納する配列 wb (行数,帯幅) の領域を確保する。

(4) wa の対角要素が wb の中央の列に並ぶように,帯幅分の要素を wb に 格納する。
wb の要素で,wa に対応する要素がない箇所にはゼロを格納する。

(5) 図 1 の入力データに対する出力結果を図 2 に示す。

  band width=    5     data size=   35
 
    data
        0.000000   0.000000   3.000000   2.000000   1.000000
        0.000000   2.000000   3.000000   2.000000   1.000000
        1.000000   2.000000   3.000000   2.000000   1.000000
        1.000000   0.000000   3.000000   0.000000   1.000000
        0.000000   2.000000   3.000000   2.000000   0.000000
        1.000000   2.000000   3.000000   2.000000   0.000000
        1.000000   2.000000   3.000000   0.000000   0.000000

            図2 出力結果例

〔プログラム〕

    real,dimension(:,:),allocatable::wa,wb
    integer::na,width,wmax,index,row,k,left,right,length
    real,parameter::eps=1.0e-06
    read(*,*) na
    allocate(wa(na,na))
    read(*,*) ((wa(row,k),k=1,na),row=1,na)
    wmax = 0
    do row=1,na
      k = 1
      left = 0
      do while () 
        if(abs(wa(row,k))>=eps) then
          left = row-k
        end if
        k = k+1
      end do
      k = na
      right = 0
      do while () 
        if(abs(wa(row,k))>=eps) then
          right = k-row
        end if
        k = k-1
      end do
      length = max(left,right)
      wmax = max(wmax,length)
    end do
    width = wmax*2+1
    allocate(wb(na,width))
    do row=1,na
      index = 0
      left = 
      right = left+width-1
 
      do k=left,right
        index = index+1
        if() then
          wb(row,index) = 0.0
        else
          wb(row,index) = wa(row,k)
        end if
      end do
    end do
    deallocate(wa)
    write(*,100) width,width*na
    write(*,200) ((wb(row,k),k=1,width),row=1,na)
100 format('    band width=',i5,'   data size=',i5)
200 format('      data'/('     ',5f14.6/))
    end

設問 プログラム中の に入れる正しい答えを,解答群の中から選べ。

a,b に関する解答群

 ア k<row .and. left==0    イ k<row .and. right==0

 ウ k<row .or. left==0    エ k<row .or. right==0

 オ k>row .and. left==0    カ k>row .and. right==0

 キ k>row .or. left==0    ク k>row .or. right==0

 

c に関する解答群

 ア row        イ row+wmax

 ウ row+wmax-1    エ row-wmax

 オ row-wmax+1    カ row-wmax-1

 

d に関する解答群

 ア index<1 .and. index>na    イ index<1 .or. index>na

 ウ index>1 .and. index<na    エ index>1 .or. index<na

 オ k<1 .and. k>na    カ k<1 .or. k>na

 キ k>1 .and. k<na    ク k>1 .or. k<na

 


東京理科大学 infoserv 戻る 次頁:問10