Time for an 2014 update…
This commit is contained in:
parent
372c577f83
commit
09687c4926
2520 changed files with 34227 additions and 7318 deletions
|
|
@ -2,8 +2,9 @@
|
|||
|
||||
A complex number has a real and complex part written sometimes as <code>a + bi</code>, where a and b stand for real numbers and i stands for the square root of minus 1. An example of a complex number might be <code>-3 + 2i</code>, where the real part, a is -3.0 and the complex part, b is +2.0.
|
||||
|
||||
A quaternion has one real part and ''three'' imaginary parts, i, j, and k. A quaternion might be written as <code>a + bi + cj + dk</code>. In this numbering system, <code>ii = jj = kk = ijk = -1</code>. The order of multiplication is important, as, in general, for two quaternions q<sub>1</sub> and q<sub>2</sub>; <code>q<sub>1</sub>q<sub>2</sub> != q<sub>2</sub>q<sub>1</sub></code>. An example of a quaternion might be <code>1 +2i +3j +4k</code>
|
||||
A quaternion has one real part and ''three'' imaginary parts, i, j, and k. A quaternion might be written as <code>a + bi + cj + dk</code>. In this numbering system, <code>ii = jj = kk = ijk = -1</code>. The order of multiplication is important, as, in general, for two quaternions q<sub>1</sub> and q<sub>2</sub>; <code>q<sub>1</sub>q<sub>2</sub> != q<sub>2</sub>q<sub>1</sub></code>.
|
||||
|
||||
An example of a quaternion might be <code>1 +2i +3j +4k</code><br>
|
||||
There is a list form of notation where just the numbers are shown and the imaginary multipliers i, j, and k are assumed by position. So the example above would be written as (1, 2, 3, 4)
|
||||
|
||||
'''Task Description'''<br>
|
||||
|
|
|
|||
|
|
@ -9,10 +9,23 @@ b := BasisVectors(Basis(A));
|
|||
q := [1, 2, 3, 4]*b;
|
||||
# e+(2)*i+(3)*j+(4)*k
|
||||
|
||||
# Computing norm may be difficult, since the result would be in a quadratic field (Sqrt exists in GAP, is quite unusual, see ?E in GAP, and the following example
|
||||
# Conjugate
|
||||
ComplexConjugate(q);
|
||||
# e+(-2)*i+(-3)*j+(-4)*k
|
||||
|
||||
# Division
|
||||
1/q;
|
||||
# (1/30)*e+(-1/15)*i+(-1/10)*j+(-2/15)*k
|
||||
|
||||
# Computing norm may be difficult, since the result would be in a quadratic field.
|
||||
# Sqrt exists in GAP, but it is quite unusual: see ?E in GAP documentation, and the following example
|
||||
Sqrt(5/3);
|
||||
# 1/3*E(60)^7+1/3*E(60)^11-1/3*E(60)^19-1/3*E(60)^23-1/3*E(60)^31+1/3*E(60)^43-1/3*E(60)^47+1/3*E(60)^59
|
||||
|
||||
# However, the square of the norm is easy to compute
|
||||
q*ComplexConjugate(q);
|
||||
# (30)*e
|
||||
|
||||
q1 := [2, 3, 4, 5]*b;
|
||||
# (2)*e+(3)*i+(4)*j+(5)*k
|
||||
|
||||
|
|
@ -23,17 +36,75 @@ q1*q2 - q2*q1;
|
|||
# (-2)*i+(4)*j+(-2)*k
|
||||
|
||||
# Can't add directly to a rational, one must make a quaternion of it
|
||||
r:=5/3*b[1];
|
||||
r := 5/3*b[1];
|
||||
# (5/3)*e
|
||||
r + q;
|
||||
# (8/3)*e+(2)*i+(3)*j+(4)*k
|
||||
|
||||
# For multiplication, no problem (we are in an algebra over rationals !)
|
||||
r * q;
|
||||
r*q;
|
||||
# (5/3)*e+(10/3)*i+(5)*j+(20/3)*k
|
||||
5/3 * q;
|
||||
5/3*q;
|
||||
# (5/3)*e+(10/3)*i+(5)*j+(20/3)*k
|
||||
|
||||
# Negative
|
||||
-q;
|
||||
(-1)*e+(-2)*i+(-3)*j+(-4)*k
|
||||
|
||||
|
||||
# While quaternions are built-in, you can define an algebra in GAP by specifying it's multiplication table.
|
||||
# See tutorial, p. 60, and reference of the functions used below.
|
||||
|
||||
# A multiplication table of dimension 4.
|
||||
|
||||
T := EmptySCTable(4, 0);
|
||||
SetEntrySCTable(T, 1, 1, [1, 1]);
|
||||
SetEntrySCTable(T, 1, 2, [1, 2]);
|
||||
SetEntrySCTable(T, 1, 3, [1, 3]);
|
||||
SetEntrySCTable(T, 1, 4, [1, 4]);
|
||||
SetEntrySCTable(T, 2, 1, [1, 2]);
|
||||
SetEntrySCTable(T, 2, 2, [-1, 1]);
|
||||
SetEntrySCTable(T, 2, 3, [1, 4]);
|
||||
SetEntrySCTable(T, 2, 4, [-1, 3]);
|
||||
SetEntrySCTable(T, 3, 1, [1, 3]);
|
||||
SetEntrySCTable(T, 3, 2, [-1, 4]);
|
||||
SetEntrySCTable(T, 3, 3, [-1, 1]);
|
||||
SetEntrySCTable(T, 3, 4, [1, 2]);
|
||||
SetEntrySCTable(T, 4, 1, [1, 4]);
|
||||
SetEntrySCTable(T, 4, 2, [1, 3]);
|
||||
SetEntrySCTable(T, 4, 3, [-1, 2]);
|
||||
SetEntrySCTable(T, 4, 4, [-1, 1]);
|
||||
|
||||
A := AlgebraByStructureConstants(Rationals, T, ["e", "i", "j", "k"]);
|
||||
b := GeneratorsOfAlgebra(A);
|
||||
|
||||
IsAssociative(A);
|
||||
# true
|
||||
|
||||
IsCommutative(A);
|
||||
# false
|
||||
|
||||
# Then, like above
|
||||
|
||||
q := [1, 2, 3, 4]*b;
|
||||
# e+(2)*i+(3)*j+(4)*k
|
||||
|
||||
# However, as is, GAP does not know division or conjugate on this algebra.
|
||||
# QuaternionAlgebra is useful as well for extensions of rationals,
|
||||
# and this one _has_ conjugate and division, as seen previously.
|
||||
|
||||
# Try this on Q[z] where z is the square root of 5 (in GAP it's ER(5))
|
||||
F := FieldByGenerators([ER(5)]);
|
||||
A := QuaternionAlgebra(F);
|
||||
b := GeneratorsOfAlgebra(A);
|
||||
|
||||
q := [1, 2, 3, 4]*b;
|
||||
# e+(2)*i+(3)*j+(4)*k
|
||||
|
||||
# Conjugate and division
|
||||
|
||||
ComplexConjugate(q);
|
||||
# e+(-2)*i+(-3)*j+(-4)*k
|
||||
|
||||
1/q;
|
||||
# (1/30)*e+(-1/15)*i+(-1/10)*j+(-2/15)*k
|
||||
|
|
|
|||
48
Task/Quaternion-type/Julia/quaternion-type-1.julia
Normal file
48
Task/Quaternion-type/Julia/quaternion-type-1.julia
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
import Base: convert, promote_rule, show, real, imag, conj, abs, abs2, inv, +, -, /, *
|
||||
|
||||
immutable Quaternion{T<:Real} <: Number
|
||||
q0::T
|
||||
q1::T
|
||||
q2::T
|
||||
q3::T
|
||||
end
|
||||
|
||||
Quaternion(q0::Real,q1::Real,q2::Real,q3::Real) = Quaternion(promote(q0,q1,q2,q3)...)
|
||||
|
||||
convert{T}(::Type{Quaternion{T}}, x::Real) =
|
||||
Quaternion(convert(T,x), zero(T), zero(T), zero(T))
|
||||
convert{T}(::Type{Quaternion{T}}, z::Complex) =
|
||||
Quaternion(convert(T,real(z)), convert(T,imag(z)), zero(T), zero(T))
|
||||
convert{T}(::Type{Quaternion{T}}, z::Quaternion) =
|
||||
Quaternion(convert(T,z.q0), convert(T,z.q1), convert(T,z.q2), convert(T,z.q3))
|
||||
|
||||
promote_rule{T,S}(::Type{Complex{T}}, ::Type{Quaternion{S}}) = Quaternion{promote_type(T,S)}
|
||||
promote_rule{T<:Real,S}(::Type{T}, ::Type{Quaternion{S}}) = Quaternion{promote_type(T,S)}
|
||||
promote_rule{T,S}(::Type{Quaternion{T}}, ::Type{Quaternion{S}}) = Quaternion{promote_type(T,S)}
|
||||
|
||||
function show(io::IO, z::Quaternion)
|
||||
pm(x) = x < 0 ? " - $(-x)" : " + $x"
|
||||
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,
|
||||
z.q2 - w.q2, z.q3 - w.q3)
|
||||
(*)(z::Quaternion, w::Quaternion) = Quaternion(z.q0*w.q0 - z.q1*w.q1 - z.q2*w.q2 - z.q3*w.q3,
|
||||
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)
|
||||
26
Task/Quaternion-type/Julia/quaternion-type-2.julia
Normal file
26
Task/Quaternion-type/Julia/quaternion-type-2.julia
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
julia> q = Quaternion(1,0,0,0)
|
||||
julia> q = Quaternion (1, 2, 3, 4)
|
||||
q1 = Quaternion(2, 3, 4, 5)
|
||||
q2 = Quaternion(3, 4, 5, 6)
|
||||
r = 7.
|
||||
|
||||
julia> norm(q)
|
||||
5.477225575051661
|
||||
|
||||
julia> -q
|
||||
-1 - 2i - 3j - 4k
|
||||
|
||||
julia> conj(q)
|
||||
1 - 2i - 3j - 4k
|
||||
|
||||
julia> r + q, q + r
|
||||
(8.0 + 2.0i + 3.0j + 4.0k,8.0 + 2.0i + 3.0j + 4.0k)
|
||||
|
||||
julia> q1 + q2
|
||||
5 + 7i + 9j + 11k
|
||||
|
||||
julia> r*q, q*r
|
||||
(7.0 + 14.0i + 21.0j + 28.0k,7.0 + 14.0i + 21.0j + 28.0k)
|
||||
|
||||
julia> q1*q2, q2*q1, q1*q2 != q2*q1
|
||||
(-56 + 16i + 24j + 26k,-56 + 18i + 20j + 28k,true)
|
||||
|
|
@ -1,34 +1,47 @@
|
|||
class Qu {
|
||||
class Quaternion {
|
||||
has Real ( $.r, $.i, $.j, $.k );
|
||||
|
||||
multi method new ( Real $r, Real $i, Real $j, Real $k ) {
|
||||
self.bless: *, :$r, :$i, :$j, :$k;
|
||||
self.bless: :$r, :$i, :$j, :$k;
|
||||
}
|
||||
method Str ( ) { "$.r + {$.i}i + {$.j}j + {$.k}k" }
|
||||
method reals ( ) { $.r, $.i, $.j, $.k }
|
||||
method conj ( ) { self.new: $.r, -$.i, -$.j, -$.k }
|
||||
method norm ( ) { sqrt [+] self.reals X** 2 }
|
||||
}
|
||||
multi qu(*@r) is export { Quaternion.new: |@r }
|
||||
sub postfix:<j>(Real $x) is export { qu 0, 0, $x, 0 }
|
||||
sub postfix:<k>(Real $x) is export { qu 0, 0, 0, $x }
|
||||
|
||||
multi sub infix:<eqv> ( Qu $a, Qu $b ) { [and] $a.reals Z== $b.reals }
|
||||
multi sub infix:<+> ( Qu $a, Real $b ) { $a.new: $b+$a.r, $a.i, $a.j, $a.k }
|
||||
multi sub infix:<+> ( Real $a, Qu $b ) { $b.new: $a+$b.r, $b.i, $b.j, $b.k }
|
||||
multi sub infix:<+> ( Qu $a, Qu $b ) { $a.new: |( $a.reals Z+ $b.reals ) }
|
||||
multi sub prefix:<-> ( Qu $a ) { $a.new: |( $a.reals X* -1 ) }
|
||||
multi sub infix:<*> ( Qu $a, Real $b ) { $a.new: |( $a.reals X* $b ) }
|
||||
multi sub infix:<*> ( Real $a, Qu $b ) { $b.new: |( $b.reals X* $a ) }
|
||||
multi sub infix:<*> ( Qu $a, Qu $b ) {
|
||||
my @a_rijk = $a.reals;
|
||||
my ( $r, $i, $j, $k ) = $b.reals;
|
||||
return $a.new: ( [+] @a_rijk Z* $r, -$i, -$j, -$k ), # real
|
||||
( [+] @a_rijk Z* $i, $r, $k, -$j ), # i
|
||||
( [+] @a_rijk Z* $j, -$k, $r, $i ), # j
|
||||
( [+] @a_rijk Z* $k, $j, -$i, $r ); # k
|
||||
}
|
||||
method Str () { "$.r + {$.i}i + {$.j}j + {$.k}k" }
|
||||
method reals () { $.r, $.i, $.j, $.k }
|
||||
method conj () { qu $.r, -$.i, -$.j, -$.k }
|
||||
method norm () { sqrt [+] self.reals X** 2 }
|
||||
|
||||
my Qu $q .= new: 1, 2, 3, 4;
|
||||
my Qu $q1 .= new: 2, 3, 4, 5;
|
||||
my Qu $q2 .= new: 3, 4, 5, 6;
|
||||
multi infix:<eqv> ( Quaternion $a, Quaternion $b ) is export { $a.reals eqv $b.reals }
|
||||
|
||||
multi infix:<+> ( Quaternion $a, Real $b ) is export { qu $b+$a.r, $a.i, $a.j, $a.k }
|
||||
multi infix:<+> ( Real $a, Quaternion $b ) is export { qu $a+$b.r, $b.i, $b.j, $b.k }
|
||||
multi infix:<+> ( Quaternion $a, Complex $b ) is export { qu $b.re + $a.r, $b.im + $a.i, $a.j, $a.k }
|
||||
multi infix:<+> ( Complex $a, Quaternion $b ) is export { qu $a.re + $b.r, $a.im + $b.i, $b.j, $b.k }
|
||||
multi infix:<+> ( Quaternion $a, Quaternion $b ) is export { qu $a.reals Z+ $b.reals }
|
||||
|
||||
multi prefix:<-> ( Quaternion $a ) is export { qu $a.reals X* -1 }
|
||||
|
||||
multi infix:<*> ( Quaternion $a, Real $b ) is export { qu $a.reals X* $b }
|
||||
multi infix:<*> ( Real $a, Quaternion $b ) is export { qu $b.reals X* $a }
|
||||
multi infix:<*> ( Quaternion $a, Complex $b ) is export { $a * qu $b.reals, 0, 0 }
|
||||
multi infix:<*> ( Complex $a, Quaternion $b ) is export { $b R* qu $a.reals, 0, 0 }
|
||||
|
||||
multi infix:<*> ( Quaternion $a, Quaternion $b ) is export {
|
||||
my @a_rijk = $a.reals;
|
||||
my ( $r, $i, $j, $k ) = $b.reals;
|
||||
return qu [+]( @a_rijk Z* $r, -$i, -$j, -$k ), # real
|
||||
[+]( @a_rijk Z* $i, $r, $k, -$j ), # i
|
||||
[+]( @a_rijk Z* $j, -$k, $r, $i ), # j
|
||||
[+]( @a_rijk Z* $k, $j, -$i, $r ); # k
|
||||
}
|
||||
}
|
||||
import Quaternion;
|
||||
|
||||
my $q = 1 + 2i + 3j + 4k;
|
||||
my $q1 = 2 + 3i + 4j + 5k;
|
||||
my $q2 = 3 + 4i + 5j + 6k;
|
||||
my $r = 7;
|
||||
|
||||
say "1) q norm = {$q.norm}";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue