Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

ディラック作用素の代数計算

More than 1 year has passed since last update.

微分作用素の一種であるディラック作用素を実装します。代数計算に必要な要素を確認するのが狙いです。

ディラック作用素については以下の記事を参照してください。

この記事で作ったプログラムによる計算結果を使った記事です。

実装には F# を使用します。

以下の記事で紹介した手法で開発しました。

F#の入門記事を書いています。

この記事には関連記事があります。

概要

ベクトル解析ではスカラー場の微分をgrad、ベクトル場の微分をrot/divと呼びます。

\begin{align*}
\mathrm{grad}F&=\left(\begin{matrix}F_x\\F_y\\F_z\end{matrix}\right)\\
\mathrm{rot}\left(\begin{matrix}X\\Y\\Z\end{matrix}\right)&=\left(\begin{matrix}Z_y-Y_z\\X_z-Z_x\\Y_x-X_y\end{matrix}\right)\\
\mathrm{div}\left(\begin{matrix}X\\Y\\Z\end{matrix}\right)&=X_x+Y_y+Z_z
\end{align*}

ディラック作用素を使えば、これらを算出して関係を体系的に整理できます。

\begin{align*}
DF
&=\underbrace{F_x\,dx+F_y\,dy+F_z\,dz}_{\mathrm{grad}}\\
D(X\,dx+Y\,dy+Z\,dz)
&=\underbrace{X_x+Y_y+Z_z}_{\mathrm{div}}\\
&\quad+\underbrace{(Z_y-Y_z)dy\,dz+(X_z-Z_x)dz\,dx+(Y_x-X_y)dx\,dy}_{\mathrm{rot}}\\
D(X\,dy\,dz+Y\,dz\,dx+Z\,dx\,dy)
&=\underbrace{(Y_z-Z_y)dx+(Z_x-X_z)dy+(X_y-Y_x)dz}_{-\mathrm{rot}}\\
&\quad+\underbrace{(X_x+Y_y+Z_z)dx\,dy\,dz}_{\mathrm{div}}\\
DF\,dx\,dy\,dz
&=\underbrace{F_x\,dy\,dz+F_y\,dz\,dx+F_z\,dx\,dy}_{\mathrm{grad}}
\end{align*}

関係を図示します。右向きの矢印と左向きの矢印はほぼ左右対称となっています。rot の符号反転は係数配置の左右反転に由来すると解釈できます。例: $(Z_y-Y_z)$ → $(Y_z-Z_y)$

図1.png

この計算を実装します。先に、完成したコード全体を示します。

計算で必要となる項の構造をタプルで表現します。

-X_{yz}\,dx\,dy
(-1, "X", ["y"; "z"], ["x"; "y"])

エイリアスを定義します。

type Term = int * string * string list * string list

表示用に文字列に変換する関数を実装します。

基底

簡単のため微分形式に決め打ちします。

let t, w, x, y, z = "t", "w", "x", "y", "z"

let tostrb (tb:string list) =
    if tb.IsEmpty then "" else
    @"d" + String.concat @"\,d" tb
動作確認
do
    let test xs =
        printfn "tostrb: %A -> %s" xs (tostrb xs)
    test [x;y]
実行結果
tostrb: ["x"; "y"] -> dx\,dy

一項

1つの項を変換します。

let tostr1 ((ts, tf, tp, tb):Term) =
    if ts = 0 then "0" else
    let s = match ts with 1 -> "" | -1 -> "-" | _ -> ts.ToString()
    let p =
        if tp.IsEmpty then "" else
        sprintf "_{%s}" (String.concat "" tp)
    match tf, p, tostrb tb with
    | "", "", "" -> ts.ToString()
    | "", "", tb -> s + tb
    | _ , _ , "" -> s + tf + p
    | _ , _ , tb -> s + tf + p + @"\," + tb
