Quaternion type: Difference between revisions
Content added Content deleted
(Added XPL0 example.) |
Thundergnat (talk | contribs) 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}} |
||
< |
<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</ |
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): |
||
< |
<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;</ |
end Quaternions;</syntaxhighlight> |
||
The package implementation: |
The package implementation: |
||
< |
<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;</ |
end Quaternions;</syntaxhighlight> |
||
Test program: |
Test program: |
||
< |
<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;</ |
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'''< |
'''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 #</ |
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)) |
||
)</ |
)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 718: | Line 718: | ||
=={{header|ALGOL W}}== |
=={{header|ALGOL W}}== |
||
< |
<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+) |
||
< |
<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 |
||
}</ |
}</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. |
||
< |
<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</ |
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. |
||
< |
<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$)) + ")"</ |
= LEFT$(LEFT$(a$)) + ")"</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,148: | Line 1,148: | ||
=={{header|C}}== |
=={{header|C}}== |
||
< |
<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]); |
||
}</ |
}</syntaxhighlight> |
||
< |
<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; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C sharp}}== |
=={{header|C sharp}}== |
||
< |
<syntaxhighlight lang="csharp">using System; |
||
struct Quaternion : IEquatable<Quaternion> |
struct Quaternion : IEquatable<Quaternion> |
||
Line 1,429: | Line 1,429: | ||
#endregion |
#endregion |
||
}</ |
}</syntaxhighlight> |
||
Demonstration: |
Demonstration: |
||
< |
<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) ? "==" : "!="); |
||
} |
} |
||
}</ |
}</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. |
||
< |
<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; |
||
}</ |
}</syntaxhighlight> |
||
Test program: |
Test program: |
||
< |
<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; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,683: | Line 1,683: | ||
=={{header|CLU}}== |
=={{header|CLU}}== |
||
< |
<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</ |
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}}== |
||
< |
<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}} |
||
< |
<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)}"</ |
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}}== |
||
< |
<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))); |
||
}</ |
}</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}}== |
||
< |
<syntaxhighlight lang="delphi">unit Quaternions; |
||
interface |
interface |
||
Line 2,390: | Line 2,390: | ||
end; |
end; |
||
end.</ |
end.</syntaxhighlight> |
||
Test program |
Test program |
||
< |
<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.</ |
end.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,449: | Line 2,449: | ||
=={{header|E}}== |
=={{header|E}}== |
||
< |
<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 } |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
< |
<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)</ |
# value: (0 + 3i + 4j + 5k)</syntaxhighlight> |
||
=={{header|Eero}}== |
=={{header|Eero}}== |
||
< |
<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</ |
return 0</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,653: | Line 2,653: | ||
{{trans|C#}} |
{{trans|C#}} |
||
ELENA 5.0 : |
ELENA 5.0 : |
||
< |
<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("==","!=")) |
||
}</ |
}</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}}== |
||
< |
<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))})</ |
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. |
||
< |
<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</ |
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. |
||
< |
<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 |
||
]</ |
]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,055: | Line 3,055: | ||
=={{header|Forth}}== |
=={{header|Forth}}== |
||
< |
<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)</ |
m1 m2 q= . \ 0 (false)</syntaxhighlight> |
||
=={{header|Fortran}}== |
=={{header|Fortran}}== |
||
{{works with|Fortran|90 and later}} |
{{works with|Fortran|90 and later}} |
||
< |
<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</ |
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}}== |
||
< |
<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}}== |
||
< |
<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</ |
# (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. |
||
< |
<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 |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,626: | Line 3,626: | ||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
< |
<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]"</ |
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]]: |
||
< |
<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</ |
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: |
||
< |
<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</ |
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</ |
_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}}== |
||
< |
<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")); |
||
} |
} |
||
}</ |
}</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. |
||
< |
<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; |
||
})();</ |
})();</syntaxhighlight> |
||
Task/Example Usage: |
Task/Example Usage: |
||
< |
<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)");</ |
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< |
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</ |
demo</syntaxhighlight> |
||
Example usage and output: |
Example usage and output: |
||
< |
<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</ |
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. |
||
< |
<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: |
||
< |
<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)</ |
(-56 + 16i + 24j + 26k,-56 + 18i + 20j + 28k,true)</syntaxhighlight> |
||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
< |
<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}") |
||
}</ |
}</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 |
||
</ |
</syntaxhighlight> |
||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
< |
<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</ |
end</syntaxhighlight> |
||
Examples: |
Examples: |
||
< |
<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 )</ |
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}}== |
||
< |
<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>. |
||
< |
<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 ).</ |
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. |
||
< |
<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.</ |
:- 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. |
||
< |
<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</ |
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: |
||
< |
<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): |
||
< |
<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</ |
<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</ |
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). |
||
< |
<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 * + ) ;</ |
q _a @d * q _b @c * + q _c @b * - q _d @a * + ) ;</syntaxhighlight> |
||
Usage : |
Usage : |
||
< |
<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 ] ;</ |
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. |
||
< |
<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: | ||
) |
) |
||
) |
) |
||
};</ |
};</syntaxhighlight> |
||
Usage: |
Usage: |
||
< |
<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)</ |
q1.mult(q2) != q2.mult(q1)</syntaxhighlight> |
||
=={{header|Pascal}}== |
=={{header|Pascal}}== |
||
Line 5,675: | Line 5,675: | ||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
< |
<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";</ |
print "b * a = ", $b * $a, "\n";</syntaxhighlight> |
||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
<!--< |
<!--<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> |
||
<!--</ |
<!--</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>. |
||
< |
<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.</ |
test.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 5,917: | Line 5,917: | ||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
< |
<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") ) )</ |
'(" + " "i + " "j + " "k") ) )</syntaxhighlight> |
||
Test: |
Test: |
||
< |
<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"))</ |
(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}}== |
||
< |
<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;</ |
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}}== |
||
< |
<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.</ |
I is -Ii, J is -Ji, K is -Ki.</syntaxhighlight> |
||
'''Test:''' |
'''Test:''' |
||
< |
<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.</ |
test.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> ?- test. |
<pre> ?- test. |
||
Line 6,333: | Line 6,333: | ||
=={{header|PureBasic}}== |
=={{header|PureBasic}}== |
||
< |
<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</ |
EndProcedure</syntaxhighlight> |
||
Implementation & test |
Implementation & test |
||
< |
<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</ |
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. |
||
< |
<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</ |
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: |
||
< |
<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) |
||
>>> </ |
>>> </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}}== |
||
< |
<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)))</ |
(multiply q2 q1)))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 6,754: | Line 6,754: | ||
=={{header|Raku}}== |
=={{header|Raku}}== |
||
(formerly Perl 6) |
(formerly Perl 6) |
||
<lang |
<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";</ |
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. |
||
< |
<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 */</ |
numeric digits d; return (g/1)i /*make complex if X<0 */</syntaxhighlight> |
||
{{out|output|text= when using the internal default inputs:}} |
{{out|output|text= when using the internal default inputs:}} |
||
<pre> |
<pre> |
||
Line 6,971: | Line 6,971: | ||
{{works with|Ruby|1.9}} |
{{works with|Ruby|1.9}} |
||
< |
<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</ |
end</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 7,071: | Line 7,071: | ||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
< |
<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()); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 7,276: | Line 7,276: | ||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
< |
<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) |
||
}</ |
}</syntaxhighlight> |
||
Demonstration: |
Demonstration: |
||
< |
<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)</ |
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}}== |
||
< |
<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;</ |
end func;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 7,574: | Line 7,574: | ||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
{{trans|Raku}} |
{{trans|Raku}} |
||
< |
<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"</ |
say "8) q1q2 #{ q1*q2 == q2*q1 ? '==' : '!=' } q2q1"</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 7,626: | Line 7,626: | ||
=={{header|Swift}}== |
=={{header|Swift}}== |
||
< |
<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) |
||
""")</ |
""")</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}} |
||
< |
<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 - + * == |
||
}</ |
}</syntaxhighlight> |
||
Demonstration code: |
Demonstration code: |
||
< |
<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]]"</ |
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}}== |
||
< |
<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</ |
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}} |
||
< |
<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</ |
End Structure</syntaxhighlight> |
||
Demonstration: |
Demonstration: |
||
< |
<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</ |
End Module</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 8,155: | Line 8,155: | ||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
< |
<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)")</ |
System.print("q1q2 ≠ q2q1 = %(q3 != q4)")</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 8,242: | Line 8,242: | ||
=={{header|XPL0}}== |
=={{header|XPL0}}== |
||
< |
<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)); |
||
]</ |
]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 8,322: | Line 8,322: | ||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
{{trans|D}} |
{{trans|D}} |
||
< |
<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(); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
< |
<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());</ |
println(" s.exp().log(): ", s.exp().log());</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |