Math-Calculus-TaylorSeries

 view release on metacpan or  search on metacpan

TaylorSeries.pm  view on Meta::CPAN

the engine is strict about syntax. For example, note above that you must write 5*x and not
just 5x. Whitespace is allowed in the expression, but does not have any effect on precedence.
If you require control of precedence, use brackets; bracketed expressions will always be
evaluated first, as you would normally expect. The module follows the BODMAS precedence
convention. Returns undef on failure and a true value on success.

=item getExpression

  $expr = $exp->getExpression;

Returns a textaul, human readable representation of the expression that is being stored.

=cut


# Taylor Series.
# ##############

=item taylorSeries

  $result = $exp->taylorSeries($variable, $terms, $about);

Finds the first $terms non-zero terms of the Taylor series of the expression object
for the variable $variable evaluated about the value $about and returns a new
expression object that represents it.
=cut

sub taylorSeries {
	# Get invocant and variable.
	my ($self, $variable, $terms, $about) = @_;
	
	# Clear error and traceback.
	$self->{'error'} = $self->{'traceback'} = '';
	
	# Check variable is in the list of variables.
	unless (grep { $_ eq $variable } @{$self->{'variables'}})
	{
		$self->{'error'} = 'Function variable was not declared.';
		return undef;
	}
	
	# Check number of terms is sane.
	unless ($terms =~ /^\d+$/ && $terms > 1)
	{
		$self->{'error'} = 'Attempt to evaluate Taylor series with an invalid number of terms.';
		return undef;
	}
	
	# Check about value is sane.
	unless ($about =~ /^[\-\d\.]+$/)
	{
		$self->{'error'} = 'Attempt to evaluate Taylor series about an invalid value.';
		return undef;
	}
	
	# Create a clone of the expression object that we'll differentiate and prepare to find co-efficients.
	my $diffExp = $self->clone;
	my @coeffs = ();
	my $coeffsFound = 0;
	
	# Loop until we've found enough terms or we hit our maximum number of iterations.
	my $numIters = 0;
	while ($coeffsFound < $terms) {
		# Evaluate.
		my $coeff = $diffExp->evaluate($variable => $about);
		return undef unless defined($coeff);
		
		# Put in co-effs list, and if it's non-zero then state we've found a term.
		push @coeffs, $coeff;
		$coeffsFound++ if $coeff != 0;
		
		# Differentiate for next round.
		return undef unless $diffExp->differentiate($variable);
		$diffExp->simplify;
		
		# Sanity check - we may run out of terms.
		last if ++$numIters == $MAXITERATIONS;
	}
	
	# Now we need to generate the expression with the real co-efficients.
	my @termList = ();
	for (my $i = 0; $i < @coeffs; $i++) {
		# If the co-efficient is non-zero, create the term and put it on the list.
		if ($coeffs[$i] != 0) {
			my $term = $coeffs[$i];
			$term .= '*' . $variable if $i > 0;
			$term .= '^' . $i if $i > 1;
			$term .= '/' . $self->fact($i);
			push @termList, $term;
		}
	}
	
	# Create a new expression object containing the term, and simplify.
	my $newExp = Math::Calculus::Expression->new;
	unless ($newExp->setExpression(join '+', @termList)) {
		$self->{'error'} = "Could not parse generated taylor series expression.";
	}
	$newExp->simplify;
	
	# Return the Taylor series, if no errors.
	if ($self->{'error'}) {
		return undef;
	} else {
		return $newExp;
	}
}


# Taylor Series Co-efficients.
# ############################

=item taylorSeries_coeffs

  $result = $exp->taylorSeries($variable, $numcoeffs, $about);

Returns an array containing the first $numcoeffs terms when the Taylor series for
the variable $variable is found about $about.
=cut

sub taylorSeries_coeffs {
	# Get invocant and variable.



( run in 0.449 second using v1.01-cache-2.11-cpan-71847e10f99 )