バナッハ空間での二階微分の例(フレッシェ微分)

(2018年8月31日)多分これフレッシェ微分ではないです(当時なんでそんなことを書いたのかよくわからない)

いよいよはてな記法で書くの辛くなってきたのでTeXで書いた。HTML5対応ブラウザでないと見えないかも。pdfファイルは「https://github.com/ashiato45/blog_article/tree/master/postmodern_8_13」のmain.pdf。

これは何?

ポストモダン解析学を読んでいて,バナッハ空間での微分*1が出てきて,この定義なら多変数関数に対す
る二階微分ができるはずなのだが手頃な計算例が載っていなかったので作ってみた.値を与えると関数を吐
く関数のノルムをとったりとかしなくてはいけなくて,これの扱いに慣れていなかったのがてこずった原因
だった.

本文

PDFファイルを指定します。


ご覧の環境では、object要素がサポートされていないようです。PDFファイルをダウンロードしてください

IronPython+PTVS+MonoGameでの環境構築(主にIntellisense)

これは何?

IronPython+PTVS(Python Tools for Visual Studio)+MonoGame(XNAライクなライブラリ)を使ってVS2012でゲームを作ろうとしたらIntellisenseが効かなくて悩んだ話。多分MonoGameに限らずPTVSとdllの連携でIntellisenseが効かないという話に対応すると思う。

どうするの?

とりあえずIronPythonとPTVSが入っていればIronPythonのアプリケーションが作れるはずなので、それを作る。

本題ではないけれど、とりあえずWindowsアプリということで、ソリューションエクスプローラの中でプロジェクトを右クリックして、プロパティを開く。GeneralタブのWindowsApplicationにチェックを入れて、InterpreterIronPythonにしておく。

dllの読みこみは

clr.AddReferenceToFile("MonoGame.Framework.dll")

みたいにやるわけだけど、これだけだとIntellisenseが効かなくて、

import Microsoft.

まで打っても「xna」を補ってくれないので、これが問題になっていた。ちなみにこのとき、IronPython Console(VSやPTVSとは無関係)で補完が効くのは確認していたので、VSかPTVSで問題がおきていることは分かっていた。

結局、先のプロパティページのDebugのSearch Pathのところにdllの在処(私の場合「C:\Program Files (x86)\MonoGame\v3.0\Assemblies\WindowsGL」)を入れて、保存すると、コード中で補完してくれるようになった。DebugのところとIntellisenseが関係あるとは思わなかったので全然思い付かなかったが、PTVSもオープンソースなのだしコードを読む習慣があればもっと早く解決していたのかもしれない。

結局MonoGame+IronPythonのコードがどんな感じになったか。

後述の参考の「MonoGame w/ IronPython Example - doesn't work?」を参考に。

import sys
import os
sys.path.append(os.getcwd() + '\\lib')
 
import clr
clr.AddReferenceToFile("MonoGame.Framework.dll")

from Microsoft.Xna.Framework import *
from Microsoft.Xna.Framework.Graphics import *
from Microsoft.Xna.Framework.Content import *
from Microsoft.Xna.Framework.Storage import *
from Microsoft.Xna.Framework.Input import *

 
class App(Game):
    def __init__(self):
        self.graphics = GraphicsDeviceManager(self)
        RootDirectory = "Content"
 
    def Initialize(self):
        super(App, self).Initialize()
 
    def LoadContent(self):
        self.spriteBatch = SpriteBatch(self.GraphicsDevice)
 
    #TODO: use this.Content to load your game content here
    def Update(self, gameTime):
        if GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed or \
            Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Escape):
            self.Exit()

        super(App, self).Update(gameTime)
 
    def Draw(self, gameTime):
        self.graphics.GraphicsDevice.Clear(Color.CornflowerBlue)

        super(App, self).Draw(gameTime)
 
game = App()
game.Run()

これで無地の青画面が出る。この1ファイル感が好きです。

コンピュータビジョンでできた偶然の産物

「実践コンピュータビジョン」読んで書いてたらこんなのできた。

