⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch29.htm

📁 《Perl 5 Unreleased》
💻 HTM
📖 第 1 页 / 共 4 页
字号:
function is derived using the <TT><FONT FACE="Courier">ref()</FONT></TT>

function call in line 46. If the passed parameter is a reference,

then the function uses the first argument; otherwise, <TT><FONT FACE="Courier">$a</FONT></TT>

is assigned to the entire incoming argument list:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">my $a = ref($_[0]) ? $_[0] : \@_;</FONT></TT>

</BLOCKQUOTE>

<P>

The math operations are performed in lines 72 to 79. The results

of these calculations are returned in line 83. Listing 29.1 and

Listing 29.2 should be enough to get you started on creating more

complicated functions. For example, let's add two routines for

performing vector calculations.

<H3><A NAME="DotandCrossProductsofVectors"><B>Dot and Cross Products

of Vectors</B></A></H3>

<P>

Two subroutines that perform the cross and dot products of two

vectors are shown in Listing 29.3. A cross product of a vector

of length <TT><FONT FACE="Courier">n</FONT></TT> and a vector

of length <TT><FONT FACE="Courier">m</FONT></TT> will return a

matrix of size <TT><FONT FACE="Courier">m</FONT></TT> <FONT FACE="Symbol">&#165;</FONT>

<TT><FONT FACE="Courier">n</FONT></TT>, whereas a dot product

of two vectors of the same size (i.e., <TT><FONT FACE="Courier">m</FONT></TT>

= <TT><FONT FACE="Courier">n</FONT></TT>) will return a scalar

value.

<HR>

<BLOCKQUOTE>

<B>Listing 29.3. Vector functions.<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">&nbsp;1 #!/usr/bin/perl<BR>

&nbsp;2<BR>

&nbsp;3 #<BR>

&nbsp;4 # Simple statistical functions in Perl<BR>

&nbsp;5 #<BR>

&nbsp;6<BR>

&nbsp;7<BR>

&nbsp;8 #----------------------------------------------------------------

<BR>

&nbsp;9 #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Declare

any subroutines here<BR>

10 #----------------------------------------------------------------

<BR>

11 sub xProduct(\@\@\@);&nbsp;&nbsp;&nbsp;# Declare as taking

two pointers to arrays<BR>

12 sub dProduct(\@\@);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Declare

as taking two pointers to arrays<BR>

13<BR>

14 @one = ( 2, 4, 3);<BR>

15 @two = ( 4, -1, 7);<BR>

16 @result = ();<BR>

17<BR>

18 $r = &amp;dProduct(\@one,\@two);<BR>

19<BR>

20 print &quot;\n Dot Product = $r \n&quot;;<BR>

21<BR>

22 &amp;xProduct(\@one,\@two,\@result);<BR>

23<BR>

24 print &quot;\n Cross Product = \n&quot;;<BR>

25&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for ($i=0;$i&lt;3;$i++)

