2 static void /* sum coefficients less than res */
3 eval(projUV
**w
, int nu
, int nv
, double res
, projUV
*resid
) {
8 resid
->u
= resid
->v
= 0.;
9 for (i
= 0; i
< nu
; ++i
)
10 for (s
= w
[i
], j
= 0; j
< nv
; ++j
, ++s
) {
11 if ((ab
= fabs(s
->u
)) < res
)
13 if ((ab
= fabs(s
->v
)) < res
)
17 static Tseries
* /* create power series structure */
18 makeT(int nru
, int nrv
) {
22 if ((T
= (Tseries
*)pj_malloc(sizeof(Tseries
))) &&
23 (T
->cu
= (struct PW_COEF
*)pj_malloc(
24 sizeof(struct PW_COEF
) * nru
)) &&
25 (T
->cv
= (struct PW_COEF
*)pj_malloc(
26 sizeof(struct PW_COEF
) * nrv
))) {
27 for (i
= 0; i
< nru
; ++i
)
29 for (i
= 0; i
< nrv
; ++i
)
36 mk_cheby(projUV a
, projUV b
, double res
, projUV
*resid
, projUV (*func
)(projUV
),
37 int nu
, int nv
, int power
) {
38 int j
, i
, nru
, nrv
, *ncu
, *ncv
;
43 if (!(w
= (projUV
**)vector2(nu
, nv
, sizeof(projUV
))) ||
44 !(ncu
= (int *)vector1(nu
+ nv
, sizeof(int))))
47 if (!bchgen(a
, b
, nu
, nv
, w
, func
)) {
51 /* analyse coefficients and adjust until residual OK */
53 for (i
= 4; i
; --i
) {
54 eval(w
, nu
, nv
, cutres
, resid
);
55 if (resid
->u
< res
&& resid
->v
< res
)
59 if (i
<= 0) /* warn of too many tries */
60 resid
->u
= - resid
->u
;
61 /* apply cut resolution and set pointers */
63 for (j
= 0; j
< nu
; ++j
) {
64 ncu
[j
] = ncv
[j
] = 0; /* clear column maxes */
65 for (s
= w
[j
], i
= 0; i
< nv
; ++i
, ++s
) {
66 if ((ab
= fabs(s
->u
)) < cutres
) /* < resolution ? */
67 s
->u
= 0.; /* clear coefficient */
69 ncu
[j
] = i
+ 1; /* update column max */
70 if ((ab
= fabs(s
->v
)) < cutres
) /* same for v coef's */
75 if (ncu
[j
]) nru
= j
+ 1; /* update row max */
76 if (ncv
[j
]) nrv
= j
+ 1;
78 if (power
) { /* convert to bivariate power series */
79 if (!bch2bps(a
, b
, w
, nu
, nv
))
81 /* possible change in some row counts, so readjust */
83 for (j
= 0; j
< nu
; ++j
) {
84 ncu
[j
] = ncv
[j
] = 0; /* clear column maxes */
85 for (s
= w
[j
], i
= 0; i
< nv
; ++i
, ++s
) {
87 ncu
[j
] = i
+ 1; /* update column max */
91 if (ncu
[j
]) nru
= j
+ 1; /* update row max */
92 if (ncv
[j
]) nrv
= j
+ 1;
94 if ((T
= makeT(nru
, nrv
)) != NULL
) {
100 for (i
= 0; i
< nru
; ++i
) /* store coefficient rows for u */
102 if ((T
->cu
[i
].m
= ncu
[i
]) != 0)
104 if ((p
= T
->cu
[i
].c
=
105 (double *)pj_malloc(sizeof(double) * ncu
[i
])))
106 for (j
= 0; j
< ncu
[i
]; ++j
)
107 *p
++ = (w
[i
] + j
)->u
;
112 for (i
= 0; i
< nrv
; ++i
) /* same for v */
114 if ((T
->cv
[i
].m
= ncv
[i
]) != 0)
116 if ((p
= T
->cv
[i
].c
=
117 (double *)pj_malloc(sizeof(double) * ncv
[i
])))
118 for (j
= 0; j
< ncv
[i
]; ++j
)
119 *p
++ = (w
[i
] + j
)->v
;
125 } else if ((T
= makeT(nru
, nrv
)) != NULL
) {
126 /* else make returned Chebyshev coefficient structure */
127 T
->mu
= nru
- 1; /* save row degree */
129 T
->a
.u
= a
.u
+ b
.u
; /* set argument scaling */
131 T
->b
.u
= 1. / (b
.u
- a
.u
);
132 T
->b
.v
= 1. / (b
.v
- a
.v
);
134 for (i
= 0; i
< nru
; ++i
) /* store coefficient rows for u */
136 if ((T
->cu
[i
].m
= ncu
[i
]) != 0)
138 if ((p
= T
->cu
[i
].c
=
139 (double *)pj_malloc(sizeof(double) * ncu
[i
])))
140 for (j
= 0; j
< ncu
[i
]; ++j
)
141 *p
++ = (w
[i
] + j
)->u
;
146 for (i
= 0; i
< nrv
; ++i
) /* same for v */
148 if ((T
->cv
[i
].m
= ncv
[i
]) != 0)
150 if ((p
= T
->cv
[i
].c
=
151 (double *)pj_malloc(sizeof(double) * ncv
[i
])))
152 for (j
= 0; j
< ncv
[i
]; ++j
)
153 *p
++ = (w
[i
] + j
)->v
;
163 if (T
) { /* pj_dalloc up possible allocations */
164 for (i
= 0; i
<= T
->mu
; ++i
)
166 pj_dalloc(T
->cu
[i
].c
);
167 for (i
= 0; i
<= T
->mv
; ++i
)
169 pj_dalloc(T
->cv
[i
].c
);
174 freev2((void **) w
, nu
);