@@ -52,6 +52,13 @@ proc `/.`*[T: SomeNumber|Complex[float32]|Complex[float64]](a, b: Tensor[T]): Te
5252 else :
5353 result = map2_inline (tmp_a, tmp_b, x / y )
5454
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+
5562proc `mod` * [T: SomeNumber ](a, b: Tensor [T]): Tensor [T] {.noinit .} =
5663 # # Tensor element-wise modulo operation
5764 # #
@@ -195,81 +202,196 @@ proc `/.=`*[T: SomeNumber|Complex[float32]|Complex[float64]](t: var Tensor[T], v
195202
196203
197204# #################################################
198- # # Mixed Complex64 tensor - real scalar operations
205+ # # Mixed complex - real tensor operations
199206#
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.
203210
204- proc `+.` * [T: SomeNumber ](val: T, t: Tensor [Complex64 ]): 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)
210215
211- proc `+.` * [T: SomeNumber ](t: Tensor [Complex64 ], 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)
217220
218- proc `-.` * [T: SomeNumber ](val: T, t: Tensor [Complex64 ]): 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)
224225
225- proc `-.` * [T: SomeNumber ](t: Tensor [Complex64 ], 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)
231230
232- proc `*.` * [T: SomeNumber ](val: T, t : Tensor [Complex64 ]): 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).
234233 # #
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)
238237
239- proc `*.` * [T: SomeNumber ](t : Tensor [Complex64 ], 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).
241240 # #
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)
245244
246- proc `/.` * [T: SomeNumber ](val: T, t : Tensor [Complex64 ]): 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
248247 # #
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 )
252254
253- proc `/.` * [T: SomeNumber ](t : Tensor [Complex64 ], 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
255257 # #
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 )
259264
260- proc `^.` * [T: SomeNumber ](val: T, t: Tensor [Complex64 ]): 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
262277 # #
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)
266281
267- proc `^. ` * [T: SomeNumber ](t : Tensor [Complex64 ], 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
269284 # #
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))
273395
274396proc `+.=` * [T: SomeNumber ](t: var Tensor [Complex64 ], val: T) {.inline .} =
275397 # # Complex64 tensor in-place addition with a real scalar.
0 commit comments