Just another update
This commit is contained in:
parent
a25938f123
commit
00a190b0a6
6591 changed files with 94363 additions and 23227 deletions
48
Task/Quaternion-type/Axiom/quaternion-type.axiom
Normal file
48
Task/Quaternion-type/Axiom/quaternion-type.axiom
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
qi := quatern$Quaternion(Integer);
|
||||
|
||||
Type: ((Integer,Integer,Integer,Integer) -> Quaternion(Integer))
|
||||
q := qi(1,2,3,4);
|
||||
|
||||
Type: Quaternion(Integer)
|
||||
q1 := qi(2,3,4,5);
|
||||
|
||||
Type: Quaternion(Integer)
|
||||
q2 := qi(3,4,5,6);
|
||||
|
||||
Type: Quaternion(Integer)
|
||||
r : Integer := 7;
|
||||
|
||||
Type: Integer
|
||||
sqrt norm q
|
||||
|
||||
+--+
|
||||
(6) \|30
|
||||
Type: AlgebraicNumber
|
||||
-q
|
||||
|
||||
(7) - 1 - 2i - 3j - 4k
|
||||
Type: Quaternion(Integer)
|
||||
conjugate q
|
||||
|
||||
(8) 1 - 2i - 3j - 4k
|
||||
Type: Quaternion(Integer)
|
||||
r + q
|
||||
|
||||
(9) 8 + 2i + 3j + 4k
|
||||
Type: Quaternion(Integer)
|
||||
q1 + q2
|
||||
|
||||
(10) 5 + 7i + 9j + 11k
|
||||
Type: Quaternion(Integer)
|
||||
q*r
|
||||
|
||||
(11) 7 + 14i + 21j + 28k
|
||||
Type: Quaternion(Integer)
|
||||
r*q
|
||||
|
||||
(12) 7 + 14i + 21j + 28k
|
||||
Type: Quaternion(Integer)
|
||||
q1*q2 ~= q2*q1
|
||||
|
||||
(13) true
|
||||
Type: Boolean
|
||||
|
|
@ -2,92 +2,96 @@ import std.math, std.numeric, std.traits, std.conv, std.complex;
|
|||
|
||||
|
||||
struct Quat(T) if (isFloatingPoint!T) {
|
||||
alias Complex!T CT;
|
||||
alias CT = Complex!T;
|
||||
|
||||
union {
|
||||
struct { T re, i, j, k; } // Default init to NaN
|
||||
struct { T re, i, j, k; } // Default init to NaN.
|
||||
struct { CT x, y; }
|
||||
struct { T[4] vector; }
|
||||
}
|
||||
|
||||
string toString() const /*pure nothrow*/ {
|
||||
return text(vector);
|
||||
string toString() const pure /*nothrow*/ @safe {
|
||||
return vector.text;
|
||||
}
|
||||
|
||||
@property T norm2() const pure nothrow { /// Norm squared
|
||||
@property T norm2() const pure nothrow @safe @nogc { /// Norm squared.
|
||||
return re ^^ 2 + i ^^ 2 + j ^^ 2 + k ^^ 2;
|
||||
}
|
||||
|
||||
@property T abs() const pure nothrow { /// Norm
|
||||
@property T abs() const pure nothrow @safe @nogc { /// Norm.
|
||||
return sqrt(norm2);
|
||||
}
|
||||
|
||||
@property T arg() const pure nothrow { /// Theta
|
||||
@property T arg() const pure nothrow @safe @nogc { /// Theta.
|
||||
return acos(re / abs); // this may be incorrect...
|
||||
}
|
||||
|
||||
@property Quat!T conj() const pure nothrow { /// Conjugate
|
||||
@property Quat!T conj() const pure nothrow @safe @nogc { /// Conjugate.
|
||||
return Quat!T(re, -i, -j, -k);
|
||||
}
|
||||
|
||||
@property Quat!T recip() const pure nothrow { /// Reciprocal
|
||||
@property Quat!T recip() const pure nothrow @safe @nogc { /// Reciprocal.
|
||||
return Quat!T(re / norm2, -i / norm2, -j / norm2, -k / norm2);
|
||||
}
|
||||
|
||||
@property Quat!T pureim() const pure nothrow { /// Pure imagery
|
||||
@property Quat!T pureim() const pure nothrow @safe @nogc { /// Pure imagery.
|
||||
return Quat!T(0, i, j, k);
|
||||
}
|
||||
|
||||
@property Quat!T versor() const pure nothrow { /// Unit versor
|
||||
@property Quat!T versor() const pure nothrow @safe @nogc { /// Unit versor.
|
||||
return this / abs;
|
||||
}
|
||||
|
||||
/// Unit versor of imagery part
|
||||
@property Quat!T iversor() const pure nothrow {
|
||||
/// Unit versor of imagery part.
|
||||
@property Quat!T iversor() const pure nothrow @safe @nogc {
|
||||
return pureim / pureim.abs;
|
||||
}
|
||||
|
||||
/// Assignment
|
||||
Quat!T opAssign(U : T)(Quat!U z) pure nothrow {
|
||||
/// Assignment.
|
||||
Quat!T opAssign(U : T)(Quat!U z) pure nothrow @safe @nogc {
|
||||
x = z.x; y = z.y;
|
||||
return this;
|
||||
}
|
||||
|
||||
Quat!T opAssign(U : T)(Complex!U c) pure nothrow {
|
||||
Quat!T opAssign(U : T)(Complex!U c) pure nothrow @safe @nogc {
|
||||
x = c; y = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
Quat!T opAssign(U : T)(U r) pure nothrow if (isNumeric!U) {
|
||||
Quat!T opAssign(U : T)(U r) pure nothrow @safe @nogc
|
||||
if (isNumeric!U) {
|
||||
re = r; i = 0; y = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// Test for equal, not ordered so no opCmp
|
||||
bool opEquals(U : T)(Quat!U z) const pure nothrow {
|
||||
/// Test for equal, not ordered so no opCmp.
|
||||
bool opEquals(U : T)(Quat!U z) const pure nothrow @safe @nogc {
|
||||
return re == z.re && i == z.i && j == z.j && k == z.k;
|
||||
}
|
||||
|
||||
bool opEquals(U : T)(Complex!U c) const pure nothrow {
|
||||
bool opEquals(U : T)(Complex!U c) const pure nothrow @safe @nogc {
|
||||
return re == c.re && i == c.im && j == 0 && k == 0;
|
||||
}
|
||||
|
||||
bool opEquals(U : T)(U r) const pure nothrow if (isNumeric!U) {
|
||||
bool opEquals(U : T)(U r) const pure nothrow @safe @nogc
|
||||
if (isNumeric!U) {
|
||||
return re == r && i == 0 && j == 0 && k == 0;
|
||||
}
|
||||
|
||||
/// Unary op
|
||||
Quat!T opUnary(string op)() const pure nothrow if (op == "+") {
|
||||
/// Unary op.
|
||||
Quat!T opUnary(string op)() const pure nothrow @safe @nogc
|
||||
if (op == "+") {
|
||||
return this;
|
||||
}
|
||||
|
||||
Quat!T opUnary(string op)() const pure nothrow if (op == "-") {
|
||||
Quat!T opUnary(string op)() const pure nothrow @safe @nogc
|
||||
if (op == "-") {
|
||||
return Quat!T(-re, -i, -j, -k);
|
||||
}
|
||||
|
||||
/// Binary op, Quaternion on left of op
|
||||
/// Binary op, Quaternion on left of op.
|
||||
Quat!(CommonType!(T,U)) opBinary(string op, U)(Quat!U z)
|
||||
const pure nothrow {
|
||||
const pure nothrow @safe @nogc {
|
||||
alias typeof(return) C;
|
||||
|
||||
static if (op == "+" ) {
|
||||
|
|
@ -104,15 +108,16 @@ struct Quat(T) if (isFloatingPoint!T) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Extend complex to quaternion
|
||||
/// Extend complex to quaternion.
|
||||
Quat!(CommonType!(T,U)) opBinary(string op, U)(Complex!U c)
|
||||
const pure nothrow {
|
||||
const pure nothrow @safe @nogc {
|
||||
return opBinary!op(typeof(return)(c.re, c.im, 0, 0));
|
||||
}
|
||||
|
||||
/// For scalar
|
||||
/// For scalar.
|
||||
Quat!(CommonType!(T,U)) opBinary(string op, U)(U r)
|
||||
const pure nothrow if (isNumeric!U) {
|
||||
const pure nothrow @safe @nogc
|
||||
if (isNumeric!U) {
|
||||
alias typeof(return) C;
|
||||
|
||||
static if (op == "+" ) {
|
||||
|
|
@ -128,23 +133,25 @@ struct Quat(T) if (isFloatingPoint!T) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Power function
|
||||
/// Power function.
|
||||
Quat!(CommonType!(T,U)) pow(U)(U r)
|
||||
const pure nothrow if (isNumeric!U) {
|
||||
const pure nothrow @safe @nogc
|
||||
if (isNumeric!U) {
|
||||
return (abs^^r) * exp(r * iversor * arg);
|
||||
}
|
||||
|
||||
/// Handle binary op if Quaternion on right of op and left is
|
||||
/// not quaternion.
|
||||
Quat!(CommonType!(T,U)) opBinaryRight(string op, U)(Complex!U c)
|
||||
const pure nothrow {
|
||||
const pure nothrow @safe @nogc {
|
||||
alias typeof(return) C;
|
||||
auto w = C(c.re, c.im, 0, 0);
|
||||
return w.opBinary!(op)(this);
|
||||
}
|
||||
|
||||
Quat!(CommonType!(T,U)) opBinaryRight(string op, U)(U r)
|
||||
const pure nothrow if (isNumeric!U) {
|
||||
const pure nothrow @safe @nogc
|
||||
if (isNumeric!U) {
|
||||
alias typeof(return) C;
|
||||
|
||||
static if (op == "+" || op == "*") {
|
||||
|
|
@ -159,20 +166,23 @@ struct Quat(T) if (isFloatingPoint!T) {
|
|||
}
|
||||
|
||||
|
||||
HT exp(HT)(HT z) pure nothrow if (is(HT T == Quat!T)) {
|
||||
HT exp(HT)(HT z) pure nothrow @safe @nogc
|
||||
if (is(HT T == Quat!T)) {
|
||||
immutable inorm = z.pureim.abs;
|
||||
return std.math.exp(z.re) * (cos(inorm) + z.iversor * sin(inorm));
|
||||
}
|
||||
|
||||
HT log(HT)(HT z) pure nothrow if (is(HT T == Quat!T)) {
|
||||
HT log(HT)(HT z) pure nothrow @safe @nogc
|
||||
if (is(HT T == Quat!T)) {
|
||||
return std.math.log(z.abs) + z.iversor * acos(z.re / z.abs);
|
||||
}
|
||||
|
||||
|
||||
void main() { // Demo code
|
||||
void main() @safe { // Demo code.
|
||||
import std.stdio;
|
||||
alias Quat!real QR;
|
||||
immutable real r = 7;
|
||||
|
||||
alias QR = Quat!real;
|
||||
enum real r = 7.0;
|
||||
|
||||
immutable QR q = QR(2, 3, 4, 5),
|
||||
q1 = QR(2, 3, 4, 5),
|
||||
|
|
@ -207,7 +217,7 @@ void main() { // Demo code
|
|||
writeln(" log(q): ", log(q));
|
||||
writeln(" exp(log(q)): ", exp(log(q)));
|
||||
writeln(" log(exp(q)): ", log(exp(q)));
|
||||
immutable s = log(exp(q));
|
||||
immutable s = q.exp.log;
|
||||
writeln("9.5 let s = log(exp(q)): ", s);
|
||||
writeln(" exp(s): ", exp(s));
|
||||
writeln(" log(s): ", log(s));
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import Base: convert, promote_rule, show, real, imag, conj, abs, abs2, inv, +, -, /, *
|
||||
import Base: convert, promote_rule, show, conj, abs, +, -, *
|
||||
|
||||
immutable Quaternion{T<:Real} <: Number
|
||||
q0::T
|
||||
|
|
@ -25,18 +25,11 @@ function show(io::IO, z::Quaternion)
|
|||
print(io, z.q0, pm(z.q1), "i", pm(z.q2), "j", pm(z.q3), "k")
|
||||
end
|
||||
|
||||
real(z::Quaternion) = z.q0
|
||||
imag(z::Quaternion) = z.q1
|
||||
|
||||
conj(z::Quaternion) = Quaternion(z.q0, -z.q1, -z.q2, -z.q3)
|
||||
abs(z::Quaternion) = sqrt(z.q0*z.q0 + z.q1*z.q1 + z.q2*z.q2 + z.q3*z.q3)
|
||||
abs2(z::Quaternion) = z.q0*z.q0 + z.q1*z.q1 + z.q2*z.q2 + z.q3*z.q3
|
||||
inv(z::Quaternion) = conj(z)/abs2(z)
|
||||
|
||||
(-)(z::Quaternion) = Quaternion(-z.q0, -z.q1, -z.q2, -z.q3)
|
||||
|
||||
(/)(z::Quaternion, x::Real) = Quaternion(z.q0/x, z.q1/x, z.q2/x, z.q3/x)
|
||||
|
||||
(+)(z::Quaternion, w::Quaternion) = Quaternion(z.q0 + w.q0, z.q1 + w.q1,
|
||||
z.q2 + w.q2, z.q3 + w.q3)
|
||||
(-)(z::Quaternion, w::Quaternion) = Quaternion(z.q0 - w.q0, z.q1 - w.q1,
|
||||
|
|
@ -45,4 +38,3 @@ inv(z::Quaternion) = conj(z)/abs2(z)
|
|||
z.q0*w.q1 + z.q1*w.q0 + z.q2*w.q3 - z.q3*w.q2,
|
||||
z.q0*w.q2 - z.q1*w.q3 + z.q2*w.q0 + z.q3*w.q1,
|
||||
z.q0*w.q3 + z.q1*w.q2 - z.q2*w.q1 + z.q3*w.q0)
|
||||
(/)(z::Quaternion, w::Quaternion) = z*inv(w)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ io.write( "r*q1 = " ); Quaternion.print( r*q1 )
|
|||
io.write( "q1*r = " ); Quaternion.print( q1*r )
|
||||
io.write( "q1*q2 = " ); Quaternion.print( q1*q2 )
|
||||
io.write( "q2*q1 = " ); Quaternion.print( q2*q1 )
|
||||
Output:
|
||||
{{out}}
|
||||
norm(q1) = 5.4772255750517
|
||||
-q1 = -1.000000 -2.000000i -3.000000j -4.000000k
|
||||
conj(q1) = 1.000000 -2.000000i -3.000000j -4.000000k
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue