From 8d96c4d30214a2c27561740b7b3f7e1e3b0bbfe4 Mon Sep 17 00:00:00 2001 From: Jaron Kent-Dobias Date: Mon, 23 Jul 2018 23:16:52 -0400 Subject: sped up orthogonal generation a bit --- lib/orthogonal.h | 51 ++++++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 23 deletions(-) (limited to 'lib') diff --git a/lib/orthogonal.h b/lib/orthogonal.h index 523fd54..ce2d300 100644 --- a/lib/orthogonal.h +++ b/lib/orthogonal.h @@ -166,51 +166,56 @@ orthogonal_t generate_rotation_uniform (gsl_rng *r, vector_t -orthogonal_t generate_rotation_perturbation (gsl_rng *r, vector_t v, double epsilon) { +orthogonal_t generate_rotation_perturbation (gsl_rng *r, vector_t v0, double epsilon, unsigned int n) { orthogonal_t m; - vector_t tmp_v; m.is_reflection = true; + m.x = (double *)malloc(q * sizeof(double)); - tmp_v.x = (double *)malloc(q * sizeof(double)); + vector_t v; - double tmp2 = 0; - double M2 = 0; - double tmpM = 0; + if (n > 1) { + unsigned int rotation = gsl_rng_uniform_int(r, n); + v.x = (double *)malloc(q * sizeof(double)); - for (q_t i = 0; i < q; i++) { - tmp_v.x[i] = gsl_ran_ugaussian(r); - M2 += pow(v.x[i], 2); - tmpM += tmp_v.x[i] * v.x[i]; - } + double cosr = cos(2 * M_PI * rotation / (double)n / 2.0); + double sinr = sin(2 * M_PI * rotation / (double)n / 2.0); - double v2 = 0; - double factor = gsl_ran_ugaussian(r); + v.x[0] = v0.x[0] * cosr - v0.x[1] * sinr; + v.x[1] = v0.x[1] * cosr + v0.x[0] * sinr; - for (q_t i = 0; i < q; i++) { - tmp_v.x[i] = (tmp_v.x[i] - tmpM * v.x[i] / M2) + epsilon * factor * v.x[i] / sqrt(M2); - v2 += tmp_v.x[i] * tmp_v.x[i]; + for (q_t i = 2; i < q; i++) { + v.x[i] = v0.x[i]; + } + } else { + v.x = v0.x; } - double mag_v = sqrt(v2); + double m2 = 0; + double m_dot_v = 0; for (q_t i = 0; i < q; i++) { - tmp_v.x[i] /= mag_v; + m.x[i] = gsl_ran_ugaussian(r); + m_dot_v += m.x[i] * v.x[i]; } - m.x = tmp_v.x; - - v2 = 0; + double v2 = 0; + double factor = epsilon * gsl_ran_ugaussian(r); for (q_t i = 0; i < q; i++) { - v2 += m.x[i] * m.x[i]; + m.x[i] = m.x[i] - m_dot_v * v.x[i] + factor * v.x[i]; + v2 += pow(m.x[i], 2); } - mag_v = sqrt(v2); + double mag_v = sqrt(v2); for (q_t i = 0; i < q; i++) { m.x[i] /= mag_v; } + if (n > 1) { + free(v.x); + } + return m; } -- cgit v1.2.3-70-g09d2