From 466812e61e2ccec7750c791835111b402938411c Mon Sep 17 00:00:00 2001 From: Jaron Kent-Dobias Date: Mon, 9 Jul 2018 14:19:16 -0400 Subject: wolff run from own function, called with types to run --- lib/orthogonal.h | 116 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 79 insertions(+), 37 deletions(-) (limited to 'lib/orthogonal.h') diff --git a/lib/orthogonal.h b/lib/orthogonal.h index 0b2fdd5..0a2b5c7 100644 --- a/lib/orthogonal.h +++ b/lib/orthogonal.h @@ -9,10 +9,11 @@ #include "types.h" template -struct orthogonal_t { T *x; }; +struct orthogonal_t { bool is_reflection; T *x; }; template void init(orthogonal_t *ptr) { + ptr->is_reflection = false; ptr->x = (T *)calloc(q * q, sizeof(T)); for (q_t i = 0; i < q; i++) { @@ -23,9 +24,19 @@ void init(orthogonal_t *ptr) { template orthogonal_t copy (orthogonal_t m) { orthogonal_t m_copy; - m_copy.x = (T *)calloc(q * q, sizeof(T)); + m_copy.is_reflection = m.is_reflection; - for (q_t i = 0; i < q * q; i++) { + q_t size; + + if (m.is_reflection) { + size = q; + } else { + size = q * q; + } + + m_copy.x = (T *)calloc(size, sizeof(T)); + + for (q_t i = 0; i < size; i++) { m_copy.x[i] = m.x[i]; } @@ -42,9 +53,19 @@ vector_t act (orthogonal_t m, vector_t v) { vector_t v_rot; v_rot.x = (T *)calloc(q, sizeof(T)); - for (q_t i = 0; i < q; i++) { - for (q_t j = 0; j < q; j++) { - v_rot.x[i] += m.x[q * i + j] * v.x[j]; + if (m.is_reflection) { + double prod = 0; + for (q_t i = 0; i < q; i++) { + prod += v.x[i] * m.x[i]; + } + for (q_t i = 0; i < q; i++) { + v_rot.x[i] = v.x[i] - 2 * prod * m.x[i]; + } + } else { + for (q_t i = 0; i < q; i++) { + for (q_t j = 0; j < q; j++) { + v_rot.x[i] += m.x[q * i + j] * v.x[j]; + } } } @@ -54,12 +75,28 @@ vector_t act (orthogonal_t m, vector_t v) { template orthogonal_t act (orthogonal_t m1, orthogonal_t m2) { orthogonal_t m2_rot; + + m2_rot.is_reflection = false; m2_rot.x = (T *)calloc(q * q, sizeof(T)); - for (q_t i = 0; i < q; i++) { - for (q_t j = 0; j < q; j++) { + if (m1.is_reflection) { + for (q_t i = 0; i < q; i++) { + double akOki = 0; + for (q_t k = 0; k < q; k++) { - m2_rot.x[i * q + j] += m1.x[i * q + j] * m2.x[j * q + k]; + akOki += m1.x[k] * m2.x[q * k + i]; + } + + for (q_t j = 0; j < q; j++) { + m2_rot.x[q * j + i] = m2.x[q * j + i] - 2 * akOki * m1.x[j]; + } + } + } else { + for (q_t i = 0; i < q; i++) { + for (q_t j = 0; j < q; j++) { + for (q_t k = 0; k < q; k++) { + m2_rot.x[i * q + j] += m1.x[i * q + j] * m2.x[j * q + k]; + } } } } @@ -69,54 +106,59 @@ orthogonal_t act (orthogonal_t m1, orthogonal_t m2) { template vector_t act_inverse (orthogonal_t m, vector_t v) { - vector_t v_rot; - v_rot.x = (T *)calloc(q, sizeof(T)); - - for (q_t i = 0; i < q; i++) { - for (q_t j = 0; j < q; j++) { - v_rot.x[i] += m.x[q * j + i] * v.x[j]; + if (m.is_reflection) { + return act(m, v); // reflections are their own inverse + } else { + vector_t v_rot; + v_rot.x = (T *)calloc(q, sizeof(T)); + + for (q_t i = 0; i < q; i++) { + for (q_t j = 0; j < q; j++) { + v_rot.x[i] += m.x[q * j + i] * v.x[j]; + } } - } - return v_rot; + return v_rot; + } } template orthogonal_t act_inverse (orthogonal_t m1, orthogonal_t m2) { - orthogonal_t m2_rot; - m2_rot.x = (T *)calloc(q * q, sizeof(T)); - - for (q_t i = 0; i < q; i++) { - for (q_t j = 0; j < q; j++) { - for (q_t k = 0; k < q; k++) { - m2_rot.x[i * q + j] += m1.x[j * q + i] * m2.x[j * q + k]; + if (m1.is_reflection) { + return act(m1, m2); // reflections are their own inverse + } else { + orthogonal_t m2_rot; + m2_rot.x = (T *)calloc(q * q, sizeof(T)); + + for (q_t i = 0; i < q; i++) { + for (q_t j = 0; j < q; j++) { + for (q_t k = 0; k < q; k++) { + m2_rot.x[i * q + j] += m1.x[j * q + i] * m2.x[j * q + k]; + } } } - } - return m2_rot; + return m2_rot; + } } template void generate_rotation (gsl_rng *r, orthogonal_t *ptr) { - double *v = (double *)malloc(q * sizeof(double)); + ptr->is_reflection = true; + ptr->x = (double *)calloc(q, sizeof(double)); + double v2 = 0; for (q_t i = 0; i < q; i++) { - v[i] = gsl_ran_ugaussian(r); - v2 += v[i] * v[i]; + ptr->x[i] = gsl_ran_ugaussian(r); + v2 += ptr->x[i] * ptr->x[i]; } - ptr->x = (double *)calloc(q * q, sizeof(double)); - + double mag_v = sqrt(v2); + for (q_t i = 0; i < q; i++) { - ptr->x[q * i + i] = 1.0; - for (q_t j = 0; j < q; j++) { - ptr->x[q * i + j] -= 2 * v[i] * v[j] / v2; - } + ptr->x[i] /= mag_v; } - - free(v); } -- cgit v1.2.3-70-g09d2