%表題   下位基本数学処理ライブラリリファレンスマニュアル
%
%履歴
%\Drireki{
%         89/05/31  酒井 敏
%         91/09/05  林 祥介
%         91/12/20  酒井 敏
%         91/03/16  酒井 敏・塩谷雅人
%         92/04/22  林祥介   (4.1版)
%         94/01/22  塩谷雅人
%         94/04/06  酒井 敏・塩谷雅人
%         94/05/07  塩谷雅人
%         95/04/19  塩谷雅人
%        }
%
%\Dchapter{概要}
\Dchapterhead
   % \label{概要}

\section{はじめに}
   % \label{概要.intro}

  MATH1 (数学処理下位パッケージ)は,
  地球流体電脳ライブラリ群のなかでも,
  もっとも基本的なサブルーチンおよび関数を集めたパッケージである.

  \vspace{1em}
  MATH1 は, いくつかのサブパッケージからなる.
  \begin{itemize}
      \item {\bf SYSLIB : } 内部変数管理, メッセージ出力.
      \item {\bf OSLIB  : } システム依存ルーチン.
      \item {\bf FNCLIB : } 基本関数(最大整数, 剰余など).
      \item {\bf SUBLIB : } 基本サブルーチン(自然数列の生成など).
      \item {\bf CHRLIB : } 文字列の左・右詰め, 反転, 空白処理.
      \item {\bf XFCLIB : } 文字列の数値化. 
      \item {\bf LRLLIB : } 実数値の比較.
      \item {\bf BLKLIB : } 実数値と順序列.
      \item {\bf GNMLIB : } きりのよい打ち切り数.
      \item {\bf INTLIB : } 実数に近い整数.
      \item {\bf INDXLIB : } 配列要素の検索.
      \item {\bf IFALIB : } 整数の欠損値処理付最大最小など.
      \item {\bf RFALIB : } 実数の欠損値処理付最大最小など.
      \item {\bf RFBLIB : } 実数列の内積,共分散,相関係数.
      \item {\bf VIALIB : } 1つの整数型配列への作用素.
      \item {\bf VIBLIB : } 2つの整数型配列への作用素.
      \item {\bf VRALIB : } 1つの実数型配列への作用素.
      \item {\bf VRBLIB : } 2つの実数型配列への作用素.
      \item {\bf CTRLIB : } 座標変換/回転.
      \item {\bf MAPLIB : } 地図投影変換.
  \end{itemize}

  これらの中の多くのサブパッケージでは,
  「欠損値の処理」や「実数の誤差を考慮した大小関係の判定」
  ができるようになっている.
  なお, これらのサブパッケージの中でソースレベルでの機種依存性が
  あるのは OSLIB のみである.
  ( SYSLIB はシステムに依存する定数を管理している. )
  \vspace{1em}
  
  以下本章では, MATH1 の特色である内部変数管理, 欠損値処理, 
  並びに, 誤差を含めた判断について若干の解説をおこない, さらに, そのよ 
  うなパッケージのよってきたる FORTRAN 77 の構造について説明を行なう
  ことにする.

\section{内部変数}

地球流体電脳ライブラリでは,
MATH1/SYSLIB の \GLPGETSET のような{\bf 内部変数管理ルーチン}
が多く使われている.
(ここで, {\it p} は{\tt R/I/L/C} のどれかで, 
それぞれ, 実数, 整数, 論理変数, 文字変数用である. )
{\bf 内部変数管理ルーチン} とは, 設定された変数の値を保持し,
問い合わせに答えて値を返す機能を持ったルーチンで,
「掲示版」のような役目をするものである.
この様なルーチンを使う理由は,

\begin{itemize}
  \item 複数のサブルーチンで情報を共有するため.
  \item サブルーチンの引数の個数を最小限にするため.
\end{itemize}

である. 複数のサブルーチンで情報を共有するには,
COMMON BLOCK を使うこともできるが,
これを多用するとプログラムの可読性を落とすことにつながるので,
電脳ライブラリでは極力 COMMON BLOCK の使用を避けている.
また, サブルーチンの引数を少くすると融通の効かないサブルーチンになって
しまうが, かといって, むやみに引数の数を増やすとかえって使いにくくなっ
てしまう.
このような問題を解決するのが {\bf 内部変数管理ルーチン} である.
もともと「パッケージの内部で使われる変数」という意味で,
内部変数という言葉を使っているが,
その変数はパッケージ外からも設定/参照できるので,
その有効範囲からすると C 言語の「外部変数」に
似た性格を持つものである.
\vspace{1em}

