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