T Linalg< T, H >::tril(const T &x) {
  T r(x.allocator());
  return *tril(x, &r);
}
Example #2
0
/*
 * Returns a latticized graph with equivalent degree sequence to the original
 * weighted undirected graph.  On average, each edge is rewired ITER times.
 * Strength distributions are not preserved for weighted graphs.
 */
MATRIX_T* BCT_NAMESPACE::latmio_und(const MATRIX_T* R, int ITER) {
    if (safe_mode) check_status(R, SQUARE | UNDIRECTED, "latmio_und");

    gsl_rng* rng = get_rng();

    // n=length(R);
    int n = length(R);

    // D=zeros(n);
    MATRIX_T* D = zeros(n);

    // u=[0 min([mod(1:n-1,n);mod(n-1:-1:1,n)])];
    VECTOR_T* seq1 = sequence(1, n - 1);
    VECTOR_T* seq2 = sequence(n - 1, -1, 1);
    MATRIX_T* seq1_seq2 = concatenate_columns(seq1, seq2);
    VECTOR_ID(free)(seq1);
    VECTOR_ID(free)(seq2);
    VECTOR_T* min_seq1_seq2 = min(seq1_seq2);
    MATRIX_ID(free)(seq1_seq2);
    VECTOR_T* u = concatenate(0.0, min_seq1_seq2);
    VECTOR_ID(free)(min_seq1_seq2);

    // for v=1:ceil(n/2)
    for (int v = 1; v <= (int)std::ceil((FP_T)n / 2.0); v++) {

        // D(n-v+1,:)=u([v+1:n 1:v]);
        VECTOR_T* u_indices1 = sequence(v, n - 1);
        VECTOR_T* u_indices2 = sequence(0, v - 1);
        VECTOR_T* u_indices = concatenate(u_indices1, u_indices2);
        VECTOR_ID(free)(u_indices1);
        VECTOR_ID(free)(u_indices2);
        VECTOR_T* u_idx = ordinal_index(u, u_indices);
        VECTOR_ID(free)(u_indices);
        MATRIX_ID(set_row)(D, n - v, u_idx);
        VECTOR_ID(free)(u_idx);

        // D(v,:)=D(n-v+1,n:-1:1);
        VECTOR_T* D_rows = VECTOR_ID(alloc)(1);
        VECTOR_ID(set)(D_rows, 0, (FP_T)(n - v));
        VECTOR_T* D_cols = sequence(n - 1, -1, 0);
        MATRIX_T* D_idx = ordinal_index(D, D_rows, D_cols);
        VECTOR_ID(free)(D_rows);
        VECTOR_ID(free)(D_cols);
        VECTOR_T* D_idx_v = to_vector(D_idx);
        MATRIX_ID(free)(D_idx);
        MATRIX_ID(set_row)(D, v - 1, D_idx_v);
        VECTOR_ID(free)(D_idx_v);
    }

    // [i j]=find(tril(R));
    MATRIX_T* tril_R = tril(R);
    MATRIX_T* find_tril_R = find_ij(tril_R);
    MATRIX_ID(free)(tril_R);
    VECTOR_ID(view) i = MATRIX_ID(column)(find_tril_R, 0);
    VECTOR_ID(view) j = MATRIX_ID(column)(find_tril_R, 1);

    // K=length(i);
    int K = length(&i.vector);

    // ITER=K*ITER;
    ITER = K * ITER;

    MATRIX_T* _R = copy(R);

    // for iter=1:ITER
    for (int iter = 1; iter <= ITER; iter++) {

        // while 1
        while (true) {

            int e1, e2;
            int a, b, c, d;

            // while 1
            while (true) {

                // e1=ceil(K*rand);
                e1 = gsl_rng_uniform_int(rng, K);

                // e2=ceil(K*rand);
                e2 = gsl_rng_uniform_int(rng, K);

                // while (e2==e1),
                while (e2 == e1) {

                    // e2=ceil(K*rand);
                    e2 = gsl_rng_uniform_int(rng, K);
                }

                // a=i(e1); b=j(e1);
                a = (int)VECTOR_ID(get)(&i.vector, e1);
                b = (int)VECTOR_ID(get)(&j.vector, e1);

                // c=i(e2); d=j(e2);
                c = (int)VECTOR_ID(get)(&i.vector, e2);
                d = (int)VECTOR_ID(get)(&j.vector, e2);

                // if all(a~=[c d]) && all(b~=[c d]);
                if (a != c && a != d && b != c && b != d) {

                    // break
                    break;
                }
            }

            // if rand>0.5
            if (gsl_rng_uniform(rng) > 0.5) {

                // i(e2)=d; j(e2)=c;
                VECTOR_ID(set)(&i.vector, e2, (FP_T)d);
                VECTOR_ID(set)(&j.vector, e2, (FP_T)c);

                // c=i(e2); d=j(e2);
                c = (int)VECTOR_ID(get)(&i.vector, e2);
                d = (int)VECTOR_ID(get)(&j.vector, e2);
            }

            // if ~(R(a,d) || R(c,b))
            if (fp_zero(MATRIX_ID(get)(_R, a, d)) && fp_zero(MATRIX_ID(get)(_R, c, b))) {

                // if (D(a,b)+D(c,d))>=(D(a,d)+D(c,b))
                if (fp_greater_or_equal(MATRIX_ID(get)(D, a, b) + MATRIX_ID(get)(D, c, d),
                                        MATRIX_ID(get)(D, a, d) + MATRIX_ID(get)(D, c, b))) {

                    // R(a,d)=R(a,b); R(a,b)=0;
                    MATRIX_ID(set)(_R, a, d, MATRIX_ID(get)(_R, a, b));
                    MATRIX_ID(set)(_R, a, b, 0.0);

                    // R(d,a)=R(b,a); R(b,a)=0;
                    MATRIX_ID(set)(_R, d, a, MATRIX_ID(get)(_R, b, a));
                    MATRIX_ID(set)(_R, b, a, 0.0);

                    // R(c,b)=R(c,d); R(c,d)=0;
                    MATRIX_ID(set)(_R, c, b, MATRIX_ID(get)(_R, c, d));
                    MATRIX_ID(set)(_R, c, d, 0.0);

                    // R(b,c)=R(d,c); R(d,c)=0;
                    MATRIX_ID(set)(_R, b, c, MATRIX_ID(get)(_R, d, c));
                    MATRIX_ID(set)(_R, d, c, 0.0);

                    // j(e1) = d;
                    VECTOR_ID(set)(&j.vector, e1, (FP_T)d);

                    // j(e2) = b;
                    VECTOR_ID(set)(&j.vector, e2, (FP_T)b);

                    // break;
                    break;
                }
            }
        }
    }

    MATRIX_ID(free)(D);
    MATRIX_ID(free)(find_tril_R);
    return _R;
}