Community RSS Feed
http://community.wolfram.com
RSS Feed for Wolfram Community showing any discussions in tag Education sorted by activeBuilding a simple Mathematica code for Tensorial/Vectorial Calculus
http://community.wolfram.com/groups/-/m/t/1127218
There are a lot of Mathematica packages for vector/tensor calculus: [Tensorial][1], [Advanced Tensor Analysis][2], [Ricci][3], [TensoriaCalc][4], [grt][5], [xAct][6] are just a few mentions.
The main thing I don't like about these packages is that the majority of them (if not all) are not up to date with the current Mathematica version. Some of them haven't seen an update in decades. The other major drawback of these packages is the cumbersome notation, declaration and the fact that almost all are to be used with General Relativity in mind and use coordinate notation. The results are not really coordinate-free.
With this in mind, I have developed a "Package" that can deal with symbolic vectors/tensors in a coordinate-free form and the package is human-readable (some packages implementations in this matter are simply indecipherable).
In the first part, I'll present the code with simple explanations and the second part some simple examples.
These functions are needed to clear the OenOwnValues, DownValues, UpValues, SubValues. Mathematica has no built-in way of doing it.
(* Prevent evaluation *)
SetAttributes[{ClearOwnValues, ClearDownValues, ClearUpValues, ClearSubValues}, HoldFirst]
(* Always return true for commodity later *)
ClearOwnValues[var_Symbol] := (OwnValues@var = {}; True)
ClearDownValues[var_Symbol] := (DownValues@var = {}; True)
ClearUpValues[var_Symbol] := (UpValues@var = {}; True)
ClearSubValues[var_Symbol] := (SubValues@var = {}; True)
(* Delete Values of "f" if they match the input *)
ClearDownValues[expr:f_Symbol[___]] := (DownValues@f = DeleteCases[DownValues@f, _?(!FreeQ[First@#, HoldPattern@expr] &)]; True)
ClearUpValues[expr:f_Symbol[___]] := (UpValues@f = DeleteCases[UpValues@f, _?(!FreeQ[First@#, HoldPattern@expr] &)]; True)
ClearSubValues[expr:f_Symbol[___][___]] := (SubValues@f = DeleteCases[SubValues@f, _?(!FreeQ[First@#, HoldPattern@expr] &)]; True)
The Define-family functions are the main core of this package, they are used to define all kinds of relationship and can be easily expanded.
You can define a Symbol "var" or a function "fun[var, ___]" to be a certain "type". "var" cannot have OwnValues, otherwise it will be evaluated.
You can only define symbols. the function "fun" should be primarily used as script-like functions as Subscript, SuperHat, etc.
(* Prevent evaluation *)
SetAttributes[Define$Internal, HoldAll]
(*
Internal version of Define, all others versions are a call of this function.
The OwnValues and/or DownValues are cleared immediately, this step is to avoid rule-parsing.
The possible types are: Real, Imaginary, Tensor and Constant. For Tensor type additional parameters are needed: rank and dimension.
*)
Define$Internal[(var_Symbol /; ClearOwnValues@var) | (var:Except[Hold, fun_][head_Symbol /; ClearOwnValues@head, ___] /; ClearDownValues@var),
type:"Real" | "Imaginary" | "Tensor" | "Constant",
rank_Integer:2, dim_Integer:3] := Module[{tag},
(* All expressions are defined as UpValues, assign it to the corresponding tag *)
(* UpValues cannot be deeply nested, hence the need to assign it to the "tag" *)
tag = If[Head@var === Symbol, var, fun];
Which[
type === "Real", (* Typical properties needed for real quantities *)
Evaluate@tag /: Element[var, Reals] = True;
Evaluate@tag /: Re[v:var] := v;
Evaluate@tag /: Im[v:var] := 0;
Evaluate@tag /: Conjugate[v:var] := v;
Evaluate@tag /: Abs[v:var] := RealAbs@v;
,
type === "Imaginary", (* Typical properties needed for Imaginary quantities *)
Evaluate@tag /: Element[var, Reals] = False;
Evaluate@tag /: Re[v:var] = 0;
Evaluate@tag /: Im[v:var] := v/I;
Evaluate@tag /: Conjugate[v:var] := -v;
Evaluate@tag /: Abs[v:var] := RealAbs@Im@v;
,
type === "Tensor", (* For compativility with Mathematica current Tensor-functions *)
Evaluate@tag /: ArrayQ@var = rank != 0;
Evaluate@tag /: TensorQ@var = rank != 0;
Evaluate@tag /: MatrixQ@var = rank == 2;
Evaluate@tag /: VectorQ@var = rank == 1;
Evaluate@tag /: ListQ@var = rank != 0;
Evaluate@tag /: ScalarQ@var = rank == 0;
Evaluate@tag /: TensorRank@var = rank;
Evaluate@tag /: TensorDimensions@var = ConstantArray[dim, {rank}];
Evaluate@tag /: Element[var, Arrays@TensorDimensions@var] = True;
Evaluate@tag /: Element[var, Matrices@{dim, dim}] = rank == 2;
Evaluate@tag /: Element[var, Vectors@dim] = rank == 1;
,
type === "Constant", (* A constant has zero "derivative" *)
Evaluate@tag /: ConstantQ@var = True;
Evaluate@tag /: grad@var = 0;
Evaluate@tag /: div@var = 0;
Evaluate@tag /: curl@var = 0;
Evaluate@tag /: DotNabla[_, var] = 0;
Evaluate@tag /: D[var, __] = 0;
Evaluate@tag /: Dp[var, __] = 0;
Evaluate@tag /: Dt[var, ___] = 0;
Evaluate@tag /: Delta[var] = 0;
,
True, $Failed]
]
(* Assign more than one variable *)
Define$Internal[vars__ /; Length@{vars} > 1, type:"Real" | "Imaginary" | "Tensor" | "Constant", rank_Integer:2, dim_Integer:3] :=(
Define$Internal[#, type, rank, dim] & /@ Hold /@ Hold@vars // ReleaseHold;) (* Hacky-way of passing Hold down *)
Define$Internal[Hold@var_, type:"Real" | "Imaginary" | "Tensor" | "Constant", rank_Integer:2, dim_Integer:3] := Define$Internal[var, type, rank, dim]
(* Main Define functions *)
SetAttributes[{DefineReal, DefineImaginary, DefineTensor, DefineConstant}, HoldAll]
DefineReal[vars__] := Define$Internal[vars, "Real"]
DefineImaginary[vars__] := Define$Internal[vars, "Imaginary"]
DefineTensor[vars__, rank_Integer:2, dim_Integer:3] := Define$Internal[vars, "Tensor", rank, dim]
DefineConstant[vars__] := Define$Internal[vars, "Constant"]
(* Define multiple things at once *)
SetAttributes[{DefineRealTensor, DefineConstantTensor, DefineRealConstantTensor}, HoldAll]
DefineRealTensor[vars__, rank_Integer:2, dim_Integer:3] := (DefineReal@vars; DefineTensor[vars, rank, dim];)
DefineConstantTensor[vars__, rank_Integer:2, dim_Integer:3] := (DefineConstant@vars; DefineTensor[vars, rank, dim];)
DefineRealConstantTensor[vars__, rank_Integer:2, dim_Integer:3] := (DefineReal@vars; DefineConstant@vars; DefineTensor[vars, rank, dim];)
Now it is possible to define tensorial variables and make them behave as tensor with current Mathematica implementation.
Some built-in functions needed to be redefined to work with symbolic tensors. An example of this necessity is:
(* Define two tensors a and b *)
DefineTensor[a, b, 2]
TensorRank[2*a - 3*b] (* Return 2 *)
TensorQ[a] (* Return True *)
TensorQ[2*a] (* Return False *)
Mathematica function TensorQ don't know that a scalar times a tensor is a tensor. The following code is for refifinition:
Unprotect[TensorQ, VectorQ, TensorRank, Dot, Cross, TensorProduct]
(* Numbers are always scalar/constant. These functions are not built-in. *)
ScalarQ[a_?NumericQ] := True
ConstantQ[a_?NumericQ] := True
(* Complexes *)
TensorQ[(Re|Im|Conjugate)[a_]] := TensorQ@a
VectorQ[(Re|Im|Conjugate)[a_]] := VectorQ@a
ScalarQ[(Re|Im|Conjugate)[a_]] := ScalarQ@a
ConstantQ[(Re|Im|Conjugate)[a_]] := ConstantQ@a
TensorRank[(Re|Im|Conjugate)[a_]] := TensorRank@a
(* Plus *)
TensorQ[(a_?TensorQ) + (b_?TensorQ)] := TensorRank@a === TensorRank@b
VectorQ[(a_?VectorQ) + (b_?VectorQ)] := True
ScalarQ[(a_?ScalarQ) + (b_?ScalarQ)] := True
ConstantQ[(a_?ConstantQ) + (b_?ConstantQ)] := True
(* Times *)
TensorQ[(a__?ScalarQ) * (b_?TensorQ)] := True
VectorQ[(a__?ScalarQ) * (b_?VectorQ)] := True
ScalarQ[(a__?ScalarQ) * (b_?ScalarQ)] := True
ConstantQ[(a_?ConstantQ /; ScalarQ@a) * (b_?ConstantQ)] := True
(* Pass scalars out of Dot and Cross, as is done in TensorProduct *)
Dot[a___, Times[b_, s__?ScalarQ], c___] := Times[s, Dot[a, b, c]]
Cross[a_, Times[b_, s__?ScalarQ]] := Times[s, Cross[a, b]]
Cross[Times[a_, s__?ScalarQ], b_] := Times[s, Cross[a, b]]
(* Dot *)
TensorQ[(a_?TensorQ) . (b_?TensorQ)] /; TensorRank@a + TensorRank@b - 2 >= 1 := True
VectorQ[(a_?TensorQ) . (b_?TensorQ)] /; TensorRank@a + TensorRank@b - 2 == 1 := True
ScalarQ[(a_?VectorQ) . (b_?VectorQ)] := True
ConstantQ[(a_?ConstantQ /; TensorQ@a) . (b_?ConstantQ /; TensorQ@b)] := True
(* Automatically evaluate to zero, as TensorProduct *)
Dot[a___, 0, b___] := 0
(* Cross *)
TensorQ[(a_?VectorQ) \[Cross] (b_?VectorQ)] := True
VectorQ[(a_?VectorQ) \[Cross] (b_?VectorQ)] := True
ConstantQ[(a_?ConstantQ /; VectorQ@a) \[Cross] (b_?ConstantQ /; VectorQ@b)] := True
(* Perpendicular vectors automatically evalute to zero *)
Cross[a_?VectorQ, a_?VectorQ] := 0
(* Automatically evaluate to zero, as TensorProduct *)
Cross[a___, 0, b___] := 0
(* Return single argument as Dot, Times and TensorProduct *)
Cross[a_] := a
(* Tensor Product *)
TensorQ[(a_?TensorQ) \[TensorProduct] (b_?TensorQ)] := True
ConstantQ[(a_?ConstantQ /; TensorQ@a) \[TensorProduct] (b_?ConstantQ /; TensorQ@b)] := True
(* Power *)
ScalarQ@Power[a_?ScalarQ, b_?ScalarQ] := True
ScalarQ[1/a_?ScalarQ] := True
ConstantQ@Power[a_?ConstantQ /; ScalarQ@a, b_?ConstantQ /; ScalarQ@b] := True
ConstantQ[1/a_?ConstantQ /; ScalarQ@a] := True
(* grad *)
grad[_?ConstantQ] := 0
TensorQ@grad[a_?ScalarQ] := True
VectorQ@grad[a_?ScalarQ] := True
TensorQ@grad[a_?TensorQ] := True
TensorRank@grad[a_?ScalarQ] := 1
TensorRank@grad[a_?TensorQ] := TensorRank@a + 1
(* div *)
div[_?ConstantQ] := 0
TensorQ@div[a_?TensorQ /; TensorRank@a >= 2] := True
VectorQ@div[a_?TensorQ /; TensorRank@a == 2] := True
ScalarQ@div[a_?VectorQ] := True
TensorRank@div[a_?TensorQ] := TensorRank@a - 1
(* curl *)
curl[_?ConstantQ] := 0
TensorQ@curl[a_?VectorQ] := True
VectorQ@curl[a_?VectorQ] := True
TensorRank@curl[a_?VectorQ] := 1
(* DotNabla *)
DotNabla[_, _?ConstantQ] := 0
(* Dp *)
Dp[_?ConstantQ, args__] := 0
TensorQ@Dp[a_, args__] := TensorQ@a
VectorQ@Dp[a_, args__] := VectorQ@a
ScalarQ@Dp[a_, args__] := ScalarQ@a
TensorRank@Dp[a_, args__] := TensorRank@a
(* Delta *)
Delta[_?ConstantQ] := 0
TensorQ@Delta[a_] := TensorQ@a
VectorQ@Delta[a_] := VectorQ@a
ScalarQ@Delta[a_] := ScalarQ@a
TensorRank@Delta[a_] := TensorRank@a
(* List *)
Dp[a_List, args__] := Dp[#, args] & /@ a
(* Don't assume anything is a scalar/constant *)
ScalarQ[a_] := False
ConstantQ[a_] := False
Protect[TensorQ, VectorQ, TensorRank, Dot, Cross, TensorProduct]
Where we have defined the Tensor-functions: grad, div, curl which are self-explanatory; Dp is the partial derivative, Delta gives the variation of a quantity, somewhat related to Dp, and DotNabla is (for the lack of better name) the convective derivative.
For better print, we'll define the following notation:
(* Hacky-way to create parenthesis *)
MakeBoxes[Parenthesis[a_], _] := MakeBoxes[a.1][[1, 1]]
MakeBoxes[grad[a_], form:TraditionalForm] := TemplateBox[{MakeBoxes@Parenthesis@a}, "grad", Tooltip -> Automatic,
DisplayFunction :> (RowBox@{"\[Del]", #1} &)]
MakeBoxes[div[a_], form:TraditionalForm] := TemplateBox[{MakeBoxes@Parenthesis@a}, "div", Tooltip -> Automatic,
DisplayFunction :> (RowBox@{"\[Del]\[CenterDot]", #1} &)]
MakeBoxes[curl[a_], form:TraditionalForm] := TemplateBox[{MakeBoxes@Parenthesis@a}, "curl", Tooltip -> Automatic,
DisplayFunction :> (RowBox@{"\[Del]\[Cross]", #1} &)]
MakeBoxes[DotNabla[a_, b_], form:TraditionalForm] := TemplateBox[{MakeBoxes@Parenthesis@a, MakeBoxes@Parenthesis@b}, "DotNabla", Tooltip -> Automatic,
DisplayFunction :> (RowBox@{"(", #1, "\[CenterDot]\[Del]", ")", #2} &)]
MakeBoxes[Delta[a_], form:TraditionalForm] := TemplateBox[{MakeBoxes@Parenthesis@a}, "Delta", Tooltip -> Automatic,
DisplayFunction :> (RowBox@{"\[Delta]", #1} &)]
And now for the most important part of the code, the function ExpandDerivative, which as the name suggest, expand the derivative-like functions:
(* Expand Derivatives/Vectors/Tensors on expr and apply custom rules *)
ExpandDerivative[expr_, rules_:{}] := expr //. Flatten@{
(* Custom Rules *)
rules,
(* Linearity *)
(op:grad|div|curl|Delta|Inactive[grad]|Inactive[div]|Inactive[curl]|Inactive[Delta]|Re|Im|Conjugate)[a_ + b__] :> op@a + op[+b],
(op:Dp|Inactive[Dp]|Sum|Inactive[Sum])[a_ + b__, arg__] :> op[a, arg] + op[+b, arg],
(op:Times|Dot|TensorProduct|Cross|DotNabla|Inactive[DotNabla])[a___, b_ + c__, d___] :> op[a, b, d] + op[a, +c, d],
(op:grad|div|curl|Delta|Inactive[grad]|Inactive[div]|Inactive[curl]|Inactive[Delta]|Re|Im|Conjugate)[(op\[CapitalSigma]:Sum|Inactive[Sum])[a_, args__]] :> op\[CapitalSigma][op@a, args],
(* Sum *)
(op:Sum|Inactive[Sum])[s_*a_, v_Symbol] /; FreeQ[s, v] :> s*op[a, v],
(op:Sum|Inactive[Sum])[s_, v_Symbol] /; FreeQ[s, v] :> s*op[1, v],
(* Complexes *)
Conjugate@(op:Times|Dot|Cross|TensorProduct)[a_, b__] :> op[Conjugate@a, Conjugate@op@b], (* Pass Conjugate to child *)
(op:grad|div|curl|Delta|Inactive[grad]|Inactive[div]|Inactive[curl]|Inactive[Delta])[(opC:Re|Im|Conjugate)[a_]] :> opC@op@a, (* Pass Conjugate/Re/Im to parent *)
Dp[(op:Re|Im|Conjugate)[a_], v_] :> op@Dp[a, v], (* Pass Conjugate/Re/Im to parent *)
(* Triple Product *)
Cross[a_?VectorQ, Cross[b_?VectorQ, c_?VectorQ]] :> b*a.c - c*a.b,
Cross[Cross[a_?VectorQ, b_?VectorQ], c_?VectorQ] :> b*a.c - a*b.c,
(* Quadruple Product *)
Dot[Cross[a_?VectorQ, b_?VectorQ], Cross[c_?VectorQ, d_?VectorQ]] :> (a.c)*(b.d) - (a.d)*(b.c),
(* Second Derivatives *)
div@curl[_?VectorQ] :> 0,
curl@grad[_?ScalarQ | _?VectorQ] :> 0,
(* grad *)
grad[(s_?ScalarQ) * (b_)] :> s*grad@b + b\[TensorProduct]grad@s,
grad[(a_?VectorQ) . (b_?VectorQ)] :> a\[Cross]curl@b + b\[Cross]curl@a + DotNabla[a, b] + DotNabla[b, a], (* Use physics form *)
grad[(s_?ScalarQ) ^ (n_?ConstantQ)] :> n*s^(n-1)*grad@s,
grad[(n_?ConstantQ /; ScalarQ@n) ^ (s_?ScalarQ)] :> n^s*Log[n]*grad@s,
(* div *)
div[(s_?ScalarQ) * (b_?TensorQ)] :> s*div@b + b.grad@s,
div[(a_?VectorQ) \[TensorProduct] (b_?VectorQ)] :> DotNabla[b, a] + a*div@b,
div[(a_?VectorQ) \[Cross] (b_?VectorQ)] :> b.curl@a - a.curl@b,
(* curl *)
curl[(s_?ScalarQ) * (b_?VectorQ)] :> grad[s]\[Cross]b + s*curl@b,
curl[(a_?VectorQ) \[Cross] (b_?VectorQ)] :> div[a\[TensorProduct]b - b\[TensorProduct]a],
(* DotNabla *)
DotNabla[(s_?ScalarQ) * (b_?VectorQ), c_?VectorQ] :> s*DotNabla[b, c],
DotNabla[a_?VectorQ, (\[Beta]_?ScalarQ)*(c_?VectorQ)] :> c*a.grad@\[Beta] + \[Beta]*DotNabla[a, c],
(* Dp *)
Dp[(op:Times|Dot|Cross|TensorProduct)[a_, b__], v_Symbol] :> op[Dp[a, v], b] + op[a, Dp[op@b, v]],
Dp[Power[a_?ScalarQ, b_?ScalarQ], v_Symbol] :> Power[a, b-1]*b*Dp[a, v] + Power[a,b]*Log[a]*Dp[b, v],
(* Delta *)
Delta[(op:Times|Dot|Cross|TensorProduct)[a_, b__]] :> op[Delta@a, b] + op[a, Delta@op@b],
Delta@Power[a_?ScalarQ, b_?ScalarQ] :> Power[a, b-1]*b*Delta[a] + Power[a,b]*Log[a]*Delta[b]
}
Some examples. Calculating the divergent of Maxwell Stress Tensor in vaccum:
![MST][7]
Calculate the Einstein-Laub force density for linear dielectrics:
![EL][8]
Testing Poynting theorem in vaccum (no sources):
![P][9]
Where the first argument is the quantity being "tested".
Many other uses are possible and is fairly easy to extended some definitions.
[1]: http://library.wolfram.com/infocenter/Demos/434/
[2]: http://library.wolfram.com/infocenter/MathSource/8827/
[3]: https://sites.math.washington.edu/~lee/Ricci/
[4]: http://www.stargazing.net/yizen/Tensoria.html
[5]: http://www.vaudrevange.com/pascal/grt/
[6]: http://www.xact.es/
[7]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Fig1.png&userId=845022
[8]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Fig2.png&userId=845022
[9]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Fig3.png&userId=845022Thales Fernandes2017-06-23T22:49:11ZVisual Interface to the Wolfram Language
http://community.wolfram.com/groups/-/m/t/1124967
Hi everyone.
I'm working on a visual interface to the Wolfram Language called [visX][1], and I'd like to ask what you all think of it.
Wolfram Language code can often be thought of as a set of blocks, each of which takes some inputs, does something, and produces an output. VisX lets you write WL code exactly this way - you draw a digram, connecting blocks with links. For example, say you want to count how many times each digit (0 to 9) occurs in the first 30 digits of Pi. With text-based WL code, you'd write
digits = RealDigits[N[Pi, 30]][[1]]
Count[digits, #] & /@ Range[0, 9]
In visX, you'd draw this:
![digits of Pi][2]
I guess it's pretty self-explanatory. In addition to using built-in WL blocks, you can write your own, like the CountInList block. Normally, blocks just transform inputs to output, but the CountInList block is mapped over its input which is indicated by the little brackets on the outside of its connection ports. (That's basically visual syntactic sugar for "/@" or Map.) The 4 in the upper-right corner indicates that results inside this block are showing results from the 4-th time through the map. The block with "digits" in it sets a variable, which is then referenced in the CountInList block.
You define blocks (which are basically functions) by just making an empty rectangle and dragging contents in then wiring them together, then you can use copies of the block wherever you want. A change in any copy of the block will be reflected in all other copies. There's no real difference between a defining a block and using it. Recursion can be specified by just including a copy of the block inside itself. Blocks can call other blocks in the same manner.
Just like regular WL code, visX blocks can be nested deeply, but with the visual interface, it's easy to zoom in and out. At any point, the UI will show you the right amount of detail for each block - sometimes no detail at all, sometimes its name and labels on its inputs, sometimes its actual contents (which can then be edited or further zoomed...).
visX is stand-alone software that runs locally on your machine, evaluates the diagram using your local Mathematica kernel, and receives the results and puts them back in the diagram. You can load data files using Import as usual.
One of the problems that I've seen with visual languages in the past is that while simple things are easy to do, the code quickly gets too complex to manage and the visual interface starts to get in the way. With the Wolfram Language in theory everything is an expression, and this can lead you to write functional-style programs which are easily thought of as a diagram, but that's not always the most natural way to express a computation. Sometimes you just need a little for loop. Consider calculating Fibonacci numbers. Start the sequence with 1, 1, ... then each element of the sequence is the sum of the previous two. Yes, you can write a recursive algorithm to do this, but most people just want to write a little for loop. In visX, you can do this (calculates the 6th Fibonacci number):
![embedded code][4]
I've tried to let you use blocks-and-links when that's the most natural thing (which is usually), and text-based code when that's better. Of course, you can mix them together however you want.
A second problem I've found with visual programming languages is that it can actually be much slower to use then writing out text, because you have to laboriously drag and drop every single block. Even simple algebraic expressions like
Sin[x]^2 + Cos[x]^2
2x^2 + 4x*y + 8y^2
would involve a lot of blocks because of all the Plus, Times, and Power blocks, as well as all the constants and symbols. With visX, you can enter Wolfram Language code snippets like those, and it will parse them and transform them into blocks which you can then insert into your diagram all at once and edit at will. This makes it much faster to get your idea onto the screen so that you can start evaluating it and developing it. I'm also working on the ability to take a visX block and give you back the Wolfram Language code that it represents.
The examples given here are simple, but of course you can use this interface for putting together a complex piece of code as well. I find it especially handy when building up a calculation with lots of intermediate results along the way, or to rapidly prototype an algorithm where I want to be able to easily switch the data flows around.
Does this project seem useful to anyone? I'd like to get some feedback - what do you think of it? Would you use it? For what?
If there's interest, I could do a small-scale alpha test in about a month from now.
More info at [visx.io][5].
-Nicholas Hoff
*edited to clarify block definitions and recursion*
[1]: http://visx.io
[2]: http://community.wolfram.com//c/portal/getImageAttachment?filename=pi_digits_without_chrome.png&userId=1124239
[3]: http://community.wolfram.com//c/portal/getImageAttachment?filename=pi_digits.png&userId=1124239
[4]: http://community.wolfram.com//c/portal/getImageAttachment?filename=embeded_wl.png&userId=1124239
[5]: http://visx.ioNicholas Hoff2017-06-20T10:02:52ZPage breaks with writing assistant
http://community.wolfram.com/groups/-/m/t/1121632
I have a problem that I hope someone has a solution for. I'm using Writing Assistant to write a book in Mathematica. After selecting the page break button on Writing Assistant, I find that Mathematica inserts two page breaks at the start and end of the (hidden) cell. So when I print the document, it throws a whole blank page.
How do I ensure that only one page break is inserted?Jonathan Kinlay2017-06-16T17:26:25ZUsing Mathematica in Teaching Differential Equations
http://community.wolfram.com/groups/-/m/t/1124581
I am Brian Winkel, Professor Emeritus (civilian) United States Military Academy, West Point NY USA. I wish to contact colleagues who teach differential equations using or considering using modeling and technology.
I am currently the Director of SIMIODE-Systemic Initiative for Modeling Investigations and Opportunities with Differential Equations, an organization of teachers and students interested in teaching and learning differential equations by using modeling and technology throughout the process. Visit us at www.simiode.org.
We have designed a Student Competition Using Differential Equation Modeling – SCUDEM for April 2018 (see www.simiode.org/scudem for complete details) and invite schools to host SCUDEM (we have some 60 teams in the US already)and to consider sponsoring a team.
SIMIODE is a 501(c)3 organization and all its resources are freely available under the most generous Creative Commons license. Visit us at www.simiode.org and join. All is FREE at SIMIODE.
![SCUDEM 2018 local site locations in the United States as of 16 June 2017][1]
[1]: http://community.wolfram.com//c/portal/getImageAttachment?filename=SCUDEMSitesMap.jpg&userId=1124219Brian Winkel2017-06-19T23:12:18ZCDF templates for creating textbook notes?
http://community.wolfram.com/groups/-/m/t/1109137
I purchased the license for Mathematica 11 and got it installed this week, So far I'm having a great learning experience with it. One of the most highlights of purchasing Mathematica was CDF documentation . I would like to create notes on textbooks by using the exact same feature as shown on this website: [Link][1].
Is this a template created by Mathematica, how do I go about creating a CDF such as this for a textbook I am learning.
[1]: http://www.wolfram.com/cdf/uses-examples/textbooks.htmlAbhilash Sukumari2017-05-26T19:18:21Z