tmatrix.nim 2.8 KB

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