倭マン's BLOG

くだらない日々の日記書いてます。 たまにプログラミング関連の記事書いてます。 書いてます。

物理量 in シミュレーション設計図

今回は物理量をシミュレーション設計図で設定する方法を見ていきましょう。 これは <simulation-schema> 要素の子要素である <observable-set> 要素で設定します。

先に言っておくと、物理系の設定に使用した <system> 要素と基本的に同じです。

ObservableSet インターフェースをちょっと変更


インターフェース定義は以前やりましたが、メソッド getDataEntries(), getDatatype() は削除します(同様のことをユーティリティ・クラス SimulationUtils を用いて出来るようにします)。

import java.util.List;

public interface ObservableSet{

    PhysicalSystem getPhysicalSystem();
    void setPhysicalSystem(PhysicalSystem system);

    void observe(DataRegistry registry);
}

@DataEntry を定義


ここで少し新たな規約を。 物理系 Physical System の実装クラスに対して、その中でどんな初期条件が設定できるのかを @InitParamEntry*1 を使って宣言(区別)しました。 これと同様に、ObservableSet の中でどんな物理量が観測されるのかを知るために @DataEntry を定義します:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface DataEntry{
    Class<?> value();
}

@InitParamEntry とほとんど同じですね。 このアノテーションObservableSet インターフェースのネストクラスとして定義します。

このアノテーションを使って観測される物理量を宣言するには、これまた PhysicalSystem インターフェースと @InitParamEntry の時と同様に、"public static final" な String フィールドに @DataEntry を付加します。 具体的には下記の実装例参照。

また、ユーティリティ・クラス SimulationUtils に新たにユーティリティ・メソッドを定義しておきましょう:

public final class SimulationUtils{

    private SimulationUtils(){}

    // @InitParamEntry に対するユーティリティ・メソッド。

    public static List<String> getDataEntries(
            final Class<? extends ObservableSet> targetType){
        // 実装は省略
    }

    public static boolean supportsData(
            final Class<? extends ObservableSet> targetType, 
            final String name){
        // 実装は省略
    }

    public static Class<?> getDataType(
            final Class<? extends ObservableSet> targetType, 
            final String name){
        // 実装は省略
    }  
}

実装例


RandomWalk1D クラス(定義は以前の記事を参照。)に対する物理量 PositionObservable を実装してみましょう。 PositionObservable 内で観測される物理量はランダム・ウォークする粒子の位置である "position" で、型は整数です。

public class PositionObservable implements ObservableSet{

    @DataEntry(Integer.class)
    public static final String POSITION = "position";

    private RandomWalk1D system;

    public RandomWalk1D getPhysicalSystem(){
        return this.system;
    }

    public void setPhysicalSystem(final PhysicalSystem system){
        this.system = (RandomWalk1D)system;
    }

    public void observe(final DataRegistry registry){
        registry.setData(POSITION, system.position);
    }
}

シミュレーション設計図


シミュレーション設計図での設定は簡単です。 class 属性に自作の ObservableSet のサブクラス名を指定するだけです。

<?xml version="1.0"?>

<simulation-schema xmlns="http://xmlns.org.waman/simulation/0.1">

  ...

  <observable-set class="PositionObservable"/>
</simulation-schema>

基本的にはこれだけですが、2つほど機能を付け加えておきます。

  • <system> 要素、<iteration-condition> 要素などと同じように、type 属性、class 属性以外の属性はプロパティとして設定されます。
  • <simulation-schema> 要素下に <observable-set> 要素を幾つ書いてもかまいません。 例えば、PositionObservable の他に AnotherObservableSet を作ったとします。 このとき、シミュレーション設計図は以下のようにかけます:
<?xml version="1.0"?>

<simulation-schema xmlns="http://xmlns.org.waman/simulation/0.1">

  ...

  <observable-set class="PositionObservable"/>
  <observable-set class="AnotherObservableSet"/>
</simulation-schema>

*1:以降の記事内では、アノテーションは名前の前に "@" を付けて分かるようにします。