元画像(http://www.ashinari.com/2010/07/23-338955.php?category=243)
f:id:sle:20100717205247j:plain
できたの
f:id:sle:20130428110859p:plain

from PIL import Image
from numpy import *
import imtools
from pylab import *

im = array(Image.open("sample/artist.jpg").convert("L"))
im2, cdf = imtools.histeq(im)

## imshow(im)
imshow(im2)
show()

ポストモダン解析学: 補題5.13

これは何?

補題5.13の行間(?)が気になって、結局2日ぐらい考えたら分かったので書く。引用は全て丸善出版ポストモダン解析学 原書第3版 J.ヨスト著」から。引用中の赤字強調は全てashiato45による。

問題

状況設定

  • Iは実数の閉区間で、I=[a, b]
  • DはIの可算部分集合*1
  • fはIから実数への関数。以下の性質を満たす。
    • fはI上連続
    • fはI-D上で微分可能(I-D=I \cap D^c)
    • 任意のI-Dの元xについて、f'(x)\le M
    • \rho_nはDの番号付け(Dの定義により、番号付けは可能である。)
    • ηは任意の正実数。

証明しようとしているもの

f(b)-f(a)\le M(b-a)+\eta(b-a+1)

本題

証明から問題の箇所を引用します。

A:=\{\xi\in I: a\le \zeta <\xiとなるすべての\zetaf(\zeta)-f(a)\le M(\zeta-a)+\eta(\zeta-a)+\eta\sum_{\rho_n<\zeta} 2^{-n}\}とおく。a\in Aなので、Aは空集合ではない。c:=\sup Aとおく。fの連続性よりc\in Aであり…(略)

というのが本文なのだが、「fの連続性」からどうしてc\in Aが出るのか分からなかった。cがここに書いてある条件を満たしているのかとも思ったのだが、この直後にc\in Aそのものから
f(c)-f(a)\le M(c-a)+\eta (c-a)+\eta \sum_{\rho_n <  c} 2^{-n}
を導いているのでそうではないっぽい。

「fの連続性より」で何がおこったのか。

かいとう

登場人物が多くて大変なので、問題と直接の関わりがあるかは分からないがとりあえずいろいろ調べてみる。状況をなんとか目視しやすくしてみる。

まず、Aの定義からして\xi'<\xi\xi \in Aならxi'\in Aなことがわかる。*2よって、Aはぶちぶち途中で千切れたりせず、A=[a,c ] A=[a,c)のどちらかであることが分かる。
f:id:sle:20130427230710p:plain

図の下の青字にあるように、AがA=[a,c ] だろうがA=[a,c)だろうがAの任意の点\zeta\in [a,c)
f(\zeta)-f(a)\le M(\zeta-a)+\eta(\zeta-a)+\eta\sum_{\rho_n<\zeta} 2^{-n}\}がなりたつ。なぜなら、cはAの上限なので、cがAに属するとすればAの定義そのままで言え、cがAに属さなかったとしても、cよりちょっとだけ小さい点c-\epsilonを十分小さい正数εで表わせばこれはAに属するので、任意の正数εと任意の\zeta\in [a,c-\epsilon] について
f(\zeta)-f(a)\le M(\zeta-a)+\eta(\zeta-a)+\eta\sum_{\rho_n<\zeta} 2^{-n}\}がなりたち、結局同じことになる。証明おわり。なんなら、一方の点を一個とって、それが他方に入ることを言ってもいい。

ではAから出てしまったらどうなるのかというと、それはf(\zeta)-f(a)M(\zeta-a)+\eta(\zeta-a)+\eta\sum_{\rho_n<\zeta} 2^{-n}\}の大小はどちらだか分からなくなってしまう。先程言ったように、「千切れて」とびとびにf(\zeta)-f(a)\le M(\zeta-a)+\eta(\zeta-a)+\eta\sum_{\rho_n<\zeta} 2^{-n}\}がなりたっているかもしれないし、ひょっとしたらそんな区間はないのかもしれない。

してみると、cは「aからここまでは確実にf(\zeta)-f(a)\le M(\zeta-a)+\eta(\zeta-a)+\eta\sum_{\rho_n<\zeta} 2^{-n}\}と言える」という右端の限界だということになる。そしてこれが大事なのだが、緑字で書いたとおり「右端の限界」ということは、その(cの)ちょっと右ではf(\zeta)-f(a) > M(\zeta-a)+\eta(\zeta-a)+\eta\sum_{\rho_n<\zeta} 2^{-n}\}という風に否定が確実に成りたつということが分かる。

以上をまとめてみると、青字の情報を特殊化してとりだして、「cのちょっと左まではf(\zeta)-f(a)\le M(\zeta-a)+\eta(\zeta-a)+\eta\sum_{\rho_n<\zeta} 2^{-n}\}(不等号が小なりイコール)」が言え、緑字より「cのちょっと右まではf(\zeta)-f(a) > M(\zeta-a)+\eta(\zeta-a)+\eta\sum_{\rho_n<\zeta} 2^{-n}\}(不等号が大なり)」が言える。連続性めいてきた。

不等号の両端に式を書くのが面倒なので、以下
F(\zeta):=[f(\zeta)-f(a)]-[M(\zeta-a)+\eta(\zeta-a)+\eta\sum_{\rho_n<\zeta} 2^{-n}]
と定義する。すると、先程のは「cのちょっと左まではFは0以下」で「cのちょっと右まではFは正」ということが言える。

今は簡単のために、このcの左右ちょっとの範囲で\sum_{\rho_n<\zeta} 2^{-n}は定数であるとする。*3すると、fは連続関数であること、Fはfの足し引き定数倍であること、連続関数の足し引き定数倍は連続関数となることより、Fが連続関数であることが言える。連続関数Fが、cのちょっと左まで0以下、ちょっと右まで正なので、F(c)=0が言えた。

最後に、「cの左右ちょっとの範囲で\sum_{\rho_n<\zeta} 2^{-n}は定数である」の仮定を外す。心配なのは、「cのちょっと左まではFは0以下だったのに、不連続性をつかってぴょんとcで0でない正になってしまうのでは」ということだが、\sum_{\rho_n<\zeta} 2^{-n}が単調増加であることから、この項はFを減少させる方向にしか寄与しない。したがって不連続性を使って「増える」ことは絶対にできない。おわり。