{<BR>

26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for

($j=0;$j&lt; 3;$j++) {<BR>

27&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf&nbsp;&nbsp;&quot;

%4d&quot;, $result[$i][$j];<BR>

28&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

<BR>

29&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print &quot;\n&quot;;<BR>

30&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>

31<BR>

32 exit (0);<BR>

33 # ------------------------------------------------<BR>

34 #&nbsp;&nbsp;Returns dot product of two vectors.<BR>

35 #&nbsp;&nbsp;Takes two pointers to arrays as input<BR>

36 #&nbsp;&nbsp;Returns a scalar.<BR>

37 sub dProduct {&nbsp;&nbsp;#<BR>

38&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my ($x,$y) = @_;<BR>

39&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $sum;<BR>

40&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $ct1 = $#{$x} + 1;&nbsp;&nbsp;

# items in $x<BR>

41&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $ct2 = $#{$y} + 1;&nbsp;&nbsp;

# items in $y<BR>

42&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return undef if ($ct1 !=

$ct2) ;<BR>

43<BR>

44&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for ($i=0;$i&lt;$ct1;$i++)

{<BR>

45&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$sum += $$x[$i] * $$y[$i];

<BR>

46&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>

47&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $sum;<BR>

48 }<BR>

49 # ------------------------------------------------<BR>

50 # Returns a cross product of two vectors.<BR>

51 # Takes two pointers to arrays as input<BR>

52 # Returns a two-dimensional array.<BR>

53 sub xProduct {<BR>

54&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my ($x,$y) = @_;<BR>

55&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $i, $j, @array;<BR>

56&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $ct1 = $#{$x} + 1;&nbsp;&nbsp;&nbsp;#

items in $x<BR>

57&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $ct2 = $#{$y} + 1;&nbsp;&nbsp;&nbsp;#

items in $y<BR>

58&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $result = \@arrau;<BR>

59&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for ($i=0;$i&lt;$ct1;$i++)

{<BR>

60&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for

($j=0;$j&lt;$ct2;$j++) {<BR>

61&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$$result[$i][$j]

= $$x[$i] * $$y[$i];<BR>

62&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#

print &quot; $i, $j, $$result[$i][$j] \n&quot;;<BR>

63&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

<BR>

64&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>

64&nbsp;&nbsp;return ($result);&nbsp;&nbsp;&nbsp;return result.

<BR>

65 }</FONT></TT>

</BLOCKQUOTE>

<HR>

<P>

Notice how the subroutines for the two functions are declared

at lines 11 and 12. At line 18, the script calls <TT><FONT FACE="Courier">dProduct</FONT></TT>

to return the dot product of the two vectors. The return value

from the <TT><FONT FACE="Courier">dProduct</FONT></TT> function

can also be <TT><FONT FACE="Courier">undef</FONT></TT> if the

vectors are not the same size.

<P>

At line 22, you get the resulting cross product matrix of multiplying

the two vectors together. The size of the matrix is M<FONT FACE="Symbol">&#165;</FONT>N,

where M is the size of the first vector and N is the size of the

second vector passed into <TT><FONT FACE="Courier">xProduct()</FONT></TT>.

<P>

To return an entire result of a calculation instead of having

to pass the <TT><FONT FACE="Courier">@result</FONT></TT> array,

you can rewrite the cross product function as shown in Listing

29.4. Line 9 now declares only two pointers to arrays into <TT><FONT FACE="Courier">xProduct</FONT></TT>.

The array in <TT><FONT FACE="Courier">xProduct</FONT></TT> is

referred to by reference as well at line 53. The reference, <TT><FONT FACE="Courier">$result</FONT></TT>,

is returned to the caller in line 64. Note the <TT><FONT FACE="Courier">@array</FONT></TT>,

even though declared as a <TT><FONT FACE="Courier">my</FONT></TT>

variable, is not destroyed because the reference to it in <TT><FONT FACE="Courier">$result</FONT></TT>

is returned by the <TT><FONT FACE="Courier">xProduct</FONT></TT>

function. As long as the returned reference to the calling program

continues to be used, the space allocated for the <TT><FONT FACE="Courier">@array</FONT></TT>

will not be destroyed.

<H3><A NAME="AddingorSubtractingVectors"><B>Adding or Subtracting

Vectors</B></A></H3>

<P>

It's quite straightforward to include the two functions to add

and subtract two vectors. These two subroutines are defined in

Listing 29.4 at lines 65 and 87, respectively.

<P>

The number of elements in each array passed into the functions

is kept in variables <TT><FONT FACE="Courier">$ct1</FONT></TT>

and <TT><FONT FACE="Courier">$ct2</FONT></TT> (see lines 105 and

106). The counts are used in loops elsewhere in the code.

<HR>

<BLOCKQUOTE>

<B>Listing 29.4. Calculations returning an array.<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">&nbsp;&nbsp;1 #!/usr/bin/perl<BR>

&nbsp;&nbsp;2<BR>

&nbsp;&nbsp;3 #---------------------------------------------------------------

<BR>

&nbsp;&nbsp;4 #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Vector

Arithmetic Routines for use in Perl.<BR>

&nbsp;&nbsp;5 #&nbsp;&nbsp;Copy these freely with NO RESTRICTIONS

AND NO WARRANTY!<BR>

&nbsp;&nbsp;6 #----------------------------------------------------------------

<BR>

&nbsp;&nbsp;7 #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Declare

thy subroutines here<BR>

&nbsp;&nbsp;8 #----------------------------------------------------------------

<BR>

&nbsp;&nbsp;9 sub xProduct(\@\@);&nbsp;&nbsp;# Declare as taking

two pointers to arrays<BR>

&nbsp;10 sub dProduct(\@\@);&nbsp;&nbsp;# Declare as taking two

pointers to arrays<BR>

&nbsp;11 sub vAdd(\@\@);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#

Declare as taking two pointers to arrays<BR>

&nbsp;12 sub vSubtract(\@\@); # Declare as taking two pointers

to arrays<BR>

&nbsp;13<BR>

&nbsp;14 # -------------------------------------------------------------------

<BR>

&nbsp;15 #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Test

with these vectors<BR>

&nbsp;16 # -------------------------------------------------------------------

<BR>

&nbsp;17 @one = ( 2, 4, 3);<BR>

&nbsp;18 @two = ( 4, -1, 7);<BR>

&nbsp;19 @result = ();<BR>

&nbsp;20<BR>

&nbsp;21 print &quot;\n Vector 1 = &quot;;<BR>

&nbsp;22 for (@one) { printf &quot; %4d&quot;, $_; }<BR>

&nbsp;23<BR>

&nbsp;24 print &quot;\n Vector 2 = &quot;;<BR>

&nbsp;25 for (@two) { printf &quot; %4d&quot;, $_; }<BR>

&nbsp;26<BR>

&nbsp;27<BR>

&nbsp;28 # -------------------------------------------------------------------

<BR>

&nbsp;29 #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Test

Dot Product<BR>

&nbsp;30 # -------------------------------------------------------------------

<BR>

&nbsp;31 $r = &amp;dProduct(@one,@two);<BR>

&nbsp;32 print &quot;\n Dot Product = $r \n&quot;;<BR>

&nbsp;33<BR>

&nbsp;34 # -------------------------------------------------------------------

<BR>

&nbsp;35 #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Test

Addition<BR>

&nbsp;36 # -------------------------------------------------------------------

<BR>

&nbsp;37 @result = &amp;vAdd(\@one,\@two);<BR>

&nbsp;38 print &quot;\n Added = &quot;;<BR>

&nbsp;39&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (@result) { printf

&quot; %4d&quot;, $_; }<BR>

&nbsp;40<BR>

&nbsp;41 # -------------------------------------------------------------------

<BR>

&nbsp;42 #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Test

Subtraction<BR>

&nbsp;43 # -------------------------------------------------------------------

<BR>

&nbsp;44 @result = &amp;vSubtract(\@one,\@two);<BR>

&nbsp;45 print &quot;\n Subtract&nbsp;&nbsp;= &quot;;<BR>

&nbsp;46&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (@result) { printf

&quot; %4d&quot;, $_; }<BR>

&nbsp;47<BR>

&nbsp;48 # -------------------------------------------------------------------

<BR>

&nbsp;49 #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Test

Cross Product<BR>

&nbsp;50 # -------------------------------------------------------------------

<BR>

&nbsp;51 @result = &amp;xProduct(\@one,\@two);<BR>

&nbsp;52<BR>

&nbsp;53 print &quot;\n Cross Product = \n&quot;;<BR>

&nbsp;54&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for ($i=0;$i&lt;3;$i++)

{<BR>

&nbsp;55&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for

($j=0;$j&lt; 3;$j++) {<BR>

&nbsp;56&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf&nbsp;&nbsp;&quot;

%4d&quot;, $result[$i][$j];<BR>

&nbsp;57&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

}<BR>

&nbsp;58&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print &quot;\n&quot;;

<BR>

&nbsp;59&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>

&nbsp;60<BR>

&nbsp;61 exit (0);<BR>

&nbsp;62<BR>

&nbsp;63 # -------------------------------------------------------------------

<BR>

&nbsp;64 # Returns a vector that is the result of subtracting

one vector from<BR>

&nbsp;65 # another. Both vectors have to be the same size.<BR>

&nbsp;66 # -------------------------------------------------------------------

<BR>

&nbsp;67 sub vAdd {&nbsp;&nbsp;# (\@\@); Declare as taking two

pointers to arrays<BR>

&nbsp;68&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my ($x,$y) = @_;<BR>

&nbsp;69&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $ct1 = $#{$x} +

1;&nbsp;&nbsp; # items in $x<BR>

&nbsp;70&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $ct2 = $#{$y} +

1;&nbsp;&nbsp; # items in $y<BR>

&nbsp;71&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return undef if ($ct1

!= $ct2) ;<BR>

&nbsp;72&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $i;<BR>

&nbsp;73&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my @answer;<BR>

&nbsp;74<BR>

&nbsp;75&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for ($i=0;$i&lt;$ct1;$i++)

{<BR>

&nbsp;76&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$answer[$i]

= $$x[$i] + $$y[$i];<BR>

&nbsp;77&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>

&nbsp;78&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return @answer;<BR>

&nbsp;79 }<BR>

&nbsp;80<BR>

&nbsp;81 # -------------------------------------------------------------------

<BR>

&nbsp;82 # Returns a vector that is the result of subtracting

one vector from<BR>

&nbsp;83 # another. Both vectors have to be the same size.<BR>

&nbsp;84 # -------------------------------------------------------------------

<BR>

&nbsp;85 sub vSubtract {&nbsp;&nbsp;# (\@\@); Declare as taking

two pointers to arrays<BR>

&nbsp;86&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my ($x,$y) = @_;<BR>

&nbsp;87&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $ct1 = $#{$x} +

1;&nbsp;&nbsp;&nbsp;# items in $x<BR>

&nbsp;88&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $ct2 = $#{$y} +

1;&nbsp;&nbsp;&nbsp;# items in $y<BR>

&nbsp;89&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return undef if ($ct1

!= $ct2) ;<BR>

&nbsp;90&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $i;<BR>

&nbsp;91&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my @answer;<BR>

&nbsp;92<BR>

&nbsp;93&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for ($i=0;$i&lt;$ct1;$i++)

{<BR>

&nbsp;94&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$answer[$i]

= $$x[$i] - $$y[$i];<BR>

&nbsp;95&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>

&nbsp;96&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return @answer;<BR>

&nbsp;97 }<BR>

&nbsp;98<BR>

&nbsp;99 # -------------------------------------------------------------------

<BR>

100 # Returns a scalar that is a dot product of two vectors.<BR>

101 # -------------------------------------------------------------------

<BR>

102 sub dProduct {&nbsp;&nbsp;# (\@\@); Declare as taking two

pointers to arrays<BR>

103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my ($x,$y) = @_;<BR>

104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $sum;<BR>

105&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $ct1 = $#{$x} + 1;&nbsp;&nbsp;&nbsp;#

items in $x<BR>

106&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $ct2 = $#{$y} + 1;&nbsp;&nbsp;&nbsp;#

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -