<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 sat - Summed Area Table (integral image)
Synopse
The sat function is used to calculate from a given grayscale image, the summed area table (integral image).
g = iasat(f)
Output
g
Step1:  Examples
Step2:  Numerical example
Step3:  Image example
Step4:  Calculating a rectangle area with SAT (Summed Area Table)
<ASSISTANT_TASK:>
Python Code:
def sat(f):
    return f.cumsum(axis=1).cumsum(axis=0)
def satarea(sat,r0_c0,r1_c1):
    a,b,c,d = 0,0,0,0
    r0,c0 = r0_c0
    r1,c1 = r1_c1
    if ((r0 - 1 >= 0) and (c0 - 1 >= 0)):
        a = sat[r0-1,c0-1]
    if (r0 - 1 >= 0):
        b = sat[r0-1,c1]
    if (c0 - 1 >= 0):
        c = sat[r1,c0-1]
    d = sat[r1,c1]
    return a + d - c - b
Explanation: sat - Summed Area Table (integral image)
Synopse
The sat function is used to calculate from a given grayscale image, the summed area table (integral image).
g = iasat(f)
Output
g: ndarray with the summed area table.
Input
f: ndarray with a grayscale image.
Description
The Integral Image is used as a quick and effective way of calculating the sum of values 
(pixel values) in a given image or a rectangular subset of a grid (the given image). 
It can also, or is mainly, used for calculating the average intensity within a given image.
End of explanation
testing = (__name__ == "__main__")
if testing:
    ! jupyter nbconvert --to python sat.ipynb
    %matplotlib inline
    import numpy as np
    import sys,os
    ia898path = os.path.abspath('../../')
    if ia898path not in sys.path:
        sys.path.append(ia898path)
    import ia898.src as ia
    import matplotlib.image as mpimg
Explanation: Examples
End of explanation
if testing:    
    f = np.array([[0,1,1,0,0,0,0,0,0],
                  [1,0,0,0,0,0,0,1,0],
                  [1,0,0,1,0,0,0,1,0],
                  [0,0,0,0,0,1,1,0,0]], dtype=np.uint8)
    s = ia.sat(f)
    print('f (input):\n',f)
    print('s (output):\n',s)
    a = ia.satarea(s,(0,0),(3,8))
    print('area:',a)
Explanation: Numerical example:
End of explanation
if testing:
    f = mpimg.imread('../data/lenina.pgm')[::2,::2]   
    nb = ia.nbshow(2)
    nb.nbshow(f, 'Original Image')
    nb.nbshow(ia.normalize(ia.sat(f)), 'Integral Image')
    nb.nbshow()
Explanation: Image example
End of explanation
if testing:
    f = mpimg.imread('../data/lenina.pgm')[::2,::2]
    H,W = f.shape
    s = ia.sat(f)
    a0 = ia.satarea(s,(0,0),(H-1,W-1))
    atopleft  = ia.satarea(s,(   0,0   ),(H//2-1,W//2-1))
    abotleft  = ia.satarea(s,(H//2,0   ),(H-1,   W//2-1))
    atopright = ia.satarea(s,(   0,W//2),(H//2-1,W-1))
    abotright = ia.satarea(s,(H//2,W//2),(H-1,   W-1))
    print('Area Total: ', a0)
    print('Area Top-left: ', atopleft)
    print('Area Bot-left: ', abotleft)
    print('Area Top-right: ', atopright)
    print('Area Bot-right: ', abotright)
    print('Area Total:', atopleft+abotleft+atopright+abotright)
Explanation: Calculating a rectangle area with SAT (Summed Area Table)
End of explanation
<END_TASK>