--- ./boost/math/octonion.hpp~ 2011-08-01 22:14:24.000000000 +0900 +++ ./boost/math/octonion.hpp 2011-08-02 21:24:08.000000000 +0900 @@ -4780,8 +4780,10 @@ #else // acos(q) = 1/UVq acosh(q) //return(static_cast(1)/u*acosh(q)); // the signs of imagpart are different with complex ones when |Vq| == 0 - octonion r = static_cast(1)/u*acosh(q); - return(r.real() + r.unreal()*static_cast((abs(unreal(q)) != static_cast(0)) ? 1 : -1)); + octonion s = sqrt(pow(q, 2) - static_cast(1)), r = log(q + s); + r = (real(r) < 0) ? log(q - s) : r; + r = static_cast(1)/u*r; // the signs of imagpart are different with complex ones when |Vq| == 0 && |Sq| > 1 + return(r.real() + r.unreal()*static_cast((abs(unreal(q)) != static_cast(0) || !(std::abs(real(q)) > 1)) ? 1 : -1)); #endif } @@ -4799,7 +4801,8 @@ #else // asin(q) = 1/UVq asinh(q UVq) //return(static_cast(1)/u*asinh(q*u)); // the signs of imagpart are different with complex ones when |Vq| == 0 && Sq > 0 - octonion r = static_cast(1)/u*asinh(q*u); + octonion p = q*u; + octonion r = static_cast(1)/u*log(p + sqrt(pow(p, 2) + static_cast(1))); return(r.real() + r.unreal()*static_cast((abs(unreal(q)) != static_cast(0) || real(q) < 0) ? 1 : -1)); #endif } @@ -4829,7 +4832,13 @@ // the signs of realpart are different with complex ones when Sq == 0 && Vq < -1 #else // atan(q) = -UVq atanh(q UVq) - return(static_cast(1)/u*atanh(q*u)); // the signs of realpart are different with complex ones when Sq == 0 && Vq < -1 + //return(static_cast(1)/u*atanh(q*u)); // the signs of realpart are different with complex ones when Sq == 0 && Vq < -1 + octonion p = q*u; + octonion v = (abs(unreal(p)) != static_cast(0)) ? unreal(p)/abs(unreal(p)) : octonion (0, 1, 0, 0, 0, 0, 0, 0); + octonion d = (static_cast(1)-p), c = static_cast(1)/d*(static_cast(1)+p), r = static_cast(1)/static_cast(2)*log(c); + r = (abs(d) != static_cast(0) && abs(c) != static_cast(0)) ? ((real(p) != static_cast(0)) ? r : r.unreal()) : octonion (0); + r = -u*r; + return(r); // the signs of realpart are different with complex ones when Sq == 0 && Vq < -1 #endif } @@ -4837,18 +4846,40 @@ template inline octonion acosh(octonion const & q) { +#if 1 // acosh(q) = log(q + sqrt(q^2 - 1)) //return(log(q + sqrt(pow(q, 2) - static_cast(1)))); octonion s = sqrt(pow(q, 2) - static_cast(1)), r = log(q + s); - return((real(r) < 0) ? log(q - s) : r); + r = (real(r) < 0) ? log(q - s) : r; // the signs of imagpart are different with complex ones when |Vq| == 0 && |Sq| > 1 + return(r.real() + r.unreal()*static_cast((abs(unreal(q)) != static_cast(0) || !(std::abs(real(q)) > 1)) ? 1 : -1)); +#else + octonion u = (abs(unreal(q)) != static_cast(0)) ? unreal(q)/abs(unreal(q)) : octonion (0, 1, 0, 0, 0, 0, 0, 0); + // acosh(q) = UVq acos(q) + //return(u*acos(q)); // the signs of realpart are different with complex ones when |Vq| == 0 + octonion r = log(q + (u)*sqrt(static_cast(1) - pow(q, 2))); + // the signs of realpart are different with complex ones when |Vq| == 0 && Sq > 1 + //return(r.real()*static_cast((abs(unreal(q)) != static_cast(0) || real(q) < 1) ? 1 : -1) + r.unreal()); // the values of imagpart are different when |Vq| == 0 && Sq > 1 + r = r.real()*static_cast((abs(unreal(q)) != static_cast(0) || real(q) < 1) ? 1 : -1) + ((abs(unreal(q)) != static_cast(0) || real(q) < 1) ? r.unreal() : octonion (0)); + // the signs of imagpart are different with complex ones when |Vq| == 0 && |Sq| > 1 + return(r.real() + r.unreal()*static_cast((abs(unreal(q)) != static_cast(0) || !(std::abs(real(q)) > 1)) ? 1 : -1)); +#endif } template inline octonion asinh(octonion const & q) { +#if 1 // asinh(q) = log(q + sqrt(q^2 + 1)) return(log(q + sqrt(pow(q, 2) + static_cast(1)))); // the signs of realpart are different with complex ones when Sq == 0 && Vq > 1 +#else + octonion u = (abs(unreal(q)) != static_cast(0)) ? unreal(q)/abs(unreal(q)) : octonion (0, 1, 0, 0, 0, 0, 0, 0); + // asinh(q) = UVq asin(-q UVq) + //return(u*asin(-q*u)); // the signs of realpart are different with complex ones when Sq == 0 && Vq < 1 + octonion p = -q*u; + octonion v = (abs(unreal(p)) != static_cast(0)) ? unreal(p)/abs(unreal(p)) : octonion (0, 1, 0, 0, 0, 0, 0, 0); + return(u*(-v*log(p*v + sqrt(static_cast(1) - pow(p, 2))))); // the signs of realpart are different with complex ones when Sq == 0 && Vq > 1 +#endif } @@ -4865,11 +4896,23 @@ (q.R_component_6()==static_cast(0)) ? 0 : q.R_component_6()*inf, (q.R_component_7()==static_cast(0)) ? 0 : q.R_component_7()*inf, (q.R_component_8()==static_cast(0)) ? 0 : q.R_component_8()*inf)); +#if 1 // atanh(q) = 1/2 log( (1-q)^{-1} (1+q) ) //return(static_cast(1)/static_cast(2)*log(static_cast(1)/(static_cast(1)-q)*(static_cast(1)+q))); octonion d = (static_cast(1)-q), c = static_cast(1)/d*(static_cast(1)+q), r = static_cast(1)/static_cast(2)*log(c); - //return((abs(d) != static_cast(0) && abs(c) != static_cast(0)) ? r : octonion (0)); - return((abs(d) != static_cast(0) && abs(c) != static_cast(0)) ? ((real(q) != static_cast(0)) ? r : unreal(r)) : octonion (0)); + //return((abs(d) != static_cast(0) && abs(c) != static_cast(0)) ? r : octonion (0)); // the values of realpart are different when Sq == 0 + return((abs(d) != static_cast(0) && abs(c) != static_cast(0)) ? ((real(q) != static_cast(0)) ? r : r.unreal()) : octonion (0)); +#else + octonion u = (abs(unreal(q)) != static_cast(0)) ? unreal(q)/abs(unreal(q)) : octonion (0, 1, 0, 0, 0, 0, 0, 0); + // atanh(q) = UVq atan(-q UVq) + //return(u*atan(-q*u)); // the signs of realpart are different with complex ones when Sq == 0 && Vq < 0 + octonion p = -q*u; + octonion v = (abs(unreal(p)) != static_cast(0)) ? unreal(p)/abs(unreal(p)) : octonion (0, 1, 0, 0, 0, 0, 0, 0); + octonion d = static_cast(1)-p*v, c = static_cast(1)/d*(static_cast(1)+p*v), r = -v/static_cast(2)*log(c); + r = (abs(d) != static_cast(0) && abs(c) != static_cast(0)) ? ((abs(unreal(p)) != static_cast(0)) ? r : octonion (real(r))) : octonion (0); + r = u*r; // the signs of imagpart are different with complex ones when Sq > 1 && |Vq| == 0 + return(r.real() + r.unreal()*static_cast((real(q) < 1 || abs(unreal(q)) != static_cast(0)) ? 1: -1)); +#endif } --- ./boost/math/quaternion.hpp~ 2011-08-01 22:06:15.000000000 +0900 +++ ./boost/math/quaternion.hpp 2011-08-02 20:25:05.000000000 +0900 @@ -1974,8 +1974,10 @@ #else // acos(q) = 1/UVq acosh(q) //return(static_cast(1)/u*acosh(q)); // the signs of imagpart are different with complex ones when |Vq| == 0 - quaternion r = static_cast(1)/u*acosh(q); - return(r.real() + r.unreal()*static_cast((abs(unreal(q)) != static_cast(0)) ? 1 : -1)); + quaternion s = sqrt(pow(q, 2) - static_cast(1)), r = log(q + s); + r = (real(r) < 0) ? log(q - s) : r; + r = static_cast(1)/u*r; // the signs of imagpart are different with complex ones when |Vq| == 0 && |Sq| > 1 + return(r.real() + r.unreal()*static_cast((abs(unreal(q)) != static_cast(0) || !(std::abs(real(q)) > 1)) ? 1 : -1)); #endif } @@ -1993,7 +1995,8 @@ #else // asin(q) = 1/UVq asinh(q UVq) //return(static_cast(1)/u*asinh(q*u)); // the signs of imagpart are different with complex ones when |Vq| == 0 && Sq > 0 - quaternion r = static_cast(1)/u*asinh(q*u); + quaternion p = q*u; + quaternion r = static_cast(1)/u*log(p + sqrt(pow(p, 2) + static_cast(1))); return(r.real() + r.unreal()*static_cast((abs(unreal(q)) != static_cast(0) || real(q) < 0) ? 1 : -1)); #endif } @@ -2019,7 +2022,13 @@ // the signs of realpart are different with complex ones when Sq == 0 && Vq < -1 #else // atan(q) = -UVq atanh(q UVq) - return(static_cast(1)/u*atanh(q*u)); // the signs of realpart are different with complex ones when Sq == 0 && Vq < -1 + //return(static_cast(1)/u*atanh(q*u)); // the signs of realpart are different with complex ones when Sq == 0 && Vq < -1 + quaternion p = q*u; + quaternion v = (abs(unreal(p)) != static_cast(0)) ? unreal(p)/abs(unreal(p)) : quaternion(0, 1, 0, 0); + quaternion d = (static_cast(1)-p), c = static_cast(1)/d*(static_cast(1)+p), r = static_cast(1)/static_cast(2)*log(c); + r = (abs(d) != static_cast(0) && abs(c) != static_cast(0)) ? ((real(p) != static_cast(0)) ? r : r.unreal()) : quaternion(0); + r = -u*r; + return(r); // the signs of realpart are different with complex ones when Sq == 0 && Vq < -1 #endif } @@ -2027,18 +2036,40 @@ template inline quaternion acosh(quaternion const & q) { +#if 1 // acosh(q) = log(q + sqrt(q^2 - 1)) //return(log(q + sqrt(pow(q, 2) - static_cast(1)))); quaternion s = sqrt(pow(q, 2) - static_cast(1)), r = log(q + s); - return((real(r) < 0) ? log(q - s) : r); + r = (real(r) < 0) ? log(q - s) : r; // the signs of imagpart are different with complex ones when |Vq| == 0 && |Sq| > 1 + return(r.real() + r.unreal()*static_cast((abs(unreal(q)) != static_cast(0) || !(std::abs(real(q)) > 1)) ? 1 : -1)); +#else + quaternion u = (abs(unreal(q)) != static_cast(0)) ? unreal(q)/abs(unreal(q)) : quaternion(0, 1, 0, 0); + // acosh(q) = UVq acos(q) + //return(u*acos(q)); // the signs of realpart are different with complex ones when |Vq| == 0 + quaternion r = log(q + (u)*sqrt(static_cast(1) - pow(q, 2))); + // the signs of realpart are different with complex ones when |Vq| == 0 && Sq > 1 + //return(r.real()*static_cast((abs(unreal(q)) != static_cast(0) || real(q) < 1) ? 1 : -1) + r.unreal()); // the values of imagpart are different when |Vq| == 0 && Sq > 1 + r = r.real()*static_cast((abs(unreal(q)) != static_cast(0) || real(q) < 1) ? 1 : -1) + ((abs(unreal(q)) != static_cast(0) || real(q) < 1) ? r.unreal() : quaternion(0)); + // the signs of imagpart are different with complex ones when |Vq| == 0 && |Sq| > 1 + return(r.real() + r.unreal()*static_cast((abs(unreal(q)) != static_cast(0) || !(std::abs(real(q)) > 1)) ? 1 : -1)); +#endif } template inline quaternion asinh(quaternion const & q) { +#if 1 // asinh(q) = log(q + sqrt(q^2 + 1)) return(log(q + sqrt(pow(q, 2) + static_cast(1)))); // the signs of realpart are different with complex ones when Sq == 0 && Vq > 1 +#else + quaternion u = (abs(unreal(q)) != static_cast(0)) ? unreal(q)/abs(unreal(q)) : quaternion(0, 1, 0, 0); + // asinh(q) = UVq asin(-q UVq) + //return(u*asin(-q*u)); // the signs of realpart are different with complex ones when Sq == 0 && Vq < 1 + quaternion p = -q*u; + quaternion v = (abs(unreal(p)) != static_cast(0)) ? unreal(p)/abs(unreal(p)) : quaternion(0, 1, 0, 0); + return(u*(-v*log(p*v + sqrt(static_cast(1) - pow(p, 2))))); // the signs of realpart are different with complex ones when Sq == 0 && Vq > 1 +#endif } @@ -2051,11 +2082,23 @@ (q.R_component_2()==static_cast(0)) ? 0 : q.R_component_2()*inf, (q.R_component_3()==static_cast(0)) ? 0 : q.R_component_3()*inf, (q.R_component_4()==static_cast(0)) ? 0 : q.R_component_4()*inf)); +#if 1 // atanh(q) = 1/2 log( (1-q)^{-1} (1+q) ) //return(static_cast(1)/static_cast(2)*log(static_cast(1)/(static_cast(1)-q)*(static_cast(1)+q))); quaternion d = (static_cast(1)-q), c = static_cast(1)/d*(static_cast(1)+q), r = static_cast(1)/static_cast(2)*log(c); - //return((abs(d) != static_cast(0) && abs(c) != static_cast(0)) ? r : quaternion(0)); - return((abs(d) != static_cast(0) && abs(c) != static_cast(0)) ? ((real(q) != static_cast(0)) ? r : unreal(r)) : quaternion(0)); + //return((abs(d) != static_cast(0) && abs(c) != static_cast(0)) ? r : quaternion(0)); // the values of realpart are different when Sq == 0 + return((abs(d) != static_cast(0) && abs(c) != static_cast(0)) ? ((real(q) != static_cast(0)) ? r : r.unreal()) : quaternion(0)); +#else + quaternion u = (abs(unreal(q)) != static_cast(0)) ? unreal(q)/abs(unreal(q)) : quaternion(0, 1, 0, 0); + // atanh(q) = UVq atan(-q UVq) + //return(u*atan(-q*u)); // the signs of realpart are different with complex ones when Sq == 0 && Vq < 0 + quaternion p = -q*u; + quaternion v = (abs(unreal(p)) != static_cast(0)) ? unreal(p)/abs(unreal(p)) : quaternion(0, 1, 0, 0); + quaternion d = static_cast(1)-p*v, c = static_cast(1)/d*(static_cast(1)+p*v), r = -v/static_cast(2)*log(c); + r = (abs(d) != static_cast(0) && abs(c) != static_cast(0)) ? ((abs(unreal(p)) != static_cast(0)) ? r : quaternion(real(r))) : quaternion(0); + r = u*r; // the signs of imagpart are different with complex ones when Sq > 1 && |Vq| == 0 + return(r.real() + r.unreal()*static_cast((real(q) < 1 || abs(unreal(q)) != static_cast(0)) ? 1: -1)); +#endif }