/* Variable manipulation */ void tour1d_manip_init(gint p1, gint p2, splotd *sp) { displayd *dsp = (displayd *) sp->displayptr; GGobiStage *d = dsp->d; cpaneld *cpanel = &dsp->cpanel; GGobiSession *gg = GGobiFromSPlot(sp); gint j; gint n1vars = dsp->t1d.nactive; gboolean dontdoit = false; dsp->t1d_phi = 0.; /* gets mouse position */ if (cpanel->t1d.vert) dsp->t1d_pos = dsp->t1d_pos_old = p2; else dsp->t1d_pos = dsp->t1d_pos_old = p1; /* initializes indicator for manip var being one of existing vars */ dsp->t1d_manipvar_inc = false; /* need to turn off tour */ if (!cpanel->t1d.paused) tour1d_func(T1DOFF, gg->current_display, gg); /* check if manip var is one of existing vars */ /* n1vars, n2vars is the number of variables, excluding the manip var in hor and vert directions */ for (j=0; j<dsp->t1d.nactive; j++) if (dsp->t1d.active_vars.els[j] == dsp->t1d_manip_var) { dsp->t1d_manipvar_inc = true; n1vars--; } /* make manip basis, from existing projection */ /* 0 will be the remainder of the projection, and 1 will be the indicator vector for the manip var */ for (j=0; j<d->n_cols; j++) { dsp->t1d_manbasis.vals[0][j] = dsp->t1d.F.vals[0][j]; dsp->t1d_manbasis.vals[1][j] = 0.; } dsp->t1d_manbasis.vals[1][dsp->t1d_manip_var]=1.; if (n1vars > 0) { while (!gram_schmidt(dsp->t1d_manbasis.vals[0], dsp->t1d_manbasis.vals[1], d->n_cols)) { gt_basis(dsp->t1d.tv, dsp->t1d.nactive, dsp->t1d.active_vars, d->n_cols, (gint) 1); for (j=0; j<d->n_cols; j++) dsp->t1d_manbasis.vals[1][j] = dsp->t1d.tv.vals[0][j]; } } if (dontdoit) disconnect_motion_signal (sp); }
Matrix *orthonormal_basis(Matrix *m){ Matrix *orthog; unsigned int i, j; double factor; if(m == NULL) return NULL; orthog = gram_schmidt(m); for(i = 0; i < m->columns; i++){ factor = 0; for(j = 0; j < m->rows; j++) factor += orthog->numbers[i][j]*orthog->numbers[i][j]; factor = sqrt(factor); for(j = 0; j < m->rows; j++) orthog->numbers[i][j] /= factor; } return orthog; }
// This performs a Gram-Schmidt orthogonalization process on a monomial basis. static void gram_schmidt(div_free_poly_basis_t* basis) { // Make a copy of the original basis vectors. polynomial_vector_t v[basis->dim]; for (int i = 0; i < basis->dim; ++i) v[i] = basis->vectors[i]; for (int i = 0; i < basis->dim; ++i) { // ui = vi. polynomial_vector_t ui = v[i]; for (int j = 0; j < i; ++j) { polynomial_vector_t uj = basis->vectors[j]; // Compute <vi, uj>. real_t vi_o_uj = inner_product(basis, &v[i], &uj); // Compute <uj, uj>. real_t uj2 = inner_product(basis, &uj, &uj); ASSERT(uj2 > 0.0); // Compute the projection of vi onto uj. polynomial_vector_t proj_uj = {.x = scaled_polynomial_new(uj.x, vi_o_uj/uj2), .y = scaled_polynomial_new(uj.y, vi_o_uj/uj2), .z = scaled_polynomial_new(uj.z, vi_o_uj/uj2)}; // Subtract this off of ui. polynomial_add(ui.x, -1.0, proj_uj.x); polynomial_add(ui.y, -1.0, proj_uj.y); polynomial_add(ui.z, -1.0, proj_uj.z); } // Copy the new ui basis vector into place. basis->vectors[i] = ui; } } div_free_poly_basis_t* spherical_div_free_poly_basis_new(int degree, point_t* x0, real_t radius) { ASSERT(radius > 0.0); ASSERT(degree >= 0); ASSERT(degree <= 2); // FIXME div_free_poly_basis_t* basis = GC_MALLOC(sizeof(div_free_poly_basis_t)); basis->polytope = SPHERE; basis->x0 = *x0; basis->radius = radius; basis->dim = basis_dim[degree]; basis->vectors = polymec_malloc(sizeof(polynomial_vector_t) * basis->dim); GC_register_finalizer(basis, div_free_poly_basis_free, basis, NULL, NULL); // Construct the naive monomial basis. for (int i = 0; i < basis->dim; ++i) { basis->vectors[i].x = polynomial_from_monomials(degree, 1, &x_poly_coeffs[degree][i], &x_poly_x_powers[degree][i], &x_poly_y_powers[degree][i], &x_poly_z_powers[degree][i], NULL); basis->vectors[i].y = polynomial_from_monomials(degree, 1, &y_poly_coeffs[degree][i], &y_poly_x_powers[degree][i], &y_poly_y_powers[degree][i], &y_poly_z_powers[degree][i], NULL); basis->vectors[i].z = polynomial_from_monomials(degree, 1, &z_poly_coeffs[degree][i], &z_poly_x_powers[degree][i], &z_poly_y_powers[degree][i], &z_poly_z_powers[degree][i], NULL); } // Perform a Gram-Schmidt orthogonalization. gram_schmidt(basis); return basis; }
/*=========================================================================== * francisQRstep * This algorithm performs the Francis QR Step to find the eigen values * of a square matrix. * * I don't know what this algorithm should produce and I just read this * technique on wikipedia. Currently I have this method to test the * approach. *=========================================================================*/ matrix* francisQRstep(matrix* a) { int i, j, k = 0; int upper_triangle; const double EPSILON = 0.001; matrix* a_k; // Matrix A_k matrix* a_kp1; // Matrix A_(k+1) matrix* q = NULL; matrix* r = NULL; matrix* out; double* ptr; double* outPtr; assert(a->width == a->height, "Matrix must be square."); out = makeMatrix(1, a->height); a_k = copyMatrix(a); while (1) { // Perform the QR decomposition of a_k printf("Loop.\n"); gram_schmidt(a_k, &q, &r); // a_kp1 is the product of r * q a_kp1 = multiplyMatrix(r, q); // And the cleanup freeMatrix(a_k); freeMatrix(q); freeMatrix(r); a_k = copyMatrix(a_kp1); freeMatrix(a_kp1); q = NULL; r = NULL; printMatrix(a_k); // Test for completion. // We need to make sure this is an upper triangular matrix upper_triangle = 1; // TRUE for (i = 1; i < a_k->height; i++) { for (j = 0; j < i; j++) { if (fabs(a_k->data[i * a_k->width + j]) >= EPSILON) { upper_triangle = 0; // FALSE break; } } if (upper_triangle == 0) { break; } } if (upper_triangle == 1) { break; } k++; } // Gather up all of the elements along the diagonal. ptr = a_k->data; outPtr = out->data; for (i = 0; i < a_k->width; i++) { *outPtr = *ptr; outPtr++; ptr += a_k->width + 1; } // Sort the eigen values quicksort(out->data, 0, out->width * out->height - 1); freeMatrix(a_k); return out; }