Quaternion type: Difference between revisions

Content added Content deleted
(Added XPL0 example.)
m (syntax highlighting fixup automation)
Line 57: Line 57:
{{libheader|Action! Tool Kit}}
{{libheader|Action! Tool Kit}}
{{libheader|Action! Real Math}}
{{libheader|Action! Real Math}}
<lang Action!>INCLUDE "H6:REALMATH.ACT"
<syntaxhighlight lang="action!">INCLUDE "H6:REALMATH.ACT"


DEFINE A_="+0"
DEFINE A_="+0"
Line 220: Line 220:
QuatMult(q1,q2,q3) Print(" q1*q2 = ") PrintQuatE(q3)
QuatMult(q1,q2,q3) Print(" q1*q2 = ") PrintQuatE(q3)
QuatMult(q2,q1,q3) Print(" q2*q1 = ") PrintQuatE(q3)
QuatMult(q2,q1,q3) Print(" q2*q1 = ") PrintQuatE(q3)
RETURN</lang>
RETURN</syntaxhighlight>
{{out}}
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Quaternion_type.png Screenshot from Atari 8-bit computer]
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Quaternion_type.png Screenshot from Atari 8-bit computer]
Line 244: Line 244:
=={{header|Ada}}==
=={{header|Ada}}==
The package specification (works with any floating-point type):
The package specification (works with any floating-point type):
<lang Ada>generic
<syntaxhighlight lang="ada">generic
type Real is digits <>;
type Real is digits <>;
package Quaternions is
package Quaternions is
Line 259: Line 259:
function "*" (Left, Right : Quaternion) return Quaternion;
function "*" (Left, Right : Quaternion) return Quaternion;
function Image (Left : Quaternion) return String;
function Image (Left : Quaternion) return String;
end Quaternions;</lang>
end Quaternions;</syntaxhighlight>
The package implementation:
The package implementation:
<lang Ada>with Ada.Numerics.Generic_Elementary_Functions;
<syntaxhighlight lang="ada">with Ada.Numerics.Generic_Elementary_Functions;
package body Quaternions is
package body Quaternions is
package Elementary_Functions is
package Elementary_Functions is
Line 319: Line 319:
Real'Image (Left.D) & "k";
Real'Image (Left.D) & "k";
end Image;
end Image;
end Quaternions;</lang>
end Quaternions;</syntaxhighlight>
Test program:
Test program:
<lang Ada>with Ada.Text_IO; use Ada.Text_IO;
<syntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO;
with Quaternions;
with Quaternions;
procedure Test_Quaternion is
procedure Test_Quaternion is
Line 346: Line 346:
Put_Line ("q1 * q2 = " & Image (q1 * q2));
Put_Line ("q1 * q2 = " & Image (q1 * q2));
Put_Line ("q2 * q1 = " & Image (q2 * q1));
Put_Line ("q2 * q1 = " & Image (q2 * q1));
end Test_Quaternion;</lang>
end Test_Quaternion;</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 372: Line 372:
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-2.6 algol68g-2.6].}}
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-2.6 algol68g-2.6].}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''.}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''.}}
'''File: prelude/Quaternion.a68'''<lang algol68># -*- coding: utf-8 -*- #
'''File: prelude/Quaternion.a68'''<syntaxhighlight lang="algol68"># -*- coding: utf-8 -*- #


COMMENT REQUIRES:
COMMENT REQUIRES:
Line 630: Line 630:
PROC quat exp = (QUAT q)QUAT: (exp OF class quat)(LOC QUAT := q);
PROC quat exp = (QUAT q)QUAT: (exp OF class quat)(LOC QUAT := q);


SKIP # missing: quat arc{sin, cos, tan}h, log, exp, ln etc END #</lang>'''File: test/Quaternion.a68'''<lang algol68>#!/usr/bin/a68g --script #
SKIP # missing: quat arc{sin, cos, tan}h, log, exp, ln etc END #</syntaxhighlight>'''File: test/Quaternion.a68'''<syntaxhighlight lang="algol68">#!/usr/bin/a68g --script #
# -*- coding: utf-8 -*- #
# -*- coding: utf-8 -*- #


Line 684: Line 684:
));
));
print((REPR(-q1*q2), ", ", REPR(-q2*q1), new line))
print((REPR(-q1*q2), ", ", REPR(-q2*q1), new line))
)</lang>
)</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 718: Line 718:


=={{header|ALGOL W}}==
=={{header|ALGOL W}}==
<lang algolw>begin
<syntaxhighlight lang="algolw">begin
% Quaternion record type %
% Quaternion record type %
record Quaternion ( real a, b, c, d );
record Quaternion ( real a, b, c, d );
Line 819: Line 819:


end.
end.
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 842: Line 842:
=={{header|AutoHotkey}}==
=={{header|AutoHotkey}}==
{{works with|AutoHotkey_L}} (AutoHotkey1.1+)
{{works with|AutoHotkey_L}} (AutoHotkey1.1+)
<lang AutoHotkey>q := [1, 2, 3, 4]
<syntaxhighlight lang="autohotkey">q := [1, 2, 3, 4]
q1 := [2, 3, 4, 5]
q1 := [2, 3, 4, 5]
q2 := [3, 4, 5, 6]
q2 := [3, 4, 5, 6]
Line 913: Line 913:
b .= v (A_Index = q.MaxIndex() ? ")" : ", ")
b .= v (A_Index = q.MaxIndex() ? ")" : ", ")
return b
return b
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>q = (1, 2, 3, 4)
<pre>q = (1, 2, 3, 4)
Line 931: Line 931:
=={{header|Axiom}}==
=={{header|Axiom}}==
Axiom has built-in support for quaternions.
Axiom has built-in support for quaternions.
<lang Axiom>qi := quatern$Quaternion(Integer);
<syntaxhighlight lang="axiom">qi := quatern$Quaternion(Integer);


Type: ((Integer,Integer,Integer,Integer) -> Quaternion(Integer))
Type: ((Integer,Integer,Integer,Integer) -> Quaternion(Integer))
Line 978: Line 978:


(13) true
(13) true
Type: Boolean</lang>
Type: Boolean</syntaxhighlight>


=={{header|BASIC256}}==
=={{header|BASIC256}}==
{{works with|BASIC256|2.0.0.11}}
{{works with|BASIC256|2.0.0.11}}
<syntaxhighlight lang="basic256">
<lang BASIC256>
dim q(4)
dim q(4)
dim q1(4)
dim q1(4)
Line 1,069: Line 1,069:
print "q1q2 = ";printq(q_mul(q1,q2))
print "q1q2 = ";printq(q_mul(q1,q2))
print "q2q1 = ";printq(q_mul(q2,q1))
print "q2q1 = ";printq(q_mul(q2,q1))
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 1,088: Line 1,088:
=={{header|BBC BASIC}}==
=={{header|BBC BASIC}}==
Although BBC BASIC doesn't have native support for quaternions its array arithmetic provides all of the required operations either directly or very straightforwardly.
Although BBC BASIC doesn't have native support for quaternions its array arithmetic provides all of the required operations either directly or very straightforwardly.
<lang bbcbasic> DIM q(3), q1(3), q2(3), t(3)
<syntaxhighlight lang="bbcbasic"> DIM q(3), q1(3), q2(3), t(3)
q() = 1, 2, 3, 4
q() = 1, 2, 3, 4
q1() = 2, 3, 4, 5
q1() = 2, 3, 4, 5
Line 1,129: Line 1,129:
DEF FNq_show(q()) : LOCAL i%, a$ : a$ = "("
DEF FNq_show(q()) : LOCAL i%, a$ : a$ = "("
FOR i% = 0 TO 3 : a$ += STR$(q(i%)) + ", " : NEXT
FOR i% = 0 TO 3 : a$ += STR$(q(i%)) + ", " : NEXT
= LEFT$(LEFT$(a$)) + ")"</lang>
= LEFT$(LEFT$(a$)) + ")"</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 1,148: Line 1,148:


=={{header|C}}==
=={{header|C}}==
<lang c>#include <stdio.h>
<syntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdbool.h>
Line 1,278: Line 1,278:
printf("(%lf, %lf, %lf, %lf)\n",
printf("(%lf, %lf, %lf, %lf)\n",
q->q[0], q->q[1], q->q[2], q->q[3]);
q->q[0], q->q[1], q->q[2], q->q[3]);
}</lang>
}</syntaxhighlight>


<lang c>int main()
<syntaxhighlight lang="c">int main()
{
{
size_t i;
size_t i;
Line 1,337: Line 1,337:
free(q[0]); free(q[1]); free(q[2]); free(r);
free(q[0]); free(q[1]); free(q[2]); free(r);
return EXIT_SUCCESS;
return EXIT_SUCCESS;
}</lang>
}</syntaxhighlight>


=={{header|C sharp}}==
=={{header|C sharp}}==
<lang csharp>using System;
<syntaxhighlight lang="csharp">using System;


struct Quaternion : IEquatable<Quaternion>
struct Quaternion : IEquatable<Quaternion>
Line 1,429: Line 1,429:


#endregion
#endregion
}</lang>
}</syntaxhighlight>


Demonstration:
Demonstration:
<lang csharp>using System;
<syntaxhighlight lang="csharp">using System;


static class Program
static class Program
Line 1,465: Line 1,465:
Console.WriteLine("q1*q2 {0} q2*q1", (q1 * q2) == (q2 * q1) ? "==" : "!=");
Console.WriteLine("q1*q2 {0} q2*q1", (q1 * q2) == (q2 * q1) ? "==" : "!=");
}
}
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 1,489: Line 1,489:
This example uses templates to provide the underlying data-type, and includes several extra functions and constructors that often come up when using quaternions.
This example uses templates to provide the underlying data-type, and includes several extra functions and constructors that often come up when using quaternions.


<lang cpp>#include <iostream>
<syntaxhighlight lang="cpp">#include <iostream>
using namespace std;
using namespace std;


