Matrix-exponentiation operator: Difference between revisions

m
(→‎{{header|rust}}: Rust version.)
m (→‎{{header|Wren}}: Minor tidy)
 
(33 intermediate revisions by 22 users not shown)
Line 1:
{{task|Matrices}}
{{task|Matrices}}Most programming languages have a built-in implementation of exponentiation for integers and reals only.
 
Most programming languages have a built-in implementation of exponentiation for integers and reals only.
 
;Task:
Demonstrate how to implement matrix exponentiation as an operator.
<br><br>
{{Omit From|Java}}
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">F matrix_mul(m1, m2)
assert(m1[0].len == m2.len)
V r = [[0] * m2[0].len] * m1.len
L(j) 0 .< m1.len
L(i) 0 .< m2[0].len
V s = 0
L(k) 0 .< m2.len
s += m1[j][k] * m2[k][i]
r[j][i] = s
R r
 
F identity(size)
V rsize = 0 .< size
R rsize.map(j -> @rsize.map(i -> Int(i == @j)))
 
F matrixExp(m, pow)
assert(pow >= 0 & Int(pow) == pow, ‘Only non-negative, integer powers allowed’)
V accumulator = identity(m.len)
L(i) 0 .< pow
accumulator = matrix_mul(accumulator, m)
R accumulator
 
