2017年8月5日土曜日

MIT OCW, Fundamentals of Probability 16日目 特性関数

Lecture 16. Characteristic Functions

1. Equivalence of the Tree Definitions of the Multivariate Normal Distribution

1.1 The definitions

Lec.15の定義を再掲する.

Definition 16-1

nondegenerate (multivariate) normal distributionをもつ


と,joint PDFが書ける.ここでは実ベクトルで,はpositive definateである.

Definition 16-2

(multivariate) normal distributionをもつ


と,行列と実ベクトル,各要素がに従う確率ベクトルで書ける.

Definition 16-3

(multivariate) normal distributionをもつ
任意の実ベクトルについて,がnormalである.

これらの定義が同値であることを証明する.

2. Proof of Equivalence

Lec.15で, def 16-2であればdef 16-3が成立することを学んだ.

Theorem 15-1(再掲)

def 16-2の意味でがmultivariate normalで,とすると
(d) であるとき,によってdef 16-1の意味でもnondegenerate multivariate normalである.

proof.

と仮定する. が存在するとき,Lec.10 2-1から

と書ける.でi.i.d.だから

で,したがって

そこで,

Theorem 16-1

(a) がdef 16-1を満たすとき, def 16-2も満たす
(b) がdef 16-3を満たすとき, def 16-2も満たす と示せば良い

proof.

(a)
仮定のもとで,はpositive definateなので,となるsymmetricながあって(Spectral Decomposition), から, は可逆. とすると,で,さらに

したがってたちはdef 16-1の意味でnormalでかつcovariance matrixが単位行列だからindependentである.
(b)
仮定のもとで,として,これは対称行列だから

3. Whitening of a Sequence of Normal Random Variables

がmultivariate normal vectorとして,基底変換によってをつくるとき,様々な作り方が考えられるが,

とすることが出来る.ただし
(a) はそれぞれ, をもとにから得られる新しい情報と考えることができる.たちをinnovationsという.
(b) conditional expectationは線形写像だから,の線形写像と考えることが出来る. 下三角行列を使ってと書ける.これはによって決定されるということであって,これをからへの変換はcausalであるという.また,もまた下三角行列だから,causally invertibleという.この関係をwhitening filterと呼ぶことが有る.
(c) たちはそれぞれ独立で,これはから言える. またここからはuncorrelatedであることが言えて,さらにともuncorrrelated.normalだからuncorrelated => independent. varianceが0でなければ,varianceが1となるように出来る.
(d) のcovariance matrix は対角行列で,. と,下三角行列と上三角行列に分解することをCholesky factorizationという.

4. Introduction to Characteristic Functions

moment generating function をすでに定義したが,のような場合には意味を持たない(Cauchy distributionを思い出せ). そこでを複素数と考えて,

と定める. がPDF をもつcontinuous random variableとすると,

が成立する.はcomplex-value random variableであるが,三角関数での表示を思い出せば

として計算できる.さらに
(a) が任意のに成立するから,は必ず定義されて,しかもである.
(b) moment generating fucntionの主要な性質はcharacteristic functionと共通する.

Theorem 16-2

(a) とすると,
(b) がindependentなら
(c) がindependentで,が確率に等しく,確率に等しいとき,

(c) Inversion theorem 同じcharacteristic functionをもつrandom variableがあるとき,分布も同じ
(d) がmultivariateなときでcharacteristic functionを定めて,(c)はこれでも成立
(e) がcontinuous でPDFがとすると,

が微分可能な点で成立する.
(f) dominated convergence theoremを,定数関数1に支配される複素数の実部と仮部にそれぞれ使って,
がなら,任意の

(g) ならば

2017年8月2日水曜日

MIT OCW, Fundamentals of Probability 15日目 モーメント母関数2

David Gamarnik, and John Tsitsiklis. 6.436J Fundamentals of Probability. Fall 2008. Massachusetts Institute of Technology: MIT OpenCourseWare, https://ocw.mit.edu. License: Creative Commons BY-NC-SA.
[TOC]

Lecture 14. Moment Generating Functions

2. Sum of a Random Number of Independent Random Variables

をi.i.d. なrandom variableの列とする.meanは, varianceはとする.を非負整数をとる別のrandom variableとする. とし,の様々な統計量を考える.
まず

さらに, law of total varianceによって

まただから,

Example

はexp()に従う独立なrandom variableとする.またとすると


このように,はパラメータのexponential random variableのmoment generating functionと一致する.
cf.

とすると,

inversion theoremから.exponential random variableの有限和はexponential出ないことを考えると驚くべき結果である. 後にPoisson processの視点から直感的な説明を与える.

3. Transfroms Associated wtih Joint Distributions

にjoint distribution(joint PDF)があるとき,が導ける.これはmarginal distribution の変換で,もう一方のrandom variableとの関係性を保存しない. の関係を保存する変換を述べる. について,を実数のパラメータとすると,associated multivariate transform変数関数

と定める.

2017年7月23日日曜日

The Rust Programming Language 2nd 16日目 テスト2

https://doc.rust-lang.org/book/second-edition/
Apache License Version 2.0

Testing

Rustはコードの中にテストを書き込むことを許している.

Controlling How Tests are Run

cargo testにオプションを与えてデフォルトとは異なる動作をさせることが出来る.オプションはcargo test --aaa --bbb というふうに書く.cargo testそのものに与えるオプションはaaaに,生成されるバイナリに与えるオプションはbbbに列挙する.

