new (methods and applications of programming in mathematicaelie.korea.ac.kr/~mssc2015/chung.pdf ·...

63
Mathematica 프로그래밍의 기법과 응용 (Methods and Applications of Programming in Mathematica) 정영주 광주과학기술원 정보통신공학부 [email protected] 2015. 8. 22 수학 소프트웨어 여름 캠프 고려대학교 © 2015 Youngjoo Chung All Rights Reserved

Upload: others

Post on 21-Oct-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

  • Mathematica 프로그래밍의 기법과 응용(Methods and Applications ofProgramming in Mathematica)

    정영주

    광주과학기술원 정보통신공학부[email protected]

    2015. 8. 22수학 소프트웨어 여름 캠프

    고려대학교

    © 2015Youngjoo Chung

    All Rights Reserved

  • Mathematica의 프로그래밍 패러다임

    변수의 영역과 Context

    Namespace Management (Mathematica Guide)

    변수와 Context

    Mathematica에서 변수는 선언 혹은 설정 등 최초 사용과 동시에 생성되며 현재의 con-text가 주어진다.

    Context[x]Global`

    변수 x의 전체 이름은 Global`x이며 다른 context를 가지는 같은 이름의 변수 x와는 구별된다. 변수의 전체 이름 context`x 형태를 사용하면 충돌을 피할 수 있다.

    변수 x의 값을 설정한다.

    x = 1010

    변수 x의 값을 확인한다.

    2 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • x

    10

    아래와 같이 패키지에서 같은 변수명을 사용하면 충돌이 발생하여 변수의 값이 명확하지 않을 수 있다.

    BeginPackage["Test`"];x = 100;EndPackage[];

    x::shdw: Symbol x appears in multiple contexts Test`, Global`;definitions in context Test` may shadow or be shadowed by other definitions.

    변수의 값을 확인한다.

    {x, Global`x, Test`x}{100, 10, 100}변수 Test`x를 제거한다.

    Remove[Test`x]

    함수

    Mathematical Functions (Mathematica Guide)

    함수의 정의

    Defining Functions (Mathematica Tutorial)

    Set (=)과 SetDelayed (:=)

    Set (=)은 함수를 정의할 때 우변을 실행한 결과를 설정하고 SetDelayed (:=)는 함수가 호출될 때마다 주어진 변수를 사용하여 우변을 실행한다.

    f[x_] = Expand[x];g[x_] := Expand[x];함수 f의 경우 Expand[x]의 결과는 x이므로 f[x_]=x와 같다.

    f(x + a)2(a + x)2g(x + a)2

    a2 + 2 a x + x2

    Presentation-Y. Chung (2015-08-22 Summer School).nb 3

  • Remove[f, g]함수와 Context

    함수 f를 정의한다.

    In[25]:= f[x_] := x^3;함수 f의 context는 “Global`”이다.Context[f]

    Global`

    커널 함수들의 context는 “System`”이다.Context[Integrate]

    System`

    • 아래와 같이 패키지 Test에서 같은 이름의 함수를 정의하면 충돌이 발생한다.BeginPackage["Test`"];f;Begin["`Private`"];f[x_] := x^2;End[];EndPackage[];

    f::shdw: Symbol f appears in multiple contexts Test`, Global`;definitions in context Test` may shadow or be shadowed by other definitions.

    아래와 같이 함수 f를 실행하니 Test`f가 실행되었다.

    f[a]a2

    함수명에 context를 포함하면 의미가 명확해진다.

    {Test`f[a], Global`f[a]}{a2, a3}• 현재 상태에서는 Test`f가 Global`f를 가리고 있음을 알 수 있다.?? f

    Test`f

    f[Test`Private`x_] := Test`Private`x2

    4 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • ?? Global`f

    Global`f

    Global`f[x_] := x3Test`f를 제거한다.

    Remove[Test`f]함수의 Attributes

    함수의 성질은 attributes에 의해 영향을 받는다. 함수의 attributes는 Attributes 함수를 사용하여 확인할 수 있고 SetAttributes, ClearAttributes 함수를 사용하여 변경할 수 있다. 보호된 함수의 경우 Unprotect를 사용하여 보호를 해제하여야 하며 변경 후 Protect를 사용하여 다시 보호할 수 있다.

    Plut (+) 함수의 attributes

    In[26]:= Attributes[Plus]Out[26]= {Flat, Listable, NumericFunction, OneIdentity, Orderless, Protected}

    In[31]:= Plus[{1, 2, 3}, {4, 5, 6}]Out[31]= {5, 7, 9}

    Plot 함수의 attributes

    In[27]:= Attributes[Plot]Out[27]= {HoldAll, Protected, ReadProtected}

    예제

    함수 f를 정의한다.

    In[91]:= f[x_?NumericQ] := x3함수 f는 설정된 attributes가 없다.

    In[51]:= Attributes[f]Out[51]= {}

    Attributes를 Listable로 설정한다.

    In[53]:= SetAttributes[f, Listable]행렬에 f를 적용하면 각 element에 f가 적용된다.

    Presentation-Y. Chung (2015-08-22 Summer School).nb 5

  • In[54]:= f[{{a, b, c}, {1, 2, 3}}]Out[54]= {{f[a], f[b], f[c]}, {1, 8, 27}}함수명

    함수명은 다른 변수와 마찬가지로 다른 값으로 설정이 가능하며 (단 Protected attribute가 없을 때) 옵션명 등 다른 용도로도 사용이 가능하다.

    f를 a로 설정하면 f[x]는 a[x]로 된다.

    In[77]:= f = a;f[x]

    Out[78]= a[x]f를 Sin으로 설정하면 f[x]는 Sin[x]로 된다.

    In[100]:= f = Sin;f[x]

    Out[101]= Sin[x]f 자체의 attributes는 변경되지 않지만 f는 곧바로 Sin으로 되므로 같은 attributes를 가지는 효과를 가진다.

    In[102]:= Attributes[f]f[{a, b, c}]

    Out[102]= {}Out[103]= {Sin[a], Sin[b], Sin[c]}

    f를 제거한다.

    In[104]:= Remove[f]위의 경우 Remove의 attributes에 HoldAll이 있으므로 f가 제거되고 Sin은 제거되지 않는다.

    In[72]:= Attributes[Remove]Out[72]= {HoldAll, Locked, Protected}

    6 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • Packages

    Wolfram Language Packages (Mathematica Tutorial)

    Package Development (Mathematica Guide)

    A Sample Package

    FilePrint["Sample.m"]

    Presentation-Y. Chung (2015-08-22 Summer School).nb 7

  • (*:Copyright: Copyright 2002-2015 Youngjoo Chung, Gwangju Institute of Science and Technology,(*:Mathematica Version: 7.0 *)(*:Package Version: 1.0 *)(*:Name: Sample` *)(*:Author: Youngjoo Chung *)(*:Summary: This package contains sample macros.*)(*:Disclaimer: Neither the author nor Gwangju Institute of Science and Technology makes any warranty, or assumes any legal liability or responsibility for the accuracy of the information contained and the results that are incurred due to the use of this package.*)BeginPackage["Sample`"];(* Function Declarations *)addTwoaddThreetestFun

    Begin["`Private`"](* Private functions *)addTwo[a_, b_] := a + b;addThree[a_?NumericQ, b_?NumericQ, c_?NumericQ] := a + b + c;testFun[x_] := F[x];testFun[x_?NumericQ] := G[x];End[] (* end the private context *)EndPackage[] (* Sample` *)Sample 패키지를 로드한다.

  • ? Sample`*Sample`

    addThree addTwo testFun

    addTwo 함수의 context는 “Sample`”이다.Context[addTwo]

    Sample`

    addTwo 함수의 내용을 확인한다.

    ?? addTwo

    Sample`addTwo

    addTwo[Sample`Private`a_, Sample`Private`b_] := Sample`Private`a + Sample`Private`baddTwo 함수의 변수에는 제한이 없다.

    addTwo[a, b]a + baddThree 함수의 변수에는 NumericQ가 True여야 한다는 조건이 있다.

    addThree[a, b, c]addThree[a, b, c]addThree[1, 2, 3]

    6

    • testFun 함수에는 두 가지 정의가 있다.testFun[x_] := F[x];testFun[x_?NumericQ] := G[x];

    x가 numeric이면 G[x]가 실행되고, numeric이 아니면 F[x]가 실행된다.

    {testFun[2.0], testFun[a]}{Sample`Private`G[2.], Sample`Private`F[a]}“Sample`” context를 가지는 모든 함수와 변수를 제거한다.Remove["Sample`*"]

    Module, Block, With

    Presentation-Y. Chung (2015-08-22 Summer School).nb 9

  • Blocks Compared with Modules (Mathematica Tutorial)

    Module : lexical scoping (변수명에 $ModuleNumber가 추가되어 새로운 변수가 생성)Block : dynamic scoping (같은 변수명을 사용)With : local constants (실행 전 상수를 설정하고 변경할 수 없음)

    Module내 변수명에 추가되는 $ModuleNumber는 Module을 실행할 때마다 하나씩 증가한다.

    $ModuleNumber

    1473

    Module[{x}, x]x$1474

    Block의 변수명은 변경되지 않는다.

    Block[{x}, x]x

    아래 예제에서 Module 내부와 외부의 x가 서로 다른 변수이므로 y이 값은 변경되지 않는다.

    y = x2;Module[{x = 2},

    Print[y]];y

    x2

    x2

    그러나 Block의 경우 x는 같은 변수명을 사용하므로 y의 값이 변경된다. Block에서 나오면서 y는 원래의 값으로 환원된다.

    y = x2;Block[{x = 2},

    Print[y]];y

    4x2

    10 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • With의경우 상수는 한 번 설정되며 With 내부에서 변경할 수 없다.

    x = 10;With[{x = x + 1}, x2]x

    121

    10

    Pure Functions

    Pure Functions (Mathematica Tutorial)

    Pure function은 함수명을 지정하지 않고 Select, Map, Nest, Fold 등 함수의 인수나 옵션의 값으로 사용할 수 있다.

    data = RandomInteger[{-10, 10}, 20]{-4, -9, 7, 3, -1, -8, -4, -7, -3, 6, 10, 1, 7, 3, 5, 5, -9, 1, 7, 0}Select[data, (# > 5) &]

    {7, 6, 10, 7, 7}Select[data, (# < -3 || # > 5) &]

    {-4, -9, 7, -8, -4, -7, 6, 10, 7, -9, 7}Map[#2 &, data]

    {16, 81, 49, 9, 1, 64, 16, 49, 9, 36, 100, 1, 49, 9, 25, 25, 81, 1, 49, 0}Nest[(# + 1) &, data, 3]

    {-1, -6, 10, 6, 2, -5, -1, -4, 0, 9, 13, 4, 10, 6, 8, 8, -6, 4, 10, 3}Fold 1Plus[##] &, x, data

    7 + 11 + 1-9+ 1

    5+ 15+ 1

    3+ 17+ 1

    1+ 110+ 1

    6+ 1-3+ 1-7+ 1-4+ 1-8+ 1-1+ 13+ 1

    7+ 1-9+ 1-4+x

    Presentation-Y. Chung (2015-08-22 Summer School).nb 11

  • 아래 예에서는 StreamPlot 함수의 RegionFunction option의 값으로 설정되었다.

    StreamPlot-x2 + 2 z2 + (x2 + z2)5/2, 3 x z, {z, -4, 4}, {x, -2, 2},AspectRatio → 12 , FrameLabel → {z, x}, RegionFunction → #12 + #22 > 1 &,Epilog → {Thickness[0.01], Circle[{0, 0}, 1]}

    -4 -2 0 2 4-2-1

    0

    1

    2

    z

    x

    Pure function에는 함수명을 정할 필요가 없으므로 일회성으로 사용되는 경우가 많다.

    #12 + #22 &[a, b]a2 + b2Function[{x, y}, x2 + y2][a, b]

    a2 + b2Pure function에 함수명을 지정하는 것도 가능하다.

    f = Function[{x, y}, x2 + y2];f[a, b]

    a2 + b2f =.

    Pure function의 사용 예제• data2는 random integer로 이루어진 5× 5 행렬이다.data2 = RandomInteger[{-10, 10}, {5, 5}]

    {{9, 7, 9, -6, -7}, {0, -1, -6, -5, 2},{7, 3, -7, -9, -8}, {-5, 2, 0, -5, 10}, {7, 2, 9, -1, -2}}Select[#, (# > 0) &] & /@ data2

    {{9, 7, 9}, {2}, {7, 3}, {2, 10}, {7, 2, 9}}

    12 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • Function[x, Select[x, (# > 0) &]] /@ data2{{9, 7, 9}, {2}, {7, 3}, {2, 10}, {7, 2, 9}}##3 & @@ {1, 2, 3, 4, 5}

    Sequence[3, 4, 5]{##3} & @@ {1, 2, 3, 4, 5}

    {3, 4, 5}f[##3] & @@ {1, 2, 3, 4, 5}

    f[3, 4, 5]{##3} & @@@ data2

    {{9, -6, -7}, {-6, -5, 2}, {-7, -9, -8}, {0, -5, 10}, {9, -1, -2}}Drop[#, 2] & /@ data2

    {{9, -6, -7}, {-6, -5, 2}, {-7, -9, -8}, {0, -5, 10}, {9, -1, -2}}##3 & @@@ data2

    {9, -6, -7, -6, -5, 2, -7, -9, -8, 0, -5, 10, 9, -1, -2}Apply[##3 &, data2, {1}]

    {9, -6, -7, -6, -5, 2, -7, -9, -8, 0, -5, 10, 9, -1, -2}

    패턴

    Patterns (Mathematica Guide)

    패턴의 사용 예제

    Cases의 default level 지정은 {1}이다.

    Cases4, 2.5, 1 + ⅈ, -2, 34 , 5, (-1)1/4, 3.0, π, 511 , ⅇ, _Rational 34 , 511 Cases4, 2.5, 1 + ⅈ, -2, 34 , 5, (-1)1/4, 3.0, π, 511 , ⅇ, _Integer?(# > 1 &)

    {4, 5}

    Presentation-Y. Chung (2015-08-22 Summer School).nb 13

  • Cases4, 2.5, 1 + ⅈ, -2, 34 , 5, (-1)1/4, 3.0, π, 511 , ⅇ, x_Integer /; (x > 1){4, 5}CasesSin[x], Sin[y]2, Cos[x], ⅇCos[x], 1 + Tan[x], (Sin Cos)[x]

    {Sin[x], Cos[x]}CasesSin[x], Sin[y]2, Cos[x], ⅇCos[x], 1 + Tan[x], (Sin Cos)[x], {0, ∞}

    {Sin[x], Cos[x], Cos[x]}MatchQ는 패턴이 일치하는지 확인한다.

    MatchQ[{1, 4, 5}, {__Integer}]True

    MatchQ[{}, {__Integer}]False

    MatchQ[{1, 4., 5}, {__Integer}]False

    MatchQ[{1, 4, 5}, {___Integer}]True

    MatchQ[{}, {___Integer}]True

    Select 함수는 매우 긴 식에서 원하는 부분만을 추출하는데 편리하다.

    Pi,NL ⩵ 4 χi,j,k,l Εj Εk ΕlSCMAF%, RA, At[2], Εj_ ⩵ 12 n=24 Εj[ωn] ⅇⅈ (ωn t-βn z) + Εj*[ωn] ⅇ-ⅈ (ωn t-βn z),SCEvalSum, At[2], Apply → {SCSimpExp, Expand},SCExpApply, {At[2], Collect[#, {z, t}, Simplify] &},ChangeSign → {-β2 - β3 + β4, -ω2 - ω3 + ω4}, , ,Select, {At[2], ! FreeQ[#, ω2 + ω3 - ω4] &}, RA → {At[1], Pi,NL ⩵ Pi[ω1]},Comment → "Collect only the terms with ω1=ω2+ω3-ω4",Collect, At[2], 12 ⅇ-ⅈ z (β2+β3-β4)+ⅈ t (ω2+ω3-ω4), 12 ⅇⅈ z (β2+β3-β4)-ⅈ t (ω2+ω3-ω4), Factor

    Pi,NL ⩵ 4 Εj Εk Εl χi,j,k,l

    14 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • Collect only the terms with ω1=ω2+ω3-ω4Pi[ω1] ⩵ 12 ⅇⅈ z (β2+β3-β4)-ⅈ t (ω2+ω3-ω4) χi,j,k,l Εk*[ω3] Εl*[ω2] Εj[ω4] +

    12 ⅇⅈ z (β2+β3-β4)-ⅈ t (ω2+ω3-ω4) χi,j,k,l Εk*[ω2] Εl*[ω3] Εj[ω4] +12 ⅇ-ⅈ z (β2+β3-β4)+ⅈ t (ω2+ω3-ω4) χi,j,k,l Εl*[ω4] Εj[ω3] Εk[ω2] +12 ⅇ-ⅈ z (β2+β3-β4)+ⅈ t (ω2+ω3-ω4) χi,j,k,l Εl*[ω4] Εj[ω2] Εk[ω3] +12 ⅇⅈ z (β2+β3-β4)-ⅈ t (ω2+ω3-ω4) χi,j,k,l Εj*[ω3] Εl*[ω2] Εk[ω4] +12 ⅇⅈ z (β2+β3-β4)-ⅈ t (ω2+ω3-ω4) χi,j,k,l Εj*[ω2] Εl*[ω3] Εk[ω4] +12 ⅇ-ⅈ z (β2+β3-β4)+ⅈ t (ω2+ω3-ω4) χi,j,k,l Εk*[ω4] Εj[ω3] Εl[ω2] +12 ⅇ-ⅈ z (β2+β3-β4)+ⅈ t (ω2+ω3-ω4) χi,j,k,l Εj*[ω4] Εk[ω3] Εl[ω2] +12 ⅇ-ⅈ z (β2+β3-β4)+ⅈ t (ω2+ω3-ω4) χi,j,k,l Εk*[ω4] Εj[ω2] Εl[ω3] +12 ⅇ-ⅈ z (β2+β3-β4)+ⅈ t (ω2+ω3-ω4) χi,j,k,l Εj*[ω4] Εk[ω2] Εl[ω3] +12 ⅇⅈ z (β2+β3-β4)-ⅈ t (ω2+ω3-ω4) χi,j,k,l Εj*[ω3] Εk*[ω2] Εl[ω4] +12 ⅇⅈ z (β2+β3-β4)-ⅈ t (ω2+ω3-ω4) χi,j,k,l Εj*[ω2] Εk*[ω3] Εl[ω4]

    Pi[ω1] ⩵ 12 ⅇ-ⅈ z (β2+β3-β4)+ⅈ t (ω2+ω3-ω4) χi,j,k,l (Εl*[ω4] Εj[ω3] Εk[ω2] + Εl*[ω4] Εj[ω2] Εk[ω3] +Εk*[ω4] Εj[ω3] Εl[ω2] + Εj*[ω4] Εk[ω3] Εl[ω2] + Εk*[ω4] Εj[ω2] Εl[ω3] + Εj*[ω4] Εk[ω2] Εl[ω3]) +12 ⅇⅈ z (β2+β3-β4)-ⅈ t (ω2+ω3-ω4) χi,j,k,l (Εk*[ω3] Εl*[ω2] Εj[ω4] + Εk*[ω2] Εl*[ω3] Εj[ω4] +Εj*[ω3] Εl*[ω2] Εk[ω4] + Εj*[ω2] Εl*[ω3] Εk[ω4] + Εj*[ω3] Εk*[ω2] Εl[ω4] + Εj*[ω2] Εk*[ω3] Εl[ω4])

    함수의 정의와 독립변수

    하나의 함수명으로 여러 가지 다른 정의를 할 수 있다. 이 때 변수들의 조건을 설정하여 충돌을 피하도록 하여야 한다.

    f[x_] := F[x]f[x_Integer] := G[x]f[x_?(# > 5 &)] := H[x]{f[1], f[10], f[10.0], f[a]}

    {G[1], G[10], H[10.], F[a]}Symbolic Computing 패키지 내에 정의된 SCMultColumns 함수의 예

    Presentation-Y. Chung (2015-08-22 Summer School).nb 15

  • ? SCMultColumns

    SCMultColumns[mat] multiplies all columns of the matrix mat.SCMultColumns[mat, mop] multiplies all columns of the matrix mat using the multiplication operator mop.SCMultColumns[mat, {i, j, ...}] multiplies the columns i, j, ... of the matrix mat and replaces the ith column with the result.SCMultColumns[mat, {i, j, ...}, mop] multiplies the columns i, j, ... of the

    matrix mat using the multiplication operator mop and replaces the ith column with the result.

    SCMultColumn[m_?MatrixQ, fact__, mult:MultOpsAlt..., nargv:(_Integer | {__Integer})..., opts___?OptionQ]SCMultColumn[m_?MatrixQ, nargv:{__Integer}..., mult:MultOpsAlt..., opt-s___?OptionQ]

    Remove[f]

    Functional Programming

    Functional Programming (Mathematica Guide)

    예제 : 데이터 다루기

    데이터를 생성한다.

    data = RandomReal[{-10, 10}, 100]{-6.2541, 9.92516, 3.6055, -9.79653, -5.36686, -3.70611, -3.80058, -5.30104, -9.30848,-5.69453, -8.92302, -7.84394, 7.0017, -8.89071, -6.49795, 4.73976, -9.67418,3.52384, -6.90599, 1.9326, 3.67471, 2.96993, 0.440846, 4.37379, 7.38759, 8.60218,-1.81238, -1.33307, 4.26668, -5.47444, -4.85972, -3.10039, 6.78935, -1.76425,6.3538, -1.87188, 4.27796, -5.38651, -4.71169, 6.01736, 5.19828, -9.77278,-1.11242, 0.871814, 7.54941, -6.62417, 2.08964, -8.88556, -4.56421, 0.921479,7.825, 5.71663, -7.69583, 5.01206, 1.66881, -1.59517, -0.754285, 9.00438, -1.32906,9.01465, -4.79204, -1.84418, 8.92173, 9.56447, 2.93224, -0.500099, 6.1942, 3.63957,-8.56149, 1.94167, 0.926791, -4.77889, -3.2055, 2.81796, -9.49371, 0.397163,-2.8277, 7.12561, -6.8535, -0.90975, 1.5682, -3.22558, -1.33468, -3.43715,-5.10417, 3.85029, 9.41088, 1.20242, -1.2869, -1.55911, -7.57064, -1.26514,0.637735, -5.91801, 2.88839, -5.38843, -2.93887, -2.70052, 3.81812, 5.97963}데이터의 수

    Length[data]100

    데이터를 모두 합하기

    16 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • Plus @@ data-41.5359양수만 선택

    Select[data, Positive]{9.92516, 3.6055, 7.0017, 4.73976, 3.52384, 1.9326, 3.67471, 2.96993, 0.440846, 4.37379,7.38759, 8.60218, 4.26668, 6.78935, 6.3538, 4.27796, 6.01736, 5.19828, 0.871814,7.54941, 2.08964, 0.921479, 7.825, 5.71663, 5.01206, 1.66881, 9.00438, 9.01465,8.92173, 9.56447, 2.93224, 6.1942, 3.63957, 1.94167, 0.926791, 2.81796, 0.397163,7.12561, 1.5682, 3.85029, 9.41088, 1.20242, 0.637735, 2.88839, 3.81812, 5.97963}위의 명령을 아래와 같이 Cases 함수를 사용해서 수행할 수 있다.

    Cases[data, _?Positive]{9.92516, 3.6055, 7.0017, 4.73976, 3.52384, 1.9326, 3.67471, 2.96993, 0.440846, 4.37379,7.38759, 8.60218, 4.26668, 6.78935, 6.3538, 4.27796, 6.01736, 5.19828, 0.871814,7.54941, 2.08964, 0.921479, 7.825, 5.71663, 5.01206, 1.66881, 9.00438, 9.01465,8.92173, 9.56447, 2.93224, 6.1942, 3.63957, 1.94167, 0.926791, 2.81796, 0.397163,7.12561, 1.5682, 3.85029, 9.41088, 1.20242, 0.637735, 2.88839, 3.81812, 5.97963}데이터를 두 개씩 모아서 각각을 합하기

    Partition[#, 2] &@dataPlus @@@ %

    {{-6.2541, 9.92516}, {3.6055, -9.79653}, {-5.36686, -3.70611},{-3.80058, -5.30104}, {-9.30848, -5.69453}, {-8.92302, -7.84394},{7.0017, -8.89071}, {-6.49795, 4.73976}, {-9.67418, 3.52384}, {-6.90599, 1.9326},{3.67471, 2.96993}, {0.440846, 4.37379}, {7.38759, 8.60218}, {-1.81238, -1.33307},{4.26668, -5.47444}, {-4.85972, -3.10039}, {6.78935, -1.76425}, {6.3538, -1.87188},{4.27796, -5.38651}, {-4.71169, 6.01736}, {5.19828, -9.77278}, {-1.11242, 0.871814},{7.54941, -6.62417}, {2.08964, -8.88556}, {-4.56421, 0.921479}, {7.825, 5.71663},{-7.69583, 5.01206}, {1.66881, -1.59517}, {-0.754285, 9.00438}, {-1.32906, 9.01465},{-4.79204, -1.84418}, {8.92173, 9.56447}, {2.93224, -0.500099}, {6.1942, 3.63957},{-8.56149, 1.94167}, {0.926791, -4.77889}, {-3.2055, 2.81796}, {-9.49371, 0.397163},{-2.8277, 7.12561}, {-6.8535, -0.90975}, {1.5682, -3.22558}, {-1.33468, -3.43715},{-5.10417, 3.85029}, {9.41088, 1.20242}, {-1.2869, -1.55911}, {-7.57064, -1.26514},{0.637735, -5.91801}, {2.88839, -5.38843}, {-2.93887, -2.70052}, {3.81812, 5.97963}}{3.67105, -6.19103, -9.07297, -9.10162, -15.003, -16.767, -1.88901, -1.75819, -6.15034,-4.9734, 6.64464, 4.81464, 15.9898, -3.14545, -1.20776, -7.96011, 5.0251, 4.48192,-1.10855, 1.30567, -4.5745, -0.240605, 0.925235, -6.79592, -3.64273, 13.5416,-2.68376, 0.0736349, 8.25009, 7.68559, -6.63622, 18.4862, 2.43215, 9.83376,-6.61982, -3.8521, -0.387534, -9.09654, 4.29791, -7.76325, -1.65738, -4.77183,-1.25387, 10.6133, -2.84601, -8.83578, -5.28027, -2.50004, -5.63939, 9.79775}

    Presentation-Y. Chung (2015-08-22 Summer School).nb 17

  • 위의 명령을 한 번에 수행

    Plus @@@ Partition[#, 2] &@data{3.67105, -6.19103, -9.07297, -9.10162, -15.003, -16.767, -1.88901, -1.75819, -6.15034,-4.9734, 6.64464, 4.81464, 15.9898, -3.14545, -1.20776, -7.96011, 5.0251, 4.48192,-1.10855, 1.30567, -4.5745, -0.240605, 0.925235, -6.79592, -3.64273, 13.5416,-2.68376, 0.0736349, 8.25009, 7.68559, -6.63622, 18.4862, 2.43215, 9.83376,-6.61982, -3.8521, -0.387534, -9.09654, 4.29791, -7.76325, -1.65738, -4.77183,-1.25387, 10.6133, -2.84601, -8.83578, -5.28027, -2.50004, -5.63939, 9.79775}

    Nest, NestList

    차분방정식 an+1 = (n+ 1) an (a0 = 1)의 해출력 f (x)가 다음에는 입력 x가 된다. n번째 (최초 입력은 n = 0) 입력 x는 (n+ 1, an)이고 출력은 (n+ 2, an+1)가 된다. an+1 = (n+ 1) an이므로 아래와 같이 a0, a1, …, a10을 구할 수 있다.

    Last /@ NestList[Function[x, {x[[1]] + 1, Times @@ x}], {1, 1}, 10]{1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800}또는

    Last /@ NestList[{#[[1]] + 1, Times @@ #} &, {1, 1}, 10]{1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800}예제 : 피보나치 수열

    피보나치 수열은 an = an-1 + an-2, a0 = 0, a1 = 1을 만족한다. For loop을 사용하여 a0, a1, …, a20을 구하면For[n = 1;list = {0, 1}, n < 20, n++, list = Append[list, list[[-2]] + list[[-1]]]]

    list

    {0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765}

    18 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • 아래와 같이 함수 f[n]을 정의해서 구하면

    f[n_Integer] := f[n] = f[n - 1] + f[n - 2];f[0] = 0;f[1] = 1;

    a20과 a100

    {f[20], f[100]}{6765, 354224848179261915075}NestList를 사용하여 구해보자. n번째 (최초 입력은 n = 0) 입력 x는 (an, an+1)이고 출력은 (an+1, an+2)가 된다. an+2 = an + an+1이므로 아래와 같이 a0, a1, …, a20을 구할 수 있다.First /@ NestList[Function[x, {x[[2]], Plus @@ x}], {0, 1}, 20]

    {0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765}Nest를 사용하면 마지막 수 a20가 출력된다.

    First@Nest[Function[x, {x[[2]], Plus @@ x}], {0, 1}, 20]6765

    함수 f와 변수 n을 제거한다.

    Remove[f, n]

    Procedural Programming

    Procedural Programming (Mathematica Guide)

    n! = n(n- 1) (n- 2)⋯2× 1의 계산함수 facp를 정의한다.

    facp[n_Integer?(# ≥ 0 &)] :=Module[{i, ret},If[n ⩵ 0,ret = 1,For[i = ret = n, i > 1, , ret *= --i]];

    Return[ret]];0!, 1!, 2!, …, 10!을 구하면

    Presentation-Y. Chung (2015-08-22 Summer School).nb 19

  • Table[facp[n], {n, 0, 10}]{1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800}facp 함수는 0 이상의 정수인 경우에 한해 계산한다.

    {facp[x], facp[-1], facp[1.5]}{facp[x], facp[-1], facp[1.5]}Remove[facp]

    Rule-Based Programming

    n! = n(n- 1) (n- 2)⋯2× 1의 계산Version 1

    함수 facr을 정의한다.

    facr[n_] := facr[n] = n facr[n - 1];facr[0] = 1;

    0!, 1!, 2!, …, 10!을 구하면Table[facr[n], {n, 0, 10}]

    {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800}위의 함수 정의는 변수 n에 제한이 없어 위험성이 있다.

    facr[x]$RecursionLimit::reclim2 : Recursion depth of 1024 exceeded during evaluation of -1021+x. $RecursionLimit::reclim2 : Recursion depth of 4096 exceeded during evaluation of -4088+x. Hold[facr[x] = x facr[x - 1]]facr[-1]

    $RecursionLimit::reclim2 : Recursion depth of 1024 exceeded during evaluation of -1023 facr[-1023-1]. $RecursionLimit::reclim2 : Recursion depth of 4096 exceeded during evaluation of -4090 facr[-4090-1]. Hold[facr[-1] = -facr[-1 - 1]]Remove[facr]

    Version 2

    변수에 제한을 주어 함수 facr을 재정의한다.

    20 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • facr[n_Integer?Positive] := facr[n] = n facr[n - 1];facr[0] = 1;

    0!, 1!, 2!, …, 10!을 구하면Table[facr[n], {n, 0, 10}]

    {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800}facr 함수는 0 이상의 정수인 경우에 한해 계산하며, 그렇지 않은 경우는 아무 작용을 하지 않는다.

    {facr[x], facr[-1]}{facr[x], facr[-1]}예제 : 선형 차분방정식 an+2 + 3 an+1 + 2 an = 0 (a0 = 1, a1 = 0)의 해{an+2 + 3 an+1 + 2 an ⩵ 0, a0 ⩵ 1, a1 ⩵ 1}

    Rule-based programming을 사용하여 해를 구한다.

    a[n_Integer?(# ≥ 2 &)] := -3 a[n - 1] - 2 a[n - 2];a[0] = 1; a[1] = 1;Table[a[n], {n, 0, 10}]

    {1, 1, -5, 13, -29, 61, -125, 253, -509, 1021, -2045}커널 함수 RSolve를 사용하여 일반해를 구한다.

    {an+2 + 3 an+1 + 2 an ⩵ 0, a0 ⩵ 1, a1 ⩵ 1}SCMAF[%, SCRSolve, {All, an, n},Table, {At[2], {n, 0, 10}}]

    {2 an + 3 a1+n + a2+n ⩵ 0, a0 ⩵ 1, a1 ⩵ 1}an ⩵ (-2)1+n + 3 (-1)nan ⩵ {1, 1, -5, 13, -29, 61, -125, 253, -509, 1021, -2045}Remove[a]예제 : 비선형 차분방정식 an+1 = 2 an(1- an) (a0 = 2)의 해{an+1 ⩵ 2 an (1 - an), a0 ⩵ 2}

    Rule-based programming을 사용하여 해를 구한다.

    Presentation-Y. Chung (2015-08-22 Summer School).nb 21

  • In[159]:= a[n_Integer?(# ≥ 1 &)] := 2 a[n - 1] (1 - a[n - 1]);a[0] = 2;

    In[161]:= Table[a[n], {n, 0, 6}]Out[161]= {2, -4, -40, -3280, -21523360, -926510094425920, -1716841910146256242328924544640}

    커널 함수 RSolve를 사용하여 일반해를 구한다.

    In[167]:= {an+1 ⩵ 2 an (1 - an), a0 ⩵ 2}SCMAF%, SCRSolve, {All, an, n, Apply → SCExpandExp},SCSepExps, At[2], RA → ⅇⅈ 2n π ⧴ (1 - 2 KroneckerDelta[n, 0]),Table, {At[2], {n, 0, 6}}

    Out[167]= {a1+n ⩵ 2 (1 - an) an, a0 ⩵ 2}an ⩵ 12 (1 - 32n (1 - 2 KroneckerDelta[0, n]))

    Out[168]= an ⩵ {2, -4, -40, -3280, -21523360,-926510094425920, -1716841910146256242328924544640}Remove[a]

    Rules & Patterns (Mathematica Guide)

    Rule (→)과 RuleDelayed (:>)Rule은 우변을 실행한 결과를 사용하여 규칙을 설정하고 RuleDelayed는 규칙을 적용할 때마다 우변을 실행한다.

    f(x + a)2, f(x + a)3 /. f[x_] → Expand[x](a + x)2, (a + x)3위의 경우 Expand[x]의 결과는 x이므로 f[x_]→x와 같다.f(x + a)2, f(x + a)3 /. f[x_] ⧴ Expand[x]

    {a2 + 2 a x + x2, a3 + 3 a2 x + 3 a x2 + x3}{f[1], f[-2], f[x]} /. f[x_Integer] → x2

    {1, 4, f[x]}{f[1], f[-2], f[x]} /. f[x_Integer?Positive] → x2

    {1, f[-2], f[x]}ReplaceAll (/.)

    22 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • a + b + c /. {a → A, b → B, c → C}A + B + Ca + b + c /. {a → A, b + c → BC}

    a + BCTreeForm[a + b + c]

    Plus

    a b c

    ReplaceRepeated (//.)

    a + b + c //. {a → A, A + b → AB}AB + ca + b + c //. {a + b + c → ABC, a → A, b → B, c → C}

    ABC

    Replace

    Replace[a + b + c, a + b + c → ABC]ABC

    Replace[a + b + c, {a → A, b + c → B}, {1}]A + b + c

    Presentation-Y. Chung (2015-08-22 Summer School).nb 23

  • Replace[a + b + c, {a → A, a_. + b + c → a + BC}, {0, ∞}]A + BC• ReplaceAll, ReplaceRepeated, Replace의 차이TreeForm[f[x] + f[y]]

    Plus

    f

    x

    f

    y

    ReplaceAll과 ReplaceRepeated는 expression 전체부터 시작하여 하위 레벨의 subpart로 대체를 진행한다.

    f[x] + f[y] /. {x → 1, f[x] → p}p + f[y]a + b + c /. {a + b + c → ABC, a → A, b → B, c → C}

    ABC

    a + b + c + d + e + f /. {a → A, b + c → BC}a + BC + d + e + fReplace는 levelspec이 지정된 경우 하위 레벨의 subpart부터 시작하여 상위 레벨로 대체를 진행한다.

    24 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • Replace[f[x] + f[y], {x → 1, f[x] → p}, {0, ∞}]f[1] + f[y]Replace[a + b + c, {a + b + c → ABC, a → A, b → B, c → C}]

    ABC

    Replace[a + b + c, {a + b + c → ABC, a → A, b → B, c → C}, {0, ∞}]A + B + CReplace[a + b + c, {a + b + c → ABC, a → A, b → B, c → C}, {0, ∞}]

    A + B + CReplace[a + b + c, {a + b + c → ABC, a → A, b + c → BC}, {0, ∞}]

    A + b + cReplace[a + b + c, {a + b + c → ABC, a → A, b + c + x_ → BC + x}, {0, ∞}]

    A + BCReplace[a + b + c + d + e + f, {a → A, b + c + x_. → BC + x}, {0, ∞}]

    A + BC + d + e + f• Vector product (A⨯B)의 전개ReplaceAll의 한 번 적용으로는 완전히 전개하지 못한다.

    ReplaceAll[a⨯(b⨯(c⨯(d⨯e))), a_⨯(b_⨯c_) → b a.c - c a.b]-c⨯(d⨯e) a.b + b a.c⨯(d⨯e)ReplaceRepeated를 적용하여 vector product는 전개하였으나 dot product를 추가적으로 전개할 필요가 있다.

    ReplaceRepeated[a⨯(b⨯(c⨯(d⨯e))), a_⨯(b_⨯c_) → b a.c - c a.b]b a.(-e c.d + d c.e) - (-e c.d + d c.e) a.ba.(-e c.d + d c.e)를 전개하는 규칙을 추가한다.ReplaceRepeated[a⨯(b⨯(c⨯(d⨯e))),{a_⨯(b_⨯c_) → b a.c - c a.b, a_ .b_Plus ⧴ (a.# & /@ b)}]

    b (a.(-e c.d) + a.(d c.e)) - (-e c.d + d c.e) a.ba.(-e c.d)와 a.(d c.e)를 전개하는 규칙을 추가하고 마지막에 전체식을 Expand를 사용하여 전개한다.

    Presentation-Y. Chung (2015-08-22 Summer School).nb 25

  • ReplaceRepeated[a⨯(b⨯(c⨯(d⨯e))), {a_⨯(b_⨯c_) → b a.c - c a.b,a_ .b_Plus ⧴ (a.# & /@ b), a_ .(Optional[b_?NumericQ, 1] c_ d_Dot) → b a.c d}]

    Expand[%]-(-e c.d + d c.e) a.b + b (-a.e c.d + a.d c.e)e a.b c.d - b a.e c.d - d a.b c.e + b a.d c.e규칙은 순서에 따라 적용되므로 규칙의 집합을 만들 때 앞에 위치한 규칙이 뒤에 위치한 규칙을 가리지 않도록 유의할 필요가 있다.• 위와 같이 규칙을 매번 작성하기는 매우 번거로우므로 관계된 모든 규칙을 내장하고 있는 함수를 만들어 호출하여 사용하면 편리하다.

    SCVecExpand[a⨯(b⨯(c⨯(d⨯e))), Vectors → {a, b, c, d, e}]e a.b c.d - b a.e c.d - d a.b c.e + b a.d c.eSCVecExpandn⨯n⨯p⨯n⨯n⨯n⨯p% /. n.n → 1 // Simplify

    -n n.n n.p2 + n n.n2 p.p-n.p2 + p.p nSCVecExpand∇ ⨯A ∇.f B, A, B, f

    ∇B.∇f⨯A + ∇∇f.B⨯A + f ∇∇.B⨯A + ∇f.B ∇ ⨯A + ∇f.A ∇ ⨯B + ∇f⨯A ∇.B + f ∇ ⨯A ∇.B - ∇ ⨯B.A ∇f• SCStirlingSeries 함수는 factorial 함수이 Stirling 근사식을 내장하고 있다.SCStirlingSeries[n!, 4]

    ⅇ-n n 12 +n 2 π 1 - 13951840 n3

    + 1288 n2

    + 112 nBinomial 분포로부터 Poisson 분포를 구해보자. Binomial 전개식은

    SCAFE(p + q)N, SCBinomialExpand, {All, n, Assumptions → N ∈ Integers && N ≥ 0}(p + q)N ⩵

    n=0N pn q-n+N N!

    n! (-n + N)!따라서 binomial 확률 분포는 아래와 같고 n ≪ N을 가정하고 N !과 (N - n)!을 근사하면

    26 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • Pn ⩵ pn q-n+N N!n! (-n + N)!SCMAF[%, RA, {At[2], q ⩵ 1 - p},SCStirlingSeries, (N + _.)!, Head → Tilde]

    Pn ⩵ pn q-n+N N!n! (-n + N)!Pn ⩵ (1 - p)-n+N pn N!n! (-n + N)!Pn ~ ⅇ-n N 12 +N (-n + N)- 12 +n-N (1 - p)-n+N pnn!평균값 λ는 아래와 같이 정의한다.λ ⩵ N p위 정의를 이용하여 p를 λ로 대체하면 Poisson 확률 분포를 얻는다 (λ ≪ N).Pn ~ ⅇ-n N 12 +N (-n + N)- 12 +n-N (1 - p)-n+N pnn!SCMAF%, SCEliminate, {At[2], λ ⩵ N p, p},SCFactor, {-n + N, N}, Target → (-n + N)- 12 +n-N, Apply → {At[2], PowerExpand},RA, At[2], 1 + a_N b_ ⩵ ⅇ a bN , Apply → SCExpandExp, RA → 1N ⩵ 0

    Pn ~ ⅇ-n N 12 +N (-n + N)- 12 +n-N (1 - p)-n+N pnn!Pn ~ ⅇ-n λnn! 1 - nN -

    12 +n-N 1 - λN -n+N

    Pn ~ ⅇ-λ λnn!Pn의 합은 1.

    SCARAn=0∞Pn, Pn ~ ⅇ-λ λnn! , Apply → SCEvalSum

    n=0∞Pn ⩵ 1

    λ값의 따른 Poisson 확률 분포의 변화. λ가 커지면서 Gaussian 분포에 접근함을 알 수 있다.

    Presentation-Y. Chung (2015-08-22 Summer School).nb 27

  • ManipulateDiscretePlot ⅇ-λ λnn! , {n, 0, 40}, AxesLabel → {n, Pn}, PlotRange → {0, 0.2}, {λ, 4, 20}

    λ

    0 10 20 30 40n

    0.05

    0.10

    0.15

    0.20Pn

    • Harmonic oscillator의 n번째 energy eigenstate를 n〉이라 하고 a와 a†가 annihilation opera-tior, creation operator이면 아래 관계식이 성립한다.

    a n〉 = n n- 1a† n = n+ 1 n+ 1위 관계식을 반복적으로 적용하여 여러가지 물리량을 계산할 수 있다. 예를 들어

    SCAFEm a†2 · a2 n, SCBraKetToMult, All, SCOpExpand → {a, Power → False}SCMAF%, RR, At[2], a · c_. n_ ⩵ c n n - 1, a† · c_. n_ ⩵ c n + 1 n + 1,Apply → SCBraKetSimp,RA, At[2], m n ⩵ δm,n

    m a†2 · a2 n ⩵ m · a† · a† · a · a · nm a†2 · a2 n ⩵ (-1 + n) n m nm a†2 · a2 n ⩵ (-1 + n) n δm,nPerturbation energy V ′(x) = λ x3 + μ x4일 때 n번째 eigenstate의 에너지 변화량은

    28 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • ΔE ⩵ n V′[x] nSCMAF%, RA, {At[2], V′[x] ⩵ λ x3 + μ x4}, Apply → SCBraKetToMult, ,RA, At[2], x ⩵ 1

    2ℏm ω (a + a†),

    SCOpExpand, {At[2], a, Power → False},RR, At[2], a · c_. n_ ⩵ c n n - 1, a† · c_. n_ ⩵ c n + 1 n + 1,Apply → SCBraKetExpand,RA, At[2], m_ n_ ⧴ If[m === n, 1, 0], Apply → Simplify

    ΔE ⩵ n V′[x] nΔE ⩵ n · (x3 λ + x4 μ) · nΔE ⩵ -3 + n -2 + n -1 + n n μ ℏ2 n -4 + n

    4 m2 ω2 +1

    2 2ℏm ω 3/2 -2 + n -1 + n n λ n -3 + n - -1 + n n μ ℏ2 n -2 + n2 m2 ω2 +

    -1 + n n3/2 μ ℏ2 n -2 + nm2 ω2 + 32 2

    ℏm ω 3/2 n3/2 λ n -1 + n + 3 μ ℏ2 n n4 m2 ω2 + 3 n μ ℏ2 n n2 m2 ω2 +

    3 n2 μ ℏ2 n n2 m2 ω2 + 32 2

    ℏm ω 3/2 1 + n λ n 1 + n + 32 2

    ℏm ω 3/2 n 1 + n λ n 1 + n +

    3 1 + n 2 + n μ ℏ2 n 2 + n2 m2 ω2 + n 1 + n 2 + n μ ℏ2 n 2 + nm2 ω2 +

    12 2

    ℏm ω 3/2 1 + n 2 + n 3 + n λ n 3 + n + 1 + n 2 + n 3 + n 4 + n μ ℏ2 n 4 + n4 m2 ω2

    ΔE ⩵ 3 (1 + 2 n + 2 n2) μ ℏ24 m2 ω2

    Notations

    Formatted Output (Mathematica Tutorial)

    Notation, Symbolize, and InfixNotation (Mathematica Tutorial)

    Low-Level Input and Output Rules (Mathematica Tutorial)

    Example

    Tensor product 함수 tProd의 정의

    tProd[x_?ArrayQ, y_?ArrayQ] := Outer[Times, x, y]; a

    b · ( c d ) = a c a d

    b c b d

    Presentation-Y. Chung (2015-08-22 Summer School).nb 29

  • tProd[{a, b}, {c, d}] // MatrixForm a c a db c b d 조건에 따라 변수 x와 y는 array여야 한다.

    tProd[x, y]tProd[x, y]MakeBoxes과 MakeExpression 함수를 이용하여 low-level 출력과 입력을 정의한다.

    tProd /: MakeBoxes[tProd[x_, y_], form_] :=RowBox[{MakeBoxes[x, form], "⊗", MakeBoxes[y, form]}];

    MakeExpression[RowBox[{x_, "⊗", y_}], form_] :=MakeExpression[RowBox[{"tProd", "[", x, ",", y, "]"}], form];

    출력

    tProd[x, y]x ⊗ y입력

    x ⊗ y // FullFormtProd[x, y]• 아래 출력에서는 y+ z에 괄호 ( )가 표시되지 않으며, MakeBoxes를 이용하여 출력을 정의할 때 좀더 세밀한 코딩이 필요함을 알 수 있다.

    tProd[x, y + z]x ⊗ y + z위 출력을 복사하여 다시 출력하면 y와 z가 분리된다.

    x ⊗ y + zz + x ⊗ yCircleTimes의출력은 tProd와 동일한데 괄호 ( )가 표시된다.

    CircleTimes[x, y + z]x ⊗ (y + z)하지만 위 출력을 복사하여 다시 출력하면 tProd로 변환된다.

    x ⊗ (y + z)x ⊗ y + z

    30 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • 위와 같은 모호함은 TagBox를 사용하여 해결할 수 있다.

    {z*, z*} // FullFormList[SuperStar[z], Conjugate[z]]위 예에서 SuperStar와 Conjugate는 같은 표시를 사용하지만 (Conjugate는 Tooltip이 표시됨) 서로 다르게 해석된다.• Subscript의 출력Symbolic Computing 패키지 로딩 전

    Subscript[x + y + z, x ⩵ 0]x + y + zx⩵0Symbolic Computing 패키지 로딩 후

    Subscript[x + y + z, x ⩵ 0](x + y + z)x⩵0• ⊗를 이용한 tProd의 계산{a, b} ⊗ {c, d} // MatrixForm

    a c a db c b d {1, 0, 0} ⊗ {0, 1, 0} // MatrixForm0 1 00 0 00 0 0• tProd의 정의와 output과 input의 코드를 제거한다.Remove[tProd]MakeExpression[RowBox[{x_, "⊗", y_}], form_] =.

    • ⊗를 tProd 함수로 정의하지 않고 규칙을 사용{1, 0, 0} ⊗ {0, 1, 0} /. x_ ⊗ y_ ⧴ Outer[Times, x, y]

    {{0, 1, 0}, {0, 0, 0}, {0, 0, 0}}혹은 규칙을 내장하고 있는 함수 SCEvalMult를 사용

    SCEvalMult[{1, 0, 0} ⊗ {0, 1, 0}]{{0, 1, 0}, {0, 0, 0}, {0, 0, 0}}

    Symbolic Computing 패키지

    Presentation-Y. Chung (2015-08-22 Summer School).nb 31

  • Symbolic Computing 패키지는 기호계산을 수행할 수 있는 상용 소프트웨어인 Mathemat-ica의 기능을 보완하는 Add-On 패키지로 전통적 표기법에 따른 미분, 적분, 벡터 연산자, 브라켓 등 수식의 입출력을 지원하고 다양한 수식을 다룰 수 있는 800여 개에 이르는 함수를 포함하고 있으며 Mathematica에서 제공하는 다른 함수들과 연동하여 사용할 수 있다.

    목표

    수식 처리를 위한 지필 계산을 완전히 대체하여 소프트웨어로 계산을 수행

    패키지 홈페이지

    http://symbcomp.gist.ac.kr

    패키지에 관한 간단한 설명과 설치 방법이 게시되어 있다.

    설치 (Mathematica 버전 9 이상)

    홈페이지에 접속하기 위해 인터넷 연결이 필요.Mathematica 버전 9.0 이상의 경우, 아래 명령을 Shift-Enter를 사용하여 실행한다.

    ToExpression[URLFetch["http://symbcomp.gist.ac.kr/downloads/InstallSymbCompPersonal.m"]];

    설치에 관한 보다 상세한 내용은 InstallSymbCompPersonal.nb 노트북 파일에서 찾아볼 수 있다.

    NotebookOpen["http://symbcomp.gist.ac.kr/downloads/InstallSymbCompPersonal.nb"];패키지 로딩

    • Symbolic Computing 패키지를 로드하고 몇 가지 경고 메시지를 끈다.

  • 저작권

    이 패키지의 저작권은 광주과학기술원 (GIST) 소유이다.

    관련 사이트들

    http://symbcomp.gist.ac.kr (Download Site at GIST)http://www.wolfram.com (Wolfram Research Inc. Homepage)http://cafe.naver.com/mugkr (Mathematica User Group of Korea)

    예제

    • 다항식에서 인수를 추출하기a x+ y → ax+ y

    a

    SCFactor[a x + y, a]a x + ya • 분자와 분모를 인수로 나누기a x+yc x+z → a x+ ya c x+ z

    c

    SCDivFrac a x + yc x + z , a, ca x + ya c x + zc • 적분을 합치기∫ f ⅆx+ ∫ ∫ g ⅆy ⅆx → ∫ f + ∫ g ⅆy ⅆxSCMergeInts f ⅆx + g ⅆy ⅆx

    f + g ⅆy ⅆx• 미분의 변수 변환∂ f∂x → ∂ f∂η ∂η∂x + ∂ f∂ξ ∂ξ∂xSCTransDeriv ∂3 f∂x3 , TransVar → {x, {ξ, η}} // Expand∂3 f∂η3 ∂η∂x 3 + 3 ∂2 f∂η2 ∂η∂x ∂2η∂x2 + ∂f∂η ∂3η∂x3 + ∂3 f∂ξ3 ∂ξ∂x 3 + 3 ∂2 f∂ξ2 ∂ξ∂x ∂2ξ∂x2 + ∂f∂ξ ∂3ξ∂x3 +3 ∂2η∂x2 ∂ξ∂x ∂2 f∂ξ ∂η + 3 ∂η∂x ∂2ξ∂x2 ∂2 f∂ξ ∂η + 3 ∂η∂x 2 ∂ξ∂x ∂3 f∂ξ ∂η2 + 3 ∂η∂x ∂ξ∂x 2 ∂3 f∂ξ2 ∂η• 벡터식을 전개 (A, B와 f 는 함수)

    Presentation-Y. Chung (2015-08-22 Summer School).nb 33

  • ∇ ⨯(A ∇ · ( f B)) → (∇B ·∇ f )⨯A+ (∇∇ f ·B)⨯A+ f ∇ (∇ ·B)⨯A+∇ f ·B ∇ ⨯A+∇ f ·A ∇ ⨯B+∇ f ⨯A ∇ ·B+ f ∇ ⨯A ∇ ·B-∇ ⨯B ·A ∇ fSCVecExpand∇ ⨯A ∇.f B, A, B, f

    ∇B.∇f⨯A + ∇∇f.B⨯A + f ∇∇.B⨯A + ∇f.B ∇ ⨯A + ∇f.A ∇ ⨯B + ∇f⨯A ∇.B + f ∇ ⨯A ∇.B - ∇ ⨯B.A ∇f확인: A = x2, y z, 0, B = {0, ⅇx, z}, f = sin xSCEvalVecOp∇ ⨯A ∇.f B, ∇B.∇f⨯A + ∇∇f.B⨯A +

    f ∇∇.B⨯A + ∇f.B ∇ ⨯A + ∇f.A ∇ ⨯B + ∇f⨯A ∇.B + f ∇ ⨯A ∇.B - ∇ ⨯B.A ∇f,A ⩵ {x2, y z, 0}, B ⩵ {0, ⅇx, z}, f ⩵ Sin[x], {x, y, z}, Apply → Simplify{{-y Sin[x], 0, y z Cos[x]}, {-y Sin[x], 0, y z Cos[x]}}• SCMAF 함수를 사용하여 여러 가지 명령을 단계적으로 실행하고 SCMAF Viewer 팔레트를 사용하여 단계별 실행 결과를 확인∫-∞∞ 1a2+x2 ⅆx = πa-∞∞ 1a2 + x2 ⅆxSCMAF[%, SCTransInt, {All, TransVar → {x, t, x ⩵ a Tan[t]}},Simplify, All, Apply → PowerExpand,SCEvalInt, All,Trace → True]

    -∞∞ 1a2 + x2 ⅆx- π2 1a2 a

    π2

    1a2 a a Sec[t]2

    a2 + a2 Tan[t]2 ⅆt- π2

    π2 1a ⅆtπ

    a

    지필 계산을 소프트웨어 계산으로 대체한 예제

    • 금속 실린더 (반지름 b)와 중심에서 R ( > b)의 거리에 선 전하 τ가 있다. 이미지 전하(-τ)는 실리더 중심에서 b2 R의 거리에 있다.

    34 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • 지필 계산(R, 0)에 위치한 선 전하와 실리더 표면의 유도 전하에 의한 전기 포텐셜

    이미지 전하(-τ)는 b2 R, 0에 위치하고 있으며 실린더 표면에 유도되는 표면 전하 밀도 σ는 아래와 같다.

    Presentation-Y. Chung (2015-08-22 Summer School).nb 35

  • 심볼릭 계산(R, 0)에 위치한 선 전하와 실리더 표면의 유도 전하에 의한 전기 포텐셜ϕ ⩵ -τ Log ρ2 + R2 - 2 ρ R Cos[θ]ρ2 + b2R 2 - 2 ρ b2R Cos[θ] 이미지 전하(-τ)는 b2 R, 0에 위치하고 있으며 실린더에 아주 멀리 떨어진 곳에서(ρ ≫ R) 전기 포텐설의 근사식은 아래와 같다.ϕ ⩵ -τ Log ρ2 + R2 - 2 ρ R Cos[θ]ρ2 + b2R 2 - 2 ρ b2R Cos[θ] SCMAF%, SCTaylorExpand, At[2], 1ρ , Variables → ρ,Apply → Simplify, SCDivNum → -b2, Head → TildeTilde

    ϕ ⩵ -τ Log R2 + ρ2 - 2 R ρ Cos[θ]b4R2 + ρ2 - 2 b2 ρ Cos[θ]R

    ϕ ≈ - 2 b2 τ Cos[θ]R ρ 1 - R2b2실린더 표면에 유도되는 표면 전하 밀도 σ는 아래와 같다.

    36 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • σ ⩵ - 14 π ∂ϕ∂ρ ρ⩵bSCMAF%, RA, At[2], ϕ ⩵ -τ Log ρ2 + R2 - 2 ρ R Cos[θ]ρ2 + b2R 2 - 2 ρ b2R Cos[θ] ,Apply → {Simplify, SCEvalEqSub, SCEvalDeriv},SCDivFrac, {At[2], b2}, ChangeSign → 1 - R2b2

    σ ⩵ - 14 π ∂ϕ∂ρ ρ⩵bσ ⩵ (b2 - R2) τ

    2 b π (b2 + R2 - 2 b R Cos[θ])σ ⩵ - τ -1 + R2b2

    2 b π 1 + R2b2 - 2 R Cos[θ]b R / b를 파라메터로 σ를 θ의 함수로 그려본다.σ ⩵ τ 1 - R2b2

    2 b π 1 + R2b2 - 2 R Cos[θ]b SCMAF%, SCDivEq, All, τ2 b π ,Plot, At[2], {θ, -π, π}, AxesLabel → θ, " 2 b π στ ", PlotRange → {-3, 0},Ticks → π2 Range[-4, 4], Automatic, HoldForm → True, Take → Last, , ,

    Manipulate, All, Rb , 2, " Rb ", 1.0001, 10, ReplVar → Rb σ ⩵ τ 1 - R2b2

    2 b π 1 + R2b2 - 2 R Cos[θ]b Rb

    -π -π2

    π2

    π θ

    -3.0-2.5-2.0-1.5-1.0-0.5

    2 bπ στ

    Presentation-Y. Chung (2015-08-22 Summer School).nb 37

  • 전체 표면 유도 전하는 이미지 전하 -τ와 같다.τind ⩵ 02 πσ b ⅆθSCMAF%, RA, At[2], σ ⩵ τ 1 - R2b2

    2 b π 1 + R2b2 - 2 R Cos[θ]b , Apply → SCFactorInt,SCEvalInt, At[2],SCChangeSign, {At[2], b - R}, Apply → {Simplify, PowerExpand}

    τind ⩵ 0

    2 πb σ ⅆθ

    τind ⩵ (b + R)2(b - R)2 b2 τ(b + R)2 1 - R2b2τind ⩵ -τ전하의 위치(R)에 따른 전기 포텐셜의 contour plot

    38 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • ϕ ⩵ -τ Log ρ2 + R2 - 2 ρ R Cos[θ]ρ2 + b2R 2 - 2 ρ b2R Cos[θ] SCMAF%, SCTransCoords, {At[2], "Polar" → "Cartesian", {ρ, θ} → {x, y}},

    Together, 1 + _, , ,PowerExpand, x

    2 + y2x2 , RA → {At[2], {b ⩵ 1, τ ⩵ 1}};

    ManipulateWith{R = Max[p[[1]], 1]},ContourPlot%[[2]], {x, -2, 6}, {y, -2, 2},ContourShading → False, FrameLabel → {x, y}, RegionFunction → #12 + #22 > 1 &,AspectRatio → 12 , Epilog → {Thickness[0.01], Circle[{0, 0}],

    PointSize[0.03], Red, Point[{R, 0}], Blue, Point[{1 / R, 0}]}, {{p, {2, 0}}, Locator}ϕ ⩵ -τ Log R2 + ρ2 - 2 R ρ Cos[θ]

    b4R2 + ρ2 - 2 b2 ρ Cos[θ]R

    -2 0 2 4 6-2-1

    0

    1

    2

    x

    y

    전하의 위치(R)에 따른 전기장의 field plot

    Presentation-Y. Chung (2015-08-22 Summer School).nb 39

  • Ε ⩵ -∇ϕSCMAF%, SCEvalVecOp, At[2], ϕ ⩵ -Log R2 - 2 R x + x2 + y21

    R2 - 2 xR + x2 + y2 , {x, y}, Apply → Simplify;ManipulateWith{R = Max[p[[1]], 1]},StreamPlot%[[2]], {x, -2, 6}, {y, -2, 2}, FrameLabel → {x, y},RegionFunction → #12 + #22 > 1 &, AspectRatio → 12 , Epilog → {Thickness[0.01],

    Circle[{0, 0}], PointSize[0.03], Red, Point[{R, 0}], Blue, Point[{1 / R, 0}]}, {{p, {2, 0}}, Locator}Ε ⩵ -∇ϕ

    -2 0 2 4 6-2-1

    0

    1

    2

    x

    y

    Compile 함수

    Compile

    함수 f를 compiled function으로 정의한다.

    f = Compile[x, x^2];변수 x는 Real여야 한다.

    f[a]CompiledFunction::cfsa : Argument a at position 1 should be a machine-size real number. a2

    x에 Integer를 입력하면 Real로 변환된다.

    40 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • f[2]4.

    변수에 Integer 조건을 추가

    g = Compile[{{x, _Integer}}, x2];변수에 정수로 변환되지 않는 값을 입력하면 경고 메시지가 뜬다.

    {g[2], g[2.0], g[2.5], g[a]}CompiledFunction::cfsa : Argument 2.5` at position 1 should be a machine-size integer. CompiledFunction::cfsa : Argument a at position 1 should be a machine-size integer. {4, 4, 6.25, a2}Plot[f[x], {x, -2, 2}]

    -2 -1 1 2

    1

    2

    3

    4

    • BeamProp 패키지를 로드한다.

  • {zl, tl, fl} = FFTBPMPulseⅇ-τ2, {ξ, 0, 1, 11}, {τ, -5, 5, 256};ListPlot3DAbs[fl], PlotRange → All,DataRange → {{-5, 5}, {0, 1}}, AxesLabel → t - β1 zT0 , zLD , U[z, t]

    ManipulateListPlotTransposetl, Abs[fl[[n]]]2, AxesLabel → {τ},Joined → True, PlotRange → {0, 1}, {{n, 1, ξ}, 1, 11, 1}, SaveDefinitions → True

    ξ

    -4 -2 0 2 4 τ0.2

    0.4

    0.6

    0.8

    1.0

    – Cubic dispersion만 있는 경우

    42 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • {zl3, tl3, fl3} =FFTBPMPulseⅇ-τ2, {ξ, 0, 2, 11}, {τ, -10, 10, 256}, DispersionLength → ∞;

    ListPlot3DAbs[fl3], PlotRange → All,DataRange → {{-10, 10}, {0, 2}}, AxesLabel → t - β1 zT0 , zLD,3 , U[z, t]

    ManipulateListPlotTransposetl3, Abs[fl3[[n]]]2, AxesLabel → {τ},Joined → True, PlotRange → {0, 1}, {{n, 1, ξ}, 1, 11, 1}, SaveDefinitions → True

    ξ

    -10 -5 0 5 10 τ0.2

    0.4

    0.6

    0.8

    1.0

    광섬유 격자

    – Ref.: Yariv & Yeh, Optical Waves in Crystals, Chapter 6

    Presentation-Y. Chung (2015-08-22 Summer School).nb 43

  • Long-Period Fiber Fiber Bragg Grating모드 결합 이론

    광섬유 격자의 주기가 Λ일 때 모드 결합 이론에 따르면 두 모드의 진폭 A1, A2는 다음 식을 만족한다.

    ⅆA1ⅆz ⩵ - ⅈ ⅇⅈ z Δβ β1 C1,2m A2β1 , ⅆA2ⅆz ⩵ - ⅈ ⅇ-ⅈ z Δβ β2 C2,1-m A1β2 여기서 β1, β2는 각 모드의 전파 상수, κ = C12m = C21-m*는 결합 상수, Δβ는 detuning parameter이다.

    Δβ ⩵ - 2 m πΛ + β1 - β2, κ ⩵ C1,2m ⩵ C2,1-m *Co-directional Coupling (Long-Period Fiber Grating)• 장주기 격자의 경우 두 모드의 진행 방향은 같으므로 β1β1 = β2β2 = 1. 따라서 모드 결합 방정식은 아래와 같다.

    ⅆA1ⅆz ⩵ - ⅈ ⅇⅈ z Δβ β1 C1,2m A2β1 , ⅆA2ⅆz ⩵ - ⅈ ⅇ-ⅈ z Δβ β2 C2,1-m A1β2 SCMAF%, RR, All, β1β1 ⩵ 1, β2β2 ⩵ 1, C1,2m ⩵ κ, C2,1-m ⩵ κ*

    ⅆA1ⅆz ⩵ - ⅈ ⅇⅈ z Δβ β1 C1,2m A2β1 , ⅆA2ⅆz ⩵ - ⅈ ⅇ-ⅈ z Δβ β2 C2,1-m A1β2 ⅆA1ⅆz ⩵ -ⅈ ⅇⅈ z Δβ κ A2, ⅆA2ⅆz ⩵ -ⅈ ⅇ-ⅈ z Δβ κ* A1이 방정식의 해는 아래와 같다.

    44 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • ⅆA1ⅆz ⩵ -ⅈ ⅇⅈ z Δβ κ A2, ⅆA2ⅆz ⩵ -ⅈ ⅇ-ⅈ z Δβ κ* A1SCMAF%, SCDSolve, {All, {A1[0] ⩵ A1,0, A2[0] ⩵ 0}, {A1[z], A2[z]}, z},RA → A1,0 ⩵ A1[0], SCToAbs → True,SCFactorI, -Δβ2 - 4 κ2 ,SCFactor, Δβ2 + 4 κ2, 4,RA, All, Δβ24 + κ2 ⩵ s, Apply → Simplify,SCExpToTrigHalf, All,

    Expand, (2 s - Δβ) (2 s + Δβ), RA → s ⩵ Δβ24 + κ2 , Apply → Expand,Simplify, At[_, 2], Apply → {SCSimpExp, SCExpToTrigHalf},SCDivNum, {At[1, 2], 2 s}

    ⅆA1ⅆz ⩵ -ⅈ ⅇⅈ z Δβ κ A2, ⅆA2ⅆz ⩵ -ⅈ ⅇ-ⅈ z Δβ κ* A1A1[z] ⩵ ⅇⅈ z Δβ2 (2 s Cos[s z] - ⅈ Δβ Sin[s z]) A1[0]2 s , A2[z] ⩵ - ⅈ ⅇ

    - 12 ⅈ z Δβ κ2 Sin[s z] A1[0]s κ

    A1[z] ⩵ ⅇⅈ z Δβ2 A1[0] Cos[s z] - ⅈ Δβ Sin[s z]2 s , A2[z] ⩵ - ⅈ ⅇ- 12 ⅈ z Δβ κ2 Sin[s z] A1[0]

    s κ 여기서

    s ⩵ Δβ24 + κ2위치 z에서 두 모드의 파워는

    Presentation-Y. Chung (2015-08-22 Summer School).nb 45

  • P1P0 ⩵ A1[z]A1[0] 2, P2P0 ⩵ A2[z]A1[0] 2SCMAF%, RA, All,

    A1[z] ⩵ ⅇⅈ z Δβ2 A1[0] Cos[s z] - ⅈ Δβ Sin[s z]2 s , A2[z] ⩵ - ⅈ ⅇ-12 ⅈ z Δβ κ2 Sin[s z] A1[0]

    s κ ,SCComplexExpand → κ, SCToAbs → True,RA, All, s ⩵ Δβ24 + κ2 ,SCFactor, Δβ24 + κ2, κ2, ,SCEqsListForm, All,Plot, At[2], Δβκ , -10, 10, PlotRange → {0, 1}, AxesLabel → " Δβκ ",Tooltip → P1P0 , P2P0 , HoldForm → True, , ,Manipulate, At[2], z κπ , 0, " κ zπ ", 0, 2, Appearance → "Open",ReplVar → z κπ , Δβκ , Take → Last

    P1P0 ⩵ A1[z]A1[0]2, P2P0

    ⩵ A2[z]A1[0]2

    P1P0 ⩵ Cosz κ 1 + Δβ2

    4 κ2 2 +Δβ2 Sinz κ 1 + Δβ24 κ2 2

    4 κ2 1 + Δβ24 κ2 ,P2P0

    ⩵ Sinz κ 1 +Δβ2

    4 κ2 21 + Δβ24 κ2

    κ zπ1.702

    -10 -5 0 5 10 Δβκ

    0.2

    0.4

    0.6

    0.8

    1.0

    Contra-directional Coupling (Fiber Bragg Grating)• 단주기 브라그 격자의 경우 두 모드의 진행 방향은 반대미므로 β1β1 = - β2β2 = 1. 따라서

    46 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • 모드 결합 방정식은 아래와 같다.

    ⅆA1ⅆz ⩵ - ⅈ ⅇⅈ z Δβ β1 C1,2m A2β1 , ⅆA2ⅆz ⩵ - ⅈ ⅇ-ⅈ z Δβ β2 C2,1-m A1β2 SCMAF%, RR, All, β1β1 ⩵ 1, β2β2 ⩵ -1, C1,2m ⩵ κ, C2,1-m ⩵ κ*

    ⅆA1ⅆz ⩵ - ⅈ ⅇⅈ z Δβ β1 C1,2m A2β1 , ⅆA2ⅆz ⩵ - ⅈ ⅇ-ⅈ z Δβ β2 C2,1-m A1β2 ⅆA1ⅆz ⩵ -ⅈ ⅇⅈ z Δβ κ A2, ⅆA2ⅆz ⩵ ⅈ ⅇ-ⅈ z Δβ κ* A1이 방정식의 해는 아래와 같다.

    ⅆA1ⅆz ⩵ -ⅈ ⅇⅈ z Δβ κ A2, ⅆA2ⅆz ⩵ ⅈ ⅇ-ⅈ z Δβ κ* A1SCMAF%, SCDSolve, {All, {A1[0] ⩵ A1,0, A2[L] ⩵ 0}, {A1[z], A2[z]}, z},SCToAbs → True, RA → A1,0 ⩵ A1[0],SCFactor, -Δβ2 + 4 κ2, 4,RA, All, - Δβ24 + κ2 ⩵ s, Apply → Simplify,Expand, {{ⅇ2 s z (2 s - ⅈ Δβ) + ⅇ2 L s (2 s + ⅈ Δβ)}, {(2 s - ⅈ Δβ) (2 s + ⅈ Δβ)}},SCFactor,{{2 ⅇ2 L s s + 2 ⅇ2 s z s + ⅈ ⅇ2 L s Δβ - ⅈ ⅇ2 s z Δβ, ⅇ2 L s}, {ⅇ2 L s - ⅇ2 s z, ⅇ2 L s}}, SCSimpExp → True,SCExpToTrigHalf, All, Apply → {Simplify, ExpandAll},RA, 4 s2 + Δβ2, s ⩵ - Δβ24 + κ2 , Apply → Simplify

    ⅆA1ⅆz ⩵ -ⅈ ⅇⅈ z Δβ κ A2, ⅆA2ⅆz ⩵ ⅈ ⅇ-ⅈ z Δβ κ* A1A1[z] ⩵ⅇⅈ z Δβ2 (-2 ⅈ s Cosh[s (L - z)] + Δβ Sinh[s (L - z)]) A1[0] (-2 ⅈ s Cosh[L s] + Δβ Sinh[L s]),A2[z] ⩵ ⅇ- 12 ⅈ z Δβ 2 s - ⅈ Δβ2 Sinh[s (L - z)] A1[0]4 ⅈ s κ Cosh[L s] - 2 Δβ κ Sinh[L s] A1[z] ⩵ⅇⅈ z Δβ2 (-2 ⅈ s Cosh[s (L - z)] + Δβ Sinh[s (L - z)]) A1[0] (-2 ⅈ s Cosh[L s] + Δβ Sinh[L s]),A2[z] ⩵ ⅇ- 12 ⅈ z Δβ 2 s - ⅈ Δβ2 Sinh[s (L - z)] A1[0]4 ⅈ s κ Cosh[L s] - 2 Δβ κ Sinh[L s] 여기서 L은 광섬유 격자의 길이이며

    s ⩵ - Δβ24 + κ2위치 z에서 두 모드의 파워는

    Presentation-Y. Chung (2015-08-22 Summer School).nb 47

  • P1P0 ⩵ A1[z]A1[0] 2, P2P0 ⩵ A2[z]A1[0] 2SCMAF%, RA, All, A1[z] ⩵ ⅇⅈ z Δβ2 (-2 ⅈ s Cosh[s (L - z)] + Δβ Sinh[s (L - z)]) A1[0] (-2 ⅈ s Cosh[L s] + Δβ Sinh[L s]),

    A2[z] ⩵ - 2 ⅇ- 12 ⅈ z Δβ κ2 Sinh[s (L - z)] A1[0]κ (-2 ⅈ s Cosh[L s] + Δβ Sinh[L s]) , RA → _Im ⩵ 0,SCSepAbs, At[2, 2], Hold → Sinh[s (L - z)]-2 ⅈ s Cosh[L s] + Δβ Sinh[L s] ,RA, All, s ⩵ - Δβ24 + κ2 ,SCFactor, {L - z, L}, - Δβ24 + κ2, κ2,SCDivFrac, {All, κ },SCFactorAbs, At[2, 2], 1κ , Hold → κ2, ,SCEqsListForm, All, RA → L κ ⩵ 3,Plot, At[2], Δβκ , -10, 10, PlotRange → {0, 2}, AxesLabel → " Δβκ ",Tooltip → P1P0 , P2P0 , HoldForm → True, , ,Manipulate, At[2], zL , 0, " zL ", 0, 1, Appearance → "Open",ReplVar → zL , Δβκ , Take → Last

    P1P0 ⩵ A1[z]A1[0]2, P2P0

    ⩵ A2[z]A1[0]2

    P1P0 ⩵ -2 ⅈ 1 - Δβ2

    4 κ2 CoshL κ 1 - Δβ2

    4 κ2 1 - zL +Δβκ SinhL κ 1 - Δβ24 κ2 1 - zL

    -2 ⅈ 1 - Δβ24 κ2 CoshL κ 1 - Δβ

    2

    4 κ2 + Δβκ SinhL κ 1 - Δβ2

    4 κ2 2

    ,

    P2P0

    ⩵ 4 SinhL κ 1 - Δβ24 κ2 1 - zL

    -2 ⅈ 1 - Δβ24 κ2 CoshL κ 1 - Δβ

    2

    4 κ2 + Δβκ SinhL κ 1 - Δβ2

    4 κ2 2

    48 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • zL

    0.

    -10 -5 0 5 10 Δβκ

    0.5

    1.0

    1.5

    2.0

    • FiberGratings 패키지를 로드한다.In[105]:=

  • – Apodization을 하기 위하여 z에 따라 결합 상수 κ를 변화시키는 단주기 브라그 격자의 반사 스펙트럼

    In[130]:= ManipulateModule{f},f = κ Cosπ (# - 5)L &;GridPlot[f[z], {z, 0, 10}, AxesLabel → {z[mm], "κ(z)"},

    PlotRange → {0, 0.0005}, Filling → Bottom, ImageSize → 300], FBGPlotReflectionFBGNTMatrixSingle1.55 + 0.001 Δλ, 1.5, f, 1.553 , 10, {Δλ, -1, 1},AxesLabel → {Δλ[nm], R}, PlotRange → {0, 1.05}, ImageSize → 300,{{κ, 0.0005, "κmax"}, 0, 0.0005}, {L, {10, 12, 15, 20, 30}},

    ContinuousAction → False,SaveDefinitions → True

    Out[130]=

    κmaxL 10 12 15 20 30

    0 2 4 6 8 10z(mm)

    0.0001

    0.0002

    0.0003

    0.0004

    0.0005κ(z)

    -1.0 -0.5 0.0 0.5 1.0 Δλ(nm0.2

    0.4

    0.6

    0.8

    1.0

    R

    LibraryLink를 이용하여 C 소스 코드를 결합하기

    Wolfram LibraryLink User Guide (Mathematica Tutorial)

    함수 예제

    • C 컴파일러 드라이버를 로드한다.In[3]:= Needs["CCompilerDriver`"];

    컴파일러가 설치되어 있는지 확인한다.

    50 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • In[4]:= CCompilers[]Out[4]= {{Name → Visual Studio,

    Compiler → CCompilerDriver`VisualStudioCompiler`VisualStudioCompiler,CompilerInstallation → C:\Program Files\Microsoft Visual Studio 12.0,CompilerName → Automatic}, {Name → Visual Studio,Compiler → CCompilerDriver`VisualStudioCompiler`VisualStudioCompiler,CompilerInstallation → C:\Program Files\Microsoft Visual Studio 11.0,CompilerName → Automatic},{Name → MinGW, Compiler → CCompilerDriver`MinGWCompiler`MinGWCompiler,CompilerInstallation → C:\MinGW\bin\gcc.exe, CompilerName → Automatic}}

    – MacOS의 경우 OS를 Mac OS X Mountain Lion 이상으로 업그레이드 하고 X code와 command line interface for X code를 설치한다. X code의 소스를 다운 받으려면 개발자로 등록하여야 한다.• 텍스트로 되어 있는 C 소스코드로 라이브러리를 만든다.csrc = "/* Include required header */#include \"WolframLibrary.h\"#include \"math.h\"#include \"stdlib.h\"/* Return the version of Library Link */DLLEXPORT mint WolframLibrary_getVersion() {

    return WolframLibraryVersion;}/* Initialize Library */DLLEXPORT int WolframLibrary_initialize(WolframLibraryData libData) {

    return LIBRARY_NO_ERROR;}/* Uninitialize Library */DLLEXPORT void WolframLibrary_uninitialize(WolframLibraryData libData) {

    return;}DLLEXPORT int lib_print_hello_world(WolframLibraryData

    libData, mint Argc, MArgument *Args, MArgument Res){char *s;if (Argc != 0) return LIBRARY_FUNCTION_ERROR;MArgument_setUTF8String(Res, \"Hello, World!\");

    Presentation-Y. Chung (2015-08-22 Summer School).nb 51

  • return LIBRARY_NO_ERROR;}DLLEXPORT int lib_add_two(WolframLibraryData

    libData, mint Argc, MArgument *Args, MArgument Res){mint a,b,f;

    if (Argc != 2) return LIBRARY_FUNCTION_ERROR;a = MArgument_getInteger(Args[0]);b = MArgument_getInteger(Args[1]);f = a + b;MArgument_setInteger(Res, f);return LIBRARY_NO_ERROR;}

    ";

    • “strexamples.dll”의 이름으로 라이브러리를 만든다. 맥 OS에서는 다른 이름으로 만들어진다.

    CreateLibrary[csrc, "strexamples", "SystemDefines" → {}]C:\Users\ychung\AppData\Roaming\Mathematica\SystemFiles\LibraryResources\Windows\

    strexamples.dll

    – C 함수 lib_print_hello_world()를 Mathematica 함수 libPrintHelloWorld로 로드한다. 현재 디렉터리에서 로드하려면 상대적 파일명 “./filename”을 사용한다.libPrintHelloWorld =LibraryFunctionLoad["strexamples", "lib_print_hello_world", {}, "UTF8String"]

    LibraryFunction Function name: lib_print_hello_worldArgument count: 0

    libPrintHelloWorld 함수를 호출한다.

    libPrintHelloWorld[]Hello, World!libPrintHelloWorld 함수를 언로드한다.

    LibraryFunctionUnload[libPrintHelloWorld]– C 함수 lib_add_two()를 Mathematica 함수 libAddTwo로 로드한다.

    52 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • libAddTwo =LibraryFunctionLoad["strexamples", "lib_add_two", {Integer, Integer}, Integer]

    LibraryFunction Function name: lib_add_twoArgument count: 2

    libAddTwo 함수를 호출한다.

    libAddTwo[1, 2]3

    libAddTwo[1.0, 2.0]3

    libAddTwo 함수를 언로드한다.

    LibraryFunctionUnload[libAddTwo]– 언로드할 함수가 남아 있을 경우 라이브러리를 언로드한다.

    LibraryUnload["strexamples"]• C 소스코드 파일 examples.c가 있는 디렉터리로 변경한다.

    In[6]:= SetDirectory["I:/Mathematica/LibraryLink/Examples/examples"]Out[6]= I:\Mathematica\LibraryLink\Examples\examples

    • C 소스코드 파일 examples.c와 Windows 라이브러리 libnrd.a를 사용하여 라이브러리를 생성한다.

    In[7]:= CreateLibrary{"examples.c"}, "examples","SystemDefines" → {}, "IncludeDirectories" → "I:\\Include","LibraryDirectories" → "I:\\Lib", "Libraries" → "nrd", "Defines" → "NRDOUBLE"

    Out[7]= C:\Users\ychung\AppData\Roaming\Mathematica\SystemFiles\LibraryResources\Windows\examples.dll

    – C 함수 lib_add_vector(x)의 정수 버전을 Mathematica 함수 libAddVector로 로드한다.

    libAddVector =LibraryFunctionLoad["examples", "lib_add_vector", {{Integer, 1}}, Integer]

    LibraryFunction Function name: lib_add_vectorArgument count: 1

    libAddVector 함수를 호출한다.

    Presentation-Y. Chung (2015-08-22 Summer School).nb 53

  • libAddVector[{1, 2, 3, 4, 5}]15

    libAddVector 함수를 언로드한다.

    LibraryFunctionUnload[libAddVector]– C 함수 lib_add_vector(x)의 플로팅 버전을 Mathematica 함수 libAddVector로 로드한다.

    libAddVector = LibraryFunctionLoad["examples", "lib_add_vector", {{Real, 1}}, Real]LibraryFunction Function name: lib_add_vector

    Argument count: 1

    libAddVector 함수를 호출한다.

    libAddVector[Range[100]]5050.

    libAddVector 함수를 언로드한다.

    LibraryFunctionUnload[libAddVector]– 임의의 행렬과 벡터를 곱하는 C 함수 lib_dot(x,y)를 Mathematica 함수 libDot로 로드한다. 아래의 경우 입력된 두 행렬을 곱하여 결과를 행렬로 출력하도록 설정되었다.

    In[149]:= libDot = LibraryFunctionLoad["examples", "lib_dot", {{Real, 2}, {Real, 2}}, {Real, 2}]Out[149]= LibraryFunction Function name: lib_dot

    Argument count: 2

    행렬 m1, m2를 생성한다.

    In[151]:= n = 200;m1 = Table[RandomReal[10.0], {n}, {n}];m2 = Table[RandomReal[10.0], {n}, {n}];

    m1과 m2를 곱할 때 libDot과 Dot 함수가 걸리는 시간 비교 (N ×N 행렬의 경우 계산 시간 스케일링은 N3)

    In[158]:= {AbsoluteTiming[libDot[m1, m2];], AbsoluteTiming[m1.m2;]}Out[158]= {{0.011056, Null}, {0.00965251, Null}}

    libDot 함수를 언로드한다.

    54 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • In[15]:= LibraryFunctionUnload[libDot]– C 함수 lib_sin(x)를 Mathematica 함수 libSin로 로드한다.

    libSin = LibraryFunctionLoad["examples", "lib_sin", {Real}, Real];libSin 함수를 그린다.

    PlotlibSin[x], {x, 0, 2 π},AxesLabel → {x, Sin[x]}, Ticks → π2 Range[0, 4], Automatic

    π2

    π 3π2

    2π x

    -1.0

    -0.5

    0.5

    1.0

    sin(x)

    libSin 함수를 언로드한다.LibraryFunctionUnload[libSin]

    – 언로드할 함수가 남아 있을 경우 라이브러리를 언로드한다.

    LibraryUnload["examples"]

    WSTP (Wolfram Symbolic Transfer Protocol, 이전의 MathLink)를 이용하여 외부 프로그램과 연동

    WSTP and External Program Communication (Mathematica Tutorial)

    예제 (addtwo.exe)

    두 개의 수(Integer 혹은 Real)를 더하는 함수 AddTwo

    addtwo.c

    #include “wstp.h”extern int addtwo( int i, int j);int addtwo( int i, int j)

    Presentation-Y. Chung (2015-08-22 Summer School).nb 55

  • {return i+j;

    }

    addtwo.tm

    int addtwo P(( int, int));:Begin::Function: addtwo:Pattern: AddTwo[i_Integer, j_Integer]:Arguments: { i, j }:ArgumentTypes: { Integer, Integer }:ReturnType: Integer:End::Evaluate: AddTwo::usage = "AddTwo[x, y] gives the sum of two machine integers x and y."

    Compile and link

    SET CL=/nologo /c /DWIN32 /D_WINDOWS /W3 /O2 /DNDEBUGSET LINK=/NOLOGO /SUBSYSTEM:windows /INCREMENTAL:no /PDB:NONE ker-nel32.lib user32.lib gdi32.libWSPREP addtwo.tm -o addtwotm.cCL addtwo.c addtwotm.cLINK addtwo.obj addtwotm.obj wstp32i4m.lib /OUT:addtwo.exe

    Install and run

    wslink = Install["I:/Mathematica/WSTP/WSTPExamples/addtwo/addtwo.exe"];두 인수는 Integer이거나 Real이어야만 한다.

    AddTwo[1, 2]3

    AddTwo[1.0, 2.0]3.

    Rational은 계산되지 않는다.

    AddTwo 12 , 23 AddTwo 12 , 23 WSTP 연결을 해제한다.

    56 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • Uninstall[wslink]"I:\Mathematica\WSTP\WSTPExamples\addtwo\addtwo.exe"

    예제 (wsdot.exe)

    행렬 m1, m2를 생성한다.

    In[139]:= n = 200;m1 = Table[RandomReal[10.0], {n}, {n}];m2 = Table[RandomReal[10.0], {n}, {n}];설치하고 실행한다.

    In[142]:= wslink = Install["I:/Mathematica/WSTP/Misc/wsdot/wsdot.exe"];m1과 m2를 곱할 때 wsDot과 Dot 함수가 걸리는 시간 비교 (N ×N 행렬의 경우 계산 시간 스케일링은 N3)

    In[143]:= {AbsoluteTiming[wsDot[m1, m2];], AbsoluteTiming[Dot[m1, m2];]}Out[143]= {{0.0171684, Null}, {0.00194267, Null}}

    WSTP 연결을 해제한다.

    In[144]:= Uninstall[wslink]Out[144]= "I:\Mathematica\WSTP\Misc\wsdot\wsdot.exe"

    예제 (광섬유 모드 시뮬레이션)

    초기화• 패키지 로딩

    Presentation-Y. Chung (2015-08-22 Summer School).nb 57

  • In[1]:=

  • The data format for the α index profile is {Alpha, α, {{0, ncore}, {acore, n1}, {r2, n2}, ... , {rN , nN}, {acore-clad, nclad}}or{Alpha, α, {{0, Δcore}, {acore, Δ1}, {r2, Δ2}, ... , {rN , ΔN}, {acore-clad, Δclad}}.profile = {Alpha, 2, {{0, 1}, {4, -0.5}, {6, -0.5}, {8, 0}}}DspnPlotIndex[1.55, profile, Scale → Delta, AxesLabel → {r[μm], "Δ[%]"}]

    {Alpha, 2, {{0, 1}, {4, -0.5}, {6, -0.5}, {8, 0}}}

    5 10 15r(μm)

    -0.5

    0.5

    1.0

    Δ[%]

    • General indexThe data format for the general index profile is{General, {0, ncore}, {r1, n1}, {r2, n2}, ... , {rN , nN}, {acore-clad, nclad}}or{General, {0, Δcore}, {r1, Δ1}, {r2, Δ2}, ... , {rN , ΔN}, {acore-clad, Δclad}}.profile = {General, {{0, 1}, {4, -0.5}, {6, -0.5}, {6, 0}}}DspnPlotIndex[1.55, profile, Scale → Delta, AxesLabel → {r[μm], "Δ[%]"}]

    {General, {{0, 1}, {4, -0.5}, {6, -0.5}, {6, 0}}}

    2 4 6 8 10 12r(μm)

    -0.5

    0.5

    1.0

    Δ[%]

    굴절률 프로파일과 특성 방정식• 광섬유 굴절률 프로파일과 특성 방정식을 그려서 모드의 존재를 확인한다.

    Presentation-Y. Chung (2015-08-22 Summer School).nb 59

  • In[129]:= Manipulate[profile = {Step, Δ, {a, 0}};Grid[{{DspnPlotIndex[1.55, profile, Sellmeier → False,

    AxesLabel → {r[μm], "Δ[%]"}, PlotRange → {{0, 15}, {0, 1}}, ImageSize → 300],DspnPlotCharEquation[m, 1.55, profile, AxesLabel → {"neff", "Log10|G|"},PlotRange → {-10, 0}, ImageSize → 300]}}],{{m, 1}, Range[0, 4]}, {{Δ, 0.2, "Δ[%]"}, 0.1, 1}, {{a, 4, "a[μm]"}, 1, 8}]

    Out[129]=

    m 0 1 2 3 4

    Δ[%]a[μm]

    0 2 4 6 8 10 12 14r(μm)0.0

    0.2

    0.4

    0.6

    0.8

    1.0Δ[%]

    1.4445 1.4450 1.4455 1.4460 1.4465neff

    -10-8-6-4-2

    Log10|G|

    유효 굴절률, 그룹 굴절률과 분산• 광섬유 모드의 유효 굴절률, 그룹 굴절률과 분산을 계산한다.profile = {Step, 1.46, {4, 1.45}};sols = DspnNeffNgroupDspn[1, {1.2, 1.6, 0.02}, profile, NumModes → 1]

    {Mode → {HE1,1}, Lambda → {1.2, 1.22, 1.24, 1.26, 1.28, 1.3, 1.32, 1.34,1.36, 1.38, 1.4, 1.42, 1.44, 1.46, 1.48, 1.5, 1.52, 1.54, 1.56, 1.58, 1.6},

    Neff → {{1.4573, 1.45723, 1.45716, 1.45709, 1.45702, 1.45696, 1.45689,1.45682, 1.45675, 1.45668, 1.45661, 1.45654, 1.45647, 1.45641,1.45634, 1.45627, 1.4562, 1.45613, 1.45606, 1.45599, 1.45592}},

    Ngroup → {{1.46137, 1.46138, 1.46139, 1.4614, 1.46141, 1.46142, 1.46143,1.46143, 1.46144, 1.46144, 1.46144, 1.46144, 1.46144, 1.46144,1.46144, 1.46143, 1.46143, 1.46142, 1.46142, 1.46141, 1.4614}},

    Dspn → {{2.10049, 1.93054, 1.75769, 1.58207, 1.4038, 1.22301, 1.03981,0.854336, 0.666699, 0.477018, 0.285407, 0.0919793, -0.103155, -0.299888,-0.498114, -0.697731, -0.898639, -1.10074, -1.30395, -1.50817, -1.71333}}}

    • 유효 굴절률 Neff를 그린다.

    60 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • ListPlot[Transpose[{Lambda /. sols, (Neff /. sols)[[1]]}],Joined → True, AxesLabel → {λ[μm], Neff}]

    1.3 1.4 1.5 1.6λ(μm)1.4560

    1.4562

    1.4564

    1.4566

    1.4568

    1.4570

    1.4572

    Neff

    • 그룹 굴절률 Ng를 그린다.ListPlot[Transpose[{Lambda /. sols, (Ngroup /. sols)[[1]]}],Joined → True, AxesLabel → {λ[μm], Ng}]

    1.3 1.4 1.5 1.6λ(μm)

    1.46138

    1.46140

    1.46142

    1.46144

    Ng

    • 분산 D를 그린다.ListPlot[Transpose[{Lambda /. sols, (Dspn /. sols)[[1]]}],Joined → True, AxesLabel → {λ[μm], "D[ps/nm/km]"}]

    1.3 1.4 1.5 1.6λ(μm)

    -1

    1

    2

    D[ps/nm/km]

    Presentation-Y. Chung (2015-08-22 Summer School).nb 61

  • 포인팅 벡터와 광의 세기 프로파일• 포인팅 벡터의 계산In[132]:= profile = {Step, 1.46, {4, 1.45}};

    sols = DspnNeff[1, 1.55, profile]ssol = DspnPoyntingVector[1, 1.55, 1, profile, {x, y, z}, Phase → π / 2, MaxRadius → 20];

    Out[133]= {Mode → {HE1,1}, Lambda → 1.55, Neff → {1.44306}}• 포인팅 벡터를 그린다.In[135]:= Plot[(PoyntingVector[[3]] /. ssol)[x, 0], {x, -10, 10}, AxesLabel → {r[μm], Sz}]

    Out[135]=

    -10 -5 5 10 r(μm)0.005

    0.010

    0.015

    0.020

    Sz

    광의 세기의 밀도 플롯과 3차원 플롯

    62 Presentation-Y. Chung (2015-08-22 Summer School).nb

  • In[138]:= Grid[{{DensityPlot[(PoyntingVector[[3]] /. ssol)[x, y], {x, -10, 10},{y, -10, 10}, PlotPoints → 50, PlotRange → All, ImageSize → 300],Plot3D[(PoyntingVector[[3]] /. ssol)[x, y], {x, -10, 10},{y, -10, 10}, AxesLabel → {x, y, Sz}, BoxRatios → {1, 1, 1},PlotPoints → 50, PlotRange → All, ImageSize → 300]}}]

    Out[138]=

    WSTP 연결을 해제한다.

    Uninstall[mlelink]mle.exe

    Presentation-Y. Chung (2015-08-22 Summer School).nb 63