Quaternion type: Difference between revisions

Added Easylang
(Added Easylang)
 
(7 intermediate revisions by 6 users not shown)
Line 846:
qneg: $ => [map & => neg]
 
qconj: $[q] [@[q\0] ++ qneg drop q 1]
 
qaddr: function [q r][
Line 895:
 
=={{header|ATS}}==
{{libheader|ats2-xprelude}}
 
<syntaxhighlight lang="ATS">
Line 2,613 ⟶ 2,614:
exp(log(s)): [2, 0.33427, 0.445694, 0.557117]
log(exp(s)): [2, 0.33427, 0.445694, 0.557117]</pre>
 
 
=={{header|Dart}}==
{{trans|Kotlin}}
<syntaxhighlight lang="Dart">
import 'dart:math' as math;
 
class Quaternion {
final double a, b, c, d;
 
Quaternion(this.a, this.b, this.c, this.d);
 
Quaternion operator +(Object other) {
if (other is Quaternion) {
return Quaternion(a + other.a, b + other.b, c + other.c, d + other.d);
} else if (other is double) {
return Quaternion(a + other, b, c, d);
}
throw ArgumentError('Invalid type for addition: ${other.runtimeType}');
}
 
Quaternion operator *(Object other) {
if (other is Quaternion) {
return Quaternion(
a * other.a - b * other.b - c * other.c - d * other.d,
a * other.b + b * other.a + c * other.d - d * other.c,
a * other.c - b * other.d + c * other.a + d * other.b,
a * other.d + b * other.c - c * other.b + d * other.a,
);
} else if (other is double) {
return Quaternion(a * other, b * other, c * other, d * other);
}
throw ArgumentError('Invalid type for multiplication: ${other.runtimeType}');
}
 
Quaternion operator -() => Quaternion(-a, -b, -c, -d);
 
Quaternion conj() => Quaternion(a, -b, -c, -d);
 
double norm() => math.sqrt(a * a + b * b + c * c + d * d);
 
@override
String toString() => '($a, $b, $c, $d)';
}
 
void main() {
var q = Quaternion(1.0, 2.0, 3.0, 4.0);
var q1 = Quaternion(2.0, 3.0, 4.0, 5.0);
var q2 = Quaternion(3.0, 4.0, 5.0, 6.0);
var r = 7.0;
print("q = $q");
print("q1 = $q1");
print("q2 = $q2");
print("r = $r\n");
print("norm(q) = ${q.norm().toStringAsFixed(6)}");
print("-q = ${-q}");
print("conj(q) = ${q.conj()}\n");
print("r + q = ${q + r}");
print("q + r = ${q + r}");
print("q1 + q2 = ${q1 + q2}\n");
print("r * q = ${q * r}");
print("q * r = ${q * r}");
var q3 = q1 * q2;
var q4 = q2 * q1;
print("q1 * q2 = $q3");
print("q2 * q1 = $q4\n");
print("q1 * q2 != q2 * q1 = ${q3 != q4}");
}
</syntaxhighlight>
{{out}}
<pre>
q = (1.0, 2.0, 3.0, 4.0)
q1 = (2.0, 3.0, 4.0, 5.0)
q2 = (3.0, 4.0, 5.0, 6.0)
r = 7.0
 
norm(q) = 5.477226
-q = (-1.0, -2.0, -3.0, -4.0)
conj(q) = (1.0, -2.0, -3.0, -4.0)
 
r + q = (8.0, 2.0, 3.0, 4.0)
q + r = (8.0, 2.0, 3.0, 4.0)
q1 + q2 = (5.0, 7.0, 9.0, 11.0)
 
r * q = (7.0, 14.0, 21.0, 28.0)
q * r = (7.0, 14.0, 21.0, 28.0)
q1 * q2 = (-56.0, 16.0, 24.0, 26.0)
q2 * q1 = (-56.0, 18.0, 20.0, 28.0)
 
q1 * q2 != q2 * q1 = true
 
</pre>
 
 
=={{header|Delphi}}==
Line 2,882 ⟶ 2,976:
? q1+(-2)
# value: (0 + 3i + 4j + 5k)</syntaxhighlight>
 
=={{header|EasyLang}}==
<syntaxhighlight>
func qnorm q[] .
for i to 4
s += q[i] * q[i]
.
return sqrt s
.
func[] qneg q[] .
for i to 4
q[i] = -q[i]
.
return q[]
.
func[] qconj q[] .
for i = 2 to 4
q[i] = -q[i]
.
return q[]
.
func[] qaddreal q[] r .
q[1] += r
return q[]
.
func[] qadd q[] q2[] .
for i to 4
q[i] += q2[i]
.
return q[]
.
func[] qmulreal q[] r .
for i to 4
q[i] *= r
.
return q[]
.
func[] qmul q1[] q2[] .
res[] &= q1[1] * q2[1] - q1[2] * q2[2] - q1[3] * q2[3] - q1[4] * q2[4]
res[] &= q1[1] * q2[2] + q1[2] * q2[1] + q1[3] * q2[4] - q1[4] * q2[3]
res[] &= q1[1] * q2[3] - q1[2] * q2[4] + q1[3] * q2[1] + q1[4] * q2[2]
res[] &= q1[1] * q2[4] + q1[2] * q2[3] - q1[3] * q2[2] + q1[4] * q2[1]
return res[]
.
q[] = [ 1 2 3 4 ]
q1[] = [ 2 3 4 5 ]
q2[] = [ 3 4 5 6 ]
r = 7
#
print "q = " & q[]
print "q1 = " & q1[]
print "q2 = " & q2[]
print "r = " & r
print "norm(q) = " & qnorm q[]
print "neg(q) = " & qneg q[]
print "conjugate(q) = " & qconj q[]
print "q+r = " & qaddreal q[] r
print "q1+q2 = " & qadd q1[] q2[]
print "qr = " & qmulreal q[] r
print "q1q2 = " & qmul q1[] q2[]
print "q2q1 = " & qmul q2[] q1[]
if q1[] <> q2[]
print "q1 != q2"
.
</syntaxhighlight>
 
{{out}}
<pre>
q = [ 1 2 3 4 ]
q1 = [ 2 3 4 5 ]
q2 = [ 3 4 5 6 ]
r = 7
norm(q) = 5.48
neg(q) = [ -1 -2 -3 -4 ]
conjugate(q) = [ 1 -2 -3 -4 ]
q+r = [ 8 2 3 4 ]
q1+q2 = [ 5 7 9 11 ]
qr = [ 7 14 21 28 ]
q1q2 = [ -56 16 24 26 ]
q2q1 = [ -56 18 20 28 ]
q1 != q2
</pre>
 
=={{header|Eero}}==
Line 3,006 ⟶ 3,182:
=={{header|Elena}}==
{{trans|C#}}
ELENA 56.0x :
<syntaxhighlight lang="elena">import system'math;
import extensions;
Line 3,013 ⟶ 3,189:
struct Quaternion
{
rprop real A : rprop;
rprop real B : rprop;
rprop real C : rprop;
rprop real D : rprop;
constructor new(a, b, c, d)
Line 7,626 ⟶ 7,802:
|
≪ 0 1 4 '''FOR''' q OVER q GET SQ + '''NEXT''' √ SWAP DROP
≫ ''''<span style="color:blue">QNORM'''</span>' STO
≪ NEG 1 DUP2 GET NEG PUT ≫ ''''<span style="color:blue">QCONJ'''</span>' STO
DUP TYPE 3 == ≪ SWAP ≫ IFT
OVER 1 GET + 1 SWAP PUT
≫ ''''<span style="color:blue">QRADD'''</span>' STO
Line 7,642 ⟶ 7,818:
'a1*d2 + b1*c2 − c1*b2 + d1*a2' EVAL
{ 4 } →ARRY
≫ ≫ ''''<span style="color:blue">QMULT'''</span>' STO
|
'''<span style="color:blue">QNORM'''</span> ''( [ a b c d ] -- √(a²+b²+c²+d²) )''
'''<span style="color:blue">QCONJ'''</span> ''( [ a b c d ] -- [ a -b -c -d ] )''
'''<span style="color:blue">QRADD'''</span> ''( [ a b c d ] r -- [ a+r b c d ] )''
switch arguments if quaternion is at stack level 1
replace a by a+r
'''<span style="color:blue">QMULT'''</span> ''( [Q1] [Q2] -- [Q1 x Q2] )''
put the 2 quaternions in local variables
do the math in stack
Line 7,664 ⟶ 7,840:
|}
 
[1 2 3 4] <span style="color:blue">QNORM</span>
{{in}}
[1 2 3 4] NEG
<pre>
[1 2 3 4] QNORM<span style="color:blue">QCONJ</span>
[1 2 3 4] 7 <span style="color:blue">QRADD</span>
[1 2 3 4] NEG
[1 2 3 4 5] [3 4 5 6] QCONJ+
[1 2 3 4] 7 QRADD*
[2 3 4 5] [3 4 5 6] +<span style="color:blue">QMULT</span>
[3 4 5 6] [2 3 4 5] <span style="color:blue">QMULT</span>
[1 2 3 4] 7 *
[2 3 4 5] [3 4 5 6] QMULT
[3 4 5 6] [2 3 4 5] QMULT
</pre>
 
{{out}}
Line 7,700 ⟶ 7,873:
d a * b c CONJ * + C→R
{ 4 } →ARRY
≫ ≫ ''''<span style="color:blue">QMULT'''</span>' STO
|
'''<span style="color:blue">QMULT'''</span> ''( [Q1] [Q2] -- [Q1 x Q2] )''
convert the 2 quaternions into 2 pairs of complex numbers
and store them locally
Line 7,711 ⟶ 7,884:
|}
Output is the same.
===Using the matrix form===
This efficient implementation is based on an article of [https://edspi31415.blogspot.com/2015/06/hp-prime-and-hp-50g-quaternions.html?fbclid=IwAR1KTjHt4xVt2FoMqL-82MJ1SS3SBg8jNoF-8uNcqg2Y5bLD2oiyxVfO88Y Eddie's Math and Calculator Blog].
 
« ARRY→ DROP → a b c d
« a b R→C c d R→C
c NEG d R→C
3 PICK CONJ
{ 2 2 } →ARRY
» » '<span style="color:blue">→QTM</span>' STO <span style="color:grey">''@ ( [ a b c d ] → [[ a+bi c+di ][ -c+di a-bi ]] )''</span>
« DUP 1 GET RE LASTARG IM
ROT 2 GET RE LASTARG IM
{ 4 } →ARRY
» '<span style="color:blue">QTM→</span>' STO <span style="color:grey">''@ ( [[ a+bi c+di ][ -c+di a-bi ]] → [ a b c d ] )''</span>
« <span style="color:blue">→QTM</span> SWAP <span style="color:blue">QTM→</span> SWAP * <span style="color:blue">QTM→</span>
» '<span style="color:blue">QMULT</span>' STO <span style="color:grey">''@ ( q1 q2 → q1*q2 ) ''</span>
« <span style="color:blue">→QTM</span> DET √ ABS
» '<span style="color:blue">QNORM</span>' STO <span style="color:grey">''@ ( q → qnorm(q) ) ''</span>
« DUP INV SWAP <span style="color:blue">QNORM</span> SQ *
» '<span style="color:blue">QCONJ</span>' STO <span style="color:grey">''@ ( q → conj(q) ) ''</span>
 
Quaternions' matrix form allows to quickly develop additional operations:
 
« DUP <span style="color:blue">QNORM</span> /
» '<span style="color:blue">QSIGN</span>' STO <span style="color:grey">''@ ( q → q/norm(q) ) ''</span>
« <span style="color:blue">→QTM</span> INV <span style="color:blue">QTM→</span>
» '<span style="color:blue">QINV</span>' STO <span style="color:grey">''@ ( q → q^(-1) ) ''</span>
« <span style="color:blue">QINV QMULT</span>
» '<span style="color:blue">QDIV</span>' STO <span style="color:grey">''@ ( q1 q2 → q1/q2 )''</span>
 
=={{header|Ruby}}==
Line 8,949 ⟶ 9,156:
 
=={{header|Wren}}==
<syntaxhighlight lang="ecmascriptwren">class Quaternion {
construct new(a, b, c, d ) {
_a = a
2,049

edits