動作確認
do
    let test t =
        printfn "tostr1: %A -> %s" t (tostr1 t)
    test( 1,"X",[]   ,[x])
    test(-1,"Y",[x;x],[y])
    test( 2,"Y",[z]  ,[z;x])
実行結果
tostr1: (1, "X", [], ["x"]) -> X\,dx
tostr1: (-1, "Y", ["x"; "x"], ["y"]) -> -Y_{xx}\,dy
tostr1: (2, "Y", ["z"], ["z"; "x"]) -> 2Y_{z}\,dz\,dx

多項式

項のリストで多項式を表現して、多項式を変換します。

let tostr (xs:Term list) =
    xs
    |> Seq.zip (Seq.init xs.Length id)
    |> Seq.map (fun (i, t) ->
        let s = tostr1 t
        if i = 0 || s.StartsWith "-" then s else "+" + s)
    |> String.concat ""
動作確認
do
    let test xs = printfn "tostr: %A -> %s" xs (tostr xs)
    test [1,"X",[],[x]; -1,"Y",[x;x],[y;z]]
実行結果
tostr: [(1, "X", [], ["x"]); (-1, "Y", ["x"; "x"], ["y"; "z"])] -> X\,dx-Y_{xx}\,dy\,dz

ディラック作用素

スカラー関数にディラック作用素を適用します。

DF=F_x\,dx+F_y\,dy+F_z\,dz

空間の全基底を偏微分と基底に付加して多項式を出力します。

let r2b1, r3b1, r4b1 = [x;y], [x;y;z], [w;x;y;z]
let m2b1, m3b1, m4b1 = [t;x], [t;x;y], [t;x;y;z]

let dirac0 f b1 = [for b in b1 -> 1, f, [b], [b]]
動作確認
do
    let test b1 f = printfn @"\mathrm{dirac0}&: %s\\ %s\\" f (dirac0 f b1 |> tostr)
    test r3b1 "F"
実行結果
\mathrm{dirac0}&: F\ →\ F_{x}\,dx+F_{y}\,dy+F_{z}\,dz\\

以後、実行結果は数式で示します。

\mathrm{dirac0}: F\ →\ F_{x}\,dx+F_{y}\,dy+F_{z}\,dz\\

項への作用を実装します。

let dirac1 b1 ((ts, tf, tp, tb):Term) =
    [for b in b1 -> ts, tf, List.append tp [b], List.append [b] tb]
動作確認
do
    let test t =
        for b1 in [r2b1; r3b1; r4b1] do
        printfn @"\mathrm{dirac1}&: %s\\ %s\\"
            (tostr1 t) (dirac1 b1 t |> tostr)
    test (1,"F",[],[])
    test (1,"F",[],[x])
\begin{align*}
\mathrm{dirac1}&: F\ →\ F_{x}\,dx+F_{y}\,dy\\
\mathrm{dirac1}&: F\ →\ F_{x}\,dx+F_{y}\,dy+F_{z}\,dz\\
\mathrm{dirac1}&: F\ →\ F_{w}\,dw+F_{x}\,dx+F_{y}\,dy+F_{z}\,dz\\
\mathrm{dirac1}&: F\,dx\ →\ F_{x}\,dx\,dx+F_{y}\,dy\,dx\\
\mathrm{dirac1}&: F\,dx\ →\ F_{x}\,dx\,dx+F_{y}\,dy\,dx+F_{z}\,dz\,dx\\
\mathrm{dirac1}&: F\,dx\ →\ F_{w}\,dw\,dx+F_{x}\,dx\,dx+F_{y}\,dy\,dx+F_{z}\,dz\,dx\\
\end{align*}

次元を変えてテストしています。

多項式

多項式への作用を実装します。

let f = [1,"F",[],[]]

let dirac b1 xs = List.collect (dirac1 b1) xs
動作確認
do
    let test b1 xs =
        let dxs = dirac b1 xs
        printfn @"\mathrm{dirac}&: %s\\ %s\\"
            (tostr dxs) (dirac b1 dxs |> tostr)
    test r2b1 f
    test m2b1 f
