5
$\begingroup$

I'm new with mathematica and I'm trying to solve a problem. I have a set of functions in the same variable. Let's say the domain is [0,2]. I would like to get an ordered list of the functions representing the "envelope". I'll try to explain, I have these 4 linear functions red, orange, green, blue. enter image description here

And this is the plot of the maximum among all the functions. enter image description here

How can I get a list {red, orange, green, blue} saying which is the max function in each segment?

Thanks

$\endgroup$
  • 2
    $\begingroup$ Max[f1, f2, f3, f4]? $\endgroup$ – Michael E2 Apr 15 '16 at 10:14
7
$\begingroup$

Michael E2 is correct in that Max is remarkably capable with functions as well as values.

Defining

f1[x_] := -2 x + 2
f2[x_] := -x + 1.5
f3[x_] := x - 0.5
f4[x_] := 2 x - 2

funcs = {f1[x], f2[x], f3[x], f4[x]};

We can use Max to get the function of the envelope:

m[x_] = PiecewiseExpand@Max[f1[x], f2[x], f3[x], f4[x]]

enter image description here

Plot[funcs, {x, 0, 2}, Epilog -> First@Plot[m[x], {x, 0, 2}, PlotStyle -> Directive[Dashed, Black]]]

enter image description here

Provided your functions are all linear we can safely solve for all the intersections and then examine which function is the largest in each region:

crossings = Union@N@Flatten[Outer[Solve[#1 == #2, x] &, funcs, funcs]][[;;, 2]];

Plot[funcs, {x, 0, 2}, Epilog -> {Line[{{#, -2}, {#, 2}}] & /@ crossings}]

enter image description here

Thus the different regions are bounded by:

regions =  Join[{x < crossings[[1]]}, (#[[1]] < x < #[[2]]) & /@ Partition[crossings, 2, 1], {crossings[[-1]] < x}]

{x < 0.5, 0.5 < x < 0.833333, 0.833333 < x < 1., 1. < x < 1.16667, 1.16667 < x < 1.5, 1.5 < x}

Within which the orderings are:

Reverse /@ (Ordering@Through[{f1, f2, f3, f4}[#]] & /@ MovingAverage[
Join[{crossings[[1]] - 1}, crossings, {crossings[[-1]] + 1}], 2])

{{1, 2, 3, 4}, {2, 1, 3, 4}, {2, 3, 1, 4}, {3, 2, 4, 1}, {3, 4, 2, 1}, {4, 3, 2, 1}}

$\endgroup$
  • $\begingroup$ Thank you! Is there a way to substitute "True" with the real interval of x (that is 1.<x<=1.5) in the output of PiecewiseExpand? $\endgroup$ – Fabio Sist Apr 19 '16 at 16:25
1
$\begingroup$

Let

f[x_] := {-x+2,-2x+3,1.1x-1,2x-3}
A=0;
B=3;
Plot[Evaluate@f[x],{x,A,B}]

enter image description here

With this,

Flatten[Ordering[#,-1]&/@f/@ Mean/@Partition[Sort@Flatten[{A,B,x/.Table[NSolve[{f[x][[i]]==f[x][[j]],A<=x<=B},x],{i,1,Length[f[0]]-1},{j,i+1,Length[f[0]]}]}],2,1]]//.{a___,b_,b_,c___}:>{a,b,c}

Outputs {2,1,3,4}. This code works also for non-linear functions.

For example, if

f[x_] := {Sin[x],-2x^2+3,1.1x^3-4,2x-3,4Cos[7x]}

enter image description here

the output is {5, 2, 5, 1, 5, 3}.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.