Running Tests in Parallel or Consecutively

デフォルトでは,それぞれのテストはいちいち結果を出力せずに平行実行され,最後に全ての結果を出力する.これは高速だが,以前行ったテストの結果や途中の計算を利用したテストを行えないという問題が有る.たとえばtest-output.txtというファイルを作成し,その中に何かしらのデータを書き込み,そのファイルがテストごとに異なる特定の値を含んでいるという一連のテストを考える.平行実行によるテストでは同じ名前のファイルの作成によって上書きが生じてしまい,正しいコードでもテストに通らなくなるおそれがある.この問題を解決するため,テストを一つずつ実行するという手段が有る.これを実現するには実行ファイルに--test-threadフラグを与える.
$cargo test -- --test-threads=1とすれば,テストを一つずつ実行するようになる.

Showing Function Output

あるテスト関数の中での標準出力は,そのテストが成功するとtest libraryに回収されて,出力されない.例えばprintln!を中に含むテストが成功すると,シェルからそのprintln!が出力した値を見ることはできない.一方テストが失敗すれば全ての標準出力とエラーメッセージがシェルから見れる.
例えばlisting 11-10は成功するテストと失敗するテストを持つ.
src/lib.rs listing 11-10

fn prints_and_returns_10(a: i32) -> i32 {
  println!("I got the value {}", a);
  10
}

#[cfg(test)]
mod tests {
  use super::*;

  #[test]
  fn this_test_will_pass() {
    let value = prints_and_returns_10(4);
    assert_eq!(10, value);
  }

  fn this_test_will_fail() {
    let value = prints_and_returns_10(8);
    assert_eq!(5, value);
  }
}

shell

running 2 tests
test tests::this_test_will_fail ... FAILED
test tests::this_test_will_pass ... ok


failures:

---- tests::this_test_will_fail stdout ----
        I got the value 8
thread 'tests::this_test_will_fail' panicked at 'assertion failed: `(left == right)` (left: `5`, right: `10`)', src/lib.rs:19
note: Run with `RUST_BACKTRACE=1` for a backtrace.


failures:
    tests::this_test_will_fail

test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured

error: test failed, to rerun pass '--lib'

たしかにI got the value 8と,エラー時のみ標準出力が現れている.通過したテストの標準出力を見たい場合,--nocaptureフラグを使う.
$ cargo test -- --nocaptureによって
shell

running 2 tests
I got the value 4
I got the value 8
thread 'tests::this_test_will_fail' panicked at 'assertion failed: `(left == right)` (left: `5`, right: `10`)', src/lib.rs:19

note: Run with `RUST_BACKTRACE=1` for a backtrace.
test tests::this_test_will_pass ... ok
test tests::this_test_will_fail ... FAILED

と,たしかに両方の標準出力がシェルから見れるようになっている.

Running a Subset of Tests by Name

全てのテストを行うと時間がかかりすぎるときは,cargo testの引数としてどのテストを走らせるかを指定することが出来る.
例えば
src/lib.rs listing 11-11

pub fn add_two(a: i32) -> i32 {
  a + 2
}

#[cfg(test)]
mod tests {
  use super::*;

  #[test]
  fn add_two_and_two() {
    assert_eq!(4, add_two(2));
  }

  #[test]
  fn add_three_and_two() {
    assert_eq!(5, add_two(3));
  }

  #[test]
  fn one_hunder() {
    assert_eq!(102, add_two(100));
  }
}

listing 11-11のコードは明らかに全てのテストが通過する.

Running Single Tests

cargo testの引数にテスト関数名を入れることで,そのテスト関数だけを実行できる.

$ cargo test one_hundred
    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running target/debug/deps/adder-06a75b4a1f2515e9

running 1 test
test tests::one_hundred ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

Ignore Some Tests Unless Specifically Requested

非常に時間がかかるテストを,特に指定した場合以外実行したくないときがある.このときは,テスト関数にtest attributeに加えてignore attributeをつける.
src/lib.rs

#[test]
fn it_works() {
  assert!(true);
}

#[test]
#[ignore]
fn expensive test() {
  // code that takes and hour tu run
}

このようにすれば,ただcargo testとしてもexpensive_testは実行されない.ignoreした関数も実行したいときには,cargo test -- --ignoredとオプションをつける.

The Organization

テストには大きく分けてunit(単体)テストとintegration(結合)テストが有る.unit testはそれぞれのモジュールを切り離して,private interfacesについてテストする.integration testはpublic interfaceと既存のモジュールのみを使って,外からコードを利用しているのと同じ方法でテストされる対象にアクセスし,テストする

Unit tests

コードのそれぞれの部分を他と切り離し,その部分が予期したとおり動くかを試す.unit testはsrc directoryに,テストされるコードとともに書く.testsという名前のcfg(test) annotation モジュールを作って中にテスト関数を列挙するのが慣習である.

The Tests Module and #[cfg(test)]

#[cfg(test)] annotationはRustに,cargo testコマンドが実行されたときにのみこのモジュールをコンパイルするように命令する.cargo buildが高速かつ生成される実行ファイルが小さくてすむ.integration testはコードとは別のところに書くので,#[cfg(test)]を書く必要はない.
新しくライブラリプロジェクトを生成すると,src/lib.rs

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}

と,予めテストの雛形が自動的に書き込まれている.cfgとはconfigurationの略であって,以下のコードをtestに設定している.testに設定されたコードはcargo test時のみコンパイルされる.

