/*
 * SpinGlass.java
 * Created on Mar 28, 2005
 */
package search;

/**
 * A spin glass.
 */
public final class SpinGlass {
    
    private final boolean[] spins;
    private final double[] energies;

    /**
     * Creates a random spin glass.
     */
    public SpinGlass(boolean[] spins, double[] energies) {
        if (spins.length != energies.length) {
            throw new IllegalArgumentException("lengths of arguments not equal");
        }
        this.spins = new boolean[spins.length];
        System.arraycopy(spins, 0, this.spins, 0, spins.length);
        this.energies = new double[spins.length];
        System.arraycopy(energies, 0, this.energies, 0, spins.length);
    }
    
    public int size() {
        return spins.length;
    }
    
    public boolean[] spins() {
        boolean[] spins = new boolean[this.spins.length];
        System.arraycopy(this.spins, 0, spins, 0, spins.length);
        return spins;
    }
    
    public double energy() {
        double total = 0;
        for (int i = 0; i < spins.length; i++) {
            total += (spins[i] ^ spins[(i + 1) % spins.length]) ? -energies[i] : energies[i];
        }
        return total;
    }
    
    /**
     * Flips the ith spin, zero based.
     */
    public void flip(int i) {
        spins[i] = !spins[i];
    }

}