\begin{align*}
\mathrm{dirac}&: F_{x}\,dx+F_{y}\,dy\ →\ F_{xx}\,dx\,dx+F_{xy}\,dy\,dx+F_{yx}\,dx\,dy+F_{yy}\,dy\,dy\\
\mathrm{dirac}&: F_{t}\,dt+F_{x}\,dx\ →\ F_{tt}\,dt\,dt+F_{tx}\,dx\,dt+F_{xt}\,dt\,dx+F_{xx}\,dx\,dx\\
\end{align*}

スカラー関数に作用させて作った多項式に、再度作用させてテストしています。

ラプラシアン

2回の作用を関数化します。これはいわゆるラプラシアン(ラプラス作用素)です。

let laplace sp = dirac sp >> dirac sp
動作確認
do
    let test sp xs =
        printfn @"\mathrm{laplace}&: %s\\ %s\\"
            (tostr xs) (laplace sp xs |> tostr)
    test r2b1 f
    test m2b1 f
\begin{align*}
\mathrm{laplace}&: F\ →\ F_{xx}\,dx\,dx+F_{xy}\,dy\,dx+F_{yx}\,dx\,dy+F_{yy}\,dy\,dy\\
\mathrm{laplace}&: F\ →\ F_{tt}\,dt\,dt+F_{tx}\,dx\,dt+F_{xt}\,dt\,dx+F_{xx}\,dx\,dx\\
\end{align*}

式の整理

単に計算しただけでは式が複雑なままです。更に計算を進めて式を整理します。

縮約

簡単のため今回は正規直交基底に限定します。同じ基底同士の幾何積はスカラーに縮約します(内積)。値は空間の計量に依存しますが、ユークリッド空間では 1 です。

\underbrace{dx\,dx}_{縮約}=1

縮約するには基底が隣接している必要があります。隣接していない場合、バブルソートのように基底を交換して隣接させます。交換の際に符号が反転しますが、これを反交換性と呼びます。

dx\,\underbrace{dy\,dx}_{交換}=-\underbrace{dx\,dx}_{縮約}\,dy=-dy

※ このようなルールで交換と縮約を行う代数系をクリフォード代数と呼びます。

交換回数

交換回数を数えることで符号が決まります。偶数なら正、奇数なら負です。

let acom i = if i &&& 1 = 1 then -1 else 1
動作確認
do
    let test i =
        printfn @"\mathrm{acom}&: %d\\ %d\\" i (acom i)
    test 0
    test 1
    test 2
    test 3
\begin{align*}
\mathrm{acom}&: 0\ →\ 1\\
\mathrm{acom}&: 1\ →\ -1\\
\mathrm{acom}&: 2\ →\ 1\\
\mathrm{acom}&: 3\ →\ -1\\
\end{align*}

基底

基底の交換と縮約を実装します。計量を指定します。

let r2g = Map.ofList [x,1; y,1]
let r3g = Map.ofList [x,1; y,1; z,1]
let r4g = Map.ofList [w,1; x,1; y,1; z,1]
let m2g = Map.ofList [t,1; x,-1]
let m3g = Map.ofList [t,1; x,-1; y,-1]
let m4g = Map.ofList [t,1; x,-1; y,-1; z,-1]

let rec pair0 g = function
| [] -> 1, []
| x::xs ->
    match List.tryFindIndex ((=) x) xs with
    | None ->
        let i, ys = pair0 g xs
        i, x::ys
    | Some i ->
        let xa = List.toArray xs
        let j, ys = pair0 g (Array.append xa.[.. i - 1] xa.[i + 1 ..] |> Array.toList)
        acom i * Map.find x g * j, ys
