Compute the global energy for the current joint state of all nodes

        >>> q11_4 = BoltzmanMachine(bv=[0., 0.], bh=[-2.], Whh=np.zeros((1, 1)), Wvv=np.zeros((2, 2)), Wvh=[[3.], [-1.]])
        >>> q11_4.configurations()

        >>> v1v2h = product([0, 1], [0, 1], [0, 1])
        >>> E = np.array([q11_4.energy(v=x[0:2], h=[x[2]]) for x in v1v2h])
        >>> expnegE = np.exp(-E)
        >>> sumexpnegE = np.sum(expnegE)
        >>> pvh = np.array([ene / sumexpnegE for ene in expnegE])
        >>> pv = [0] * len(df)
        >>> num_hid_states = 2 ** self.Nh
        >>> for i in range(len(df)):
                j = int(i / num_hid_states)
                pv[i] = sum(pvh[k] for k in range(j * num_hid_states, (j + 1) * num_hid_states))
        >>> pd.DataFrame(tablify(v1v2h, -E, expnegE, pvh, pv), columns='v1 v2 h -E exp(-E) p(v,h), p(v)'.split())

def energy(self, v, h=None):
        """Compute the global energy for the current joint state of all nodes

        >>> q11_4 = BoltzmanMachine(bv=[0., 0.], bh=[-2.], Whh=np.zeros((1, 1)), Wvv=np.zeros((2, 2)), Wvh=[[3.], [-1.]])
        >>> q11_4.configurations()

        >>> v1v2h = product([0, 1], [0, 1], [0, 1])
        >>> E = np.array([q11_4.energy(v=x[0:2], h=[x[2]]) for x in v1v2h])
        >>> expnegE = np.exp(-E)
        >>> sumexpnegE = np.sum(expnegE)
        >>> pvh = np.array([ene / sumexpnegE for ene in expnegE])
        >>> pv = [0] * len(df)
        >>> num_hid_states = 2 ** self.Nh
        >>> for i in range(len(df)):
                j = int(i / num_hid_states)
                pv[i] = sum(pvh[k] for k in range(j * num_hid_states, (j + 1) * num_hid_states))
        >>> pd.DataFrame(tablify(v1v2h, -E, expnegE, pvh, pv), columns='v1 v2 h -E exp(-E) p(v,h), p(v)'.split())
        """
        h = np.zeros(self.Nh) if h is None else h
        negE = np.dot(v, self.bv)
        negE += np.dot(h, self.bh)
        for j in range(self.Nv):
            for i in range(j):
                negE += v[i] * v[j] * self.Wvv[i][j]
        for i in range(self.Nv):
            for k in range(self.Nh):
                negE += v[i] * h[k] * self.Wvh[i][k]
        for l in range(self.Nh):
            for k in range(l):
                negE += h[k] * h[l] * self.Whh[k][l]
        return -negE