mikera / core.matrix

core.matrix : Multi-dimensional array programming API for Clojure
Other
700 stars 113 forks source link

element-wise equality comparison for non-numbers #363

Open maxrothman opened 6 months ago

maxrothman commented 6 months ago

Currently, eq only works on numerical matrices because the protocol implementation uses ==. (Note that this appears to not always have been true, https://github.com/mikera/core.matrix/commit/eb71bb43d401b8bab7701a4e187411e3a6252889 changed the uses of = to ==, causing eq to no longer work on non-numeric matrices.) It would be helpful to have eq work on non-numerical matrices too, for example character or keyword matrices. Currently, applying eq to such matrices throws an exception.

mikera commented 6 months ago

So eq was defined to work with numerical values only (for consistency with ge etc.).

e= performs a comparison of all elements with Clojure = semantics.

Non-numerical equality on an element wise basis is somewhat tricky because array implementations might not support booleans as results (or even numerical values, for that matter...)

Potential workaround that probably does what you want:

(emap = a b)

Though you may need to be careful that the implementation of a supports booleans or do something like:

(emap 
  (fn [x y] (if (= x y 1.0 0.0)) 
  a b)
maxrothman commented 6 months ago

Having the results be numeric (1 and 0 instead of true and false) is desirable IMO, I think that having boolean results would drastically change the semantics of eq, and I'm not suggesting that. This request was to allow for non-numeric inputs. For example:

(matrix/eq [[:a :b][:c :d]] [[:a :d][:c :b]])
; => [[1 0][1 0]

This example does not currently work because eq uses ==, causing the comparison to fail. ((== :a :a) raises an exception)

The emap workaround you shared above does what I'd expect eq to do, I was surprised that it does not.