内部変数管理ルーチンは \xxPGET, \xxPSET という名前
({\tt xx} は通常パッケージの先頭2文字) を持ち,
あらかじめ, システムが用意した変数の値 (システムデフォルト) を
保持している.
この値は \xxPGET によって参照,
\xxPSET によって変更することがでる. 
電脳ライブラリの多くのルーチンでは,
必要なパラメタの多くを \xxPGET によって取得しており,
ユーザーが何も指定しなければシステムデフォルトを使い,
\xxPSET で値を指定すれば, その値を使うようになっている.
\vspace{1em}

この内部変数は実行時オプションによって変更することもできる. 
実行時オプションとは, プログラム実行時に外部環境と交信することによって
内部変数への介入を可能にするような指定である. 
具体的には, 外部ファイル, 環境変数, コマンドライン引数など
による交信手段を念頭においた概念であるが,
それがどのように実現されているかは, システムに依存する.
%標準的な電脳ライブラリでは, 実行時オプションを得る手段として, 
%コマンドラインオプション, 環境変数, 外部ファイルの3種類を
%想定している. 
なお,
{\bf 実行時オプションの効力は, システムデフォルトよりも強く,
\xxPSET の指定よりも弱い. }
\vspace{1em}

実行時オプションに比べて
\xxPSET による設定は強力なので,
その設定を実行時に変更することができないが,
実行時オプションより効力の弱い \xxPSTX というルーチンも
用意されている.
これを使えば,
プログラム中でデフォルト値 (ユーザーデフォルト) を設定し,
実行時に変更することが可能になる.
\vspace{1em}

内部変数の設定手段を, その効力の強さの順に並べると,

\begin{quote}
\begin{tabular}{ll}
1: & \xxPSET \\
2: & 実行時オプション \\
3: & \xxPSTX \\
4: & システムデフォルト\\
\end{tabular}
\end{quote}

となる.
\vspace{1em}

実行時オプションは, 「オプション名」と「オプションの値」の組合せからなり, 
複数個指定できる. 
オプション名は原則として, 介入しようとする内部変数を
管理している{\tt \xxPGET /\xxPSET } の最初の2文字 {\tt 'xx'} と
内部変数名 {\tt 'PNAME'} を組み合わせて {\tt xx:PNAME} となる.
\vspace{1em}

環境変数を通してオプションを指定する場合, 
例えば UNIX の C シェル環境で \GLPGETSET が
管理する内部変数 {\tt 'MSGLEV'} を 1 に変更したいときには,

\begin{verbatim}
    > setenv GL:MSGLEV 1
\end{verbatim}

とする.
このとき{\bf 環境変数名はすべて大文字でなければならない. }
\vspace{1em}

また, コマンドライン引数を通してオプションを指定する場合は,
原則としてオプション名に {\tt -} 記号を付け, 
さらにオプション名とオプションの値の間に {\tt '='} を入れて, 
{\tt -xx:PNAME=value} という形式で指定する
(環境変数名と違って大文字・小文字の区別はない).
例えば, {\tt sample} というプログラム実行時に

\begin{verbatim}
    > sample -gl:msglev=1
\end{verbatim}

とすると, 上記の環境変数の場合と同じ結果が得られる. 
ここで, {\bf {\tt '='} 記号の前後に空白を入れてはいけない.}
\vspace{1em}

外部ファイルを通してオプションを指定する場合は, 

\begin{Dprogram}
gl:msglev  1
gl:lmiss .true.
\end{Dprogram}

のように(行のはじめの番号は便宜的につけてある), 
オプション名とオプションの値を並べて書いたファイルを, 
たとえば {\tt .dclrc} として
カレントディレクトリに用意してやればよい. 
ここで, オプション名は第1カラム目から書きはじめ, 
オプションの値との間は1個以上の空白によって
区切らなければならない(タブなどを入れてはいけない). 
読み込むファイルを検索するルールについては, 
第\ref{syslib}節を参照のこと.
\vspace{1em}

なお, 環境変数, コマンドライン引数, 外部ファイルを通して
同じオプションを指定した場合には,
原則としてその優先順位はコマンドライン引数, 
環境変数, 外部ファイルを通して指定したもの順になる.
(コマンドライン引数による指定が一番強い.)

%----------------------------------------------------------------------
\section{欠損値処理}
  % \label{概要.MISS}

自然を相手に観測などする場合,
観測機器の不調等により正常にデータが取れない場合がある.
そのような場合, 本来データを書くべきところに,
特定のある数値 (例えば999.) を書いて,
正常にデータが取れていないことを示すことがある.
この「正常なデータでない」ことを意味する数値が欠損値である.
地球流体電脳ライブラリの多くのパッケージでは,
このような欠損値を含むデータを直接扱うことができる.
\vspace{1em}

例えば,
次のようなデータがあったとしよう.

