Ejemplo n.º 1
0
// -------------------------------------------------------------------------------------------------
//  OperatorList::check(StateVector sv)
//
//  Use: Check the operator list for consitency
//  Input: StateVector sv - the spin configuration
//  Output: bool - true if ok, false if not
// -------------------------------------------------------------------------------------------------
bool OperatorList::check(StateVector sv)
{
    // Check that no diagonal or off-diagonal operator acts
    // on two parallel spins
    int N = sv.getSize();
    int L = getSize();

    for (int i = 0; i < L; i++) {
        int op = list->operators[i].op;
        int spin1 = list->operators[i].spin;
        int spin2 = spin1 + 1;
        if (spin2 > (N - 1))
            spin2 = 0;

        if ((op > 0) && (sv(spin1) == sv(spin2))) {
            cout << "Error: Operating on parallel spins!!" << endl;
            cout << "operator " << op << " on " << spin1 << "," << spin2;
            cout << " in " << sv << endl;
            cout << (*this) << endl;
            return false;
        }

        if (op == 2) {
            sv.flip(spin1);
            sv.flip(spin2);
        }
    }

    return true;
}
Ejemplo n.º 2
0
// -------------------------------------------------------------------------------------------------
//  OperatorList::diagonalMove(StateVector& sv, double beta)
//
//  Use: Performs a diagonal update on the operator list
//  Input: StateVector& sv - the spin configuration
//         double beta - the inverse temperature
//  Output: none
// -------------------------------------------------------------------------------------------------
void OperatorList::diagonalUpdate(StateVector& sv, double beta)
{
    int N = sv.getSize();       // Number of spins
    int L = getSize();          // Operator list length

    for (int i = 0; i < L; i++) {
        int n = countDOD();   // Number of diagonal and off-diagonal operators
        int op = list->operators[i].op;
        if (op == 0) {
            // unit operator
            // Calculate probability to change operator
            double P = (double)(N*beta/(2*(L-n)));
            // Generate a random spin that this operator acts on
            int spin1 = (int)(ran()*N);
            // and its adjacent spin
            int spin2 = (spin1 + 1) % N;
            
            // Change operator to diagonal only if the spins are _not_ parallel...
            if (sv(spin1) != sv(spin2)) {
                // ...and with probability P
                double r = ran();

                if (r < P) {
                    //cout << "Change..." << endl;
                    list->operators[i].op = 1;
                    list->operators[i].spin = spin1;
                }
            }
        } else if (op == 1) { 
            // diagonal operator
            // Calculate probability to change to unit operator
            double P = (double)(2*(L-n+1)/(N*beta));
            double r = ran();
            
            // Get the spins this off-diagonal operator acts on
            int spin1 = list->operators[i].spin;
            int spin2 = (spin1 + 1) % N;
            
            if (r < P) {
                list->operators[i].op = 0;    
                // unit ops cannot act on spins
                list->operators[i].spin = -1;    
            }
        } else if (op == 2) { 
            // off-diagonal operator
            // Get the spins this off-diagonal operator acts on
            int spin1 = list->operators[i].spin;
            int spin2 = (spin1 + 1) % N;
            
            // Flip both spins
            sv.flip(spin1);
            sv.flip(spin2);                
        }
    }
} 
Ejemplo n.º 3
0
// -------------------------------------------------------------------------------------------------
//  OperatorList::display(StateVector sv)
//
//  Use: Output a text visualisation of the operator list
//  Input: StateVector sv - the spin configuration
//  Output: none
// -------------------------------------------------------------------------------------------------
void OperatorList::display(StateVector sv)
{
    int N = sv.getSize();
    int L = getSize();

    const char* spins[2] = {"U", "D"};
    const char* ops[3] = {" ", "-", "="};

    for (int i = 0; i < L; i++) {
        cout << " ";
        for (int j = 0; j < N; j++)
            cout << spins[sv(j)] << " ";
        cout  << " (" << i << ")" << endl;

        int op = list->operators[i].op;
        if (op == 0) 
            cout << endl;
        else {
            int spin1 = list->operators[i].spin;
            int spin2 = spin1 + 1;
            if (spin2 > (N - 1))
                spin2 = 0;
            
            if (spin2 == 0) {
                cout << " " << ops[op];
                for (int k = 0; k < (2*N - 3); k++)
                    cout << " ";
                cout << ops[op] << endl;
            } else {
                for (int k = 0; k < (2*spin1 + 1); k++)
                    cout << " ";            
                for (int k = 0; k < 3; k++)
                    cout << ops[op];
                cout << endl;
            }

            // flip spins if off diagonal operator
            if (op == 2) {
                sv.flip(spin1);
                sv.flip(spin2);
            }            
        }
    }
    cout << " ";
    for (int j = 0; j < N; j++)
        cout << spins[sv(j)] << " ";
    cout << endl << endl << endl;
}
Ejemplo n.º 4
0
// -------------------------------------------------------------------------------------------------
//  OperatorList::loopUpdate(StateVector& sv, double beta)
//
//  Use: Performs a loop cluster update on the operator list
//  Input: StateVector& sv - the spin configuration
//         double beta - the inverse temperature
//  Output: none
// -------------------------------------------------------------------------------------------------
void OperatorList::loopUpdate(StateVector& sv, double beta)
{
    int N = sv.getSize();     // Number of spins
    int L = getSize();        // Operator list length

    int noDOD = countDOD();
    if (noDOD > 0) {
        // j is the operator loop index
        int j;
        // Select a random non-unit operator...
        do {
            j = (int)(ran()*L);
            if (j > (L - 1)) 
              j = L - 1;
        } while (list->operators[j].op == 0); 

        // i is the state loop index
        int i = j;

        // direction = -1 : backward direction
        // direction = 1 : forward direction
        int direction = 1;
        int loops = 0;
        int spin = list->operators[j].spin;
        int startop = j;
        int startstate = i;
        int startspin = spin;
        int spin1 = spin;
        int spin2 = (spin1 + 1) % N;

        // change this operator from diagonal to off-diagonal and vice versa...
        changeOp(j);

        // this is the actual loop update
        do {
            if (loops > 0) {
                // Break the loop when we return to the starting operator
                if ((i == startstate) &&(j == startop))
                    if (spin == startspin) {
                        changeOp(j);
                        break;
                    } else if ((spin - 1) == startspin)
                        break;
            }

            j += direction;
            // we use periodic boundary conditions
            if (j < 0) {
                j = L - 1;
                sv.flip(spin);
            }
            if (j > (L - 1)) {
                j = 0;
                sv.flip(spin);
            }

            int op = list->operators[j].op;
            spin1 = list->operators[j].spin;
            spin2 = (spin1 + 1) % N;

            if (op == 0) {
                // in case of a unit operator just update state index
                i += direction;
                if (i < 0) i = L - 1;
                if (i > (L-1)) i = 0;
            } else {
                // diagonal or off-diagonal operator
                if ((spin != spin1) && (spin != spin2)) {
                    i += direction;
                    if (i < 0) i = L - 1;
                    if (i > (L-1)) i = 0;
                } else if (spin == spin1) {
                    spin++;
                    if (spin > (N - 1))
                        spin = 0;
                    direction *= -1;
                    changeOp(j);
                } else if (spin == spin2) {
                    spin--;
                    if (spin < 0)
                        spin = N - 1;
                    direction *= -1;
                    changeOp(j);
                }
            }

            loops = 1;
        } while(true);
    }
}