Plot functions with different domains in Maxima - plot

What is the best way of plotting several functions with different domains into the same plot? Is there a way to do this with plot2d, or do I have to use draw2d instead?
I especially like the possibility in plot2d to give several functions in a list, whereas I would have to add the different functions in draw2d as separate parameters, if I understand the documentation correctly.
An example of what I mean:
f(x, a) := sqrt(a) * exp(-(x-a)^2);
fmax(x) := sqrt(x);
In this example I would like to plot f(x, a) for several a (e.g. using makelist(f(x, a), a, [0, 0.5, 1, 2, 5])) from -1 to 10 and fmax from 0 to 5 (to show where the maxima of the f(x, a) family of curves are located).

You can try draw2d
f(x, a) := sqrt(a) * exp(-(x-a)^2);
fmax(x) := sqrt(x);
flist: makelist(f(x, a), a, [0, 0.5, 1, 2, 5]);
par: map(lambda([f], explicit(f, x, -1, 10)), flist);
par: append([explicit(fmax, x, 0, 5), color=red], par);
load(draw);
apply(draw2d, par);

One approach I am not particularly happy with is to declare the functions with smaller domains as parametric curves, with the x axis parameter being simply x:
f(x, a) := sqrt(a) * exp(-(x-a)^2);
fmax(x) := sqrt(x);
plot2d(endcons([parametric, x, fmax(x), [x, 0, 5], [nticks, 80]],
makelist(f(x, a), a, [0, 1/2, 1, 2, 5])),
[x, -1, 10]);

This was frustrating me for hours but I found a way to have multiple differently domained functions on the same graph.
wxplot2d([if x < 0 then -x else sin(x), if x > -1 then x^2],[x,-%pi,%pi],[y,-2,2]);

Related

Artifacts in DensityPlot (Wolfram Mathematica)

I am trying to visualize the result of numerical integration in Wolfram Mathematica using DensityPlot. But dark artifacts appear inside the circle on the graph, this is incorrect. How to fix this?
f[u_, v_]:=(1/1.2)*(1/(3.14159*0.02^2)*E^(-((x-u)^2+(y-v)^2)/0.02^2)+0.2/(3.14159*2^2)*E^(-((x-u)^2+(y-v)^2)/2^2));
i[x_, y_]:=NIntegrate[f[u, v],{u, v} \[Element] Disk[{0,0},2.5], AccuracyGoal -> 30];
DensityPlot[i[x, y], {x, -3, 3}, {y, -3, 3},ColorFunction->"SunsetColors",PlotPoints -> 20, PlotLegends -> Automatic]
Link to the image: https://postimg.cc/47MJTYj7
Well, that is not an artifact, or is it. First I'd like to point out that f is a function of u, v, x and y. So the way it is programmed is not very clean. Now to the main problem. There are two Gaussian peaks. One is very broad, the other very sharp. In many cases the numerical integral just does not get points near the sharp peak, therefore not detecting it. As the rest is smooth and easy, no subset is generated and the integral is just missing this contribution. Luckily, there is an option specifically for this. MinRecursion: NIntegrate may miss sharp peaks of integrands:.... So this works
g[x_, y_, s_] := Exp[ -( x^2 + y^2 ) / s^2] / (s^2 Pi)
f[x_, y_, u_, v_] := g[ x - u, y - v, 0.02 ] / 1.2 + 0.2 g[ x - u, y - v, 2 ]
i[x_, y_] := NIntegrate[ f[x, y, u, v], {u, v} \[Element] Disk[{0, 0}, 2.5], MinRecursion -> 5]
nn = 30;
t = Table[i[x, y], {x, -3, 3, 6/nn}, {y, -3, 3, 6/nn}];
ListDensityPlot[t, ColorFunction -> "SunsetColors", PlotLegends -> Automatic]
Takes quite some time, though. Probably, it would be better to split this up in two integrals and invest some thought on the integration boundaries.

Mathematica - export multiple plots, each with different name (depending on variables used in plot)

