Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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

share|improve this question
2  
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 –  Peltio Jan 21 at 2:57
add comment

2 Answers

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

share|improve this answer
add comment

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}]
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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