Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Mathematica question

  1. Sep 23, 2010 #1

    radou

    User Avatar
    Homework Helper

    OK, here's a problem I'm trying to solve for my work.

    Given a set of n points {(x1, y1), (x2, y2), ... (xn, yn)} I need to obtain a linear function f from the broken line which connects all these points, so that I can the value of f at any point.

    I need to do this for two sets of points, i.e. obtain functions f and g, because I have an expression which involves both the values of f and g at specific points.

    Thanks in advance for any help.
     
  2. jcsd
  3. Sep 23, 2010 #2
    Use the functions Fit and FindFit or other related functions. See help on Fit function:

    mydata = {{1, 1}, {2, 4}, {3, 8.5}}

    myfunction = Fit[mydata, {1, x, x^2}, x]
    N[myfunction /. x -> 2.1]
    Plot[myfunction, {x, 0, 10}]
     
  4. Sep 24, 2010 #3

    radou

    User Avatar
    Homework Helper

    jackmell, thanks for the reply.

    The fitting functons are not what I need, I need to obtain a linear function which directly connects these given points, and not an interpolation for this set of points. Any ideas how to do this?
     
  5. Sep 24, 2010 #4
    Directly as in "exactly"? Well I know you can fit n points exactly to an n-degree polynomial. Gotta' solve a system of n equations in n unknowns for the coefficients I think. Be interesting to set that up in Mathematica. I don't think it has a built-in function to do this however but not sure.
     
  6. Sep 24, 2010 #5

    Hepth

    User Avatar
    Gold Member

    So like a bunch of lines together? One "linear" function cannot connect all of them unless they all lie on one line.

    You can construct a total function that includes those, connecting with heaviside theta functions.

    ASSUMING THEY'RE ORDERED in increasing X values:
    Code (Text):

    data = {{1, 1}, {2, 3}, {3, 7}, {6, 10}};
    slopes = Table[(data[[i + 1]][[2]] - data[[i]][[2]])/(data[[i + 1]][[1]] - data[[i]][[1]]), {i, 1, Length[data] - 1}];
    yint = Table[(data[[i]][[2]] - slopes[[i]] (data[[i]][[1]])), {i, 1, Length[slopes]}];
    functions = Table[slopes[[i]] x + yint[[i]], {i, 1, Length[slopes]}];
    totalfunction[x_] =  Sum[HeavisideTheta[data[[i + 1]][[1]] - x] HeavisideTheta[
        x - data[[i]][[1]]] functions[[i]], {i, 1, Length[slopes]}];
    Plot[totalfunction[x], {x, 0, 4}]
     
    is something i just whipped up, you can obviously turn everything into just one equation

    Code (Text):
    fullfunction[x_] =
     Sum[HeavisideTheta[data[[i + 1]][[1]] - x] HeavisideTheta[x - data[[i]][[1]]] ((data[[i + 1]][[2]] -  data[[i]][[2]])/(data[[i + 1]][[1]] - data[[i]][[1]]) x + (data[[i]][[2]] - slopes[[i]] (data[[i]][[1]])))  , {i, 1, Length[data] - 1}]
     
  7. Sep 24, 2010 #6

    radou

    User Avatar
    Homework Helper

    Hepth, thanks.

    When evaluating, I get error messages of type:

    "Plot::plnr: totalfunction[x] is not a machine-size real number at x = \
    1.6666666666666665`*^-7."

    Btw, how can I get the value of this function at a point? For example, the line

    "N[totalfunction[2], 2]"

    returns

    "6.0 HeavisideTheta[0] HeavisideTheta[
    1.0] + 6.0 HeavisideTheta[-1.0] HeavisideTheta[4.0]"
     
  8. Sep 24, 2010 #7

    Hepth

    User Avatar
    Gold Member

    Ah, its because heavisidetheta isnt defined at those points. Try piecewise instead:
    replace the totalfunction in the above code with this
    Code (Text):

    totalfunction[x_] =
     Piecewise[Table[{functions[[i]], data[[i]][[1]] <= x <= data[[i + 1]][[1]]}, {i, 1, Length[slopes]}]]
     
     
  9. Sep 24, 2010 #8

    radou

    User Avatar
    Homework Helper

    Hm, for some reason, I still get the same error message when trying to plot the functions.

    Btw:

    "In[18]:=
    totalfunction[3]

    Out[18]=
    Piecewise[{{5,False},{7,True},{7,True}}]"

    Is there a way Mathematica can recognize that 3 is in the domain of the second function, and give its value at this function only?

    This function will be a parameter in another function, so I only need the value of one of the piecewise it consists of, depending in which domain the value is.
     
  10. Sep 24, 2010 #9

    Hepth

    User Avatar
    Gold Member

    try resetting mathematica by
    evaluation> quit kernel local (or whatever)

    The FALSE, TRUE stuff means you have defined "x" somewhere. If you need to in all my code rename "x" to "X" or something.

    or Clear[x]

    From a clear start I have
    Code (Text):
    data = {{1, 1}, {2, 3}, {3, 7}, {6, 10}};
    slopes = Table[(data[[i + 1]][[2]] -
          data[[i]][[2]])/(data[[i + 1]][[1]] - data[[i]][[1]]), {i, 1,
        Length[data] - 1}];
    yint = Table[(data[[i]][[2]] - slopes[[i]] (data[[i]][[1]])), {i, 1,
        Length[slopes]}];
    functions = Table[slopes[[i]] x + yint[[i]], {i, 1, Length[slopes]}];
    totalfunction[x_] =
     Piecewise[
      Table[{functions[[i]],
        data[[i]][[1]] <= x <= data[[i + 1]][[1]]}, {i, 1,
        Length[slopes]}]]
    Plot[totalfunction[x], {x, 0, 4}]
    totalfunction[3]
    which gives
    Out->
    [tex]
    \begin{cases}
    2 x-1 & 1\leq x\leq 2 \\
    4 x-5 & 2\leq x\leq 3 \\
    x+4 & 3\leq x\leq 6
    \end{cases}
    [/tex]
    and the plot
    then
    7
     
    Last edited: Sep 24, 2010
  11. Sep 24, 2010 #10

    Hepth

    User Avatar
    Gold Member

    Also, 3 is in the domain of both functions, I guess you can just change one of your less than equal to signs to less than, that way it wont be inclusive of both functions (though they're the same value), I just did it so it included the end points in each function as well, though you can prescribe it to only one if needed.:

    Code (Text):

    data = {{1, 1}, {2, 3}, {3, 7}, {6, 10}};
    slopes = Table[(data[[i + 1]][[2]] -
          data[[i]][[2]])/(data[[i + 1]][[1]] - data[[i]][[1]]), {i, 1,
        Length[data] - 1}];
    yint = Table[(data[[i]][[2]] - slopes[[i]] (data[[i]][[1]])), {i, 1,
        Length[slopes]}];
    functions = Table[slopes[[i]] x + yint[[i]], {i, 1, Length[slopes]}];
    totalfunction[x_] =
     Piecewise[
      Table[{functions[[i]],
        If[i == Length[slopes], data[[i]][[1]] <= x <= data[[i + 1]][[1]],
          data[[i]][[1]] <= x < data[[i + 1]][[1]]]}, {i, 1,
        Length[slopes]}]]
    Plot[totalfunction[x], {x, 0, 4}]
    totalfunction[3]
     
    That way the last function includes both the preceeding point as well as the final one, though every other segment only includes the leading point.
     
  12. Sep 24, 2010 #11

    radou

    User Avatar
    Homework Helper

    I'll try this out tomorrow.

    Thanks a lot for your help. :)
     
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook