File: ops.pd

package info (click to toggle)
pdl 1.99988-5
  • links: PTS
  • area: main
  • in suites: slink
  • size: 3,908 kB
  • ctags: 3,426
  • sloc: perl: 15,352; ansic: 7,852; fortran: 3,327; makefile: 39; sh: 19
file content (136 lines) | stat: -rw-r--r-- 3,272 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
pp_addpm({At=>Top},<<'EOD');

=head1 NAME

PDL::Ops - Fundamental mathematical operators

=head1 DESCRIPTION

This module provides the functions used by PDL to
overload the basic mathematical operators (C<+ - / *>
etc.) and functions (C<sin sqrt> etc.)

You probably don't need to know about this
and the interface may well
change so the documentation ends here.

=head1 SYNOPSIS

none

=cut

EOD
# REPLACE FOLLOWING BY USE
# when using not in this package.
#
# Parts from old mkpdlbasicops.p, rest Copyright (C) Tuomas J. Lukka 1996, 1997

# Phase 1: generate lists of
#	[operator_name, how_to_apply]

@biops1  = map {[$_,"\$c() = \$a() $_ \$b()"]} qw( + * - / );
@biops2  = map {[$_,"\$c() = \$a() $_ \$b()"]} qw( > < <= >= == != );
@biops3  = map {[$_,"\$c() = (PDL_Long) \$a() $_ (PDL_Long) \$b()"]}qw( << >> | & ^ );

@ufuncs1 = map {[$_,"\$b() = ($_(\$a()))"]} qw( sqrt abs );
@ufuncs1f = map {[$_,"\$b() = ($_(\$a()))"]} qw( sin cos );
@ufuncs2 = map {[$_,"\$b() = ($_((PDL_Long)\$a()))"]} qw( ! ~ NOTHING );
@ufuncs2f = map {[$_,"\$b() = ($_((PDL_Long)\$a()))"]} qw( log exp );
@bifuncs = map {[$_,"\$c() = ($_(\$a(),\$b()))"]}
	qw( pow atan2 MODULO SPACESHIP );

sub nofloat { # Decide which ops can't be done on floats/doubles
    	my $op = shift;
	my (@bitops) = qw( << >> | & ^ ~ );
    	for (@bitops) { return 1 if $_ eq $op }
	return 0;
}

sub remove_float_casts { # Remove casts in certain cases
  my $op=shift;
  my $code = $op->[1];
  $code =~ s/\(PDL_Long\)//g unless nofloat($op->[0]);
  return $code;
}

sub remove_all_casts { # Remove casts in all cases
  my $op=shift;
  my $code = $op->[1];
  $code =~ s/\(PDL_Long\)//g;
  return $code;
}

# Fudge ABS function for unsigned types to get
# rid of the stupid compiler warning

sub absfudge{
   my $s = shift;
   $s =~ s/abs/\$TBSUL(NOTHING,abs,NOTHING,abs)/;
   return $s;
}

pp_addhdr('
#include <math.h>

#define MODULO(X,N)     ( (X) - (N)*((int)((X)/(N))) )
#define SPACESHIP(A,B)  ( ((A)<(B)) ? -1 : ((A)!=(B)) )
#define abs(A)          ( (A)>=0 ? (A) : -(A) )
#define NOTHING
');

# First, map all the types

$arg3str = 'a(); b(); [o]c();';
$arg2str = 'a(); [o]b();';

my $ind = 0;
for $optype ([biop1,\@biops1,$arg3str,undef],
     [biop2,\@biops2,$arg3str,undef],
     [biop3,\@biops3,$arg3str,undef],
     [bifunc1,\@bifuncs,$arg3str,undef],
     [ufunc1,\@ufuncs1,$arg2str,undef],
     [ufunc1f,\@ufuncs1f,$arg2str,[F,D]],
     [ufunc2,\@ufuncs2,$arg2str,undef],
     [ufunc2f,\@ufuncs2f,$arg2str,[F,D]],
     ) { $ind ++;
pp_def("my_$optype->[0]",
	($optype->[3] ? (GenericTypes => $optype->[3]) : ()),
	Pars => $optype->[2],
	OtherPars => "char* pdl_op",
Code => "if(0) {".
	  (join '',map {qq^
     } else if(!strcmp(\$COMP(pdl_op),"$_->[0]")) {
		  types(FD) %{
		      threadloop %{
			  ^.remove_float_casts($_).qq^;
                      %}
		  %}
		  types(BSUL) %{
		      threadloop %{
			  ^.absfudge(remove_all_casts($_)).qq^;
                      %}
		   %}
             ^
# Close the type loop.
# End the enclosing "if".
		} @{$optype->[1]}).
	q|}; /* printf("OMYBIOP, '%s'\n",pdl_op); */ |,
	Doc  => 'internal',
);
}


pp_addpm({At=>Bot},<<'EOPM');

=head1 AUTHOR

Tuomas J. Lukka (lukka@fas.harvard.edu) and Karl Glazebrook
(kgb@aaoepp.aao.gov.au).

=cut

EOPM

pp_done();