動作確認
do
    let test g xs =
        printfn @"\mathrm{pair0}&: %A\\ %A\\" xs (pair0 g xs)
    test r2g [x;x]
    test r2g [x;y]
    test r2g [x;y;x]
    test m2g [x;t;x]
\begin{align*}
\mathrm{pair0}&: ["x"; "x"]\ →\ (1, [])\\
\mathrm{pair0}&: ["x"; "y"]\ →\ (1, ["x"; "y"])\\
\mathrm{pair0}&: ["x"; "y"; "x"]\ →\ (-1, ["y"])\\
\mathrm{pair0}&: ["x"; "t"; "x"]\ →\ (1, ["t"])\\
\end{align*}

項に対して適用します。

let pair1 g ((ts, tf, tp, tb):Term) =
    let s, b = pair0 g tb
    s * ts, tf, tp, b
動作確認
do
    let test g x =
        let t = 1, "", [], x
        printfn @"\mathrm{pair1}&: %s\\ %s\\" (tostr1 t) (pair1 g t |> tostr1)
    test r2g [x;x]
    test r2g [x;y]
    test r2g [x;y;x]
    test m2g [x;t;x]
\begin{align*}
\mathrm{pair1}&: dx\,dx\ →\ 1\\
\mathrm{pair1}&: dx\,dy\ →\ dx\,dy\\
\mathrm{pair1}&: dx\,dy\,dx\ →\ -dy\\
\mathrm{pair1}&: dx\,dt\,dx\ →\ dt\\
\end{align*}

多項式

多項式に対して適用します。

let pair g = List.map (pair1 g)
動作確認
do
    let test b1 g xs =
        let lxs = laplace b1 xs
        printfn @"\mathrm{pair}&: %s\\ %s\\"
            (tostr lxs) (pair g lxs |> tostr)
    test r2b1 r2g f
    test m2b1 m2g f
\begin{align*}
\mathrm{pair}&: F_{xx}\,dx\,dx+F_{xy}\,dy\,dx+F_{yx}\,dx\,dy+F_{yy}\,dy\,dy\ →\ F_{xx}+F_{xy}\,dy\,dx+F_{yx}\,dx\,dy+F_{yy}\\
\mathrm{pair}&: F_{tt}\,dt\,dt+F_{tx}\,dx\,dt+F_{xt}\,dt\,dx+F_{xx}\,dx\,dx\ →\ F_{tt}+F_{tx}\,dx\,dt+F_{xt}\,dt\,dx-F_{xx}\\
\end{align*}

基底の並べ替え

反交換性を利用すれば、並びが異なる基底を同類項として整理できます。

a\,dx\,dy+b\,\underbrace{dy\,dx}_{交換}=a\,dx\,dy-b\,dx\,dy=(a-b)dx\,dy

回数

並びを指定して並べ替えます。符号を決めるのに必要な回数を返します。要素が合わなければ None を返します。

let rec bsortc = function
| [], [] -> Some 0
| [], _  -> None
| b::bs, xs ->
    match List.tryFindIndex ((=) b) xs with
    | None -> None
    | Some i ->
        match bsortc (bs, List.filter ((<>) b) xs) with
        | None -> None
        | Some j -> Some (i + j)
動作確認
do
    let test bs xs =
        printfn @"\mathrm{bsortc}&: %s\\ %A\\" (tostrb xs) (bsortc(bs, xs))
    test [z;x]   [x;z]
    test [x;y]   [x;z]
    test [x;y;z] [z;y;x]
\begin{align*}
\mathrm{bsortc}&: dx\,dz\ →\ Some 1\\
\mathrm{bsortc}&: dx\,dz\ →\ <null>\\
\mathrm{bsortc}&: dz\,dy\,dx\ →\ Some 3\\
\end{align*}

標準化

標準的な並びを定義します。

let r2b = [[x];[y]
           [x;y]]
let r3b = [[x];[y];[z]
           [y;z];[z;x];[x;y]
           [x;y;z]]
