Skip to content

Commit c9a6b9d

Browse files
committedJan 18, 2025·
Add exponential functions for Vector and Matrix structs
1 parent 8ec8df3 commit c9a6b9d

File tree

4 files changed

+172
-0
lines changed

4 files changed

+172
-0
lines changed
 
+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
Matrix extension for exponential functions.
3+
*/
4+
5+
import Accelerate
6+
7+
public protocol Exponential {
8+
static func exp(a: Matrix<Self>) -> Matrix<Self>
9+
static func exp2(a: Matrix<Self>) -> Matrix<Self>
10+
static func expm1(a: Matrix<Self>) -> Matrix<Self>
11+
}
12+
13+
extension Float: Exponential {
14+
public static func exp(a: Matrix<Float>) -> Matrix<Float> {
15+
var mat = Matrix(like: a)
16+
vForce.exp(a.buffer, result: &mat.buffer)
17+
return mat
18+
}
19+
20+
public static func exp2(a: Matrix<Float>) -> Matrix<Float> {
21+
var mat = Matrix(like: a)
22+
vForce.exp2(a.buffer, result: &mat.buffer)
23+
return mat
24+
}
25+
26+
public static func expm1(a: Matrix<Float>) -> Matrix<Float> {
27+
var mat = Matrix(like: a)
28+
vForce.expm1(a.buffer, result: &mat.buffer)
29+
return mat
30+
}
31+
}
32+
33+
extension Double: Exponential {
34+
public static func exp(a: Matrix<Double>) -> Matrix<Double> {
35+
var mat = Matrix(like: a)
36+
vForce.exp(a.buffer, result: &mat.buffer)
37+
return mat
38+
}
39+
40+
public static func exp2(a: Matrix<Double>) -> Matrix<Double> {
41+
var mat = Matrix(like: a)
42+
vForce.exp2(a.buffer, result: &mat.buffer)
43+
return mat
44+
}
45+
46+
public static func expm1(a: Matrix<Double>) -> Matrix<Double> {
47+
var mat = Matrix(like: a)
48+
vForce.expm1(a.buffer, result: &mat.buffer)
49+
return mat
50+
}
51+
}
52+
53+
extension Matrix where Scalar: Exponential {
54+
55+
/// Calculate the exponential for each matrix element.
56+
/// - Returns: Element-wise exponential matrix.
57+
public func exp() -> Matrix {
58+
Scalar.exp(a: self)
59+
}
60+
61+
/// Calculate 2 raised to the power of each matrix element.
62+
/// - Returns: Element-wise 2 raised to the power matrix.
63+
public func exp2() -> Matrix {
64+
Scalar.exp2(a: self)
65+
}
66+
67+
/// Calculate the exponential minus one of each matrix element.
68+
/// - Returns: Element-wise exponential minus one matrix.
69+
public func expm1() -> Matrix {
70+
Scalar.expm1(a: self)
71+
}
72+
}
+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
Vector extension for exponential functions.
3+
*/
4+
5+
import Accelerate
6+
7+
public protocol Exponential {
8+
static func exp(a: Vector<Self>) -> Vector<Self>
9+
static func exp2(a: Vector<Self>) -> Vector<Self>
10+
static func expm1(a: Vector<Self>) -> Vector<Self>
11+
}
12+
13+
extension Float: Exponential {
14+
public static func exp(a: Vector<Float>) -> Vector<Float> {
15+
var mat = Vector(like: a)
16+
vForce.exp(a.buffer, result: &mat.buffer)
17+
return mat
18+
}
19+
20+
public static func exp2(a: Vector<Float>) -> Vector<Float> {
21+
var mat = Vector(like: a)
22+
vForce.exp2(a.buffer, result: &mat.buffer)
23+
return mat
24+
}
25+
26+
public static func expm1(a: Vector<Float>) -> Vector<Float> {
27+
var mat = Vector(like: a)
28+
vForce.expm1(a.buffer, result: &mat.buffer)
29+
return mat
30+
}
31+
}
32+
33+
extension Double: Exponential {
34+
public static func exp(a: Vector<Double>) -> Vector<Double> {
35+
var mat = Vector(like: a)
36+
vForce.exp(a.buffer, result: &mat.buffer)
37+
return mat
38+
}
39+
40+
public static func exp2(a: Vector<Double>) -> Vector<Double> {
41+
var mat = Vector(like: a)
42+
vForce.exp2(a.buffer, result: &mat.buffer)
43+
return mat
44+
}
45+
46+
public static func expm1(a: Vector<Double>) -> Vector<Double> {
47+
var mat = Vector(like: a)
48+
vForce.expm1(a.buffer, result: &mat.buffer)
49+
return mat
50+
}
51+
}
52+
53+
extension Vector where Scalar: Exponential {
54+
55+
/// Calculate the exponential for each vector element.
56+
/// - Returns: Element-wise exponential vector.
57+
public func exp() -> Vector {
58+
Scalar.exp(a: self)
59+
}
60+
61+
/// Calculate 2 raised to the power of each vector element.
62+
/// - Returns: Element-wise 2 raised to the power vector.
63+
public func exp2() -> Vector {
64+
Scalar.exp2(a: self)
65+
}
66+
67+
/// Calculate the exponential minus one of each vector element.
68+
/// - Returns: Element-wise exponential minus one vector.
69+
public func expm1() -> Vector {
70+
Scalar.expm1(a: self)
71+
}
72+
}

