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   1697 use strict;
  1         2  
  1         21  
3 1     1   2 use warnings;
  1         2  
  1         20  
4 1     1   2 use vars qw(@EXPORT_OK $VERSION $MAXPOL $FMAXPOL $flag $fflag);
  1         1  
  1         3294  
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.5305';
16              
17             require Math::Cephes;
18             require Math::Cephes::Fraction;
19             require Math::Cephes::Complex;
20              
21             sub new {
22 40     40 0 2218 my ($caller, $arr) = @_;
23 40         38 my $refer = ref($caller);
24 40   66     118 my $class = $refer || $caller;
25 40 50 66     106 die "Must supply data for the polynomial"
26             unless ($refer or $arr);
27 40         36 my ($type, $ref, $data, $n);
28 40 100       43 if ($refer) {
29             ($type, $ref, $n) =
30 2         6 ($caller->{type}, $caller->{ref}, $caller->{n});
31 2         2 my $cdata = $caller->{data};
32 2 100       5 if (ref($cdata) eq 'ARRAY') {
33 1         3 $data = [ @$cdata ];
34             }
35             else {
36 1 50       4 my ($f, $s) = ($type eq 'fract') ? ('n', 'd') : ('r', 'i');
37 1         2 $data = {$f => [ @{$cdata->{$f}} ],
38 1         1 $s => [ @{$cdata->{$s}} ],
  1         3  
39             };
40             }
41             }
42             else {
43 38         49 ($type, $ref, $data, $n) = get_data($arr);
44             }
45 40         185 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 531 return $_[0]->{data};
58             }
59              
60             sub get_data {
61 39     39 0 35 my ($arr, $ref_in) = @_;
62 39 50       66 die "Must supply an array reference" unless ref($arr) eq 'ARRAY';
63 39         39 my $n = scalar @$arr - 1;
64 39         45 my $ref = ref($arr->[0]);
65 39 50 66     70 die "array data must be of type '$ref_in'"
66             if (defined $ref_in and $ref_in ne $ref);
67 39         24 my ($type, $data);
68             SWITCH: {
69 39 100       28 not $ref and do {
  39         47  
70 21         14 $type = 'scalar';
71 21         28 foreach (@$arr) {
72 3124 50       3269 die 'Found conflicting types in array data'
73             if ref($_);
74             }
75 21         13 $data = $arr;
76 21 100       37 set_max() unless $flag;
77 21         25 last SWITCH;
78             };
79 18 100       30 $ref eq 'Math::Cephes::Complex' and do {
80 5         5 $type = 'cmplx';
81 5         6 foreach (@$arr) {
82 15 50       25 die 'Found conflicting types in array data'
83             unless ref($_) eq $ref;
84 15 50 33     21 die "array data must be of type '$ref_in'"
85             if (defined $ref_in and $ref_in ne $ref);
86 15         8 push @{$data->{r}}, $_->r;
  15         31  
87 15         16 push @{$data->{i}}, $_->i;
  15         28  
88             }
89 5 50       10 set_max() unless $flag;
90 5         5 last SWITCH;
91             };
92 13 100       17 $ref eq 'Math::Complex' and do {
93 3         2 $type = 'cmplx';
94 3         6 foreach (@$arr) {
95 9 50       39 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         4 push @{$data->{r}}, Re($_);
  9         22  
100 9         50 push @{$data->{i}}, Im($_);
  9         17  
101             }
102 3 50       18 set_max() unless $flag;
103 3         3 last SWITCH;
104             };
105 10 50       16 $ref eq 'Math::Cephes::Fraction' and do {
106 10         9 $type = 'fract';
107 10         11 foreach (@$arr) {
108 33 50       49 die 'Found conflicting types in array data'
109             unless ref($_) eq $ref;
110 33 50 33     43 die "array data must be of type '$ref_in'"
111             if (defined $ref_in and $ref_in ne $ref);
112 33         58 my ($gcd, $n, $d) = Math::Cephes::euclid($_->n, $_->d);
113 33         42 push @{$data->{n}}, $n;
  33         51  
114 33         16 push @{$data->{d}}, $d;
  33         41  
115             }
116 10 100       18 set_fmax() unless $fflag;
117 10         11 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         85 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 940 my ($self, $b) = @_;
176             my ($atype, $aref, $adata, $na) =
177 3         8 ($self->{type}, $self->{ref}, $self->{data}, $self->{n});
178             my ($btype, $bref, $bdata, $nb) =
179             ref($b) eq 'Math::Cephes::Polynomial' ?
180 3 100       9 ($b->{type}, $b->{ref}, $b->{data}, $b->{n}) :
181             get_data($b, $aref);
182 3         3 my $c = [];
183 3         3 my $nc;
184             SWITCH: {
185 3 100       4 $atype eq 'fract' and do {
  3         7  
186 1 50       3 $nc = $na > $nb ? $na: $nb;
187 1         4 my $cn = [split //, 0 x ($nc+1)];
188 1         4 my $cd = [split //, 0 x ($nc+1)];
189             Math::Cephes::fpoladd_wrap($adata->{n}, $adata->{d}, $na,
190 1         15 $bdata->{n}, $bdata->{d}, $nb,
191             $cn, $cd, $nc);
192 1         4 for (my $i=0; $i<=$nc; $i++) {
193 3         7 my ($gcd, $n, $d) = Math::Cephes::euclid($cn->[$i], $cd->[$i]);
194 3 50       8 push @$c, ($aref eq 'Math::Fraction' ?
195             Math::Fraction->new($n, $d) :
196             Math::Cephes::Fraction->new($n, $d) );
197             }
198 1         2 last SWITCH;
199             };
200 2 100       4 $atype eq 'cmplx' and do {
201 1 50       4 $nc = $na > $nb ? $na: $nb;
202 1         4 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         8 $bdata->{r}, $nb, $cr);
206             Math::Cephes::poladd($adata->{i}, $na,
207 1         5 $bdata->{i}, $nb, $ci);
208 1         3 for (my $i=0; $i<=$nc; $i++) {
209 3 50       8 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         2 last SWITCH;
214             };
215 1 50       3 $nc = $na > $nb ? $na + 1 : $nb + 1;
216 1         8 $c = [split //, 0 x $nc];
217 1         16 Math::Cephes::poladd($adata, $na, $bdata, $nb, $c);
218             }
219 3 50       6 return wantarray ? (Math::Cephes::Polynomial->new($c), $nc) :
220             Math::Cephes::Polynomial->new($c);
221              
222             }
223              
224             sub sub {
225 3     3 0 1396 my ($self, $b) = @_;
226             my ($atype, $aref, $adata, $na) =
227 3         7 ($self->{type}, $self->{ref}, $self->{data}, $self->{n});
228             my ($btype, $bref, $bdata, $nb) =
229             ref($b) eq 'Math::Cephes::Polynomial' ?
230 3 50       9 ($b->{type}, $b->{ref}, $b->{data}, $b->{n}) :
231             get_data($b, $aref);
232 3         3 my $c = [];
233 3         4 my $nc;
234             SWITCH: {
235 3 100       2 $atype eq 'fract' and do {
  3         7  
236 1 50       6 $nc = $na > $nb ? $na: $nb;
237 1         5 my $cn = [split //, 0 x ($nc+1)];
238 1         8 my $cd = [split //, 0 x ($nc+1)];
239             Math::Cephes::fpolsub_wrap($bdata->{n}, $bdata->{d}, $nb,
240 1         16 $adata->{n}, $adata->{d}, $na,
241             $cn, $cd, $nc);
242 1         4 for (my $i=0; $i<=$nc; $i++) {
243 3         12 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       11 $atype eq 'cmplx' and do {
251 1 50       3 $nc = $na > $nb ? $na: $nb;
252 1         4 my $cr = [split //, 0 x ($nc+1)];
253 1         3 my $ci = [split //, 0 x ($nc+1)];
254             Math::Cephes::polsub($bdata->{r}, $nb,
255 1         8 $adata->{r}, $na, $cr);
256             Math::Cephes::polsub($bdata->{i}, $nb,
257 1         4 $adata->{i}, $na, $ci);
258 1         7 for (my $i=0; $i<=$nc; $i++) {
259 3 50       9 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         2 last SWITCH;
264             };
265 1 50       2 $nc = $na > $nb ? $na + 1 : $nb + 1;
266 1         5 $c = [split //, 0 x $nc];
267 1         10 Math::Cephes::polsub($bdata, $nb, $adata, $na, $c);
268             }
269 3 50       10 return wantarray ? (Math::Cephes::Polynomial->new($c), $nc) :
270             Math::Cephes::Polynomial->new($c);
271              
272             }
273              
274             sub mul {
275 4     4 0 849 my ($self, $b) = @_;
276             my ($atype, $aref, $adata, $na) =
277 4         8 ($self->{type}, $self->{ref}, $self->{data}, $self->{n});
278             my ($btype, $bref, $bdata, $nb) =
279             ref($b) eq 'Math::Cephes::Polynomial' ?
280 4 50       12 ($b->{type}, $b->{ref}, $b->{data}, $b->{n}) :
281             get_data($b, $aref);
282 4         5 my $c = [];
283 4         3 my $nc;
284             SWITCH: {
285 4 100       4 $atype eq 'fract' and do {
  4         9  
286 1         2 $nc = $na + $nb;
287 1         5 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         17 $bdata->{n}, $bdata->{d}, $nb,
291             $cn, $cd, $nc);
292 1         4 for (my $i=0; $i<=$nc; $i++) {
293 4         12 my ($gcd, $n, $d) = Math::Cephes::euclid($cn->[$i], $cd->[$i]);
294 4 50       12 push @$c, ($aref eq 'Math::Fraction' ?
295             Math::Fraction->new($n, $d) :
296             Math::Cephes::Fraction->new($n, $d) );
297             }
298 1         2 last SWITCH;
299             };
300 3 100       5 $atype eq 'cmplx' and do {
301 2         3 my $dc = $na + $nb + 3;
302 2         7 my $cr = [split //, 0 x $dc];
303 2         9 my $ci = [split //, 0 x $dc];
304             $nc = Math::Cephes::cpmul_wrap($adata->{r}, $adata->{i}, $na+1,
305 2         29 $bdata->{r}, $bdata->{i}, $nb+1,
306             $cr, $ci, $dc);
307 2         5 $cr = [ @{$cr}[0..$nc] ];
  2         4  
308 2         4 $ci = [ @{$ci}[0..$nc] ];
  2         2  
309 2         5 for (my $i=0; $i<=$nc; $i++) {
310 8 100       111 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         28 last SWITCH;
315             };
316 1         2 $nc = $na + $nb + 1;
317 1         5 $c = [split //, 0 x $nc];
318 1         10 Math::Cephes::polmul($adata, $na, $bdata, $nb, $c);
319             }
320 4 50       10 return wantarray ? (Math::Cephes::Polynomial->new($c), $nc) :
321             Math::Cephes::Polynomial->new($c);
322             }
323              
324             sub div {
325 1     1 0 131 my ($self, $b) = @_;
326             my ($atype, $aref, $adata, $na) =
327 1         2 ($self->{type}, $self->{ref}, $self->{data}, $self->{n});
328             my ($btype, $bref, $bdata, $nb) =
329             ref($b) eq 'Math::Cephes::Polynomial' ?
330 1 50       6 ($b->{type}, $b->{ref}, $b->{data}, $b->{n}) :
331             get_data($b, $aref);
332 1         2 my $c = [];
333 1         1 my $nc;
334             SWITCH: {
335 1 50       1 $atype eq 'fract' and do {
  1         3  
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       7 $atype eq 'cmplx' and do {
351 0         0 die "Cannot do complex division";
352 0         0 last SWITCH;
353             };
354 1         1 $nc = $MAXPOL;
355 1         61 $c = [split //, 0 x ($nc+1)];
356 1         290 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 458 my $self = shift;
364             my ($atype, $aref, $adata, $na) =
365 2         8 ($self->{type}, $self->{ref}, $self->{data}, $self->{n});
366 2 50       6 set_max() unless $flag;
367 2   33     3 my $n = shift || $na;
368 2 100       4 $n = $na if $n > $na;
369             SWITCH: {
370 2 100       2 $atype eq 'fract' and do {
  2         5  
371 1         4 for (my $i=0; $i<=$n; $i++) {
372 2         3 $self->{data}->{n}->[$i] = 0;
373 2         4 $self->{data}->{d}->[$i] = 1;
374             }
375 1         2 last SWITCH;
376             };
377 1 50       2 $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         3 for (my $i=0; $i<=$n; $i++) {
385 3         7 $self->{data}->[$i] = 0;
386             }
387             }
388             }
389              
390             sub sbt {
391 3     3 0 125 my ($self, $b) = @_;
392             my ($atype, $aref, $adata, $na) =
393 3         7 ($self->{type}, $self->{ref}, $self->{data}, $self->{n});
394             my ($btype, $bref, $bdata, $nb) =
395             ref($b) eq 'Math::Cephes::Polynomial' ?
396 3 50       12 ($b->{type}, $b->{ref}, $b->{data}, $b->{n}) :
397             get_data($b, $aref);
398 3 50       7 set_max() unless $flag;
399 3         4 my $c = [];
400 3         3 my $nc;
401             SWITCH: {
402 3 100       3 $atype eq 'fract' and do {
  3         6  
403 2         3 $nc = ($na+1)*($nb+1);
404 2         13 my $cn = [split //, 0 x ($nc+1)];
405 2         8 my $cd = [split //, 0 x ($nc+1)];
406             Math::Cephes::fpolsbt_wrap($bdata->{n}, $bdata->{d}, $nb,
407 2         45 $adata->{n}, $adata->{d}, $na,
408             $cn, $cd, $nc);
409 2         2 $nc = $na * $nb;
410 2         6 for (my $i=0; $i<=$nc; $i++) {
411 6         13 my ($gcd, $n, $d) = Math::Cephes::euclid($cn->[$i], $cd->[$i]);
412 6 50       18 push @$c, ($aref eq 'Math::Fraction' ?
413             Math::Fraction->new($n, $d) :
414             Math::Cephes::Fraction->new($n, $d) );
415             }
416 2         4 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         2 $nc = ($na+1)*($nb+1);
423 1         6 $c = [split //, 0 x $nc];
424 1         14 Math::Cephes::polsbt($bdata, $nb, $adata, $na, $c);
425 1         1 $nc = $na*$nb;
426 1         4 $c = [@$c[0..$nc]];
427             }
428 3 50       10 return wantarray ? (Math::Cephes::Polynomial->new($c), $nc) :
429             Math::Cephes::Polynomial->new($c);
430             }
431              
432             sub set_max {
433 1     1 0 21 Math::Cephes::polini($MAXPOL);
434 1         1 $flag = 1;
435             }
436              
437             sub set_fmax {
438 1     1 0 13 Math::Cephes::fpolini($FMAXPOL);
439 1         1 $fflag = 1;
440             }
441              
442             sub eval {
443 10     10 0 3083 my $self = shift;
444 10         9 my $x = 0 || shift;
445             my ($atype, $aref, $adata, $na) =
446 10         20 ($self->{type}, $self->{ref}, $self->{data}, $self->{n});
447 10         8 my $y;
448             SWITCH: {
449 10 100       6 $atype eq 'fract' and do {
  10         23  
450 4         5 my $xref = ref($x);
451 4         10 $y = Math::Cephes::Fraction->new(0, 1);
452             FRACT: {
453 4 100       4 not $xref and do {
  4         6  
454 2         5 $x = Math::Cephes::Fraction->new($x, 1);
455 2         3 last FRACT;
456             };
457 2 50       4 $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         45 Math::Cephes::fpoleva_wrap($adata->{n}, $adata->{d}, $na, $x, $y);
467 4 50       7 $y = Math::Fraction->new($y->n, $y->d) if $aref eq 'Math::Fraction';
468 4         4 last SWITCH;
469             };
470 6 100       10 $atype eq 'cmplx' and do {
471 2         13 my $r = Math::Cephes::poleva($adata->{r}, $na, $x);
472 2         5 my $i = Math::Cephes::poleva($adata->{i}, $na, $x);
473 2 100       10 $y = $aref eq 'Math::Complex' ?
474             Math::Complex->make($r, $i) :
475             Math::Cephes::Complex->new($r, $i);
476 2         38 last SWITCH;
477             };
478 4         23 $y = Math::Cephes::poleva($adata, $na, $x);
479             }
480 10         21 return $y;
481             }
482              
483             sub fract_to_real {
484 9     9 0 8 my $in = shift;
485 9         10 my $a = [];
486 9         10 my $n = scalar @{$in->{n}} - 1;
  9         10  
487 9         16 for (my $i=0; $i<=$n; $i++) {
488 39         74 push @$a, $in->{n}->[$i] / $in->{d}->[$i];
489             }
490 9         11 return $a;
491             }
492              
493             sub atn {
494 2     2 0 603 my ($self, $bin) = @_;
495 2         3 my $type = $self->{type};
496 2 50       9 die "Cannot take the atan of a complex polynomial"
497             if $type eq 'cmplx';
498 2         49 my ($a, $b);
499             my ($atype, $aref, $adata, $na) =
500 2         5 ($self->{type}, $self->{ref}, $self->{data}, $self->{n});
501 2 50       4 die "Cannot take the atan of a complex polynomial"
502             if $atype eq 'cmplx';
503 2 100       6 $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       8 ($bin->{type}, $bin->{ref}, $bin->{data}, $bin->{n}) :
508             get_data($bin);
509              
510 2 50       3 die "Cannot take the atan of a complex polynomial"
511             if $btype eq 'cmplx';
512 2 100       6 $b = $btype eq 'fract' ? fract_to_real($bdata) : $bdata;
513              
514 2         89 my $c = [split //, 0 x ($MAXPOL+1)];
515 2         1490 Math::Cephes::polatn($a, $b, $c, 16);
516 2         7 return Math::Cephes::Polynomial->new($c);
517             }
518              
519             sub sqt {
520 3     3 0 1003 my $self = shift;
521 3         6 my $type = $self->{type};
522 3 50       8 die "Cannot take the sqrt of a complex polynomial"
523             if $type eq 'cmplx';
524 3 100       8 my $a = $type eq 'fract' ? fract_to_real($self->{data}) : $self->coef;
525 3         137 my $b = [split //, 0 x ($MAXPOL+1)];
526 3         1135 Math::Cephes::polsqt($a, $b, 16);
527 3         8 return Math::Cephes::Polynomial->new($b);
528             }
529              
530             sub sin {
531 3     3 0 1084 my $self = shift;
532 3         5 my $type = $self->{type};
533 3 50       8 die "Cannot take the sin of a complex polynomial"
534             if $type eq 'cmplx';
535 3 100       10 my $a = $type eq 'fract' ? fract_to_real($self->{data}) : $self->coef;
536 3         154 my $b = [split //, 0 x ($MAXPOL+1)];
537 3         1878 Math::Cephes::polsin($a, $b, 16);
538 3         11 return Math::Cephes::Polynomial->new($b);
539             }
540              
541             sub cos {
542 3     3 0 956 my $self = shift;
543 3         6 my $type = $self->{type};
544 3 50       8 die "Cannot take the cos of a complex polynomial"
545             if $type eq 'cmplx';
546 3 100       9 my $a = $type eq 'fract' ? fract_to_real($self->{data}) : $self->coef;
547 3         157 my $b = [split //, 0 x ($MAXPOL+1)];
548 3         2322 Math::Cephes::polcos($a, $b, 16);
549 3         10 return Math::Cephes::Polynomial->new($b);
550             }
551              
552             sub rts {
553 2     2 0 8 my $self = shift;
554             my ($atype, $aref, $adata, $na) =
555 2         5 ($self->{type}, $self->{ref}, $self->{data}, $self->{n});
556 2         2 my ($a, $b, $ret);
557 2         8 my $cof = [split //, 0 x ($na+1)];
558 2         7 my $r = [split //, 0 x ($na+1)];
559 2         5 my $i = [split //, 0 x ($na+1)];
560             SWITCH: {
561 2 100       3 $atype eq 'fract' and do {
  2         6  
562 1         2 $adata = fract_to_real($adata);
563 1         18 $ret = Math::Cephes::polrt_wrap($adata, $cof, $na, $r, $i);
564 1         4 for (my $j=0; $j<$na; $j++) {
565 6         13 push @$b,
566             Math::Cephes::Complex->new($r->[$j], $i->[$j]);
567             }
568 1         2 last SWITCH;
569             };
570 1 50       2 $atype eq 'cmplx' and do {
571 0         0 die "Cannot do complex root finding";
572 0         0 last SWITCH;
573             };
574 1         21 $ret = Math::Cephes::polrt_wrap($adata, $cof, $na, $r, $i);
575 1         4 for (my $j=0; $j<$na; $j++) {
576 4         14 push @$b,
577             Math::Cephes::Complex->new($r->[$j], $i->[$j]);
578             }
579             }
580 2 50       9 return wantarray ? ($ret, $b) : $b;
581             }
582              
583             1;
584              
585             __END__