Testing Private Functions

privateな関数をテストする.
src/lib.rs listing 11-12

pub fn add_two(a: i32) -> i32 {             // public
  internal_adder(a, 2)
}

fn internal_adder(a: i32, b: i32) -> i32 {  // private
  a + b
}

#[cfg(test)]
mod tests {
  use super::*;

  #[test]
  fn internal() {
    assert_eq!(4, internal_adder(2, 2));
  }
}

Privacy Rules

あるアイテムがpublicであるとき,親moduleを通じてそのアイテムにアクセスできる.
あるアイテムがprivateであるとき,そのアイテムがあるmoduleとその子moduleからしかそのアイテムにはアクセスできない.

を思い出すと,testsadd_twointernal_adderが定義されたスコープの子moduleだから,internalinternal_adderにアクセスできて,テストできる.

2017年7月22日土曜日

The Rust Programming Language 2nd 15日目 テスト1

https://doc.rust-lang.org/book/second-edition/
Apache License Version 2.0

Testing

Rustはコードの中にテストを書き込むことを許している.

How to Write Tests

testはRustの関数で,testでないコードが期待した通りに動いているか確かめる.test関数のbodyはふつう, 1.準備, 2.テストしたいコード, 期待する結果の3つを含んでいる.ここではtest attribute(属性)といくつかのマクロ,そしてshould_panic attributeを学ぶ.

The Anatomy of a Test Function

attributeはRustコードのメタデータで,chap.5 ですでにderiveを扱った.test attribute付きの関数がRustのテストコードである.関数をtest関数にするには,#[test]fnの上の行に書く.cargo testによってテストを実行し,test関数のどれが成功してどれが失敗したかを返す.
testの働きを実験を,自動生成されるtemplate testを通して見ていく.そのあと実際のtestを書いてみる.
ライブラリプロジェクトadderを生成すると,src/lib.rsにはすでにテストコードが書いてある.
src/lib.rs listing 11-1

#[cfg(test)]
mod tests {
  #[test]
  fn it_works() {}
  }
}

it_works() {}は何もしないから,テストを無事通過する.

shell

$ cargo test
   Compiling adder v0.1.0 (file:///projects/adder)
    Finished dev [unoptimized + debuginfo] target(s) in 0.22 secs
     Running target/debug/deps/adder-ce99bcc2479f4607

running 1 test
test tests::it_works ... ok     // testsモジュールのit_worksが正常と言っている

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

   Doc-tests adder  // documentに対するテスト

running 0 tests     // docを書いていないのでテストは行われない

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured

失敗するテストを書いてみる.test functionがどこかでpanicするとテストは失敗する.
src/lib.rs listing 11-3

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }

    #[test]
    fn anoter() {
        panic!("Make this test fail");
    }
}

shell listing 11-4

running 2 tests
test tests::exploration ... ok
test tests::another ... FAILED

failures:

---- tests::another stdout ----
    thread 'tests::another' panicked at 'Make this test fail', src/lib.rs:9
note: Run with `RUST_BACKTRACE=1` for a backtrace.

failures:
    tests::another

test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured

error: test failed

test tests::anotherFAILEDだったと言っている.成功したit_worksには触れられず,anotherの失敗の理由と,失敗したtestの一覧が表示され,最後にtest全体の要約が表示される.testが失敗するのはpanicが生じたときだけではない次節では,panicは起きないが予期した結果と違った計算を行ったときエラーを出すマクロを学ぶ.

Checking Result with the assert! Macro

assert! macroはtest functionがfalseを返したとき場合にpanic!を呼び,testを失敗させる.

rectangle/src/lib.rs listing 11-5

#[cfg(test)]
mod tests {
  use super::*;  // tests modの外に有るstructをスコープに入れる

  #[test]
  fn larger_can_hold_smaller() {
    let larger = Rectangle { length:8, width: 7};
    let smaller = Rectangle { length:5, width: 1};

    assert!(larger.can_hold(&smaller));             // assert!(ture)
  }

  #[test]
  fn smaller_can_not_hold_larger() {
    let larger = Rectangle {length: 8, width: 7};
    let smaller = Rectangle {length: 5, width: 1};

    assert!(!smaller.can_hold(&larger))             // assert!(!false)
  }
}

#[derive(Debug)]
pub struct Rectangle {
  length: u32,
  width: u32,
}
impl Rectangle {
  pub fn can_hold(&self, other: &Rectangle) -> bool {
    self.length > other.length && self.width > other.width
  }
}

listing 11-5では,Rectangleのcan_holdメソッドが真となる場合と偽になる場合の両方を確かめている.計算の結果がfalseであることを確かめたいなら,assert!(!false)によって,確かにfalseである場合のみtestを通過させるようにできる.
shell

running 2 tests
test tests::larger_can_hold_smaller ... ok
test tests::smaller_can_not_hold_larger ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured

また,コードにバグを埋め込んでみる.ここではRectangle.can_holdの不等号演算子の一つを逆にしてみる.
self.length < other.length && self.width > other.width
結果は
shell

running 2 tests
test tests::smaller_can_not_hold_larger ... ok
test tests::larger_can_hold_smaller ... FAILED

failures:

---- tests::larger_can_hold_smaller stdout ----
        thread 'tests::larger_can_hold_smaller' panicked at 'assertion failed: larger.can_hold(&smaller)', src/lib.rs:10