let r4b = [[w];[x];[y];[z]
           [w;x];[w;y];[w;z];[y;z];[z;x];[x;y]
           [x;y;z];[w;y;z];[w;z;x];[w;x;y]
           [w;x;y;z]]

let m2b = [[t];[x]
           [t;x]]
let m3b = [[t];[x];[y]
           [x;y];[t;x];[t;y]
           [t;x;y]]
let m4b = [[t];[x];[y];[z]
           [t;x];[t;y];[t;z];[y;z];[z;x];[x;y]
           [x;y;z];[t;y;z];[t;z;x];[t;x;y]
           [t;x;y;z]]

この中から合致する組み合わせを探して、符号を添えて返します。

let bsort0 b list =
    let len = List.length list
    let f bb =
        if List.length bb <> len then None else
        match bsortc (bb, list) with
        | None   -> None
        | Some i -> Some (acom i, bb)
    match List.tryPick f b with
    | None   -> 1, list
    | Some x -> x
動作確認
do
    let test b xs =
        let s, ys = bsort0 b xs
        printfn @"\mathrm{bsort0}&: %s\\ %d, %s\\" (tostrb xs) s (tostrb ys)
    test r3b [x;z]
    test r3b [z;x]
    test r3b [y;x]
    test r3b [z;y;x]
\begin{align*}
\mathrm{bsort0}&: dx\,dz\ →\ -1, dz\,dx\\
\mathrm{bsort0}&: dz\,dx\ →\ 1, dz\,dx\\
\mathrm{bsort0}&: dy\,dx\ →\ -1, dx\,dy\\
\mathrm{bsort0}&: dz\,dy\,dx\ →\ -1, dx\,dy\,dz\\
\end{align*}

項の基底を並べ替えます。

let bsort1 b ((ts, tf, tp, tb):Term) =
    let ts2, tb2 = bsort0 b tb
    ts2 * ts, tf, tp, tb2
動作確認
do
    let test b tb =
        let x = 1, "", [], tb
        printfn @"\mathrm{bsort1}&: %s\\ %s\\" (tostr1 x) (bsort1 b x |> tostr1)
    test r3b [x;z]
    test r3b [z;x]
    test r3b [y;x]
    test r3b [z;y;x]
\begin{align*}
\mathrm{bsort1}&: dx\,dz\ →\ -dz\,dx\\
\mathrm{bsort1}&: dz\,dx\ →\ dz\,dx\\
\mathrm{bsort1}&: dy\,dx\ →\ -dx\,dy\\
\mathrm{bsort1}&: dz\,dy\,dx\ →\ -dx\,dy\,dz\\
\end{align*}

空間の属性

空間の属性として基底、基底の並び、計量が出て来ました。使い分けると面倒なため、まとめてセットにします。

let r2, r3, r4 = (r2b1, r2b, r2g), (r3b1, r3b, r3g), (r4b1, r4b, r4g)
let m2, m3, m4 = (m2b1, m2b, m2g), (m3b1, m3b, m3g), (m4b1, m4b, m4g)

多項式

多項式の基底を並べ替えます。

let bsort (_, b, _) = List.map (bsort1 b)
動作確認
do
    let test ((b1, _, g) as sp) xs =
        let lxs = laplace b1 xs |> pair g
        printfn @"\mathrm{bsort}&: %s\\ %s\\"
            (tostr lxs) (bsort sp lxs |> tostr)
    test r2 f
    test m2 f
\begin{align*}
\mathrm{bsort}&: F_{xx}+F_{xy}\,dy\,dx+F_{yx}\,dx\,dy+F_{yy}\ →\ F_{xx}-F_{xy}\,dx\,dy+F_{yx}\,dx\,dy+F_{yy}\\
\mathrm{bsort}&: F_{tt}+F_{tx}\,dx\,dt+F_{xt}\,dt\,dx-F_{xx}\ →\ F_{tt}-F_{tx}\,dt\,dx+F_{xt}\,dt\,dx-F_{xx}\\
\end{align*}