Line 1,604: Line 1,604:
(q.z < T()) ? (io << " - " << (-q.z) << "k") : (io << " + " << q.z << "k");
(q.z < T()) ? (io << " - " << (-q.z) << "k") : (io << " + " << q.z << "k");
return io;
return io;
}</lang>
}</syntaxhighlight>


Test program:
Test program:
<lang cpp>int main()
<syntaxhighlight lang="cpp">int main()
{
{
Quaternion<> q0(1, 2, 3, 4);
Quaternion<> q0(1, 2, 3, 4);
Line 1,646: Line 1,646:
Quaternion<int> q5(2), q6(3);
Quaternion<int> q5(2), q6(3);
cout << endl << q5*q6 << endl;
cout << endl << q5*q6 << endl;
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 1,683: Line 1,683:


=={{header|CLU}}==
=={{header|CLU}}==
<lang clu>quat = cluster is make, minus, norm, conj, add, addr, mul, mulr,
<syntaxhighlight lang="clu">quat = cluster is make, minus, norm, conj, add, addr, mul, mulr,
equal, get_a, get_b, get_c, get_d, q_form
equal, get_a, get_b, get_c, get_d, q_form
rep = struct[a,b,c,d: real]
rep = struct[a,b,c,d: real]
Line 1,764: Line 1,764:
if q1*q2 ~= q2*q1 then stream$putl(po, "q1 * q2 ~= q2 * q1") end
if q1*q2 ~= q2*q1 then stream$putl(po, "q1 * q2 ~= q2 * q1") end
end start_up</lang>
end start_up</syntaxhighlight>
{{out}}
{{out}}
<pre> q0 = 1.000 + 2.000i + 3.000j + 4.000k
<pre> q0 = 1.000 + 2.000i + 3.000j + 4.000k
Line 1,782: Line 1,782:


=={{header|Common Lisp}}==
=={{header|Common Lisp}}==
<lang lisp>
<syntaxhighlight lang="lisp">
(defclass quaternion () ((a :accessor q-a :initarg :a :type real)
(defclass quaternion () ((a :accessor q-a :initarg :a :type real)
(b :accessor q-b :initarg :b :type real)
(b :accessor q-b :initarg :b :type real)
Line 1,860: Line 1,860:
(format t "q*q1*q2 = ~a~&" (reduce #'mul (list q q1 q2)))
(format t "q*q1*q2 = ~a~&" (reduce #'mul (list q q1 q2)))
(format t "q-q1-q2 = ~a~&" (reduce #'sub (list q q1 q2)))
(format t "q-q1-q2 = ~a~&" (reduce #'sub (list q q1 q2)))
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 1,872: Line 1,872:
=={{header|Crystal}}==
=={{header|Crystal}}==
{{trans|Rust and Ruby}}
{{trans|Rust and Ruby}}
<lang ruby>class Quaternion
<syntaxhighlight lang="ruby">class Quaternion
property a, b, c, d
property a, b, c, d


Line 1,960: Line 1,960:
puts
puts
puts "q1 * q2 != q2 * q1 => #{(q1 * q2) != (q2 * q1)}"
puts "q1 * q2 != q2 * q1 => #{(q1 * q2) != (q2 * q1)}"
puts "q1 * q2 == q2 * q1 => #{(q1 * q2) == (q2 * q1)}"</lang>
puts "q1 * q2 == q2 * q1 => #{(q1 * q2) == (q2 * q1)}"</syntaxhighlight>
{{out}}
{{out}}
<pre>q0 = (1 + 2i + 3j + 4k)
<pre>q0 = (1 + 2i + 3j + 4k)
Line 2,002: Line 2,002:


=={{header|D}}==
=={{header|D}}==
<lang d>import std.math, std.numeric, std.traits, std.conv, std.complex;
<syntaxhighlight lang="d">import std.math, std.numeric, std.traits, std.conv, std.complex;




Line 2,227: Line 2,227:
writeln(" exp(log(s)): ", exp(log(s)));
writeln(" exp(log(s)): ", exp(log(s)));
writeln(" log(exp(s)): ", log(exp(s)));
writeln(" log(exp(s)): ", log(exp(s)));
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>1. q - norm: 7.34847
<pre>1. q - norm: 7.34847
Line 2,262: Line 2,262:
=={{header|Delphi}}==
=={{header|Delphi}}==


<lang Delphi>unit Quaternions;
<syntaxhighlight lang="delphi">unit Quaternions;


interface
interface
Line 2,390: Line 2,390:
end;
end;


end.</lang>
end.</syntaxhighlight>


Test program
Test program
<lang Delphi>program QuaternionTest;
<syntaxhighlight lang="delphi">program QuaternionTest;


{$APPTYPE CONSOLE}
{$APPTYPE CONSOLE}
Line 2,424: Line 2,424:
writeln('q1 * q2 = ', (q1 * q2).ToString);
writeln('q1 * q2 = ', (q1 * q2).ToString);
writeln('q2 * q1 = ', (q2 * q1).ToString);
writeln('q2 * q1 = ', (q2 * q1).ToString);
end.</lang>
end.</syntaxhighlight>


{{out}}
{{out}}
Line 2,449: Line 2,449:
=={{header|E}}==
=={{header|E}}==


<lang e>interface Quaternion guards QS {}
<syntaxhighlight lang="e">interface Quaternion guards QS {}
def makeQuaternion(a, b, c, d) {
def makeQuaternion(a, b, c, d) {
return def quaternion implements QS {
return def quaternion implements QS {
Line 2,509: Line 2,509:
to d() { return d }
to d() { return d }
}
}
}</lang>
}</syntaxhighlight>


<lang e>? def q1 := makeQuaternion(2,3,4,5)
<syntaxhighlight lang="e">? def q1 := makeQuaternion(2,3,4,5)
# value: (2 + 3i + 4j + 5k)
# value: (2 + 3i + 4j + 5k)


Line 2,527: Line 2,527:


? q1+(-2)
? q1+(-2)
# value: (0 + 3i + 4j + 5k)</lang>
# value: (0 + 3i + 4j + 5k)</syntaxhighlight>


=={{header|Eero}}==
=={{header|Eero}}==
<lang objc>#import <Foundation/Foundation.h>
<syntaxhighlight lang="objc">#import <Foundation/Foundation.h>


interface Quaternion : Number
interface Quaternion : Number
Line 2,631: Line 2,631:
Log( 'q2 * q1 = %@', q2 * q1 )
Log( 'q2 * q1 = %@', q2 * q1 )


return 0</lang>
return 0</syntaxhighlight>


{{out}}
{{out}}
Line 2,653: Line 2,653:
{{trans|C#}}
{{trans|C#}}
ELENA 5.0 :
ELENA 5.0 :
<lang elena>import system'math;
<syntaxhighlight lang="elena">import system'math;
import extensions;
import extensions;
import extensions'text;
import extensions'text;
Line 2,740: Line 2,740:
console.printLineFormatted("q1*q2 {0} q2*q1", ((q1 * q2) == (q2 * q1)).iif("==","!="))
console.printLineFormatted("q1*q2 {0} q2*q1", ((q1 * q2) == (q2 * q1)).iif("==","!="))
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 2,762: Line 2,762:


=={{header|ERRE}}==
=={{header|ERRE}}==
<syntaxhighlight lang="erre">
<lang ERRE>
PROGRAM QUATERNION
PROGRAM QUATERNION


Line 2,867: Line 2,867:
PRINTQ(R.)
PRINTQ(R.)
END PROGRAM
END PROGRAM
</syntaxhighlight>
</lang>


=={{header|Euphoria}}==
=={{header|Euphoria}}==
<lang euphoria>function norm(sequence q)
<syntaxhighlight lang="euphoria">function norm(sequence q)
return sqrt(power(q[1],2)+power(q[2],2)+power(q[3],2)+power(q[4],2))
return sqrt(power(q[1],2)+power(q[2],2)+power(q[3],2)+power(q[4],2))
end function
end function
Line 2,917: Line 2,917:
printf(1, "q1 + q2 = %s\n", {quats(add(q1,q2))})
printf(1, "q1 + q2 = %s\n", {quats(add(q1,q2))})
printf(1, "q1 * q2 = %s\n", {quats(mul(q1,q2))})
printf(1, "q1 * q2 = %s\n", {quats(mul(q1,q2))})
printf(1, "q2 * q1 = %s\n", {quats(mul(q2,q1))})</lang>
printf(1, "q2 * q1 = %s\n", {quats(mul(q2,q1))})</syntaxhighlight>


{{out}}
{{out}}
Line 2,931: Line 2,931:
Mainly a {{trans|C#}} On the minus side we have no way to define a conversion to Quaternion from any suitable (numeric) type.
Mainly a {{trans|C#}} On the minus side we have no way to define a conversion to Quaternion from any suitable (numeric) type.
On the plus side we can avoid the stuff to make the equality structual (from the referential equality default) by just declaring it as an attribute to the type and let the compiler handle the details.
On the plus side we can avoid the stuff to make the equality structual (from the referential equality default) by just declaring it as an attribute to the type and let the compiler handle the details.
<lang fsharp>open System
<syntaxhighlight lang="fsharp">open System


[<Struct; StructuralEquality; NoComparison>]
[<Struct; StructuralEquality; NoComparison>]
Line 2,993: Line 2,993:
printfn "q1*q2 %s q2*q1" (if (q1 * q2) = (q2 * q1) then "=" else "<>")
printfn "q1*q2 %s q2*q1" (if (q1 * q2) = (q2 * q1) then "=" else "<>")
printfn "q %s Q(1.,2.,3.,4.)" (if q = Quaternion(1., 2., 3., 4.) then "=" else "<>")
printfn "q %s Q(1.,2.,3.,4.)" (if q = Quaternion(1., 2., 3., 4.) then "=" else "<>")
0</lang>
0</syntaxhighlight>
{{out}}
{{out}}
<pre>q = Q(1.000000, 2.000000, 3.000000, 4.000000)
<pre>q = Q(1.000000, 2.000000, 3.000000, 4.000000)
Line 3,015: Line 3,015:
=={{header|Factor}}==
=={{header|Factor}}==
The <code>math.quaternions</code> vocabulary provides words for treating sequences like quaternions. <code>norm</code> and <code>vneg</code> come from the <code>math.vectors</code> vocabulary. Oddly, I wasn't able to find a word for adding a real to a quaternion, so I wrote one.
The <code>math.quaternions</code> vocabulary provides words for treating sequences like quaternions. <code>norm</code> and <code>vneg</code> come from the <code>math.vectors</code> vocabulary. Oddly, I wasn't able to find a word for adding a real to a quaternion, so I wrote one.
<lang factor>USING: generalizations io kernel locals math.quaternions
<syntaxhighlight lang="factor">USING: generalizations io kernel locals math.quaternions
math.vectors prettyprint sequences ;
math.vectors prettyprint sequences ;
IN: rosetta-code.quaternion-type
IN: rosetta-code.quaternion-type
Line 3,041: Line 3,041:
[ q2 q1 [ q* ] ]
[ q2 q1 [ q* ] ]
} 2show
} 2show
]</lang>
]</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 3,055: Line 3,055:


=={{header|Forth}}==
=={{header|Forth}}==
<lang forth>: quaternions 4 * floats ;
<syntaxhighlight lang="forth">: quaternions 4 * floats ;


: qvariable create 1 quaternions allot ;
: qvariable create 1 quaternions allot ;
Line 3,131: Line 3,131:
m1 q1 q2 q* m1 q. \ ( -56. 16. 24. 26. )
m1 q1 q2 q* m1 q. \ ( -56. 16. 24. 26. )
m2 q2 q1 q* m2 q. \ ( -56. 18. 20. 28. )
m2 q2 q1 q* m2 q. \ ( -56. 18. 20. 28. )
m1 m2 q= . \ 0 (false)</lang>
m1 m2 q= . \ 0 (false)</syntaxhighlight>


=={{header|Fortran}}==
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
{{works with|Fortran|90 and later}}
<lang fortran>module Q_mod
<syntaxhighlight lang="fortran">module Q_mod
implicit none
implicit none


Line 3,295: Line 3,295:
write(*, "(a, 4f8.3)") " q2 * q1 = ", q2 * q1
write(*, "(a, 4f8.3)") " q2 * q1 = ", q2 * q1


end program</lang>
end program</syntaxhighlight>
{{out}}
{{out}}
<pre> q = 1.000 2.000 3.000 4.000
<pre> q = 1.000 2.000 3.000 4.000
Line 3,313: Line 3,313:


=={{header|FreeBASIC}}==
=={{header|FreeBASIC}}==
<lang freebasic>
<syntaxhighlight lang="freebasic">
Dim Shared As Integer q(3) = {1, 2, 3, 4}
Dim Shared As Integer q(3) = {1, 2, 3, 4}
Dim Shared As Integer q1(3) = {2, 3, 4, 5}
Dim Shared As Integer q1(3) = {2, 3, 4, 5}
Line 3,391: Line 3,391:
For i = 0 To 3 : t(i) = q2(i) : Next i : q_mul(t(),q1()) : Print "q2 * q1 = "; q_show(t())
For i = 0 To 3 : t(i) = q2(i) : Next i : q_mul(t(),q1()) : Print "q2 * q1 = "; q_show(t())
End
End
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 3,410: Line 3,410:


=={{header|GAP}}==
=={{header|GAP}}==
<lang gap># GAP has built-in support for quaternions
<syntaxhighlight lang="gap"># GAP has built-in support for quaternions


A := QuaternionAlgebra(Rationals);
A := QuaternionAlgebra(Rationals);
Line 3,519: Line 3,519:


1/q;
1/q;
# (1/30)*e+(-1/15)*i+(-1/10)*j+(-2/15)*k</lang>
# (1/30)*e+(-1/15)*i+(-1/10)*j+(-2/15)*k</syntaxhighlight>


=={{header|Go}}==
=={{header|Go}}==
Line 3,527: Line 3,527:
The three inputs are reused repeatedly without being modified.
The three inputs are reused repeatedly without being modified.
The output is also reused repeatedly, being overwritten for each operation.
The output is also reused repeatedly, being overwritten for each operation.
<lang go>package main
<syntaxhighlight lang="go">package main


import (
import (
Line 3,605: Line 3,605:
q1.r*q2.k+q1.i*q2.j-q1.j*q2.i+q1.k*q2.r
q1.r*q2.k+q1.i*q2.j-q1.j*q2.i+q1.k*q2.r
return z
return z
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 3,626: Line 3,626:


=={{header|Haskell}}==
=={{header|Haskell}}==
<lang haskell>import Control.Monad (join)
<syntaxhighlight lang="haskell">import Control.Monad (join)


data Quaternion a =
data Quaternion a =
Line 3,678: Line 3,678:
print $ q2 * q1 -- prints "Q (-56.0) 18.0 20.0 28.0"
print $ q2 * q1 -- prints "Q (-56.0) 18.0 20.0 28.0"
print $ q1 * q2 == q2 * q1 -- prints "False"
print $ q1 * q2 == q2 * q1 -- prints "False"
print $ imagQ q -- prints "[2.0,3.0,4.0]"</lang>
print $ imagQ q -- prints "[2.0,3.0,4.0]"</syntaxhighlight>


==Icon and {{header|Unicon}}==
==Icon and {{header|Unicon}}==
Line 3,684: Line 3,684:
Using Unicon's class system.
Using Unicon's class system.


<syntaxhighlight lang="unicon">
<lang Unicon>
class Quaternion(a, b, c, d)
class Quaternion(a, b, c, d)


Line 3,728: Line 3,728:
self.d := if /d then 0 else d
self.d := if /d then 0 else d
end
end
</syntaxhighlight>
</lang>


To test the above:
To test the above:


<syntaxhighlight lang="unicon">
<lang Unicon>
procedure main ()
procedure main ()
q := Quaternion (1,2,3,4)
q := Quaternion (1,2,3,4)
Line 3,749: Line 3,749:
write ("q2*q1 = " || q2.multiply(q1).string ())
write ("q2*q1 = " || q2.multiply(q1).string ())
end
end
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 3,768: Line 3,768:
With [[wp:Dependent_type|dependent types]] we can implement the more general [[wp:Cayley-Dickson_construction|Cayley-Dickson construction]]. Here the dependent type <code>CD n a</code> is implemented. It depends on a natural number <code>n</code>, which is the number of iterations carried out, and the base type <code>a</code>. So the real numbers are just <code>CD 0 Double</code>, the complex numbers <code>CD 1 Double</code> and the quaternions <code>CD 2 Double</code>
With [[wp:Dependent_type|dependent types]] we can implement the more general [[wp:Cayley-Dickson_construction|Cayley-Dickson construction]]. Here the dependent type <code>CD n a</code> is implemented. It depends on a natural number <code>n</code>, which is the number of iterations carried out, and the base type <code>a</code>. So the real numbers are just <code>CD 0 Double</code>, the complex numbers <code>CD 1 Double</code> and the quaternions <code>CD 2 Double</code>


<syntaxhighlight lang="idris">
<lang Idris>
module CayleyDickson
module CayleyDickson


Line 3,864: Line 3,864:
Abs (CD n Double) where
Abs (CD n Double) where
abs {n} = fromBase n . absCD
abs {n} = fromBase n . absCD
</syntaxhighlight>
</lang>


To test it:
To test it:


<syntaxhighlight lang="idris">
<lang Idris>
import CayleyDickson
import CayleyDickson


Line 3,880: Line 3,880:
printLn $ q2 * q1
printLn $ q2 * q1
printLn $ q1 * q2 == q2 * q1
printLn $ q1 * q2 == q2 * q1
</syntaxhighlight>
</lang>


=={{header|J}}==
=={{header|J}}==
Line 3,886: Line 3,886:
Derived from the [[j:System/Requests/Quaternions|j wiki]]:
Derived from the [[j:System/Requests/Quaternions|j wiki]]:


<lang j> NB. utilities
<syntaxhighlight lang="j"> NB. utilities
ip=: +/ .* NB. inner product
ip=: +/ .* NB. inner product
T=. (_1^#:0 10 9 12)*0 7 16 23 A.=i.4
T=. (_1^#:0 10 9 12)*0 7 16 23 A.=i.4
Line 3,896: Line 3,896:
conj=: 1 _1 _1 _1 * toQ NB. + y
conj=: 1 _1 _1 _1 * toQ NB. + y
add=: +&toQ NB. x + y
add=: +&toQ NB. x + y
mul=: (ip T ip ])&toQ NB. x * y</lang>
mul=: (ip T ip ])&toQ NB. x * y</syntaxhighlight>


T is a rank 3 tensor which allows us to express quaternion product ab as the inner product ATB if A and B are 4 element vectors representing the quaternions a and b. (Note also that once we have defined <code>mul</code> we no longer need to retain the definition of T, so we define T using =. instead of =:). The value of T is probably more interesting than its definition, so:
T is a rank 3 tensor which allows us to express quaternion product ab as the inner product ATB if A and B are 4 element vectors representing the quaternions a and b. (Note also that once we have defined <code>mul</code> we no longer need to retain the definition of T, so we define T using =. instead of =:). The value of T is probably more interesting than its definition, so:


<lang J> T
<syntaxhighlight lang="j"> T
1 0 0 0
1 0 0 0
0 1 0 0
0 1 0 0
Line 3,919: Line 3,919:
0 0 _1 0
0 0 _1 0
0 1 0 0
0 1 0 0
1 0 0 0</lang>
1 0 0 0</syntaxhighlight>


In other words, the last dimension of T corresponds to the structure of the right argument (columns, in the display of T), the first dimension of T corresponds to the structure of the left argument (tables, in the display of T) and the middle dimension of T corresponds to the structure of the result (rows, in the display of T).
In other words, the last dimension of T corresponds to the structure of the right argument (columns, in the display of T), the first dimension of T corresponds to the structure of the left argument (tables, in the display of T) and the middle dimension of T corresponds to the structure of the result (rows, in the display of T).
Line 3,925: Line 3,925:
Example use:
Example use:


<lang> q=: 1 2 3 4
<syntaxhighlight lang="text"> q=: 1 2 3 4
q1=: 2 3 4 5
q1=: 2 3 4 5
q2=: 3 4 5 6
q2=: 3 4 5 6
Line 3,945: Line 3,945:
_56 16 24 26
_56 16 24 26
q2 mul q1
q2 mul q1
_56 18 20 28</lang>
_56 18 20 28</syntaxhighlight>


Finally, note that when quaternions are used to represent [[wp:Quaternions_and_spatial_rotation|orientation or rotation]], we are typically only interested in unit length quaternions. As this is the typical application for quaternions, you will sometimes see quaternion multiplication expressed using "simplifications" which are only valid for unit length quaternions. But note also that in many of those contexts you also need to normalize the quaternion length after multiplication.
Finally, note that when quaternions are used to represent [[wp:Quaternions_and_spatial_rotation|orientation or rotation]], we are typically only interested in unit length quaternions. As this is the typical application for quaternions, you will sometimes see quaternion multiplication expressed using "simplifications" which are only valid for unit length quaternions. But note also that in many of those contexts you also need to normalize the quaternion length after multiplication.
Line 3,952: Line 3,952:


=={{header|Java}}==
=={{header|Java}}==
<lang java>public class Quaternion {
<syntaxhighlight lang="java">public class Quaternion {
private final double a, b, c, d;
private final double a, b, c, d;


Line 4,054: Line 4,054:
System.out.format("q1 \u00d7 q2 %s q2 \u00d7 q1%n", (q1q2.equals(q2q1) ? "=" : "\u2260"));
System.out.format("q1 \u00d7 q2 %s q2 \u00d7 q1%n", (q1q2.equals(q2q1) ? "=" : "\u2260"));
}
}
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 4,075: Line 4,075:
Runs on Firefox 3+, limited support in other JS engines. More compatible JavaScript deserves its own entry.
Runs on Firefox 3+, limited support in other JS engines. More compatible JavaScript deserves its own entry.


<lang javascript>var Quaternion = (function() {
<syntaxhighlight lang="javascript">var Quaternion = (function() {
// The Q() function takes an array argument and changes it
// The Q() function takes an array argument and changes it
// prototype so that it becomes a Quaternion instance. This is
// prototype so that it becomes a Quaternion instance. This is
Line 4,132: Line 4,132:
Quaternion.prototype = proto;
Quaternion.prototype = proto;
return Quaternion;
return Quaternion;
})();</lang>
})();</syntaxhighlight>


Task/Example Usage:
Task/Example Usage:


<lang javascript>var q = Quaternion(1,2,3,4);
<syntaxhighlight lang="javascript">var q = Quaternion(1,2,3,4);
var q1 = Quaternion(2,3,4,5);
var q1 = Quaternion(2,3,4,5);
var q2 = Quaternion(3,4,5,6);
var q2 = Quaternion(3,4,5,6);
Line 4,153: Line 4,153:
console.log("7.a. q1.mul(q2) = "+q1.mul(q2));
console.log("7.a. q1.mul(q2) = "+q1.mul(q2));
console.log("7.b. q2.mul(q1) = "+q2.mul(q1));
console.log("7.b. q2.mul(q1) = "+q2.mul(q1));
console.log("8. q1.mul(q2) " + (q1.mul(q2).equals(q2.mul(q1)) ? "==" : "!=") + " q2.mul(q1)");</lang>
console.log("8. q1.mul(q2) " + (q1.mul(q2).equals(q2.mul(q1)) ? "==" : "!=") + " q2.mul(q1)");</syntaxhighlight>


{{out}}
{{out}}
Line 4,172: Line 4,172:
=={{header|jq}}==
=={{header|jq}}==


Program file: quaternion.jq<lang jq>def Quaternion(q0;q1;q2;q3): { "q0": q0, "q1": q1, "q2": q2, "q3": q3, "type": "Quaternion" };
Program file: quaternion.jq<syntaxhighlight lang="jq">def Quaternion(q0;q1;q2;q3): { "q0": q0, "q1": q1, "q2": q2, "q3": q3, "type": "Quaternion" };


# promotion of a real number to a quaternion
# promotion of a real number to a quaternion
Line 4,263: Line 4,263:
) ;
) ;


demo</lang>
demo</syntaxhighlight>
Example usage and output:
Example usage and output:
<lang sh># jq -c -n -R -f quaternion.jq
<syntaxhighlight lang="sh"># jq -c -n -R -f quaternion.jq
Quaternion(1;0;0;0) => 1 + 0i + 0j + 0k
Quaternion(1;0;0;0) => 1 + 0i + 0j + 0k
abs($q) => 5.477225575051661
abs($q) => 5.477225575051661
Line 4,281: Line 4,281:
times($q1;$q2) => -56 + 16i + 24j + 26k
times($q1;$q2) => -56 + 16i + 24j + 26k
times($q2; $q1) => -56 + 18i + 20j + 28k
times($q2; $q1) => -56 + 18i + 20j + 28k
times($q1; $q2) != times($q2; $q1) => true</lang>
times($q1; $q2) != times($q2; $q1) => true</syntaxhighlight>


=={{header|Julia}}==
=={{header|Julia}}==
https://github.com/andrioni/Quaternions.jl/blob/master/src/Quaternions.jl has a more complete implementation.
https://github.com/andrioni/Quaternions.jl/blob/master/src/Quaternions.jl has a more complete implementation.
This is derived from the [https://github.com/JuliaLang/julia/blob/release-0.2/examples/quaternion.jl quaternion example file] included with Julia 0.2, which implements a quaternion type complete with arithmetic, type conversions / promotion rules, polymorphism over arbitrary real numeric types, and pretty-printing.
This is derived from the [https://github.com/JuliaLang/julia/blob/release-0.2/examples/quaternion.jl quaternion example file] included with Julia 0.2, which implements a quaternion type complete with arithmetic, type conversions / promotion rules, polymorphism over arbitrary real numeric types, and pretty-printing.
<lang julia>import Base: convert, promote_rule, show, conj, abs, +, -, *
<syntaxhighlight lang="julia">import Base: convert, promote_rule, show, conj, abs, +, -, *


immutable Quaternion{T<:Real} <: Number
immutable Quaternion{T<:Real} <: Number
Line 4,326: Line 4,326:
z.q0*w.q2 - z.q1*w.q3 + z.q2*w.q0 + z.q3*w.q1,
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.q0*w.q3 + z.q1*w.q2 - z.q2*w.q1 + z.q3*w.q0)
</syntaxhighlight>
</lang>


Example usage and output:
Example usage and output:
<lang julia>julia> q = Quaternion(1,0,0,0)
<syntaxhighlight lang="julia">julia> q = Quaternion(1,0,0,0)
julia> q = Quaternion (1, 2, 3, 4)
julia> q = Quaternion (1, 2, 3, 4)
q1 = Quaternion(2, 3, 4, 5)
q1 = Quaternion(2, 3, 4, 5)
Line 4,354: Line 4,354:


julia> q1*q2, q2*q1, q1*q2 != q2*q1
julia> q1*q2, q2*q1, q1*q2 != q2*q1
(-56 + 16i + 24j + 26k,-56 + 18i + 20j + 28k,true)</lang>
(-56 + 16i + 24j + 26k,-56 + 18i + 20j + 28k,true)</syntaxhighlight>


=={{header|Kotlin}}==
=={{header|Kotlin}}==
<lang scala>// version 1.1.2
<syntaxhighlight lang="scala">// version 1.1.2


data class Quaternion(val a: Double, val b: Double, val c: Double, val d: Double) {
data class Quaternion(val a: Double, val b: Double, val c: Double, val d: Double) {
Line 4,413: Line 4,413:
println("q2 * q1 = $q4\n")
println("q2 * q1 = $q4\n")
println("q1 * q2 != q2 * q1 = ${q3 != q4}")
println("q1 * q2 != q2 * q1 = ${q3 != q4}")
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 4,440: Line 4,440:
=={{header|Liberty BASIC}}==
=={{header|Liberty BASIC}}==
Quaternions saved as a space-separated string of four numbers.
Quaternions saved as a space-separated string of four numbers.
<syntaxhighlight lang="lb">
<lang lb>


q$ = q$( 1 , 2 , 3 , 4 )
q$ = q$( 1 , 2 , 3 , 4 )
Line 4,553: Line 4,553:
add2$ =q$( ar +br, ai +bi, aj +bj, ak +bk)
add2$ =q$( ar +br, ai +bi, aj +bj, ak +bk)
end function
end function
</lang>
</syntaxhighlight>


=={{header|Lua}}==
=={{header|Lua}}==
<lang lua>Quaternion = {}
<syntaxhighlight lang="lua">Quaternion = {}


function Quaternion.new( a, b, c, d )
function Quaternion.new( a, b, c, d )
Line 4,618: Line 4,618:
function Quaternion.print( p )
function Quaternion.print( p )
print( string.format( "%f + %fi + %fj + %fk\n", p.a, p.b, p.c, p.d ) )
print( string.format( "%f + %fi + %fj + %fk\n", p.a, p.b, p.c, p.d ) )
end</lang>
end</syntaxhighlight>
Examples:
Examples:
<lang lua>q1 = Quaternion.new( 1, 2, 3, 4 )
<syntaxhighlight lang="lua">q1 = Quaternion.new( 1, 2, 3, 4 )
q2 = Quaternion.new( 5, 6, 7, 8 )
q2 = Quaternion.new( 5, 6, 7, 8 )
r = 12
r = 12
Line 4,632: Line 4,632:
io.write( "q1*r = " ); Quaternion.print( q1*r )
io.write( "q1*r = " ); Quaternion.print( q1*r )
io.write( "q1*q2 = " ); Quaternion.print( q1*q2 )
io.write( "q1*q2 = " ); Quaternion.print( q1*q2 )
io.write( "q2*q1 = " ); Quaternion.print( q2*q1 )</lang>
io.write( "q2*q1 = " ); Quaternion.print( q2*q1 )</syntaxhighlight>


{{out}}
{{out}}
Line 4,647: Line 4,647:
=={{header|M2000 Interpreter}}==
=={{header|M2000 Interpreter}}==
We can define Quaternions using a class, using operators for specific tasks, as negate, add, multiplication and equality with rounding to 13 decimal place (thats what doing "==" operator for doubles)
We can define Quaternions using a class, using operators for specific tasks, as negate, add, multiplication and equality with rounding to 13 decimal place (thats what doing "==" operator for doubles)
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module CheckIt {
Module CheckIt {
class Quaternion {
class Quaternion {
Line 4,747: Line 4,747:
}
}
CheckIt
CheckIt
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 4,766: Line 4,766:


=={{header|Maple}}==
=={{header|Maple}}==
<syntaxhighlight lang="maple">
<lang Maple>
with(ArrayTools);
with(ArrayTools);


Line 4,913: Line 4,913:
print("divide q1 by q2"):
print("divide q1 by q2"):
q1 / q2;
q1 / q2;
</syntaxhighlight>
</lang>
{{out}}<pre>
{{out}}<pre>
"q, q1, q2"
"q, q1, q2"
Line 4,967: Line 4,967:


=={{header|Mathematica}}/{{header|Wolfram Language}}==
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<lang Mathematica><<Quaternions`
<syntaxhighlight lang="mathematica"><<Quaternions`
q=Quaternion[1,2,3,4]
q=Quaternion[1,2,3,4]
q1=Quaternion[2,3,4,5]
q1=Quaternion[2,3,4,5]
Line 4,997: Line 4,997:
q2**q1
q2**q1
->Quaternion[-56,18,20,28]
->Quaternion[-56,18,20,28]
</syntaxhighlight>
</lang>


=={{header|Mercury}}==
=={{header|Mercury}}==
Line 5,003: Line 5,003:
A possible implementation of quaternions in Mercury (the simplest representation) would look like this. Note that this is a full module implementation, complete with boilerplate, and that it works by giving an explicit conversion function for floats, converting a float into a quaternion representation of that float. Thus the float value <code>7.0</code> gets turned into the quaternion representation <code>q(7.0, 0.0, 0.0, 0.0)</code> through the function call <code>r(7.0)</code>.
A possible implementation of quaternions in Mercury (the simplest representation) would look like this. Note that this is a full module implementation, complete with boilerplate, and that it works by giving an explicit conversion function for floats, converting a float into a quaternion representation of that float. Thus the float value <code>7.0</code> gets turned into the quaternion representation <code>q(7.0, 0.0, 0.0, 0.0)</code> through the function call <code>r(7.0)</code>.


<lang Mercury>:- module quaternion.
<syntaxhighlight lang="mercury">:- module quaternion.


:- interface.
:- interface.
Line 5,040: Line 5,040:
W0*I1 + I0*W1 + J0*K1 - K0*J1,
W0*I1 + I0*W1 + J0*K1 - K0*J1,
W0*J1 - I0*K1 + J0*W1 + K0*I1,
W0*J1 - I0*K1 + J0*W1 + K0*I1,
W0*K1 + I0*J1 - J0*I1 + K0*W1 ).</lang>
W0*K1 + I0*J1 - J0*I1 + K0*W1 ).</syntaxhighlight>


The following test module puts the module through its paces.
The following test module puts the module through its paces.


<lang Mercury>:- module test_quaternion.
<syntaxhighlight lang="mercury">:- module test_quaternion.


:- interface.
:- interface.
Line 5,119: Line 5,119:
to_string(q(I, J, K, W)) = string.format("q(%f, %f, %f, %f)",
to_string(q(I, J, K, W)) = string.format("q(%f, %f, %f, %f)",
[f(I), f(J), f(K), f(W)]).
[f(I), f(J), f(K), f(W)]).
:- end_module test_quaternion.</lang>
:- end_module test_quaternion.</syntaxhighlight>


The output of the above code follows:
The output of the above code follows:
Line 5,162: Line 5,162:
For simplicity, we have limited the type of quaternion fields to floats (i.e. float64). An implementation could use a generic type in order to allow other field types such as float32.
For simplicity, we have limited the type of quaternion fields to floats (i.e. float64). An implementation could use a generic type in order to allow other field types such as float32.


<lang Nim>import math, tables
<syntaxhighlight lang="nim">import math, tables


type Quaternion* = object
type Quaternion* = object
Line 5,233: Line 5,233:
echo "rq = ", r * q
echo "rq = ", r * q
echo "q1 * q2 = ", q1 * q2
echo "q1 * q2 = ", q1 * q2
echo "q2 * q1 = ", q2 * q1</lang>
echo "q2 * q1 = ", q2 * q1</syntaxhighlight>


{{out}}
{{out}}
Line 5,252: Line 5,252:


This implementation was build strictly to the specs without looking (too much) at other implementations. The implementation as a record type with only floats is said (on the ocaml mailing list) to be especially efficient. Put this into a file quaternion.ml:
This implementation was build strictly to the specs without looking (too much) at other implementations. The implementation as a record type with only floats is said (on the ocaml mailing list) to be especially efficient. Put this into a file quaternion.ml:
<lang ocaml>
<syntaxhighlight lang="ocaml">
type quaternion = {a: float; b: float; c: float; d: float}
type quaternion = {a: float; b: float; c: float; d: float}


Line 5,317: Line 5,317:
pf "8. instead q2 * q1 = %s \n" (qstring (multq q2 q1));
pf "8. instead q2 * q1 = %s \n" (qstring (multq q2 q1));
pf "\n";
pf "\n";
</syntaxhighlight>
</lang>


using this file on the command line will produce:
using this file on the command line will produce:
Line 5,333: Line 5,333:
</pre>
</pre>
For completeness, and since data types are of utmost importance in OCaml, here the types produced by pasting the code into the toplevel (''ocaml'' is the toplevel):
For completeness, and since data types are of utmost importance in OCaml, here the types produced by pasting the code into the toplevel (''ocaml'' is the toplevel):
<lang ocaml>
<syntaxhighlight lang="ocaml">
type quaternion = { a : float; b : float; c : float; d : float; }
type quaternion = { a : float; b : float; c : float; d : float; }
val norm : quaternion -> float = <fun>
val norm : quaternion -> float = <fun>
Line 5,345: Line 5,345:
val qmake : float -> float -> float -> float -> quaternion = <fun>
val qmake : float -> float -> float -> float -> quaternion = <fun>
val qstring : quaternion -> string = <fun>
val qstring : quaternion -> string = <fun>
</syntaxhighlight>
</lang>


=={{header|Octave}}==
=={{header|Octave}}==
Line 5,352: Line 5,352:
Such a package can be install with the command:
Such a package can be install with the command:


<lang>pkg install -forge quaternion</lang>
<syntaxhighlight lang="text">pkg install -forge quaternion</syntaxhighlight>


Here is a sample interactive session solving the task:
Here is a sample interactive session solving the task:


<lang>> q = quaternion (1, 2, 3, 4)
<syntaxhighlight lang="text">> q = quaternion (1, 2, 3, 4)
q = 1 + 2i + 3j + 4k
q = 1 + 2i + 3j + 4k
> q1 = quaternion (2, 3, 4, 5)
> q1 = quaternion (2, 3, 4, 5)
Line 5,379: Line 5,379:
ans = -56 + 16i + 24j + 26k
ans = -56 + 16i + 24j + 26k
> q1 == q2
> q1 == q2
ans = 0</lang>
ans = 0</syntaxhighlight>


=={{header|Oforth}}==
=={{header|Oforth}}==
Line 5,385: Line 5,385:
neg is defined as "0 self -" into Number class, so no need to define it (if #- is defined).
neg is defined as "0 self -" into Number class, so no need to define it (if #- is defined).


<lang Oforth>160 Number Class newPriority: Quaternion(a, b, c, d)
<syntaxhighlight lang="oforth">160 Number Class newPriority: Quaternion(a, b, c, d)


Quaternion method: _a @a ;
Quaternion method: _a @a ;
Line 5,408: Line 5,408:
q _a @b * q _b @a * + q _c @d * + q _d @c * -,
q _a @b * q _b @a * + q _c @d * + q _d @c * -,
q _a @c * q _b @d * - q _c @a * + q _d @b * +,
q _a @c * q _b @d * - q _c @a * + q _d @b * +,
q _a @d * q _b @c * + q _c @b * - q _d @a * + ) ;</lang>
q _a @d * q _b @c * + q _c @b * - q _d @a * + ) ;</syntaxhighlight>


Usage :
Usage :


<lang Oforth>: test
<syntaxhighlight lang="oforth">: test
| q q1 q2 r |
| q q1 q2 r |


Line 5,431: Line 5,431:
System.Out "q * r = " << q r * << cr
System.Out "q * r = " << q r * << cr
System.Out "q1 * q2 = " << q1 q2 * << cr
System.Out "q1 * q2 = " << q1 q2 * << cr
q1 q2 * q2 q1 * == ifFalse: [ "q1q2 and q2q1 are different quaternions" println ] ;</lang>
q1 q2 * q2 q1 * == ifFalse: [ "q1q2 and q2q1 are different quaternions" println ] ;</syntaxhighlight>


{{out}}
{{out}}
Line 5,450: Line 5,450:
=={{header|ooRexx}}==
=={{header|ooRexx}}==
Note, this example uses operator overloads to perform the math operation. The operator overloads only work if the left-hand-side of the operation is a quaterion instance. Thus something like "7 + q1" would not work because this would get passed to the "+" of the string class. For those situations, the best solution would be an addition method on the .Quaternion class itself that took the appropriate action. I've chosen not to implement those to keep the example shorter.
Note, this example uses operator overloads to perform the math operation. The operator overloads only work if the left-hand-side of the operation is a quaterion instance. Thus something like "7 + q1" would not work because this would get passed to the "+" of the string class. For those situations, the best solution would be an addition method on the .Quaternion class itself that took the appropriate action. I've chosen not to implement those to keep the example shorter.
<syntaxhighlight lang="oorexx">
<lang ooRexx>
q = .quaternion~new(1, 2, 3, 4)
q = .quaternion~new(1, 2, 3, 4)
q1 = .quaternion~new(2, 3, 4, 5)
q1 = .quaternion~new(2, 3, 4, 5)
Line 5,602: Line 5,602:
::requires rxmath LIBRARY
::requires rxmath LIBRARY


</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 5,624: Line 5,624:
{{works with|PARI/GP|version 2.4.2 and above}}<!-- Needs closures -->
{{works with|PARI/GP|version 2.4.2 and above}}<!-- Needs closures -->
Here is a simple solution in GP. I think it's possible to implement this type directly in Pari by abusing t_COMPLEX, but I haven't attempted this.
Here is a simple solution in GP. I think it's possible to implement this type directly in Pari by abusing t_COMPLEX, but I haven't attempted this.
<lang parigp>q.norm={
<syntaxhighlight lang="parigp">q.norm={
if(type(q) != "t_VEC" || #q != 4, error("incorrect type"));
if(type(q) != "t_VEC" || #q != 4, error("incorrect type"));
sqrt(q[1]^2+q[2]^2+q[3]^2+q[4]^2)
sqrt(q[1]^2+q[2]^2+q[3]^2+q[4]^2)
Line 5,658: Line 5,658:
)
)
)
)
};</lang>
};</syntaxhighlight>
Usage:
Usage:
<lang parigp>r=7;q=[1,2,3,4];q1=[2,3,4,5];q2=[3,4,5,6];
<syntaxhighlight lang="parigp">r=7;q=[1,2,3,4];q1=[2,3,4,5];q2=[3,4,5,6];
q.norm
q.norm
-q
-q
Line 5,669: Line 5,669:
q.mult(r) \\ or r*q or q*r
q.mult(r) \\ or r*q or q*r
q1.mult(q2)
q1.mult(q2)
q1.mult(q2) != q2.mult(q1)</lang>
q1.mult(q2) != q2.mult(q1)</syntaxhighlight>


=={{header|Pascal}}==
=={{header|Pascal}}==
Line 5,675: Line 5,675:


=={{header|Perl}}==
=={{header|Perl}}==
<lang Perl>package Quaternion;
<syntaxhighlight lang="perl">package Quaternion;
use List::Util 'reduce';
use List::Util 'reduce';
use List::MoreUtils 'pairwise';
use List::MoreUtils 'pairwise';
Line 5,744: Line 5,744:
print "a conjugate is ", $a->conjugate, "\n";
print "a conjugate is ", $a->conjugate, "\n";
print "a * b = ", $a * $b, "\n";
print "a * b = ", $a * $b, "\n";
print "b * a = ", $b * $a, "\n";</lang>
print "b * a = ", $b * $a, "\n";</syntaxhighlight>


=={{header|Phix}}==
=={{header|Phix}}==
<!--<lang Phix>(phixonline)-->
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">norm</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">q</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">norm</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">q</span><span style="color: #0000FF;">)</span>
Line 5,820: Line 5,820:
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">" .c 6.a === 6.b: %t\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #7060A8;">equal</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">q</span><span style="color: #0000FF;">,</span><span style="color: #000000;">49</span><span style="color: #0000FF;">),</span><span style="color: #000000;">mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">49</span><span style="color: #0000FF;">,</span><span style="color: #000000;">q</span><span style="color: #0000FF;">))})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">" .c 6.a === 6.b: %t\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #7060A8;">equal</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">q</span><span style="color: #0000FF;">,</span><span style="color: #000000;">49</span><span style="color: #0000FF;">),</span><span style="color: #000000;">mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">49</span><span style="color: #0000FF;">,</span><span style="color: #000000;">q</span><span style="color: #0000FF;">))})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">" .d 7.a === 7.b: %t\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #7060A8;">equal</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">q1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">q2</span><span style="color: #0000FF;">),</span><span style="color: #000000;">mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">q2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">q1</span><span style="color: #0000FF;">))})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">" .d 7.a === 7.b: %t\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #7060A8;">equal</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">q1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">q2</span><span style="color: #0000FF;">),</span><span style="color: #000000;">mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">q2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">q1</span><span style="color: #0000FF;">))})</span>
<!--</lang>-->
<!--</syntaxhighlight>-->
{{out}}
{{out}}
<pre>
<pre>
Line 5,852: Line 5,852:
{{trans|Prolog}}
{{trans|Prolog}}
A quaternion is represented as a complex term <code>qx/4</code>.
A quaternion is represented as a complex term <code>qx/4</code>.
<lang Picat>go =>
<syntaxhighlight lang="picat">go =>
test,
test,
nl.
nl.
Line 5,901: Line 5,901:
test :- data(q1, Q1), data(q2, Q2), mul(Q2, Q1, Qx),
test :- data(q1, Q1), data(q2, Q2), mul(Q2, Q1, Qx),
printf("q2*q1 is %w\n", Qx), fail.
printf("q2*q1 is %w\n", Qx), fail.
test.</lang>
test.</syntaxhighlight>


{{out}}
{{out}}
Line 5,917: Line 5,917:


=={{header|PicoLisp}}==
=={{header|PicoLisp}}==
<lang PicoLisp>(scl 6)
<syntaxhighlight lang="picolisp">(scl 6)


(def 'quatCopy copy)
(def 'quatCopy copy)
Line 5,949: Line 5,949:
(mapcar '((R S) (pack (format R *Scl) S))
(mapcar '((R S) (pack (format R *Scl) S))
Q
Q
'(" + " "i + " "j + " "k") ) )</lang>
'(" + " "i + " "j + " "k") ) )</syntaxhighlight>
Test:
Test:
<lang PicoLisp>(setq
<syntaxhighlight lang="picolisp">(setq
Q (1.0 2.0 3.0 4.0)
Q (1.0 2.0 3.0 4.0)
Q1 (2.0 3.0 4.0 5.0)
Q1 (2.0 3.0 4.0 5.0)
Line 5,972: Line 5,972:
(prinl "Q1 * Q2 = " (quatFmt (quatMul Q1 Q2)))
(prinl "Q1 * Q2 = " (quatFmt (quatMul Q1 Q2)))
(prinl "Q2 * Q1 = " (quatFmt (quatMul Q2 Q1)))
(prinl "Q2 * Q1 = " (quatFmt (quatMul Q2 Q1)))
(prinl (if (= (quatMul Q1 Q2) (quatMul Q2 Q1)) "Equal" "Not equal"))</lang>
(prinl (if (= (quatMul Q1 Q2) (quatMul Q2 Q1)) "Equal" "Not equal"))</syntaxhighlight>
{{out}}
{{out}}
<pre>R = 7.000000
<pre>R = 7.000000
Line 5,992: Line 5,992:


=={{header|PL/I}}==
=={{header|PL/I}}==
<lang pli>*process source attributes xref or(!);
<syntaxhighlight lang="pli">*process source attributes xref or(!);
qu: Proc Options(main);
qu: Proc Options(main);
/**********************************************************************
/**********************************************************************
Line 6,137: Line 6,137:
End;
End;


End;</lang>
End;</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 6,161: Line 6,161:
=={{header|PowerShell}}==
=={{header|PowerShell}}==
===Implementation===
===Implementation===
<syntaxhighlight lang="powershell">
<lang PowerShell>
class Quaternion {
class Quaternion {
[Double]$w
[Double]$w
Line 6,220: Line 6,220:
"`$q1 * `$q2: $([Quaternion]::show([Quaternion]::mul($q1,$q2)))"
"`$q1 * `$q2: $([Quaternion]::show([Quaternion]::mul($q1,$q2)))"
"`$q2 * `$q1: $([Quaternion]::show([Quaternion]::mul($q2,$q1)))"
"`$q2 * `$q1: $([Quaternion]::show([Quaternion]::mul($q2,$q1)))"
</syntaxhighlight>
</lang>
<b>Output:</b>
<b>Output:</b>
<pre>
<pre>
Line 6,233: Line 6,233:
</pre>
</pre>
===Library===
===Library===
<syntaxhighlight lang="powershell">
<lang PowerShell>
function show([System.Numerics.Quaternion]$c) {
function show([System.Numerics.Quaternion]$c) {
function st([Double]$r) {
function st([Double]$r) {
Line 6,256: Line 6,256:
"`$q1 * `$q2: $(show ([System.Numerics.Quaternion]::Multiply($q1,$q2)))"
"`$q1 * `$q2: $(show ([System.Numerics.Quaternion]::Multiply($q1,$q2)))"
"`$q2 * `$q1: $(show ([System.Numerics.Quaternion]::Multiply($q2,$q1)))"
"`$q2 * `$q1: $(show ([System.Numerics.Quaternion]::Multiply($q2,$q1)))"
</syntaxhighlight>
</lang>
<b>Output:</b>
<b>Output:</b>
<pre>
<pre>
Line 6,270: Line 6,270:


=={{header|Prolog}}==
=={{header|Prolog}}==
<lang Prolog>% A quaternion is represented as a complex term qx/4
<syntaxhighlight lang="prolog">% A quaternion is represented as a complex term qx/4
add(qx(R0,I0,J0,K0), qx(R1,I1,J1,K1), qx(R,I,J,K)) :-
add(qx(R0,I0,J0,K0), qx(R1,I1,J1,K1), qx(R,I,J,K)) :-
!, R is R0+R1, I is I0+I1, J is J0+J1, K is K0+K1.
!, R is R0+R1, I is I0+I1, J is J0+J1, K is K0+K1.
Line 6,291: Line 6,291:
R is -Ri, I is -Ii, J is -Ji, K is -Ki.
R is -Ri, I is -Ii, J is -Ji, K is -Ki.
conjugate(qx(R,Ii,Ji,Ki),qx(R,I,J,K)) :-
conjugate(qx(R,Ii,Ji,Ki),qx(R,I,J,K)) :-
I is -Ii, J is -Ji, K is -Ki.</lang>
I is -Ii, J is -Ji, K is -Ki.</syntaxhighlight>


'''Test:'''
'''Test:'''
<lang Prolog>data(q, qx(1,2,3,4)).
<syntaxhighlight lang="prolog">data(q, qx(1,2,3,4)).
data(q1, qx(2,3,4,5)).
data(q1, qx(2,3,4,5)).
data(q2, qx(3,4,5,6)).
data(q2, qx(3,4,5,6)).
Line 6,317: Line 6,317:
test :- data(q1, Q1), data(q2, Q2), mul(Q2, Q1, Qx),
test :- data(q1, Q1), data(q2, Q2), mul(Q2, Q1, Qx),
writef('q2*q1 is %w\n', [Qx]), fail.
writef('q2*q1 is %w\n', [Qx]), fail.
test.</lang>
test.</syntaxhighlight>
{{out}}
{{out}}
<pre> ?- test.
<pre> ?- test.
Line 6,333: Line 6,333:


=={{header|PureBasic}}==
=={{header|PureBasic}}==
<lang PureBasic>Structure Quaternion
<syntaxhighlight lang="purebasic">Structure Quaternion
a.f
a.f
b.f
b.f
Line 6,417: Line 6,417:
EndIf
EndIf
ProcedureReturn 1 ;true
ProcedureReturn 1 ;true
EndProcedure</lang>
EndProcedure</syntaxhighlight>
Implementation & test
Implementation & test
<lang PureBasic>Procedure.s ShowQ(*x.Quaternion, NN = 0)
<syntaxhighlight lang="purebasic">Procedure.s ShowQ(*x.Quaternion, NN = 0)
ProcedureReturn "{" + StrF(*x\a, NN) + "," + StrF(*x\b, NN) + "," + StrF(*x\c, NN) + "," + StrF(*x\d, NN) + "}"
ProcedureReturn "{" + StrF(*x\a, NN) + "," + StrF(*x\b, NN) + "," + StrF(*x\c, NN) + "," + StrF(*x\d, NN) + "}"
EndProcedure
EndProcedure
Line 6,447: Line 6,447:
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
CloseConsole()
CloseConsole()
EndIf</lang>
EndIf</syntaxhighlight>
Result
Result
<pre>Q0 = {1,2,3,4}
<pre>Q0 = {1,2,3,4}
Line 6,464: Line 6,464:
=={{header|Python}}==
=={{header|Python}}==
This example extends Pythons [http://docs.python.org/library/collections.html?highlight=namedtuple#collections.namedtuple namedtuples] to add extra functionality.
This example extends Pythons [http://docs.python.org/library/collections.html?highlight=namedtuple#collections.namedtuple namedtuples] to add extra functionality.
<lang python>from collections import namedtuple
<syntaxhighlight lang="python">from collections import namedtuple
import math
import math


Line 6,545: Line 6,545:
q1 = Q(2, 3, 4, 5)
q1 = Q(2, 3, 4, 5)
q2 = Q(3, 4, 5, 6)
q2 = Q(3, 4, 5, 6)
r = 7</lang>
r = 7</syntaxhighlight>


'''Continued shell session'''
'''Continued shell session'''
Run the above with the -i flag to python on the command line, or run with idle then continue in the shell as follows:
Run the above with the -i flag to python on the command line, or run with idle then continue in the shell as follows:
<lang python>>>> q
<syntaxhighlight lang="python">>>> q
Quaternion(real=1.0, i=2.0, j=3.0, k=4.0)
Quaternion(real=1.0, i=2.0, j=3.0, k=4.0)
>>> q1
>>> q1
Line 6,604: Line 6,604:
>>> q1 * q1.reciprocal()
>>> q1 * q1.reciprocal()
Quaternion(real=0.9999999999999999, i=0.0, j=0.0, k=0.0)
Quaternion(real=0.9999999999999999, i=0.0, j=0.0, k=0.0)
>>> </lang>
>>> </syntaxhighlight>


=={{header|R}}==
=={{header|R}}==
Line 6,610: Line 6,610:
Using the quaternions package.
Using the quaternions package.


<syntaxhighlight lang="r">
<lang R>
library(quaternions)
library(quaternions)


Line 6,645: Line 6,645:
## q1*q2 != q2*q1
## q1*q2 != q2*q1


</syntaxhighlight>
</lang>


=={{header|Racket}}==
=={{header|Racket}}==
<lang Racket>#lang racket
<syntaxhighlight lang="racket">#lang racket
(struct quaternion (a b c d)
(struct quaternion (a b c d)
Line 6,722: Line 6,722:
(multiply q2 q1)
(multiply q2 q1)
(equal? (multiply q1 q2)
(equal? (multiply q1 q2)
(multiply q2 q1)))</lang>
(multiply q2 q1)))</syntaxhighlight>


{{out}}
{{out}}
Line 6,754: Line 6,754:
=={{header|Raku}}==
=={{header|Raku}}==
(formerly Perl 6)
(formerly Perl 6)
<lang perl6>class Quaternion {
<syntaxhighlight lang="raku" line>class Quaternion {
has Real ( $.r, $.i, $.j, $.k );
has Real ( $.r, $.i, $.j, $.k );
Line 6,807: Line 6,807:
say "6) q * r = {$q * $r}";
say "6) q * r = {$q * $r}";
say "7) q1 * q2 = {$q1 * $q2}";
say "7) q1 * q2 = {$q1 * $q2}";
say "8) q1q2 { $q1 * $q2 eqv $q2 * $q1 ?? '==' !! '!=' } q2q1";</lang>
say "8) q1q2 { $q1 * $q2 eqv $q2 * $q1 ?? '==' !! '!=' } q2q1";</syntaxhighlight>
{{out}}
{{out}}
<pre>1) q norm = 5.47722557505166
<pre>1) q norm = 5.47722557505166
Line 6,819: Line 6,819:


=={{header|Red}}==
=={{header|Red}}==
<syntaxhighlight lang="red">
<lang Red>
quaternion: context [
quaternion: context [
quaternion!: make typeset! [block! hash! vector!]
quaternion!: make typeset! [block! hash! vector!]
Line 6,879: Line 6,879:
`equal? quaternion/multiply q1 q2 mold quaternion/multiply q2 q1` =>}
`equal? quaternion/multiply q1 q2 mold quaternion/multiply q2 q1` =>}
equal? quaternion/multiply q1 q2 quaternion/multiply q2 q1]
equal? quaternion/multiply q1 q2 quaternion/multiply q2 q1]
</syntaxhighlight>
</lang>


Output:
Output:
Line 6,911: Line 6,911:
=={{header|REXX}}==
=={{header|REXX}}==
The REXX language has no native quaternion support, but subroutines can be easily written.
The REXX language has no native quaternion support, but subroutines can be easily written.
<lang rexx>/*REXX program performs some operations on quaternion type numbers and displays results*/
<syntaxhighlight lang="rexx">/*REXX program performs some operations on quaternion type numbers and displays results*/
q = 1 2 3 4 ; q1 = 2 3 4 5
q = 1 2 3 4 ; q1 = 2 3 4 5
r = 7 ; q2 = 3 4 5 6
r = 7 ; q2 = 3 4 5 6
Line 6,951: Line 6,951:
do j=0 while h>9; m.j=h; h= h % 2 + 1; end /*j*/
do j=0 while h>9; m.j=h; h= h % 2 + 1; end /*j*/
do k=j+5 to 0 by -1; numeric digits m.k; g= (g + x/g)* .5; end /*k*/
do k=j+5 to 0 by -1; numeric digits m.k; g= (g + x/g)* .5; end /*k*/
numeric digits d; return (g/1)i /*make complex if X<0 */</lang>
numeric digits d; return (g/1)i /*make complex if X<0 */</syntaxhighlight>
{{out|output|text=&nbsp; when using the internal default inputs:}}
{{out|output|text=&nbsp; when using the internal default inputs:}}
<pre>
<pre>
Line 6,971: Line 6,971:
{{works with|Ruby|1.9}}
{{works with|Ruby|1.9}}


<lang ruby>class Quaternion
<syntaxhighlight lang="ruby">class Quaternion
def initialize(*parts)
def initialize(*parts)
raise ArgumentError, "wrong number of arguments (#{parts.size} for 4)" unless parts.size == 4
raise ArgumentError, "wrong number of arguments (#{parts.size} for 4)" unless parts.size == 4
Line 7,047: Line 7,047:
puts "%20s = %s" % [exp, eval(exp)]
puts "%20s = %s" % [exp, eval(exp)]
end
end
end</lang>
end</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 7,071: Line 7,071:
=={{header|Rust}}==
=={{header|Rust}}==


<lang rust>use std::fmt::{Display, Error, Formatter};
<syntaxhighlight lang="rust">use std::fmt::{Display, Error, Formatter};
use std::ops::{Add, Mul, Neg};
use std::ops::{Add, Mul, Neg};


Line 7,243: Line 7,243:
println!();
println!();
println!("normal of q0 = {}", q0.norm());
println!("normal of q0 = {}", q0.norm());
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 7,276: Line 7,276:


=={{header|Scala}}==
=={{header|Scala}}==
<lang scala>case class Quaternion(re: Double = 0.0, i: Double = 0.0, j: Double = 0.0, k: Double = 0.0) {
<syntaxhighlight lang="scala">case class Quaternion(re: Double = 0.0, i: Double = 0.0, j: Double = 0.0, k: Double = 0.0) {
lazy val im = (i, j, k)
lazy val im = (i, j, k)
private lazy val norm2 = re*re + i*i + j*j + k*k
private lazy val norm2 = re*re + i*i + j*j + k*k
Line 7,306: Line 7,306:


implicit def number2Quaternion[T:Numeric](n: T) = Quaternion(n.toDouble)
implicit def number2Quaternion[T:Numeric](n: T) = Quaternion(n.toDouble)
}</lang>
}</syntaxhighlight>
Demonstration:
Demonstration:
<lang scala>val q0=Quaternion(1.0, 2.0, 3.0, 4.0);
<syntaxhighlight lang="scala">val q0=Quaternion(1.0, 2.0, 3.0, 4.0);
val q1=Quaternion(2.0, 3.0, 4.0, 5.0);
val q1=Quaternion(2.0, 3.0, 4.0, 5.0);
val q2=Quaternion(3.0, 4.0, 5.0, 6.0);
val q2=Quaternion(3.0, 4.0, 5.0, 6.0);
Line 7,342: Line 7,342:
println("q2/q1 = "+ q2/q1)
println("q2/q1 = "+ q2/q1)
println("q1/r = "+ q1/r)
println("q1/r = "+ q1/r)
println("r/q1 = "+ r/q1)</lang>
println("r/q1 = "+ r/q1)</syntaxhighlight>
{{out}}
{{out}}
<pre>q0 = Q(1.00, 2.00i, 3.00j, 4.00k)
<pre>q0 = Q(1.00, 2.00i, 3.00j, 4.00k)
Line 7,375: Line 7,375:


=={{header|Seed7}}==
=={{header|Seed7}}==
<lang seed7>$ include "seed7_05.s7i";
<syntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "float.s7i";
include "float.s7i";
include "math.s7i";
include "math.s7i";
Line 7,551: Line 7,551:
writeln("q1 * q2 = " <& q1 * q2);
writeln("q1 * q2 = " <& q1 * q2);
writeln("q2 * q1 = " <& q2 * q1);
writeln("q2 * q1 = " <& q2 * q1);
end func;</lang>
end func;</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 7,574: Line 7,574:
=={{header|Sidef}}==
=={{header|Sidef}}==
{{trans|Raku}}
{{trans|Raku}}
<lang ruby>class Quaternion(r, i, j, k) {
<syntaxhighlight lang="ruby">class Quaternion(r, i, j, k) {


func qu(*r) { Quaternion(r...) }
func qu(*r) { Quaternion(r...) }
Line 7,612: Line 7,612:
say "6) q * r = #{q * r}"
say "6) q * r = #{q * r}"
say "7) q1 * q2 = #{q1 * q2}"
say "7) q1 * q2 = #{q1 * q2}"
say "8) q1q2 #{ q1*q2 == q2*q1 ? '==' : '!=' } q2q1"</lang>
say "8) q1q2 #{ q1*q2 == q2*q1 ? '==' : '!=' } q2q1"</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 7,626: Line 7,626:


=={{header|Swift}}==
=={{header|Swift}}==
<lang swift>import Foundation
<syntaxhighlight lang="swift">import Foundation


struct Quaternion {
struct Quaternion {
Line 7,759: Line 7,759:
q₂q₁ = \(q2 * q1)
q₂q₁ = \(q2 * q1)
q₁q₂ ≠ q₂q₁ is \(q1*q2 != q2*q1)
q₁q₂ ≠ q₂q₁ is \(q1*q2 != q2*q1)
""")</lang>
""")</syntaxhighlight>


{{out}}
{{out}}
Line 7,780: Line 7,780:
=={{header|Tcl}}==
=={{header|Tcl}}==
{{works with|Tcl|8.6}} or {{libheader|TclOO}}
{{works with|Tcl|8.6}} or {{libheader|TclOO}}
<lang tcl>package require TclOO
<syntaxhighlight lang="tcl">package require TclOO


# Support class that provides C++-like RAII lifetimes
# Support class that provides C++-like RAII lifetimes
Line 7,878: Line 7,878:


export - + * ==
export - + * ==
}</lang>
}</syntaxhighlight>
Demonstration code:
Demonstration code:
<lang tcl>set q [Q new 1 2 3 4]
<syntaxhighlight lang="tcl">set q [Q new 1 2 3 4]
set q1 [Q new 2 3 4 5]
set q1 [Q new 2 3 4 5]
set q2 [Q new 3 4 5 6]
set q2 [Q new 3 4 5 6]
Line 7,901: Line 7,901:
puts "q1 * q2 = [[$q1 * $q2] p]"
puts "q1 * q2 = [[$q1 * $q2] p]"
puts "q2 * q1 = [[$q2 * $q1] p]"
puts "q2 * q1 = [[$q2 * $q1] p]"
puts "equal(q1*q2, q2*q1) = [[$q1 * $q2] == [$q2 * $q1]]"</lang>
puts "equal(q1*q2, q2*q1) = [[$q1 * $q2] == [$q2 * $q1]]"</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 7,923: Line 7,923:


=={{header|VBA}}==
=={{header|VBA}}==
<lang vb>Option Base 1
<syntaxhighlight lang="vb">Option Base 1
Private Function norm(q As Variant) As Double
Private Function norm(q As Variant) As Double
norm = Sqr(WorksheetFunction.SumSq(q))
norm = Sqr(WorksheetFunction.SumSq(q))
Line 7,993: Line 7,993:
Debug.Print "q1 * q2 = ";: quats mult(q1, q2)
Debug.Print "q1 * q2 = ";: quats mult(q1, q2)
Debug.Print "q2 * q1 = ";: quats mult(q2, q1)
Debug.Print "q2 * q1 = ";: quats mult(q2, q1)
End Sub</lang>{{out}}
End Sub</syntaxhighlight>{{out}}
<pre>q = 1 + 2i + 3j + 4k
<pre>q = 1 + 2i + 3j + 4k
q1 = 2 + 3i + 4j + 5k
q1 = 2 + 3i + 4j + 5k
Line 8,012: Line 8,012:
{{works with|.NET Core|2.1}}
{{works with|.NET Core|2.1}}


<lang vbnet>Option Compare Binary
<syntaxhighlight lang="vbnet">Option Compare Binary
Option Explicit On
Option Explicit On
Option Infer On
Option Infer On
Line 8,107: Line 8,107:
End Operator
End Operator
#End Region
#End Region
End Structure</lang>
End Structure</syntaxhighlight>


Demonstration:
Demonstration:
<lang vbnet>Module Program
<syntaxhighlight lang="vbnet">Module Program
Sub Main()
Sub Main()
Dim q As New Quaternion(1, 2, 3, 4),
Dim q As New Quaternion(1, 2, 3, 4),
Line 8,134: Line 8,134:
Console.WriteLine($"q1*q2 {If((q1 * q2) = (q2 * q1), "=", "!=")} q2*q1")
Console.WriteLine($"q1*q2 {If((q1 * q2) = (q2 * q1), "=", "!=")} q2*q1")
End Sub
End Sub
End Module</lang>
End Module</syntaxhighlight>


{{out}}
{{out}}
Line 8,155: Line 8,155:


=={{header|Wren}}==
=={{header|Wren}}==
<lang ecmascript>class Quaternion {
<syntaxhighlight lang="ecmascript">class Quaternion {
construct new(a, b, c, d ) {
construct new(a, b, c, d ) {
_a = a
_a = a
Line 8,219: Line 8,219:
System.print("q1q2 = %(q3)")
System.print("q1q2 = %(q3)")
System.print("q2q1 = %(q4)")
System.print("q2q1 = %(q4)")
System.print("q1q2 ≠ q2q1 = %(q3 != q4)")</lang>
System.print("q1q2 ≠ q2q1 = %(q3 != q4)")</syntaxhighlight>


{{out}}
{{out}}
Line 8,242: Line 8,242:


=={{header|XPL0}}==
=={{header|XPL0}}==
<lang XPL0>proc QPrint(Q); \Display quaternion
<syntaxhighlight lang="xpl0">proc QPrint(Q); \Display quaternion
real Q;
real Q;
[RlOut(0, Q(0)); Text(0, " + "); RlOut(0, Q(1)); Text(0, "i + ");
[RlOut(0, Q(0)); Text(0, " + "); RlOut(0, Q(1)); Text(0, "i + ");
Line 8,303: Line 8,303:
Text(0, "q1 * q2 = "); QPrint(QMul (Q0, Q1, Q2));
Text(0, "q1 * q2 = "); QPrint(QMul (Q0, Q1, Q2));
Text(0, "q2 * q1 = "); QPrint(QMul (Q0, Q2, Q1));
Text(0, "q2 * q1 = "); QPrint(QMul (Q0, Q2, Q1));
]</lang>
]</syntaxhighlight>


{{out}}
{{out}}
Line 8,322: Line 8,322:
=={{header|zkl}}==
=={{header|zkl}}==
{{trans|D}}
{{trans|D}}
<lang zkl>class Quat{
<syntaxhighlight lang="zkl">class Quat{
fcn init(real=0,i1=0,i2=0,i3=0){
fcn init(real=0,i1=0,i2=0,i3=0){
var [const] vector= // Quat(r,i,j,k) or Quat( (r,i,j,k) )
var [const] vector= // Quat(r,i,j,k) or Quat( (r,i,j,k) )
Line 8,374: Line 8,374:
(iversor*inorm.sin() + inorm.cos()) * r.exp();
(iversor*inorm.sin() + inorm.cos()) * r.exp();
}
}
}</lang>
}</syntaxhighlight>
<lang zkl> // Demo code
<syntaxhighlight lang="zkl"> // Demo code
r:=7;
r:=7;
q:=Quat(2,3,4,5); q1:=Quat(2,3,4,5); q2:=Quat(3,4,5,6);
q:=Quat(2,3,4,5); q1:=Quat(2,3,4,5); q2:=Quat(3,4,5,6);
Line 8,413: Line 8,413:
println(" s.log(): ", s.log());
println(" s.log(): ", s.log());
println(" s.log().exp(): ", s.log().exp());
println(" s.log().exp(): ", s.log().exp());
println(" s.exp().log(): ", s.exp().log());</lang>
println(" s.exp().log(): ", s.exp().log());</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>