Just another update

This commit is contained in:
Ingy döt Net 2015-02-20 00:35:01 -05:00
parent a25938f123
commit 00a190b0a6
6591 changed files with 94363 additions and 23227 deletions

View 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

View file

@ -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));

View file

@ -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)

View file

@ -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