Plotting a function as a function of another function in Mathematica - function

I wasn't entirely sure what to search for, so if this question has been asked before, I apologize in advance:
I have two functions
R := Rref*mx(mx^(4/3) - C0)^(-1)
M := Mref*(mx + C1*mx^(-1)*((1 - C0*mx^(-4/3))^(-3) - 1))
where Rref, Mref, C0 and C1 are constants and mx is the variable. I need to plot R as a function of M. Surely there must be something available in Mathematica to do such a plot - I just can't seem to find it.

The comment is correct, in that what you have is a set of two "parametric equations". You would use the ParametricPlot command. However, the syntax of functions with parameters is sometimes tricky, so let me give you my best recommendation:
R[Rref_, C0_, C1_][mx_] = Rref*mx (mx^(4/3) - C0)^(-1);
M[Mref_, C0_, C1_][mx_] = Mref*(mx + C1*mx^(-1)*((1 - C0*mx^(-4/3))^(-3) - 1));
I like that notation better because you can do things like derivatives:
R[Rref,C0,C1]'[mx]
(* Output: -((4 mx^(4/3) Rref)/(3 (-C0 + mx^(4/3))^2)) + Rref/(-C0 + mx^(4/3)) *)
Then you just plot the functions parametrically:
ParametricPlot[
{R[0.6, 0.3, 0.25][mx], M[0.2, 0.3, 0.25][mx]},
{mx, -10, 10},
PlotRange -> {{-10, 10}, {-10, 10}}
]
You can box this up in a Manipulate command to play with the parameters:
Manipulate[
ParametricPlot[
{R[Rref, C0, C1][mx], M[Mref, C0, C1][mx]},
{mx, -mmax, mmax},
PlotRange -> {{-10, 10}, {-10, 10}}
],
{Rref, 0, 1},
{Mref, 0, 1},
{C0, 0, 1},
{C1, 0, 1},
{mmax, 1, 10}
]
That should do it, I think.

Related

How to get Elixir AST from local function

I want to get the AST from a local function that is passed as an argument like doSomething(fn a -> a * 10 end)
So I tried
def test do
inspectAST(fn a,b -> a + b + 42 end)
inspectAST(quote do: fn a,b -> a + b + 42 end)
inspectFunctionInfo(fn a,b -> a + b + 42 end)
:ok
end
def inspectAST(this_is_AST) do
IO.inspect(this_is_AST)
IO.inspect("--------------------------------")
end
def inspectFunctionInfo(fun) do
IO.inspect(Function.info(fun))
IO.inspect("--------------------------------")
end
Results :
iex(3)> Utils.test
#Function<0.30424669/2 in Utils.test/0>
"--------------------------------"
{:fn, [],
[
{:->, [],
[
[{:a, [], Utils}, {:b, [], Utils}],
{:+, [context: Utils, import: Kernel],
[
{:+, [context: Utils, import: Kernel],
[{:a, [], Utils}, {:b, [], Utils}]},
42
]}
]}
]}
"--------------------------------"
[
pid: #PID<0.485.0>,
module: Utils,
new_index: 1,
new_uniq: <<58, 7, 203, 172, 99, 108, 54, 80, 24, 151, 75, 56, 73, 174, 138,
177>>,
index: 1,
uniq: 30424669,
name: :"-test/0-fun-1-",
arity: 2,
env: [],
type: :local
]
"--------------------------------"
What I want is the result from inspectAST(quote do: fn a,b -> a + b + 42 end) ( the AST ) but I would like to send the function like inspectAST(fn a,b -> a + b + 42 end) without the quote do:
If anyone has some idea about this, your help would be really appreciated :)
If you want a "function" to be called on the AST, not values, it should be a macro, not a function.
The following should be a good base for what you want to achieve:
defmacro inspectAST(ast) do
quote do
IO.inspect(unquote(Macro.escape(ast)))
:ok
end
end
def test do
inspectAST(fn a,b -> a + b + 42 end)
end
you need to use defmacro to treat your parameter as AST, not a regular value
we want IO.inspect to happen at runtime, not compile time, so we need to return the AST for it using quote
what we want to inspect is the content of the ast variable, so we are using unquote
but unquote will unescape ast as well, so we need to escape it once more using Macro.escape/2
Please note that the macro should be defined before calling it, so defmacro has to be before test, not after.
For more advanced explanations about macros, you should check this serie of articles which is very detailed.

Find all "pairing sets", such that all elements have a pair, and no pairs contain common elements

