16
$\begingroup$

I am completely new to Mathematica. Basically I was trying to write a code to plot a function and draw the approximate area by rectangles. To be more precise, plot a function f on an interval $[a,b]$, choose a step size $n$, divide the interval in n parts (so let's say $h=(b-a)/n$) and then draw the rectangles with coordinates $(a+ih,f(a+ih)),(a+(i+1)h, f(a+(i+1)h))$. I don't know how to store the information relative to the several rectangles. I would like to define a list or array (not sure how to call it) of rectangles parametrized by $i$, so something like:

For[i = 0, i < n, 
 R[i] = Rectangle[{a + i h, f[a + i h]}, {a + (i + 1) h,  f[a + (i + 1) h]}]]

which clearly doesn't work. I can't seem to find an appropriate way to do this.

I am attaching the code I wrote for a single rectangle, so if you also have any suggestion on how to improve that, it would be greatly appreciated. thank you!

f[x_] := x^2
a = 0
b = 2
n = 3

h = (b - a)/n
R = Rectangle[{a , f[a ]}, {a + h, f[a + h]}]]
r = Graphics[{ Opacity[0.2], Blue, R}]
Show[Plot[f[x], {x, a, b}], r ]

I would like to thank everyone for all of your answers!

$\endgroup$
2
  • 1
    $\begingroup$ Use Epilog to display your rectangle along with your plot. For more than one rectangle, there's Table[]. Alternatively, use Graphics[r] instead of just r in your last line. $\endgroup$ Commented May 6, 2015 at 3:43
  • 2
    $\begingroup$ You might also be interested in this MathWorld entry on Riemann sums, and in particular the associated Mathematica notebook. $\endgroup$ Commented May 6, 2015 at 4:04

6 Answers 6

15
$\begingroup$
f[x_] := x^2
With[
 {a = 0, b = 6, n = 7},
 rectangles = Table[
   {Opacity[0.05], EdgeForm[Gray], Rectangle[
     {a + i (b - a)/n, 0},
     {a + (i + 1) (b - a)/n, 
      Mean[{f[a + i (b - a)/n], f[a + (i + 1) (b - a)/n]}]}
     ]},
   {i, 0, n - 1, 1}
   ];
 Show[
  Plot[f[x], {x, a, b}, PlotStyle -> Thick, AxesOrigin -> {0, 0}],
  Graphics@rectangles
  ]
]

Mathematica graphics

Update:

I tried to combine @J. M.'s comment regarding the midpoint vs. "left-" or "right-"valued rectangles, and @belisarius 's fun idea of wrapping this in a Manipulate expression. Here's the outcome:

