@@ -52,6 +52,13 @@ proc `/.`*[T: SomeNumber|Complex[float32]|Complex[float64]](a, b: Tensor[T]): Te
52
52
else :
53
53
result = map2_inline(tmp_a, tmp_b, x / y )
54
54
55
+ proc `^.` * [T: SomeNumber| Complex[float32 ]| Complex[float64 ]](a, b: Tensor[T]) : Tensor[T] {.noinit.} =
56
+ # # Tensor element-wise exponentiation
57
+ # #
58
+ # # And broadcasted element-wise exponentiation.
59
+ let (tmp_a, tmp_b) = broadcast2(a, b)
60
+ result = map2_inline(tmp_a, tmp_b, pow(x, y))
61
+
55
62
proc `mod` * [T: SomeNumber](a, b: Tensor[T]): Tensor[T] {.noinit.} =
56
63
## Tensor element-wise modulo operation
57
64
##
@@ -195,81 +202,196 @@ proc `/.=`*[T: SomeNumber|Complex[float32]|Complex[float64]](t: var Tensor[T], v
195
202
196
203
197
204
# #################################################
198
- # # Mixed Complex64 tensor - real scalar operations
205
+ # # Mixed complex - real tensor operations
199
206
#
200
- # It is always possible to operate on a Complex64 tensor with a real scalar
201
- # without loss of precission, so we allow it without explicit type conversion.
202
- # This makes complex tensor arithmetic more convenient to use.
207
+ # Since nim's built-in complex module supports mixed complex- real operations
208
+ # we allow them too (but in tensor form). This makes such mixed arithmetic
209
+ # more efficient in addition to more convenient to use.
203
210
204
- proc `+.` * [T: SomeNumber](val: T, t: Tensor[Complex6 4]) : Tensor[Complex64] {.noinit, inline.} =
205
- # # Broadcasted addition for real scalar + Complex64 tensor
206
- # #
207
- # # The scalar is automatically converted to Complex64 before the operation.
208
- let complex_val = complex(float64 (val))
209
- complex_val +. t
211
+ proc `+.` * [T: SomeNumber](a: Tensor[Complex[T]], b: Tensor[T]): Tensor[Complex[T]] {.noinit,inline.} =
212
+ ## Broadcasted addition for tensors of incompatible but broadcastable shape.
213
+ #check_shape(a, b, relaxed_rank1_check = RelaxedRankOne)
214
+ result = map2_inline(a, b, x + y)
210
215
211
- proc `+.` * [T: SomeNumber](t: Tensor[Complex6 4], val: T) : Tensor[Complex64] {.noinit, inline.} =
212
- # # Broadcasted addition for real scalar + Complex64 tensor
213
- # #
214
- # # The scalar is automatically converted to Complex64 before the operation.
215
- let complex_val = complex(float64 (val))
216
- t +. complex_val
216
+ proc `+.`*[T: SomeNumber](a: Tensor[T], b: Tensor[Complex[T]]): Tensor[Complex[T]] {.noinit,inline.} =
217
+ ## Broadcasted addition for tensors of incompatible but broadcastable shape.
218
+ #check_shape(a, b, relaxed_rank1_check = RelaxedRankOne)
219
+ result = map2_inline(a, b, x + y)
217
220
218
- proc `-.` * [T: SomeNumber](val: T, t: Tensor[Complex6 4]) : Tensor[Complex64] {.noinit, inline.} =
219
- # # Broadcasted subtraction for real scalar - Complex64 tensor
220
- # #
221
- # # The scalar is automatically converted to Complex64 before the operation.
222
- let complex_val = complex(float64 (val))
223
- complex_val -. t
221
+ proc `-.`*[T: SomeNumber](a: Tensor[Complex[T]], b: Tensor[T]): Tensor[Complex[T]] {.noinit,inline.} =
222
+ ## Broadcasted subtraction for tensors of incompatible but broadcastable shape.
223
+ #check_shape(a, b, relaxed_rank1_check = RelaxedRankOne)
224
+ result = map2_inline(a, b, x - y)
224
225
225
- proc `-.` * [T: SomeNumber](t: Tensor[Complex6 4], val: T) : Tensor[Complex64] {.noinit, inline.} =
226
- # # Broadcasted subtraction for real scalar - Complex64 tensor
227
- # #
228
- # # The scalar is automatically converted to Complex64 before the operation.
229
- let complex_val = complex(float64 (val))
230
- t -. complex_val
226
+ proc `-.`*[T: SomeNumber](a: Tensor[T], b: Tensor[Complex[T]]): Tensor[Complex[T]] {.noinit,inline.} =
227
+ ## Broadcasted subtraction for tensors of incompatible but broadcastable shape.
228
+ #check_shape(a, b, relaxed_rank1_check = RelaxedRankOne)
229
+ result = map2_inline(a, b, x - y)
231
230
232
- proc `*.` * [T: SomeNumber](val: T, t : Tensor[Complex6 4 ]) : Tensor[Complex64] {.noinit, inline .} =
233
- # # Broadcasted multiplication for real scalar * Complex64 tensor
231
+ proc `*.`*[T: SomeNumber](a: Tensor[Complex[T]], b : Tensor[T ]): Tensor[Complex[T]] {.noinit.} =
232
+ ## Element-wise multiplication (Hadamard product).
234
233
##
235
- # # The scalar is automatically converted to Complex64 before the operation .
236
- let complex_val = complex( float64 (val) )
237
- complex_val *. t
234
+ ## And broadcasted element-wise multiplication .
235
+ #check_shape(a, b, relaxed_rank1_check = RelaxedRankOne )
236
+ result = map2_inline(a, b, x * y)
238
237
239
- proc `*.` * [T: SomeNumber](t : Tensor[Complex6 4 ], val: T ) : Tensor[Complex64] {.noinit, inline .} =
240
- # # Broadcasted multiplication for real scalar * Complex64 tensor
238
+ proc `*.`*[T: SomeNumber](a : Tensor[T ], b: Tensor[Complex[T]] ): Tensor[Complex[T]] {.noinit.} =
239
+ ## Element-wise multiplication (Hadamard product).
241
240
##
242
- # # The scalar is automatically converted to Complex64 before the operation .
243
- let complex_val = complex( float64 (val) )
244
- t *. complex_val
241
+ ## And broadcasted element-wise multiplication .
242
+ #check_shape(a, b, relaxed_rank1_check = RelaxedRankOne )
243
+ result = map2_inline(a, b, x * y)
245
244
246
- proc `/.` * [T: SomeNumber](val: T, t : Tensor[Complex6 4 ]) : Tensor[Complex64] {.noinit, inline .} =
247
- # # Broadcasted division for real scalar / Complex64 tensor
245
+ proc `/.`*[T: SomeNumber](a: Tensor[Complex[T]], b : Tensor[T ]): Tensor[Complex[T]] {.noinit.} =
246
+ ## Tensor element-wise division
248
247
##
249
- # # The scalar is automatically converted to Complex64 before the operation.
250
- let complex_val = complex(float64 (val))
251
- complex_val /. t
248
+ ## And broadcasted element-wise division.
249
+ #check_shape(a, b, relaxed_rank1_check = RelaxedRankOne)
250
+ when T is SomeInteger:
251
+ result = map2_inline(a, b, x div y )
252
+ else:
253
+ result = map2_inline(a, b, x / y )
252
254
253
- proc `/.` * [T: SomeNumber](t : Tensor[Complex6 4 ], val: T ) : Tensor[Complex64] {.noinit, inline .} =
254
- # # Broadcasted division for real scalar / Complex64 tensor
255
+ proc `/.`*[T: SomeNumber](a : Tensor[T ], b: Tensor[Complex[T]] ): Tensor[Complex[T]] {.noinit.} =
256
+ ## Tensor element-wise division
255
257
##
256
- # # The scalar is automatically converted to Complex64 before the operation.
257
- let complex_val = complex(float64 (val))
258
- t /. complex_val
258
+ ## And broadcasted element-wise division.
259
+ #check_shape(a, b, relaxed_rank1_check = RelaxedRankOne)
260
+ when T is SomeInteger:
261
+ result = map2_inline(a, b, x div y )
262
+ else:
263
+ result = map2_inline(a, b, x / y )
259
264
260
- proc `^.` * [T: SomeNumber](val: T, t: Tensor[Complex6 4]) : Tensor[Complex64] {.noinit, inline.} =
261
- # # Broadcasted exponentiation for real scalar ^ Complex64 tensor
265
+ proc `^.`*[T: SomeFloat](a: Tensor[Complex[T]], b: Tensor[T]): Tensor[Complex[T]] {.noinit.} =
266
+ ## Tensor element-wise exponentiation for real complex ^ scalar tensors
267
+ #check_shape(a, b, relaxed_rank1_check = RelaxedRankOne)
268
+ result = map2_inline(a, b, pow(x, complex(y)))
269
+
270
+ proc `^.`*[T: SomeFloat](a: Tensor[T], b: Tensor[Complex[T]]): Tensor[Complex[T]] {.noinit.} =
271
+ ## Tensor element-wise exponentiation for real scalar ^ complex tensors
272
+ #check_shape(a, b, relaxed_rank1_check = RelaxedRankOne)
273
+ result = map2_inline(a, b, pow(complex(x), y))
274
+
275
+ proc `mod`*[T: SomeNumber](a: Tensor[Complex[T]], b: Tensor[T]): Tensor[Complex[T]] {.noinit.} =
276
+ ## Tensor element-wise modulo operation
262
277
##
263
- # # The scalar is automatically converted to Complex64 before the operation.
264
- let complex_val = complex( float64 (val) )
265
- complex_val ^. t
278
+ ## And broadcasted element-wise modulo operation.
279
+ #check_shape(a, b, relaxed_rank1_check = RelaxedRankOne )
280
+ result = map2_inline(a, b, x mod y)
266
281
267
- proc `^. ` * [T: SomeNumber](t : Tensor[Complex6 4 ], val: T ) : Tensor[Complex64] {.noinit, inline .} =
268
- # # Broadcasted exponentiation for real scalar ^ Complex64 tensor
282
+ proc `mod `*[T: SomeNumber](a : Tensor[T ], b: Tensor[Complex[T]] ): Tensor[Complex[T]] {.noinit.} =
283
+ ## Tensor element-wise modulo operation
269
284
##
270
- # # The scalar is automatically converted to Complex64 before the operation.
271
- let complex_val = complex(float64 (val))
272
- t ^. complex_val
285
+ ## And broadcasted element-wise modulo operation.
286
+ #check_shape(a, b, relaxed_rank1_check = RelaxedRankOne)
287
+ result = map2_inline(a, b, x mod y)
288
+
289
+ # #################################################
290
+ # # Mixed complex tensor - real scalar operations
291
+ #
292
+ # Since nim's built-in complex module supports mixed complex-real operations
293
+ # we allow them too (but in tensor form). This makes such mixed arithmetic
294
+ # more efficient in addition to more convenient to use.
295
+
296
+ proc `+.`*[T: SomeNumber](val: T, t: Tensor[Complex[T]]): Tensor[Complex[T]] {.noinit, inline.} =
297
+ ## Broadcasted addition for real scalar + complex tensor
298
+ returnEmptyIfEmpty(t)
299
+ result = t.map_inline(val + x)
300
+
301
+ proc `+.`*[T: SomeNumber](val: Complex[T], t: Tensor[T]): Tensor[Complex[T]] {.noinit, inline.} =
302
+ ## Broadcasted addition for real scalar + complex tensor
303
+ returnEmptyIfEmpty(t)
304
+ result = t.map_inline(val + x)
305
+
306
+ proc `+.`*[T: SomeNumber](t: Tensor[Complex[T]], val: T): Tensor[Complex[T]] {.noinit, inline.} =
307
+ ## Broadcasted addition for real scalar + complex tensor
308
+ returnEmptyIfEmpty(t)
309
+ result = t.map_inline(x + val)
310
+
311
+ proc `+.`*[T: SomeNumber](t: Tensor[T], val: Complex[T]): Tensor[Complex[T]] {.noinit, inline.} =
312
+ ## Broadcasted addition for real scalar + complex tensor
313
+ returnEmptyIfEmpty(t)
314
+ result = t.map_inline(x + val)
315
+
316
+ proc `-.`*[T: SomeNumber](val: T, t: Tensor[Complex[T]]): Tensor[Complex[T]] {.noinit, inline.} =
317
+ ## Broadcasted subtraction for real scalar - complex tensor
318
+ returnEmptyIfEmpty(t)
319
+ result = t.map_inline(val - x)
320
+
321
+ proc `-.`*[T: SomeNumber](val: Complex[T], t: Tensor[T]): Tensor[Complex[T]] {.noinit, inline.} =
322
+ ## Broadcasted subtraction for real scalar - complex tensor
323
+ returnEmptyIfEmpty(t)
324
+ result = t.map_inline(val + x)
325
+
326
+ proc `-.`*[T: SomeNumber](t: Tensor[Complex[T]], val: T): Tensor[Complex[T]] {.noinit, inline.} =
327
+ ## Broadcasted subtraction for real scalar - complex tensor
328
+ returnEmptyIfEmpty(t)
329
+ result = t.map_inline(x - val)
330
+
331
+ proc `-.`*[T: SomeNumber](t: Tensor[T], val: Complex[T]): Tensor[Complex[T]] {.noinit, inline.} =
332
+ ## Broadcasted subtraction for real scalar - complex tensor
333
+ returnEmptyIfEmpty(t)
334
+ result = t.map_inline(x - val)
335
+
336
+ proc `*.`*[T: SomeNumber](val: T, t: Tensor[Complex[T]]): Tensor[Complex[T]] {.noinit, inline.} =
337
+ ## Broadcasted multiplication for real scalar * complex tensor
338
+ returnEmptyIfEmpty(t)
339
+ result = t.map_inline(val * x)
340
+
341
+ proc `*.`*[T: SomeNumber](val: Complex[T], t: Tensor[T]): Tensor[Complex[T]] {.noinit, inline.} =
342
+ ## Broadcasted multiplication for real scalar * complex tensor
343
+ returnEmptyIfEmpty(t)
344
+ result = t.map_inline(val * x)
345
+
346
+ proc `*.`*[T: SomeNumber](t: Tensor[Complex[T]], val: T): Tensor[Complex[T]] {.noinit, inline.} =
347
+ ## Broadcasted multiplication for real scalar * complex tensor
348
+ returnEmptyIfEmpty(t)
349
+ result = t.map_inline(x * val)
350
+
351
+ proc `*.`*[T: SomeNumber](t: Tensor[T], val: Complex[T]): Tensor[Complex[T]] {.noinit, inline.} =
352
+ ## Broadcasted multiplication for real scalar * complex tensor
353
+ returnEmptyIfEmpty(t)
354
+ result = t.map_inline(x * val)
355
+
356
+ proc `/.`*[T: SomeNumber](val: T, t: Tensor[Complex[T]]): Tensor[Complex[T]] {.noinit, inline.} =
357
+ ## Broadcasted division for real scalar / complex tensor
358
+ returnEmptyIfEmpty(t)
359
+ result = t.map_inline(val / x)
360
+
361
+ proc `/.`*[T: SomeNumber](val: Complex[T], t: Tensor[T]): Tensor[Complex[T]] {.noinit, inline.} =
362
+ ## Broadcasted division for real scalar / complex tensor
363
+ returnEmptyIfEmpty(t)
364
+ result = t.map_inline(val / x)
365
+
366
+ proc `/.`*[T: SomeNumber](t: Tensor[Complex[T]], val: T): Tensor[Complex[T]] {.noinit, inline.} =
367
+ ## Broadcasted division for real scalar / complex tensor
368
+ returnEmptyIfEmpty(t)
369
+ result = t.map_inline(x / val)
370
+
371
+ proc `/.`*[T: SomeNumber](t: Tensor[T], val: Complex[T]): Tensor[Complex[T]] {.noinit, inline.} =
372
+ ## Broadcasted division for real scalar / complex tensor
373
+ returnEmptyIfEmpty(t)
374
+ result = t.map_inline(x / val)
375
+
376
+ proc `^.`*[T: SomeFloat](val: T, t: Tensor[Complex[T]]): Tensor[Complex[T]] {.noinit, inline.} =
377
+ ## Broadcasted exponentiation for real scalar ^ complex tensor
378
+ returnEmptyIfEmpty(t)
379
+ result = t.map_inline(pow(complex(val), x))
380
+
381
+ proc `^.`*[T: SomeFloat](val: Complex[T], t: Tensor[T]): Tensor[Complex[T]] {.noinit, inline.} =
382
+ ## Broadcasted exponentiation for real scalar ^ complex tensor
383
+ returnEmptyIfEmpty(t)
384
+ result = t.map_inline(pow(val, x))
385
+
386
+ proc `^.`*[T: SomeFloat](t: Tensor[Complex[T]], val: T): Tensor[Complex[T]] {.noinit, inline.} =
387
+ ## Broadcasted exponentiation for real scalar ^ complex tensor
388
+ returnEmptyIfEmpty(t)
389
+ result = t.map_inline(pow(x, val))
390
+
391
+ proc `^.`*[T: SomeFloat](t: Tensor[T], val: Complex[T]): Tensor[Complex[T]] {.noinit, inline.} =
392
+ ## Broadcasted exponentiation for real scalar ^ complex tensor
393
+ returnEmptyIfEmpty(t)
394
+ result = t.map_inline(pow(complex(x), val))
273
395
274
396
proc `+.=`*[T: SomeNumber](t: var Tensor[Complex6 4], val: T) {.inline.} =
275
397
# # Complex64 tensor in-place addition with a real scalar.
0 commit comments