I'm new to Mathematica. I'm trying to produce whole lotta plots, but I don't know how to make Mathematica name them after variables. Here for example I have code producing sine plots for different coefficients infront of x variable:
d = 2;
For[n = 1, n <= 3, n = n + 1, {Do[Print[Plot[Sin[n*x] + d, {x, 0, 6 Pi}]]], Export["E:\\plots\\a.pdf", Plot[Sin[n*x] + d, {x, 0, 6 Pi}]]}]
And in program it produces 3 plots, and each time each plot is exported to a.pdf. Sadly every next time it is overwritten, so I end up with single a.pdf plot when n = 3.
Here is what I would like to achieve. After running program it would produce me 3 plots of names:
S, n=1, d=2.pdf
S, n=2, d=2.pdf
S, n=3, d=2.pdf
or
S n1 d2.pdf
S n2 d2.pdf
S n3 d2.pdf
Something like this perhaps ?
Do[Export["Plot" <> ToString[n] <> "_" <> ToString[d] <> ".pdf",
Plot[Sin[n*x] + d, {x, 0, 6 Pi}]], {n, 1, 3}]
You'll probably want to adjust the file names.

Walking through multidimensional space in a proper way

Assuming I have a vector of say four dimensions in which every variable lays in a special interval. Thus we got:
Vector k = (x1,x2,x3,x4) with x1 = (-2,2), x2 = (0,2), x3 = (-4,1), x4 = (-1,1)
I am only interested in the points constraint by the intervals.
So to say v1 = (0,1,2,0) is important where v2 = (-5,-5,5,5) is not.
In additon to that the point i+1 should be relatively close to point i among my journey. Therefore I dont want to jump around in space.
Is there a proper way of walking through those interesting points?
For example in 2D space with x1,x2 = (-2,2) like so:
Note: The frequenz of the red line could be higher
There are many ways to create a space-filling curve while preserving closeness. See the Wikipedia article for a few examples (some have associated algorithms for generating them): https://en.wikipedia.org/wiki/Space-filling_curve
Regardless, let's work with your zig-zag pattern for 2D and work on extending it to 3D and 4D. To extend it into 3D, we just add another zig to the zig-zag. Take a look at the (rough) diagram below:
Essentially, we repeat the pattern that we had in 2D but we now have multiple layers that represent the third dimension. The extra zig that we need to add is the switch between bottom-to-top and top-to-bottom every layer. This is pretty simple to abstract:
In 2D, we have x and y axes.
We move across the x domain switching between positive and negative
directions most frequently.
We move across the y domain once.
In 3D, we have x, y, and z axes.
We move across the x domain switching between positive and negative directions most frequently.
We move across the y domain switching between positive and negative directions second most frequently.
We move across the z domain once.
It should be clear how this generalizes to higher dimensions. Now, I'll present some (Python 3) code that implements the zig-zag pattern for 4D. Let's represent the position in 4D space as (x, y, z, w) and the ranges in each dimension as (x0, x1), (y0, y1), (z0, z1), (w0, w1). These are our inputs. Then, we also define xdir, ydir, and zdir to keep track of the direction of the zig-zag.
x, y, z, w = x0, y0, z0, w0
xdir, ydir, zdir = +1, +1, +1
for iw in range(w1 - w0):
for iz in range(z1 - z0):
for iy in range(y1 - y0):
for ix in range(x1 - x0):
print(x, y, z, w)
x = x + xdir
xdir = -xdir
print(x, y, z, w)
y = y + ydir
ydir = -ydir
print(x, y, z, w)
z = z + zdir
zdir = -zdir
print(x, y, z, w)
w = w + 1
This algorithm has the guarantee that no two points printed out after each other have a distance greater than 1.
Using recursion, you can clean this up to make a very nice generalizable method. I hope this helps; let me know if you have any questions.
With the work of #Matthew Miller I implemented this generalization for any given multidimenisonal space:
'''assuming that we take three points out of our intervals [0,2] for a,b,c
which every one of them is corresponding to one dimension i.e. a 3D-space'''
a = [0,1,2]
b = [0,1,2]
c = [0,1,2]
vec_in = []
vec_in.append(a)
vec_in.append(b)
vec_in.append(c)
result = []
hold = []
dir = [False] * len(vec_in)
def create_points(vec , index, temp, desc):
if (desc):
loop_x = len(vec[index])-1
loop_y = -1
loop_z = -1
else:
loop_x = 0
loop_y = len(vec[index])
loop_z = 1
for i in range(loop_x,loop_y,loop_z):
temp.append(vec[index][i])
if (index < (len(vec) - 1)):
create_points(vec, index + 1, temp, dir[index])
else:
u = []
for k in temp:
u.append(k)
result.append(u)
temp.pop()
if (dir[index] == False):
dir[index] = True
else:
dir[index] = False
if len(temp) != 0:
temp.pop()
#render
create_points(vec_in, 0, hold, dir[0])
for x in (result):
print(x)
The result is a journey which covers every possible postion in a continous way:
[0, 0, 0]
[0, 0, 1]
[0, 0, 2]
[0, 1, 2]
[0, 1, 1]
[0, 1, 0]
[0, 2, 0]
[0, 2, 1]
[0, 2, 2]
[1, 2, 2]
[1, 2, 1]
[1, 2, 0]
[1, 1, 0]
[1, 1, 1]
[1, 1, 2]
[1, 0, 2]
[1, 0, 1]
[1, 0, 0]
[2, 0, 0]
[2, 0, 1]
[2, 0, 2]
[2, 1, 2]
[2, 1, 1]
[2, 1, 0]
[2, 2, 0]
[2, 2, 1]
[2, 2, 2]

