Pattern matching in Matrix

Find each instance of the smaller matrix in the larger and create a NamedTuple (;a,b)

[
    :X  a   _
    b   _   :Y   
]

[
    1   2   3
    :X  1   2
    3   4   :Y
    :X  1   2
    4   5   :Y
    10  11  12
    :X  3   3
    7   4   :Y
    6   7   8
    8   7   6
]

#output 
[
(a=1,b=3)
(a=1,b=4)
(a=3,b=7)
]

Guess, this needs a bit of help as you might want to match on overlapping/non-overlapping rows etc. Nevertheless, here is a way using Match.jl:

julia> using IterTools, Match

julia> Z = [1 2 3; :X 1 2; 3 4 :Y; :X 1 2; 4 5 :Y; 10 11 12; :X 3 3; 7 4 :Y; 6 7 8; 8 7 6];

julia> foo(x) = @match x begin
           # Note: @match does not work on matrices directly 
           ([:X, a, _], [b, _, :Y]) => (; a, b)
           _ => missing
       end
foo (generic function with 1 method)

# Note: IterTools to get overlapping partitions of two rows
julia> skipmissing(foo.(IterTools.partition(eachrow(Z), 2, 1))) |> collect
3-element Vector{@NamedTuple{a::Int64, b::Int64}}:
 (a = 1, b = 3)
 (a = 1, b = 4)
 (a = 3, b = 7)
5 Likes
m=[
    :X  :a   0
    :b   0   :Y   
]

M=[
    1   2   3
    :X  1   2
    3   4   :Y
    :X  1   2
    4   5   :Y
    10  11  12
    :X  3   3
    7   4   5
    :X   7   8
    8   7   :Y
]

#output 
[
(a=1,b=3)
(a=1,b=4)
(a=3,b=7)
]
rm,cm = size(m)
r,c=size(M)

AX=findall(e->e==:X ,M)
BY=AX.+CartesianIndex(rm-1,cm-1)
y=findall(e->M[e]==:Y,BY)

[(;a=M[x+CartesianIndex(0,1)],b=M[x+CartesianIndex(1,0)]) for x in AX[y]]
1 Like

stretching a bit more in an attempt to be more general

[(;zip((m[1,2],m[2,1]),(M[x+CartesianIndex(0,1)],M[x+CartesianIndex(1,0)]))...) for x in AX[y]]