note: Run with `RUST_BACKTRACE=1` for a backtrace.



failures:
    tests::larger_can_hold_smaller

test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured

と,やはり失敗したtestの詳細と全体の要約を出力してくる.

Testing Equality with the assert_eq! and assert_ne! Macros

ある関数が適当なfuncが数値や文字列xxxを返すときにのみ通過するテストは,assert(func()== xxx)などとすれば書けるのだが,手間を省くためにassert_eq!(xxx, func())として同じ意味になるマクロassert_eq!が定義されている.また,assert_ne!(xxx, funct())func()の返り値がxxxでない場合のみ通過する.どちらのマクロも,テストを通過しなかったときには問題となっている関数の返り値と想定された値を出力する.例えば
src/lib.rs listing 11-7

pub fn add_two(a: i32) -> i32 {
    a + 2
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_adds_two() {
        assert_eq!(4, add_two(2));
    }
}

は無事通過し,ここでadd_twoのbodyをa+3に書き換えてテストを再度実行すると
shell

test tests::it_adds_two ... FAILED

failures:

---- tests::it_adds_two stdout ----
        thread 'tests::it_adds_two' panicked at 'assertion failed: `(left == right)` (left: `4`, right: `5`)', src/lib.rs:11
note: Run with `RUST_BACKTRACE=1` for a backtrace.

と,左辺,すなわち予期した値は4であるのに,返り値が5であったとしてエラーを返してくる.
ここで我々はassert_eq!(xxx, func())と,左辺に左に予期した値,右に関数を書いたが,この順序が逆でも構わないし,両方が関数でも構わない.例えば
src/lib.rs listing 11-7-0

pub fn add_two(a: i32) -> i32 {
    a + 2
}

pub fn mut_3(a: i32) -> i32 {
    a * 3
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn mul_and_add() {
        assert_eq!(mut_3(4), add_two(10));
    }
}

はテストを通過する.

assert_eq!assert_ne!は内部で==!=演算子をそれぞれ使っており,また失敗時にはマクロの引数をdebug formattingによって出力する.ゆえに,比較される値はPartialE1Debug traitを実装していなければならない.全ての基本型と殆どの標準ライブラリ型はこれらのtraitを実装しているが,プログラマが実装したstructやenumにassert_eq!assert_ne!を適用するには,以上のtraitを実装しなければならない.しかしこれらのtraitはderivableだから,chap.5で見たように,#[derive(PartialEq, Debug)]定義時に注釈することで,簡単に実装できる.derivable traitについてはappendix Cに詳しい.

Custom Failure Messages

テストが失敗したときに好きなメッセージを出力させることが出来る.assert!は1つ,assert_eq!, assert_ne!は2つの引数を必ず取るが,さらに引数を与えると,それらはformat!マクロによって加工されるので,format stringと適当な変数を引数に渡すと,適当にパースして出力してくれる.例えば,人名を引数としてその人を歓迎する関数を作ってテストするときには以下のようなコードが考えられる.

src/lib.rs listing

pub fn greeting(name: &str) -> String {
  format!("Hello {}!", name)
}

#[cfg(test)]
mod tests {
  use super::*;

  #[test]
  fn greeting_contains_name() {
    let result = greeting("Carol");
    assert!(result.contains("Carol"));
  }
}

これはテストを通過する.greetingのbodyをString::from("Hello!")としてバグを入れると,
shell

test tests::greeting_contains_name ... FAILED

failures:

---- tests::greeting_contains_name stdout ----
        thread 'tests::greeting_contains_name' panicked at 'assertion failed: result.contains("Carol")', src/lib.rs:12
note: Run with `RUST_BACKTRACE=1` for a backtrace.

とエラーを生じる.assertionが失敗したことを言っているが,よりエラーを見やすくするために,greeting関数の返り値を表示するようにする.
src/lib.rs

#[test]
fn greeting_contains_name() {
    let result = greeting("Carol");
    assert!(
        result.contains("Carol"),
        "Greeting did not contain name, value was `{}`", result
    );    // 第二引数はプレースホルダー{}を持てる文字列で,
          // 第三引数以降がそのプレースホルダーに入る.
}

ここでまたテストを行うと
shell

test tests::greeting_contains_name ... FAILED

failures:

---- tests::greeting_contains_name stdout ----
        thread 'tests::greeting_contains_name' panicked at 'Greeting did not contain name, value was 'Hello'', src/lib.rs:12
note: Run with `RUST_BACKTRACE=1` for a backtrace.

と,確かにエラーメッセージが想定したとおりになる.

Checking for Panics with should_panic

予期した通りの値を返すかを確かめるのと同じくらいに,発生したエラーを予期したとおりに対処するか確かめるのは重要である.たとえばChap. 9, listing9-8で定義したGuess型で,そのinstanceは必ず1から100の値を取ることを約束したので,Guessのinstanceでその範囲から外れたものを作ろうとしたときには確かにpanicを起こすことを確かめたい.
これをshould_panic attributeを関数につけて実現する.shold_panicは,それがつけられた関数がpanicを起こすときにのみテストを通過するようにする.
src/lib.rs listing 11-8

struct Guess {
  value: u32,
}

impl Guess {
  pub fn new(value: u32) -> Guess {
    if value < 1 || value > 100 {
      panic!("Guess value must be between 1 and 100, got {}", value);
    }

    Guess {
      value
    }
  }
}

#[cfg(test)]
mod tests {
  use super::*;

