Skip to content

Commit e592b4c

Browse files
committed
Add more to LAPACK spec, add more docs.
1 parent cff5aa7 commit e592b4c

File tree

6 files changed

+122
-2
lines changed

6 files changed

+122
-2
lines changed

shell.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ in
1010
function test-runner () {
1111
${pkgs.ag}/bin/ag -l | \
1212
${pkgs.entr}/bin/entr sh -c \
13-
'cabal build test && dist/build/test/test +RTS -N -RTS'
13+
'cabal build test && dist/build/test/test'
1414
}
1515
'';
1616
})

src/ArrayFire/Arith.hs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,39 +135,55 @@ ge x y (fromIntegral . fromEnum -> batch) = do
135135
eq
136136
:: AFType a
137137
=> Array a
138+
-- ^ First input
138139
-> Array a
140+
-- ^ Second input
139141
-> Bool
142+
-- ^ Use batch
140143
-> Array a
144+
-- ^ Result of equal
141145
eq x y (fromIntegral . fromEnum -> batch) = do
142146
x `op2` y $ \arr arr1 arr2 ->
143147
af_eq arr arr1 arr2 batch
144148

145149
neq
146150
:: AFType a
147151
=> Array a
152+
-- ^ First input
148153
-> Array a
154+
-- ^ Second input
149155
-> Bool
156+
-- ^ Use batch
150157
-> Array a
158+
-- ^ Result of not equal
151159
neq x y (fromIntegral . fromEnum -> batch) = do
152160
x `op2` y $ \arr arr1 arr2 ->
153161
af_neq arr arr1 arr2 batch
154162

155163
and
156164
:: AFType a
157165
=> Array a
166+
-- ^ First input
158167
-> Array a
168+
-- ^ Second input
159169
-> Bool
170+
-- ^ Use batch
160171
-> Array a
172+
-- ^ Result of and
161173
and x y (fromIntegral . fromEnum -> batch) = do
162174
x `op2` y $ \arr arr1 arr2 ->
163175
af_and arr arr1 arr2 batch
164176

165177
or
166178
:: AFType a
167179
=> Array a
180+
-- ^ First input
168181
-> Array a
182+
-- ^ Second input
169183
-> Bool
184+
-- ^ Use batch
170185
-> Array a
186+
-- ^ Result of or
171187
or x y (fromIntegral . fromEnum -> batch) = do
172188
x `op2` y $ \arr arr1 arr2 ->
173189
af_or arr arr1 arr2 batch
@@ -181,57 +197,79 @@ not = flip op1 af_not
181197
bitAnd
182198
:: AFType a
183199
=> Array a
200+
-- ^ First input
184201
-> Array a
202+
-- ^ Second input
185203
-> Bool
204+
-- ^ Use batch
186205
-> Array a
206+
-- ^ Result of bitwise and
187207
bitAnd x y (fromIntegral . fromEnum -> batch) = do
188208
x `op2` y $ \arr arr1 arr2 ->
189209
af_bitand arr arr1 arr2 batch
190210

191211
bitOr
192212
:: AFType a
193213
=> Array a
214+
-- ^ First input
194215
-> Array a
216+
-- ^ Second input
195217
-> Bool
218+
-- ^ Use batch
196219
-> Array a
220+
-- ^ Result of bit or
197221
bitOr x y (fromIntegral . fromEnum -> batch) = do
198222
x `op2` y $ \arr arr1 arr2 ->
199223
af_bitor arr arr1 arr2 batch
200224

201225
bitXor
202226
:: AFType a
203227
=> Array a
228+
-- ^ First input
204229
-> Array a
230+
-- ^ Second input
205231
-> Bool
232+
-- ^ Use batch
206233
-> Array a
234+
-- ^ Result of bit xor
207235
bitXor x y (fromIntegral . fromEnum -> batch) = do
208236
x `op2` y $ \arr arr1 arr2 ->
209237
af_bitxor arr arr1 arr2 batch
210238

211239
bitShiftL
212240
:: AFType a
213241
=> Array a
242+
-- ^ First input
214243
-> Array a
244+
-- ^ Second input
215245
-> Bool
246+
-- ^ Use batch
216247
-> Array a
248+
-- ^ Result of bit shift left
217249
bitShiftL x y (fromIntegral . fromEnum -> batch) = do
218250
x `op2` y $ \arr arr1 arr2 ->
219251
af_bitshiftl arr arr1 arr2 batch
220252

221253
bitShiftR
222254
:: AFType a
223255
=> Array a
256+
-- ^ First input
224257
-> Array a
258+
-- ^ Second input
225259
-> Bool
260+
-- ^ Use batch
226261
-> Array a
262+
-- ^ Result of bit shift right
227263
bitShiftR x y (fromIntegral . fromEnum -> batch) = do
228264
x `op2` y $ \arr arr1 arr2 ->
229265
af_bitshiftr arr arr1 arr2 batch
230266

