| 403 | } |
| 404 | |
| 405 | static PJ_UV complex_default_impl(PJ *P, const HORNER *transformation, |
| 406 | PJ_DIRECTION direction, PJ_UV position) { |
| 407 | /*********************************************************************** |
| 408 | |
| 409 | A reimplementation of a classic Engsager/Poder Horner complex |
| 410 | polynomial evaluation engine. |
| 411 | |
| 412 | ***********************************************************************/ |
| 413 | assert(direction == PJ_FWD || direction == PJ_INV); |
| 414 | |
| 415 | double n, e; |
| 416 | if (direction == PJ_FWD) { /* forward */ |
| 417 | e = position.u - transformation->fwd_origin->u; |
| 418 | n = position.v - transformation->fwd_origin->v; |
| 419 | } else { /* inverse */ |
| 420 | e = position.u - transformation->inv_origin->u; |
| 421 | n = position.v - transformation->inv_origin->v; |
| 422 | } |
| 423 | if (transformation->uneg) |
| 424 | e = -e; |
| 425 | if (transformation->vneg) |
| 426 | n = -n; |
| 427 | |
| 428 | if (coords_out_of_range(P, transformation, n, e)) { |
| 429 | return generate_error_coords(); |
| 430 | } |
| 431 | |
| 432 | // coefficient pointers |
| 433 | double *cb = |
| 434 | direction == PJ_FWD ? transformation->fwd_c : transformation->inv_c; |
| 435 | PJ_UV en = {e, n}; |
| 436 | position = complex_horner_eval(transformation->order, cb, en); |
| 437 | return position; |
| 438 | } |
| 439 | |
| 440 | static PJ_UV complex_iterative_inverse_impl(PJ *P, const HORNER *transformation, |
| 441 | PJ_UV position) { |
no test coverage detected