Skip Menu |

This queue is for tickets about the Math-Quaternion CPAN distribution.

Report information
The Basics
Id: 86098
Status: resolved
Priority: 0/
Queue: Math-Quaternion

People
Owner: jon-pause-public [...] earth.li
Requestors: bruce.gray [...] acm.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 0.04
Fixed in: (no value)



Subject: Divide-by-zero error in q->power
When $q->isreal, then $q->power($some_real_number) throws "Illegal division by zero". The bug can be reproduced by: $ perl -MMath::Quaternion -wE 'my $q = Math::Quaternion->new(-9,0,0,0); say $q * $q; say $q->power(2);' ( 81 0 0 0 ) Illegal division by zero at .../Math/Quaternion.pm line 527. This is due to the interaction of any real quaternion, and this code in sub power(): my $vecmod = sqrt($a1*$a1+$a2*$a2+$a3*$a3); my $stob = ($s**$b); my $coeff = $stob/$vecmod*sin($b*$theta); When $q->isreal, then $vecmod will always be zero, and the calculation of $coeff will always cause a divide-by-zero error. The bug can be fixed by adding code just below the `if (ref $b)` block: # For real_quaternion^real_number, use built-in power. if ($a->isreal) { return Math::Quaternion->new( $a->[0] ** $b, 0, 0, 0 ) ; } Other info: $ uname -a Darwin bg 12.4.0 Darwin Kernel Version 12.4.0: Wed May 1 17:57:12 PDT 2013; root:xnu-2050.24.15~1/RELEASE_X86_64 x86_64 ( OS X Mountain Lion ) $ perl -v This is perl 5, version 18, subversion 0 (v5.18.0) built for darwin-2level BTW, I found this bug while preparing a test harness to compare the output of your Perl 5 Math::Quaternion module with my Perl 6 version: https://github.com/Util/Perl6-Math-Quaternion I have coded the fix, and added tests which fail without the fix, and pass with the fix. Patch to follow momentarily. -- Thanks for your open-source work! Bruce Gray (Util on IRC and PerlMonks)
From: bruce.gray [...] acm.org
On Wed Jun 12 15:49:47 2013, bruce.gray@acm.org wrote: Show quoted text
> Patch to follow momentarily.
Here is the patch, attached.
Subject: 0001-Fix-RT-86098-Divide-by-zero-error-in-q-power.patch
From bbd2c7533e97f03032e997b27b5bd2a950126f7d Mon Sep 17 00:00:00 2001 From: Bruce Gray <bruce.gray@acm.org> Date: Wed, 12 Jun 2013 14:58:41 -0500 Subject: [PATCH] Fix RT#86098: Divide-by-zero error in q->power. --- lib/Math/Quaternion.pm | 5 +++++ t/001_basic.t | 13 ++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/Math/Quaternion.pm b/lib/Math/Quaternion.pm index 0abea72..0055f45 100644 --- a/lib/Math/Quaternion.pm +++ b/lib/Math/Quaternion.pm @@ -516,6 +516,11 @@ sub power { return Math::Quaternion::exp(Math::Quaternion::multiply($b,Math::Quaternion::log($a))); } + # For real_quaternion^real_number, use built-in power. + if ($a->isreal) { + return Math::Quaternion->new( $a->[0] ** $b, 0, 0, 0 ) ; + } + # For quat raised to a scalar power, do it manually. my ($a0,$a1,$a2,$a3) = @$a; diff --git a/t/001_basic.t b/t/001_basic.t index ac265d6..1a6d522 100644 --- a/t/001_basic.t +++ b/t/001_basic.t @@ -1,4 +1,4 @@ -use Test::More tests => 78; +use Test::More tests => 82; use Math::Trig; use strict; use Carp; @@ -236,6 +236,17 @@ ok( equal_fuzz($q1expon->modulus,($q1->modulus)**$exponent), ok( quatequal_fuzz($q1i,Math::Quaternion::power($q1,-1)), "Quaternion raised to (-1)th power is inverse"); +{ + # RT#86098 + my $q = Math::Quaternion->new( -9, 0, 0, 0 ); + ok( $q->isreal, 'A quaternion (which ->isreal)'); + my $q_q = $q * $q; + my $q_2 = eval { $q->power(2); }; + my $lived = !$@; + ok( checkquat($q_q, 81,0,0,0), "...can be multiplied by its self,"); + ok( checkquat($q_2, 81,0,0,0), "...and can be raised to the power of 2"); + ok( $lived, "...without dying."); +} # Check exponentiation -- 1.7.10.2 (Apple Git-33)
Fixed in 0.0.5, thanks for the patch!