gsl_complex gsl_complex_pow_real (gsl_complex a, double b) { /* z=a^b */ gsl_complex z; if (GSL_REAL (a) == 0 && GSL_IMAG (a) == 0) { if (b == 0) { GSL_SET_COMPLEX (&z, 1, 0); } else { GSL_SET_COMPLEX (&z, 0, 0); } } else { double logr = gsl_complex_logabs (a); double theta = gsl_complex_arg (a); double rho = exp (logr * b); double beta = theta * b; GSL_SET_COMPLEX (&z, rho * cos (beta), rho * sin (beta)); } return z; }
/* ------------------------------------------------------ */ gsl_complex gsl_complex_carg (gsl_complex a) { gsl_complex z; GSL_SET_COMPLEX (&z, gsl_complex_arg(a), 0); return z; }
gsl_complex gsl_complex_log(gsl_complex a) { /* z=log(a) */ double logr = gsl_complex_logabs(a); double theta = gsl_complex_arg(a); gsl_complex z; GSL_SET_COMPLEX(&z, logr, theta); return z; }
void qpb_sun_project(qpb_link *u, int n) { gsl_eigen_hermv_workspace *gsl_work = gsl_eigen_hermv_alloc(NC); gsl_matrix_complex *B = gsl_matrix_complex_alloc(NC, NC); gsl_matrix_complex *A = gsl_matrix_complex_alloc(NC, NC); gsl_matrix_complex *V = gsl_matrix_complex_alloc(NC, NC); gsl_matrix_complex *U = gsl_matrix_complex_alloc(NC, NC); gsl_matrix_complex *D = gsl_matrix_complex_alloc(NC, NC); gsl_vector *S = gsl_vector_alloc(NC); gsl_permutation *perm = gsl_permutation_alloc(NC); for(int k=0; k<n; k++){ qpb_complex *a = (qpb_complex *)(u + k); for(int i=0; i<NC; i++) for(int j=0; j<NC; j++) gsl_matrix_complex_set(A, i, j, gsl_complex_rect(a[j + i*NC].re, a[j + i*NC].im)); gsl_matrix_complex_memcpy(U, A); int sgn; gsl_linalg_complex_LU_decomp(U, perm, &sgn); gsl_complex det_A = gsl_linalg_complex_LU_det(U, sgn); qpb_double phi = gsl_complex_arg(det_A); gsl_complex one = gsl_complex_rect(1., 0.); gsl_complex zero = gsl_complex_rect(0., 0.); gsl_matrix_complex_memcpy(U, A); svd(U, V, S); get_theta_matrix(D, S, phi); gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, one, U, D, zero, B); gsl_blas_zgemm(CblasNoTrans, CblasConjTrans, one, B, V, zero, A); for(int i=0; i<NC; i++) for(int j=0; j<NC; j++){ a[j + i*NC].re = GSL_REAL(gsl_matrix_complex_get(A, i, j)); a[j + i*NC].im = GSL_IMAG(gsl_matrix_complex_get(A, i, j)); } } gsl_matrix_complex_free(A); gsl_matrix_complex_free(B); gsl_matrix_complex_free(V); gsl_matrix_complex_free(U); gsl_matrix_complex_free(D); gsl_permutation_free(perm); gsl_vector_free(S); gsl_eigen_hermv_free(gsl_work); return; }
gsl_complex gsl_complex_pow(gsl_complex a, gsl_complex b) { /* z=a^b */ gsl_complex z; if (GSL_REAL(a) == 0 && GSL_IMAG(a) == 0.0) { GSL_SET_COMPLEX(&z, 0.0, 0.0); } else { double logr = gsl_complex_logabs(a); double theta = gsl_complex_arg(a); double br = GSL_REAL(b), bi = GSL_IMAG(b); double rho = exp(logr * br - bi * theta); double beta = theta * br + bi * logr; GSL_SET_COMPLEX(&z, rho * cos(beta), rho * sin(beta)); } return z; }
/* computes the svd of a complex matrix. Missing in gsl. */ int svd(gsl_matrix_complex *A, gsl_matrix_complex *V, gsl_vector *S) { int n = A->size1; gsl_eigen_hermv_workspace *gsl_work = gsl_eigen_hermv_alloc(n); gsl_matrix_complex *Asq = gsl_matrix_complex_alloc(n, n); gsl_complex zero = gsl_complex_rect(0., 0.); gsl_complex one = gsl_complex_rect(1., 0.); gsl_vector *e = gsl_vector_alloc(n); gsl_matrix_complex *U = gsl_matrix_complex_alloc(n, n); gsl_blas_zgemm(CblasNoTrans, CblasConjTrans, one, A, A, zero, Asq); gsl_eigen_hermv(Asq, e, U, gsl_work); gsl_eigen_hermv_sort(e, U, GSL_EIGEN_SORT_VAL_DESC); gsl_blas_zgemm(CblasConjTrans, CblasNoTrans, one, A, A, zero, Asq); gsl_eigen_hermv(Asq, e, V, gsl_work); gsl_eigen_hermv_sort(e, V, GSL_EIGEN_SORT_VAL_DESC); gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, one, A, V, zero, Asq); gsl_blas_zgemm(CblasConjTrans, CblasNoTrans, one, U, Asq, zero, A); for(int i=0; i<n; i++){ gsl_complex x = gsl_matrix_complex_get(A, i, i); double phase = gsl_complex_arg(gsl_complex_mul_real(x, 1./sqrt(e->data[i]))); gsl_vector_complex_view U_col = gsl_matrix_complex_column(U, i); gsl_vector_complex_scale(&U_col.vector, gsl_complex_polar(1., phase)); gsl_vector_set(S, i, sqrt(gsl_vector_get(e, i))); } gsl_matrix_complex_memcpy(A, U); gsl_vector_free(e); gsl_matrix_complex_free(U); gsl_matrix_complex_free(Asq); gsl_eigen_hermv_free(gsl_work); return 0; }
char *oph_gsl_complex_to_polar(UDF_INIT * initid, UDF_ARGS * args, char *result, unsigned long *length, char *is_null, char *error) { if (*error) { *length = 0; *is_null = 0; *error = 1; return NULL; } if (*is_null || !args->lengths[2]) { *length = 0; *is_null = 1; *error = 0; return NULL; } if (!initid->ptr) { initid->ptr = (char *) calloc(1, sizeof(oph_string)); if (!initid->ptr) { pmesg(1, __FILE__, __LINE__, "Error allocating result\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } oph_stringPtr output = (oph_stringPtr) initid->ptr; initid->extension = (char *) calloc(1, sizeof(oph_string)); if (!initid->extension) { pmesg(1, __FILE__, __LINE__, "Error allocating measure\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } oph_stringPtr measure = (oph_stringPtr) initid->extension; core_set_type(measure, args->args[0], &(args->lengths[0])); if (measure->type != OPH_COMPLEX_INT && measure->type != OPH_COMPLEX_LONG && measure->type != OPH_COMPLEX_FLOAT && measure->type == OPH_COMPLEX_DOUBLE) { pmesg(1, __FILE__, __LINE__, "Invalid input type: complex required\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } measure->length = &(args->lengths[2]); if (core_set_elemsize(measure)) { pmesg(1, __FILE__, __LINE__, "Error on setting element size\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } if (core_set_numelem(measure)) { pmesg(1, __FILE__, __LINE__, "Error on counting result elements\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } core_set_type(output, args->args[1], &(args->lengths[1])); if (output->type != OPH_COMPLEX_INT && output->type != OPH_COMPLEX_LONG && output->type != OPH_COMPLEX_FLOAT && output->type != OPH_COMPLEX_DOUBLE) { pmesg(1, __FILE__, __LINE__, "Invalid output type: complex required\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } if (core_set_elemsize(output)) { pmesg(1, __FILE__, __LINE__, "Error on setting element size\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } output->length = (unsigned long *) calloc(1, sizeof(unsigned long)); if (!output->length) { pmesg(1, __FILE__, __LINE__, "Error allocating length\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } *(output->length) = measure->numelem * output->elemsize; output->numelem = measure->numelem; output->content = (char *) calloc(1, *(output->length)); if (!output->content) { pmesg(1, __FILE__, __LINE__, "Error allocating result string\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } } oph_stringPtr output = (oph_stringPtr) initid->ptr; oph_stringPtr measure = (oph_stringPtr) initid->extension; measure->content = args->args[2]; int i, j = 0; gsl_complex z; double val1, val2; switch (measure->type) { case OPH_COMPLEX_INT: switch (output->type) { case OPH_COMPLEX_INT: for (i = 0; i < output->numelem * 2; i += 2) { z.dat[0] = (double) ((int *) (args->args[2]))[i]; //real part z.dat[1] = (double) ((int *) (args->args[2]))[i + 1]; //imag part val1 = gsl_complex_abs(z); val2 = gsl_complex_arg(z); if (core_oph_type_cast(&val1, output->content + (j * sizeof(int)), OPH_DOUBLE, OPH_INT, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } if (core_oph_type_cast(&val2, output->content + ((j + 1) * sizeof(int)), OPH_DOUBLE, OPH_INT, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } j += 2; } break; case OPH_COMPLEX_LONG: for (i = 0; i < output->numelem * 2; i += 2) { z.dat[0] = (double) ((int *) (args->args[2]))[i]; //real part z.dat[1] = (double) ((int *) (args->args[2]))[i + 1]; //imag part val1 = gsl_complex_abs(z); val2 = gsl_complex_arg(z); if (core_oph_type_cast(&val1, output->content + (j * sizeof(long long)), OPH_DOUBLE, OPH_LONG, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } if (core_oph_type_cast(&val2, output->content + ((j + 1) * sizeof(long long)), OPH_DOUBLE, OPH_LONG, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } j += 2; } break; case OPH_COMPLEX_FLOAT: for (i = 0; i < output->numelem * 2; i += 2) { z.dat[0] = (double) ((int *) (args->args[2]))[i]; //real part z.dat[1] = (double) ((int *) (args->args[2]))[i + 1]; //imag part val1 = gsl_complex_abs(z); val2 = gsl_complex_arg(z); if (core_oph_type_cast(&val1, output->content + (j * sizeof(float)), OPH_DOUBLE, OPH_FLOAT, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } if (core_oph_type_cast(&val2, output->content + ((j + 1) * sizeof(float)), OPH_DOUBLE, OPH_FLOAT, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } j += 2; } break; case OPH_COMPLEX_DOUBLE: for (i = 0; i < output->numelem * 2; i += 2) { z.dat[0] = (double) ((int *) (args->args[2]))[i]; //real part z.dat[1] = (double) ((int *) (args->args[2]))[i + 1]; //imag part val1 = gsl_complex_abs(z); val2 = gsl_complex_arg(z); if (core_oph_type_cast(&val1, output->content + (j * sizeof(double)), OPH_DOUBLE, OPH_DOUBLE, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } if (core_oph_type_cast(&val2, output->content + ((j + 1) * sizeof(double)), OPH_DOUBLE, OPH_DOUBLE, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } j += 2; } break; default: pmesg(1, __FILE__, __LINE__, "Type not recognized\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } break; case OPH_COMPLEX_LONG: switch (output->type) { case OPH_COMPLEX_INT: for (i = 0; i < output->numelem * 2; i += 2) { z.dat[0] = (double) ((long long *) (args->args[2]))[i]; //real part z.dat[1] = (double) ((long long *) (args->args[2]))[i + 1]; //imag part val1 = gsl_complex_abs(z); val2 = gsl_complex_arg(z); if (core_oph_type_cast(&val1, output->content + (j * sizeof(int)), OPH_DOUBLE, OPH_INT, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } if (core_oph_type_cast(&val2, output->content + ((j + 1) * sizeof(int)), OPH_DOUBLE, OPH_INT, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } j += 2; } break; case OPH_COMPLEX_LONG: for (i = 0; i < output->numelem * 2; i += 2) { z.dat[0] = (double) ((long long *) (args->args[2]))[i]; //real part z.dat[1] = (double) ((long long *) (args->args[2]))[i + 1]; //imag part val1 = gsl_complex_abs(z); val2 = gsl_complex_arg(z); if (core_oph_type_cast(&val1, output->content + (j * sizeof(long long)), OPH_DOUBLE, OPH_LONG, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } if (core_oph_type_cast(&val2, output->content + ((j + 1) * sizeof(long long)), OPH_DOUBLE, OPH_LONG, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } j += 2; } break; case OPH_COMPLEX_FLOAT: for (i = 0; i < output->numelem * 2; i += 2) { z.dat[0] = (double) ((long long *) (args->args[2]))[i]; //real part z.dat[1] = (double) ((long long *) (args->args[2]))[i + 1]; //imag part val1 = gsl_complex_abs(z); val2 = gsl_complex_arg(z); if (core_oph_type_cast(&val1, output->content + (j * sizeof(float)), OPH_DOUBLE, OPH_FLOAT, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } if (core_oph_type_cast(&val2, output->content + ((j + 1) * sizeof(float)), OPH_DOUBLE, OPH_FLOAT, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } j += 2; } break; case OPH_COMPLEX_DOUBLE: for (i = 0; i < output->numelem * 2; i += 2) { z.dat[0] = (double) ((long long *) (args->args[2]))[i]; //real part z.dat[1] = (double) ((long long *) (args->args[2]))[i + 1]; //imag part val1 = gsl_complex_abs(z); val2 = gsl_complex_arg(z); if (core_oph_type_cast(&val1, output->content + (j * sizeof(double)), OPH_DOUBLE, OPH_DOUBLE, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } if (core_oph_type_cast(&val2, output->content + ((j + 1) * sizeof(double)), OPH_DOUBLE, OPH_DOUBLE, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } j += 2; } break; default: pmesg(1, __FILE__, __LINE__, "Type not recognized\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } break; case OPH_COMPLEX_FLOAT: switch (output->type) { case OPH_COMPLEX_INT: for (i = 0; i < output->numelem * 2; i += 2) { z.dat[0] = (double) ((float *) (args->args[2]))[i]; //real part z.dat[1] = (double) ((float *) (args->args[2]))[i + 1]; //imag part val1 = gsl_complex_abs(z); val2 = gsl_complex_arg(z); if (core_oph_type_cast(&val1, output->content + (j * sizeof(int)), OPH_DOUBLE, OPH_INT, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } if (core_oph_type_cast(&val2, output->content + ((j + 1) * sizeof(int)), OPH_DOUBLE, OPH_INT, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } j += 2; } break; case OPH_COMPLEX_LONG: for (i = 0; i < output->numelem * 2; i += 2) { z.dat[0] = (double) ((float *) (args->args[2]))[i]; //real part z.dat[1] = (double) ((float *) (args->args[2]))[i + 1]; //imag part val1 = gsl_complex_abs(z); val2 = gsl_complex_arg(z); if (core_oph_type_cast(&val1, output->content + (j * sizeof(long long)), OPH_DOUBLE, OPH_LONG, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } if (core_oph_type_cast(&val2, output->content + ((j + 1) * sizeof(long long)), OPH_DOUBLE, OPH_LONG, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } j += 2; } break; case OPH_COMPLEX_FLOAT: for (i = 0; i < output->numelem * 2; i += 2) { z.dat[0] = (double) ((float *) (args->args[2]))[i]; //real part z.dat[1] = (double) ((float *) (args->args[2]))[i + 1]; //imag part val1 = gsl_complex_abs(z); val2 = gsl_complex_arg(z); if (core_oph_type_cast(&val1, output->content + (j * sizeof(float)), OPH_DOUBLE, OPH_FLOAT, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } if (core_oph_type_cast(&val2, output->content + ((j + 1) * sizeof(float)), OPH_DOUBLE, OPH_FLOAT, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } j += 2; } break; case OPH_COMPLEX_DOUBLE: for (i = 0; i < output->numelem * 2; i += 2) { z.dat[0] = (double) ((float *) (args->args[2]))[i]; //real part z.dat[1] = (double) ((float *) (args->args[2]))[i + 1]; //imag part val1 = gsl_complex_abs(z); val2 = gsl_complex_arg(z); if (core_oph_type_cast(&val1, output->content + (j * sizeof(double)), OPH_DOUBLE, OPH_DOUBLE, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } if (core_oph_type_cast(&val2, output->content + ((j + 1) * sizeof(double)), OPH_DOUBLE, OPH_DOUBLE, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } j += 2; } break; default: pmesg(1, __FILE__, __LINE__, "Type not recognized\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } break; case OPH_COMPLEX_DOUBLE: switch (output->type) { case OPH_COMPLEX_INT: for (i = 0; i < output->numelem * 2; i += 2) { z.dat[0] = ((double *) (args->args[2]))[i]; //real part z.dat[1] = ((double *) (args->args[2]))[i + 1]; //imag part val1 = gsl_complex_abs(z); val2 = gsl_complex_arg(z); if (core_oph_type_cast(&val1, output->content + (j * sizeof(int)), OPH_DOUBLE, OPH_INT, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } if (core_oph_type_cast(&val2, output->content + ((j + 1) * sizeof(int)), OPH_DOUBLE, OPH_INT, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } j += 2; } break; case OPH_COMPLEX_LONG: for (i = 0; i < output->numelem * 2; i += 2) { z.dat[0] = ((double *) (args->args[2]))[i]; //real part z.dat[1] = ((double *) (args->args[2]))[i + 1]; //imag part val1 = gsl_complex_abs(z); val2 = gsl_complex_arg(z); if (core_oph_type_cast(&val1, output->content + (j * sizeof(long long)), OPH_DOUBLE, OPH_LONG, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } if (core_oph_type_cast(&val2, output->content + ((j + 1) * sizeof(long long)), OPH_DOUBLE, OPH_LONG, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } j += 2; } break; case OPH_COMPLEX_FLOAT: for (i = 0; i < output->numelem * 2; i += 2) { z.dat[0] = ((double *) (args->args[2]))[i]; //real part z.dat[1] = ((double *) (args->args[2]))[i + 1]; //imag part val1 = gsl_complex_abs(z); val2 = gsl_complex_arg(z); if (core_oph_type_cast(&val1, output->content + (j * sizeof(float)), OPH_DOUBLE, OPH_FLOAT, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } if (core_oph_type_cast(&val2, output->content + ((j + 1) * sizeof(float)), OPH_DOUBLE, OPH_FLOAT, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } j += 2; } break; case OPH_COMPLEX_DOUBLE: for (i = 0; i < output->numelem * 2; i += 2) { z.dat[0] = ((double *) (args->args[2]))[i]; //real part z.dat[1] = ((double *) (args->args[2]))[i + 1]; //imag part val1 = gsl_complex_abs(z); val2 = gsl_complex_arg(z); if (core_oph_type_cast(&val1, output->content + (j * sizeof(double)), OPH_DOUBLE, OPH_DOUBLE, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } if (core_oph_type_cast(&val2, output->content + ((j + 1) * sizeof(double)), OPH_DOUBLE, OPH_DOUBLE, NULL)) { pmesg(1, __FILE__, __LINE__, "Error casting output\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } j += 2; } break; default: pmesg(1, __FILE__, __LINE__, "Type not recognized\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } break; default: pmesg(1, __FILE__, __LINE__, "Type not recognized\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } *length = *(output->length); *error = 0; *is_null = 0; return output->content; }
/** ---------------------------------------------------------------------------- * Sort eigenvectors */ int gsl_ext_eigen_sort(gsl_matrix_complex *evec, gsl_vector_complex *eval, int sort_order) { gsl_complex z; gsl_matrix_complex *evec_copy; gsl_vector_complex *eval_copy; int *idx_map, i, j, idx_temp; double p1, p2; if ((evec->size1 != evec->size2) || (evec->size1 != eval->size)) { return -1; } evec_copy = gsl_matrix_complex_alloc(evec->size1, evec->size2); eval_copy = gsl_vector_complex_alloc(eval->size); idx_map = (int *)malloc(sizeof(int) * eval->size); gsl_matrix_complex_memcpy(evec_copy, evec); gsl_vector_complex_memcpy(eval_copy, eval); // calculate new eigenvalue order for (i = 0; i < eval->size; i++) { idx_map[i] = i; } for (i = 0; i < eval->size - 1; i++) { for (j = i+1; j < eval->size; j++) { idx_temp = -1; if (sort_order == GSL_EXT_EIGEN_SORT_ABS) { p1 = gsl_complex_abs(gsl_vector_complex_get(eval, idx_map[i])); p2 = gsl_complex_abs(gsl_vector_complex_get(eval, idx_map[j])); if (p1 > p2) { idx_temp = idx_map[i]; } } if (sort_order == GSL_EXT_EIGEN_SORT_PHASE) { p1 = gsl_complex_arg(gsl_vector_complex_get(eval, idx_map[i])); p2 = gsl_complex_arg(gsl_vector_complex_get(eval, idx_map[j])); if (p1 > M_PI) p1 -= 2*M_PI; if (p1 <= -M_PI) p1 += 2*M_PI; if (p2 > M_PI) p2 -= 2*M_PI; if (p2 <= -M_PI) p2 += 2*M_PI; //if (((p2 < p1) && (p1 - p2 < M_PI)) || ) if (p2 < p1) { idx_temp = idx_map[i]; } } if (idx_temp != -1) { // swap //idx_temp = idx_map[i]; idx_map[i] = idx_map[j]; idx_map[j] = idx_temp; } } } // reshuffle the eigenvectors and eigenvalues for (i = 0; i < eval->size; i++) { for (j = 0; j < eval->size; j++) { z = gsl_matrix_complex_get(evec_copy, idx_map[i], j); gsl_matrix_complex_set(evec, i, j, z); //z = gsl_matrix_complex_get(evec_copy, i, idx_map[j]); //gsl_matrix_complex_set(evec, i, j, z); } z = gsl_vector_complex_get(eval_copy, idx_map[i]); gsl_vector_complex_set(eval, i, z); } gsl_matrix_complex_free(evec_copy); gsl_vector_complex_free(eval_copy); free(idx_map); return 0; }
double complex::arg() const { return gsl_complex_arg(_complex); }
void AbsArg(param_ param, abs_info_ *abs_info, gsl_complex *W, double *absW, double *argW, gsl_complex *complex_rot) { /* * In this function, we calculate the abs and arg * values for every point on the lattice. We also * find the total and max values for the abs across * the entire lattice. */ int i, j, tmp_int; gsl_complex complex_I; double *max_array, tmp; int max_num_threads; int L=param.L; GSL_SET_COMPLEX(&complex_I,0.,1.); tmp = 0.; tmp_int = 0; (*abs_info).max=0.; #pragma omp parallel { /* * The optimization here creates an array once in the * main thread, of length equal to the total number * of threads, and then updates local maxima along * the individual threads, storing them in the newly * created array. At the end, the local maxima are * compared. */ #pragma omp master { max_num_threads = omp_get_num_threads(); max_array = (double *)calloc(max_num_threads,sizeof(double)); } int num; num=omp_get_thread_num(); #pragma omp barrier //this barrier ensures the array //is visible to all threads #pragma omp for reduction(+:tmp) for(i=0; i<L*L; i++) { absW[i]=gsl_complex_abs(W[i]); tmp += absW[i]; if(absW[i] > max_array[num]) max_array[num]=absW[i]; argW[i] = gsl_complex_arg(W[i]); complex_rot[i] = gsl_complex_exp(gsl_complex_mul_real(\ complex_I,(-0.5)*argW[i])); } #pragma omp barrier #pragma omp master { for(i=0; i<max_num_threads; i++) if(max_array[i] > (*abs_info).max) (*abs_info).max = max_array[i]; free(max_array); } } //end parallel construct (*abs_info).total = tmp; /* * Here, we find the total number of * points considered active according to * param.p_thresh. */ for(j=0; j<param.pr_range; j++) { tmp_int = 0; #pragma omp parallel for reduction(+:tmp_int) for(i=0; i<L*L; i++) if(absW[i] >= param.pr_thresh[j]*(*abs_info).max) tmp_int++; (*abs_info).int_total[j] = tmp_int; } }
void setupTexture() { int i,j,x,y; double tmp; // Create our datapoints, store it as bytes for(i = 0; i < N; i++) { for(j = 0; j < N; j++) { double z = 0; switch(mode){ case 0: z = gsl_complex_abs(gsl_matrix_complex_get(psi,i,j)); break; case 1: z = GSL_REAL(gsl_matrix_complex_get(psi,i,j)); break; case 2: z = GSL_IMAG(gsl_matrix_complex_get(psi,i,j)); break; case 3: tmp = gsl_complex_arg(gsl_matrix_complex_get(psi,i,j)); z = (tmp - ((int) (tmp/(2*PI)))*(2*PI))/(2*PI)/5; } graph[i][j] = roundf(z * amplitude * 127 + 128); } } /* Upload the texture with our datapoints */ glBindTexture(GL_TEXTURE_2D, texture_id); glTexImage2D( GL_TEXTURE_2D, // target 0, // level, 0 = base, no minimap, GL_LUMINANCE, // internalformat N, // width N, // height 0, // border, always 0 in OpenGL ES GL_LUMINANCE, // format GL_UNSIGNED_BYTE, // type graph ); // Create an array for (grid+1) * (grid+1) vertices struct point vertices[(grid+1)][(grid+1)]; for(i = 0; i < (grid+1); i++) { for(j = 0; j < (grid+1); j++) { vertices[i][j].x = (j - (grid/2)) / (grid/2.0); vertices[i][j].y = (i - (grid/2)) / (grid/2.0); } } // Tell OpenGL to copy our array to the buffer objects glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); glBufferData(GL_ARRAY_BUFFER, sizeof vertices, vertices, GL_STATIC_DRAW); // Create an array of indices into the vertex array that traces both horizontal and vertical lines GLushort indices[grid * (grid+1) * 6]; for(i = y = 0; y < grid; y++) { for(x = 0; x < grid; x++) { indices[i++] = y * (grid+1) + x; indices[i++] = y * (grid+1) + x + 1; } } for(x = 0; x < (grid+1); x++) { for(y = 0; y < grid; y++) { indices[i++] = y * (grid+1) + x; indices[i++] = (y + 1) * (grid+1) + x; } } glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[1]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, grid * (grid+1) * 4 * sizeof *indices, indices, GL_STATIC_DRAW); // Create another array of indices that describes all the triangles needed to create a completely filled surface for(i = y = 0; y < (grid+1); y++) { for(x = 0; x < grid; x++) { indices[i++] = y * (grid+1) + x; indices[i++] = y * (grid+1) + x + 1; indices[i++] = (y + 1) * (grid+1) + x + 1; indices[i++] = y * (grid+1) + x; indices[i++] = (y + 1) * (grid+1) + x + 1; indices[i++] = (y + 1) * (grid+1) + x; } } glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[2]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof indices, indices, GL_STATIC_DRAW); }