preciz
Matrax library - use :atomics as a matrix
The main idea of this library is to use :atomics as a matrix with all its benefits preserved.
iex> matrax = Matrax.new(7, 4, seed_fun: fn _, {row, col} -> row + col end)
iex> matrax |> Matrax.put({0, 0}, 1989) # atomics are mutable
iex> matrax |> Matrax.to_list_of_lists()
[
[1989, 1, 2, 3],
[1, 2, 3, 4],
[2, 3, 4, 5],
[3, 4, 5, 6],
[4, 5, 6, 7],
[5, 6, 7, 8],
[6, 7, 8, 9]
]
All :atomics functions are wrapped and a few matrix specific functions are provided:
API summary
See https://hexdocs.pm/matrax for full documentation.
Matrax.new/2- Create new matrix.Matrax.get/2- Returns the integer at the given position.Matrax.put/3- Puts the given integer into the given position.Matrax.add/3- Adds the given increment to the value at given position atomically.Matrax.add_get/3- Adds the given increment to the value at given position atomically and returns result.Matrax.sub/3- Subtracts the given decrement to the value at given position atomically.Matrax.sub_get/3- Subtracts the given decrement to the value at given position atomically and returns result.Matrax.exchange/3- Exchanges the given integer at the given position atomically.Matrax.compare_exchange/4- Compares & exchanges the given integer at the given position atomically.Matrax.index_to_position/2- Converts the given atomics index to position tuple.Matrax.position_to_index/2- Converts the given position tuple to atomics index.Matrax.min/1- Returns smallest integer in matrix.Matrax.max/1- Returns largest integer in matrix.Matrax.sum/1- Returns sum of integers in matrix.Matrax.member?/2- Checks if value exists within matrix.Matrax.apply/2- Applies the given function to all elements of matrix.Matrax.to_list/1- Converts matrix to a flat list.Matrax.to_list_of_lists/1- Converts matrix to list of lists.Matrax.row_to_list/2- Converts row at given index of matrix to list.Matrax.column_to_list/2- Converts column at given index of matrix to list.Matrax.transpose/1- Transposes the given matrix. (access path modification only)Matrax.copy/1- Returns a copy of the matrix with a new atomics reference. Can be used to finish transpose.Matrax.submatrix/3- Returns a new submatrix. Creates new atomics and copies values over.
GitHub: GitHub - preciz/matrax: A matrix library in pure Elixir based on atomics. · GitHub
What is the use case?
An example use case is when you need concurrent access to a matrix of integers / bitmasks.
(my use case was a constraint solving algorithm)
:atomics "utilizes only atomic hardware instructions without any software level locking, which makes it very efficient for concurrent access. " - Erlang :atomics documentation.
Feedback is welcome. ![]()
(I would like to also mention that I’m looking for employment, if you are an employer or your company is hiring I would be happy to talk with you. PM me. Thank you!)
Most Liked
axelson
Looks like a neat library! Could you do a high-level comparison between Matrax and Matrex (matrex | Hex)? Since the names are so similar I’m going to have a hard time keeping them straight! (and good luck on your job search!)
preciz
The matrix_reloaded library explicitly says that “…if you need make fast operations on matrices, please use Matrex library.”
I have did a few benchmarks ignoring the above warning, and Matrax is faster.
Matrax is still missing a lot of matrix operations found in matrix_reloaded, however if it is this much faster I will implement them in the next days (the ones which makes sense with :atomics).
Keep in mind however that this is not the best benchmark.
One of the benefits of Matrax is concurrency which is not benchmarked here.
(transpose is 14k times faster because Matrax doesn’t move the data, only modifies the access path)
Benchmark suite executing with the following configuration:
warmup: 2 s
time: 5 s
memory time: 0 ns
parallel: 1
inputs: none specified
Estimated total run time: 14 s
Benchmarking matrax_put...
Benchmarking mr_update_element...
Name ips average deviation median 99th %
matrax_put 83.02 K 0.0120 ms ±357.54% 0.00946 ms 0.0177 ms
mr_update_element 0.0858 K 11.65 ms ±2.96% 11.55 ms 13.08 ms
Comparison:
matrax_put 83.02 K
mr_update_element 0.0858 K - 967.11x slower +11.64 ms
Benchmarking matrax_get...
Benchmarking mr_get_element...
Name ips average deviation median 99th %
matrax_get 74.23 K 0.0135 ms ±287.15% 0.0113 ms 0.0195 ms
mr_get_element 0.0920 K 10.87 ms ±2.56% 10.77 ms 11.96 ms
Comparison:
matrax_get 74.23 K
mr_get_element 0.0920 K - 807.29x slower +10.86 ms
Benchmarking matrax_transpose...
Benchmarking mr_transpose...
Name ips average deviation median 99th %
matrax_transpose 6.96 M 0.00014 ms ±23433.64% 0.00005 ms 0.00070 ms
mr_transpose 0.00049 M 2.05 ms ±6.64% 2.03 ms 2.43 ms
Comparison:
matrax_transpose 6.96 M
mr_transpose 0.00049 M - 14252.96x slower +2.05 ms
preciz
I love Matrex that is why I gave a similar name ![]()
The A in MatrAx is for :atomics.
MatrEx uses 4 byte floats.
MatrAx uses 64 bit integers and a mutable data structure under the hood called :atomics.
MatrEx optionally(?) depends on native code (NIFs).
MatrAx only requires Elixir.
MatrEx is more feature rich.
MatrAx only implements features that makes sense with :atomics
(at least that is the goal now).
MatraAx and MatrEx serve a different purpose and are not really similar,
apart from the fact that they are matrix libraries.
MatrAx use case example:
Let’s say you have 10x10 board with 25 possible states represented as bitmasks.
You could manipulate the states of the board’s cells from multiple processes concurrently and
only ping the processes that have the reference to update a view based on that.
I’m not sure if I’m clear but I have actually done something like this and :atomics were of course
way faster than lists.
Last Post!
preciz
rewrite matrix_reloaded with
Streamsinstead ofEnum
I think that would actually hurt performance or wouldn’t make a huge difference.
Since Matrax is limited to 64 bit integers because of :atomics maybe
a better change would be to support things Matrax can’t because of this limitation.
Popular in Announcing
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #hex
- #security









