int count_vec(const spiro_seg *s, int nseg) { int i; int n = 0; for (i = 0; i < nseg; i++) n += compute_jinc(s[i].ty, s[i + 1].ty); return n; }
static double spiro_iter(spiro_seg *s, bandmat *m, int *perm, double *v, int n, int nmat) { int cyclic, i, j, jthl, jthr, jk0l, jk0r, jk1l, jk1r, jk2l, jk2r, jinc, jj, k, n_invert; char ty0, ty1; double dk, norm, th; double ends[2][4]; double derivs[4][2][4]; cyclic = s[0].ty != '{' && s[0].ty != 'v'; for (i = 0; i < nmat; i++) { v[i] = 0.; for (j = 0; j < 11; j++) m[i].a[j] = 0.; for (j = 0; j < 5; j++) m[i].al[j] = 0.; } j = 0; if (s[0].ty == 'o') jj = nmat - 2; else if (s[0].ty == 'c') jj = nmat - 1; else jj = 0; for (i = 0; i < n; i++) { ty0 = s[i].ty; ty1 = s[i + 1].ty; jinc = compute_jinc(ty0, ty1); th = s[i].bend_th; jthl = jk0l = jk1l = jk2l = -1; jthr = jk0r = jk1r = jk2r = -1; compute_pderivs(&s[i], ends, derivs, jinc); /* constraints crossing left */ if (ty0 == 'o' || ty0 == 'c' || ty0 == '[' || ty0 == ']' || \ ty0 == 'a' || ty0 == 'h') { jthl = jj++; jj %= nmat; jk0l = jj++; if (ty0 == 'o') { jj %= nmat; jk1l = jj++; jk2l = jj++; } } /* constraints on left */ if ((ty0 == '[' || ty0 == 'v' || ty0 == '{' || ty0 == 'c' || \ ty0 == 'a') && jinc == 4) { if (ty0 != 'c') jk1l = jj++; jk2l = jj++; } /* constraints on right */ if ((ty1 == ']' || ty1 == 'v' || ty1 == '}' || ty1 == 'c' || \ ty1 == 'h') && jinc == 4) { if (ty1 != 'c') jk1r = jj++; jk2r = jj++; } /* constraints crossing right */ if (ty1 == 'o' || ty1 == 'c' || ty1 == '[' || ty1 == ']' || \ ty1 == 'a' || ty1 == 'h') { jthr = jj; jk0r = (jj + 1) % nmat; if (ty1 == 'o') { jk1r = (jj + 2) % nmat; jk2r = (jj + 3) % nmat; } } add_mat_line(m, v, derivs[0][0], th - ends[0][0], 1, j, jthl, jinc, nmat); add_mat_line(m, v, derivs[1][0], ends[0][1], -1, j, jk0l, jinc, nmat); add_mat_line(m, v, derivs[2][0], ends[0][2], -1, j, jk1l, jinc, nmat); add_mat_line(m, v, derivs[3][0], ends[0][3], -1, j, jk2l, jinc, nmat); add_mat_line(m, v, derivs[0][1], -ends[1][0], 1, j, jthr, jinc, nmat); add_mat_line(m, v, derivs[1][1], -ends[1][1], 1, j, jk0r, jinc, nmat); add_mat_line(m, v, derivs[2][1], -ends[1][2], 1, j, jk1r, jinc, nmat); add_mat_line(m, v, derivs[3][1], -ends[1][3], 1, j, jk2r, jinc, nmat); if (jthl >= 0) v[jthl] = mod_2pi(v[jthl]); if (jthr >= 0) v[jthr] = mod_2pi(v[jthr]); j += jinc; } if (cyclic) { memcpy(m + nmat, m, sizeof(bandmat) * nmat); memcpy(m + 2 * nmat, m, sizeof(bandmat) * nmat); memcpy(v + nmat, v, sizeof(double) * nmat); memcpy(v + 2 * nmat, v, sizeof(double) * nmat); n_invert = 3 * nmat; j = nmat; #ifdef VERBOSE printf("cyclic\n"); #endif } else { n_invert = nmat; j = 0; } #ifdef VERBOSE for (i = 0; i < n; i++) { for (k = 0; k < 11; k++) printf(" %2.4f", m[i].a[k]); printf(": %2.4f\n", v[i]); } printf("---\n"); #endif bandec11(m, perm, n_invert); banbks11(m, perm, v, n_invert); norm = 0.; for (i = 0; i < n; i++) { jinc = compute_jinc(s[i].ty, s[i + 1].ty); for (k = 0; k < jinc; k++) { dk = v[j++]; #ifdef VERBOSE printf("s[%d].ks[%d] += %f\n", i, k, dk); #endif s[i].ks[k] += dk; norm += dk * dk; } s[i].ks[0] = 2.0 * mod_2pi(s[i].ks[0]/2.0); } return norm; }