Manipulate 内に Animate を置くことによる動的更新の警告とそれを避ける方法

Mathematica 7のころに書いたMathematica Player Notebook (.nbp)
http://www.a.math.ryukoku.ac.jp/~hig/course/mathphb_2009/beat.nbp
を CDF に書きなおそうと考え, 元のMathematica Notebook (.nb)を開いたところ,

このドキュメントには安全でない可能性のある動的コンテンツが含まれています.

This file contains potentially unsafe dynamic content.

という警告が出た.

「動的更新を有効にする」をクリックすると, 問題なく実行されるのだが, 不特定多数の人の使用を想定してCDFに書きだしたときにも同じ警告が出るというのはまずいので, 原因を追究. まず, 「詳細」のリンク先の解説を読む.

安全でない動的内容
動的内容は以下のような場合,安全でないとみなされる.

  • File操作を使う
  • MathLink Mathematica 関数を介してプロセス間通信を使う
  • JLinkあるいはNETLinkを使う
  • 低レベルノートブックプログラミングを使う
  • データを式と文字列の間の変換によるコードとして使う
  • 名前空間の管理を使う
  • オプション管理を使う
  • 外部プログラムの呼出しを使う

この中では…どれも該当してなさそうだが, あるとすれば低レベルノートブックプログラミングくらいしか考えられない.

ここで, Notebookの中身の説明. Mathematica では, Animate 関数で簡単にアニメーションが作れるが, アニメーションにパラメタがあり, それをAnimationをManipulateでくるむことにより, 変更できるようにしたもの. 簡単に言えば,

Manipulate[
 Animate[
   Plot[a Sin[k x], {x, 0, 2 Pi}, PlotRange -> {-1, 1}], 
   {k, 1, 5}],
 {a, 1, 4}
]

みたいな感じ.

Animateのドキュメントを見ると, 時間とともに変数の値が増加する Animator というControl を備えたManipulateを作る, と書いてある. そうすると, 上のコードは動的コンテンツを動的に生成する(ManipulateがManipulateを作る)ことになっていて, これが「低レベルノートブックプログラミング」とみなされているのかもしれない.

解決策としては, Manipulate 中の Animate, という2重のManipulate を1重にすればいいだろうと.

Manipulate[
   Plot[a Sin[k x], {x, 0, 2 Pi}, PlotRange -> {-1, 1}], 
   {k, 1, 5,ControlType->Animator},
   {a, 1, 4}
]

これだと, アニメーションの速さの初期値を指定する簡単な方法(AnimateのAnimationRate オプションのような)はないようだ(Controlでマウスを使って調節はできるが). Manipulate のドキュメントを見てちょっと試行錯誤. 匿名関数を使って,

speed=0.05;
Manipulate[
   Plot[a Sin[k x], {x, 0, 2 Pi}, PlotRange -> {-1, 1}], 
   {k, 1, 5, (Animator[#1, #2, speed]) &},
   {a, 1, 4}
]

なお, DynamicModuleで内側のAnimateをwrapすることによっても, safeにできるようだ.

Manipulate[
 DynamicModule[{k},
   Animate[
     Plot[a Sin[k x], {x, 0, 2 Pi}, PlotRange -> {-1, 1}], 
     {k, 1, 5}
   ]
 ],
 {a, 1, 4}
]

結局, CDFとは関係ない話. だが, 警告が出るようになったのは, CDFのサポートのためにnotebook security が厳しくなったことによる変化なのかもしれない.

なお, 上のように修正しても, CDFファイルがUntrustedPathに置かれている場合には, 動的更新の警告が出る.

完成したCDF
http://www.a.math.ryukoku.ac.jp/~hig/course/mathphb_2011/beat.cdf