sub my_f { my $x = shift; return $x**2; }
The statement my $x = shift; has two parts. The first my $x declares $x as a local variable, while the assignment my $x = shift; assigns to $x the first (and only in this case) argument passed to the function.
The function returns the value of $x squared. Note the use of ** as the exponentiation operator. This is pure Perl, so the caret has a completely different meaning.
To print a little table of values of , , and we might write (again the code is reasonably self-documenting):
## Define the first function f(x) sub my_f{ my $x = shift; return $x**2; } ## Make a nice version to print $f_print = FEQ("\(f(x) = x^2 \)"); ## Define the second function g(x) sub my_g{ my $x = shift; return $x**3; } ## Make a nice version to print $g_print = FEQ("\(g(x) = x^3 \)"); ## Pick some randome values at which to evaluate the functions @x_values = (1, 2, 3, 5, 7); ## Set up some arrays to collect the values @f_of_x = (); @g_of_x = (); @f_of_g_of_x = (); ## Evaluate f(x), g(x), f(g(x)) and add to arrays ## scalar(@x_values) is the number of elements in the array @x_values for ($i = 0; $i < scalar(@x_values); $i++) { $f_of_x[$i] = my_f($x_values[$i]); $g_of_x[$i] = my_g($x_values[$i]); $f_of_g_of_x[$i] = my_f(my_g($x_values[$i])); } ## Ok, we are ready to begin the problem... ## TEXT(beginproblem()); BEGIN_TEXT $BR Here is a table of values of functions $f_print and $g_print. $PAR END_TEXT ## Print a table of values TEXT( begintable (scalar(@x_values) + 1), row(("\( x \)",@x_values)), row(("\( f(x) \)",@f_of_x)), row(("\( g(x) \)",@g_of_x)), row(("\( f(g(x)) \)",@f_of_g_of_x)), endtable() ); ENDDOCUMENT();
You might notice a little comfort with the use of Perl here.
The statement
row(("\( x \)",@x_values))
takes advantage of the
way that Perl handles arrays. That is, the function row
takes an array as an argument. We want an array whose first entry is
the label for the row, followed by the actual values which already
appear in an array. You will recall from an early section of this
guide that if @a
, @b
, @c
are arrays, then the statement
@a = (@b, @c)
creates an array whose members are those of
the array @b
followed by those of the array @c
.
Certainly, you can define more involved functions.
If $a
, $b
, and $c
are constants already defined
in your problem, you could define a (generic) quadratic as:
sub my_f{ my $x = shift; return $a * $x**2 + $b * $x + $c; }
You could be braver and define a generic polynomial function by
sub polynomial{ ## The function polynomial takes three arguments. The first is ## the degree, the second an array of (degree+1) coefficients, and ## the third the value of the independent variable. ## my $degree = shift; my @coefficients = shift; my $x = shift; ## Define some local variables my $i; my $sum = 0; for ($i = 0; $i <= $degree; $i++) $sum = $sum + $coefficients[$i] * ($x**($i)); return $sum; }
Could you have functions of more than one variable? Sure
## Define f(x,y) = x^2 + y^2 sub my_f{ my $x = shift; my $y = shift; return $x**2 + $y**2; }