Is there a way to numerically integrate a vector function defined via Piecewise
?
Example:
test[s_] := Piecewise[{
{{s, s^2, s^3}, s < -2},
{{0, s - 1, Sin[s]}, -2 <= s < 1},
{{1 - s^2, Exp[s], 0},1 <= s}}]
NIntegrate[test[s],{s,-2,2}]
This gives NIntegrate::inum: Integrand … is not numerical at …
as error.
Answer
I suppose I dislike mixing structural operations - like Thread
- inside algebraic expressions. My objections are two-fold:
1) I prefer to keep Mathematica operations distinct from actual algebra for aesthetic reasons.
2) If an expression is cut and pasted and changed, operations like Thread
can all too easily end up chewing into mathematical expressions, and generate nonsense!
IMHO, a better approach is to write a VectorPiecewise
function that checks if it is handling the scalar case, and returns it if it is, rejects inconsistent vector expressions, and returns the vector case as a list of scalar Piecewise
expressions, e.g.:
VectorPiecewise::syntax =
"Invalid VectorPiecewise construct - vector expressions are either of \
incompatible lengths or some are not vectors";
VectorPiecewise[expr_] := Module[{vv, hv, vc},
vv = expr[[All, 1]];
hv = Map[(Head[#] === List) &, vv];
If[! Or @@ hv,
Piecewise[expr],
If[(! And @@ hv ) || (! Equal @@ Map[Length, vv]),
Message[VectorPiecwise::syntax];,
vc = expr[[All, 2]];
vvt = Transpose[vv];
Map[Piecewise, MapIndexed[{#1, vc[[#2[[2]]]]} &, vvt, {2}]]
]
]
];
test[s_] :=
VectorPiecewise[{{{s, s^2, s^3},
s < -2}, {{0, s - 1, Sin[s]}, -2 <= s < 1}, {{1 - s^2, Exp[s], 0},
1 <= s}}]
NIntegrate[test[s], {s, -2, 2}]
{-1.33333, 0.170774, -0.956449}
Plot[test[s] // Evaluate, {s, -2, 2}, Filling -> {1 -> {2}, 2 -> {3}}]
If your complete expression contains several such VectorPiecewise
expressions, as you describe, the normal operation of the Listable
attribute will ensure the expression will work as expected, except that multiplying two vectors together needs you to specify either Dot
or Cross
- default multiplication of vectors gives you nothing useful.
Comments
Post a Comment