How to resolve the algorithm Element-wise operations step by step in the Nim programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Element-wise operations step by step in the Nim programming language

Table of Contents

Problem Statement

This task is similar to:

Implement basic element-wise matrix-matrix and scalar-matrix operations, which can be referred to in other, higher-order tasks. Implement:

Extend the task if necessary to include additional basic operations, which should not require their own specialised task.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Element-wise operations step by step in the Nim programming language

Source code in the nim programming language

import math, strutils

type Matrix[height, width: static Positive; T: SomeNumber] = array[height, array[width, T]]

####################################################################################################

proc `$`(m: Matrix): string =
  for i, row in m:
    var line = "["
    for j, val in row:
      line.addSep(" ", 1)
      line.add($val)
    line.add("]\n")
    result.add(line)

####################################################################################################
# Templates.

template elementWise(m1, m2: Matrix; op: proc(v1, v2: m1.T): auto): untyped =
  var result: Matrix[m1.height, m1.width, m1.T]
  for i in 0..<m1.height:
    for j in 0..<m1.width:
      result[i][j] = op(m1[i][j], m2[i][j])
  result

template scalarOp(m: Matrix; val: SomeNumber; op: proc(v1, v2: SomeNumber): auto): untyped =
  var result: Matrix[m.height, m.width, m.T]
  for i in 0..<m.height:
    for j in 0..<m.width:
      result[i][j] = op(m[i][j], val)
  result

template scalarOp(val: SomeNumber; m: Matrix; op: proc(v1, v2: SomeNumber): auto): untyped =
  var result: Matrix[m.height, m.width, m.T]
  for i in 0..<m.height:
    for j in 0..<m.width:
      result[i][j] = op(val, m[i][j])
  result

####################################################################################################
# Access functions.

func `[]`(m: Matrix; i, j: int): m.T =
  m[i][j]

func `[]=`(m: var Matrix; i, j: int; val: SomeNumber) =
  m[i][j] = val

####################################################################################################
# Elementwise operations.

func `+`(m1, m2: Matrix): Matrix =
  elementWise(m1, m2, `+`)

func `-`(m1, m2: Matrix): Matrix =
  elementWise(m1, m2, `-`)

func `*`(m1, m2: Matrix): Matrix =
  elementWise(m1, m2, `*`)

func `div`(m1, m2: Matrix): Matrix =
  elementWise(m1, m2, `div`)

func `mod`(m1, m2: Matrix): Matrix =
  elementWise(m1, m2, `mod`)

func `/`(m1, m2: Matrix): Matrix =
  elementWise(m1, m2, `/`)

func `^`(m1, m2: Matrix): Matrix =
  # Cannot use "elementWise" template as it requires both operator arguments
  # to be of type "m1.T" (and second argument of `^` is "Natural", not "int").
  for i in 0..<m1.height:
    for j in 0..<m1.width:
      result[i][j] = m1[i][j] ^ m2[i][j]

func pow(m1, m2: Matrix): Matrix =
  elementWise(m1, m2, pow)

####################################################################################################
# Matrix-scalar and scalar-matrix operations.

func `+`(m: Matrix; val: SomeNumber): Matrix =
  scalarOp(m, val, `+`)

func `+`(val: SomeNumber; m: Matrix): Matrix =
  scalarOp(val, m, `+`)

func `-`(m: Matrix; val: SomeNumber): Matrix =
  scalarOp(m, val, `-`)

func `-`(val: SomeNumber; m: Matrix): Matrix =
  scalarOp(val, m, `-`)

func `*`(m: Matrix; val: SomeNumber): Matrix =
  scalarOp(m, val, `*`)

func `*`(val: SomeNumber; m: Matrix): Matrix =
  scalarOp(val, m, `*`)

func `div`(m: Matrix; val: SomeNumber): Matrix =
  scalarOp(m, val, `div`)

func `div`(val: SomeNumber; m: Matrix): Matrix =
  scalarOp(val, m, `div`)

func `mod`(m: Matrix; val: m.T): Matrix =
  scalarOp(m, val, `mod`)

func `mod`(val: SomeNumber; m: Matrix): Matrix =
  scalarOp(val, m, `mod`)

proc `/`(m: Matrix; val: SomeNumber): Matrix =
  scalarOp(m, val, `/`)

func `/`(val: SomeNumber; m: Matrix): Matrix =
  scalarOp(val, m, `/`)

func `^`(m: Matrix; val: Natural): Matrix =
  # Cannot use "elementWise" template as it requires both operator arguments
  # to be of type "m.T" (and second argument of `^` is "Natural", not "int").
  for i in 0..<m.height:
    for j in 0..<m.width:
      result[i][j] = m[i][j] ^ val

func `^`(val: Natural; m: Matrix): Matrix =
  # Cannot use "elementWise" template as it requires both operator arguments
  # to be of type "m.T" (and second argument of `^` is "Natural", not "int").
  for i in 0..<m.height:
    for j in 0..<m.width:
      result[i][j] = val ^ m[i][j]

func pow(m: Matrix; val: SomeNumber): Matrix =
  scalarOp(m, val, pow)

func `pow`(val: SomeNumber; m: Matrix): Matrix =
  scalarOp(val, m, `pow`)

#———————————————————————————————————————————————————————————————————————————————————————————————————

# Operations on integer matrices.
let mint1: Matrix[2, 2, int] = [[1, 2], [3, 4]]
let mint2: Matrix[2, 2, int] = [[2, 1], [4, 2]]
echo "Integer matrices"
echo "----------------\n"
echo "m1:"
echo mint1
echo "m2:"
echo mint2
echo "m1 + m2"
echo mint1 + mint2
echo "m1 - m2"
echo mint1 - mint2
echo "m1 * m2"
echo mint1 * mint2
echo "m1 div m2"
echo mint1 div mint2
echo "m1 mod m2"
echo mint1 mod mint2
echo "m1^m2"
echo mint1^mint2
echo "2 * m1"
echo 2 * mint1
echo "m1 * 2"
echo mint1 * 2
echo "m1^2"
echo mint1 ^ 2
echo "2^m1"
echo 2 ^ mint1

# Operations on float matrices.
let mfloat1: Matrix[2, 3, float] = [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]
let mfloat2: Matrix[2, 3, float] = [[2.0, 2.0, 2.0], [3.0, 3.0, 3.0]]
echo "\nFloat matrices"
echo "--------------\n"
echo "m1"
echo mfloat1
echo "m2"
echo mfloat2
echo "m1 + m2"
echo mfloat1 + mfloat2
echo "m1 - m2"
echo mfloat1 - mfloat2
echo "m1 * m2"
echo mfloat1 * mfloat2
echo "m1 / m2"
echo mfloat1 / mfloat2
echo "pow(m1, m2)"
echo pow(mfloat1, mfloat2)
echo "pow(m1, 2.0)"
echo pow(mfloat1, 2.0)
echo "pow(2.0, m1)"
echo pow(2.0, mfloat1)


  

You may also check:How to resolve the algorithm Singleton step by step in the Python programming language
You may also check:How to resolve the algorithm Keyboard input/Keypress check step by step in the Python programming language
You may also check:How to resolve the algorithm Horizontal sundial calculations step by step in the Ruby programming language
You may also check:How to resolve the algorithm Guess the number step by step in the Vala programming language
You may also check:How to resolve the algorithm Conditional structures step by step in the BQN programming language