tmatrix.nim 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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 `=`*(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 matrix*(m, n: int, s: float): Matrix =
  42. ## Construct an m-by-n constant matrix.
  43. result.m = m
  44. result.n = n
  45. result.data = cast[type(result.data)](alloc(m * n * sizeof(float)))
  46. allocCount.inc
  47. for i in 0 ..< m * n:
  48. result.data[i] = s
  49. proc len(m: Matrix): int = m.n * m.m
  50. proc `[]`*(m: Matrix, i, j: int): float {.inline.} =
  51. ## Get a single element.
  52. m.data[i * m.n + j]
  53. proc `[]`*(m: var Matrix, i, j: int): var float {.inline.} =
  54. ## Get a single element.
  55. m.data[i * m.n + j]
  56. proc `[]=`*(m: var Matrix, i, j: int, s: float) =
  57. ## Set a single element.
  58. m.data[i * m.n + j] = s
  59. proc `-`*(m: sink Matrix): Matrix =
  60. ## Unary minus
  61. result = m
  62. for i in 0 ..< result.m:
  63. for j in 0 ..< result.n:
  64. result[i, j] = -result[i, j]
  65. proc `+`*(a: sink Matrix; b: Matrix): Matrix =
  66. ## ``C = A + B``
  67. doAssert(b.m == a.m and b.n == a.n, "Matrix dimensions must agree.")
  68. doAssert(a.len == b.len) # non destructive use before sink is ok
  69. result = a
  70. for i in 0 ..< result.m:
  71. for j in 0 ..< result.n:
  72. result[i, j] = result[i, j] + b[i, j]
  73. proc `-`*(a: sink Matrix; b: Matrix): Matrix =
  74. ## ``C = A - B``
  75. assert(b.m == a.m and b.n == a.n, "Matrix dimensions must agree.")
  76. doAssert(a.len == b.len) # non destructive use before sink is ok
  77. result = a
  78. for i in 0 ..< result.m:
  79. for j in 0 ..< result.n:
  80. result[i, j] = a[i, j] - b[i, j]
  81. proc info =
  82. echo "after ", allocCount, " ", deallocCount
  83. allocCount = 0
  84. deallocCount = 0
  85. proc copy(a: Matrix): Matrix = a
  86. proc test1 =
  87. var a = matrix(5, 5, 1.0)
  88. var b = copy a
  89. var c = a + b
  90. proc test2 =
  91. var a = matrix(5, 5, 1.0)
  92. var b = copy a
  93. var c = -a
  94. proc test3 =
  95. var a = matrix(5, 5, 1.0)
  96. var b = matrix(5, 5, 2.0)
  97. # a = a - b
  98. b = -b + a
  99. proc test4 =
  100. # bug #9294
  101. var a = matrix(5, 5, 1.0)
  102. a = -a + a
  103. test1()
  104. info()
  105. test2()
  106. info()
  107. test3()
  108. info()
  109. test4()
  110. info()