6

Quaternion multiplication is well-defined, and is known to me as "Hamilton product":

// hamilton product
vec4 qmul(in vec4 q1, in vec4 q2) {
 return vec4(
 q1.w * q2.xyz + q2.w * q1.xyz - cross(q1.xyz, q2.xyz),
 q1.w*q2.w - dot(q1.xyz, q2.xyz)
 );
}

However, for implementing qtanh() quaternionic function, we need division. So far I've found this, and it is working OK. Could you help me to undestand, where does this comes from?

// division
// https://www.boost.org/doc/libs/1_67_0/boost/math/quaternion.hpp
vec4 qdiv(in vec4 q1, in vec4 q2) {
float denominator = dot(q2,q2);
return vec4( 
 vec3(
 -q1.w*q2.x+q1.x*q2.w-q1.y*q2.z+q1.z*q2.y,
 -q1.w*q2.y+q1.x*q2.z+q1.y*q2.w-q1.z*q2.x,
 -q1.w*q2.z-q1.x*q2.y+q1.y*q2.x+q1.z*q2.w
 ),
 q1.w*q2.w + dot(q1.xyz, q2.xyz)
) / denominator;
}

Also, as far as I am trying to implement tanh().. are you aware of more computationally vat, than dividing sinh and cosh? For reals I've used to use following formula: tanh(x)=-1+2/(1+exp(-x)). And that involves only single exponential calculus, instead of two..

asked Apr 19, 2019 at 13:21

1 Answer 1

4

1. Division

Dividing a quaternion named p by a quaternion named q is nothing more than multiplying p by the reciprocal of q.

This is equivalent to multiplying p by the conjugation of q (which by definition equals a – bi – cj – dk) and dividing the product by a scalar equalling q norm squared:

From here it`s obvious where that denominator part comes from:

Now let`s rearrange the terms in vec3 sums for better readability:

vec3(
 -q1.w*q2.x + q1.x*q2.w - (q1.y*q2.z - q1.z*q2.y),
 -q1.w*q2.y + q1.y*q2.w - (q1.z*q2.x - q1.x*q2.z),
 -q1.w*q2.z + q1.z*q2.w - (q1.x*q2.y - q1.y*q2.x)
)

And now it suddenly gets clear what`s going on:

vec3(
 -q1.w * q2.x + q1.x * q2.w - (q1.y*q2.z - q1.z*q2.y),
 -q1.w * q2.y + q1.y * q2.w - (q1.z*q2.x - q1.x*q2.z),
 -q1.w * q2.z + q1.z * q2.w - (q1.x*q2.y - q1.y*q2.x)
)
...
 -q1.w * q2.xyz + q1.xyz * q2.w - (cross(q1.xyz, q2.xyz))

So yeah, quaternion division is just the regular run-of-the-mill multiplication, with the multiplicand being a reciprocal. That`s where the minuses come from, see the definition above.

2. Hyperbolic tangent

First, the definitions. For each q = a + bi + cj + dk = a + v̅:

So, to get both eq and e–q you only need to compute the following values: ea, ||v̅||, sin(||v̅||), cos(||v̅||).

To compute e–q you should take a reciprocal of ea and multiply it by the rest of the equation with signs inverted. That won`t take much time, for all the values it consists of have already been computed. One exp() call, as requested =)

answered Apr 19, 2019 at 15:33
Sign up to request clarification or add additional context in comments.

6 Comments

Could a tanh be implemented with only one exp() call, eg, for reals I used tanh(x)==-1+2/(1+exp(-x))
Could I cheat and somehow lower its computational complexity?
@xakepp35 Seems like yes, but the comment section is not very convenient to post the solution. Please amend your question and I`ll add it to my answer.
Added to the end
@xakepp35 Done.
|

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.