/* Make a new GLQ structure and set all the parameters needed */ GLQ * glq_new(int order, double lower, double upper) { GLQ *glq; int rc; glq = (GLQ *)malloc(sizeof(GLQ)); if(glq == NULL) { return NULL; } glq->order = order; glq->nodes = (double *)malloc(sizeof(double)*order); if(glq->nodes == NULL) { free(glq); return NULL; } glq->nodes_unscaled = (double *)malloc(sizeof(double)*order); if(glq->nodes_unscaled == NULL) { free(glq); free(glq->nodes); return NULL; } glq->weights = (double *)malloc(sizeof(double)*order); if(glq->weights == NULL) { free(glq); free(glq->nodes); free(glq->nodes_unscaled); return NULL; } rc = glq_nodes(order, glq->nodes_unscaled); if(rc != 0 && rc != 3) { switch(rc) { case 1: log_error("glq_nodes invalid GLQ order %d. Should be >= 2.", order); break; case 2: log_error("glq_nodes NULL pointer for nodes"); break; default: log_error("glq_nodes unknown error code %g", rc); break; } glq_free(glq); return NULL; } else if(rc == 3) { log_warning("glq_nodes max iterations reached in root finder"); log_warning("nodes might not have desired accuracy %g", GLQ_MAXERROR); } rc = glq_weights(order, glq->nodes_unscaled, glq->weights); if(rc != 0) { switch(rc) { case 1: log_error("glq_weights invalid GLQ order %d. Should be >= 2.", order); break; case 2: log_error("glq_weights NULL pointer for nodes"); break; case 3: log_error("glq_weights NULL pointer for weights"); break; default: log_error("glq_weights unknown error code %d\n", rc); break; } glq_free(glq); return NULL; } if(glq_set_limits(lower, upper, glq) != 0) { glq_free(glq); return NULL; } return glq; }
static char * test_glq_set_limits() { double prec = pow(10, -9), unscaled[5], scaled[5], a, b, correct; int rc, i; GLQ glq; glq.nodes_unscaled = unscaled; glq.nodes = scaled; glq.order = 2; a = -2.54; b = 14.9; mu_arraycp(o2roots, glq.nodes_unscaled, glq.order); rc = glq_set_limits(a, b, &glq); sprintf(msg, "(order %d, a %g, b %g) return code %d, expected 0", glq.order, a, b, rc); mu_assert(rc == 0, msg); for(i = 0; i < glq.order; i++) { correct = 8.72*o2roots[i] + 6.18; sprintf(msg, "(order %d, index %d, a %g, b %g) expected %.15f, got %.15f", glq.order, i, a, b, correct, glq.nodes[i]); mu_assert_almost_equals(glq.nodes[i], correct, prec, msg); } glq.order = 3; a = 125.6; b = 234.84; mu_arraycp(o3roots, glq.nodes_unscaled, glq.order); rc = glq_set_limits(a, b, &glq); sprintf(msg, "(order %d, a %g, b %g) return code %d, expected 0", glq.order, a, b, rc); mu_assert(rc == 0, msg); for(i = 0; i < glq.order; i++) { correct = 54.62*o3roots[i] + 180.22; sprintf(msg, "(order %d, index %d, a %g, b %g) expected %.15f, got %.15f", glq.order, i, a, b, correct, glq.nodes[i]); mu_assert_almost_equals(glq.nodes[i], correct, prec, msg); } glq.order = 4; a = 3.5; b = -12.4; mu_arraycp(o4roots, glq.nodes_unscaled, glq.order); rc = glq_set_limits(a, b, &glq); sprintf(msg, "(order %d, a %g, b %g) return code %d, expected 0", glq.order, a, b, rc); mu_assert(rc == 0, msg); for(i = 0; i < glq.order; i++) { correct = -7.95*o4roots[i] - 4.45; sprintf(msg, "(order %d, index %d, a %g, b %g) expected %.15f, got %.15f", glq.order, i, a, b, correct, glq.nodes[i]); mu_assert_almost_equals(glq.nodes[i], correct, prec, msg); } glq.order = 5; a = 0.0; b = 0.0; mu_arraycp(o5roots, glq.nodes_unscaled, glq.order); rc = glq_set_limits(a, b, &glq); sprintf(msg, "(order %d, a %g, b %g) return code %d, expected 0", glq.order, a, b, rc); mu_assert(rc == 0, msg); for(i = 0; i < glq.order; i++) { correct = 0.0; sprintf(msg, "(order %d, index %d, a %g, b %g) expected %.15f, got %.15f", glq.order, i, a, b, correct, glq.nodes[i]); mu_assert_almost_equals(glq.nodes[i], correct, prec, msg); } return 0; }