Gas chromatography and "integration"

Initialization cell.  Execute this group of cells before beginning

Left endpoint approximation

leftrect[n_] := 
        Block[{X, dX, rectangles, boundaries, RightRect}, 
          functionplot := 
            Plot[f[x], {x, a, b}, DisplayFunction -> Identity, 
              PlotRange -> All]; 
RightRect[g_, x_, 
              d_] := Line[{{x, 0}, {x + d, 0}, {x + d, g[x]}, {x, g[x]}, {x, 
                  0}}]; dX = ((b - a)/n); 
          X = Table[a + ((i (b - a))/n), {i, 0, n}]; 
          rectangles := 
            Graphics[{GrayLevel[0.9], 
                Table[Rectangle[{X[[i]], 
                      0}, {X[[i + 1]], 
                      f[X[[i]]]}], {i, 
                    1, n}]}]; 
          boundaries := 
            Graphics[
              Table[RightRect[f, X[[j]], 
                  dX], {j, 1, n}]]; 
          leftsum = 
            N[(∑_(i = 1)^n) f[
                    X[[i]]] dX, 10]; 
          label = leftsum "=  sum of  rectangle areas "; 
          Show[{functionplot,  rectangles, boundaries,  functionplot}, 
            PlotLabel -> label, 
            Frame  ->  
              True,   DisplayFunction -> $DisplayFunction];];

Midpoint approximation

midrect[n_] := 
        Block[{X, dX, rectangles, boundaries, MidRect}, 
          functionplot := 
            Plot[f[x], {x, a, b}, PlotRange  ->  All,  
              DisplayFunction -> Identity]; 
          MidRect[g_, x_, d_] := 
            Line[{{x, 0}, {x + d, 0}, {x + d, g[x + (d/2)]}, {x, 
                  g[x + (d/2)]}, {x, 0}}]; dX = ((b - a)/n); 
          X = Table[a + ((i (b - a))/n), {i, 0, n}]; 
          rectangles := 
            Graphics[{GrayLevel[0.9], 
                Table[Rectangle[{X[[i]], 
                      0}, {X[[i + 1]], 
                      f[X[[i]] + 
                          (dX/2)]}], {i, 1, n}]}]; 
          boundaries := 
            Graphics[
              Table[MidRect[f, X[[j]], 
                  dX], {j, 1, n}]]; 
          midsum = 
            N[(∑_(i = 1)^n) f[
                    X[[i]] + (dX/2)] dX, 
              10]; label = midsum "= sum  of rectangle areas"; 
          Show[{functionplot ,  rectangles, boundaries, functionplot}, 
            PlotLabel -> label, 
 
            DisplayFunction -> $DisplayFunction];];

Right endpoint approximation

\(\(rightrect[n_] := 
        Block[{X, dX, rectangles, boundaries, RightRect}, 
          functionplot := 
            Plot[f[x], {x, a, b}, DisplayFunction -> Identity, 
              PlotRange -> All]; 
          RightRect[g_, x_, d_] := 
            Line[{{x, 0}, {x + d, 0}, {x + d, g[x + d]}, {x, g[x + d]}, {x, 
                  0}}]; dX = \(b - a\)\/n; 
          X = Table[a + \(i\ \((b - a)\)\)\/n, {i, 0, n}]; 
          rectangles := 
            Graphics[{GrayLevel[0.9], 
                Table[Rectangle[{X[[i]], 
                      0}, {X[[i + 1]], 
                      f[X[[i + 
                            1]]]}], {i, 1, n}]}]; 
          boundaries := 
            Graphics[
              Table[RightRect[f, X[[j]], 
                  dX], {j, 1, n}]]; 
          rightsum = 
            N[∑\+\(i = 1\)\%n f[
                    X[[i + 1]]]\ dX, 
              10]; label = rightsum\ "=  sum of area of rectangles "; 
          Show[{functionplot, \ rectangles, boundaries, functionplot}, 
            PlotLabel -> 
              label, 
DisplayFunction -> $DisplayFunction];];\)\)

Trapezoid approximation

trapezoids[n_] := 
        Block[{X, dX, Trap, regions, boundaries}, 
          functionplot := 
            Plot[f[x], {x, a, b}, DisplayFunction -> Identity, 
              PlotRange -> All]; dX = ((b - a)/n); 
          X = Table[a + ((i (b - a))/n), {i, 0, n}]; 
          Trap[g_, x_, d_] := 
            Line[{{x, 0}, {x + d, 0}, {x + d, g[x + d]}, {x, g[x]}, {x, 0}}]; 
          regions := 
            Graphics[{GrayLevel[0.9], 
                Table[Polygon[{{X[[i]], 
                        0}, {X[[i]], 
                        f[X[[
                            i]]]}, {X[[
                          i + 1]], 
                        f[X[[i + 
                              1]]]}, {X[[
                          i + 1]], 0}}], {i, 1, n}]}]; 
          boundaries := 
            Graphics[
              Table[Trap[f, X[[j]], 
                  dX], {j, 1, n}]]; 
          trapsum = 
            N[(1/2) dX (f[a] + 
                    2 (∑_(i = 2)^n) f[
                          X[[i]]] + 
                    f[b]), 10]; 
          label = trapsum "= sum of area of trapezoids"; 
          Show[regions, boundaries, functionplot, PlotLabel -> label, 
            DisplayFunction -> $DisplayFunction];];