231267
cast
232268
:: forall a b . (AFType a, AFType b)
233269
=> Array a
270+
-- ^ Input array to cast
234271
-> Array b
272+
-- ^ Result of cast
235273
cast afArr =
236274
coerce $ afArr `op1` (\x y -> af_cast x y dtyp)
237275
where
@@ -240,19 +278,27 @@ cast afArr =
240278
minOf
241279
:: AFType a
242280
=> Array a
281+
-- ^ First input
243282
-> Array a
283+
-- ^ Second input
244284
-> Bool
285+
-- ^ Use batch
245286
-> Array a
287+
-- ^ Result of minimum of
246288
minOf x y (fromIntegral . fromEnum -> batch) = do
247289
x `op2` y $ \arr arr1 arr2 ->
248290
af_minof arr arr1 arr2 batch
249291

250292
maxOf
251293
:: AFType a
252294
=> Array a
295+
-- ^ First input
253296
-> Array a
297+
-- ^ Second input
254298
-> Bool
299+
-- ^ Use batch
255300
-> Array a
301+
-- ^ Result of maximum of
256302
maxOf x y (fromIntegral . fromEnum -> batch) = do
257303
x `op2` y $ \arr arr1 arr2 ->
258304
af_maxof arr arr1 arr2 batch
@@ -270,19 +316,27 @@ clamp a b c (fromIntegral . fromEnum -> batch) =
270316
rem
271317
:: AFType a
272318
=> Array a
319+
-- ^ First input
273320
-> Array a
321+
-- ^ Second input
274322
-> Bool
323+
-- ^ Use batch
275324
-> Array a
325+
-- ^ Result of remainder
276326
rem x y (fromIntegral . fromEnum -> batch) = do
277327
x `op2` y $ \arr arr1 arr2 ->
278328
af_rem arr arr1 arr2 batch
279329

280330
mod
281331
:: AFType a
282332
=> Array a
333+
-- ^ First input
283334
-> Array a
335+
-- ^ Second input
284336
-> Bool
337+
-- ^ Use batch
285338
-> Array a
339+
-- ^ Result of mod
286340
mod x y (fromIntegral . fromEnum -> batch) = do
287341
x `op2` y $ \arr arr1 arr2 ->
288342
af_mod arr arr1 arr2 batch
@@ -368,19 +422,27 @@ atan = flip op1 af_atan
368422
atan2
369423
:: AFType a
370424
=> Array a
425+
-- ^ First input
371426
-> Array a
427+
-- ^ Second input
372428
-> Bool
429+
-- ^ Use batch
373430
-> Array a
431+
-- ^ Result of atan2
374432
atan2 x y (fromIntegral . fromEnum -> batch) = do
375433
x `op2` y $ \arr arr1 arr2 ->
376434
af_atan2 arr arr1 arr2 batch
377435

378436
cplx2
379437
:: AFType a
380438
=> Array a
439+
-- ^ First input
381440
-> Array a
441+
-- ^ Second input
382442
-> Bool
443+
-- ^ Use batch
383444
-> Array a
445+
-- ^ Result of cplx2
384446
cplx2 x y (fromIntegral . fromEnum -> batch) = do
385447
x `op2` y $ \arr arr1 arr2 ->
386448
af_cplx2 arr arr1 arr2 batch
@@ -430,19 +492,27 @@ tanh = flip op1 af_tanh
430492
root
431493
:: AFType a
432494
=> Array a
495+
-- ^ First input
433496
-> Array a
497+
-- ^ Second input
434498
-> Bool
499+
-- ^ Use batch
435500
-> Array a
501+
-- ^ Result of root
436502
root x y (fromIntegral . fromEnum -> batch) = do
437503
x `op2` y $ \arr arr1 arr2 ->
438504
af_root arr arr1 arr2 batch
439505

440506
pow
441507
:: AFType a
442508
=> Array a
509+
-- ^ First input
443510
-> Array a
511+
-- ^ Second input
444512
-> Bool
513+
-- ^ Use batch
445514
-> Array a
515+
-- ^ Result of pow
446516
pow x y (fromIntegral . fromEnum -> batch) = do
447517
x `op2` y $ \arr arr1 arr2 ->
448518
af_pow arr arr1 arr2 batch

