50
Update 2015-7-13: PlotPiecewise now handles discontinuities of non-Piecewise functions. (It basically did this before, but required the head to be Piecewise or contain a built-in discontinuous function, like Sign. All I did was brainlessly wrap a function in Piecewise. I also had to rewrite some of the Reduce/PiecewiseExpand code. One of the more ...
27
Here's an alternative approach than Spartacus' answer. What he did is splitting up the piecewise function into many different functions valid in only a small domain; what I am doing here is directly plotting the piecewise function as given, while the coloring is done using ColorFunction.
I'll use the same function as Spartacus,
f = Piecewise[{{#^2, # <= ...
22
Here is the example from the documentation adapted for the OP's data:
data = MapIndexed[
Flatten[{#2, #1}] &,
{2, 5, 9, 15, 22, 33, 50, 70, 100, 145, 200, 280, 375, 495, 635, 800,
1000, 1300, 1600, 2000, 2450, 3050, 3750, 4600, 5650, 6950}];
f = Interpolation@data
(* InterpolatingFunction[{{1, 26}}, <>] *)
pwf = Piecewise[
Map[{...
19
Mathematica even leaves a gap when the expressions in Piecewise are equal, as long as Mathematica doesn't see the equality. Very simple example
test[x_] := Piecewise[{{x, x >= 1}, {Sqrt[x^2], x < 1}}]
Plot[test[x], {x, 0, 2}, PlotStyle -> Thick]
When you replace Sqrt[x^2] by x, no gap.
What you have to understand is that the cracks are ...
18
Here is one method, now more robust:
pwSplit[_[pairs : {{_, _} ..}]] := Piecewise[{#}, Indeterminate] & /@ pairs
pwSplit[_[pairs : {{_, _} ..}, expr_]] :=
Append[pwSplit@{pairs}, pwSplit@{{{expr, Nor @@ pairs[[All, 2]]}}}]
Testing:
pw = Piecewise[{{x^2, x < 0}, {x, 2 > x > 0}, {Log[x], x > 2}}];
Plot[Evaluate[pwSplit@pw], {x, -2, 4}, ...
answered Feb 1 '12 at 19:58
17
It looks like Plot is kind enough to split a plot of a Piecewise function in separate Line objects, so you could do something like
pl = Plot[Piecewise[{{x^2, x < 0}, {x, 2 > x > 0}, {Log[x], 3 > x > 0}}],
{x, -2, 4}];
lines = Cases[pl, _Line, Infinity];
Graphics[Transpose[{Array[ColorData[1], Length[lines]], lines}], Axes -> True]
17
There is no documented built-in way to convert the InterpolatingFunction object into explicit Piecewise form (thanks to @MichaelE2 for the link!). So the only possibility to get an explicit interpolating function is to re-implement the built-in Interpolation in the high-level Mathematica language. I have already done this for the built-in "Spline" method ...
answered Sep 18 '14 at 0:36
Alexey Popkov
48.2k44 gold badges118118 silver badges282282 bronze badges
15
That conversion is straightforward, in this case. It is a one-liner
Piecewise[List @@@ Flatten[N@ftz][[All, 2]] ]
Now let me explain. As you have noticed, Solve returns solutions of the form:
{ {_ -> _}, {_ -> _}, ...}
which is what Flatten reduces to
{_ -> _, _ -> _, ...}
Then, I take only the right hand side of each Rule via Flatten[...][...
15
l = {0, 2, 5, 9, 14};
a0 = Total[UnitStep[t - l]] - 1;
Plot[a0, {t, First[l], Last[l]}, Exclusions -> None, Frame -> True,
PlotStyle -> {Directive[Red, Thick]}]
14
Let us look at what happens a bit and start with your first question (title):
"Piecewise imposes internal boundaries in NDSolve - is this expected"
Yes, that is expected if the function introduces a discontinuity in one of the coefficients and the spatial discretization method is the finite element method (FEM). The FEM will produce better results if the ...
14
Important Update
Through a copy-paste mistake, I dropped the temperature dependence on the effective heat capacity, which was the point of the exercise. I have modified the post to correct that mistake.
Update #2
The difference between liquid and solid thermal conductivity can be quite large (4x for water), so I added support for the temperature dependent ...
13
Update:
To overcome the issue I mention in the comment, also to make it more general, here is an upgraded version, which can deal with clipping and pointwise exclusion, and preserve styles specified in the original plot.
The main function is this discontinuousHighlighter:
Clear[discontinuousHighlighter]
discontinuousHighlighter[origplot_, {excluMarker_, ...
13
As usual, it's a matter of choosing a better starting values for the parameters.
I started writing this answer before the data file was uploaded, so here's some synthetic data:
data = Table[
Interpolation[{{0, 1.1*^-6}, {200, 1.1*^-6}, {250, 9.5*^-7}, {500,
9.5*^-7}}, x, InterpolationOrder -> 1] +
2*^-8 RandomVariate[NormalDistribution[]]...
13
A drawback of the Which command is that it evaluates x repeatedly until one of the conditions of Which is satisfied. This is time consuming when x is a complicated expression or/and when the set of conditions is large.
This is not true in Compile as x will always be a number or an array. Multiple uses of x won't slow anything down.
It isn't even true ...
answered Sep 28 '16 at 12:12
Szabolcs
194k1818 gold badges481481 silver badges10181018 bronze badges
13
That $F$ should really be something like $F_n$, defining a family of functions and then your total $F$ would really be the union of the $\{F_n\}$ over the domains where they are non-zero.
Then unless I am much mistaken each of those domains will have length $2$ and so we can define your family of functions as you had above and then have a dispatcher ...
13
f[x_] := Min[x - Quotient[x, 2], Quotient[x + 2, 2]]
Plot[f[x], {x, 0, 20}]
12
Here's another quick way to visualize the support region:
RegionPlot[Or @@ g[x, y][[1, All, 2]] // Evaluate, {x, -0.5, 2.5}, {y, -0.5, 2.5}]
.
In some cases, one might want to run Reduce[] on the pile of constraints produced by Or @@ g[x, y][[1, All, 2]], before plotting, to reduce evaluation effort. (In this case, it did not do much, but it's a good idea ...
answered Jun 19 '13 at 10:25
12
You can force NDSolve to use the finite element method:
uif = NDSolveValue[{-u''[x] == UnitBox[(x - 0.5) 0.5/0.2], u[0] == 0,
u'[1] == 0}, u, {x, 0, 1},
Method -> {"PDEDiscretization" -> "FiniteElement"}];
Possibly, this might be the default.
In any case if you compare to the analytical solution:
aif = DSolveValue[{Rationalize[-u''[x] == ...
12
The undocumented function Internal`FromPiecewise seems to take a Piecewise function in the standard form returned by PiecewiseExpand and return a list consisting of a partition of the real numbers into intervals and a list of corresponding values.
try = {3 (1 - q), 2 (1 - q) + q, 1 + 1.5 q};
Internal`FromPiecewise@ PiecewiseExpand@ Min[try]
(* {{0.4 <= ...
answered Aug 14 '15 at 15:18
Michael E2
165k1313 gold badges222222 silver badges528528 bronze badges
11
The most direct way uses RegionPlot e.g.
RegionPlot[ g[x, y] > 0, {x, -0.5, 2.5}, {y, -0.5, 2.5}]
let's customize it a bit using colors from many possible ColorData["Gradients"]:
GraphicsRow[
RegionPlot[ g[x, y] > 0, {x, -0.5, 2.5}, {y, -0.5, 2.5},
ColorFunction -> Function[{x, y}, ColorData[#][Abs[g[x, y]]]],
...
11
I think this is a bug, because if we transform the Piecewise function into a combination of UnitStep (which is mathematically equivalent to the original function of course), Integrate integrates without difficulty:
um = -(2/3) - 2/(3 (-1 + u)) - (2 u)/3 + u^2/3;
up = -(10/3) - 2/(3 (-1 + u)) + (8 u)/3 - u^2/3;
sv = Simplify`PWToUnitStep@Piecewise[{{um, u &...
11
It does seem to be a bug. As a temporary workaround, you can re-express your function in terms of either UnitStep[] or Boole[], like so:
f[x_] = Dot @@ MapAt[Boole, Internal`FromPiecewise[
Piecewise[{{2 x - 3, x > 1}, {-x, -1 <= x <= 1}, {2 x + 3, x < -1}}]], 1]
StreamPlot[{y - f[x], -x}, {x, -5, 5}, {y, -5, 5}]
Note the use of the ...
answered Dec 13 '16 at 7:49
11
Summary: To perform the 3D Fourier Transform of a spherically symmetric function $f(r)$ in Mathematica, use the command
(4 Pi)/k FourierSinTransform[f[r] r, r, k]
(note the additional factor of $r$ in the function being transformed.)
This is a standard problem in scattering theory; one needs to find the transform of the electric potential of a ball of ...
10
Try using MeshShading:
Plot3D[
-(x - 12.5)^3,
{x, 0, 25},
{y, 0, 20},
MeshShading -> {Table[Hue[x], {x, 0, 1, 1/16}]}
]
The Table part generates sixteen different colors from the Hue color function. I did this because the image in this case had sixteen rows. If there are more rows than colors the colors will be reused cyclically.
10
I have been unsuccessful at getting the automatic discontinuity handling to work. (I get the errors "Failure to project onto the discontinuity surface when computing Filippov continuation".) But manually handling it with WhenEvent works, although it complains about slow convergence to the event locations. Perhaps the discontinuity conditions are too ...
9
Another option is to express Piecewise in terms of UnitStep.
In[1]:= f = Piecewise[{{x,3*x>y&&x<2*y},{y,2*x>y&&x<3*y}},0];
In[2]:= Simplify`PWToUnitStep[f]
Out[2]= x (1-UnitStep[x-2 y]) (1-UnitStep[-3 x+y])+
y ((1-UnitStep[x-3 y]) UnitStep[x-2 y] (1-UnitStep[-2 x+y])+(1-UnitStep[x-3 y])
UnitStep[-3 x+y] (1-...
9
Pretty cool example! I'm sure the following could be sped up a bit.
h[x_] = Piecewise[{{Exp[-1/(1 - (1 - 2 x)^2)], 0 < x < 1}}];
g[x_] := With[{n = Floor[x]}, h[n^2 (x - n)]];
f[x_?NumericQ] := NIntegrate[g[t], {t, 0, x}];
Plot[f[x], {x, 0, 8}]
A plot of $g(x)$ helps illustrate what's going on here as well.
Plot[g[x], {x, 0, 9.1},
PlotPoints ->...
9
Edit:
Using a helper function fh will result in no messages and no need to set extra options.
σ[t_] := 40000 Sin[0.02 t]
C1 = 80000;
C2 = 20000;
σgr = 15000;
fh[t_?NumericQ, x_, y_] := Piecewise[{{C1/(C1 + C2)*y,
(σ[t]*y > 0) && ((σ[t] - C2*x >= σgr) || (σ[t] - C2*x <= -σgr))}}, 0]
sol = NDSolve[{s[t] == σ[t]/C1 + sep[t], sep'[t] == fh[...
9
This particular ODE can be integrated by the somewhat cumbersome means,
s1 = Simplify@ExpToTrig@DSolve[{u1''[r] + k^2 u1[r] + v0 u1[r] == 0, u1[0] == 0}, u1[r],
r, Assumptions -> k^2 + v0 > 0][[1, 1]] /. C[1] -> -I c/2
s2 = First@FullSimplify@First@DSolve[{u2''[r] + k^2 u2[r] == 0,
u2[r0] == u1[r] /. s1 /. r -> r0, u2'[r0] == D[u1[r] /....
9
You can use the functions Simplify`PWToUnitStep and Simplify`SimplifyUnitStep to convert a Piecewise function to one using UnitStep:
s[t_] := Piecewise[{{1, t < 300.}, {0, 300. <= t < 1500.}, {1, t <= 3600}}];
s2[t_] := Simplify`SimplifyUnitStep[Simplify`PWToUnitStep[s@t]];
s2[t]
1 - UnitStep[-300. + t] + UnitStep[3600 - t, -1500. + t]
To ...
Only top voted, non community-wiki answers of a minimum length are eligible
Related Tags
piecewise × 315plotting × 75
calculus-and-analysis × 41
differential-equations × 40
functions × 27
function-construction × 20
equation-solving × 17
numerical-integration × 16
interpolation × 12
list-manipulation × 10
simplifying-expressions × 9
discontinuity × 9
mathematical-optimization × 8
bugs × 7
performance-tuning × 6
manipulate × 6
symbolic × 6
polynomials × 6
recursion × 6
assumptions × 6
conditional × 6
probability-or-statistics × 5
fitting × 5
color × 5
syntax × 5