Early Matter

(*Dynamic[ControllerState["B"<>ToString[#]&/@Range[15]]]*)

(*DoToken[token_]:=FrontEndExecute[{FrontEndToken[EvaluationNotebook[],token]}]

ControllerToFunction[button_,fn_]:=If[ControllerState[button]&&AbsoluteTime[]-LastTime>0.5,
LastTime=AbsoluteTime[];
fn];
SetAttributes[ControllerToFunction,HoldAll];

LastTime=AbsoluteTime[];
xxx=55;
SetOptions[EvaluationNotebook[],NotebookDynamicExpression->
Dynamic[

ControllerToFunction["B6",DoToken["ScrollPageNext"]];
ControllerToFunction["B5",DoToken["ScrollPagePrevious"]];
ControllerToFunction["B1",DoToken["ScrollPageDown"]];
ControllerToFunction["B4",DoToken["ScrollPageUp"]];
ControllerToFunction["B9",xxx+=1];
ControllerToFunction["B10",xxx-=1];
ControllerToFunction["B11",xxx=55];

]
]*)

(*Dynamic[xxx]
Dynamic[LastTime]*)

CellPrint@Cell[RowBox[{"for my ",DynamicBox[ToBoxes[$CellContext`xxx,StandardForm]]," minute talk"}], "Chapter"]

(*DuplicateWithSmallInput[]*)

Advanced Mathematica for Physics Computations

Plan

Functional Programming in Physics

Example: Large Black Hole with Scalar Hair

Scoping, Downvalues, Options

Principles of Functional Programming in Mathematica

Custom Notations

Organising Code

Building Custom Packages

Memoization

Backups

Functional Programming in Physics

Worked Example: Einstein’s Equations

coord={t,r,x,y};

metric=(({{-f[r], 0, 0, 0}, {0, (1/(f[r] )), 0, 0}, {0, 0, r^2, 0}, {0, 0, 0, r^2}}));

<<"diffgeo.m";

Elementary black brane solution

EE[1]=Union@Flatten@(Einstein-3metric)

BlackBraneSub[1]=f[r]->(r^2)-(rh/r);

Simplify@(
EE[2]/.Flatten[{
BlackBraneSub[1],
(∂_r)BlackBraneSub[1],
(∂_r)(∂_r)BlackBraneSub[1]
}]
)

BlackBraneSub[2]=BlackBraneSub[1]/.rh->1;

Custom Functions for often-used code

DD[expr_,x_]:=Flatten[{
expr,
(∂_x)expr,
(∂_x)(∂_x)expr}];

DD[BlackBraneSub[2],r]

DD[x_]:=DD[#,x]&;

DD[r]@BlackBraneSub[2]

Simplify@(
EE[2]/.DD[r]@BlackBraneSub[2]
)

Back to the physics: Massless Klein-Gordon Equation

KG= scalarLaplacian[ϕ[r](E^(I (ω t+k x)-Γ t))]/.(DD[r]@BlackBraneSub[2])

Numerical Solution

KGSol[k2_]:=NDSolve[
{
KG/.{k->k2,ω->1,Γ->1}==0,
ϕ[5]==1,
ϕ'[5]==-1/1000
},ϕ,{r,1+1/100,8}
][[1]];

sol2=KGSol[1/10]

Scoping

Module

Module allows for certain variables to be deemed as local.

Module[{x,y},
x=3;
y=4;
x*y
]

The x in the Global` context still has no definition:

x

BraneHairPlot3D[k_]:=Module[{thissol=KGSol[k]},

Plot3D[
Re[ϕ[r](E^(I k x))/.thissol],
{r,1+1/100,3},
{x,0,100},
AxesLabel->{r,x},
PlotRange->All,
PlotPoints->20
]//Quiet

]
BraneHairPlot3D[1/10]

This doesn't work if we have sol[k] in the body. Why? (Use Echo to help debug)

Timing

Timing@BraneHairPlot3D[1/10]

A Custom Function: EchoTiming

Clear[EchoTiming];
EchoTiming[expr_] := Module[{x},

  x=Timing[expr];

  Print[x[[1]]];

x[[2]]
  ]

SetAttributes[EchoTiming, HoldAll]

EchoTiming@BraneHairPlot3D[1/10]

Mathematica from a computer science point of view

The Functional Style

Mathematica is a particular kind of functional programming language.
Rather than passing around functions and data, Mathematica is built on the definition of transformation rules which are applied to expressions on evaluation.

The Structure of Expressions

Expressions have a tree-like structure.

DynamicModule[{boxes = ""}, 
 Column[{
InputField[Dynamic[boxes], Boxes, ContinuousAction -> True],
,
   Dynamic[boxes//MakeExpression//ToString//StringTake[#,{14,-2}]&]
,,
   Dynamic[boxes, BaseStyle -> {ShowStringCharacters -> True}]
}]
]

During evaluation, all known transformation rules are applied.

Transformation rules are rules for replacing ‘patterns’, which are classes of expressions.

Cases[{1,1.5,2,α},_Integer]

{1,1.5,2,α}/.x_Integer->5x

DownValues

DownValues can be defined over any pattern:

Clear[f];
f[_]:=5;

f[a]

Clear[f];
f[x_Integer]=1;
f[x_]=0;

{f[1],f[1.5],f[2],f[2.5],f[dog]}

Downvalues =/= Functions

#^2&

is a function. That means it is an object which holds its own transformation rules for its downvalues:

#^2&[2]

We more often define downvalues directly, rather than use functions.

Mathematica Slogans

“Everything is an expression.”

“Every definition is a transformation rule.”

“Everything is a pattern.”

“Everything is boxes.”

Options

Functions can take ‘options’:

Plot[(x^2),{x,0,1},Filling->Axis,FillingStyle->Red]

Options in Custom Functions

Define these in our own functions as follows:

Options[g]={Coeff->1};

g[x_,opts:OptionsPattern[]]:=OptionValue[Coeff]*(x^2)

g[x,Coeff->2]

Pushing Options Forward

Say that we want to build a custom function, BraneHairPlot, some of whose Options we intend to push to a subsidiary function like Plot.

For example,

Clear[BraneHairPlot3D]
Options[BraneHairPlot3D]={
Momentum->0,
Frequency->0,
AxesLabel->{r,x}
};

BraneHairPlot3D[opts:OptionsPattern[]]:=Module[{},
(* ... *)
Plot[x,{x,0,1},opts]
(* ... *)
]

BraneHairPlot3D[Momentum->2];

The problem is that like Plot does not like being passed Options it doesn’t know about.
We want to pass it only the options that are relevant.

I wrote a function to push Options forward selectively

PushOptions[fn_,explicitOptions_,parentSymbol_]:=Module[{opts1,opts2},

opts1=FilterRules[Options[parentSymbol],Except[explicitOptions]];
opts2=FilterRules[Flatten[{opts1,explicitOptions}],Options[fn]];

fn[##,Evaluate[opts2]]&
];

or the Operator version:

PushOptions[a_,b_]:=PushOptions[#,a,b]&;

Now it works:

BraneHairPlot3D[opts:OptionsPattern[]]:=Module[{},
(* ... *)
PushOptions[{opts},BraneHairPlot3D][Plot][(x^2),{x,0,1}]
(* ... *)
]

BraneHairPlot3D[Momentum->2]

Functional Programming for Physics

High levels of function encapsulation can be dangerous for physics problems.

Automation makes your life easier when you’re doing the exact same thing, over and over. But no two physics problems are quite alike.

One place functional encapsulation does come in handy is in hiding the implementation of a task that is conceptually simple in physics.
One can create nice ‘frontends’ for particular theories that offer simple functions.

Schwarzschild - AdS Frontend

Plot3D[

Im@SchwarzschildAdSScalarRetardedGreensFunction[
Parameters->{ω->ω2,q->q2},
SetValues->{c[1]->1},
InitialValues->{{c[2],1},{d[0],1}}
]

,{q2,0,2}
,{ω2,0,2}
,AxesLabel->Automatic
,PlotPoints->2
]//EchoTiming

This function is provided by a little frontend for the theory of a scalar field on the Schwarzschild-AdS spacetime. It looks something like

Module[{vars=ϕ,eom=(*... , *)},
(* ... *)
SchwarzschildAdSScalarRetardedGreensFunction[opts:OptionsPattern[]]:=(*...*)
(* ... *)
]

As you can see this goes quite nicely with passing arguments by name as Options.

Custom Notations

<<Notation`

For MultipleD

Notation[(NotationTemplateTag[∂(∂_(x_))expr_]) ⟺ (NotationTemplateTag[DD[x_]@expr_])]

∂(∂_r){U[r]->(r^3)}

(Subscript[DD, x_]):=DD[#,x]&;

For Raising/Lowering Operators

InfixNotation[(NotationTemplateTag[·]),NonCommutativeTimes];

Notation[(NotationTemplateTag[(Subscript[a, m_])]) ⟺ (NotationTemplateTag[AnnihilationOp[m_]])];
Notation[(NotationTemplateTag[(Subscript[(SuperDagger[a]), m_])]) ⟺ (NotationTemplateTag[CreationOp[m_]])];

Properties of NonCommutativeTimes

EmptyQ[a__]:=False
EmptyQ[] := True

l___·b_NonCommutativeTimes·r___:=l·(Sequence@@b)·r

l___·(c_?ConstQ a_)·r___:=c l·a·r
l___·(a_+b_)·r___:= l·a·r +l·b·r
l___·c_?ConstQ·r___:=c (l·r) /; !EmptyQ[l,r]

NonCommutativeTimes[a_]:=a

ConstQ[args_Times]:=And @@ ConstQ /@ List @@ args
ConstQ[args_Plus]:=And @@ ConstQ /@ List @@ args
ConstQ[((c_)^(n_))]:=ConstQ[c]∧ConstQ[n]
ConstQ[_?NumberQ]:=True
ConstQ[(Subscript[δ, __])]:=True
ConstQ[_]:=False

Definition of NormalOrder

NormalOrder[a__Plus]:=NormalOrder /@ a;
NormalOrder[a__Times]:=NormalOrder /@ a;

NormalOrder[l___·(Subscript[a, i_])·(Subscript[a, j_])·r___]:=-NormalOrder[l·(Subscript[a, j])·(Subscript[a, i])·r] /;¬OrderedQ[{i,j}]
NormalOrder[l___·(Subscript[(SuperDagger[a]), i_])·(Subscript[(SuperDagger[a]), j_])·r___]:=-NormalOrder[l·(Subscript[(SuperDagger[a]), j])·(Subscript[(SuperDagger[a]), i])·r]/;¬OrderedQ[{i,j}]
NormalOrder[l___·(Subscript[a, i_])·(Subscript[(SuperDagger[a]), j_])·r___]:=NormalOrder[l·((Subscript[δ, i,j])-(Subscript[(SuperDagger[a]), j])·(Subscript[a, i]))·r]

NormalOrder[any_]:=any

Examples

(Subscript[a, m])·(Subscript[(SuperDagger[a]), i])//NormalOrder//Expand

(Subscript[a, m])·(Subscript[(SuperDagger[a]), i])·(Subscript[(SuperDagger[a]), j])//NormalOrder

A Cute Macro

AddInputAlias["f"->(NotationTemplateTag[ClearAll[\[Placeholder]];
Options[\[Placeholder]]={

};
\[Placeholder][]:=Module[{},

]])];

Recap of this section:

Scope variables with Module[].

Options can occasionally help improve the interface of your functions.

Everything is expressions/transformation rules/patterns/boxes.

Custom Notations allow for more physics.

Organising Code

Creating a Custom Package

Creating a package

Packages provide definitions.

They are saved as .m

Packages from Notebooks

I have a function called PackageGenerator:

PackageGenerator[theName_String]:=
Catch@Module[{name,document,directory,nb},

name=StringReplace[theName,{Except[WordCharacter]->""}];

If[name==="",Throw[$Failed]];

document=
DocumentNotebook[
{
TextCell[#,"Title",TextAlignment->Center]&[name<>".m package"],
ExpressionCell[Defer[BeginPackage[#]],"Input"]&[name<>"`"],
TextCell["Usage messages","Subsection"],
TextCell["`Private context","Section"],
ExpressionCell[Defer[Begin["`Private`"]],"Input"],
TextCell["Definitions","Subsection"],
TextCell["End of `Private context","Section"],
ExpressionCell[Defer[End[]],"Input"],
TextCell["End of package context","Section"],
ExpressionCell[Defer[EndPackage[]],"Input"]
}
,
StyleDefinitions->Notebook[{
Cell[StyleData[StyleDefinitions->"Default.nb"]],Cell[StyleData["Code"],PageWidth->WindowWidth,AutoIndent->Automatic,AutoSpacing->True,LineBreakWithin->Automatic,LineIndent->1,LinebreakAdjustments->{0.85,2,10,0,1}],Cell[StyleData["Input"],InitializationCell->True]},Visible->False,StyleDefinitions->"PrivateStylesheetFormatting.nb"],
AutoGeneratedPackage->Automatic
];

nb=CreateWindow[document];

directory=SystemDialogInput["Directory", 
FileNameJoin[{$UserBaseDirectory,"/Applications"}]];

If[directory===$Canceled,Throw[$Canceled]];

NotebookSave[nb,FileNameJoin[{directory,name<>".nb"}]]
];

PackageGenerator["mathematica-talk-package"]

Memoization of Downvalues

?BraneHairPlot3D

b2[k_]:=b2[k]=BraneHairPlot3D[k];

b2[1];

b2[2];

?b2

Saving Definitions

Save

SetDirectory[NotebookDirectory[]];
Save["save.m",b2]

SetDirectory[NotebookDirectory[]];
<<save.m

Backups

Short-term backups: A package

<< NotebookBackup`

Long-term backups: Git, Github

Git is a flexible version control system.

It allows you to maintain a “master” branch, and sub-branches.

Good if you work from more than one location. Commit your changes when you leave, and download when you arrive.

Good for multi-person projects. Track changes made by your collaborators.

Github provides a clean user interface for git.

Recap of this section:

Custom packages give efficiency boosts.

Memoize computationally intensive functions.

Your backup needs a backup.

Thank-you for your attention

for my  minute talk

github.com/
	danielmartin0/
	mathematica-talk