1
\$\begingroup\$

Here is my class for calculating a Riemann Sum. I did a cursory google search for a built-in function with these specifications but didn't find anything (I'm sure I just missed it or didn't look hard enough, but this is good practice).

Your input is welcome and appreciated. I'd like to not have to assign a lambda function to a variable but it works for me. I just worry that someone using this code may get confused.

from numpy import arange


class RiemannSum(object):

    def __init__(self, index, upper, rectangles, func, endpoints='mid'):
        """
        Constructor for base class for Riemann Sums.
        Will be subclassed for left, right, or mid-points for rectangles.

        :param index: Where to begin 'n' value. [n = index]
        :param upper: Upper bound of sum.  Max 'n' value.  [Number above sigma notation]
        :param rectangles: The number of rectangles to be used in the calculation.
        :param func: pass series function here; suggest assigning lambda function to variable and passing here
        :param endpoints: default to 'mid'. Valid values are 'mid', 'left', 'right' as strings
        """
        self.total = 0
        self.index = index
        self.upper = upper
        self.delta = (upper - index) / rectangles
        self.function = func

        if endpoints.lower() == 'left':  # left endpoints
            self.points = arange(self.index, self.upper, self.delta)
        elif endpoints.lower() == 'right':  # right endpoints
            self.points = arange(self.index + self.delta, self.upper + self.delta, self.delta)
        else:  # mid endpoints, usually most accurate
            diff = self.delta / 2
            self.points = [i for i in arange((self.index + diff),
                                         (self.upper + diff), self.delta)]

    def sum(self):
        outputs = [i for i in map(self.function, self.points)]
        self.total = sum(outputs)
        return self.delta * self.total

Here is an example of the code in use:

from math import sqrt
series = sqrt(x) - 2
num = RiemannSum(1,6,5,series,'mid').sum()
print(num)
\$\endgroup\$
  • \$\begingroup\$ I'm not clear of what you mean as far as "having" to assign a lambda function to a variable. Are you aware that functions can be passed just like any other parameter? For instance, if you do def square_it(x): return(x**2), then you can pass square_it as the func parameter. Also, docs.scipy.org/doc/scipy/reference/tutorial/integrate.html \$\endgroup\$ – Acccumulation Nov 30 '17 at 4:13
  • \$\begingroup\$ Sorry for being unclear; I am aware that functions can e passed as arguments but just found it easier to assign a lambda function to variable when doing a bunch of problems in an online quiz. Each series would have to be defined as a function and since they were throw-away assignments (only for the quiz question) I just used lambda. I thought there would be an integrate SciPy, thanks! This was made for less accurate Riemann Sums which were, surprisingly, required for an online Calc 2 quiz. I figured I could possibly use it again in the future... \$\endgroup\$ – Hanzy Nov 30 '17 at 4:17
1
\$\begingroup\$

If something is called "RiemannSum", then it should return a sum. If you want summation to be a separate method, a better term would be "partition"; you could do RiemannPartition.sum(), for instance.

Several other variable names are bit unintuitive to me (e.g. rectangles, index).

You can eliminate several lines by doing:

offset = {'left':0,'right':self.delta,'mid':self.delta/2}[self.endpoints.lower()]
self.points = arange(self.index+offset, self.upper+offset, self.delta)

General tip: if you're doing an if-then with several elif/else clauses, consider whether a dictionary would be simpler.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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