  #[test]
  #[should_panic]
  fn greater_than_100() {
    Guess::new(200);
  }
}

これは確かにテストを通過する.
shell

running 1 test
test tests::greater_than_100 ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

ここでnew()における条件を外すと,
shell

running 1 test
test tests::greater_than_100 ... FAILED

failures:

failures:
    tests::greater_than_100

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured

と,正常にGuessの新しいinstanceが作られてしまうので,エラーを生じる.should_panicは,予期した形のpanicでなくともpanicを拾うとテストに通してしまうので,should_panicexpectedというパラメータを渡して,より厳密なテストを行うことが出来る.expectedには文字列が入って,panic時のメッセージにその文字列が現れるときのみテストを通すようにする.例えば
src/lib.rs listing 11-9

struct Guess {
  value: u32,
}

impl Guess {
  pub fn new(value: u32) -> Guess {
    if value < 1 {
      panic!("Guess value must be greater than or equal to 1, got {}.", value);
    }
    else if value > 100 {
      panic!("Guess value must be less than or equal to 100, got {}", value);
    }

    Guess {
      value
    }
  }
}

#[cfg(test)]
mod tests {
  use super::*;

  #[test]
  #[should_panic(expected = "Guess value must be less than or equal to 100")]
  fn greater_than_100() {
    Guess::new(200);
  }
}

をテストにかけると,確かにpanicが生じ,しかも値が100を上回るときのメッセージが与えられるから,テストを通過する.
また,if value < 1else if value > 100において数値と不等号を交換すると,

shell

test tests::greater_than_100 ... FAILED

failures:

---- tests::greater_than_100 stdout ----
        thread 'tests::greater_than_100' panicked at 'Guess value must be greater than or equal to 1, got 200.', src/lib.rs:8
note: Run with `RUST_BACKTRACE=1` for a backtrace.
note: Panic did not include expected string 'Guess value must be less than or equal to 100'

と,予期したメッセージと返されたメッセージが異なるため,panicが生じてもshould_panicはテストを通過させない.

以上でテストの書き方を学んだので,つぎはテストを行っているとき内部で何が起きているかとか,cargo testの様々なオプションを見ていくことにする.

2017年7月20日木曜日

MIT OCW, Fundamentals of Probability 14日目 モーメント母関数1

David Gamarnik, and John Tsitsiklis. 6.436J Fundamentals of Probability. Fall 2008. Massachusetts Institute of Technology: MIT OpenCourseWare, https://ocw.mit.edu. License: Creative Commons BY-NC-SA.

モーメント母関数からは逃げられなかったよ・・・

Lecture 14. Moment Generating FUnctions

momment generating function(モーメント母関数)とその類概念(probability generating function, characterstic function)はprobability distributionを1変数の関数で表現する方法の一つである.

1. Moment Generating Fucntions

1.1 Definition

Definition 14-1

random variable のmoment generating functionを

と定める.また,domain を,と定める.

がdiscrete random variableでPMFがならば

がcontinuous random variableでPMFがならば

1.2 The Domain of the Moment Generating Function

から,である.discrete random variableでならば,である.一方Cauchy distributino では,である.一般にを含む区間である.

1.3 Invension of Transforms

の定義から,においてが与えられればのdistributionが得られる.一方以外の点ではのdistributionはわからない.

Theorem 14-1 Inversion Theorem

(a) 上で有限なら,の固有のCDFを与える.
(b) で成り立つとき,は同じCDFを持つ.

1.4 Moment Generating Properties

の0における微分係数を考える.微分と積分の順序交換が可能と仮定すると


よって次モーメントはで計算できる.

1.5 The Probability Generating Function

Definition 14-2


probability generating functionという.普通である.

ならばとその微分係数がで存在するので,というPMFを持っているとき,

だから,

である.であればから容易にが得られる

1.6 Examples

Example

とすると,

Example

とすると,

Example

とすると,

1.7 Properties of Moment Generating Functions

Theorem 14-2

(a) なら
(b) が独立なら
(c) が独立でである確率が,である確率がであるとすると

proof.

(a)
(b)
(c)

Example: (Normal random variables)

(a) で,とする.で,
(b) とすると

inversion propertyから

2017年7月19日水曜日

The Rust Programming Language 2nd 13日目 GenericとTraits

https://doc.rust-lang.org/book/second-edition/
Apache License Version 2.0

Generic Types, Traits, and Lifetimes

同じロジックでも,扱う変数の型が違えばこれまで学んだ関数の定義方法では,型ごとに似たような関数をいくつも書かなければならない.このようなロジックの重複を解消するのがgenericで,変数の型に関係なく関数やstructを定義できる.
genericはすでにChap 6でOption<T>を, Chap. 8でVec<T>HashMap<K, V>を,Chap. 9でResult<T, E>を使った.これを一般化した用法をこの章では学ぶ.
まず,単純に同じロジックだが引数や返り値の型が違う二つの関数を見て,それをgenericによって一本化する.次に単純に一本化できない場合の解決法を学び,最後にlifetimeという,reference同士の関係性を記述するgenericの一種を導入し,リ方法を学ぶ.

Generic Data Types

Using Generic Data Types in Function Definitions

src/main.rs listing 10-4a

fn largest(list: &[i32]) -> i32 {
    let mut largest = list[0];

    for &item in list.iter() {
        if item > largest {
            largest = item;
        }
    }

    largest
}

