(Java)assert文
Eclipseでassert文を使う方法
assert文でエラーがどうやっても発生しなかったので調べてみた。
メニュー → 実行構成 → Javaアプリケーション → (x)=引数 → VM引数に「-ea」と書いて実行
やってみたらうまくいきました。
java コマンドによる実行時にも、フラグで有効にしないと、アサーション行は空行と等価の扱いで無視されます。 開発時にはデバッグのために有効にして、本番稼動時には無効にするのが基本的な使い方です。
だそうです。
(Java)enum(列挙型)のまとめ
基本的にクラスと同じ扱い
enum Number{ ONE, TWO, THREE, FOUR, FIVE ;} //セミコロンは無くてもいい public class Test { public static void main(String[] args) {} public enum Number2{ ONE2, TWO2, THREE2, FOUR2, FIVE2 ;} }
クラスの外でも中でも宣言できる。
使い道
割とよく見る条件分岐を使った使用法。
enum Number{ONE, TWO, THREE, FOUR, FIVE} public class Test{ public static void main(String[] args) { System.out.println(returnNumber(Number.FOUR)); } static int returnNumber(Number num){ switch (num) { case ONE: return 1; case TWO: return 2; case THREE: return 3; case FOUR: return 4; case FIVE: return 5; default: return 0; } } }
出力
4
クラスちっくな使い道
enum Season{ SPRING(1,"春"), Summer(2,"夏"), AUTUMN(3,"秋"), WINTER(4,"冬"); private final int num; private final String kanji; Season(int num, String kanji) { this.num = num; this.kanji = kanji; } int getNum(){ return num; } String getKanji(){ return kanji; } } public class Test{ public static void main(String[] args) { for(Season s : Season.values()){ System.out.println(s.getNum() + ":" + s.getKanji()); } } }
出力
1:春 2:夏 3:秋 4:冬
enum、私は「いーなむ」という謎の読み方をしていましたが元々enumerateからきているようなので「エ(イ)ニューム」が正しい読みになりそうですね。
(Java)JavaSEのインストールとエスケープシーケンスの復帰「\r」
Win8にしてから改めてJavaSEをインストールしたので色々まとめ
JavaSEのインストール
- http://www.oracle.com/technetwork/java/javase/downloads/index.html⇒Java Platform, Standard EditionのJDKダウンロード⇒Windows x64版Java SE Development Kit 7u○○のインストーラをゲット
- 適当にYesを選択してインストール
- C:\Program Files\Java\jdk1.6.0_▲▲\binの中にjavac.exeがあることを確認したらシステム環境変数に「C:\Program Files\Java\jdk1.6.0_▲▲\bin」を追加
- 再起動
これで使えるようになります。
使い方のサンプル
- Cドライブ直下にJavaTestというフォルダを作り、「HelloWorld」と出力するコードが書かれたTest.javaというファイルを置く
- コマンドプロンプトで cd \JavaTest と入力してカレントディレクトリを移動
- javac Test.java と入力してTest.classが作成されるのを確認
- java Test と入力して実行
これでHelloWorldが表示されたんじゃないかと思います。なお、プログラムの強制終了はCtrl+C。
復帰\r
Javaの勉強ではいつもEclipseを使ってます。今回復帰\rが必要になったので使ってみたのですが、コンソールに欲しい表示が出ない…。これEclipseなのが悪いんじゃない?と思い、プロンプトから実行して試すためにJavaSEのインストールに至ったわけです。
で、こんなコードを実行してみたら上手くいきました。
public class Test{ public static void main(String[] args){ for(int i=0;i<=100;i++){ System.out.print(i+"%完了\r"); try{ Thread.sleep(500); }catch (InterruptedException e){ } } } }
(Java)DateクラスとCalendarクラスのまとめ
Dateクラスの使い方
Date date1 = new Date(); //現在時刻 Date date2 = new Date(date1.getTime()); //1970年1月1日午前0時(GMT)から現在までの経過時間を指定=date1と同時刻 Date date3 = new Date(5000); //1970年1月1日午前0時(GMT)から5000ミリ秒経過 System.out.println(date1); System.out.println(date2); System.out.println(date3);
出力
Wed Jun 19 03:42:49 JST 2013 Wed Jun 19 03:42:49 JST 2013 Thu Jan 01 09:00:05 JST 1970
二つのdateを比較する関数なども用意されています。
引数ありコンストラクタは経過時間指定なのでちょっと使い勝手悪そう… setTime関数も同じく。
なお出力はSimpleDateFormatクラスを用いることで好きに改変出来ます。
参考http://www.javaroad.jp/java_date3.htm
Calendarクラスの使い方
Calendar cal = Calendar.getInstance(); System.out.println(cal)
タイムゾーンやロケールを指定することも出来ます。
で出力はというと…
java.util.GregorianCalendar[time=1371582720293,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Tokyo",offset=32400000,dstSavings=0,useDaylight=false,transitions=10,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2013,MONTH=5,WEEK_OF_YEAR=25,WEEK_OF_MONTH=4,DAY_OF_MONTH=19,DAY_OF_YEAR=170,DAY_OF_WEEK=4,DAY_OF_WEEK_IN_MONTH=3,AM_PM=0,HOUR=4,HOUR_OF_DAY=4,MINUTE=12,SECOND=0,MILLISECOND=293,ZONE_OFFSET=32400000,DST_OFFSET=0]
(;・∀・)… なんとなくわかるけど果てしなく見辛い。
なので
Calendar cal = Calendar.getInstance(); System.out.println(cal.getTime());
と書き、getTime関数を使ってCalendar型からDate型に変換することで
Wed Jun 19 04:20:13 JST 2013
という出力を得ることが出来ます。 (…Calendar#toString()何のためにあるんだろう。)
CalendarはDateとは違い、細かくset,getできます。
Calendar cal = Calendar.getInstance(); System.out.println(cal.getTime()); cal.set(Calendar.MINUTE, 18); //分だけを指定する System.out.println(cal.getTime()); cal.set(2012, 7, 22, 18, 36, 42); //全部指定する(月は0~11なので注意) System.out.println(cal.getTime()); System.out.println(cal.get(Calendar.DATE)); System.out.println(cal.get(Calendar.SECOND));
出力
Wed Jun 19 05:26:33 JST 2013 Wed Jun 19 05:18:33 JST 2013 Wed Aug 22 18:36:42 JST 2012 22 42
加減算もできます。月を2ずつ増やすとこんな感じ。
Calendar cal = Calendar.getInstance(); for(int i=0;i<5;i++){ System.out.println(cal.getTime()); cal.add(Calendar.MONTH, 2); }
出力
Wed Jun 19 04:57:49 JST 2013 Mon Aug 19 04:57:49 JST 2013 Sat Oct 19 04:57:49 JST 2013 Thu Dec 19 04:57:49 JST 2013 Wed Feb 19 04:57:49 JST 2014
年と月が自動で修正されていることがわかります。
Calendar型⇔Date型
・Calendar⇒Date
こっちは上でも使いました。
Calendar cal = Calendar.getInstance(); Date date = cal.getTime();
・Date⇒Calendar
Date date = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(date);
(R)状態空間モデルを用いたARMA乱数生成
北川先生の本にもあるように状態空間モデルを使って乱数シミュレーションすることができます。
RでARMAの乱数シミュレーションをするならarima.sim関数を使えば済む話なので、以下の内容は特に役立つものではないです。
なお、ここで扱うARMAはcausal-invertibleであるとします。
まずARMA(p,q)モデルを とします。
このモデルは状態ベクトルを
とすることで
と状態空間表現することができます。(参考 J.Durbin, S.J.Koopman "Time Series Analysis by State Space Models"(2001))
で、乱数を生成するには初期状態ベクトルの分布が必要になります。
は容易にわかりますが、問題は分散共分散行列。
状態方程式を簡略化して と表すと、定常性から といえ、
とすると という関係式を導けます。このQについての解は次のようになります。
vec関数とは、m×n行列の列ベクトルを左から順に縦に並べて長さ(m*n)のベクトルを作るものです。
※逆行列が出てきているので特異行列の場合は計算が出来ません。この場合どうしたらいいんだろう…(´・ω・`)
これで初期状態ベクトルの分布を求めることが出来るので実際にコードを書いてみます。
こんな感じでしょうか。
library(MASS) #mvrnormを使うために必要 arma <- function(n, ar, ma, sd=1){ r <- max(length(ar),length(ma)+1) T <- matrix(0,r,r); for(i in 2:r){ T[i-1,i] <- 1 }; T[1:length(ar),1] <- ar R <- matrix(0,r,1); R[1:(length(ma)+1),1] <- c(1,ma) vecQ <- solve(diag(r^2)-kronecker(T,T)) %*% as.vector(R %*% t(R)) Q <- matrix(vecQ,r,r) alpha <- matrix(0,r,n) alpha[,1] <- mvrnorm(1,mu=numeric(r),Sigma=Q) zeta <- rnorm(n+1,0,sd) for(i in 1:(n-1)){ alpha[,i+1] <- T %*% alpha[,i] + R %*% zeta[i+1] } Z <- matrix(0,1,r); Z[1,1]<-1 y <- Z %*% alpha return(y[1,]) }
値を指定して使います。
data <- arma(n=100, ar=c(0.5,0.2), ma=c(0.3,0.1), sd=1)
(R)実行時間の計測と一時的な実行中止
proc.time関数を使います。
> proc.time() ユーザ システム 経過 0.65 0.29 14.26 > proc.time() ユーザ システム 経過 0.67 0.29 15.67 > proc.time() ユーザ システム 経過 0.70 0.29 17.20 > proc.time() ユーザ システム 経過 0.70 0.31 18.68 > proc.time() ユーザ システム 経過 0.70 0.31 20.25
何回か実行すると上のように出力されました。
ユーザ、システムはCPU関係のものらしいですが、経過はRを起動してから経過した時間を表します。なので次のように調べたい処理を挟んで差をとれば処理時間を計測できます。
> start <- proc.time() > for(i in 1:10000000){} #計測される処理 > end <- proc.time() > (end-start)[3] elapsed 1.13
なお、関数の場合はsystem.time関数を使います。system.timeの中身を見ればわかりますが、proc.timeを使っておりやっていることはほとんど上と同じです。
f <- function(x){ for(i in 1:x){} } > system.time( f(10000000) ) ユーザ システム 経過 0.91 0.02 0.92
proc.timeを使ってプログラムを一時的に実行中止する関数を作れます。JavaでいうところのThread#sleepですね。
引数に待機時間(秒)を指定します。
sleep <- function(sec){ start <- proc.time() end <- proc.time() while((end-start)[3] < sec){ end <- proc.time() } } > system.time( sleep(10) ) ユーザ システム 経過 9.89 0.11 10.00
※追記
コメントで教えていただいたSys.sleepですが、上のやつと比べると明らかにSys.sleepの方が性能が良いのでこちらを使いましょう。