基底の縮約と並べ替えにより、かなり整理されて来ました。

偏微分の並べ替え

簡単のため偏微分の順序は交換可能だとします。基底とは異なる組み合わせが現れます(縮約しないため)。単独の基底として与えられたリストの順番で並べ替えます。

let psort (b1, _, _) =
    List.map <| fun ((s, tf, tp, tb):Term) ->
        let f x = List.findIndex ((=) x) b1
        s, tf, List.sortBy f tp, tb
動作確認
do
    let test ((b1, _, g) as sp) xs =
        let lxs = laplace b1 xs |> pair g |> bsort sp
        printfn @"\mathrm{psort}&: %s\\ %s\\"
            (tostr lxs) (psort sp lxs |> tostr)
    test r2 f
    test m2 f
\begin{align*}
\mathrm{psort}&: F_{xx}-F_{xy}\,dx\,dy+F_{yx}\,dx\,dy+F_{yy}\ →\ F_{xx}-F_{xy}\,dx\,dy+F_{xy}\,dx\,dy+F_{yy}\\
\mathrm{psort}&: F_{tt}-F_{tx}\,dt\,dx+F_{xt}\,dt\,dx-F_{xx}\ →\ F_{tt}-F_{tx}\,dt\,dx+F_{tx}\,dt\,dx-F_{xx}\\
\end{align*}

項の並べ替え

基底を基準にして項を並べ替えます。同じ基底では符号や係数を見ます。

let sort (_, b, _) =
    List.filter (fun (ts, _, _, _) -> ts <> 0)
    >> List.sortBy (fun (ts, tf, tp, tb) ->
        (match tb with [] -> 0 | x  -> 1 + List.findIndex ((=) x) b),
        -sign ts, tf, tp)
動作確認
do
    let test ((b1, _, g) as sp) xs =
        let lxs = laplace b1 xs |> pair g |> bsort sp |> psort sp
        printfn @"\mathrm{sort}&: %s\\ %s\\"
            (tostr lxs) (sort sp lxs |> tostr)
    test r2 f
    test m2 f
\begin{align*}
\mathrm{sort}&: F_{xx}-F_{xy}\,dx\,dy+F_{xy}\,dx\,dy+F_{yy}\ →\ F_{xx}+F_{yy}+F_{xy}\,dx\,dy-F_{xy}\,dx\,dy\\
\mathrm{sort}&: F_{tt}-F_{tx}\,dt\,dx+F_{tx}\,dt\,dx-F_{xx}\ →\ F_{tt}-F_{xx}+F_{tx}\,dt\,dx-F_{tx}\,dt\,dx\\
\end{align*}

同類項のグループ化

同類項をグループ化して表示します。Seq.groupBy を活用します。

let tostrg = function
| [ ] -> "0"
| [x] -> tostr1 x
| xs  ->
    xs
    |> Seq.groupBy (fun ((_, _, _, tb):Term) -> tb)
    |> Seq.zip (Seq.init xs.Length id)
    |> Seq.map (fun (i, (tb, xs)) ->
        let s =
            if tb = [] then Seq.toList xs |> tostr else
            match Seq.map (fun (ts, tf, tp, _) -> ts, tf, tp, []) xs |> Seq.toList with
            | [x] -> tostr1 x + @"\," + tostrb tb
            | xs  -> "(" + tostr xs + ")" + tostrb tb
        if i = 0 || s.StartsWith "-" then s else "+" + s)
    |> String.concat ""
動作確認
do
    let test ((b1, _, g) as sp) xs =
        let lxs = laplace b1 xs |> pair g |> bsort sp |> psort sp |> sort sp
        printfn @"\mathrm{tostrg}&: %s\\ %s\\"
            (tostr lxs) (tostrg lxs)
    test r2 f
    test m2 f