F printtable(data)
L(row) data
print(row.map(cell -> ‘#<5’.format(cell)).join(‘ ’))
 
V m = [[3, 2], [2, 1]]
L(i) 5
print("\n#.:".format(i))
printtable(matrixExp(m, i))
 
print("\n10:")
printtable(matrixExp(m, 10))</syntaxhighlight>
 
{{out}}
<pre>
 
0:
1 0
0 1
 
1:
3 2
2 1
 
2:
13 8
8 5
 
3:
55 34
34 21
 
4:
233 144
144 89
 
10:
1346269 832040
832040 514229
</pre>
 
=={{header|Ada}}==
This is a generic solution for any natural power exponent. It will work with any type that has +,*, additive and multiplicative 0s. The implementation factors out powers A<sup>2<sup>n</sup></sup>:
<langsyntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO;
procedure Test_Matrix is
Line 93 ⟶ 164:
Put_Line ("M**10 ="); Put (M**10);
Put_Line ("M*M*M*M*M*M*M*M*M*M ="); Put (M*M*M*M*M*M*M*M*M*M);
end Test_Matrix;</langsyntaxhighlight>
Sample output:
<pre>
Line 131 ⟶ 202:
</pre>
The following program implements exponentiation of a square Hermitian complex matrix by any complex power. The limitation to be Hermitian is not essential and comes for the limitation of the standard Ada linear algebra library.
<langsyntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO;
with Ada.Complex_Text_IO; use Ada.Complex_Text_IO;
with Ada.Numerics.Complex_Types; use Ada.Numerics.Complex_Types;
Line 155 ⟶ 226:
begin
for K in RL'Range (1) loop
Sum := Sum + X (KI, IK) * RL (K) * X (KJ, JK);
end loop;
R (I, J) := Sum;
Line 166 ⟶ 237:
begin
for I in A'Range (1) loop
for J in A'Range (12) loop
Put (A (I, J));
end loop;
Line 178 ⟶ 249:
Put_Line ("M**1 ="); Put (M**(1.0,0.0));
Put_Line ("M**0.5 ="); Put (M**(0.5,0.0));
end Test_Matrix;</langsyntaxhighlight>
This solution is not tested, because the available version of GNAT GPL Ada compiler (20070405-41) does not provide an implementation of the standard library.
 
''(Another person is talking here:)'' I have made small corrections and tested this in 2023, and it did not work as I expected. However, I have questions about the mathematical libraries. I tried both GCC 12 and GCC 13. (I also tried the last GNAT Community Edition, but it no longer functions on my system.) What might be needed here is one's own eigensystem routine.
 
On the other hand, I did get a version working to raise a real matrix to a natural number power, thus demonstrating the correctness of the approach:
<syntaxhighlight lang="ada">
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Float_Text_IO; use Ada.Float_Text_IO;
with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays;
 
procedure Test_Matrix is
procedure Put (A : Real_Matrix) is
begin
for I in A'Range (1) loop
for J in A'Range (2) loop
Put (" ");
Put (A (I, J));
end loop;
New_Line;
end loop;
end Put;
function "**" (A : Real_Matrix; Power : Integer) return Real_Matrix is
L : Real_Vector (A'Range (1));
X : Real_Matrix (A'Range (1), A'Range (2));
R : Real_Matrix (A'Range (1), A'Range (2));
RL : Real_Vector (A'Range (1));
begin
Eigensystem (A, L, X);
for I in L'Range loop
RL (I) := L (I) ** Power;
end loop;
for I in R'Range (1) loop
for J in R'Range (2) loop
declare
Sum : Float := 0.0;
begin
for K in RL'Range loop
Sum := Sum + X (I, K) * RL (K) * X (J, K);
end loop;
R (I, J) := Sum;
end;
end loop;
end loop;
return R;
end "**";
M : Real_Matrix (1..2, 1..2) := ((3.0, 2.0), (2.0, 1.0));
begin
Put_Line ("M ="); Put (M);
Put_Line ("M**0 ="); Put (M**0);
Put_Line ("M**1 ="); Put (M**1);
Put_Line ("M**2 ="); Put (M**2);
Put_Line ("M**3 ="); Put (M**3);
Put_Line ("M**50 ="); Put (M**50);
end Test_Matrix;
</syntaxhighlight>
{{out}}
<pre>
M =
3.00000E+00 2.00000E+00
2.00000E+00 1.00000E+00
M**0 =
1.00000E+00 0.00000E+00
0.00000E+00 1.00000E+00
M**1 =
3.00000E+00 2.00000E+00
2.00000E+00 1.00000E+00
M**2 =
1.30000E+01 8.00000E+00
8.00000E+00 5.00000E+00
M**3 =
5.50000E+01 3.40000E+01
3.40000E+01 2.10000E+01
M**50 =
1.61305E+31 9.96919E+30
9.96919E+30 6.16130E+30
</pre>
 
=={{header|ALGOL 68}}==
Line 186 ⟶ 332:
{{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: Matrix_algebra.a68'''
<langsyntaxhighlight lang="algol68">INT default upb=3;
MODE VEC = [default upb]COSCAL;
MODE MAT = [default upb,default upb]COSCAL;
Line 216 ⟶ 362:
OD;
out
);</langsyntaxhighlight>'''File: Matrix-exponentiation_operator.a68'''
<langsyntaxhighlight lang="algol68">OP ** = (MAT base, INT exponent)MAT: (
BITS binary exponent:=BIN exponent ;
MAT out := IF bits width ELEM binary exponent THEN base ELSE IDENTITY UPB base FI;
Line 230 ⟶ 376:
OD;
out
);</langsyntaxhighlight>'''File: test_Matrix-exponentiation_operator.a68'''
<langsyntaxhighlight lang="algol68">#!/usr/local/bin/a68g --script #
 
MODE COSCAL = COMPL;
Line 254 ⟶ 400:
printf(($" mat ** "g(0)":"l$,24));
compl mat printf(scal fmt, mat**24);
print(newline)</langsyntaxhighlight>
Output:
<pre>
Line 261 ⟶ 407:
( 0.0000+0.0000i, 1.0000+0.0000i, 0.0000+0.0000i),
( 0.0000+0.0000i, 0.0000+0.0000i, 1.0000+0.0000i));
</pre>
 
=={{header|ATS}}==
 
<syntaxhighlight lang="ats">
(* I will write a GENERAL template for raising something to a
non-negative integer power, and then apply that template to matrix
multiplication. *)
 
#include "share/atspre_staload.hats"
 
(*------------------------------------------------------------------*)
(* The interface. *)
 
extern fn {a : t@ype} nonnegative_integer_power : (a, intGte 0) -> a
extern fn {a : t@ype} zeroth_power : () -> a
extern fn {a : t@ype} product : (a, a) -> a
 
(*------------------------------------------------------------------*)
(* The implementation of "nonnegative_integer_power". *)
 
(* I use the squaring method. See
https://en.wikipedia.org/w/index.php?title=Exponentiation_by_squaring&oldid=1144956501
*)
 
implement {a}
nonnegative_integer_power (M, i) =
let
fun
repeat {i : nat} (* <-- This number consistently shrinks. *)
.<i>. (* <-- Proof the recursion will terminate. *)
(Accum : a, (* "Accumulator" *)
Base : a,
i : int i)
: a =
if i = 0 then
Accum
else
let
val i_halved = half i (* Integer division. *)
and Base_squared = product<a> (Base, Base)
in
if i_halved + i_halved = i then
repeat (Accum, Base_squared, i_halved)
else
repeat (product<a> (Base, Accum), Base_squared, i_halved)
end
in
repeat (zeroth_power<a> (), M, i)
end
 
(*------------------------------------------------------------------*)
(* Application of nonnegative_integer_power to mtrxszref. *)
 
fn {tk : tkind}
npow_mtrxszref (M : mtrxszref (g0float tk),
p : intGte 0)
: mtrxszref (g0float tk) =
let
typedef a = g0float tk
 
val n = mtrxszref_get_nrow M
val () =
if mtrxszref_get_ncol M <> n then
$raise IllegalArgExn ("npow_mtrxszref:matrix_not_square")
 
implement
zeroth_power<mtrxszref a> () =
(* Return an n-by-n identity matrix. *)
let
val I = mtrxszref_make_elt<a> (n, n, g0i2f 0)
var k : Size_t
in
for (k := i2sz 0; k <> n; k := succ k)
I[k, k] := g0i2f 1;
I
end
 
implement
product<mtrxszref a> (A, B) =
(* Return the matrix product of A and B. *)
let
val C = mtrxszref_make_elt<a> (n, n, g0i2f 0)
var i : Size_t
in
for (i := i2sz 0; i <> n; i := succ i)
let
var j : Size_t
in
for (j := i2sz 0; j <> n; j := succ j)
let
var k : Size_t
in
for (k := i2sz 0; k <> n; k := succ k)
C[i, j] := C[i, j] + (A[i, k] * B[k, j])
end
end;
C
end
in
nonnegative_integer_power<mtrxszref a> (M, p)
end
 
overload ** with npow_mtrxszref
 
(*------------------------------------------------------------------*)
 
implement
main0 () =
let
(* This matrix is borrowed from the entry for the programming
language Chapel:
1 2 0
0 3 1
1 0 0
 
*)
val A = mtrxszref_make_elt (i2sz 3, i2sz 3, 0.0)
val () = A[0, 0] := 1.0
val () = A[0, 1] := 2.0
val () = A[1, 1] := 3.0
val () = A[1, 2] := 1.0
val () = A[2, 0] := 1.0
 
var p : intGte 0
in
for (p := 0; p <> 11; p := succ p)
let
val B = A ** p
in
fprint_val<string> (stdout_ref, "power = ");
fprint_val<int> (stdout_ref, p);
fprint_val<string> (stdout_ref, "\n");
fprint_mtrxszref_sep<double> (stdout_ref, B, "\t", "\n");
fprint_val<string> (stdout_ref, "\n\n")
end
end
 
(*------------------------------------------------------------------*)
</syntaxhighlight>
 
{{out}}
<pre>$ patscc -std=gnu2x -g -O2 -DATS_MEMALLOC_GCBDW matrix_exponentiation_task.dats -lgc && ./a.out
power = 0
1.000000 0.000000 0.000000
0.000000 1.000000 0.000000
0.000000 0.000000 1.000000
 
power = 1
1.000000 2.000000 0.000000
0.000000 3.000000 1.000000
1.000000 0.000000 0.000000
 
power = 2
1.000000 8.000000 2.000000
1.000000 9.000000 3.000000
1.000000 2.000000 0.000000
 
power = 3
3.000000 26.000000 8.000000
4.000000 29.000000 9.000000
1.000000 8.000000 2.000000
 
power = 4
11.000000 84.000000 26.000000
13.000000 95.000000 29.000000
3.000000 26.000000 8.000000
 
power = 5
37.000000 274.000000 84.000000
42.000000 311.000000 95.000000
11.000000 84.000000 26.000000
 
power = 6
121.000000 896.000000 274.000000
137.000000 1017.000000 311.000000
37.000000 274.000000 84.000000
 
power = 7
395.000000 2930.000000 896.000000
448.000000 3325.000000 1017.000000
121.000000 896.000000 274.000000
 
power = 8
1291.000000 9580.000000 2930.000000
1465.000000 10871.000000 3325.000000
395.000000 2930.000000 896.000000
 
power = 9
4221.000000 31322.000000 9580.000000
4790.000000 35543.000000 10871.000000
1291.000000 9580.000000 2930.000000
 
power = 10
13801.000000 102408.000000 31322.000000
15661.000000 116209.000000 35543.000000
4221.000000 31322.000000 9580.000000
</pre>
 
=={{header|BBC BASIC}}==
<langsyntaxhighlight lang="bbcbasic"> DIM matrix(1,1), output(1,1)
matrix() = 3, 2, 2, 1
Line 288 ⟶ 632:
NEXT
ENDIF
ENDPROC</langsyntaxhighlight>
Output:
<pre>
Line 322 ⟶ 666:
196418 121393
</pre>
 
=={{header|BQN}}==
 
Matrix multiplication is a known idiom taken from BQN crate. Matrix exponentiation is simply doing Matrix multiplication n times.
<syntaxhighlight lang="bqn">MatMul ← +˝∘×⎉1‿∞
 
MatEx ← {𝕨 MatMul⍟(𝕩-1) 𝕨}
 
(>⟨3‿2
2‿1⟩) MatEx 1‿2‿3‿4‿10</syntaxhighlight><syntaxhighlight lang="bqn">┌─
· ┌─ ┌─ ┌─ ┌─ ┌─
╵ 3 2 ╵ 13 8 ╵ 55 34 ╵ 233 144 ╵ 1346269 832040
2 1 8 5 34 21 144 89 832040 514229
┘ ┘ ┘ ┘ ┘
┘</syntaxhighlight>
 
For larger exponents it's more efficient to use a fast exponentiation pattern that builds large powers quickly with repeated squaring, then multiplies the appropriate power-of-two exponents together.
 
<syntaxhighlight lang="bqn">MatEx ← MatMul{𝔽´𝔽˜⍟(/2|⌊∘÷⟜2⍟(↕1+·⌊2⋆⁼⊢)𝕩)𝕨}</syntaxhighlight>
 
=={{header|Burlesque}}==
<langsyntaxhighlight lang="burlesque">blsq ) {{1 1} {1 0}} 10 .*{mm}r[
{{89 55} {55 34}}</langsyntaxhighlight>
 
=={{header|C}}==
C doesn't support classes or allow operator overloading. The following is code that defines a function, <tt>SquareMtxPower</tt> that will raise a matrix to a positive integer power.
<langsyntaxhighlight lang="c">#include <math.h>
#include <stdio.h>
#include <stdlib.h>
Line 512 ⟶ 875:
 
return 0;
}</langsyntaxhighlight>
Output:
<pre>m0 dim:3 =
Line 534 ⟶ 897:
| 0.00000 0.00000 1.00000 |
</pre>
 
=={{header|C sharp}}==
<syntaxhighlight lang="csharp">using System;
using System.Collections;
using System.Collections.Generic;
using static System.Linq.Enumerable;
 
public static class MatrixExponentation
{
public static double[,] Identity(int size) {
double[,] matrix = new double[size, size];
for (int i = 0; i < size; i++) matrix[i, i] = 1;
return matrix;
}
 
public static double[,] Multiply(this double[,] left, double[,] right) {
if (left.ColumnCount() != right.RowCount()) throw new ArgumentException();
double[,] m = new double[left.RowCount(), right.ColumnCount()];
foreach (var (row, column) in from r in Range(0, m.RowCount()) from c in Range(0, m.ColumnCount()) select (r, c)) {
m[row, column] = Range(0, m.RowCount()).Sum(i => left[row, i] * right[i, column]);
}
return m;
}
 
public static double[,] Pow(this double[,] matrix, int exp) {
if (matrix.RowCount() != matrix.ColumnCount()) throw new ArgumentException("Matrix must be square.");
double[,] accumulator = Identity(matrix.RowCount());
for (int i = 0; i < exp; i++) {
accumulator = accumulator.Multiply(matrix);
}
return accumulator;
}
 
private static int RowCount(this double[,] matrix) => matrix.GetLength(0);
private static int ColumnCount(this double[,] matrix) => matrix.GetLength(1);
 
private static void Print(this double[,] m) {
foreach (var row in Rows()) {
Console.WriteLine("[ " + string.Join(" ", row) + " ]");
}
Console.WriteLine();
 
IEnumerable<IEnumerable<double>> Rows() =>
Range(0, m.RowCount()).Select(row => Range(0, m.ColumnCount()).Select(column => m[row, column]));
}
 
public static void Main() {
var matrix = new double[,] {
{ 3, 2 },
{ 2, 1 }
};
matrix.Pow(0).Print();
matrix.Pow(1).Print();
matrix.Pow(2).Print();
matrix.Pow(3).Print();
matrix.Pow(4).Print();
matrix.Pow(50).Print();
}
 
}</syntaxhighlight>
{{out}}
<pre style="height:30ex;overflow:scroll">
[ 1 0 ]
[ 0 1 ]
 
[ 3 2 ]
[ 2 1 ]
 
[ 13 8 ]
[ 8 5 ]
 
[ 55 34 ]
[ 34 21 ]
 
[ 233 144 ]
[ 144 89 ]
 
[ 1.61305314249046E+31 9.9692166771893E+30 ]
[ 9.9692166771893E+30 6.16131474771528E+30 ]</pre>
 
=={{header|C++}}==
This is an implementation in C++.
<langsyntaxhighlight lang="cpp">#include <complex>
#include <cmath>
#include <iostream>
Line 570 ⟶ 1,013:
for (int i = 0; i < MSize; i++) {
for (int j = 0; j < MSize; j++)
os << p.a[i][j] << "',"';
os << endl;
}
Line 585 ⟶ 1,028:
}
return d;
}</langsyntaxhighlight>
This is the task part.
<langsyntaxhighlight lang="cpp"> // C++ does not have a ** operator, instead, ^ (bitwise Xor) is used.
Mx operator^(int n) {
if (n < 0)
Line 605 ⟶ 1,048:
int main() {
double q = sqrt(0.5);
creal array[3][3] = { { { q, 0 }, { q, 0 }, { 0, 0 } },
{ {creal( 0, -q }, { 0), creal(q, 0)}, creal({ 0, 0) } },
{creal( { 0, -q), creal(0, q)}, creal({ 0, 0) }, { 0, 1 } } };
{creal(0, 0), creal(0, 0), creal(0, 1)}};
M3 m(array);
 
Line 615 ⟶ 1,057:
 
return 0;
}</langsyntaxhighlight>
{{out}}
Output:
<pre>
m ^ 23=
Line 626 ⟶ 1,068:
An alternative way would be to implement <tt>operator*=</tt> and conversion from number (giving multiples of the identity matrix) for the matrix and use the generic code from [[Exponentiation operator#C++]] with support for negative exponents removed (or alternatively, implement matrix inversion as well, implement /= in terms of it, and use the generic code unchanged). Note that the algorithm used there is much faster as well.
 
=={{header|C sharpChapel}}==
<lang csharp>using System;
using System.Collections;
using System.Collections.Generic;
using static System.Linq.Enumerable;
 
This uses the '*' operator for arrays as defined in [[Matrix_multiplication#Chapel]]
public static class MatrixExponentation
<syntaxhighlight lang="chapel">proc **(a, e) {
{
// create result matrix of same dimensions
public static double[,] Identity(int size) {
var r:[a.domain] a.eltType;
double[,] matrix = new double[size, size];
// and initialize to for (int i = 0; i < size; i++)identity matrix[i, i] = 1;
forall ij in r.domain do
return matrix;
r(ij) = if ij(1) == ij(2) then 1 else 0;
}
 
for 1..e do
public static double[,] Multiply(this double[,] left, double[,] right) {
r *= a;
if (left.ColumnCount() != right.RowCount()) throw new ArgumentException();
double[,] m = new double[left.RowCount(), right.ColumnCount()];
foreach (var (row, column) in from r in Range(0, m.RowCount()) from c in Range(0, m.ColumnCount()) select (r, c)) {
m[row, column] = Range(0, m.RowCount()).Sum(i => left[row, i] * right[i, column]);
}
return m;
}
 
return r;
public static double[,] Pow(this double[,] matrix, int exp) {
}</syntaxhighlight>
if (matrix.RowCount() != matrix.ColumnCount()) throw new ArgumentException("Matrix must be square.");
double[,] accumulator = Identity(matrix.RowCount());
for (int i = 0; i < exp; i++) {
accumulator = accumulator.Multiply(matrix);
}
return accumulator;
}
 
Usage example (like Perl):
private static int RowCount(this double[,] matrix) => matrix.GetLength(0);
<syntaxhighlight lang="chapel">var m:[1..3, 1..3] int;
private static int ColumnCount(this double[,] matrix) => matrix.GetLength(1);
m(1,1) = 1; m(1,2) = 2; m(1,3) = 0;
m(2,1) = 0; m(2,2) = 3; m(2,3) = 1;
m(3,1) = 1; m(3,2) = 0; m(3,3) = 0;
 
config param n = 10;
private static void Print(this double[,] m) {
foreach (var row in Rows()) {
Console.WriteLine("[ " + string.Join(" ", row) + " ]");
}
Console.WriteLine();
 
for i in 0..n do {
IEnumerable<IEnumerable<double>> Rows() =>
writeln("Order ", i);
Range(0, m.RowCount()).Select(row => Range(0, m.ColumnCount()).Select(column => m[row, column]));
writeln(m ** i, "\n");
}
}</syntaxhighlight>
 
public static void Main() {
var matrix = new double[,] {
{ 3, 2 },
{ 2, 1 }
};
matrix.Pow(0).Print();
matrix.Pow(1).Print();
matrix.Pow(2).Print();
matrix.Pow(3).Print();
matrix.Pow(4).Print();
matrix.Pow(50).Print();
}
 
}</lang>
{{out}}
Order 0
<pre style="height:30ex;overflow:scroll">
[ 1 0 0 ]
[ 0 1 ]0
0 0 1
 
[ 3 2 ]
Order 1
[ 2 1 ]
1 2 0
 
0 3 1
[ 13 8 ]
1 0 0
[ 8 5 ]
 
Order 2
[ 55 34 ]
1 8 2
[ 34 21 ]
1 9 3
 
1 2 0
[ 233 144 ]
[ 144 89 ]
Order 3
 
3 26 8
[ 1.61305314249046E+31 9.9692166771893E+30 ]
4 29 9
[ 9.9692166771893E+30 6.16131474771528E+30 ]</pre>
1 8 2
Order 4
11 84 26
13 95 29
3 26 8
Order 5
37 274 84
42 311 95
11 84 26
Order 6
121 896 274
137 1017 311
37 274 84
Order 7
395 2930 896
448 3325 1017
121 896 274
Order 8
1291 9580 2930
1465 10871 3325
395 2930 896
Order 9
4221 31322 9580
4790 35543 10871
1291 9580 2930
Order 10
13801 102408 31322
15661 116209 35543
4221 31322 9580
 
=={{header|Common Lisp}}==
This Common Lisp implementation uses 2D Arrays to represent matrices, and checks to make sure that the arrays are the right dimensions for multiplication and square for exponentiation.
<langsyntaxhighlight lang="lisp">(defun multiply-matrices (matrix-0 matrix-1)
"Takes two 2D arrays and returns their product, or an error if they cannot be multiplied"
(let* ((m0-dims (array-dimensions matrix-0))
Line 766 ⟶ 1,213:
(multiply-matrices me2 me2)))
(t (let ((me2 (matrix-expt matrix (/ (1- exp) 2))))
(multiply-matrices matrix (multiply-matrices me2 me2)))))))</langsyntaxhighlight>
Output (note that this lisp implementation uses single-precision floats for decimals by default). We can also use rationals:
CL-USER> (setf 5x5-matrix
Line 800 ⟶ 1,247:
(-5315/9 66493/45 90883/135 -54445/36)
(37033/144 -27374/45 -15515/54 12109/18))
 
=={{header|Chapel}}==
 
This uses the '*' operator for arrays as defined in [[Matrix_multiplication#Chapel]]
<lang chapel>proc **(a, e) {
// create result matrix of same dimensions
var r:[a.domain] a.eltType;
// and initialize to identity matrix
forall ij in r.domain do
r(ij) = if ij(1) == ij(2) then 1 else 0;
 
for 1..e do
r *= a;
 
return r;
}</lang>
 
Usage example (like Perl):
<lang chapel>var m:[1..3, 1..3] int;
m(1,1) = 1; m(1,2) = 2; m(1,3) = 0;
m(2,1) = 0; m(2,2) = 3; m(2,3) = 1;
m(3,1) = 1; m(3,2) = 0; m(3,3) = 0;
 
config param n = 10;
 
for i in 0..n do {
writeln("Order ", i);
writeln(m ** i, "\n");
}</lang>
 
{{out}}
Order 0
1 0 0
0 1 0
0 0 1
Order 1
1 2 0
0 3 1
1 0 0
Order 2
1 8 2
1 9 3
1 2 0
Order 3
3 26 8
4 29 9
1 8 2
Order 4
11 84 26
13 95 29
3 26 8
Order 5
37 274 84
42 311 95
11 84 26
Order 6
121 896 274
137 1017 311
37 274 84
Order 7
395 2930 896
448 3325 1017
121 896 274
Order 8
1291 9580 2930
1465 10871 3325
395 2930 896
Order 9
4221 31322 9580
4790 35543 10871
1291 9580 2930
Order 10
13801 102408 31322
15661 116209 35543
4221 31322 9580
 
=={{header|D}}==
<langsyntaxhighlight lang="d">import std.stdio, std.string, std.math, std.array, std.algorithm;
 
struct SquareMat(T = creal) {
Line 961 ⟶ 1,323:
foreach (immutable p; [0, 1, 23, 24])
writefln("m ^^ %d =\n%s", p, m ^^ p);
}</langsyntaxhighlight>
{{out}}
<pre>m ^^ 0 =
Line 979 ⟶ 1,341:
0.00+ 0.00i, 1.00+ 0.00i, 0.00+ 0.00i
0.00+ 0.00i, 0.00+ 0.00i, 1.00+ 0.00i></pre>
 
=={{header|Delphi}}==
<syntaxhighlight lang="delphi">
program Matrix_exponentiation_operator;
 
{$APPTYPE CONSOLE}
 
{$R *.res}
 
uses
System.SysUtils;
 
type
TCells = array of array of double;
 
TMatrix = record
private
FCells: TCells;
function GetCells(r, c: Integer): Double;
procedure SetCells(r, c: Integer; const Value: Double);
class operator Implicit(a: TMatrix): string;
class operator BitwiseXor(a: TMatrix; e: Integer): TMatrix;
class operator Multiply(a: TMatrix; b: TMatrix): TMatrix;
public
constructor Create(w, h: integer); overload;
constructor Create(c: TCells); overload;
constructor Ident(size: Integer);
function Rows: Integer;
function Columns: Integer;
property Cells[r, c: Integer]: Double read GetCells write SetCells; default;
end;
 
{ TMatrix }
 
constructor TMatrix.Create(c: TCells);
begin
Create(Length(c), Length(c[0]));
FCells := c;
end;
 
constructor TMatrix.Create(w, h: integer);
begin
SetLength(FCells, w, h);
end;
 
class operator TMatrix.BitwiseXor(a: TMatrix; e: Integer): TMatrix;
begin
if e < 0 then
raise Exception.Create('Matrix inversion not implemented');
 
Result.Ident(a.Rows);
while e > 0 do
begin
Result := Result * a;
dec(e);
end;
end;
 
function TMatrix.Rows: Integer;
begin
Result := Length(FCells);
end;
 
function TMatrix.Columns: Integer;
begin
Result := 0;
if Rows > 0 then
Result := Length(FCells);
end;
 
function TMatrix.GetCells(r, c: Integer): Double;
begin
Result := FCells[r, c];
end;
 
constructor TMatrix.Ident(size: Integer);
var
i: Integer;
begin
Create(size, size);
 
for i := 0 to size - 1 do
Cells[i, i] := 1;
end;
 
class operator TMatrix.Implicit(a: TMatrix): string;
var
i, j: Integer;
begin
Result := '[';
if a.Rows > 0 then
for i := 0 to a.Rows - 1 do
begin
if i > 0 then
Result := Trim(Result) + ']'#10'[';
for j := 0 to a.Columns - 1 do
begin
Result := Result + Format('%f', [a[i, j]]) + ' ';
end;
end;
Result := trim(Result) + ']';
end;
 
class operator TMatrix.Multiply(a, b: TMatrix): TMatrix;
var
size: Integer;
r: Integer;
c: Integer;
k: Integer;
begin
if (a.Rows <> b.Rows) or (a.Columns <> b.Columns) then
raise Exception.Create('The matrix must have same size');
 
size := a.Rows;
Result.Create(size, size);
 
for r := 0 to size - 1 do
for c := 0 to size - 1 do
begin
Result[r, c] := 0;
for k := 0 to size - 1 do
Result[r, c] := Result[r, c] + a[r, k] * b[k, c];
end;
end;
 
procedure TMatrix.SetCells(r, c: Integer; const Value: Double);
begin
FCells[r, c] := Value;
end;
 
var
M: TMatrix;
 
begin
M.Create([[3, 2], [2, 1]]);
// Delphi don't have a ** and can't override ^ operator, then XOR operator was used
Writeln(string(M xor 0), #10);
Writeln(string(M xor 1), #10);
Writeln(string(M xor 2), #10);
Writeln(string(M xor 3), #10);
Writeln(string(M xor 4), #10);
Writeln(string(M xor 50), #10);
Readln;
end.
</syntaxhighlight>
{{out}}
<pre>
[1,00 0,00]
[0,00 1,00]
 
[3,00 2,00]
[2,00 1,00]
 
[13,00 8,00]
[8,00 5,00]
 
[55,00 34,00]
[34,00 21,00]
 
[233,00 144,00]
[144,00 89,00]
 
[1,61305314249045832E31 9,96921667718930453E30]
[9,96921667718930115E30 6,16131474771527643E30]
</pre>
 
 
=={{header|ERRE}}==
Line 986 ⟶ 1,514:
| 2 1 |
</pre>
<langsyntaxhighlight ERRElang="erre">PROGRAM MAT_PROD
 
!$MATRIX
Line 1,038 ⟶ 1,566:
END FOR
 
END PROGRAM</langsyntaxhighlight>
Sample output:
<pre>
Line 1,048 ⟶ 1,576:
There is already a built-in word (<code>m^n</code>) that implements exponentiation. Here is a simple and less efficient implementation.
 
<langsyntaxhighlight lang="factor">USING: kernel math math.matrices sequences ;
 
: my-m^n ( m n -- m' )
Line 1,054 ⟶ 1,582:
[ drop length identity-matrix ]
[ swap '[ _ m. ] times ] 2bi
] if ;</langsyntaxhighlight>
 
( scratchpad ) { { 3 2 } { 2 1 } } 0 my-m^n .
Line 1,060 ⟶ 1,588:
( scratchpad ) { { 3 2 } { 2 1 } } 4 my-m^n .
{ { 233 144 } { 144 89 } }
 
=={{header|Fermat}}==
Matrix exponentiation for square matrices and integer powers is built in.
<syntaxhighlight lang="fermat">
Array a[2,2]; {illustrate with a 2x2 matrix}
[a]:=[(2/3, 1/3, 4/5, 1/5)];
[a]^-1; {matrix inverse}
[a]^0; {identity matrix}
[a]^2;
[a]^3;
[a]^10;
</syntaxhighlight>
{{out}}
<pre>
[[ -3 / 2, 6, `
5 / 2, -5 ]]
 
[[ 1, 0, `
0, 1 ]]
 
[[ 32 / 45, 52 / 75, `
13 / 45, 23 / 75 ]]
 
[[ 476 / 675, 796 / 1125, `
199 / 675, 329 / 1125 ]]
 
[[ 81409466972 / 115330078125, 135682444612 / 192216796875, `
33920611153 / 115330078125, 56534352263 / 192216796875 ]]</pre>
 
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
<langsyntaxhighlight lang="fortran">module matmod
implicit none
Line 1,115 ⟶ 1,671:
end do
 
end program Matrix_exponentiation</langsyntaxhighlight>
Output
<pre> 1.00000 0.00000 0.00000
Line 1,136 ⟶ 1,692:
17118.0 21033.0 24948.0
26676.0 32778.0 38880.0</pre>
 
=={{header|FreeBASIC}}==
The include statements incorporate the code from [[Matrix multiplication#FreeBASIC]], which defines the Matrix type and the matrix multiplication operator, [[Reduced row echelon form#FreeBASIC]] which contains a function for getting a matrix into row-echelon form, and [[Gauss-Jordan matrix inversion#FreeBASIC]] which gives the inverse of a matrix. Make sure to remove all the print statements first though.
 
This operator performs M^n for any square invertible matrix M and integer n, including negative powers.
 
<syntaxhighlight lang="freebasic">#include once "matmult.bas"
#include once "rowech.bas"
#include once "matinv.bas"
 
operator ^ (byval M as Matrix, byval n as integer ) as Matrix
dim as uinteger i, j, k = ubound( M.m, 1 )
if n < 0 then return matinv(M) ^ (-n)
if n = 0 then return M * matinv(M)
return (M ^ (n-1)) * M
end operator
 
dim as Matrix M = Matrix(2,2), Q
dim as integer i, j, n
M.m(0,0) = 1./3 : M.m(0,1) = 2./3
M.m(1,0) = 2./7 : M.m(1,1) = 5./7
 
for n = -2 to 4
Q = (M ^ n)
for i = 0 to 1
for j = 0 to 1
print Q.m(i, j),
next j
print
next i
print
next n</syntaxhighlight>
{{out}}
<pre> 308.9999999999998 -307.9999999999998
-132 133
 
14.99999999999999 -13.99999999999999
-6.000000000000003 7.000000000000004
 
1 0
0 1
 
0.3333333333333333 0.6666666666666666
0.2857142857142857 0.7142857142857143
 
0.3015873015873016 0.6984126984126984
0.2993197278911565 0.7006802721088435
 
0.3000755857898715 0.6999244142101284
0.299967606090055 0.7000323939099449
 
0.3000035993233272 0.6999964006766727
0.2999984574328597 0.7000015425671401</pre>
 
=={{header|GAP}}==
<langsyntaxhighlight lang="gap"># Matrix exponentiation is built-in
A := [[0 , 1], [1, 1]];
PrintArray(A);
Line 1,145 ⟶ 1,754:
PrintArray(A^10);
# [ [ 34, 55 ],
# [ 55, 89 ] ]</langsyntaxhighlight>
 
=={{header|Go}}==
Line 1,151 ⟶ 1,760:
<br>
Like some other languages here, Go doesn't have a symbolic operator for numeric exponentiation and even if it did doesn't support operator overloading. We therefore write the exponentiation operation for matrices as an equivalent 'pow' function.
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 1,221 ⟶ 1,830:
fmt.Println()
}
}</langsyntaxhighlight>
 
{{out}}
Line 1,263 ⟶ 1,872:
Instead of writing it directly, we can re-use the built-in [[exponentiation operator]] if we declare matrices as an instance of ''Num'', using [[matrix multiplication]] (and addition). For simplicity, we use the inefficient representation as list of lists. Note that we don't check the dimensions (there are several ways to do that on the type-level, for example with phantom types).
 
<langsyntaxhighlight lang="haskell">import Data.List (transpose)
 
(<+>)
Line 1,294 ⟶ 1,903:
-- TEST ----------------------------------------------------------------------
main :: IO ()
main = print $ Mat [[1, 2], [0, 1]] ^ 4</langsyntaxhighlight>
{{Out}}
<pre>Mat [[1,8],[0,1]]</pre>
Line 1,301 ⟶ 1,910:
 
Note: this implementation does not work for a power of 0.
 
===With Numeric.LinearAlgebra===
 
<syntaxhighlight lang="haskell">import Numeric.LinearAlgebra
 
a :: Matrix I
a = (2><2)
[1,2
,0,1]
 
main = do
print $ a^4
putStrLn "power of zero: "
print $ a^0</syntaxhighlight>
{{Out}}
<pre>
(2><2)
[ 1, 16
, 0, 1 ]
power of zero:
(1><1)
[ 1 ]</pre>
 
=={{header|J}}==
 
 
<langsyntaxhighlight lang="j">mp=: +/ .* NB. Matrix multiplication
pow=: pow0=: 4 : 'mp&x^:y =i.#x'</langsyntaxhighlight>
 
or, from [[j:Essays/Linear Recurrences|the J wiki]], and faster for large exponents:
 
<langsyntaxhighlight lang="j">pow=: pow1=: 4 : 'mp/ mp~^:(I.|.#:y) x'</langsyntaxhighlight>
 
This implements an optimization where the exponent is represented in base 2, and repeated squaring is used to create a list of relevant powers of the base matrix, which are then combined using matrix multiplication. Note, however, that these two definitions treat a zero exponent differently (<code>m pow0 0</code> gives an identity matrix whose shape matches m, while <code>m pow1 0</code> gives a scalar 1).
 
Example use:
 
<syntaxhighlight lang=J>
(3 2,:2 1) pow 3
55 34
34 21
</syntaxhighlight>
 
=={{header|JavaScript}}==
Line 1,324 ⟶ 1,957:
 
Extends [[Matrix Transpose#JavaScript]] and [[Matrix multiplication#JavaScript]]
<langsyntaxhighlight lang="javascript">// IdentityMatrix is a "subclass" of Matrix
function IdentityMatrix(n) {
this.height = n;
Line 1,349 ⟶ 1,982:
 
var m = new Matrix([[3, 2], [2, 1]]);
[0,1,2,3,4,10].forEach(function(e){print(m.exp(e)); print()})</langsyntaxhighlight>
output
<pre>1,0
Line 1,377 ⟶ 2,010:
 
matrix_exp(n) adopts a "divide-and-conquer" strategy to avoid unnecessarily many matrix multiplications. The implementation uses direct_matrix_exp(n) for small n; this function could be defined as an inner function, but is defined separately first for clarity, and second to simplify timing comparisons, as shown below.
<langsyntaxhighlight lang="jq"># produce an array of length n that is 1 at i and 0 elsewhere
def indicator(i;n): [range(0;n) | 0] | .[i] = 1;
 
Line 1,400 ⟶ 2,033:
| multiply($ans; $residue )
end
end;</langsyntaxhighlight>
'''Examples'''
The execution speeds of matrix_exp and direct_matrix_exp are compared using a one-eighth-rotation matrix, which
is raised to the 10,000th power. The direct method turns out to be almost as fast.
<langsyntaxhighlight lang="jq">def pi: 4 * (1|atan);
 
def rotation_matrix(theta):
Line 1,413 ⟶ 2,046:
 
def demo_direct_matrix_exp(n):
rotation_matrix( pi / 4 ) | direct_matrix_exp(n) ;</langsyntaxhighlight>
'''Results''':
<langsyntaxhighlight lang="sh"># For demo_matrix_exp(10000)
$ time jq -n -c -f Matrix-exponentiation_operator.rc
[[1,-1.1102230246251565e-12],[1.1102230246251565e-12,1]]
user 0m0.490s
sys 0m0.008s</langsyntaxhighlight>
<langsyntaxhighlight lang="sh"># For demo_direct_matrix_exp(10000)
$ time jq -n -c -f Matrix-exponentiation_operator.rc
[[1,-7.849831895612169e-13],[7.849831895612169e-13,1]]
user 0m0.625s
sys 0m0.006s</langsyntaxhighlight>
 
=={{header|Jsish}}==
Line 1,431 ⟶ 2,064:
Uses module listed in [[Matrix Transpose#Jsish]]. Fails the task spec actually, as Matrix.exp() is implemented as a method, not an operator.
 
<langsyntaxhighlight lang="javascript">/* Matrix exponentiation, in Jsish */
require('Matrix');
 
Line 1,453 ⟶ 2,086:
m.exp(10) ==> { height:2, mtx:[ [ 1346269, 832040 ], [ 832040, 514229 ] ], width:2 }
=!EXPECTEND!=
*/</langsyntaxhighlight>
 
{{out}}
Line 1,461 ⟶ 2,094:
=={{header|Julia}}==
Matrix exponentiation is implemented by the built-in <code>^</code> operator.
<langsyntaxhighlight Julialang="julia">julia> [1 1 ; 1 0]^10
2x2 Array{Int64,2}:
89 55
55 34</langsyntaxhighlight>
 
=={{header|K}}==
<syntaxhighlight lang="k">
<lang K>
/Matrix Exponentiation
/mpow.k
pow: {:[0=y; :({a=/:a:!x}(#x))];a: x; do[y-1; a: x _mul a]; :a}
 
</syntaxhighlight>
</lang>
The output of a session is given below:
{{out}}
Line 1,505 ⟶ 2,138:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1.3
 
typealias Vector = DoubleArray
Line 1,561 ⟶ 2,194:
)
for (i in 0..10) printMatrix(m pow i, i)
}</langsyntaxhighlight>
 
{{out}}
Line 1,609 ⟶ 2,242:
[832040.0, 514229.0]
</pre>
 
=={{header|Lambdatalk}}==
<syntaxhighlight lang="scheme">
{require lib_matrix}
 
{def M.exp
{lambda {:m :n}
{if {= :n 0}
then {M.new [ [1,0],[0,1] ]}
else {S.reduce M.multiply {S.map {{lambda {:m _} :m} :m} {S.serie 1 :n}}}}}}
-> M.exp
 
'{def M
{M.new [[3,2],
[2,1]]}}
-> M
 
{S.map {lambda {:i} {br}M{sup :i} = {M.exp {M} :i}}
0 1 2 3 4 10}
->
M^0 = [[1,0],[0,1]]
M^1 = [[3,2],[2,1]]
M^2 = [[13,8],[8,5]]
M^3 = [[55,34],[34,21]]
M^4 = [[233,144],[144,89]]
M^10 = [[1346269,832040],[832040,514229]]
</syntaxhighlight>
 
=={{header|Liberty BASIC}}==
There is no native matrix capability. A set of functions is available at http://www.diga.me.uk/RCMatrixFuncs.bas implementing matrices of arbitrary dimension in a string format.
<syntaxhighlight lang="lb">
<lang lb>
MatrixD$ ="3, 3, 0.86603, 0.50000, 0.00000, -0.50000, 0.86603, 0.00000, 0.00000, 0.00000, 1.00000"
 
Line 1,624 ⟶ 2,284:
MatrixE$ =MatrixToPower$( MatrixD$, 9)
call DisplayMatrix MatrixE$
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,643 ⟶ 2,303:
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">Matrix = {}
 
function Matrix.new( dim_y, dim_x )
Line 1,738 ⟶ 2,398:
n = m^4;
 
Matrix.Show( n )</langsyntaxhighlight>
 
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module CheckIt {
Class cArray {
Line 1,802 ⟶ 2,463:
}
Checkit
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,840 ⟶ 2,501:
196418 121393
</pre >
 
 
=={{header|Maple}}==
Maple handles matrix powers implicitly with the built-in exponentiation operator:
<langsyntaxhighlight Maplelang="maple">> M := <<1,2>|<3,4>>;
> M ^ 2;</langsyntaxhighlight>
<math>\left[\begin{array}{cc}
7 & 15 \\
Line 1,852 ⟶ 2,512:
 
If you want elementwise powers, you can use the elementwise <code>^~</code> operator:
<langsyntaxhighlight Maplelang="maple">> M := <<1,2>|<3,4>>;
> M ^~ 2;</langsyntaxhighlight>
<math>\left[\begin{array}{cc}
1 & 9 \\
Line 1,859 ⟶ 2,519:
\end{array}\right]</math>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
In Mathematica there is an distinction between powering elements wise and as a matrix. So m^2 will give m with each element squared. To do matrix exponentation we use the function MatrixPower. It can handle all types of numbers for the power (integers, floats, rationals, complex) but also symbols for the power, and all types for the matrix (numbers, symbols et cetera), and will always keep the result exact if the matrix and the exponent is exact.
<langsyntaxhighlight Mathematicalang="mathematica">a = {{3, 2}, {4, 1}};
MatrixPower[a, 0]
MatrixPower[a, 1]
Line 1,867 ⟶ 2,527:
MatrixPower[a, 4]
MatrixPower[a, 1/2]
MatrixPower[a, Pi]</langsyntaxhighlight>
gives back:
 
Line 1,925 ⟶ 2,585:
 
Symbolic matrices like {{i,j},{k,l}} to the power m give general solutions for all possible i,j,k,l, and m:
<langsyntaxhighlight Mathematicalang="mathematica">MatrixPower[{{i, j}, {k, l}}, m] // Simplify</langsyntaxhighlight>
gives back (note that the simplification is not necessary for the evaluation, it just gives a shorter output):
 
Line 1,947 ⟶ 2,607:
=={{header|MATLAB}}==
For exponents in the form of A*A*A*A*...*A, A must be a square matrix:
<langsyntaxhighlight Matlablang="matlab">function [output] = matrixexponentiation(matrixA, exponent)
output = matrixA^(exponent);</langsyntaxhighlight>
 
Otherwise, to take the individual array elements to the power of an exponent (the matrix need not be square):
<langsyntaxhighlight Matlablang="matlab">function [output] = matrixexponentiation(matrixA, exponent)
output = matrixA.^(exponent);</langsyntaxhighlight>
 
=={{header|Maxima}}==
<langsyntaxhighlight lang="maxima">a: matrix([3, 2],
[4, 1])$
 
Line 1,964 ⟶ 2,624:
a ^^ -1;
/* matrix([-1/5, 2/5],
[4/5, -3/5]) */</langsyntaxhighlight>
 
=={{header|Nim}}==
<syntaxhighlight lang="nim">import sequtils, strutils
 
type Matrix[N: static int; T] = array[1..N, array[1..N, T]]
 
func `*`[N, T](a, b: Matrix[N, T]): Matrix[N, T] =
for i in 1..N:
for j in 1..N:
for k in 1..N:
result[i][j] += a[i][k] * b[k][j]
 
 
func identityMatrix[N; T](): Matrix[N, T] =
for i in 1..N:
result[i][i] = T(1)
 
 
func `^`[N, T](m: Matrix[N, T]; n: Natural): Matrix[N, T] =
if n == 0: return identityMatrix[N, T]()
if n == 1: return m
var n = n
var m = m
result = identityMatrix[N, T]()
while n > 0:
if (n and 1) != 0:
result = result * m
n = n shr 1
m = m * m
 
 
proc `$`(m: Matrix): string =
var lg = 0
for i in 1..m.N:
for j in 1..m.N:
lg = max(lg, len($m[i][j]))
for i in 1..m.N:
echo m[i].mapIt(align($it, lg)).join(" ")
 
 
when isMainModule:
 
let m1: Matrix[3, int] = [[ 3, 2, -1],
[-1, 0, 5],
[ 2, -1, 3]]
echo m1^10
 
import math
const
C30 = sqrt(3.0) / 2
S30 = 1 / 2
let m2: Matrix[2, float] = [[C30, -S30], [S30, C30]] # 30° rotation matrix.
echo m2^12 # Nearly the identity matrix.</syntaxhighlight>
 
{{out}}
<pre>572880 154352 321344
480752 261648 306176
473168 161936 413472
 
0.9999999999999993 -3.885780586188048e-16
3.885780586188048e-16 0.9999999999999993</pre>
 
=={{header|OCaml}}==
Line 1,970 ⟶ 2,691:
We will use some auxiliary functions
 
<langsyntaxhighlight lang="ocaml">(* identity matrix *)
let eye n =
let a = Array.make_matrix n n 0.0 in
Line 2,027 ⟶ 2,748:
(* example with integers *)
pow 1 ( * ) 2 16;;
(* - : int = 65536 *)</langsyntaxhighlight>
 
Now matrix power is simply a special case of pow :
 
<langsyntaxhighlight lang="ocaml">let matpow a n =
let p, q = dim a in
if p <> q then failwith "bad dimensions" else
Line 2,043 ⟶ 2,764:
 
[| [| 1.0; 1.0|]; [| 1.0; 0.0 |] |] ^^ 10;;
(* - : float array array = [|[|89.; 55.|]; [|55.; 34.|]|] *)</langsyntaxhighlight>
 
=={{header|Octave}}==
Line 2,049 ⟶ 2,770:
Of course GNU Octave handles matrix and operations on matrix "naturally".
 
<langsyntaxhighlight lang="octave">M = [ 3, 2; 2, 1 ];
M^0
M^1
M^2
M^(-1)
M^0.5</langsyntaxhighlight>
 
Output:
Line 2,086 ⟶ 2,807:
 
=={{header|PARI/GP}}==
<syntaxhighlight lang ="parigp">M^n</langsyntaxhighlight>
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">use strict;
package SquareMatrix;
use Carp; # standard, "it's not my fault" module
Line 2,182 ⟶ 2,903:
print "\n### WAY too big:\n", $m ** 1_000_000_000_000;
print "\n### But identity matrix can handle that\n",
$m->identity ** 1_000_000_000_000;</langsyntaxhighlight>
=={{header|Perl 6}}==
{{works with|rakudo|2015.11}}
<lang perl6>subset SqMat of Array where { .elems == all(.[]».elems) }
 
multi infix:<*>(SqMat $a, SqMat $b) {[
for ^$a -> $r {[
for ^$b[0] -> $c {
[+] ($a[$r][] Z* $b[].map: *[$c])
}
]}
]}
 
multi infix:<**> (SqMat $m, Int $n is copy where { $_ >= 0 }) {
my $tmp = $m;
my $out = [for ^$m -> $i { [ for ^$m -> $j { +($i == $j) } ] } ];
loop {
$out = $out * $tmp if $n +& 1;
last unless $n +>= 1;
$tmp = $tmp * $tmp;
}
 
$out;
}
 
multi show (SqMat $m) {
my $size = $m.flatmap( *.list».chars ).max;
say .fmt("%{$size}s", ' ') for $m.list;
}
 
my @m = [1, 2, 0],
[0, 3, 1],
[1, 0, 0];
 
for 0 .. 10 -> $order {
say "### Order $order";
show @m ** $order;
}</lang>
{{out}}
<pre>### Order 0
1 0 0
0 1 0
0 0 1
### Order 1
1 2 0
0 3 1
1 0 0
### Order 2
1 8 2
1 9 3
1 2 0
### Order 3
3 26 8
4 29 9
1 8 2
### Order 4
11 84 26
13 95 29
3 26 8
### Order 5
37 274 84
42 311 95
11 84 26
### Order 6
121 896 274
137 1017 311
37 274 84
### Order 7
395 2930 896
448 3325 1017
121 896 274
### Order 8
1291 9580 2930
1465 10871 3325
395 2930 896
### Order 9
4221 31322 9580
4790 35543 10871
1291 9580 2930
### Order 10
13801 102408 31322
15661 116209 35543
4221 31322 9580</pre>
 
=={{header|Phix}}==
Phix does not permit operator overloading, however here is a simple function to raise a square matrix to a non-negative integer power.<br>
First two routines copied straight from the [[Identity_matrix#Phix|Identity_matrix]] and [[Matrix_multiplication#Phix|Matrix_multiplication]] tasks.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>function identity(integer n)
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
sequence res = repeat(repeat(0,n),n)
<span style="color: #008080;">function</span> <span style="color: #000000;">identity</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
for i=1 to n do
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">),</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
res[i][i] = 1
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
end for
<span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
return res
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function matrix_mul(sequence a, sequence b)
sequence c
<span style="color: #008080;">function</span> <span style="color: #000000;">matrix_mul</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
if length(a[1]) != length(b) then
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">ha</span><span style="color: #0000FF;">,</span><span style="color: #000000;">wa</span><span style="color: #0000FF;">,</span><span style="color: #000000;">hb</span><span style="color: #0000FF;">,</span><span style="color: #000000;">wb</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">apply</span><span style="color: #0000FF;">({</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]},</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">)</span>
return 0
<span style="color: #008080;">if</span> <span style="color: #000000;">wa</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">hb</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
else
<span style="color: #004080;">sequence</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">wb</span><span style="color: #0000FF;">),</span><span style="color: #000000;">ha</span><span style="color: #0000FF;">)</span>
c = repeat(repeat(0,length(b[1])),length(a))
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">ha</span> <span style="color: #008080;">do</span>
for i=1 to length(a) do
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">wb</span> <span style="color: #008080;">do</span>
for j=1 to length(b[1]) do
<span style="color: #008080;">for</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">wa</span> <span style="color: #008080;">do</span>
for k=1 to length(a[1]) do
<span style="color: #000000;">c</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span>
c[i][j] += a[i][k]*b[k][j]
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end for
<span style="color: #008080;">return</span> <span style="color: #000000;">c</span>
return c
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
end if
end function
<span style="color: #008080;">function</span> <span style="color: #000000;">matrix_exponent</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
 
<span style="color: #004080;">integer</span> <span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">)</span>
function matrix_exponent(sequence m, integer n)
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">identity</span><span style="color: #0000FF;">(</span><span style="color: #000000;">l</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
integer l = length(m)
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">m</span>
if n=0 then return identity(l) end if
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
sequence res = m
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">matrix_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">m</span><span style="color: #0000FF;">)</span>
for i=2 to n do
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
res = matrix_mul(res,m)
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
return res
end function
<span style="color: #008080;">constant</span> <span style="color: #000000;">M1</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">}},</span>
 
<span style="color: #000000;">M2</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">},</span>
constant M1 = {{5}}
<span style="color: #0000FF;">{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">}},</span>
constant M2 = {{3, 2},
<span style="color: #000000;">M3</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">},</span>
{2, 1}}
<span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">},</span>
constant M3 = {{1, 2, 0},
<span style="color: #0000FF;">{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">}}</span>
{0, 3, 1},
{1, 0, 0}}
<span style="color: #7060A8;">ppOpt</span><span style="color: #0000FF;">({</span><span style="color: #004600;">pp_Nest</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">})</span>
 
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">matrix_exponent</span><span style="color: #0000FF;">(</span><span style="color: #000000;">M1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">))</span>
ppOpt({pp_Nest,1})
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">matrix_exponent</span><span style="color: #0000FF;">(</span><span style="color: #000000;">M1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">))</span>
pp(matrix_exponent(M1,0))
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">matrix_exponent</span><span style="color: #0000FF;">(</span><span style="color: #000000;">M1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">))</span>
pp(matrix_exponent(M1,1))
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"==\n"</span><span style="color: #0000FF;">)</span>
pp(matrix_exponent(M1,2))
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">matrix_exponent</span><span style="color: #0000FF;">(</span><span style="color: #000000;">M2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">))</span>
puts(1,"==\n")
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">matrix_exponent</span><span style="color: #0000FF;">(</span><span style="color: #000000;">M2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">))</span>
pp(matrix_exponent(M2,0))
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">matrix_exponent</span><span style="color: #0000FF;">(</span><span style="color: #000000;">M2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">))</span>
pp(matrix_exponent(M2,1))
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">matrix_exponent</span><span style="color: #0000FF;">(</span><span style="color: #000000;">M2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">))</span>
pp(matrix_exponent(M2,2))
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"==\n"</span><span style="color: #0000FF;">)</span>
pp(matrix_exponent(M2,10))
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">matrix_exponent</span><span style="color: #0000FF;">(</span><span style="color: #000000;">M3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">))</span>
puts(1,"==\n")
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"==\n"</span><span style="color: #0000FF;">)</span>
pp(matrix_exponent(M3,10))
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">matrix_exponent</span><span style="color: #0000FF;">(</span><span style="color: #000000;">identity</span><span style="color: #0000FF;">(</span><span style="color: #000000;">4</span><span style="color: #0000FF;">),</span><span style="color: #000000;">5</span><span style="color: #0000FF;">))</span>
puts(1,"==\n")
<!--</syntaxhighlight>-->
pp(matrix_exponent(identity(4),5))</lang>
{{out}}
<pre>
Line 2,351 ⟶ 2,990:
=={{header|PicoLisp}}==
Uses the 'matMul' function from [[Matrix multiplication#PicoLisp]]
<langsyntaxhighlight PicoLisplang="picolisp">(de matIdent (N)
(let L (need N (1) 0)
(mapcar '(() (copy (rot L))) L) ) )
Line 2,361 ⟶ 3,000:
M ) )
 
(matExp '((3 2) (2 1)) 3)</langsyntaxhighlight>
Output:
<pre>-> ((55 34) (34 21))</pre>
Line 2,367 ⟶ 3,006:
=={{header|Python}}==
Using matrixMul from [[Matrix multiplication#Python]]
<langsyntaxhighlight lang="python">>>> from operator import mul
>>> def matrixMul(m1, m2):
return map(
Line 2,422 ⟶ 3,061:
1346269 832040
832040 514229
>>></langsyntaxhighlight>
 
Alternative Based Upon @ operator of Python 3.5 PEP 465 and using Matrix exponentation for faster computation of powers
<syntaxhighlight lang="text">
class Mat(list) :
def __matmul__(self, B) :
Line 2,458 ⟶ 3,097:
print('\n%i:' % i)
printtable(power(m, i))
</syntaxhighlight>
</lang>
{{Output}}
<pre>
Line 2,478 ⟶ 3,117:
 
=={{header|R}}==
===Library function call===
{{libheader|Biodem}}
<langsyntaxhighlight Rlang="rsplus">library(Biodem)
m <- matrix(c(3,2,2,1), nrow=2)
mtx.exp(m, 0)
Line 2,500 ⟶ 3,140:
# [,1] [,2]
# [1,] 1346269 832040
# [2,] 832040 514229</langsyntaxhighlight>
Note that non-integer powers are not supported with this function.
===Infix operator===
The task wants the implementation to be "as an operator". Given that R lets us define new infix operators, it seems fitting to show how to do this. Ideally, for a matrix a and int n, we'd want to be able to use a^n. R actually has this already, but it's not what the task wants:
<syntaxhighlight lang="rsplus">a <- matrix(c(1, 2, 3, 4), 2, 2)
a^1
a^2</syntaxhighlight>
{{out}}
<pre>> a^1
[,1] [,2]
[1,] 1 3
[2,] 2 4
> a^2
[,1] [,2]
[1,] 1 9
[2,] 4 16</pre>
As we can see, it instead returns the given matrix with its elements raised to the nth power. Overwriting the ^ operator would be dangerous and rude. However, R's base library suggests an alternative. %*% is already defined as matrix multiplication, so why not use %^% for exponentiation?
<syntaxhighlight lang="rsplus">`%^%` <- function(mat, n)
{
is.wholenumber <- function(x, tol = .Machine$double.eps^0.5) abs(x - round(x)) < tol#See the docs for is.integer
if(is.matrix(mat) && is.numeric(n) && is.wholenumber(n))
{
if(n==0) diag(nrow = nrow(mat))#Identity matrix of mat's dimensions
else if(n == 1) mat
else if(n > 1) mat %*% (mat %^% (n - 1))
else stop("Invalid n.")
}
else stop("Invalid input type.")
}
#For output:
a %^% 0
a %^% 1
a %^% 2
a %*% a %*% a#Base R's equivalent of a %^% 3
a %^% 3
nonSquareMatrix <- matrix(c(1, 2, 3, 4, 5, 6), nrow = 2, ncol = 3)
nonSquareMatrix %^% 1
nonSquareMatrix %^% 2#R's %*% will throw the error for us</syntaxhighlight>
{{out}}
<pre>> a %^% 0
[,1] [,2]
[1,] 1 0
[2,] 0 1
 
> a %^% 1
[,1] [,2]
[1,] 1 3
[2,] 2 4
 
> a %^% 2
[,1] [,2]
[1,] 7 15
[2,] 10 22
 
> a %*% a %*% a#Base R's equivalent of a %^% 3
[,1] [,2]
[1,] 37 81
[2,] 54 118
 
> a %^% 3
[,1] [,2]
[1,] 37 81
[2,] 54 118
 
> nonSquareMatrix <- matrix(c(1, 2, 3, 4, 5, 6), nrow = 2, ncol = 3)
 
> nonSquareMatrix %^% 1
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
 
> nonSquareMatrix %^% 2#R's %*% will throw the error for us
Error in mat %*% (mat %^% (n - 1)) : non-conformable arguments</pre>
Our code is far from efficient and could do with more error-checking, but it demonstrates the principle. If we wanted to do this properly, we'd use a library - ideally one that calls C code. Following the previous submission's example, we can just do this:
<syntaxhighlight lang="rsplus">library(Biodem)
`%^%` <- function(mat, n) Biodem::mtx.exp(mat, n)</syntaxhighlight>
And it will work just the same, except for being much faster and throwing an error on nonSquareMatrix %^% 1.
 
=={{header|Racket}}==
 
<syntaxhighlight lang="racket">
<lang Racket>
#lang racket
(require math)
Line 2,535 ⟶ 3,250:
(for ([i (in-range 1 11)])
(printf "a^~a = ~s\n" i (matrix-expt a i)))
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" line>subset SqMat of Array where { .elems == all(.[]».elems) }
 
multi infix:<*>(SqMat $a, SqMat $b) {[
for ^$a -> $r {[
for ^$b[0] -> $c {
[+] ($a[$r][] Z* $b[].map: *[$c])
}
]}
]}
 
multi infix:<**> (SqMat $m, Int $n is copy where { $_ >= 0 }) {
my $tmp = $m;
my $out = [for ^$m -> $i { [ for ^$m -> $j { +($i == $j) } ] } ];
loop {
$out = $out * $tmp if $n +& 1;
last unless $n +>= 1;
$tmp = $tmp * $tmp;
}
 
$out;
}
 
multi show (SqMat $m) {
my $size = $m.map( *.list».chars ).flat.max;
say .fmt("%{$size}s", ' ') for $m.list;
}
 
my @m = [1, 2, 0],
[0, 3, 1],
[1, 0, 0];
 
for 0 .. 10 -> $order {
say "### Order $order";
show @m ** $order;
}</syntaxhighlight>
{{out}}
<pre>### Order 0
1 0 0
0 1 0
0 0 1
### Order 1
1 2 0
0 3 1
1 0 0
### Order 2
1 8 2
1 9 3
1 2 0
### Order 3
3 26 8
4 29 9
1 8 2
### Order 4
11 84 26
13 95 29
3 26 8
### Order 5
37 274 84
42 311 95
11 84 26
### Order 6
121 896 274
137 1017 311
37 274 84
### Order 7
395 2930 896
448 3325 1017
121 896 274
### Order 8
1291 9580 2930
1465 10871 3325
395 2930 896
### Order 9
4221 31322 9580
4790 35543 10871
1291 9580 2930
### Order 10
13801 102408 31322
15661 116209 35543
4221 31322 9580</pre>
 
=={{header|RPL}}==
Operators can not be overloaded, but we can easily create a new word, with same syntax as the classical exponentiation operator. the power must be a signed integer.
{| class="wikitable"
! RPL code
! Comment
|-
|
SWAP '''IF''' OVER 0 < '''THEN''' INV '''END '''
DUP IDN → m id
≪ ABS id
'''WHILE''' OVER '''REPEAT''' m * SWAP 1 - SWAP '''END '''
SWAP DROP
≫ ≫ ''''MATXP'''' STO
|
'''MATXP''' ''( [[m]] n -- [[m^n]] ) ''
inverse matrix if n<0
store matrix and identity
initialize stack with abs(n) and identity
multiply n times
clean stack
return m^n
|}
 
[[3 2][2 1]] 0 '''MATXP'''
[[3 2][2 1]] 1 '''MATXP'''
[[3 2][2 1]] 2 '''MATXP'''
[[3 2][2 1]] 5 '''MATXP'''
[[3 2][2 1]] -5 '''MATXP'''
{{out}
<pre>
5: [[ 1 0 ]
[ 0 1 ]]
4: [[ 3 2 ]
[ 2 1 ]]
3: [[ 13 8 ]
[ 8 5 ]]
2: [[ 987 610 ]
[ 610 377 ]]
1: [[ -377 610 ]
[ 610 -987]]
</pre>
=={{header|Ruby}}==
Ruby's standard library already provides the matrix-exponentiation operator. It is <code>Matrix#**</code> from package 'matrix' of the standard library. [[MRI]] 1.9.x implements the matrix-exponentiation operator in file [http://redmine.ruby-lang.org/projects/ruby-19/repository/entry/lib/matrix.rb matrix.rb], <code>def **</code> (around [http://redmine.ruby-lang.org/projects/ruby-19/repository/entry/lib/matrix.rb#L961 line 961]).
Line 2,564 ⟶ 3,404:
4478253365354i)], [(3.899055157791345+0.05129447825336536i), (2.4097486115256355
-0.0829962092491375i)]]</pre>
 
With older Ruby, it raises an exception for Matrix ** Float.
 
<pre>irb(main):008:0> m ** 1.5
ExceptionForMatrix::ErrOperationNotDefined: This operation(**) can't defined
from /usr/lib/ruby/1.8/matrix.rb:665:in `**'
from (irb):8</pre>
 
=={{header|Rust}}==
Rust (1.37.0) does not allow to overload the ** operator, instead ^ (bitwise xor) is used.
<langsyntaxhighlight lang="rust">use std::fmt;
use std::ops;
const WIDTH: usize = 6;
Line 2,648 ⟶ 3,481:
println!("Power of {}:\n{:?}", i, sm.clone() ^ i);
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,706 ⟶ 3,539:
4221 31322 9580
</pre>
 
=={{header|Scala}}==
<langsyntaxhighlight lang="scala">class Matrix[T](matrix:Array[Array[T]])(implicit n: Numeric[T], m: ClassManifest[T])
{
import n._
Line 2,744 ⟶ 3,578:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>-- m --
Line 2,778 ⟶ 3,612:
For simplicity, the matrix is represented as a list of lists, and no dimension checking occurs. This implementation does not work when the exponent is 0.
 
<langsyntaxhighlight lang="scheme">
(define (dec x)
(- x 1))
Line 2,802 ⟶ 3,636:
(define (square-matrix mat)
(matrix-multiply mat mat))
</syntaxhighlight>
</lang>
 
 
Line 2,818 ⟶ 3,652:
*A ''for'' loop which loops over values listed in an array literal
 
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "float.s7i";
 
Line 2,909 ⟶ 3,743:
writeln(m ** exponent);
end for;
end func;</langsyntaxhighlight>
 
Original source of matrix exponentiation: [http://seed7.sourceforge.net/algorith/math.htm#matrix_exponentiation]
Line 2,951 ⟶ 3,785:
 
=={{header|Sidef}}==
<langsyntaxhighlight lang="ruby">class Array {
method ** (Number n { .>= 0 }) {
var tmp = self
Line 2,972 ⟶ 3,806:
var t = (m ** order)
say (' ', t.join("\n "))
}</langsyntaxhighlight>
{{out}}
<pre>
Line 3,005 ⟶ 3,839:
{{works with|OpenAxiom}}
{{works with|Axiom}}
<langsyntaxhighlight SPADlang="spad">(1) -> A:=matrix [[0,-%i],[%i,0]]
 
+0 - %i+
Line 3,028 ⟶ 3,862:
(4) | |
+%i 0 +
Type: Union(Matrix(Fraction(Complex(Integer))),...)</langsyntaxhighlight>
 
Domain:[http://fricas.github.io/api/Matrix.html?highlight=matrix Matrix(R)]
Line 3,036 ⟶ 3,870:
This implementation uses [https://en.wikipedia.org/wiki/Exponentiation_by_squaring Exponentiation by squaring] to compute a^n for a matrix a and an integer n (which may be positive, negative or zero).
 
<langsyntaxhighlight lang="stata">real matrix matpow(real matrix a, real scalar n) {
real matrix p, x
real scalar i, s
Line 3,048 ⟶ 3,882:
}
return(s?luinv(p):p)
}</langsyntaxhighlight>
 
Here is an example to compute Fibonacci numbers:
 
<langsyntaxhighlight lang="stata">: matpow((0,1\1,1),10)
[symmetric]
1 2
Line 3,058 ⟶ 3,892:
1 | 34 |
2 | 55 89 |
+-----------+</langsyntaxhighlight>
 
=={{header|Tcl}}==
Using code at [[Matrix multiplication#Tcl]] and [[Matrix Transpose#Tcl]]
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
namespace path {::tcl::mathop ::tcl::mathfunc}
 
Line 3,085 ⟶ 3,919:
for {set n 0} {$n < $size} {incr n} {lset i $n $n 1}
return $i
}</langsyntaxhighlight>
<pre>% print_matrix [matrix_exp {{3 2} {2 1}} 1]
3 2
Line 3,107 ⟶ 3,941:
 
=={{header|TI-89 BASIC}}==
 
{{improve|TI-89 BASIC|Explicitly implement exponentiation.}}
 
Built-in exponentiation:
<syntaxhighlight lang="ti89b">[3,2;4,1]^4</syntaxhighlight>
 
<lang ti89b>[3,2;4,1]^4</lang>
 
Output: <math>\begin{bmatrix}417 & 208 \\ 416 & 209\end{bmatrix}</math>
 
Line 3,119 ⟶ 3,948:
For matrices of floating point numbers, the library function <code>mmult</code> can be used as shown. The user-defined <code>id</code> function takes a square matrix to the identity matrix of the same dimensions. The <code>mex</code> function takes a pair <math>(A,n)</math>
representing a real matrix <math>A</math> and a natural exponent <math>n</math> to the exponentiation <math>A^n</math> using the naive algorithm.
<langsyntaxhighlight Ursalalang="ursala">#import nat
#import lin
 
id = @h ^|CzyCK33/1.! 0.!*
mex = ||id@l mmult:-0^|DlS/~& iota</langsyntaxhighlight>
Alternatively, this version uses the fast binary algorithm.
<langsyntaxhighlight Ursalalang="ursala">mex = ~&ar^?\id@al (~&lr?/mmult@llPrX ~&r)^/~&alrhPX mmult@falrtPXPRiiX</langsyntaxhighlight>
This test program raises a 2 by 2 matrix to a selection of powers.
<langsyntaxhighlight Ursalalang="ursala">#cast %eLLL
 
test = mex/*<<3.,2.>,<2.,1.>> <0,1,2,3,4,10></langsyntaxhighlight>
output:
<pre><
Line 3,150 ⟶ 3,979:
<1.346269e+06,8.320400e+05>,
<8.320400e+05,5.142290e+05>>></pre>
 
=={{header|VBA}}==
No operator overloading in VBA. Implemented as a function. Can not handle scalars. Requires matrix size greater than one. Does allow for negative exponents.
<langsyntaxhighlight lang="vb">Option Base 1
Private Function Identity(n As Integer) As Variant
Dim I() As Variant
Line 3,207 ⟶ 4,037:
Debug.Print
pp MatrixExponentiation(M3, 10)
End Sub</langsyntaxhighlight>{{out}}
<pre>-1 2
2 -3
Line 3,220 ⟶ 4,050:
15661 116209 35543
4221 31322 9580 </pre>
 
=={{header|Wren}}==
{{libheader|Wren-fmt}}
{{libheader|Wren-matrix}}
Wren's Num class uses a method (pow) rather than an operator for exponentiation.
 
The Matrix class in the above module also has a 'pow' method but, as an alternative, overloads the otherwise unused '^' operator to provide the same functionality.
<syntaxhighlight lang="wren">import "./matrix" for Matrix
import "./fmt" for Fmt
 
var m = Matrix.new([[0, 1], [1, 1]])
System.print("Original:\n")
Fmt.mprint(m, 2, 0)
System.print("\nRaised to power of 10:\n")
Fmt.mprint(m ^ 10, 3, 0)</syntaxhighlight>
 
{{out}}
<pre>
Original:
 
| 0 1|
| 1 1|
 
Raised to power of 10:
 
| 34 55|
| 55 89|
</pre>
 
{{omit from|Icon|no operator overloading}}
{{omit From|Java|no operator overloading}}
{{omit From|Processing|no operator overloading}}
{{omit from|Unicon|no operator overloading}}
9,476

edits