src/ArrayFire/Array.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,11 @@ mkArray
5656
:: forall array
5757
. AFType array
5858
=> [Int]
59+
-- ^ Dimensions
5960
-> [array]
61+
-- ^ Array elements
6062
-> Array array
63+
-- ^ Returned array
6164
{-# NOINLINE mkArray #-}
6265
mkArray dims xs =
6366
unsafePerformIO . mask_ $ do

src/ArrayFire/BLAS.hs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,15 @@ import ArrayFire.Types
2020
-- | The following applies for Sparse-Dense matrix multiplication.
2121
--
2222
-- This function can be used with one sparse input. The sparse input must always be the lhs and the dense matrix must be rhs.
23+
--
2324
-- The sparse array can only be of AF_STORAGE_CSR format.
25+
--
2426
-- The returned array is always dense.
27+
--
2528
-- optLhs an only be one of AF_MAT_NONE, AF_MAT_TRANS, AF_MAT_CTRANS.
29+
--
2630
-- optRhs can only be AF_MAT_NONE.
31+
--
2732
matmul
2833
:: Array a
2934
-- ^ 2D matrix of Array a, left-hand side

src/ArrayFire/LAPACK.hs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,23 @@ import ArrayFire.FFI
1616
import ArrayFire.Types
1717
import ArrayFire.Internal.Defines
1818

19+
-- | This function factorizes a matrix A into two unitary matrices U and Vt, and a diagonal matrix S such that
20+
-- A=U∗S∗Vt
21+
--
22+
-- If A has M rows and N columns, U is of the size M x M , V is of size N x N, and S is of size M x N
23+
--
24+
-- The arrayfire function only returns the non zero diagonal elements of S.
25+
--
1926
svd
2027
:: AFType a
2128
=> Array a
29+
-- ^ Input matrix
2230
-> (Array a, Array a, Array a)
31+
-- ^ 'u' is the output array containing U
32+
--
33+
-- 'v' is the output array containing the diagonal values of sigma, (singular values of the input matrix))
34+
--
35+
-- 'vt' is the output array containing V^H
2336
svd = (`op3p` af_svd)
2437

2538
svdInPlace
@@ -131,5 +144,5 @@ norm arr a b c =
131144
arr `infoFromArray` (\w y -> af_norm w y a b c)
132145

133146
isLAPACKAvailable :: Bool
134-
isLAPACKAvailable =
147+
isLAPACKAvailable =
135148
toEnum . fromIntegral $ afCall1' af_is_lapack_available

test/ArrayFire/LAPACKSpec.hs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,32 @@ spec =
1010
describe "LAPACK spec" $ do
1111
it "Should have LAPACK available" $ do
1212
A.isLAPACKAvailable `shouldBe` True
13+
it "Should perform svd" $ do
14+
let (s,v,d) = A.svd $ A.matrix @Double (4,2) (repeat 1)
15+
A.getDims s `shouldBe` (4,4,1,1)
16+
A.getDims v `shouldBe` (2,1,1,1)
17+
A.getDims d `shouldBe` (2,2,1,1)
18+
it "Should perform svd in place" $ do
19+
let (s,v,d) = A.svdInPlace $ A.matrix @Double (4,2) (repeat 1)
20+
A.getDims s `shouldBe` (4,4,1,1)
21+
A.getDims v `shouldBe` (2,1,1,1)
22+
A.getDims d `shouldBe` (2,2,1,1)
23+
it "Should perform lu" $ do
24+
let (s,v,d) = A.lu $ A.matrix @Double (2,2) [3,1,4,2]
25+
A.getDims s `shouldBe` (2,2,1,1)
26+
A.getDims v `shouldBe` (2,2,1,1)
27+
A.getDims d `shouldBe` (2,1,1,1)
28+
it "Should perform qr" $ do
29+
let (s,v,d) = A.lu $ A.matrix @Double (3,3) [12,6,4,-51,167,24,4,-68,-41]
30+
A.getDims s `shouldBe` (3,3,1,1)
31+
A.getDims v `shouldBe` (3,3,1,1)
32+
A.getDims d `shouldBe` (3,1,1,1)
33+
it "Should get determinant" $ do
34+
let (x,y) = A.det $ A.matrix @Double (2,2) [3,8,4,6]
35+
x `shouldBe` (-14)
36+
it "Should calculate inverse" $ do
37+
let x = flip A.inverse A.None $ A.matrix @Double (2,2) [4,7,2,6]
38+
x `shouldBe` A.matrix @Double (2,2) [0.6,-0.2,-0.7,0.4]
39+
-- it "Should calculate psuedo inverse" $ do
40+
-- let x = A.pinverse (A.matrix @Double (2,2) [4,7,2,6]) 1.0 A.None
41+
-- x `shouldBe` A.matrix @Double (2,2) [0.6,-0.2,-0.7,0.4]

0 commit comments

Comments
 (0)