f[x_] := Sin[x]
Manipulate[
 rectangles = Table[
   {Opacity[0.05], EdgeForm[Gray], Rectangle[
     {a + i (b - a)/n, 0},
     {a + (i + 1) (b - a)/n, heightfunction[i]}
     ]},
   {i, 0, n - 1, 1}
   ];
 Show[{
   Plot[f[x], {x, a, b}, PlotStyle -> Thick, AxesOrigin -> {0, 0}],
   Graphics@rectangles
   },
  ImageSize -> Large
  ],
 {{a, 0}, -20, 20},
 {{b, 6}, -20, 20},
 {{n, 15}, 1, 40, 1},
 {{heightfunction, (Mean[{f[a + # (b - a)/n], 
       f[a + (# + 1) (b - a)/n]}] &)}, {
   (f[a + # (b - a)/n] &) -> "left",
   (Mean[{f[a + # (b - a)/n], f[a + (# + 1) (b - a)/n]}] &) -> "midpoint",
   (f[a + (# + 1) (b - a)/n] &) -> "right"
   }, ControlType -> SetterBar}
]

For instance, selecting the "right" version of the rectangles by choosing the "right" heightfunction gives the following output for $f(x)=\sin(x)$:

Animation shows three kinds of rectangles

$\endgroup$
7
  • 1
    $\begingroup$ This would correspond to the "midpoint" Riemann sum. With some more work, one should also be able to produce "left" and "right" versions. $\endgroup$ Commented May 6, 2015 at 4:53
  • $\begingroup$ @J.M. Good point. I interpreted the OP's question as asking about the construction of a Riemann integral, and in that context I naturally gravitated towards the midpoints. I also like @belisarius 's idea to provide a Manipulate to play with the parameters. I'll try to combine these two ideas. $\endgroup$
    – MarcoB
    Commented May 6, 2015 at 4:57
  • 2
    $\begingroup$ Wonderful! Will upvote when I can do so again. $\endgroup$ Commented May 6, 2015 at 6:01
  • $\begingroup$ @J.M. Thank you! That's high praise coming from you! $\endgroup$
    – MarcoB
    Commented May 6, 2015 at 6:25
  • 1
    $\begingroup$ @Gio The & and # are part of a "pure function" definition (see the documentation page for Function). For instance, a named function to calculate the square of a number could be square[x_] := x^2 (square[3] will output $9$). However, if you need a "throwaway" function to use only once, as I did in the example above, you can use a nameless "pure function" #^2 & . You can apply that function to an argument by writing #^2& [3] or #^2& @ 3. Either form would return $9$. Pure functions are powerful, and very convenient! $\endgroup$
    – MarcoB
    Commented May 6, 2015 at 17:23
8
$\begingroup$
Manipulate[
 Show[Plot[Sin[x], {x, 0, 2 Pi}], 
  DiscretePlot[Sin[t], {t, 0, 2 Pi, Pi/6}, ExtentSize -> p, 
   PlotMarkers -> {"Point", Large}, ColorFunction -> "Rainbow", 
   PlotStyle -> EdgeForm[Black]]], {p, {Left, Full, Right}}]

enter image description here

$\endgroup$
5
$\begingroup$

To draw a diagram that shows how a Riemann sum approximates a the area under a function, I would write something like this:

plotAreaApprox[f_, a_, b_, n_] :=
  Module[{h = (b - a)/n, rects},
    rects = 
      Table[Rectangle[{i, 0.}, {i + h, f[i + h/2]}], {i, a, b - h, h}];
    Plot[f[x], {x, a, b},
      Epilog -> {EdgeForm[Black], FaceForm[None], rects}]]

A function like this can be used to visualize theRiemann sums that approximate many simple integrals.

Example 1: using a named function

plotAreaApprox[Sin, 0., 2 N @ π, 10]

sin-plot

Example 2: using a pure function representing $2\, x/(1-x^2)$

plotAreaApprox[(2 #/(1 + #^2)) &, 0., 3, 10]

pure-func-plot

$\endgroup$
2
  • $\begingroup$ For full flexibility, you could modify the snippet f[i + h/2] to yield the other Riemann sums. If I may also make a tiny suggestion, it looks better if the second argument of plotAreaApprox[] was an iterator; that is, plotAreaApprox[f_, {a_, b_, n_Integer}] := (* stuff *) $\endgroup$ Commented May 6, 2015 at 5:10
  • $\begingroup$ @J.M. Your first suggestion is a good one, but I don't have the time now to implement it. Your second suggestion doesn't seem so good because the fourth arg isn't the step, so the last three args don't really form a iterator, and I don't see making the user add the brackets just to make look like an iterator. $\endgroup$
    – m_goldberg
    Commented May 6, 2015 at 5:18
5
$\begingroup$

I know there are already a lot of answers here, but I think you can extend it so that the function is changeable as well.

Manipulate[dx = (stop - start)/n;
 xi[i_] := 
  Which[Method == "Right", start + (i + 1)*dx, Method == "Left", 
   start + i*dx, Method == "Middle", start + dx/2 + dx i];
 rectangles = 
  Table[{Opacity[0.3], Green, EdgeForm[Gray], 
    Rectangle[{start + i*dx, 0}, {start + (i + 1)*dx, 
      Limit[func, x -> xi[i]]}]}, {i, 0, n - 1, 1}];
 Grid[{{Style[
     "\!\(\*SubscriptBox[\(\[Sum]\),     \
\(i\)]\)f(\!\(\*SubscriptBox[\(x\), \(i\)]\))\[CapitalDelta]x = " <> 
      ToString[N@Sum[dx*Limit[func, x -> xi[i]], {i, 0, n - 1}]] <> 
      "\n\[Integral]f(x)\[DifferentialD]x = " <> 
      ToString[Quiet@NIntegrate[func, {x, start, stop}]], 25]}, {Show[
     Plot[func, {x, start, stop}, PlotStyle -> {Black, Thick}], 
     Graphics@rectangles]}}], {{func, 2*x^3 + 5*x^2 + 3*x + 2, 
   "f(x)="}, 
  InputField[]}, {{start, 0, "\!\(\*SubscriptBox[\(x\), \(i\)]\)"}, 
  InputField[]}, {{stop, 10, "\!\(\*SubscriptBox[\(x\), \(f\)]\)"}, 
  InputField[]}, {{n, 20}, 3, 50, 1, 
  Appearance -> "Open"}, {{Method, "Left"}, {"Left", "Right", 
   "Middle"}, ControlType -> Setter}]

enter image description here

$\endgroup$
0
4
$\begingroup$
k = {a + # h, f[a + # h]} &;
Manipulate[h = (b - a)/n;
           Plot[f[x], {x, a, b}, PlotStyle -> Red,
               Prolog -> (Rectangle[k@#, k[# + 1]] & /@ Range[0, n - 1])],
 {n, 1, 10, 1}]

Mathematica graphics

$\endgroup$
5
  • 1
    $\begingroup$ After looking at the picture, I believe one of the ordinates in the arguments of Rectangle[] has to be 0 to get the Riemann sum rectangles. $\endgroup$ Commented May 6, 2015 at 4:46
  • 1
    $\begingroup$ Well... you are the first to mention the Riemann sum in this thread :-) $\endgroup$
    – LLlAMnYP
    Commented May 6, 2015 at 4:53
  • 1
    $\begingroup$ @LLlAMnYP, I have selfish reasons for keyword-dropping in SE sites like here and at math; the next time I search on Google, these pages should then show up among the results. $\endgroup$ Commented May 6, 2015 at 4:57
  • $\begingroup$ @J.M., I have a sneaking suspicion, that you are not unfamiliar with SEO. I'll shut up now, before this page is overloaded with unwanted keywords. $\endgroup$
    – LLlAMnYP
    Commented May 6, 2015 at 5:00
  • 1
    $\begingroup$ @J.M. In that case this is a dup mathematica.stackexchange.com/a/58579/193 $\endgroup$ Commented May 6, 2015 at 16:28
0
$\begingroup$

This might be best left as a comment but I do not have the privileges to do so:

The answer by MarcoB is not showing the rectangles associated with a midpoint Riemann sum. Instead, it is using the average of the function at the endpoints to generate the height of the rectangles.

To show the correct rectangles for the midpoint sum we need to evaluate the function at a + (i + 1/2) (b - a)/n:

f[x_] := x^2
With[
 {a = 0, b = 6, n = 7},
 rectangles = Table[
   {Opacity[0.05], EdgeForm[Gray], Rectangle[
     {a + i (b - a)/n, 0},
     {a + (i + 1) (b - a)/n, 
     f[a + (i + 1/2) (b - a)/n]}
     ]},
   {i, 0, n - 1, 1}
   ];
 Show[
  Plot[f[x], {x, a, b}, PlotStyle -> Thick, AxesOrigin -> {0, 0}],
  Graphics@rectangles
  ]
]

and likewise for the updated answer we evaluate the function at a + (# + 1/2) (b - a)/n:

f[x_] := Sin[x]
Manipulate[
 rectangles = Table[
   {Opacity[0.05], EdgeForm[Gray], Rectangle[
     {a + i (b - a)/n, 0},
     {a + (i + 1) (b - a)/n, heightfunction[i]}
     ]},
   {i, 0, n - 1, 1}
   ];
 Show[{
   Plot[f[x], {x, a, b}, PlotStyle -> Thick, AxesOrigin -> {0, 0}],
   Graphics@rectangles
   },
  ImageSize -> Large
  ],
 {{a, 0}, -20, 20},
 {{b, 6}, -20, 20},
 {{n, 15}, 1, 40, 1},
 {{heightfunction, (f[a + (# + 1/2) (b - a)/n] &)}, {
   (f[a + # (b - a)/n] &) -> "left",
   (f[a + (# + 1/2) (b - a)/n] &) -> "midpoint",
   (f[a + (# + 1) (b - a)/n] &) -> "right"
   }, ControlType -> SetterBar}
]
$\endgroup$

Your Answer

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

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