Example #1
0
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;
}
Example #2
0
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;
}