import numpy as np

def sigmoid(z): return 1 / (1 + np.exp(-z))

# ---- tiny RBM: 2 visible units, 1 hidden unit ----
W = np.array([0.8, 0.4])   # w1 (v1-h), w2 (v2-h)
a = np.array([0.0, 0.0])   # visible biases
b = 0.0                    # hidden bias
eta = 0.1
v0 = np.array([1.0, 0.0])  # clamped data point

# ---- positive phase ----
h0_prob = sigmoid(b + W @ v0)
pos_assoc = v0 * h0_prob
print("h0 =", h0_prob, " positive <v_i h> =", pos_assoc)

# ---- negative phase: one Gibbs step (CD-1) ----
v1_prob = sigmoid(a + W * h0_prob)          # reconstruct visible units
h1_prob = sigmoid(b + W @ v1_prob)          # resample hidden from reconstruction
neg_assoc = v1_prob * h1_prob
print("v_tilde =", v1_prob, " h1 =", h1_prob, " negative <v_i h> =", neg_assoc)

# ---- CD-1 parameter updates ----
dW = eta * (pos_assoc - neg_assoc)
da = eta * (v0 - v1_prob)
db = eta * (h0_prob - h1_prob)
print("dW =", dW, " da =", da, " db =", db)

W_new = W + dW
print("Updated W =", W_new)