Numerical rules

LeftSum[n_] := 
      Block[{dX}, dX = ((b - a)/n); 
        N[(∑_(i = 0)^(n - 1))dX f[a + i dX], 10]]
MidpointSum[n_] := 
      Block[{dX}, dX = ((b - a)/n); 
        N[(∑_(i = 0)^(n - 1))dX f[a + (i + 0.5) dX], 
          10]]
RightSum[n_] := 
      Block[{dX}, dX = ((b - a)/n); 
        N[(∑_(i = 1)^n) dX f[a + i dX], 10]]
TrapezoidSum[n_] := 
      Block[{dX}, dX = ((b - a)/n); 
        N[(∑_(i = 0)^(n - 1))dX 0.5 (f[a + i dX] + 
                  f[a + (i + 1) dX]), 10]]

Gas chromatography is a procedure used to separate and quantitatively analyze mixtures of organic compounds.  It works like this:   A stream of an inert gas like nitrogen is directed under constant pressure (and constant flow rate) through an aparatus containing a tube with a material to which organic compounds selectively adhere (the separation column).  

A sample of the mixture of compounds is injected into to gas stream.   Different compounds are swept through the separation column at different rates due to their different inclinations to adhere to the material in the separation column.   

At the downstream end of the separation column, a detector measures the concentration of organic material in the gas stream, say in mmoles/ml.

A slightly idealized output from the detector might look like the following graph, which shows two compounds A and B have been well separated by the gas chromatograph.  Time is measured in minutes here.

Programming

g[x_]  :=  
      10 *Exp[-(x - 5)^2]  +  
        5 *Exp[-5 (x - 10)^2]

Plot[g[x],  {x,  0,  15},  PlotRange -> {0,  10}]

A biologist wishes to compute the total quantity of compounds A and B in the mixture.
Say the carrier gas is flowing at 10 ml/minute.   Then a concentration of  y  mmoles/ml
of one of the compounds in the effluent gas means that compound is being released from the separation column into the detector at a rate of  
10 (ml/minute) y (mmoles/ml) =  10 y (mmoles/minute).

How much of compound A was in the sample?

If compound A were released at a constant concentration  y for a period of time Δt, then
the total amound of compound A would be  
10 y (mmoles/minute) Δt minutes = 10 y Δt mmoles.

If compound A were released at a constant concentration (Subscript[y, 1])   for a period of time Δ(Subscript[t, 1]), and then at a different concentration (Subscript[y, 2]) for a period of time Δ(Subscript[t, 2]),  then the total amount would be
10 (Subscript[y, 1])Δ(Subscript[t, 1]) + 10 (Subscript[y, 2])Δ(Subscript[t, 2]) mmoles.

The situation would be similar if there were, say 5 time periods and the concentration were constant during each of these periods.  Then we would get 
10 (Subscript[y, 1])Δ(Subscript[t, 1]) + 10 (Subscript[y, 2])Δ(Subscript[t, 2]) + ... + 10 (Subscript[y, 5])Δ(Subscript[t, 5])

Let f(t)  denote the concentration of one of the organic compounds being discharged at time t.  Compound A is discharged during the time period from t = 2 to t = 8.  We can get an estimate on the amount of compound A by dividing this time interval in to some number, say 5, equal subintervals, and on each subinterval estimating the concentration of compound A being released during that short time interval by f(t*), where t* is some arbitrary choice of a time during that time interval;  we can pick, for example, the time exactly half way through the little time interval.  Then we get an estimate which looks like this:
10 f((Subscript[t, 1]))Δ(Subscript[t, 1]) + 10 f((Subscript[t, 2]))Δ(Subscript[t, 2]) + ... + 10 f((Subscript[t, 5]))Δ(Subscript[t, 5]),
where (Subscript[t, 1]), (Subscript[t, 2]), etc. are the times chosen in the first, second, etc time intervals

Here are the estimates we get by always choosing the middle of each time interval, or the beginning of each time interval:

f[x_]  :=  10*g[x]

a  =  2

    b  =  8

    midrect[5] 

    leftrect[5]

Now we increase the number of time subintervals and do the same thing:

midrect[10] 
leftrect[10]

And again:

\(\(\(
\)\(midrect[50]\ 

    leftrect[50]\)\)\)

And again:

\(\(\(
\)\(midrect[100]\ 

    leftrect[100]\)\)\)

By now I'm convinced that there was approximately 177.241 mmoles of compound A in the mixture.  How about compound B?

a  =  8

    b  =  12

    midrect[5]

midrect[20]

midrect[50]

midrect[100]

I am now convinced that the mixture contained about 39.6352 mmoles of compound B.