1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
discard """
output: '''after 2 2
after 2 2
after 2 2
after 2 2'''
"""
# bug #9263
type
Matrix* = object
# Array for internal storage of elements.
data: ptr UncheckedArray[float]
# Row and column dimensions.
m*, n*: int
var
allocCount, deallocCount: int
proc `=destroy`*(m: var Matrix) =
if m.data != nil:
dealloc(m.data)
deallocCount.inc
m.data = nil
m.m = 0
m.n = 0
proc `=sink`*(a: var Matrix; b: Matrix) =
if a.data != nil and a.data != b.data:
dealloc(a.data)
deallocCount.inc
a.data = b.data
a.m = b.m
a.n = b.n
proc `=`*(a: var Matrix; b: Matrix) =
if a.data != nil and a.data != b.data:
dealloc(a.data)
deallocCount.inc
a.data = nil
a.m = b.m
a.n = b.n
if b.data != nil:
a.data = cast[type(a.data)](alloc(a.m * a.n * sizeof(float)))
allocCount.inc
copyMem(a.data, b.data, b.m * b.n * sizeof(float))
proc matrix*(m, n: int, s: float): Matrix =
## Construct an m-by-n constant matrix.
result.m = m
result.n = n
result.data = cast[type(result.data)](alloc(m * n * sizeof(float)))
allocCount.inc
for i in 0 ..< m * n:
result.data[i] = s
proc `[]`*(m: Matrix, i, j: int): float {.inline.} =
## Get a single element.
m.data[i * m.n + j]
proc `[]`*(m: var Matrix, i, j: int): var float {.inline.} =
## Get a single element.
m.data[i * m.n + j]
proc `[]=`*(m: var Matrix, i, j: int, s: float) =
## Set a single element.
m.data[i * m.n + j] = s
proc `-`*(m: sink Matrix): Matrix =
## Unary minus
result = m
for i in 0 ..< m.m:
for j in 0 ..< m.n:
result[i, j] = -m[i, j]
proc `+`*(a: sink Matrix; b: Matrix): Matrix =
## ``C = A + B``
assert(b.m == a.m and b.n == a.n, "Matrix dimensions must agree.")
result = a
for i in 0 ..< a.m:
for j in 0 ..< a.n:
result[i, j] = a[i, j] + b[i, j]
proc `-`*(a: sink Matrix; b: Matrix): Matrix =
## ``C = A - B``
assert(b.m == a.m and b.n == a.n, "Matrix dimensions must agree.")
result = a
for i in 0 ..< a.m:
for j in 0 ..< a.n:
result[i, j] = a[i, j] - b[i, j]
proc info =
echo "after ", allocCount, " ", deallocCount
allocCount = 0
deallocCount = 0
proc test1 =
var a = matrix(5, 5, 1.0)
var b = a
var c = a + b
proc test2 =
var a = matrix(5, 5, 1.0)
var b = a
var c = -a
proc test3 =
var a = matrix(5, 5, 1.0)
var b = matrix(5, 5, 2.0)
# a = a - b
b = -b + a
proc test4 =
# bug #9294
var a = matrix(5, 5, 1.0)
a = -a + a
test1()
info()
test2()
info()
test3()
info()
test4()
info()
|