‎Tests/MatrixTests.swift

+14
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,20 @@ struct MatrixTests {
146146
#expect(invB == [[-2, 1], [1.5, -0.5]])
147147
}
148148

149+
@Test func exponential() {
150+
let a = Matrix<Float>([[1, 2], [3, 4]])
151+
let b = Matrix<Double>([[1, 2], [3, 4]])
152+
153+
#expect(a.exp() == [[2.71828183, 7.3890561], [20.08553692, 54.59815003]])
154+
#expect(b.exp().isApproximatelyEqual(to: [[2.71828, 7.38905], [20.08553, 54.59815]], relativeTolerance: 1e-4))
155+
156+
#expect(a.exp2() == [[2, 4], [8, 16]])
157+
#expect(b.exp2() == [[2, 4], [8, 16]])
158+
159+
#expect(a.expm1().isApproximatelyEqual(to: [[1.71828, 6.38905], [19.08553, 53.59815]], relativeTolerance: 1e-4))
160+
#expect(b.expm1().isApproximatelyEqual(to: [[1.71828, 6.38905], [19.08553, 53.59815]], relativeTolerance: 1e-4))
161+
}
162+
149163
@Test func integerArithmetic() {
150164
let k = 5
151165
let a = Matrix([[1, 2, 3], [4, 5, 6]])

‎Tests/VectorTests.swift

+14
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,20 @@ struct VectorTests {
5151
#expect(c.isApproximatelyEqual(to: d, absoluteTolerance: 0.001))
5252
}
5353

54+
@Test func exponential() {
55+
let a = Vector<Float>([1, 2, 3, 4])
56+
let b = Vector<Double>([1, 2, 3, 4])
57+
58+
#expect(a.exp() == [2.71828183, 7.3890561, 20.08553692, 54.59815003])
59+
#expect(b.exp().isApproximatelyEqual(to: [2.71828, 7.38905, 20.08553, 54.59815], relativeTolerance: 1e-4))
60+
61+
#expect(a.exp2() == [2, 4, 8, 16])
62+
#expect(b.exp2() == [2, 4, 8, 16])
63+
64+
#expect(a.expm1().isApproximatelyEqual(to: [1.71828, 6.38905, 19.08553, 53.59815], relativeTolerance: 1e-4))
65+
#expect(b.expm1().isApproximatelyEqual(to: [1.71828, 6.38905, 19.08553, 53.59815], relativeTolerance: 1e-4))
66+
}
67+
5468
@Test func integerArithmetic() {
5569
let k = 5
5670
let a = Vector([1, 2, 3, 4, 5])

0 commit comments

Comments
 (0)
Please sign in to comment.