kigubkur.pred.ecompare

Predicate: for element-wise comparisons of kigubkur© matrices (or blocks).

  • equal?
  • equivalent?

Import the desired predicate into the namespace by

(require '[kigubkur.pred [ecompare :refer [<abc>? <xyz>?]]])

equivalent? refers to the mathematical definition of ≡. Its implementation is based on Clojure’s == which checks if the values are “identical” to each other. That is, the identical values are type-independent. This is not the case for equal? which checks if the values are equal and hence of the same set of number-type. It is based on Clojure’s =. Below are some example.

The numbers

=> (equal? 1 2 3 4)
false

are obviously not equal. But,

=> (equal? 1 1 1 1)
true

However, if one of the number “1” is of the BigDecimal number type

=> (equal? 1 1M 1 1)
false

all the “1”’s are no longer equal but they are identical (equivalent)

=> (equivalent? 1 1M 1 1)
true

Thus, for the Clojure numbers

vs int bigint long short float double bigdec
int = = = =
float = =

The equal? and equivalent? predicates also applies to kigubkur’s data (matrix) types.

If, R1, R2, R3, … are rows of the same order 1 × n, C1, C2, C3, … are columns of the same order m × 1 and M1, M2, M3, … are matrices of the same order m × n, then the above behavior applies albeit in matrix form (instead of numbers).

The syntax being the same will appear like

=> (equal? R1 R2 R3)
=> (equal? C1 C2 C3)
=> (equal? M1 M2 M3)
=> (equivalent? R1 R2 R3)
=> (equivalent? C1 C2 C3)
=> (equivalent? M1 M2 M3)

This is also the case for blocks provided that their mothers have the same order (hence, the blocks will also have the same order). Thus,

=> (equal? B1 B2 B3)
=> (equivalent? B1 B2 B3)

Regardless of whether the argument is a row, column, matrix or a block if only one is passed as the argument then the comparison is not an element-wise comparison of the objects but instead is a comparison of all the entries (elements) in that singular object. That is,

=> (equal? R1)
=> (equal? C1)
=> (equal? M1)
=> (equal? B1)
=> (equivalent? R1)
=> (equivalent? C1)
=> (equivalent? M1)
=> (equivalent? B1)

here all the elements in the respective objects (R1 or C1 or M1 or B1) are compared.

Addendum

Note that in the table above although int, bigint, long, short, float, double and bigdec are placed as representing Clojure’s number types, strictly speaking, they are not. They are Clojure’s coercion functions; they coerce a number from one type to another. For example, int coerces the number such that it is compatible to not just integer type but also other types, i.e. the coerced number type is a superset. This becomes evident when one looks at the source of int? and integer?.

Therefore, the actual number types are: Integer BigInteger, Long, Short, Float, Double and BigDecimal

However, for most practical purposes int, bigint, long, short, float, double and bigdec can be used to refer to corresponding implied number type.

equal?

(equal? & args)

Predicate that checks if all the nums in a matrix (or vector) or among matrices (or vectors of same kind) are equal. NOTE: This also applies for blocks.

vs int bigint long short float double bigdec
int = = = =
float = =
Syntax Purpose
(equal? M) checks if all have the same magnitude and in the set of similar number types
(equal? M1 M2 M3) element-wise check among the matrices for if they are of the same magnitudes

equivalent?

(equivalent? & args)

Predicate that checks if all the elements (numbers) in a matrix (or vector) or among matrices (or vectors of same kind) are equivalent. NOTE: This also applies for blocks.

Syntax Purpose
(equivalent? M) checks if all have the same magnitude regardless of the number type
(equivalent? M1 M2 M3) element-wise check among the matrices for if they are of the same magnitudes