Statistics
| Revision:

root / trunk / libraries / libjni-proj4 / src / mk_cheby.c @ 8667

History | View | Annotate | Download (4.32 KB)

1
#ifndef lint
2
static const char SCCSID[]="@(#)mk_cheby.c        4.5        94/03/22        GIE        REL";
3
#endif
4
#include <projects.h>
5
        static void /* sum coefficients less than res */
6
eval(projUV **w, int nu, int nv, double res, projUV *resid) {
7
        int i, j;
8
        double ab;
9
        projUV *s;
10

    
11
        resid->u = resid->v = 0.;
12
        for (i = 0; i < nu; ++i)
13
                for (s = w[i], j = 0; j < nv; ++j, ++s) {
14
                        if ((ab = fabs(s->u)) < res)
15
                                resid->u += ab;
16
                        if ((ab = fabs(s->v)) < res)
17
                                resid->v += ab;
18
                }
19
}
20
        static Tseries * /* create power series structure */
21
makeT(int nru, int nrv) {
22
        Tseries *T;
23
        int i;
24

    
25
        if ((T = (Tseries *)pj_malloc(sizeof(Tseries))) &&
26
                (T->cu = (struct PW_COEF *)pj_malloc(
27
                        sizeof(struct PW_COEF) * nru)) &&
28
                (T->cv = (struct PW_COEF *)pj_malloc(
29
                        sizeof(struct PW_COEF) * nrv))) {
30
                for (i = 0; i < nru; ++i)
31
                        T->cu[i].c = 0;
32
                for (i = 0; i < nrv; ++i)
33
                        T->cv[i].c = 0;
34
                return T;
35
        } else
36
                return 0;
37
}
38
        Tseries *
39
mk_cheby(projUV a, projUV b, double res, projUV *resid, projUV (*func)(projUV), 
40
        int nu, int nv, int power) {
41
        int j, i, nru, nrv, *ncu, *ncv;
42
        Tseries *T;
43
        projUV **w;
44
        double cutres;
45

    
46
        if (!(w = (projUV **)vector2(nu, nv, sizeof(projUV))) ||
47
                !(ncu = (int *)vector1(nu + nv, sizeof(int))))
48
                return 0;
49
        ncv = ncu + nu;
50
        if (!bchgen(a, b, nu, nv, w, func)) {
51
                projUV *s;
52
                double ab, *p;
53

    
54
                /* analyse coefficients and adjust until residual OK */
55
                cutres = res;
56
                for (i = 4; i ; --i) {
57
                        eval(w, nu, nv, cutres, resid);
58
                        if (resid->u < res && resid->v < res)
59
                                break;
60
                        cutres *= 0.5;
61
                }
62
                if (i <= 0) /* warn of too many tries */
63
                        resid->u = - resid->u;
64
                /* apply cut resolution and set pointers */
65
                nru = nrv = 0;
66
                for (j = 0; j < nu; ++j) {
67
                        ncu[j] = ncv[j] = 0; /* clear column maxes */
68
                        for (s = w[j], i = 0; i < nv; ++i, ++s) {
69
                                if ((ab = fabs(s->u)) < cutres) /* < resolution ? */
70
                                        s->u = 0.;                /* clear coefficient */
71
                                else
72
                                        ncu[j] = i + 1;        /* update column max */
73
                                if ((ab = fabs(s->v)) < cutres) /* same for v coef's */
74
                                        s->v = 0.;
75
                                else
76
                                        ncv[j] = i + 1;
77
                        }
78
                        if (ncu[j]) nru = j + 1;        /* update row max */
79
                        if (ncv[j]) nrv = j + 1;
80
                }
81
                if (power) { /* convert to bivariate power series */
82
                        if (!bch2bps(a, b, w, nu, nv))
83
                                goto error;
84
                        /* possible change in some row counts, so readjust */
85
                        nru = nrv = 0;
86
                        for (j = 0; j < nu; ++j) {
87
                                ncu[j] = ncv[j] = 0; /* clear column maxes */
88
                                for (s = w[j], i = 0; i < nv; ++i, ++s) {
89
                                        if (s->u)
90
                                                ncu[j] = i + 1;        /* update column max */
91
                                        if (s->v)
92
                                                ncv[j] = i + 1;
93
                                }
94
                                if (ncu[j]) nru = j + 1;        /* update row max */
95
                                if (ncv[j]) nrv = j + 1;
96
                        }
97
                        if (T = makeT(nru, nrv)) {
98
                                T->a = a;
99
                                T->b = b;
100
                                T->mu = nru - 1;
101
                                T->mv = nrv - 1;
102
                                T->power = 1;
103
                                for (i = 0; i < nru; ++i) /* store coefficient rows for u */
104
                                        if (T->cu[i].m = ncu[i])
105
                                                if ((p = T->cu[i].c =
106
                                                                (double *)pj_malloc(sizeof(double) * ncu[i])))
107
                                                        for (j = 0; j < ncu[i]; ++j)
108
                                                                *p++ = (w[i] + j)->u;
109
                                                else
110
                                                        goto error;
111
                                for (i = 0; i < nrv; ++i) /* same for v */
112
                                        if (T->cv[i].m = ncv[i])
113
                                                if ((p = T->cv[i].c =
114
                                                                (double *)pj_malloc(sizeof(double) * ncv[i])))
115
                                                        for (j = 0; j < ncv[i]; ++j)
116
                                                                *p++ = (w[i] + j)->v;
117
                                                else
118
                                                        goto error;
119
                        }
120
                } else if (T = makeT(nru, nrv)) {
121
                        /* else make returned Chebyshev coefficient structure */
122
                        T->mu = nru - 1; /* save row degree */
123
                        T->mv = nrv - 1;
124
                        T->a.u = a.u + b.u; /* set argument scaling */
125
                        T->a.v = a.v + b.v;
126
                        T->b.u = 1. / (b.u - a.u);
127
                        T->b.v = 1. / (b.v - a.v);
128
                        T->power = 0;
129
                        for (i = 0; i < nru; ++i) /* store coefficient rows for u */
130
                                if (T->cu[i].m = ncu[i]) 
131
                                        if ((p = T->cu[i].c =
132
                                                        (double *)pj_malloc(sizeof(double) * ncu[i])))
133
                                                for (j = 0; j < ncu[i]; ++j)
134
                                                        *p++ = (w[i] + j)->u;
135
                                        else
136
                                                goto error;
137
                        for (i = 0; i < nrv; ++i) /* same for v */
138
                                if (T->cv[i].m = ncv[i])
139
                                        if ((p = T->cv[i].c =
140
                                                        (double *)pj_malloc(sizeof(double) * ncv[i])))
141
                                                for (j = 0; j < ncv[i]; ++j)
142
                                                        *p++ = (w[i] + j)->v;
143
                                        else
144
                                                goto error;
145
                } else
146
                        goto error;
147
        }
148
        goto gohome;
149
error:
150
        if (T) { /* pj_dalloc up possible allocations */
151
                for (i = 0; i <= T->mu; ++i)
152
                        if (T->cu[i].c)
153
                                pj_dalloc(T->cu[i].c);
154
                for (i = 0; i <= T->mv; ++i)
155
                        if (T->cv[i].c)
156
                                pj_dalloc(T->cv[i].c);
157
                pj_dalloc(T);
158
        }
159
        T = 0;
160
gohome:
161
        freev2((void **) w, nu);
162
        pj_dalloc(ncu);
163
        return T;
164
}