0
$\begingroup$

I have a data file with two columns. Column 1 is x-values and column 2 is f(x) values. I would like to integrate f(x) with respect to x. To load the data, I do this:

mydata = ReadList["/dataset0.txt", Number, RecordLists -> True];

It reads the data file correctly. Now how do I insert the corresponding columns in a Integrate function?

$\endgroup$
3
  • 1
    $\begingroup$ related mathematica.stackexchange.com/q/18863/2079 $\endgroup$
    – george2079
    Sep 12, 2017 at 1:19
  • 2
    $\begingroup$ 1) Welcome on MMA.SE, 2) that would be easier to help you with some dummy data (possiby using RandomReals, or pastebin.com), 3) you don't want to integrate, you want to approximate the integral, using data and an approximation scheme (which one? trapezoidal, etc.). $\endgroup$
    – anderstood
    Sep 12, 2017 at 1:46
  • $\begingroup$ Thank you for helpful comments $\endgroup$ Sep 12, 2017 at 12:56

1 Answer 1

0
$\begingroup$

The link provided by @george2079 in the comments will be very useful if you run into more technical problems. I'm going to assume that it's all plain sailing, and just go through how integrating from data can work using Interpolation.

Here's some fake data with the same structure as yours:

mydata = {#, Sin[#^2]} &@RandomReal[π, 100];

which gives you a list of x-values and a list of function values (which I'm pretending is Sin[x^2]). Without an explicit expression for your function, you'll have to approximate the integral somehow. One straightforward way of doing this is with an InterpolatingFunction.

infun = Interpolation[Transpose[mydata]];
Show[ListPlot[Transpose[mydata]], 
  Plot[infun[x], Evaluate@Flatten@{x, infun["Domain"]}]]

enter image description here

Then you can Integrate infun, using the domain stored in the InterpolatingFunction

Integrate[infun[x], Evaluate@Flatten@{x, infun["Domain"]}]
(* 0.788024 *)

Compare with the actual function

Integrate[Sin[x^2], Evaluate@Flatten@{x, infun["Domain"]}]
(* 0.788037 *)

The discrepancy is due to the fact that infun is an approximation. The more data points you have, the more accurate it will be. Obviously.

Update: As @anderstood points out, you can also implement a straighforward rectangular rule on the sorted data:

mydata = {#, Sin[#^2]} &@Sort@RandomReal[\[Pi], 100];
xlist = Differences[mydata[[1]]];

Total[xlist mydata[[2, ;; -2]]] (* forward *)
Total[xlist mydata[[2, 2 ;; ]]] (* backward *)

(* 0.76924
   0.808697 *)

which may not be quite as accurate, but improves greatly for large data sets and is a couple of orders of magnitude faster.

$\endgroup$
3
  • 2
    $\begingroup$ Another approach, using a rectangular rule: mydata = {#, Sin[#^2]} &@Sort@RandomReal[\[Pi], 100]; xlist = Differences[mydata[[1]]]; Total[xlist*mydata[[2, ;; -2]]] (change to mydata[[2, 2 ;; ]] to switch between forward and backward rule). $\endgroup$
    – anderstood
    Sep 12, 2017 at 23:14
  • $\begingroup$ @anderstood Absolutely. Depending on the size of the data, the nastiness of the function, and how much speed is a factor, that might be a better method. $\endgroup$ Sep 12, 2017 at 23:27
  • $\begingroup$ Thank you. This is very helpful $\endgroup$ Sep 15, 2017 at 13:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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