import math


def gowa(w, wm, l=1.0):
    """
       Generalized Ordered Weighted Averaging Operator
       More info can be found here:
        https://pdfs.semanticscholar.org/2810/c971af0d01d085c799fb2295dc5668d055c8.pdf

       l = -1 = Ordered Weighted Harmonic Averaging Operator
       l = -.000000000001 = Ordered Weighted Geometric Averaging Operator
       l = 1 = Ordered Weighted Arithmetic Averaging Operator
       l = 2 = Ordered Weighted Quadratic Averaging Operator

       w = list of weights
       wm = list of importance weighted membership values
       l = lambda real number specifying type of owa to use

       returns ordered weighted average
    """
    if len(w) != len(wm):
        raise ValueError("Weights and membership value lists must be of equal length.")

    if l == 0:
        raise ZeroDivisionError("Param l cannot be 0.  Use -.000000000001 for owg.")

    wm.sort(reverse=True)

    s = 0
    for i in range(len(w)):
        s += w[i] * math.pow(wm[i], l)

    return math.pow(s, 1/l)