How to get a linsolve solution in matrix form?

Im using SymPy in Julia. My purpose is to solve a homogeneous system of linear equations (Ax=0) with more unknowns than variables (A is not square).
Then, Im using the following code.
using SymPy
x, y, z, w = symbols("x y z w")
M = sympy.Matrix(((9, 2, 1,- 4, 0), (-4, -3, -1, -5, 0)))
s = linsolve(M, (x, y, z, w))
With this code Im able to get the correct solution. However, I´dont known how to manipulate that solution.
The final goal is to be able to get the solution in matrix form as lines representing (x and y) and column (z and w). (since x(z, w) and y(z,w)).
Thanks
If numerical (rather than symbolic) computations are acceptable, then this will get the job done:
julia> using LinearAlgebra
julia> M = rand(2,4)
2×4 Array{Float64,2}:
0.497965 0.704514 0.152799 0.69448
0.594486 0.695488 0.327688 0.710573
julia> Q,R = qr(M);
C = -R[1:2,1:2]\R[1:2,3:4]
xy(zw) = C*zw;
# Check that `[xy(zw); zw]` is indeed in the nullspace of `M`:
julia> zw = rand(2)
M*[xy(zw);zw]
2-element Array{Float64,1}:
-2.7755575615628914e-17
-1.1102230246251565e-16

Numerical Solution for a specified parameter in NDSolve (Mathematica)

I am working on a solution to solve a Partial Differential Equation, Fick's Second Law of Diffusion to be exact.
I was able to produce a 3D Plot using the NDSolve and Plot3D functions.
Code used:
NDSolve[{D[c[t, h], t] == 1*D[c[t, h], h, h],
c[0, h] == Erfc[h/(2*81.2)],
c[t, 0] == 1,
c[t, 4000] == 3.08*^-18}, c, {t, 0, 900}, {h, 0, 274}]
Instead of a graphical representation, I would like to find numerical points of the graph at t = 900.
I would like to know how to put in t = 900 into NDSolve (or other functions) so as to generate detailed numerical points of the solution.
Try saving the solution in a variable first:
e = NDSolve[{D[c[t, h], t] == 1*D[c[t, h], h, h], c[0, h] == Erfc[h/(2*81.2)], c[t, 0] == 1, c[t, 4000] == 3.08*^-18}, c, {t, 0, 900}, {h, 0, 274}]
Then we can Evaluate this expression for our desired variables:
Evaluate[c[900, 10] /. e]
(*{0.914014}*)
Or to make it more versatile, we can use Manipulate:
Manipulate[Evaluate[c[t, h] /. e], {t, 0, 900}, {h, 0, 274}]
Update:
Considering the information I received from the comments below; we can define a function like q[t,h] which will give us the solution as a function:
q[t_, h_] := Evaluate[c[t, h] /. e]
q[900, 10]
(*{0.914014}*)

Resources