def cascade(hk, J=<NUM_LIT:7>):
N = len(hk) - <NUM_LIT:1><EOL>if (J > <NUM_LIT:30> - np.log2(N + <NUM_LIT:1>)):<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>if (J < <NUM_LIT:1>):<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>nn, kk = np.ogrid[:N, :N]<EOL>s2 = np.sqrt(<NUM_LIT:2>)<EOL>thk = np.r_[hk, <NUM_LIT:0>]<EOL>gk = qmf(hk)<EOL>tgk = np.r_[gk, <NUM_LIT:0>]<EOL>indx1 = np.clip(<NUM_LIT:2> * nn - kk, -<NUM_LIT:1>, N + <NUM_LIT:1>)<EOL>indx2 = np.clip(<NUM_LIT:2> * nn - kk + <NUM_LIT:1>, -<NUM_LIT:1>, N + <NUM_LIT:1>)<EOL>m = np.zeros((<NUM_LIT:2>, <NUM_LIT:2>, N, N), '<STR_LIT:d>')<EOL>m[<NUM_LIT:0>, <NUM_LIT:0>] = np.take(thk, indx1, <NUM_LIT:0>)<EOL>m[<NUM_LIT:0>, <NUM_LIT:1>] = np.take(thk, indx2, <NUM_LIT:0>)<EOL>m[<NUM_LIT:1>, <NUM_LIT:0>] = np.take(tgk, indx1, <NUM_LIT:0>)<EOL>m[<NUM_LIT:1>, <NUM_LIT:1>] = np.take(tgk, indx2, <NUM_LIT:0>)<EOL>m *= s2<EOL>x = np.arange(<NUM_LIT:0>, N * (<NUM_LIT:1> << J), dtype=np.float) / (<NUM_LIT:1> << J)<EOL>phi = <NUM_LIT:0> * x<EOL>psi = <NUM_LIT:0> * x<EOL>lam, v = eig(m[<NUM_LIT:0>, <NUM_LIT:0>])<EOL>ind = np.argmin(np.absolute(lam - <NUM_LIT:1>))<EOL>v = np.real(v[:, ind])<EOL>sm = np.sum(v)<EOL>if sm < <NUM_LIT:0>:  <EOL><INDENT>v = -v<EOL>sm = -sm<EOL><DEDENT>bitdic = {}<EOL>bitdic['<STR_LIT:0>'] = v / sm<EOL>bitdic['<STR_LIT:1>'] = np.dot(m[<NUM_LIT:0>, <NUM_LIT:1>], bitdic['<STR_LIT:0>'])<EOL>step = <NUM_LIT:1> << J<EOL>phi[::step] = bitdic['<STR_LIT:0>']<EOL>phi[(<NUM_LIT:1> << (J - <NUM_LIT:1>))::step] = bitdic['<STR_LIT:1>']<EOL>psi[::step] = np.dot(m[<NUM_LIT:1>, <NUM_LIT:0>], bitdic['<STR_LIT:0>'])<EOL>psi[(<NUM_LIT:1> << (J - <NUM_LIT:1>))::step] = np.dot(m[<NUM_LIT:1>, <NUM_LIT:1>], bitdic['<STR_LIT:0>'])<EOL>prevkeys = ['<STR_LIT:1>']<EOL>for level in range(<NUM_LIT:2>, J + <NUM_LIT:1>):<EOL><INDENT>newkeys = ['<STR_LIT>' % (xx, yy) for xx in [<NUM_LIT:0>, <NUM_LIT:1>] for yy in prevkeys]<EOL>fac = <NUM_LIT:1> << (J - level)<EOL>for key in newkeys:<EOL><INDENT>num = <NUM_LIT:0><EOL>for pos in range(level):<EOL><INDENT>if key[pos] == '<STR_LIT:1>':<EOL><INDENT>num += (<NUM_LIT:1> << (level - <NUM_LIT:1> - pos))<EOL><DEDENT><DEDENT>pastphi = bitdic[key[<NUM_LIT:1>:]]<EOL>ii = int(key[<NUM_LIT:0>])<EOL>temp = np.dot(m[<NUM_LIT:0>, ii], pastphi)<EOL>bitdic[key] = temp<EOL>phi[num * fac::step] = temp<EOL>psi[num * fac::step] = np.dot(m[<NUM_LIT:1>, ii], pastphi)<EOL><DEDENT>prevkeys = newkeys<EOL><DEDENT>return x, phi, psi<EOL>
Return (x, phi, psi) at dyadic points ``K/2**J`` from filter coefficients.

Parameters
----------
hk : array_like
    Coefficients of low-pass filter.
J : int, optional
    Values will be computed at grid points ``K/2**J``. Default is 7.

Returns
-------
x : ndarray
    The dyadic points ``K/2**J`` for ``K=0...N * (2**J)-1`` where
    ``len(hk) = len(gk) = N+1``.
phi : ndarray
    The scaling function ``phi(x)`` at `x`:
    ``phi(x) = sum(hk * phi(2x-k))``, where k is from 0 to N.
psi : ndarray, optional
    The wavelet function ``psi(x)`` at `x`:
    ``phi(x) = sum(gk * phi(2x-k))``, where k is from 0 to N.
    `psi` is only returned if `gk` is not None.

Notes
-----
The algorithm uses the vector cascade algorithm described by Strang and
Nguyen in "Wavelets and Filter Banks".  It builds a dictionary of values
and slices for quick reuse.  Then inserts vectors into final vector at the
end.