という関数を考える.これはi32のリストのreferenceを取ってその最大値(i32)を返す関数で,['y', 'm', 'a', 'q']と言うようなリストを引数に取ることはできないので,型だけを(list: &[char]) -> charとしたような関数を更に定義しなければならない.これは明らかに無駄なので,genericによって一本化することを考える.
引数や返り値をgeneric型にするには,そのgeneric型の変数の型名と変数自体の名を関数宣言の際に定義し,関数の内部でその変数名を使ってロジックを書く.変数の型名にはほとんど必ずTを使う.具体的な記法は
fn largest<T>(list: &[T]) -> T {
のようになる.改めてlargestを書き直したのがlisting 10-5aである.しかしこれはコンパイルできない.

src/main.rs listing 10-5a

fn largest<T>(list: &[T]) -> T {
  let mut largest = list[0];

  for &item in list.iter() {
    if item > largest {
      largest = item;
    }
  }
  largest
}

shell

error[E0369]: binary operation `>` cannot be applied to type `T`
  |
5 |         if item > largest {
  |            ^^^^
  |
note: an implementation of `std::cmp::PartialOrd` might be missing for `T`

とエラーが出る.これは任意の型Tに不等号の演算が定義されていないことが原因で,Tの取りうる値をプログラマが制限しなければならない.そのため,標準ライブラリのもつtrait std::cmp::PartialOrdを使うようにする(後述).

Using Generic Data Types in Struct Definitions

structの定義にもgenericを使える.
src/main.rs listing 10-6a

struct Point<T> {
  x: T,
  y: T,
}

fn main() {
  let integer = Point {x: 5, y: 10};
  let float = Point {x: 1.0, y: .40};
}

listing 10-6では,generic型の型名をTしか決めておらず,x, yは1つのinstanceでは必ず同じTの型しか持てない.x, yがそれぞれ異なる型の値を持てるようにするには,generic型の名前を予め二つ用意する.
src/main.rs listing 10-8

struct Point<T, U> {
  x: T,
  y: U,
}

fn main() {
  let both_integer = Point {x: 5, y: 10};
  let both_float = Point {x: 1.0, y: 4.0};
  let integer_and_float = Point{x: 5, y: 4.0};
}

は正常にコンパイルできる.generic型の型名はいくつあってもいいが,コードを読んで把握しづらくなるほど多いようならロジック自体を考え直すべき.

Using Generic Data Types in Enum Definitions

structと同様に,enumもgeneric型をそのvariantsに持てる.Option<T>がこれを行っているのはすでに見た.Rustは変数を取らないときにはgeneric型をvariantに入れないことを許しているから

enum Option<T> {
  Some(T),
  None,
}

というふうにOption<T>を定義できる.また,あるvariantに入る型と別のvariantに入る型が異なっている場合にも

enum Result<T, E> {
  Ok(T),
  Err(E),
}

と記述できる.

Using Generic Data Types in Method Definitions

Chap.5 でやったように,struct やenumにmethodを定義できるが,これにもgenericが使える.例えば
src/main.rs listing 10-9

struct Point<T> {
  x: T,
  y: T,
}

impl<T> Point<T> {
  fn x(&self) -> &T {
    &self.x
  }
}

fn main() {
  let p = Point {x: 5, y: 10};
  println!("p.x = {}", p.x());
}

また例えば
src/main.rs listing10-10

struct Point<T, U> {
  x: T,
  y: U,
}

impl<T, U> Point<T, U> {
  fn mixup<V, W>(self, other: Point<V, W>) -> Point<T, W> {
    Point {
      x: self.x,
      y: self.y,
    }
  }
}

fn main () {
  let p1 = Point {x: 5, y: 10.4} ;
  let p2 = Point {x: "Hello", y: 'C'};  
  let p3 = p1.pixup(p2);
}

は正常に実行できる.

Performance of Code using Generics

Rustはコンパイル時にgenericを具体的な型のコードたちに変換するので,genericが実行時のオーバーヘッドになることはない.Rustのこの働きをmonomorphizationという.
たとえば

let integer = Some(5);
let float = Some(5.0);

をコンパイルするとき

enum Option_i32 {
    Some(i32),
    None,
}

enum Option_f64 {
    Some(f64),
    None,
}

fn main() {
    let integer = Option_i32::Some(5);
    let float = Option_f64::Some(5.0);
}

のように内部で変換する.

Traits: Defining Shared Behavior

traitは型の振る舞いを抽象化する.つまり複数の型に同時にメソッドを定義できる.また関数の引数などにgeneric型を使っているときtraitによってその引数が取れる型の範囲を制限して,Using Generic Data Types in Function Definitionsでみたエラーに対処することができる.

Defining a Trait

型のふるまいは型に実装されているメソッドたちによって決まる.異なった型たちが同じ名前のメソッドを持っているとき,その型たちは振る舞いを共有していると考えることが出来る.traitによって複数の型に同じ名前のメソッドを同時に定義できる.例えばNewsArticle型とTweet型を考える.両者ともに,そのインスタンスの要約を返すメソッドsummaryを,summarizable traitによって持たせる.traitはmoduleのように定義するが,body blockにはsignatureだけ書く.
src/lib.rs listing 10-11

pub trait Summarizable {
  fn summary(&self) -> String;  // method signatureのみ書く
  fn author(&self) -> String;   // 複数のメソッドも書ける.
  fn content(&self) -> String;  // 1行に一つのmethod signatureを書き,セミコロンを打つ.
}

Implementing a Trait on a Type

Summarizable traitを定義したところで,型にtraitを実装する.通常のメソッド定義は
impl NewsArticle { fn summary...}と書くが,traitを実装するときは
impl Summarizable for Newsarticle { fn summary signature { }} と書く.fn summary signature { }の中に実際のロジックをコーディングする.

具体的な例:
lib.rs listing 10-12

pub struct NewsArticle {
  pub headline: String,
  pub location: String,
  pub author: String,
  pub content: String,
}

impl Summarizable for NewsArticle {
  fn summary(&self) -> String {
    format!("{}, by {} ({})", self.headline, self.author, self.location)
  }
}

pub struct Tweet {
  pub username: String,
  pub content: String,
  pub reply: bool,
  pub retweet: bool,
}

impl Summarizable for Tweet {
  fn summary(&self) -> String {
    format!("{}: {}", self.username, self.content)
  }
}

こうしてSummarizableNewsArticleTweetに実装できた.それぞれの型のinstanceにドット記法でSummarizableの中のメソッドを呼べる.

let tweet = Tweet {
    username: String::from("horse_ebooks"),
    content: String::from("of course, as you probably already know, people"),
    reply: false,
    retweet: false,
};

println!("1 new tweet: {}", tweet.summary());

1 new tweet: horse_ebooks: of course, as you probably already know, people.を出力する.

これまではすべてをlib.rsに書いてきた.これらをaggregatorというcrateにして,他の場所にあるWeatherForecast structにSummarizable traitを実装したい場合,Summarizableをまずインポートする.
lib.rs listing 10-13 例

extern crate aggregator;

use aggregatro::Summarizable;

struct WeatherForecast {
  high_temp: f64,
  low_temp: f64,
  chance_of_precipitation: f64
}

impl Summarizable for WeatherForecast {
  fn summary(&self) -> String {
    format!("The high will be {}, and the low will be {}. The chance of precipitation is{}%", self. high_temp, self.low_temp, self.chance_of_precipitation)
  }
}

traitとtypeがともにexternalであるとき,そのtypeにtraitを新たに実装することはできない.例えば,Vecはexternal traitでDisplayはexternal traitだから,VecDisplayを実装することはできない.こうしたルールをOrphan ruleという.

Default Implementations

traitを定義するとき,予めロジックを決めておいて,改めて型にtraitのメソッドを実装しない限りそのデフォルトのロジックをその型のメソッドとすることが出来る.Default implementationという.そのためには,listing 10-11ではセミコロンで止めていおいたメソッドのsignatureを,実際のロジックまで書くようにし,
lib.rs listing 10-14

pub trait Summarizable {
  fn summary(&self) -> String {
    String::from("(Read more...)");
  }
}

さらに型への実装で{ }を空白にする. impl Summarizable for NewsArticle {}仮にここでtraitの定義とは別のロジックを書いたら,新しいロジックが優先される.

default implementationはそのtraitの他のメソッドを,デフォルトが定義されていなくても,呼ぶことが出来る.例えば

pub trait Summarizable {
  fn author_summary(&self) -> String;

  fn summary(&self) -> String {
    format!("(Read more from {}...)", self.author_summary())
  }
}

このSummarizableを使うときは,author_summaryを型に実装する.

impl Summarizable for Tweet {
    fn author_summary(&self) -> String {
        format!("@{}", self.username)
    }
}

Trait Bounds

traitをgeneric type parameterと使うことも出来る.generic typeは野放図に使うとUsing Generic Data Types in Function Definitionsのようなエラーを生じることがあるので,そのgeneric typeを取れる型が特定のtraitを実装されている型であると制限して,その制限下のどの型でも動くとコンパイラが判断すれば,コンパイルしてくれる.こうしてgeneric typeの型を制限することを,”generic typeにtrait boundsを指定する”という

例えばlisting 10-12でsummarizableNewsArticleTweetに実装したので,NewsArticleTweetを引数に取るnotifyという関数をgenericを使って定義する.generic type parameter TSummarizable traitが実装されている型に制限するには,定義時に<T: Summarizable>とすれば良い.例えば

pub fn notify<T: Summarizable>(item: T) {
  println!("Breaking news! {}", item.summary())
}

また,SummarizableDisplayを同時に実装している型にgeneric typeを制限したいときには<T: Summarizable + Displayとする.
fn some_function<T: Display + Clone, U: Clone + Debug>(t: T, u: U) -> i32 {
というふうに複数の引数にそれぞれのtrait boundsを設定することが可能だが,読みづらいのでwhereキーワードを使って

fn some_function<T, U>(t: T, u: U) -> i32
  where T: Display + Clone,
        U: Clone + Debug
{

というふうに定義することも可能である.

Fixing the largest Function with Trait Bounds

Using Generic Data Types in Function Definitionsで見たエラーを実際に修正しよう.

error[E0369]: binary operation `>` cannot be applied to type `T`
  |
5 |         if item > largest {
  |            ^^^^
  |
note: an implementation of `std::cmp::PartialOrd` might be missing for `T`

不等号演算子が定義されている型がTに来るかもしれないというのでエラーメッセージが出たので,不等号を定義する標準ライブラリのtrait, std::cmp::PartialOrdをtrait boundとしてみる.
fn largest<T: PartialOrd>(list: &[T]) -> T {
しかし,これでもエラーが出る.

error[E0508]: cannot move out of type `[T]`, a non-copy array
 --> src/main.rs:4:23
  |
4 |     let mut largest = list[0];
  |         -----------   ^^^^^^^ cannot move out of here
  |         |
  |         hint: to prevent move, use `ref largest` or `ref mut largest`

error[E0507]: cannot move out of borrowed content
 --> src/main.rs:6:9
  |
6 |     for &item in list.iter() {
  |         ^----
  |         ||
  |         |hint: to prevent move, use `ref item` or `ref mut item`
  |         cannot move out of borrowed content

cannot move out of type [T], a non-copy array.に着目する.TCopy traitを実装していないため,largest = list[0]が実行できなかったことを示している.よってtrait boundにCopyを加えることで,コンパイルが可能になる.

src/main.rs listing 10-15

use std::cmp::PartialOrd;

fn largest<T: PartialOrd + Copy>(list: &[T]) -> T {
    let mut largest = list[0];

    for &item in list.iter() {
        if item > largest {
            largest = item;
        }
    }

    largest
}

fn main() {
    let numbers = vec![34, 50, 25, 100, 65];

    let result = largest(&numbers);
    println!("The largest number is {}", result);

    let chars = vec!['y', 'm', 'a', 'q'];

    let result = largest(&chars);
    println!("The largest char is {}", result);
}

Copyをtrait boundに加えたくない場合,かわりにCloneをtrait boundsに加えても良いが,Cloneはheap構造を使うので,性能が落ちる可能性がある.

2017年7月18日火曜日

MIT OCW, Fundamentals of Probability 13日目 多次元の正規分布1

David Gamarnik, and John Tsitsiklis. 6.436J Fundamentals of Probability. Fall 2008. Massachusetts Institute of Technology: MIT OpenCourseWare, https://ocw.mit.edu. License: Creative Commons BY-NC-SA.

Lecture 14. MOMENT GENRATING FUNCTIONS

モーメント母関数.Laplace変換とか出てきたから飛ばす.そのうちやりたい(願望)

Lecture 15. MULTIVARIATE NORMAL DISTRIBUTIONS

1. Background On Positive Definate Matrices

Definition 15-1

の正方行列とする.
(a) positive definate(正定値) である
このときと書く.
(b) nonnegative definate(半正定値) である
このときと書く.

以下の事実は有名である.

(a) symmetric matrixは個の実eigenvalueを持つ.
(b) positive definate ならeigenvalueは個存在し全て正.
(c) nonnegative definateならeigenvalueは個存在し全て非負
(d) symmetri matrixの全てのeigenvalueにはそれぞれ実eigenvectorがあって,異なったeigenvalueに対応するeigenvectorは直行し,複数eigenvalueが重複しているときその重複度の分直行するeigenvectorがある.
(e) 以上から,symmetric definateなら基底変換によって対角化出来る.

上の事実から, spectral decomposition(スペクトル分解) が得られる.すなわち

任意の対称行列は,のeigenvalue, をそれぞれのeigenvalueに対応するeigenvectorとすると,

と書ける.

また,nonnegative definite matrixであるならだから平方根が実数で,

が定義できる.このとき

(a) はsymmetric
(b) である.symmetric square rootという.
(c) のeigenvalueたちはである.よって,がpositive(nonnegative) definite がpositive(nonnegative) definite.

特にがpositive definiteならばで,

が定義できて, ゆえ, である.

2. DEFINITION OF THE MULTIVARIATE NORMAL DISTRIBUTION

全ての要素がrandom variableであるベクトルをrandom vectorと呼び.全ての要素がrandom variableである行列をrandom matrixと呼ぶ.
multivariate normal distributionの表現方法3つを取り上げ,それらの同値性を確かめる.最初に,最もわかりやすいがいろいろな操作が面倒な表現を与える.

Definition 15-2

random vector nondegenerate (multivariate) normal distributionをもつ
joint PDF が,あるベクトルとpositive definite

と書ける.

さらに,操作が簡単な生成的な定義を与える.

Definition 15-3

random vector (multivariate) normal distributionをもつ
あるmatrix とベクトル, そして要素がに独立に従うランダムなベクトルによって,

と書ける.

最後に与える定義は最も難しいが,最も美しいと言う人もいる.

Definition 15-4

random vectro (multivariate) normal distributionをもつ
任意のベクトルにrandom variable がnormal.

Definition 15-2でnondegenerateという語を使ったが,これはという意味である.はNormalだが,これはDef. 15-2の方法では表現できないので,nondegenerateという制限を加えている.

3. MEANS AND COVARIANCES OF VECTOR RANDOM VARIABLES

Definition 15-5

random vector のexpectationを

とする.同様にrandom matrix についてもexpectationを

とする.

random vector があるとき,covariance matrix(分散行列, 分散共分散行列)を,

と定める.成分はである.

4. KEY PROPERTIES OF THE MULTIVARIATE NORMAL

Theorem 15-1 (証明略)

がmultivariate normalであるとする.は第要素の平均と考えることが出来る.このとき
(a) はnormalで,平均は
(b)
(c) 行列で,とする.はdef. 3の意味でmultivariate normalであって,平均は, covariance matrixはである.
(d) ならはnondegenerate multivariate normalであって,である.
(e) のjoint PDF の平均とcovarianceだけで決まる
(f) のそれぞれの要素がuncorrelatedすなわちが対角行列それぞれが独立
(g)
かつ ならば

(i)
(ii) とすると,と独立で,またと独立.
(iii)