File Coverage

blib/lib/Math/Cephes/Polynomial.pm
Criterion Covered Total %
statement 299 359 83.2
branch 108 194 55.6
condition 10 27 37.0
subroutine 21 23 91.3
pod 1 20 5.0
total 439 623 70.4


line stmt bran cond sub pod time code
1             package Math::Cephes::Polynomial;
2 1     1   5479 use strict;
  1         3  
  1         56  
3 1     1   7 use warnings;
  1         9  
  1         70  
4 1     1   6 use vars qw(@EXPORT_OK $VERSION $MAXPOL $FMAXPOL $flag $fflag);
  1         2  
  1         5394  
5             eval {require Math::Complex; import Math::Complex qw(Re Im)};
6             eval {local $^W=0; require Math::Fraction;};
7             $MAXPOL = 256;
8             $flag = 0;
9             $FMAXPOL = 256;
10             $fflag = 0;
11              
12             require Exporter;
13             *import = \&Exporter::import;
14             @EXPORT_OK = qw(poly);
15             $VERSION = '0.5308';
16              
17             require Math::Cephes;
18             require Math::Cephes::Fraction;
19             require Math::Cephes::Complex;
20              
21             sub new {
22 40     40 0 179168 my ($caller, $arr) = @_;
23 40         90 my $refer = ref($caller);
24 40   66     167 my $class = $refer || $caller;
25 40 50 66     217 die "Must supply data for the polynomial"
26             unless ($refer or $arr);
27 40         64 my ($type, $ref, $data, $n);
28 40 100       77 if ($refer) {
29             ($type, $ref, $n) =
30 2         7 ($caller->{type}, $caller->{ref}, $caller->{n});
31 2         5 my $cdata = $caller->{data};
32 2 100       7 if (ref($cdata) eq 'ARRAY') {
33 1         4 $data = [ @$cdata ];
34             }
35             else {
36 1 50       4 my ($f, $s) = ($type eq 'fract') ? ('n', 'd') : ('r', 'i');
37 1         4 $data = {$f => [ @{$cdata->{$f}} ],
38 1         46 $s => [ @{$cdata->{$s}} ],
  1         3  
39             };
40             }
41             }
42             else {
43 38         76 ($type, $ref, $data, $n) = get_data($arr);
44             }
45 40         307 bless { type => $type,
46             ref => $ref,
47             data => $data,
48             n => $n,
49             }, $class;
50             }
51              
52             sub poly {
53 0     0 0 0 return Math::Cephes::Polynomial->new(shift);
54             }
55              
56             sub coef {
57 35     35 0 196 return $_[0]->{data};
58             }
59              
60             sub get_data {
61 39     39 0 73 my ($arr, $ref_in) = @_;
62 39 50       105 die "Must supply an array reference" unless ref($arr) eq 'ARRAY';
63 39         66 my $n = scalar @$arr - 1;
64 39         69 my $ref = ref($arr->[0]);
65 39 50 66     99 die "array data must be of type '$ref_in'"
66             if (defined $ref_in and $ref_in ne $ref);
67 39         63 my ($type, $data);
68             SWITCH: {
69 39 100       80 not $ref and do {
  39         80  
70 21         41 $type = 'scalar';
71 21         46 foreach (@$arr) {
72 3124 50       5759 die 'Found conflicting types in array data'
73             if ref($_);
74             }
75 21         36 $data = $arr;
76 21 100       47 set_max() unless $flag;
77 21         46 last SWITCH;
78             };
79 18 100       49 $ref eq 'Math::Cephes::Complex' and do {
80 5         9 $type = 'cmplx';
81 5         11 foreach (@$arr) {
82 15 50       31 die 'Found conflicting types in array data'
83             unless ref($_) eq $ref;
84 15 50 33     28 die "array data must be of type '$ref_in'"
85             if (defined $ref_in and $ref_in ne $ref);
86 15         21 push @{$data->{r}}, $_->r;
  15         33  
87 15         26 push @{$data->{i}}, $_->i;
  15         31  
88             }
89 5 50       13 set_max() unless $flag;
90 5         8 last SWITCH;
91             };
92 13 100       27 $ref eq 'Math::Complex' and do {
93 3         4 $type = 'cmplx';
94 3         7 foreach (@$arr) {
95 9 50       68 die 'Found conflicting types in array data'
96             unless ref($_) eq $ref;
97 9 50 33     15 die "array data must be of type '$ref_in'"
98             if (defined $ref_in and $ref_in ne $ref);
99 9         14 push @{$data->{r}}, Re($_);
  9         23  
100 9         85 push @{$data->{i}}, Im($_);
  9         20  
101             }
102 3 50       28 set_max() unless $flag;
103 3         7 last SWITCH;
104             };
105 10 50       20 $ref eq 'Math::Cephes::Fraction' and do {
106 10         13 $type = 'fract';
107 10         21 foreach (@$arr) {
108 33 50       76 die 'Found conflicting types in array data'
109             unless ref($_) eq $ref;
110 33 50 33     63 die "array data must be of type '$ref_in'"
111             if (defined $ref_in and $ref_in ne $ref);
112 33         67 my ($gcd, $n, $d) = Math::Cephes::euclid($_->n, $_->d);
113 33         65 push @{$data->{n}}, $n;
  33         56  
114 33         47 push @{$data->{d}}, $d;
  33         68  
115             }
116 10 100       21 set_fmax() unless $fflag;
117 10         19 last SWITCH;
118             };
119 0 0       0 $ref eq 'Math::Fraction' and do {
120 0         0 $type = 'fract';
121 0         0 foreach (@$arr) {
122 0 0       0 die 'Found conflicting types in array data'
123             unless ref($_) eq $ref;
124 0 0 0     0 die "array data must be of type '$ref_in'"
125             if (defined $ref_in and $ref_in ne $ref);
126 0         0 push @{$data->{n}}, $_->{frac}->[0];
  0         0  
127 0         0 push @{$data->{d}}, $_->{frac}->[1];
  0         0  
128             }
129 0 0       0 set_fmax() unless $fflag;
130 0         0 last SWITCH;
131             };
132 0         0 die "Unknown type '$ref' in array data";
133             }
134 39         130 return ($type, $ref, $data, $n);
135             }
136              
137             sub as_string {
138 0     0 0 0 my $self = shift;
139             my ($type, $data, $n) =
140 0         0 ($self->{type}, $self->{data}, $self->{n});
141 0   0     0 my $d = shift || $n;
142 0 0       0 $d = $n if $d > $n;
143 0         0 my $string;
144 0         0 for (my $j=0; $j<=$d; $j++) {
145 0         0 my $coef;
146             SWITCH: {
147 0 0       0 $type eq 'fract' and do {
  0         0  
148 0         0 my $n = $data->{n}->[$j];
149 0         0 my $d = $data->{d}->[$j];
150 0 0       0 my $sgn = $n < 0 ? ' -' : ' +';
151 0 0       0 $coef = $sgn . ($j == 0? '(' : ' (') .
152             abs($n) . '/' . abs($d) . ')';
153 0         0 last SWITCH;
154             };
155 0 0       0 $type eq 'cmplx' and do {
156 0         0 my $re = $data->{r}->[$j];
157 0         0 my $im = $data->{i}->[$j];
158 0 0       0 my $sgn = $j == 0 ? ' ' : ' + ';
159 0 0       0 $coef = $sgn . '(' . $re .
    0          
160             ( (int( $im / abs($im) ) == -1) ? '-' : '+' ) .
161             ( ($im < 0) ? abs($im) : $im) . 'I)';
162 0         0 last SWITCH;
163             };
164 0         0 my $f = $data->[$j];
165 0 0       0 my $sgn = $f < 0 ? ' -' : ' +';
166 0 0       0 $coef = $j == 0 ? ' ' . $f :
167             $sgn . ' ' . abs($f);
168             }
169 0 0       0 $string .= $coef . ($j > 0 ? "x^$j" : '');
170             }
171 0         0 return $string . "\n";
172             }
173              
174             sub add {
175 3     3 1 144 my ($self, $b) = @_;
176             my ($atype, $aref, $adata, $na) =
177 3         11 ($self->{type}, $self->{ref}, $self->{data}, $self->{n});
178             my ($btype, $bref, $bdata, $nb) =
179             ref($b) eq 'Math::Cephes::Polynomial' ?
180 3 100       45 ($b->{type}, $b->{ref}, $b->{data}, $b->{n}) :
181             get_data($b, $aref);
182 3         5 my $c = [];
183 3         6 my $nc;
184             SWITCH: {
185 3 100       6 $atype eq 'fract' and do {
  3         10  
186 1 50       13 $nc = $na > $nb ? $na: $nb;
187 1         6 my $cn = [split //, 0 x ($nc+1)];
188 1         5 my $cd = [split //, 0 x ($nc+1)];
189             Math::Cephes::fpoladd_wrap($adata->{n}, $adata->{d}, $na,
190 1         21 $bdata->{n}, $bdata->{d}, $nb,
191             $cn, $cd, $nc);
192 1         5 for (my $i=0; $i<=$nc; $i++) {
193 3         9 my ($gcd, $n, $d) = Math::Cephes::euclid($cn->[$i], $cd->[$i]);
194 3 50       9 push @$c, ($aref eq 'Math::Fraction' ?
195             Math::Fraction->new($n, $d) :
196             Math::Cephes::Fraction->new($n, $d) );
197             }
198 1         4 last SWITCH;
199             };
200 2 100       6 $atype eq 'cmplx' and do {
201 1 50       5 $nc = $na > $nb ? $na: $nb;
202 1         5 my $cr = [split //, 0 x ($nc+1)];
203 1         4 my $ci = [split //, 0 x ($nc+1)];
204             Math::Cephes::poladd($adata->{r}, $na,
205 1         13 $bdata->{r}, $nb, $cr);
206             Math::Cephes::poladd($adata->{i}, $na,
207 1         8 $bdata->{i}, $nb, $ci);
208 1         3 for (my $i=0; $i<=$nc; $i++) {
209 3 50       10 push @$c, ($aref eq 'Math::Complex' ?
210             Math::Complex->make($cr->[$i], $ci->[$i]) :
211             Math::Cephes::Complex->new($cr->[$i], $ci->[$i]) );
212             }
213 1         4 last SWITCH;
214             };
215 1 50       4 $nc = $na > $nb ? $na + 1 : $nb + 1;
216 1         8 $c = [split //, 0 x $nc];
217 1         19 Math::Cephes::poladd($adata, $na, $bdata, $nb, $c);
218             }
219 3 50       14 return wantarray ? (Math::Cephes::Polynomial->new($c), $nc) :
220             Math::Cephes::Polynomial->new($c);
221              
222             }
223              
224             sub sub {
225 3     3 0 246 my ($self, $b) = @_;
226             my ($atype, $aref, $adata, $na) =
227 3         37 ($self->{type}, $self->{ref}, $self->{data}, $self->{n});
228             my ($btype, $bref, $bdata, $nb) =
229             ref($b) eq 'Math::Cephes::Polynomial' ?
230 3 50       14 ($b->{type}, $b->{ref}, $b->{data}, $b->{n}) :
231             get_data($b, $aref);
232 3         6 my $c = [];
233 3         5 my $nc;
234             SWITCH: {
235 3 100       5 $atype eq 'fract' and do {
  3         11  
236 1 50       4 $nc = $na > $nb ? $na: $nb;
237 1         4 my $cn = [split //, 0 x ($nc+1)];
238 1         4 my $cd = [split //, 0 x ($nc+1)];
239             Math::Cephes::fpolsub_wrap($bdata->{n}, $bdata->{d}, $nb,
240 1         24 $adata->{n}, $adata->{d}, $na,
241             $cn, $cd, $nc);
242 1         4 for (my $i=0; $i<=$nc; $i++) {
243 3         10 my ($gcd, $n, $d) = Math::Cephes::euclid($cn->[$i], $cd->[$i]);
244 3 50       9 push @$c, ($aref eq 'Math::Fraction' ?
245             Math::Fraction->new($n, $d) :
246             Math::Cephes::Fraction->new($n, $d) );
247             }
248 1         3 last SWITCH;
249             };
250 2 100       6 $atype eq 'cmplx' and do {
251 1 50       4 $nc = $na > $nb ? $na: $nb;
252 1         5 my $cr = [split //, 0 x ($nc+1)];
253 1         4 my $ci = [split //, 0 x ($nc+1)];
254             Math::Cephes::polsub($bdata->{r}, $nb,
255 1         10 $adata->{r}, $na, $cr);
256             Math::Cephes::polsub($bdata->{i}, $nb,
257 1         8 $adata->{i}, $na, $ci);
258 1         4 for (my $i=0; $i<=$nc; $i++) {
259 3 50       30 push @$c, ($aref eq 'Math::Complex' ?
260             Math::Complex->make($cr->[$i], $ci->[$i]) :
261             Math::Cephes::Complex->new($cr->[$i], $ci->[$i]) );
262             }
263 1         3 last SWITCH;
264             };
265 1 50       4 $nc = $na > $nb ? $na + 1 : $nb + 1;
266 1         8 $c = [split //, 0 x $nc];
267 1         14 Math::Cephes::polsub($bdata, $nb, $adata, $na, $c);
268             }
269 3 50       15 return wantarray ? (Math::Cephes::Polynomial->new($c), $nc) :
270             Math::Cephes::Polynomial->new($c);
271              
272             }
273              
274             sub mul {
275 4     4 0 132 my ($self, $b) = @_;
276             my ($atype, $aref, $adata, $na) =
277 4         28 ($self->{type}, $self->{ref}, $self->{data}, $self->{n});
278             my ($btype, $bref, $bdata, $nb) =
279             ref($b) eq 'Math::Cephes::Polynomial' ?
280 4 50       47 ($b->{type}, $b->{ref}, $b->{data}, $b->{n}) :
281             get_data($b, $aref);
282 4         8 my $c = [];
283 4         7 my $nc;
284             SWITCH: {
285 4 100       7 $atype eq 'fract' and do {
  4         10  
286 1         3 $nc = $na + $nb;
287 1         6 my $cn = [split //, 0 x ($nc+1)];
288 1         4 my $cd = [split //, 1 x ($nc+1)];
289             Math::Cephes::fpolmul_wrap($adata->{n}, $adata->{d}, $na,
290 1         20 $bdata->{n}, $bdata->{d}, $nb,
291             $cn, $cd, $nc);
292 1         4 for (my $i=0; $i<=$nc; $i++) {
293 4         14 my ($gcd, $n, $d) = Math::Cephes::euclid($cn->[$i], $cd->[$i]);
294 4 50       11 push @$c, ($aref eq 'Math::Fraction' ?
295             Math::Fraction->new($n, $d) :
296             Math::Cephes::Fraction->new($n, $d) );
297             }
298 1         3 last SWITCH;
299             };
300 3 100       8 $atype eq 'cmplx' and do {
301 2         5 my $dc = $na + $nb + 3;
302 2         11 my $cr = [split //, 0 x $dc];
303 2         10 my $ci = [split //, 0 x $dc];
304             $nc = Math::Cephes::cpmul_wrap($adata->{r}, $adata->{i}, $na+1,
305 2         38 $bdata->{r}, $bdata->{i}, $nb+1,
306             $cr, $ci, $dc);
307 2         7 $cr = [ @{$cr}[0..$nc] ];
  2         4  
308 2         5 $ci = [ @{$ci}[0..$nc] ];
  2         19  
309 2         7 for (my $i=0; $i<=$nc; $i++) {
310 8 100       154 push @$c, ($aref eq 'Math::Complex' ?
311             Math::Complex->make($cr->[$i], $ci->[$i]) :
312             Math::Cephes::Complex->new($cr->[$i], $ci->[$i]) );
313             }
314 2         41 last SWITCH;
315             };
316 1         3 $nc = $na + $nb + 1;
317 1         7 $c = [split //, 0 x $nc];
318 1         16 Math::Cephes::polmul($adata, $na, $bdata, $nb, $c);
319             }
320 4 50       15 return wantarray ? (Math::Cephes::Polynomial->new($c), $nc) :
321             Math::Cephes::Polynomial->new($c);
322             }
323              
324             sub div {
325 1     1 0 27 my ($self, $b) = @_;
326             my ($atype, $aref, $adata, $na) =
327 1         4 ($self->{type}, $self->{ref}, $self->{data}, $self->{n});
328             my ($btype, $bref, $bdata, $nb) =
329             ref($b) eq 'Math::Cephes::Polynomial' ?
330 1 50       8 ($b->{type}, $b->{ref}, $b->{data}, $b->{n}) :
331             get_data($b, $aref);
332 1         3 my $c = [];
333 1         2 my $nc;
334             SWITCH: {
335 1 50       2 $atype eq 'fract' and do {
  1         4  
336 0         0 $nc = $MAXPOL;
337 0         0 my $cn = [split //, 0 x ($nc+1)];
338 0         0 my $cd = [split //, 0 x ($nc+1)];
339             Math::Cephes::fpoldiv_wrap($adata->{n}, $adata->{d}, $na,
340 0         0 $bdata->{n}, $bdata->{d}, $nb,
341             $cn, $cd, $nc);
342 0         0 for (my $i=0; $i<=$nc; $i++) {
343 0         0 my ($gcd, $n, $d) = Math::Cephes::euclid($cn->[$i], $cd->[$i]);
344 0 0       0 push @$c, ($aref eq 'Math::Fraction' ?
345             Math::Fraction->new($n, $d) :
346             Math::Cephes::Fraction->new($n, $d) );
347             }
348 0         0 last SWITCH;
349             };
350 1 50       4 $atype eq 'cmplx' and do {
351 0         0 die "Cannot do complex division";
352 0         0 last SWITCH;
353             };
354 1         2 $nc = $MAXPOL;
355 1         134 $c = [split //, 0 x ($nc+1)];
356 1         291 Math::Cephes::poldiv($adata, $na, $bdata, $nb, $c);
357             }
358 1 50       10 return wantarray ? (Math::Cephes::Polynomial->new($c), $nc) :
359             Math::Cephes::Polynomial->new($c);
360             }
361              
362             sub clr {
363 2     2 0 72 my $self = shift;
364             my ($atype, $aref, $adata, $na) =
365 2         14 ($self->{type}, $self->{ref}, $self->{data}, $self->{n});
366 2 50       8 set_max() unless $flag;
367 2   33     7 my $n = shift || $na;
368 2 100       8 $n = $na if $n > $na;
369             SWITCH: {
370 2 100       2 $atype eq 'fract' and do {
  2         7  
371 1         4 for (my $i=0; $i<=$n; $i++) {
372 2         15 $self->{data}->{n}->[$i] = 0;
373 2         5 $self->{data}->{d}->[$i] = 1;
374             }
375 1         3 last SWITCH;
376             };
377 1 50       19 $atype eq 'cmplx' and do {
378 0         0 for (my $i=0; $i<=$n; $i++) {
379 0         0 $self->{data}->{r}->[$i] = 0;
380 0         0 $self->{data}->{i}->[$i] = 0;
381             }
382 0         0 last SWITCH;
383             };
384 1         6 for (my $i=0; $i<=$n; $i++) {
385 3         11 $self->{data}->[$i] = 0;
386             }
387             }
388             }
389              
390             sub sbt {
391 3     3 0 39 my ($self, $b) = @_;
392             my ($atype, $aref, $adata, $na) =
393 3         11 ($self->{type}, $self->{ref}, $self->{data}, $self->{n});
394             my ($btype, $bref, $bdata, $nb) =
395             ref($b) eq 'Math::Cephes::Polynomial' ?
396 3 50       14 ($b->{type}, $b->{ref}, $b->{data}, $b->{n}) :
397             get_data($b, $aref);
398 3 50       8 set_max() unless $flag;
399 3         16 my $c = [];
400 3         6 my $nc;
401             SWITCH: {
402 3 100       5 $atype eq 'fract' and do {
  3         10  
403 2         5 $nc = ($na+1)*($nb+1);
404 2         11 my $cn = [split //, 0 x ($nc+1)];
405 2         11 my $cd = [split //, 0 x ($nc+1)];
406             Math::Cephes::fpolsbt_wrap($bdata->{n}, $bdata->{d}, $nb,
407 2         48 $adata->{n}, $adata->{d}, $na,
408             $cn, $cd, $nc);
409 2         11 $nc = $na * $nb;
410 2         6 for (my $i=0; $i<=$nc; $i++) {
411 6         18 my ($gcd, $n, $d) = Math::Cephes::euclid($cn->[$i], $cd->[$i]);
412 6 50       19 push @$c, ($aref eq 'Math::Fraction' ?
413             Math::Fraction->new($n, $d) :
414             Math::Cephes::Fraction->new($n, $d) );
415             }
416 2         6 last SWITCH;
417             };
418 1 50       4 $atype eq 'cmplx' and do {
419 0         0 die "Cannot do complex substitution";
420 0         0 last SWITCH;
421             };
422 1         4 $nc = ($na+1)*($nb+1);
423 1         9 $c = [split //, 0 x $nc];
424 1         20 Math::Cephes::polsbt($bdata, $nb, $adata, $na, $c);
425 1         2 $nc = $na*$nb;
426 1         7 $c = [@$c[0..$nc]];
427             }
428 3 50       13 return wantarray ? (Math::Cephes::Polynomial->new($c), $nc) :
429             Math::Cephes::Polynomial->new($c);
430             }
431              
432             sub set_max {
433 1     1 0 66 Math::Cephes::polini($MAXPOL);
434 1         3 $flag = 1;
435             }
436              
437             sub set_fmax {
438 1     1 0 19 Math::Cephes::fpolini($FMAXPOL);
439 1         2 $fflag = 1;
440             }
441              
442             sub eval {
443 10     10 0 589 my $self = shift;
444 10         17 my $x = 0 || shift;
445             my ($atype, $aref, $adata, $na) =
446 10         32 ($self->{type}, $self->{ref}, $self->{data}, $self->{n});
447 10         15 my $y;
448             SWITCH: {
449 10 100       15 $atype eq 'fract' and do {
  10         30  
450 4         7 my $xref = ref($x);
451 4         11 $y = Math::Cephes::Fraction->new(0, 1);
452             FRACT: {
453 4 100       8 not $xref and do {
  4         10  
454 2         5 $x = Math::Cephes::Fraction->new($x, 1);
455 2         4 last FRACT;
456             };
457 2 50       5 $xref eq 'Math::Cephes::Fraction' and do {
458 2         3 last FRACT;
459             };
460 0 0       0 $xref eq 'Math::Fraction' and do {
461 0         0 $x = Math::Cephes::Fraction->new($x->{frac}->[0], $x->{frac}->[1]);
462 0         0 last FRACT;
463             };
464 0         0 die "Unknown data type '$xref' for x";
465             }
466 4         46 Math::Cephes::fpoleva_wrap($adata->{n}, $adata->{d}, $na, $x, $y);
467 4 50       18 $y = Math::Fraction->new($y->n, $y->d) if $aref eq 'Math::Fraction';
468 4         6 last SWITCH;
469             };
470 6 100       14 $atype eq 'cmplx' and do {
471 2         12 my $r = Math::Cephes::poleva($adata->{r}, $na, $x);
472 2         7 my $i = Math::Cephes::poleva($adata->{i}, $na, $x);
473 2 100       18 $y = $aref eq 'Math::Complex' ?
474             Math::Complex->make($r, $i) :
475             Math::Cephes::Complex->new($r, $i);
476 2         71 last SWITCH;
477             };
478 4         32 $y = Math::Cephes::poleva($adata, $na, $x);
479             }
480 10         33 return $y;
481             }
482              
483             sub fract_to_real {
484 9     9 0 16 my $in = shift;
485 9         14 my $a = [];
486 9         12 my $n = scalar @{$in->{n}} - 1;
  9         17  
487 9         39 for (my $i=0; $i<=$n; $i++) {
488 39         113 push @$a, $in->{n}->[$i] / $in->{d}->[$i];
489             }
490 9         14 return $a;
491             }
492              
493             sub atn {
494 2     2 0 129 my ($self, $bin) = @_;
495 2         6 my $type = $self->{type};
496 2 50       6 die "Cannot take the atan of a complex polynomial"
497             if $type eq 'cmplx';
498 2         5 my ($a, $b);
499             my ($atype, $aref, $adata, $na) =
500 2         6 ($self->{type}, $self->{ref}, $self->{data}, $self->{n});
501 2 50       7 die "Cannot take the atan of a complex polynomial"
502             if $atype eq 'cmplx';
503 2 100       7 $a = $atype eq 'fract' ? fract_to_real($adata) : $adata;
504              
505             my ($btype, $bref, $bdata, $nb) =
506             ref($bin) eq 'Math::Cephes::Polynomial' ?
507 2 50       10 ($bin->{type}, $bin->{ref}, $bin->{data}, $bin->{n}) :
508             get_data($bin);
509              
510 2 50       7 die "Cannot take the atan of a complex polynomial"
511             if $btype eq 'cmplx';
512 2 100       7 $b = $btype eq 'fract' ? fract_to_real($bdata) : $bdata;
513              
514 2         177 my $c = [split //, 0 x ($MAXPOL+1)];
515 2         2059 Math::Cephes::polatn($a, $b, $c, 16);
516 2         14 return Math::Cephes::Polynomial->new($c);
517             }
518              
519             sub sqt {
520 3     3 0 712 my $self = shift;
521 3         9 my $type = $self->{type};
522 3 50       9 die "Cannot take the sqrt of a complex polynomial"
523             if $type eq 'cmplx';
524 3 100       14 my $a = $type eq 'fract' ? fract_to_real($self->{data}) : $self->coef;
525 3         274 my $b = [split //, 0 x ($MAXPOL+1)];
526 3         1140 Math::Cephes::polsqt($a, $b, 16);
527 3         23 return Math::Cephes::Polynomial->new($b);
528             }
529              
530             sub sin {
531 3     3 0 217 my $self = shift;
532 3         7 my $type = $self->{type};
533 3 50       11 die "Cannot take the sin of a complex polynomial"
534             if $type eq 'cmplx';
535 3 100       20 my $a = $type eq 'fract' ? fract_to_real($self->{data}) : $self->coef;
536 3         326 my $b = [split //, 0 x ($MAXPOL+1)];
537 3         1513 Math::Cephes::polsin($a, $b, 16);
538 3         18 return Math::Cephes::Polynomial->new($b);
539             }
540              
541             sub cos {
542 3     3 0 196 my $self = shift;
543 3         7 my $type = $self->{type};
544 3 50       11 die "Cannot take the cos of a complex polynomial"
545             if $type eq 'cmplx';
546 3 100       28 my $a = $type eq 'fract' ? fract_to_real($self->{data}) : $self->coef;
547 3         314 my $b = [split //, 0 x ($MAXPOL+1)];
548 3         1295 Math::Cephes::polcos($a, $b, 16);
549 3         15 return Math::Cephes::Polynomial->new($b);
550             }
551              
552             sub rts {
553 2     2 0 11 my $self = shift;
554             my ($atype, $aref, $adata, $na) =
555 2         16 ($self->{type}, $self->{ref}, $self->{data}, $self->{n});
556 2         3 my ($a, $b, $ret);
557 2         12 my $cof = [split //, 0 x ($na+1)];
558 2         12 my $r = [split //, 0 x ($na+1)];
559 2         9 my $i = [split //, 0 x ($na+1)];
560             SWITCH: {
561 2 100       4 $atype eq 'fract' and do {
  2         7  
562 1         3 $adata = fract_to_real($adata);
563 1         21 $ret = Math::Cephes::polrt_wrap($adata, $cof, $na, $r, $i);
564 1         4 for (my $j=0; $j<$na; $j++) {
565 6         14 push @$b,
566             Math::Cephes::Complex->new($r->[$j], $i->[$j]);
567             }
568 1         3 last SWITCH;
569             };
570 1 50       4 $atype eq 'cmplx' and do {
571 0         0 die "Cannot do complex root finding";
572 0         0 last SWITCH;
573             };
574 1         20 $ret = Math::Cephes::polrt_wrap($adata, $cof, $na, $r, $i);
575 1         4 for (my $j=0; $j<$na; $j++) {
576 4         18 push @$b,
577             Math::Cephes::Complex->new($r->[$j], $i->[$j]);
578             }
579             }
580 2 50       31 return wantarray ? ($ret, $b) : $b;
581             }
582              
583             1;
584              
585             __END__