void incomplete_qr(int m, int n, const int *Acolstart, const int *Arowindex, const double *Avalue, double Qdroptol, const int *Rcolstart, const int *Rrowindex, double *Rvalue, double *Rdiag) { // column storage for intermediate Q std::vector<StaticSparseVector> Q(n); // for each column of Q, how many more times it will be used in making R // (once this gets decremented to zero, we can free the column) std::vector<int> dependency_count(n,0); for(int i=0; i<n; ++i){ for(int a=Rcolstart[i]; a<Rcolstart[i+1]; ++a){ int j=Rrowindex[a]; if(j<i) ++dependency_count[j]; } } // construct R a column at a time for(int i=0; i<n; ++i){ DynamicSparseVector q; copy_column(Acolstart[i], Acolstart[i+1], Arowindex, Avalue, q); for(int a=Rcolstart[i]; a<Rcolstart[i+1]; ++a){ int j=Rrowindex[a]; if(j<i){ Rvalue[a]=dot_product(Q[j], q); add_to_vector(-Rvalue[a], Q[j], q); --dependency_count[j]; if(dependency_count[j]==0) Q[j].clear(); }else // j>i Rvalue[a]=0; // ideally structure of R is upper triangular, so this waste of space won't happen } Rdiag[i]=vector_norm(q); copy_large_entries(q, Qdroptol*Rdiag[i], Q[i]); normalize(Q[i]); } }
void add_point(face_t *self, const char *point_string) { string_iterator_t *it; int *v; int *vt; int *vn; switch(nb_delimiters(point_string, SUB_DELIMITER)) { // f v1 v2 v3 [v*]* case 0: v = malloc(sizeof(int)); *v = atoi(point_string); add_to_vector(self->vertexes, v); break; // f v1/vt1 v2/vt2 v3/vt3 [v*/vt*]* case 1: it = new_string_iterator(point_string, SUB_DELIMITER); v = malloc(sizeof(int)); vt = malloc(sizeof(int)); if(self->textures == NULL) { self->textures = new_vector(MINIMAL_POINTS); } *v = atoi(it->current_string); add_to_vector(self->vertexes, v); next_string_iterator(it); *vt = atoi(it->current_string); add_to_vector(self->textures, vt); free_string_iterator(it); break; // f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3 [v*/vt*/vn*]* case 2: it = new_string_iterator(point_string, SUB_DELIMITER); v = malloc(sizeof(int)); vt = malloc(sizeof(int)); vn = malloc(sizeof(int)); if(self->textures == NULL) { self->textures = new_vector(MINIMAL_POINTS); } if(self->normals == NULL) { self->normals = new_vector(MINIMAL_POINTS); } *v = atoi(it->current_string); add_to_vector(self->vertexes, v); next_string_iterator(it); *vn = atoi(it->current_string); next_string_iterator(it); // case ?/?/? if(it->good) { *vt = *vn; add_to_vector(self->textures, vt); *vn = atoi(it->current_string); // case ?//? } else { free(vt); free_vector(self->textures); self->textures = NULL; } add_to_vector(self->normals, vn); free_string_iterator(it); break; } }