ところで

Dで区切られた区間の各々について、千切れない区間での有限増分の定理をつかって、それを足しあわせるんじゃだめなんですか。

*1:1,2,...とIDを振れるようなIの点の集まり。Dとして[a,(a+b)/2]とかはとれない。

*2:「すべての」があるので、特殊ケースとして得られる。

*3:あとで外せることが分かる。

微分積分学(初等の解析学)やるときに大事っぽい式

ポストモダン解析学を読んでいたら、イプシロンデルタ論法の性質で単独でまとめられてもいんじゃねって思ったのがいくつかできたので書きます。多分、微分積分の教科書の行間埋めに役立つんじゃないかと。「かつ」は楔(くさび)の記号\wedgeで表わしてます。あと、PとかQとかは、括弧のなかの文字の関係について述べる*1命題をさします。

2つのイプシロンデルタの式を結びつける

\left(\left(\exists N; \forall n \ge N; P(n)\right) \wedge \left(\exists M; \forall m \ge M; Q(m)\right)\right) \Rightarrow \exists L; \forall l \ge L ; \left(P(l) \wedge Q(l)\right)
lをnとmとのうち、大きいほうをとれば満たされる。2つ以上のイプシロンデルタの命題を結びつけてひとつにしたいときに使う。たとえば、実数列\{a_n\}\lim_{n\rightarrow \infty} a_n = aと収束するとき、
\lim_{n\rightarrow \infty} \frac{a_1 + a_2 + \cdots + a_n}{n}=aを示せ、みたいなときにつかえるはず。

「小さい」のイメージ

fは常に0以上として、P(\epsilon) \Leftrightarrow \exists N; \forall n\ge N; f(n) \le \epsilonとすると、0\le a\le b \wedge P(a) \Rightarrow P(b)がなりたつ。

よく教科書とかにしれっと書いてある、「εは十分小さいので、\epsilon < 1としてよい」みたいなやつの根拠になる。そこで示せたなら、このことによりそれより大きいところは自動的に証明されたことになる。

イプシロンを加工してよい

\left(\forall \epsilon; P\left(\epsilon\right)\right) \Rightarrow \left(\forall \epsilon; P\left(f(\epsilon)\right)\right)
例えばなりゆきで2\epsilonとかで最後の評価をしてしまったときとかに使える。さっきのと組合せて。

訂正

\left(\lim_{n\rightarrow\infty}b_n=0 \wedge \exists N; \forall n\ge N |a_n-a| \le b_n\right)\Rightarrow \forall \epsilon \exists N \forall n\ge N |a_n-a|\le \epsilon
特に、
\left(k\ge 0 \wedge \forall \epsilon \exists N; \forall n\ge N |a_n-a| \le k\epsilon\right)\Rightarrow \forall \epsilon \exists N \forall n\ge N |a_n-a|\le \epsilon

要するにいくらでも縮むもので差を抑えられれば、εで直接に抑えなくてもいいという話。なりゆきで2\epsilonで抑えちゃったときとかの合法化に使える。あと、εで抑えるところでは<\leかを気にしなくてよい、ということも保証する。

全称と存在の交換

\left(\exists a; \forall b; P(a,b)\right) \Rightarrow \forall b; \exists a; P(a,b)
一様連続性から普通の連続性まで情報を落して使うときに。

*1:使わない文字があってもよいが、他の変数には依存しない

変数スコープに関する初歩的なミスで詰んでた

なんか書いてるjsのコードでの問題が切り離せたので備忘録に。

    var array = [];
    
    for(var i=0; i < 3; i++){
      console.log("i=", i);
      array.push(function(){
        console.log("in function ", i);
      });
      array[i]()
    }

    console.log(array.length);
    for(var j=0; j < array.length; j++){
      console.log("run function no.", j);
      array[j]();
    }

こういうコードで、最後の配列に入った関数を実行するときに、

run function no. 0
in function 0
run function no. 1
in function 1
run function no. 2
in function 2

となることを期待していたというのが本質のバグ作ってた。このコードの最後は実際は、

run function no. 0
in function 3
run function no. 1
in function 3
run function no. 2
in function 3

と実行される。「なんで"i<3"なのにi=3になってるんだよ!」という類のことで悩んでいたのだが、カウンタが生きているならば、forが終ったあとはその制約の一個次になるんだったなあと高校のBASICの授業を思いだす。

DIM I

FOR I = 0 TO 3
  PRINT I
NEXT
PRINT I

みたいに書くと(正確な文法忘れた)

0
1
2
3
4

となるはず

追記

"JavaScript: The Good Parts"のクロージャの章に全く同じの載ってました。結局こう直します。

    var array = [];

    for(var i=0; i < 3; i++){
      array.push(function(j){
        return function(){
          console.log("in function (revised): ", j);
        };
      }(i));
    }

    for(var j=0; j < array.length; j++){
      console.log("run function no.", j);
      array[j]();
    }