\vspace{1em}
\begin{center}
\begin{tabular}{c|ccccccc}
  \hline
  \multicolumn{7}{c}{\gt 日最高気温の月平均値} \\
  \hline\hline
  月$\backslash$観測点 & 札幌   & 仙台   & 東京
              & 名古屋 & 京都   & 福岡   & 鹿児島 \\
  \hline
  1月 & -1.1 &  5.0 &  9.5 &  8.4 & 999. &  9.3 & 12.2 \\
  7月 & 24.8 & 25.6 & 28.8 & 999. & 999. & 30.6 & 31.4 \\
  \hline
\end{tabular}
\end{center}

\vspace{1em}
1月の京都, 7月の名古屋, 京都の 999. は
データが正常に得られなかったことを示している.
1月, 7月それぞれの月のデータを配列{\tt T1}, {\tt T7}に読み込んで
平均値を算出するとき,
999. まで有効なデータとして扱ってしまうと,
とんでもない値が算出されてしまう.
そこで, 以下のように
\GLPGETSET が管理する内部変数{\tt 'LMISS'}を
{\tt .TRUE.}として(初期値は{\tt .FALSE.})
RFALIBの{\tt RAVE}を用いれば,
999. を除いた平均値が算出できる.

\begin{Dprogram}
      CALL GLLSET('LMISS', .TRUE.)
      TAVE1 = RAVE(T1, 7, 1)
      TAVE7 = RAVE(T7, 7, 1)
\end{Dprogram}

なお, 欠損値処理をおこなうことができる関数では,
すべての配列要素が欠損値のときは欠損値が返される.

\vspace{1em}
また, VRBLIBの{\tt VRADD}を用いて
配列{\tt T1}と{\tt T7}の和を{\tt TX}として求めるときは,

\begin{Dprogram}
      CALL GLLSET('LMISS', .TRUE.)
      CALL VRADD(T1, T7, TX, 7, 1, 1, 1)
\end{Dprogram}

としてやればよい.
{\tt 'LMISS'}を{\tt .TRUE.}としたとき,
{\tt VRADD}は{\tt T1}および{\tt T7}の配列要素の少なくとも
どちらかが欠損値ならば欠損値を返すようになっているので,
この場合, 名古屋, 京都に対応する{\tt TX}の配列要素は
欠損値となる.

\vspace{1em}
欠損値は \GLPGETSET が管理する内部変数
{\tt 'RMISS'}で指定され, 初期値は 999. である.
999. という値は, 気温としては本来ありえない値なので,
気温データなどの場合には問題はないが,
この値がデータの範囲に入ってしまうような場合には,
{\tt 'RMISS'}の値を変更しておく必要がある.

%----------------------------------------------------------------------
\section{誤差を含めた判断}
% \label{概要.MISS}

計算機内部で実数値は近似的に扱われるため,
どうしても誤差を含んでしまう.
例えば,

\begin{Dprogram}
      LOGICAL LEQ

      X = 1.
      Y = X/3.
      LEQ = X .EQ. (Y*3.)
\end{Dprogram}

というプログラムでは{\tt LEQ}は{\tt .TRUE.}にならない.
しかし, もともと{\tt X}や{\tt Y}は近似値なのであるから,
それらを比較するときも近似的に比較するのが合理的であり,
実際そのような比較をしたい場合も多い.
すなわち, {\tt X}と{\tt Y*3.}が正確に一致するかどうかではなく,
近似的に一致するかどうか調べたい場合も多い.
\vspace{1em}

そのような場合のために, LRLLIB が用意されている.
例えば,

\begin{Dprogram}
      LOGICAL LEQ, LREQ

      X = 1.
      Y = X/3.
      CALL GLLSET('LEPSL', .TRUE.)
      LEQ = LREQ(X, Y*3.)
\end{Dprogram}

とすると,
近似的な比較が可能になる.
{\tt LREQ} は LRLLIBの関数で,
2つの値が計算機の精度内で近似的に一致するかどうか調べるものである.
ここでいう計算機の精度とは \GLPGETSET の管理する内部変数{\tt 'REPSL'}に
{\tt 'RFACT'}をかけた値である.
{\tt 'REPSL'}には,
実際の実数の内部表現の精度に安全率として10倍をかけた値が設定されており,
{\tt 'RFACT'}には初期値として1が設定されている.
{\tt 'REPSL'}はライブラリのインストール時に決るもので,
この値をプログラムの中で変更することはできないが,
計算精度が悪くて,
この値よりもラフな比較をしたい時には,
内部変数 {\tt 'RFACT'}に1以上の数値を指定すればよい.
\vspace{1em}

LRLLIBだけでなく, MATH1のいくつかのサブパッケージには同様の機能がある.
