Suppose you have a matrix m, how do you get the indexes of all the columns whose values are all the same.
For example, if m is such as below, the answer should be 1 because only the first column has all entries equal.
m = [1 2 3; 1 4 5; 1 6 7]
I did find some questions here and at StackOverflow that sort of pointed me in the direction I wanted, but I couldn’t make them work. For instance, in the StackOverflow example of the function allequal_1(x), I couldn’t understand the set up: all(y->y==x[1],x). For instance, why the y?
this is the notation for an anonymous function. It can be read as "given y return the result of y == x[1], and there it is mapped to all elements of x, comparing each of them to x[1].
It would be exactly the same if it was written element_of_x -> element_of_x == x[1] or any other variable name instead of y.
That stackoverflow post is for a much older version, there’s been some convenient methods since then. EDIT: the next answer in fact uses a v1.8 method allequal I didn’t know about that serves the same purpose as points 1-3, though its equality test uses isequal and is different from == here in edge cases.
result = findall(col -> all(el -> el == col[1], col), eachcol(m))
1.^----------------^
2.^--------------------------^
3.^---------------------------------^
4.^--------^
5.^------------------------------------------------------^
1. anonymous function that captures col[1] from surrounding
anonymous function (3), compares its input to col[1]
2. <all> checks each element of col and evaluates the function (1)
if it is false anywhere, it stops and returns false. So <all>
returns true only if the function at every element returns true
3. anonymous function that takes a column <col> and checks if
every element is equal to the first element by doing (2)
4. iterable whose elements are columns of input matrix <m>
5. <findall> checks each column in eachcol(m) and returns all
indices where (3) is true. If your matrix is 1-based like how
eachcol is 1-based, then these would be the row indices
I think the >length(itr) allocations has to do with findall doing a collect on a generator expression with an if statement. When I pulled the method out and omitted the if statement, the allocations went to single digits, though 78.250 KiB. That probably should be optimized one day, the generator does have access to its maximum length from the start.
a previous experiment with different m (see below) , led me to make the following reflection regarding a scheme used in making comparisons between different algorithms that are claimed to be equivalent.
probably this consideration, which has no burden for practical purposes but is only a logical whim, has already been made by others, but I would like to propose it again here.
The scheme used by @rafael.guerra here (and by all of us elsewhere) sets forth ONE example where two different algorithms give the same result, implying that this holds as equivalence in general.
obviously this is not logically true(the only thing that a single example can logically imply is NOT GENERAL EQUIVALENCE).