Matft is Numpy-like library in Swift. Function name and usage is similar to Numpy.
This version is type-safe, but slightly slower than original one(master branch)
-
Many types
-
Pretty print
-
Indexing
- Positive
- Negative
- Boolean
-
Slicing
- Start / To / By
- New Axis
-
View
- Assignment
-
Conversion
- Broadcast
- Transpose
- Reshape
- Astype
-
Mathematic
- Arithmetic
- Statistic
- Linear Algebra
...etc.
See Function List for all functions.
-
The MfArray such like a numpy.ndarray
let a = MfArray<Int>([[[ -8, -7, -6, -5], [ -4, -3, -2, -1]], [[ 0, 1, 2, 3], [ 4, 5, 6, 7]]]) let aa = Matft.arange(start: -8, to: 8, by: 1, shape: [2,2,4]) print(a) print(aa) /* mfarray = [[[ -8, -7, -6, -5], [ -4, -3, -2, -1]], [[ 0, 1, 2, 3], [ 4, 5, 6, 7]]], type=Int, shape=[2, 2, 4] mfarray = [[[ -8, -7, -6, -5], [ -4, -3, -2, -1]], [[ 0, 1, 2, 3], [ 4, 5, 6, 7]]], type=Int, shape=[2, 2, 4] */
-
You can use specific Type comformed to MfTypable.
※Note that stored data type will be Float or Double only (comformed
MfStorable
) even if you setInt
. So, if you input big number to MfArray, it may be cause to overflow or strange results in any calculation (+, -, *, /,... etc.). But I believe this is not problem in practical use. -
MfTypeable list is below
Bool, UInt8, UInt16, UInt32, UInt64, UInt, Int8, Int16, Int32, Int64, Int, Float, Double: MfTypable
-
Also, you can convert MfType easily using
astype
let a = MfArray<Int>([[[ -8, -7, -6, -5], [ -4, -3, -2, -1]], [[ 0, 1, 2, 3], [ 4, 5, 6, 7]]]) print(aa.astype(Double.self)) /* mfarray = [[[ -8.0, -7.0, -6.0, -5.0], [ -4.0, -3.0, -2.0, -1.0]], [[ 0.0, 1.0, 2.0, 3.0], [ 4.0, 5.0, 6.0, 7.0]]], type=Double, shape=[2, 2, 4] */
- You can access specific data using subscript.
You can set MfSlice (see below's list) to subscript.
-
MfSlice(start: Int? = nil, to: Int? = nil, by: Int = 1)
-
Matft.newaxis
-
~< //this is prefix, postfix and infix operator. same as python's slice, ":"
-
Normal indexing
let a = Matft.arange(start: 0, to: 27, by: 1, shape: [3,3,3]) print(a) /* mfarray = [[[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8]], [[ 9, 10, 11], [ 12, 13, 14], [ 15, 16, 17]], [[ 18, 19, 20], [ 21, 22, 23], [ 24, 25, 26]]], type=Int, shape=[3, 3, 3] */ print(a[2,1,0]) // 21
-
If you replace
:
with~<
, you can get sliced mfarray. Note that usea[0~<]
instead ofa[:]
to get all elements along axis.print(a[~<1]) //same as a[:1] for numpy /* mfarray = [[[ 9, 10, 11], [ 12, 13, 14], [ 15, 16, 17]]], type=Int, shape=[1, 3, 3] */ print(a[1~<3]) //same as a[1:3] for numpy /* mfarray = [[[ 9, 10, 11], [ 12, 13, 14], [ 15, 16, 17]], [[ 18, 19, 20], [ 21, 22, 23], [ 24, 25, 26]]], type=Int, shape=[2, 3, 3] */ print(a[~<~<2]) //same as a[::2] for numpy //print(a[~<<2]) //alias /* mfarray = [[[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8]], [[ 18, 19, 20], [ 21, 22, 23], [ 24, 25, 26]]], type=Int, shape=[2, 3, 3] */
-
Negative indexing is also available That's implementation was hardest for me...
print(a[~<-1]) /* mfarray = [[[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8]], [[ 9, 10, 11], [ 12, 13, 14], [ 15, 16, 17]]], type=Int, shape=[2, 3, 3] */ print(a[-1~<-3]) /* mfarray = [], type=Int, shape=[0, 3, 3] */ print(a[~<~<-1]) //print(a[~<<-1]) //alias /* mfarray = [[[ 18, 19, 20], [ 21, 22, 23], [ 24, 25, 26]], [[ 9, 10, 11], [ 12, 13, 14], [ 15, 16, 17]], [[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8]]], type=Int, shape=[3, 3, 3]*/
-
You can use boolean indexing.
Caution! I don't check performance, so this boolean indexing may be slow
let img = MfArray<UInt8>([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) img[img > 3] = MfArray<UInt8>([10]) print(img) /* mfarray = [[ 1, 2, 3], [ 10, 10, 10], [ 10, 10, 10]], type=UInt8, shape=[3, 3] */
-
Note that returned subscripted mfarray will have
base
property (is similar toview
in Numpy). See numpy doc in detail.let a = Matft.arange(start: 0, to: 4*4*2, by: 1, shape: [4,4,2]) let b = a[0~<, 1] b[~<<-1] = MfArray<Int>([9999]) // cannot pass Int directly such like 9999 print(a) /* mfarray = [[[ 0, 1], [ 9999, 9999], [ 4, 5], [ 6, 7]], [[ 8, 9], [ 9999, 9999], [ 12, 13], [ 14, 15]], [[ 16, 17], [ 9999, 9999], [ 20, 21], [ 22, 23]], [[ 24, 25], [ 9999, 9999], [ 28, 29], [ 30, 31]]], type=Int, shape=[4, 4, 2] */
Below is Matft's function list. As I mentioned above, almost functions are similar to Numpy. Also, these function use Accelerate framework inside, the perfomance may keep high.
* means method function exists too. Shortly, you can use a.shallowcopy()
where a
is MfArray
.
^ means method function only. Shortly, you can use a.tolist()
not Matft.tolist
where a
is MfArray
.
- Creation
Matft | Numpy |
---|---|
*Matft.shallowcopy | *numpy.copy |
*Matft.deepcopy | copy.deepcopy |
Matft.nums | numpy.ones * N |
Matft.nums_like | numpy.ones_like * N |
Matft.arange | numpy.arange |
Matft.eye | numpy.eye |
Matft.diag | numpy.diag |
Matft.vstack | numpy.vstack |
Matft.hstack | numpy.hstack |
Matft.concatenate | numpy.concatenate |
- Conversion
Matft | Numpy |
---|---|
*Matft.astype | *numpy.astype |
*Matft.transpose | *numpy.transpose |
*Matft.expand_dims | *numpy.expand_dims |
*Matft.squeeze | *numpy.squeeze |
*Matft.broadcast_to | *numpy.broadcast_to |
*Matft.conv_order | *numpy.ascontiguousarray |
*Matft.flatten | *numpy.flatten |
*Matft.flip | *numpy.flip |
*Matft.clip | *numpy.clip |
*Matft.swapaxes | *numpy.swapaxes |
*Matft.moveaxis | *numpy.moveaxis |
*Matft.sort | *numpy.sort |
*Matft.argsort | *numpy.argsort |
^MfArray.toArray | ^numpy.ndarray.tolist |
-
File
save function has not developed yet.
Matft | Numpy |
---|---|
Matft.file.loadtxt | numpy.loadtxt |
Matft.file.genfromtxt | numpy.genfromtxt |
-
Operation
Line 2 is infix (prefix) operator.
Matft | Numpy |
---|---|
Matft.add + |
numpy.add + |
Matft.sub - |
numpy.sub - |
Matft.div / |
numpy.div . |
Matft.mul * |
numpy.multiply * |
Matft.inner *+ |
numpy.inner n/a |
Matft.cross *^ |
numpy.cross n/a |
Matft.matmul *& |
numpy.matmul @ |
Matft.equal === |
numpy.equal == |
Matft.not_equal !== |
numpy.not_equal != |
Matft.less < |
numpy.less < |
Matft.less_equal <= |
numpy.less_equal <= |
Matft.greater > |
numpy.greater > |
Matft.greater_equal >= |
numpy.greater_equal >= |
Matft.allEqual == |
numpy.array_equal n/a |
Matft.neg - |
numpy.negative - |
- Math function
Matft | Numpy |
---|---|
Matft.math.sin | numpy.sin |
Matft.math.asin | numpy.asin |
Matft.math.sinh | numpy.sinh |
Matft.math.asinh | numpy.asinh |
Matft.math.sin | numpy.cos |
Matft.math.acos | numpy.acos |
Matft.math.cosh | numpy.cosh |
Matft.math.acosh | numpy.acosh |
Matft.math.tan | numpy.tan |
Matft.math.atan | numpy.atan |
Matft.math.tanh | numpy.tanh |
Matft.math.atanh | numpy.atanh |
Matft.math.sqrt | numpy.sqrt |
Matft.math.rsqrt | numpy.rsqrt |
Matft.math.exp | numpy.exp |
Matft.math.log | numpy.log |
Matft.math.log2 | numpy.log2 |
Matft.math.log10 | numpy.log10 |
*Matft.math.ceil | numpy.ceil |
*Matft.math.floor | numpy.floor |
*Matft.math.trunc | numpy.trunc |
*Matft.math.nearest | numpy.nearest |
*Matft.math.round | numpy.round |
Matft.math.abs | numpy.abs |
Matft.math.reciprocal | numpy.reciprocal |
Matft.math.power | numpy.power |
Matft.math.square | numpy.square |
Matft.math.sign | numpy.sign |
- Statistics function
Matft | Numpy |
---|---|
*Matft.stats.mean | *numpy.mean |
*Matft.stats.max | *numpy.max |
*Matft.stats.argmax | *numpy.argmax |
*Matft.stats.min | *numpy.min |
*Matft.stats.argmin | *numpy.argmin |
*Matft.stats.sum | *numpy.sum |
Matft.stats.maximum | numpy.maximum |
Matft.stats.minimum | numpy.minimum |
Matft.stats.sumsqrt | n/a |
Matft.stats.squaresum | n/a |
- Linear algebra
Matft | Numpy |
---|---|
Matft.linalg.solve | numpy.linalg.solve |
Matft.linalg.inv | numpy.linalg.inv |
Matft.linalg.det | numpy.linalg.det |
Matft.linalg.eigen | numpy.linalg.eig |
Matft.linalg.svd | numpy.linalg.svd |
Matft.linalg.polar_left | scipy.linalg.polar |
Matft.linalg.polar_right | scipy.linalg.polar |
Matft.linalg.normlp_vec | scipy.linalg.norm |
Matft.linalg.normfro_mat | scipy.linalg.norm |
Matft.linalg.normnuc_mat | scipy.linalg.norm |