0

私は Oleg Kiselyov のチュートリアルReconciling Abstraction with High Performance: A MetaOCaml approach に取り組んでいます。1 つの演習 (演習 23) では、ローカル変数への配列インデックス アクセスをバインドするために、let 挿入が要求されます。問題の関数は でvmult_ca、複素数の配列を乗算するためのコードを生成します。

let vmult_ca : 
    (float_complex array -> float_complex array -> float_complex array -> unit)
    code =
 .<fun vout v1 v2 ->
    let n = Array.length vout in  
                                      (* vector representations *)
  .~(let vout = OVec (.<n>., fun i v -> 
       .<vout.(.~i) <- .~(of_code_complex v)>.) in
     let v1   = Vec  (.<n>., fun i -> 
       of_complex_code .<v1.(.~i)>.) in
     let v2   = Vec  (.<n>., fun i -> 
       of_complex_code .<v2.(.~i)>.) in
     let module V = VMULT(FloatCodeComplex)(VecDyn) in
     V.vmult vout v1 v2)
  >.
;;

vout結果を格納する出力ベクトルは どこにありますか。Vec (n, fun i -> v)は抽象ベクトルで、nは長さで、fun i -> v各インデックスを値にマップします。 OVec (n, fun i v -> body)は抽象的な「出力ベクトル」でnあり、 は長さでありfun i v -> body、各インデックスiおよび の関連する出力要素vで実行されiます。 値を値にof_complex_code変換します。たとえば、 に変換します。このモジュールは、(点ごとの) ベクトル乗算を定義します (詳細については、こちらのコードを参照してください)。complex codecode complex.<{real=1.0, imag=0.0}>.{real=.<1.0>., imag=.<0.0>.}VMULT

実行するとvmult_ca、次のコードが生成されます。

val vmult_ca :
  (float_complex array -> float_complex array -> float_complex array -> unit)
  code = .<
  fun vout_4  ->
    fun v1_5  ->
      fun v2_6  ->
        let n_7 = Array.length vout_4  in
        for i_8 = 0 to n_7 - 1 do
          vout_4.(i_8) <-
            {
              Cmplx.im =
                (((v1_5.(i_8)).Cmplx.re *. (v2_6.(i_8)).Cmplx.im) +.
                   ((v1_5.(i_8)).Cmplx.im *. (v2_6.(i_8)).Cmplx.re));
              Cmplx.re =
                (((v1_5.(i_8)).Cmplx.re *. (v2_6.(i_8)).Cmplx.re) -.
                   ((v1_5.(i_8)).Cmplx.im *. (v2_6.(i_8)).Cmplx.im))
            }
        done>.

注記v1_5.(i_8)は 4 回繰り返されます。課題は、繰り返しを避けるためにローカル変数にバインドするためにletどこかに挿入することです。を呼び出すだけで「ごまかす」ことができましたが、なしでどこに挿入すればよいかわかりません。ヒントをいただければ幸いです。vmult_cav1_5.(i_8)genlet.<v1.(~i)>.letgenlet

4

1 に答える 1