import tensorflow as tf


    A = tf.subtract(tf.expand_dims(X, 0), tf.expand_dims(X, 1))
    return (1.0/(N*N)) * tf.reduce_sum(N0(A, 2*y)) + N0(0.0, 2.0 + 2*y) - (2/N) * tf.reduce_sum(N0(X, 1.0 + 2*y))


def cw_2d(X, y=None):
    def __phi(x):
        def __phi_f(s):
            t = s/7.5
            return tf.exp(-s/2) * (1 + 3.5156229*t**2 + 3.0899424*t**4 + 1.2067492*t**6 + 0.2659732*t**8
                                   + 0.0360768*t**10 + 0.0045813*t**12)

        def __phi_g(s):
            t = s/7.5
            return tf.sqrt(2/s) * (0.39894228 + 0.01328592*t**(-1) + 0.00225319*t**(-2) - 0.00157565*t**(-3)
                                   + 0.0091628*t**(-4) - 0.02057706*t**(-5) + 0.02635537*t**(-6) - 0.01647633*t**(-7)
                                   + 0.00392377*t**(-8))

        a = 7.5
        return __phi_f(tf.minimum(x, a)) - __phi_f(a) + __phi_g(tf.maximum(x, a))

    N = tf.cast(tf.shape(X)[0], tf.float32)
    if y is None:
        y = silverman_rule_of_thumb(N)

    A = 1/(N*N*tf.sqrt(y))
    B = 2.0/(N*tf.sqrt(y+0.5))

