multrix/src/procedures.nim
array-in-a-matrix 5c954b63b1 accept fractions
2024-02-27 14:01:33 -05:00

181 lines
5.9 KiB
Nim

import strutils, sequtils, terminal, re
#? validate if user input is of correct type
proc getInt: int =
while(true):
try:
return parseInt(readline(stdin))
except:
styledEcho resetStyle, "Please enter an ", styleBright, "integer, " , resetStyle, "try again."
#? validate if user input is of correct type
proc getFloat: float =
while(true):
try:
let number: string = readline(stdin).replace(" ","").replace("\t", "")
#? if the number given is a fraction convert it into decimal
if match(number, re"[0-9]+/[0-9]+"):
let
numerator: float = number.split('/')[0].parseFloat
denominator: float = number.split('/')[1].parseFloat
return numerator / denominator
return parseFloat(number)
except:
styledEcho resetStyle, "Please enter a ", styleBright, "number, " , resetStyle, "try again."
#? prints a matrix to the standard output
proc printMatrix*(matrix: seq[seq[float]]) =
let row: int = matrix.len
for i in countup(1, row):
echo matrix[i-1]
#? get elements of matrix from standard input
proc fillMatrix*(matrix: var seq[seq[float]], row, col: int) =
for i in countup(1, row):
for j in countup(1, col):
echo "Enter item:"
matrix[i-1].add(getFloat())
matrix[i-1].delete(0)
echo matrix[i-1]
#? calculate scalar product
proc calcScalar(factor: float, matrix: seq[seq[float]]): seq[seq[float]] =
let col: int = matrix[0].len
let row: int = matrix.len
var newMatrix = newSeqWith(row, newSeq[float](col))
if col == row and col == 1:
styledEcho fgRed, "\nPure scalar multiplication detected!"
return @[@[ factor * matrix[0][0]]]
for i in countup(0, row-1):
for j in countup(0, col-1):
newMatrix[i][j] = factor * matrix[i][j]
return newMatrix
#? calculate dot product
proc calcDot(matrix1: seq[seq[float]], matrix2: seq[seq[float]]): seq[seq[float]] =
let col1: int = matrix1[0].len
let row1: int = matrix1.len
let col2: int = matrix2[0].len
let row2: int = matrix2.len
var col, row: int
#? check if both matrics are actually scalars
if (col1 == row1 and col1 == 1) and (col2 == row2 and col2 == 1):
styledEcho fgRed, "\nPure scalar multiplication detected!"
return @[@[matrix1[0][0] * matrix2[0][0]]]
#? check if the first matrix is actually a scalar
elif col1 == row1 and col1 == 1:
styledEcho fgRed, "\nMatrix scalar multiplication detected!"
var matrix = newSeqWith(row2, newSeq[float](col2))
matrix = calcScalar(matrix1[0][0], matrix2)
return matrix
#? check if the second matrix is actually a scalar
elif col2 == row2 and col2 == 1:
styledEcho fgRed, "\nMatrix scalar multiplication detected!"
var matrix = newSeqWith(row1, newSeq[float](col1))
matrix = calcScalar(matrix2[0][0], matrix1)
return matrix
elif col1 == row2:
col = col2
row = row1
else:
styledEcho fgRed, "Matrix dimensions mismatched!"
quit QuitFailure
var matrix = newSeqWith(row, newSeq[float](col))
for i in countup(0, row1-1):
for j in countup(0, col2-1):
for k in countup(0, col1-1):
matrix[i][j] = matrix[i][j] + matrix1[i][k] * matrix2[k][j]
return matrix
#? calculate cross product
proc calcCross(vector1: array[3, float], vector2: array[3, float]): array[3, float] =
let i: float = vector1[1] * vector2[2] - vector1[2] * vector2[1]
let j: float = vector1[2] * vector2[0] - vector1[0] * vector2[2]
let k: float = vector1[0] * vector2[1] - vector1[1] * vector2[0]
result = [i, j, k]
proc dot* =
styledEcho styleBright, "Matrix Dot Product"
#? record first matrix
styledEcho "Enter number of ", styleBright, "rows ", resetStyle, "in the first matrix:"
let r1: int = getInt()
styledEcho "Enter number of ", styleBright, "columns ", resetStyle, "in the first matrix:"
let c1: int = getInt()
var m1 = newSeqWith(r1, newSeq[float](c1))
fillMatrix(m1, r1, c1)
echo ""
#? record second matrix
styledEcho "Enter number of ", styleBright, "rows ", resetStyle, "in the second matrix:"
let r2: int = getInt()
styledEcho "Enter number of ", styleBright, "columns ", resetStyle, "in the second matrix:"
let c2: int = getInt()
var m2 = newSeqWith(r2, newSeq[float](c2))
fillMatrix(m2, r2, c2)
#? resultent matrix
let m: seq[seq[float]] = calcDot(m1, m2)
echo "\nFirst matrix is:"
printMatrix(m1)
echo "\nSecond matrix is:"
printMatrix(m2)
echo "\nResult matrix is:"
printMatrix(m)
proc cross* =
styledEcho styleBright, "Vector Cross Product"
type
VECTOR = array[3, float]
var
v1: VECTOR
v2: VECTOR
v: VECTOR
styledEcho "Enter numbers in the ", styleBright, "first ", resetStyle, "vector:"
for i in 0..2:
echo "Enter item:"
v1[i] = getFloat()
styledEcho "Enter numbers in the ", styleBright, "second ", resetStyle, "vector:"
for i in 0..2:
echo "Enter item:"
v2[i] = getFloat()
#? resultent vector
v = calcCross(v1, v2)
echo v1, " \u2A2F ", v2
echo "\nResult vector is:"
echo v
proc scalar* =
styledEcho styleBright, "Matrix Scalar Multiplication"
styledEcho "Enter the " ,styleBright, "scale factor", resetStyle, ":"
let f: float = getFloat()
styledEcho "Enter number of ", styleBright, "rows ", resetStyle, "in the matrix:"
let r: int = getInt()
styledEcho "Enter number of ", styleBright, "columns ", resetStyle, "in the matrix:"
let c: int = getInt()
var m = newSeqWith(r, newSeq[float](c))
fillMatrix(m, r, c)
let M = calcScalar(f, m)
echo "\nInitial matrix is:"
printMatrix(m)
echo "\nScaled matrix is:"
printMatrix(M)