# HG changeset patch # User Avinoam # Date 1466966118 -10800 # Sun Jun 26 21:35:18 2016 +0300 # Node ID 47a9ccc0b315acb16cadbedf29ea349ad0d88c73 # Parent aa6ed971e5b366fcd8dfe98b711254a8cff29a84 Fix log and exp in degenerate cases (bug #48288) * log.m: special treatment for the case norm(q)=0, norn(v)=0 * exp.m: special treatment for the case norn(v)=0 diff -r aa6ed971e5b3 -r 47a9ccc0b315 inst/@quaternion/exp.m --- a/inst/@quaternion/exp.m Thu Jan 21 11:24:08 2016 +0100 +++ b/inst/@quaternion/exp.m Sun Jun 26 21:35:18 2016 +0300 @@ -32,9 +32,14 @@ exps = exp (q.w); sinv = sin (normv); - q.w = exps .* cos (normv); - q.x = exps .* (q.x ./ normv) .* sinv; - q.y = exps .* (q.y ./ normv) .* sinv; - q.z = exps .* (q.z ./ normv) .* sinv; - + q.w = exps .* cos (normv); + if (normv == 0) + q.x = 0; + q.y = 0; + q.z = 0; + else + q.x = exps .* (q.x ./ normv) .* sinv; + q.y = exps .* (q.y ./ normv) .* sinv; + q.z = exps .* (q.z ./ normv) .* sinv; + end endfunction diff -r aa6ed971e5b3 -r 47a9ccc0b315 inst/@quaternion/log.m --- a/inst/@quaternion/log.m Thu Jan 21 11:24:08 2016 +0100 +++ b/inst/@quaternion/log.m Sun Jun 26 21:35:18 2016 +0300 @@ -30,13 +30,21 @@ normq = abs (q); normv = normv (q); - acossq = acos (q.w ./ normq); - q.w = log (normq); - q.x = (q.x ./ normv) .* acossq; - q.y = (q.y ./ normv) .* acossq; - q.z = (q.z ./ normv) .* acossq; + if (normv == 0) + if (q.w >= 0) + q = quaternion (log (normq), 0, 0, 0); + else + q = quaternion (log (normq), pi, 0, 0); + endif + else + acossq = acos (q.w ./ normq); + q.w = log (normq); + q.x = (q.x ./ normv) .* acossq; + q.y = (q.y ./ normv) .* acossq; + q.z = (q.z ./ normv) .* acossq; + endif ## FIXME: q = quaternion (2, 3, 4, 5) ## p = log (exp (q)) ## p.v is wrong, probably somehow related to acos