\begin{align*}
\mathrm{tostrg}&: F_{xx}+F_{yy}+F_{xy}\,dx\,dy-F_{xy}\,dx\,dy\ →\ F_{xx}+F_{yy}+(F_{xy}-F_{xy})dx\,dy\\
\mathrm{tostrg}&: F_{tt}-F_{xx}+F_{tx}\,dt\,dx-F_{tx}\,dt\,dx\ →\ F_{tt}-F_{xx}+(F_{tx}-F_{tx})dt\,dx\\
\end{align*}

表示の際にグループ化しているだけで、データ構造の変更(ネスト等)は行っていません。

同類項の整理

同類項を整理します。List.partition を活用します。

let rec simplify = function
| [] -> []
| (ts1, tf1, tp1, tb1)::xs ->
    let t1 = tostr1 (1, tf1, tp1, tb1)
    let xs1, xs2 =
        xs
        |> List.partition (fun (_, tf2, tp2, tb2) ->
            t1 = tostr1 (1, tf2, tp2, tb2))
    match ts1 + (Seq.map (fun (ts, _, _, _) -> ts) xs1 |> Seq.sum) with
    | 0  -> simplify xs2
    | ts -> (ts, tf1, tp1, tb1)::simplify xs2
動作確認
do
    let test ((b1, _, g) as sp) xs =
        let lxs = laplace b1 xs |> pair g |> bsort sp |> psort sp |> sort sp
        printfn @"\mathrm{simplify}&: %s\\ %s\\"
            (tostrg lxs) (simplify lxs |> tostrg)
    test r2 f
    test m2 f
\begin{align*}
\mathrm{simplify}&: F_{xx}+F_{yy}+(F_{xy}-F_{xy})dx\,dy\ →\ F_{xx}+F_{yy}\\
\mathrm{simplify}&: F_{tt}-F_{xx}+(F_{tx}-F_{tx})dt\,dx\ →\ F_{tt}-F_{xx}\\
\end{align*}

これで今回の目的だった形になりました。

まとめ関数

工程を細かく分割したため関数が多くなりました。利便性のため、まとめ関数を用意します。

let doDirac ((b1, _, g) as sp) =
    dirac b1 >> pair g >> bsort sp >> psort sp >> sort sp >> simplify

テスト

冒頭に挙げた3次元のユークリッド空間を計算します。

let test sp f =
    let df = doDirac sp f
    printfn @"D(%s)&=%s\\" (tostr f) (tostrg df)

test r3 [1,"F",[],[]]
test r3 [1,"X",[],[x]; 1,"Y",[],[y]; 1,"Z",[],[z]]
test r3 [1,"X",[],[y;z]; 1,"Y",[],[z;x]; 1,"Z",[],[x;y]]
test r3 [1,"F",[],[x;y;z]]
\begin{align*}
D(F)&=F_{x}\,dx+F_{y}\,dy+F_{z}\,dz\\
D(X\,dx+Y\,dy+Z\,dz)&=X_{x}+Y_{y}+Z_{z}+(Z_{y}-Y_{z})dy\,dz+(X_{z}-Z_{x})dz\,dx+(Y_{x}-X_{y})dx\,dy\\
D(X\,dy\,dz+Y\,dz\,dx+Z\,dx\,dy)&=(Y_{z}-Z_{y})dx+(Z_{x}-X_{z})dy+(X_{y}-Y_{x})dz+(X_{x}+Y_{y}+Z_{z})dx\,dy\,dz\\
D(F\,dx\,dy\,dz)&=F_{x}\,dy\,dz+F_{y}\,dz\,dx+F_{z}\,dx\,dy\\
\end{align*}

うまく計算できています。

少し手を加えれば、他の次元やミンコフスキー空間も計算できます。計算結果についてはこちらの記事を参照してください。

7shi
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away