RienmanSum
Let be bounded.
i) The value
is called the upper integral of .
ii) The value
is called the lower integral of .
iii) The function is (Riemann) integrable if
In this case, we define
and call it the (Riemann) integral of .
How to use the applet
- Drag the two blue points on the -axis to choose the interval .
- Move the slider to choose the number of subintervals in the partition
- Click “Randomize partition” to generate a new random partition with the same number .
- Move the slider to control how “loose” the upper and lower staircase bounds are.
- The blue curve is the function .
- The red rectangles form an upper staircase function: on each subinterval the height is , where
- The green rectangles form a lower staircase function: on each subinterval the height is , where
- The green step function stays below , and the red step function stays above (by construction).
- Decreasing toward makes the bounds tighter for the chosen partition.
- Increasing (more, finer subintervals) typically makes the upper and lower step functions closer, illustrating why integrable functions have matching upper and lower integrals in the limit of finer partitions.
- Hold Shift + scroll to zoom
- Hold Shift + drag to move
- Points shaped like <> act as sliders
Description
Reference: Lecture Notes Calculus 1 ( May22,2022 ) Definition7.5 page 125
This applet illustrates the idea behind the lower and upper integrals definition. The function is fixed in the code as
const f = (x: number) => 0.25 * x ** 3 - x ** 2 - x + 2;.
The interval is controlled by two draggable points.
The slider nSlider sets the number of subintervals in a partition .
The partition is randomized by assigning random positive “weights”
randomWeights = Array.from({ length: MAX_PARTITIONS }, () => Math.random() * 0.8 + 0.3);
and converting them into cut points with the helper
buildRandomCuts(n, start, end).
Pressing the button “Randomize partition” regenerates these weights
and therefore produces a new random partition.
On each subinterval the applet computes
and .
Since is a cubic polynomial, these extrema are attained at the endpoints
and at critical points (zeros of ).
In the code the two critical points are precomputed in criticalPoints,
and the values and are computed by the function:
const extremaOnInterval = (x1: number, x2: number) => {
let minVal = Math.min(f(x1), f(x2));
let maxVal = Math.max(f(x1), f(x2));
for (const c of criticalPoints) {
if (c >= x1 - EPS && c <= x2 + EPS) {
const v = f(c);
minVal = Math.min(minVal, v);
maxVal = Math.max(maxVal, v);
}
}
return { min: minVal, max: maxVal };
};
The red rectangles represent an upper staircase function and the green rectangles
represent a lower staircase function.
Their shapes are produced by the two JSXGraph curves upperCurve and lowerCurve.
For each subinterval, the rectangle heights are built in computeRectangleCurve(cuts, type).
The slider deltaSlider controls how tight these staircase bounds are.
On each subinterval the applet draws the lower bound with height
and the upper bound with height :
const h = type === "upper" ? max + delta : min - delta;
This guarantees that the green staircase function stays below and the red staircase
function stays above .
When is decreased toward , the bounds become tighter and approach
the “best” lower and upper step functions associated to the chosen partition.
const computeRectangleCurve = (cuts: number[], type: "upper" | "lower") => {
const X: number[] = [];
const Y: number[] = [];
const delta = Math.max(0, deltaSlider.Value());
for (let i = 0; i < cuts.length - 1; i++) {
const x1 = cuts[i];
const x2 = cuts[i + 1];
const { min, max } = extremaOnInterval(x1, x2);
const h = type === "upper" ? max + delta : min - delta;
X.push(x1, x1, x2, x2);
Y.push(0, h, h, 0);
}
return { X, Y };
};