情報基礎A 「Cプログラミング」総合演習
このページでは、電力量のデータをCのプログラムで扱うための「支援プログラム(tsa-helper.c)」について、使い方や仕様を説明する。
「支援プログラム」の仕様
データの表現
基本的に、時刻は、対象とする年の元旦午前0時からの経過時間(整数値)で表現する。
電力量はfloat型の実数値で表現。単位は 万kW・時。
CSV形式のデータの読み出し
int n ; float data[10000] ; ・・・ n = read_csv("CSVファイル名",data) ;
あらかじめ、データを格納するのに十分な大きさのfloat型の配列を用意しておく
(上の例では、配列data
。1年分で24*365 = 8760 以上のサイズが必要)。
read_csv()
関数は、"CSVファイル名"で指定したファイルから電力量の数値を読み出し、
時間ごとの電力量(万kW・時)を、float型の配列に順に格納する。
読み込まれたデータ点の数の総数(時系列の長さ)が、関数の戻り値として返される(上の例では変数nにそれがセットされる)。
すなわち、注目している年の、正月深夜0時から1時までの電力量が data[0]、大晦日23時から24時までの電力量は data[n-1]
にセットされる。
ただし、今年分のデータについては(まだ大晦日はずっと先なので)、「ダウンロードした日より前(のある時点)」で、データはおしまいとなっている。
そんな場合でも、(上の例の)変数n
には、ただしいデータ件数がセットされるようになっている。
閏年で年間の時間数が平年と異なる場合も同様。
実行後に、読み込みファイル名と、読み込まれたデータ数が、画面に出力される。
経過時間から日付/時刻への換算
print_date_plus_hour(西暦年, 月, 日, 時間数) ;
基点となる年月日の深夜零時から、指定した時間数が経過した後の、「年/月/日 時刻」を画面にプリントする。 行末の改行コードなし。
print_date_plus_hour(2011,1,1,1234) ; printf("\n") ;
上記のプログラム(の部分)を実行すると、画面には
2011/2/21 10:00
と表示される。2011年1月1日午前0時から1234時間後は"2011/2/21 10:00"である。
二つの日付/時刻が何時間離れているかを計算
int d ; ・・・ d = diff_in_hour(年1, 月1, 日1, 時刻1, 年2, 月2, 日2, 時刻2) ;
二つの時刻:(年2)/(月2)/(日2) (時刻2):00 と (年1)/(月1)/(日1) (時刻1):00 の差を、時間を単位として返す。
int d ; ・・・ d = diff_in_hour(2012,7,1,0,2012,8,1,0) ; printf("%d\n",d) ;
を実行すると、2012/8/1から2012/7/1までの(1ヶ月の)時間数に相当する744がプリントされる。
日付から曜日を求める
バグを修正しました(7/16)
int dow ; ... dow = day_of_the_week(西暦年, 月, 日) ;
西暦年/月/日 をそれぞれ整数値として与えると、対応する曜日を整数値として返す。 0が日曜、1が月曜、...、6が土曜。
ARモデルの係数を求める
仕様を変更しました(7/16)
float data[10000] ; float coef[51],sigma ; int n,p ; ・・・ n = read_csv("CSVファイル名",data) ; ・・・ p = 次数 ; sigma = arcoef(p, n, data, coef) ;
時系列データ(data)を元に、AR(p)モデルの係数を計算し、配列(coef)にセットする。
coef[0]
には前ページの解説の$a(0)$が、coef[1]
には$a(1)$が、
coef[p-1]
には$a(p-1)$が、それぞれ対応し、
coef[p]
には定数項$c$がセットされる。
よって、係数を格納する配列(coef)はp+1以上の大きさを確保する必要がある。
また、関数の戻り値として、ランダムな変動分の標準偏差(予測誤差)$\sigma$が変数sigma
にセットされる。
プログラム上、モデルの次数(p
の値)として設定できる上限値は999。
ガウス分布に従う乱数を生成する
float r ; ... r = dgauss() ;
平均0, 分散1のガウス分布に従う乱数値を返す。
dgauss()
を呼び出す度に、異なる(乱数の)数値が、上の例では変数rにセットされる。
dgauss()
関数を使った次のコード
for (i=0; i<5 ; i++) printf("%f ",dgauss()); printf("\n") ;
を実行すると、例えば、
1.115775 -0.738492 0.720115 0.044360 -0.370444
擬似乱数は、「毎回違う動作をさせる」などの目的で、ゲーム等にも使われている。
のように表示される。このように、コンピュータによって擬似的にランダムな数値が生成することができて、 その分布を調べると、ガウス分布(正規分布)になっている(そうなるようにプログラムされている)。