I am currently trying to solve the following problem.
I must find all pairs of a set (with even number of elements) such that:
No two pairs have common elements
All elements are in a pair
As an example:
pairingsSet({0, 1, 2, 3})
should return something like
{
{{0, 1}, {2, 3}},
{{0, 2}, {1, 3}},
{{0, 3}, {1, 2}},
}
And a more verbose example:
pairingsSet({0, 1, 2, 3, 4, 5})
should return something like
{
{{0, 1}, {2, 3}, {4, 5}},
{{0, 1}, {2, 4}, {3, 5}},
{{0, 1}, {2, 5}, {3, 4}},
{{0, 2}, {1, 3}, {4, 5}},
{{0, 2}, {1, 4}, {3, 5}},
...
{{0, 5}, {1, 3}, {2, 4}},
{{0, 5}, {1, 4}, {2, 3}},
}
I can tell that the easiest way to solve this problem is with recursion, but I can't quite get my finger on how to do it.
I ordered the sets above because it helped me think of a solution, but the order does not matter. I still can't quite put my finger on a solution. I will likely be figuring out the answer soon, I made this question in case anyone else encountered a similar problem. If anyone figures out an alternative answer though, I would love to see it!
(I am currently working on a solution in Go although solutions in other languages are very much welcome)
Here is my solution in Go:
func allPairingSetsForAlphabet(alphabet []int) [][][2]int {
if len(alphabet) == 2 {
return [][][2]int{{{alphabet[0], alphabet[1]}}}
}
first := alphabet[0]
rest := alphabet[1:]
var pairingsSet [][][2]int
for i, v := range rest {
pair := [2]int{first, v}
withoutV := make([]int, len(rest)-1)
copy(withoutV[:i], rest[:i])
copy(withoutV[i:], rest[i+1:])
// recursive call
otherPairingsSet := allPairingSetsForAlphabet(withoutV)
for _, otherPairings := range otherPairingsSet {
thisPairing := make([][2]int, len(otherPairings)+1)
thisPairing[0] = pair
copy(thisPairing[1:], otherPairings)
pairingsSet = append(pairingsSet, thisPairing)
}
}
return pairingsSet
}
Essentially it performs the following steps:
If there are only two remaining things in the alphabet, we return a pairing set containing only those two pairs (ie {{{0, 1}}})
Pick an element (we will call it first)
Makes a new set which contains all elements of the alphabet, without first (we will call this rest)
For each element (v) in rest, we:
Make a pair of {first, v} (we will call this pair)
Create a subset of rest which contains all elements in rest except v (we will call this withoutV)
We make a recursive call, allPairingsForAlphabet(withoutV)
For each pairing (pairing) that this call returns, we add {pair} U pairing to the result.

Mathematica: Plotting a module with FindRoot in it

