mers/examples/05_Matrix_Multiplicator.mers

129 lines
2.6 KiB
Plaintext
Raw Permalink Normal View History

2023-10-27 19:19:42 +02:00
parse_matrix_line := input -> {
vals := input.str_split(" ")
2023-10-27 19:19:42 +02:00
vals_len := vals.len
// reverse vals
2024-06-19 13:58:30 +02:00
// vals_rev := {() -> &vals.pop}.as_list
nums := vals.filter_map(v -> v.parse_float).as_list
2023-10-27 19:19:42 +02:00
if nums.len.eq(vals_len)
if nums.len.signum.eq(1)
(nums)
else ()
else ()
}
read_matrix_line := width -> {
2024-06-19 13:58:30 +02:00
().read_line.try((line) -> line.trim, () -> "").parse_matrix_line.try(
2023-10-27 19:19:42 +02:00
(line) -> {
line := [List<Float>] line
2023-10-27 19:19:42 +02:00
w := width.deref
if w.eq(0) {
width = line.len
} else {
loop {
if line.len.subtract(w).signum.eq(-1) {
&line.push(0.0)
} else (())
}
2023-10-27 19:19:42 +02:00
}
(line)
}
() -> ()
2024-03-22 16:50:01 +01:00
)
2023-10-27 19:19:42 +02:00
}
read_matrix := () -> {
width := 0
2024-03-22 16:50:01 +01:00
if false &width.read_matrix_line
2023-10-27 19:19:42 +02:00
{ () -> &width.read_matrix_line }.as_list
}
matrix_get := (matrix, (line, col)) -> {
2024-03-22 16:50:01 +01:00
matrix.get(line).try(
2023-10-27 19:19:42 +02:00
() -> ()
(line) -> line.get(col)
2024-03-22 16:50:01 +01:00
)
2023-10-27 19:19:42 +02:00
}
leftpad := (str, l) -> {
str := (str).concat
2023-11-07 20:24:20 +01:00
d := l.subtract(str.len)
loop {
if d.signum.eq(1) {
&str = (" ", str).concat
&d = d.subtract(1)
} else (())
}
2023-10-27 19:19:42 +02:00
str
}
matrix_print := matrix -> {
height := matrix.len
width := 0
val_len := 0
matrix.for_each(line -> {
l := line.len
2023-11-07 20:24:20 +01:00
if width.subtract(l).signum.eq(-1)
2023-10-27 19:19:42 +02:00
&width = l
line.for_each(val -> {
l := (val).concat.len
2023-11-07 20:24:20 +01:00
if val_len.subtract(l).eq(-1)
2023-10-27 19:19:42 +02:00
&val_len = l
})
})
&val_len = val_len.sum(1)
(height, "x", width, "-matrix").concat.println
matrix.for_each(line -> {
"(".print
line.for_each(val -> val.leftpad(val_len).print)
" )".println
})
}
2024-03-22 16:50:01 +01:00
fget := v -> v.get.try(
2023-10-27 19:19:42 +02:00
() -> {
2024-06-19 13:58:30 +02:00
("called fget but get returned (): ", v).concat.panic
2023-10-27 19:19:42 +02:00
}
(v) -> v
2024-03-22 16:50:01 +01:00
)
2023-10-27 19:19:42 +02:00
matrix_height := a -> a.len
2024-03-22 16:50:01 +01:00
matrix_width := a -> a.get(0).try(
2023-10-27 19:19:42 +02:00
() -> 0
(v) -> v.len
2024-03-22 16:50:01 +01:00
)
2023-10-27 19:19:42 +02:00
multiply_matrix := (a, b) -> {
if a.matrix_width.eq(b.matrix_height) {
a.map(line -> {
{() -> (())} // an infinite iterator repeatedly returning ()
.enumerate // an infinite iterator returning (i, ())
.take(b.matrix_width) // an iterator returning (i, ()), i < b.matrix_width
.map((x, ()) -> line
.enumerate
.map((y, val) -> val.product(b.fget(y).fget(x)))
.sum
) // an iterator returning floats
.as_list // becomes a row in the output matrix
}).as_list
} else {
"cannot multiply A and B because A's width isn't B's height."
}
}
"Enter matrix A".println
a := ().read_matrix
"Enter matrix B".println
b := ().read_matrix
"A = ".print
a.matrix_print
"B = ".print
b.matrix_print
"A * B = ".print
2024-03-22 16:50:01 +01:00
a.multiply_matrix(b).try(
2023-10-27 19:19:42 +02:00
m -> m.matrix_print
e -> e.println
2024-03-22 16:50:01 +01:00
)