code wiki / (root) / nx_matrix_test.nx

nx_matrix_test.nx source

↩ module page · 148 lines · 6433 B

1// nx_matrix_test.nx -- smoke for matrix algebra. 2 3import "syscalls.nx" 4import "nx_matrix.nx" 5 6func main() -> i64 { 7 // === Test 1: alloc + set + get === 8 let m: *Matrix = nx_matrix_alloc(2, 3) 9 if m.rows != 2 { return 1 } 10 if m.cols != 3 { return 2 } 11 nx_matrix_set(m, 0, 0, 10) 12 nx_matrix_set(m, 1, 2, 99) 13 if nx_matrix_get(m, 0, 0) != 10 { return 3 } 14 if nx_matrix_get(m, 1, 2) != 99 { return 4 } 15 if nx_matrix_get(m, 0, 1) != 0 { return 5 } // zeroed 16 17 // === Test 2: identity === 18 let id: *Matrix = nx_matrix_alloc(3, 3) 19 nx_matrix_identity(id, 1) 20 if nx_matrix_get(id, 0, 0) != 1 { return 10 } 21 if nx_matrix_get(id, 1, 1) != 1 { return 11 } 22 if nx_matrix_get(id, 2, 2) != 1 { return 12 } 23 if nx_matrix_get(id, 0, 1) != 0 { return 13 } 24 if nx_matrix_get(id, 1, 0) != 0 { return 14 } 25 26 // === Test 3: transpose === 27 let a: *Matrix = nx_matrix_alloc(2, 3) 28 nx_matrix_set(a, 0, 0, 1); nx_matrix_set(a, 0, 1, 2); nx_matrix_set(a, 0, 2, 3) 29 nx_matrix_set(a, 1, 0, 4); nx_matrix_set(a, 1, 1, 5); nx_matrix_set(a, 1, 2, 6) 30 let at: *Matrix = nx_matrix_transpose(a) 31 if at.rows != 3 { return 20 } 32 if at.cols != 2 { return 21 } 33 if nx_matrix_get(at, 0, 0) != 1 { return 22 } 34 if nx_matrix_get(at, 1, 0) != 2 { return 23 } 35 if nx_matrix_get(at, 2, 0) != 3 { return 24 } 36 if nx_matrix_get(at, 0, 1) != 4 { return 25 } 37 if nx_matrix_get(at, 1, 1) != 5 { return 26 } 38 if nx_matrix_get(at, 2, 1) != 6 { return 27 } 39 40 // === Test 4: multiply 2x3 * 3x2 = 2x2 === 41 // A = [[1,2,3],[4,5,6]] 42 // B = [[7,8],[9,10],[11,12]] 43 // AB = [[58,64],[139,154]] 44 let b: *Matrix = nx_matrix_alloc(3, 2) 45 nx_matrix_set(b, 0, 0, 7); nx_matrix_set(b, 0, 1, 8) 46 nx_matrix_set(b, 1, 0, 9); nx_matrix_set(b, 1, 1, 10) 47 nx_matrix_set(b, 2, 0, 11); nx_matrix_set(b, 2, 1, 12) 48 let c: *Matrix = nx_matrix_alloc(2, 2) 49 if nx_matrix_multiply(a, b, c) != 0 { return 30 } 50 if nx_matrix_get(c, 0, 0) != 58 { return 31 } 51 if nx_matrix_get(c, 0, 1) != 64 { return 32 } 52 if nx_matrix_get(c, 1, 0) != 139 { return 33 } 53 if nx_matrix_get(c, 1, 1) != 154 { return 34 } 54 55 // === Test 5: multiply identity * A = A === 56 let id2: *Matrix = nx_matrix_alloc(2, 2) 57 nx_matrix_identity(id2, 1) 58 let a2: *Matrix = nx_matrix_alloc(2, 2) 59 nx_matrix_set(a2, 0, 0, 5); nx_matrix_set(a2, 0, 1, 7) 60 nx_matrix_set(a2, 1, 0, 9); nx_matrix_set(a2, 1, 1, 11) 61 let prod: *Matrix = nx_matrix_alloc(2, 2) 62 nx_matrix_multiply(id2, a2, prod) 63 if nx_matrix_get(prod, 0, 0) != 5 { return 40 } 64 if nx_matrix_get(prod, 0, 1) != 7 { return 41 } 65 if nx_matrix_get(prod, 1, 0) != 9 { return 42 } 66 if nx_matrix_get(prod, 1, 1) != 11 { return 43 } 67 68 // === Test 6: multiply shape mismatch returns -1 === 69 let bad: *Matrix = nx_matrix_alloc(3, 3) 70 if nx_matrix_multiply(a2, bad, prod) != -1 { return 50 } 71 72 // === Test 7: 2x2 determinant === 73 // [[3,8],[4,6]] -> det = 18 - 32 = -14 74 let d2: *Matrix = nx_matrix_alloc(2, 2) 75 nx_matrix_set(d2, 0, 0, 3); nx_matrix_set(d2, 0, 1, 8) 76 nx_matrix_set(d2, 1, 0, 4); nx_matrix_set(d2, 1, 1, 6) 77 if nx_matrix_det_2x2(d2) != -14 { return 60 } 78 79 // === Test 8: 2x2 inverse === 80 // Inverse of [[3,8],[4,6]] is (1/-14) * [[6,-8],[-4,3]] 81 // In Q14: [[6*16384/-14, -8*16384/-14], [-4*16384/-14, 3*16384/-14]] 82 // = [[-7021, 9362], [4681, -3510]] 83 let d2_inv: *Matrix = nx_matrix_alloc(2, 2) 84 if nx_matrix_inv_2x2(d2, d2_inv) != 0 { return 70 } 85 // Approximate check 86 let i00: i64 = nx_matrix_get(d2_inv, 0, 0) 87 let d00: i64 = i00 - (-7021) 88 var ad00: i64 = d00 89 if ad00 < 0 { ad00 = -ad00 } 90 if ad00 > 5 { return 71 } 91 92 // === Test 9: 2x2 inverse: M * inv_M = I (in Q14) === 93 // M * inv_M should give Q14 identity (entries 16384 on diag, 0 off). 94 let id_q14: *Matrix = nx_matrix_alloc(2, 2) 95 nx_matrix_multiply(d2, d2_inv, id_q14) 96 // diagonal should be ~Q14 = 16384 97 let d_00: i64 = nx_matrix_get(id_q14, 0, 0) - 16384 98 var ad_00: i64 = d_00 99 if ad_00 < 0 { ad_00 = -ad_00 } 100 if ad_00 > 20 { return 80 } 101 let d_11: i64 = nx_matrix_get(id_q14, 1, 1) - 16384 102 var ad_11: i64 = d_11 103 if ad_11 < 0 { ad_11 = -ad_11 } 104 if ad_11 > 20 { return 81 } 105 // off-diagonal should be ~0 106 var d_01: i64 = nx_matrix_get(id_q14, 0, 1) 107 if d_01 < 0 { d_01 = -d_01 } 108 if d_01 > 20 { return 82 } 109 110 // === Test 10: 3x3 determinant === 111 // [[1,2,3],[4,5,6],[7,8,10]] -> det = 1*(50-48) - 2*(40-42) + 3*(32-35) 112 // = 2 + 4 - 9 = -3 113 let d3: *Matrix = nx_matrix_alloc(3, 3) 114 nx_matrix_set(d3, 0, 0, 1); nx_matrix_set(d3, 0, 1, 2); nx_matrix_set(d3, 0, 2, 3) 115 nx_matrix_set(d3, 1, 0, 4); nx_matrix_set(d3, 1, 1, 5); nx_matrix_set(d3, 1, 2, 6) 116 nx_matrix_set(d3, 2, 0, 7); nx_matrix_set(d3, 2, 1, 8); nx_matrix_set(d3, 2, 2, 10) 117 if nx_matrix_det_3x3(d3) != -3 { return 90 } 118 119 // === Test 11: 3x3 singular matrix det = 0 === 120 let sing: *Matrix = nx_matrix_alloc(3, 3) 121 nx_matrix_set(sing, 0, 0, 1); nx_matrix_set(sing, 0, 1, 2); nx_matrix_set(sing, 0, 2, 3) 122 nx_matrix_set(sing, 1, 0, 2); nx_matrix_set(sing, 1, 1, 4); nx_matrix_set(sing, 1, 2, 6) 123 nx_matrix_set(sing, 2, 0, 3); nx_matrix_set(sing, 2, 1, 6); nx_matrix_set(sing, 2, 2, 9) 124 if nx_matrix_det_3x3(sing) != 0 { return 100 } 125 // Inverse should fail 126 let bad_inv: *Matrix = nx_matrix_alloc(3, 3) 127 if nx_matrix_inv_3x3(sing, bad_inv) != -1 { return 101 } 128 129 // === Test 12: 3x3 inverse: M * inv_M = Q14 identity === 130 let d3_inv: *Matrix = nx_matrix_alloc(3, 3) 131 if nx_matrix_inv_3x3(d3, d3_inv) != 0 { return 110 } 132 let r3: *Matrix = nx_matrix_alloc(3, 3) 133 nx_matrix_multiply(d3, d3_inv, r3) 134 var dd_00: i64 = nx_matrix_get(r3, 0, 0) - 16384 135 if dd_00 < 0 { dd_00 = -dd_00 } 136 if dd_00 > 100 { return 111 } 137 var dd_11: i64 = nx_matrix_get(r3, 1, 1) - 16384 138 if dd_11 < 0 { dd_11 = -dd_11 } 139 if dd_11 > 100 { return 112 } 140 var dd_22: i64 = nx_matrix_get(r3, 2, 2) - 16384 141 if dd_22 < 0 { dd_22 = -dd_22 } 142 if dd_22 > 100 { return 113 } 143 var dd_01: i64 = nx_matrix_get(r3, 0, 1) 144 if dd_01 < 0 { dd_01 = -dd_01 } 145 if dd_01 > 100 { return 114 } 146 147 return 0 148}