I run into this problem occasionally, and I haven't found a way around it.
It usually happens when I'm finding the root of an equation, and want to maximize/minimize/plot that root according to some parameter. So I try to wrap the the code in a module so it can all be executed with just an input number, but it won't work inside functions like Plot.
For example:
f[din_] := Module[{d = din},
sol = NDSolve[{y'[x] == y[x], y[0] == 1}, y[x], {x, 0, 10}];
t1 = Flatten[FindRoot[y[x] - d /. sol, {x, 1}]];
x /. t1
]
f[2]
f[2.5]
f[3]
Plot[f[x], {x, 2, 3}]
The calls to f with a number all work as expected, but the f in the Plot function seems to be evaluated with the symbol 'x' - or something and just gives a lot of error text.
Any way around this?
Looking around the forums I found some suggestions for similar problems - like making the definition like this:
f[din_?NumericQ]:=
and I tried everything I could but nothing seems to make a difference.
I'm using Mathematica 8.0
The main fix is to take the sol = NDSolve[... out of the module. The module itself can also be simplified as shown:-
sol = NDSolve[{y'[x] == y[x], y[0] == 1}, y[x], {x, 0, 10}];
f[din_] := x /. FindRoot[y[x] - din /. sol, {x, 1}]
Plot[f[x], {x, 2, 3}]
Try :
f[din_?NumericQ] := Module[{LocalDummy, Localy, LocalSol},
Localy = y /. NDSolve[{y'[LocalDummy] == y[LocalDummy], y[0] == 1}, y, {LocalDummy, 0, 10}][[1]];
LocalSol = FindRoot[Localy[LocalDummy] - din == 0, {LocalDummy, 1}][[1, 2]] ]

How do I plot a function and data in Mathematica?

Simple question but I can't find the answer.
I want to combine a ListLinePlot and a regular Plot (of a function) onto one plot. How do I do this?
Thanks.
Use Show, e.g.
Show[Plot[x^2, {x, 0, 3.5}], ListPlot[{1, 4, 9}]]
Note, if plot options conflict Show uses the first plot's option, unless the option is specified in Show. I.e.
Show[Plot[x^2, {x, 0, 3.5}, ImageSize -> 100],
ListPlot[{1, 4, 9}, ImageSize -> 400]]
shows a combined plot of size 100.
Show[Plot[x^2, {x, 0, 3.5}, ImageSize -> 100],
ListPlot[{1, 4, 9}, ImageSize -> 400], ImageSize -> 300]
Shows a combined plot of size 300.
An alternative to using Show and combining two separate plots, is to use Epilog to add the data points to the main plot. For example:
data = Table[{i, Sin[i] + .1 RandomReal[]}, {i, 0, 10, .5}];
Plot[Sin[x], {x, 0, 10}, Epilog -> Point[data], PlotRange -> All]
or
Plot[Sin[x], {x, 0, 10}, Epilog -> Line[data], PlotRange -> All]

Mathematica NDSolve: Is there a way to have variable coefficients?

Is there a way in mathematica to have variable coefficients for NDSolve? I need to vary the coefficient values and create multiple graphs, but I cannot figure out a way to do it short of reentering the entire expression for every graph. Here is an example (non-functional) of what I would like to do; hopefully it is close to working:
X[\[CapitalDelta]_, \[CapitalOmega]_, \[CapitalGamma]_] =
NDSolve[{\[Rho]eg'[t] ==
(I*\[CapitalDelta] - .5*\[CapitalGamma])*\[Rho]eg[t] -
I*.5*\[CapitalOmega]*\[Rho]ee[t] +
I*.5*\[CapitalOmega]*\[Rho]gg[t],
\[Rho]ge'[t] == (-I*\[CapitalDelta] - .5*\[CapitalGamma])*\[Rho]ge[t] +
I*.5*\[CapitalOmega]\[Conjugate]*\[Rho]ee[t] -
I*.5*\[CapitalOmega]\[Conjugate]*\[Rho]gg[t],
\[Rho]ee'[t] == -I*.5*\[CapitalOmega]\[Conjugate]*\[Rho]eg[t] +
I*.5*\[CapitalOmega]*\[Rho]ge[t] - \[CapitalGamma]*\[Rho]ee[t],
\[Rho]gg'[t] == I*.5*\[CapitalOmega]\[Conjugate]*\[Rho]eg[t] -
I*.5*\[CapitalOmega]*\[Rho]ge[t] + \[CapitalGamma]*\[Rho]ee[t],
\[Rho]ee[0] == 0, \[Rho]gg[0] == 1, \[Rho]ge[0] == 0, \[Rho]eg[0] == 0},
{\[Rho]ee, \[Rho]eg, \[Rho]ge, \[Rho]gg}, {t, 0, 12}];
Plot[Evaluate[\[Rho]ee[t] /. X[5, 2, 6]], {t, 0, 10},PlotRange -> {0, 1}]
In this way I would only have to re-call the plot command with inputs for the coefficients, rather than re-enter the entire sequence over and over. That would make things much cleaner.
PS: Apologies for the awful looking code. I never realized until now that mathematica didn't keep the character conversions.
EDIT a nicer formatted version:
You should just use SetDelayed (":=") instead of Set in the function definition:
X[\[CapitalDelta]_, \[CapitalOmega]_, \[CapitalGamma]_] :=
NDSolve[{\[Rho]eg'[
t] == (I*\[CapitalDelta] - .5*\[CapitalGamma])*\[Rho]eg[t] -
I*.5*\[CapitalOmega]*\[Rho]ee[t] +
I*.5*\[CapitalOmega]*\[Rho]gg[t], \[Rho]ge'[
t] == (-I*\[CapitalDelta] - .5*\[CapitalGamma])*\[Rho]ge[t] +
I*.5*\[CapitalOmega]\[Conjugate]*\[Rho]ee[t] -
I*.5*\[CapitalOmega]\[Conjugate]*\[Rho]gg[t], \[Rho]ee'[
t] == -I*.5*\[CapitalOmega]\[Conjugate]*\[Rho]eg[t] +
I*.5*\[CapitalOmega]*\[Rho]ge[t] - \[CapitalGamma]*\[Rho]ee[
t], \[Rho]gg'[t] ==
I*.5*\[CapitalOmega]\[Conjugate]*\[Rho]eg[t] -
I*.5*\[CapitalOmega]*\[Rho]ge[t] + \[CapitalGamma]*\[Rho]ee[
t], \[Rho]ee[0] == 0, \[Rho]gg[0] == 1, \[Rho]ge[0] ==
0, \[Rho]eg[0] ==
0}, {\[Rho]ee, \[Rho]eg, \[Rho]ge, \[Rho]gg}, {t, 0, 12}];
Plot[Evaluate[{\[Rho]ee[t] /. X[5, 2, 6], \[Rho]ee[t] /.
X[2, 6, 17]}], {t, 0, 10}, PlotRange -> {0, 1}]