This site is version 0.0.1. Most of the code on this site is drafted by an agent and needs review. I apologize for the AI-speak, we are working on rewriting it!
viv-lang.org

Python and Viv · Numerics

Matrix operations

What to notice

Open the Viv in the workbench The atlas of the Viv py2viv refuses this Python (the reason is in its column).
Python matrix_ops.py · 32 lines
Viv matrix_ops.viv · 38 lines
py2viv refuses matrix_ops.py
1 imports
4import numpy as np
2# nothing to import: matrices are part of the language
py2viv refuses this program:
matrix_ops.py:24:14: not numeric Python: np.round with decimals or of an array
    print("C =", np.round(C, 6).tolist())
                 ^^^^^^^^^^^^^^
  Round numbers one at a time with round(x).
1 construct outside the numeric subset (tools/py2viv/SUBSET.md)
2 build matrices
7A = np.array([[1.0, 2.0], [3.0, 4.0]])
8B = np.eye(2) * 2.0
9v = np.array([1.0, -1.0])
10print("A =", A.tolist())
11print("shape", A.shape, "size", A.size)
5A = [[1.0, 2.0], [3.0, 4.0]]
6B = [[2.0, 0.0], [0.0, 2.0]]
7v = [1.0, -1.0]
8print("A =", fmt(A))
9rows, cols = shape(A)
10print("shape (", rows, ", ", cols, ") size ", numel(A), sep="")
(refused)
3 products
14print("A @ B =", (A @ B).tolist())
15print("A * B =", (A * B).tolist())
16print("A @ v =", (A @ v).tolist())
17print("A^T =", A.T.tolist())
13print("A @ B =", fmt(A @ B))
14print("A * B =", fmt(A * B))
15print("A @ v =", fmt(A @ v))
16print("A^T =", fmt(transpose(A)))
(refused)
4 reductions along an axis
20print("sum", A.sum(), "column sums", A.sum(axis=0).tolist(), "row sums", A.sum(axis=1).tolist())
19col_sums = sum(A, axis=0)
20row_sums = sum(A, axis=1)
21print("sum", fmt(sum(A)), "column sums", fmt(col_sums), "row sums", fmt(row_sums))
(refused)
5 elementwise functions and masks
23C = np.sqrt(A) * (A > 1.5)
24print("C =", np.round(C, 6).tolist())
24C = sqrt(A) * (A > 1.5)
25print("C =", fmt(round(C * 1e6) / 1e6))
(refused)
6 determinant and inverse of a 2 by 2
27det = A[0, 0] * A[1, 1] - A[0, 1] * A[1, 0]
28inv = np.array([[A[1, 1], -A[0, 1]], [-A[1, 0], A[0, 0]]]) / det
29print("det", det, "inverse", inv.tolist())
28det = A[0, 0] * A[1, 1] - A[0, 1] * A[1, 0]
29inv = [[A[1, 1], -A[0, 1]], [-A[1, 0], A[0, 0]]] / det
30print("det", fmt(det), "inverse", fmt(inv))
(refused)
7 checks
32assert np.allclose(A @ inv, np.eye(2))
33test "inverse" {
34 assert_allclose(A @ inv, [[1.0, 0.0], [0.0, 1.0]], 1e-12)
35}
(refused)

What they print

identical — the two programs print the same text.

Dimmed lines are left out of the comparison. Each Viv test block prints one PASS line; the Python checks the same facts with assert, which prints nothing.

$ python3 matrix_ops.py

A = [[1.0, 2.0], [3.0, 4.0]]
shape (2, 2) size 4
A @ B = [[2.0, 4.0], [6.0, 8.0]]
A * B = [[2.0, 0.0], [0.0, 8.0]]
A @ v = [-1.0, -1.0]
A^T = [[1.0, 3.0], [2.0, 4.0]]
sum 10.0 column sums [4.0, 6.0] row sums [3.0, 7.0]
C = [[0.0, 1.414214], [1.732051, 2.0]]
det -2.0 inverse [[-2.0, 1.0], [1.5, -0.5]]

$ viv run matrix_ops.viv

A = [[1.0, 2.0], [3.0, 4.0]]
shape (2, 2) size 4
A @ B = [[2.0, 4.0], [6.0, 8.0]]
A * B = [[2.0, 0.0], [0.0, 8.0]]
A @ v = [-1.0, -1.0]
A^T = [[1.0, 3.0], [2.0, 4.0]]
sum 10.0 column sums [4.0, 6.0] row sums [3.0, 7.0]
C = [[0.0, 1.414214], [1.732051, 2.0]]
det -2.0 inverse [[-2.0, 1.0], [1.5, -0.5]]
PASS inverse