2
$\begingroup$

in below picture I draw a graph base on weight of a controller system against cost function. I want to linearise and divide this curve to for example 5 five intervals. is there any function in mathematica to give me such a thing. I thinking first maybe I can get gradient of function and choose the nearest amount together.

enter image description here

$\endgroup$
  • 2
    $\begingroup$ You can, for example, select 6 points - they will define 5 intervals - and then compute the equations of the lines passing through two points at the time. Or you can get an interpolating function of order 1 to pass through those points. Look up Interpolation $\endgroup$ – Peltio Jan 21 '14 at 2:57
1
$\begingroup$

A simple approach. Given a function f to be plotted, I create a Piecewise function where I approximate the function with a linear equation for each interval starting at an odd integer. It's quite easy to adapt this solution for any interval setup.

f[x_] := 1/(x);

sol[min_, max_] := First@Solve[{f@min == a min + b, f@max == a max + b}, {a, b}];

linf[t_, {min_, max_, d_}] := Piecewise@Table[
    {If[OddQ@i, (a*t + b) /. sol[i, i + d], f@t], i <= t < i + d},
    {i, min, max - d, d}];

linf[x, {0, 5, 1}]
Plot[linf[x, {0, 5, 1}], {x, 0, 5}, 
 GridLines -> {Range[0, 5, 1], None},
 GridLinesStyle -> Directive[GrayLevel[.3, .3], Dashed],
 Mesh -> 4, MeshFunctions -> {#1 &}, MeshShading -> {Dashing[0], Dashed}]

Mathematica graphics

The same with Interpolation. A Quiet is needed to prevent the appearance of some error messages related to the fact that Plot tries to sample the InterpolatingFunction-s outside their defined intervals as part of its adaptive sampling method.

linIntf[t_, {min_, max_, d_}] := Piecewise@Table[{If[OddQ@i, 
      Quiet@Interpolation[{{i, f[i]}, {i + d, f[i + d]}},
                          InterpolationOrder -> 1][t],
      f@t
      ], i <= t < i + d}, {i, min, max-d, d}];

linIntf[x, {0, 5, 1}]
Plot[linIntf[x, {0, 5, 1}], {x, 0, 5}, 
 GridLines -> {Range[0, 5, 1], None}, 
 GridLinesStyle -> Directive[GrayLevel[.3, .3], Dashed], Mesh -> 4, 
 MeshFunctions -> {#1 &}, MeshShading -> {Dashing[0], Dashed}]

Mathematica graphics

| improve this answer | |
$\endgroup$
0
$\begingroup$

My idea of using Interpolation is this. You have a function defined in an interval [a,b]

f[x_] := 1/(1 + x)
a = 0; b = 6;
Plot[f[x], {x, a, b}, Frame -> True]

Define your n intervals

n = 5;
xrange = Range[a, b, (b - a)/n];
yrange = f[xrange];

And use Interpolation to create your piecewise linear approximation

linf = Interpolation[Transpose[{xrange, yrange}], InterpolationOrder -> 1]

Plot[linf[x], {x, 0, 6}]

You can fit all the steps in a single function that will return an interpolating function

piecewiseLinearize[f_, {x_, a_, b_}, n_] := Module[{xrange, yrange},
    xrange = Range[a, b, (b - a)/n];
    yrange = (f /. x -> #) & /@ xrange;
    Interpolation[Transpose[{xrange, yrange}], InterpolationOrder -> 1]
    ]

Here's how to call it

linf = piecewiseLinearize[f[x], {x, 0, 6}, 5]

Plot[linf[x], {x, 0, 6}]
| improve this answer | |
$\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.