# -*- coding: utf-8 -*-

import numpy as np

from . import Filter  # prevent circular import in Python < 3.5


class Expwin(Filter):
    r"""Design an exponential window filter.

    Parameters
    ----------
    G : graph
    bmax : float
        Maximum relative band (default = 0.2)
    a : int
        Slope parameter (default = 1)

    Examples
    --------

    Filter bank's representation in Fourier and time (ring graph) domains.

    >>> import matplotlib.pyplot as plt
    >>> G = graphs.Ring(N=20)
    >>> G.estimate_lmax()
    >>> G.set_coordinates('line1D')
    >>> g = filters.Expwin(G)
    >>> s = g.localize(G.N // 2)
    >>> fig, axes = plt.subplots(1, 2)
    >>> g.plot(ax=axes[0])
    >>> G.plot_signal(s, ax=axes[1])

    """

    def __init__(self, G, bmax=0.2, a=1.):

        def fx(x, a):
            y = np.exp(-float(a)/x)
            if isinstance(x, np.ndarray):
                y = np.where(x <= 0, 0., y)
            else:
                if x <= 0:
                    y = 0.
            return y

        def gx(x, a):
            y = fx(x, a)
            return y/(y + fx(1 - x, a))

        def ffin(x, a):
            return gx(1 - x, a)

        g = [lambda x: ffin(np.float64(x)/bmax/G.lmax, a)]

        super(Expwin, self).__init__(G, g)

@@ -18,16 +18,49 @@
 -8 -*-%0A%0A
+from __future__ import division%0A%0A
 import n
@@ -254,16 +254,20 @@
 ph%0A    b
+and_
 max : fl
@@ -324,14 +324,20 @@
     
-a : in
+slope : floa
 t%0A  
@@ -811,16 +811,20 @@
 lf, G, b
+and_
 max=0.2,
@@ -828,12 +828,15 @@
 .2, 
-a
+slope
 =1
-.
 ):%0A%0A
@@ -851,19 +851,16 @@
 def fx(x
-, a
 ):%0A     
@@ -870,78 +870,57 @@
     
-y = np.exp(-float(a)/x)%0A            if isinstance(x, np.ndarray):%0A    
+# Canary to avoid division by zero and overflow.%0A
     
@@ -952,13 +952,13 @@
  0, 
-0., y
+-1, x
 )%0A  
@@ -971,88 +971,72 @@
     
-else:%0A                if x %3C= 0:%0A                    y = 0.%0A            return
+y = np.exp(-slope / y)%0A            return np.where(x %3C= 0, 0,
  y
+)
 %0A%0A  
@@ -1049,19 +1049,16 @@
 def gx(x
-, a
 ):%0A     
@@ -1072,19 +1072,16 @@
 y = fx(x
-, a
 )%0A      
@@ -1094,17 +1094,19 @@
 return y
-/
+ / 
 (y + fx(
@@ -1110,19 +1110,16 @@
 fx(1 - x
-, a
 ))%0A%0A    
@@ -1132,19 +1132,16 @@
 f ffin(x
-, a
 ):%0A     
@@ -1162,19 +1162,16 @@
 gx(1 - x
-, a
 )%0A%0A     
@@ -1197,23 +1197,15 @@
 fin(
-np.float64(x)/b
+x/band_
 max/
@@ -1210,19 +1210,16 @@
 x/G.lmax
-, a
 )%5D%0A%0A    

clean and fix div by zero