0

I am currently working on a intro project in Computer Graphics. For a specific part of my implementation, I am working with a boolean NumPy matrix, where all the values are False and some rows/columns are True. Lets say I have two boolean matrices of different sizes (for context - this is because while running some of the rows/columns are deleted):

[[True, False, False]
[True, False, False]
[True, False, False]]

and

[[True, True]
[False, False]
[False, False]]

I would like to create a new matrix that will be:

[[True, True, True]
[True, False, False]
[True, False, False]]

=> meaning I would like to receive a matrix holding all of the true values from both rows and columns matrices.

How can this be done? Thanks

By1
  • 23
  • 4
  • First problem would be to map the index of a column/row in the smaller matrix to the right column/row in the larger matrix. Or is always e. g. column 1 in the smaller matrix related to column 1 in the larger matrix regardless of the size difference? – Michael Butscher Apr 08 '23 at 08:29
  • The matrices are always of different sizes. the context is im implementing a seam-carving algorithm, and after finding the seam I am trying to visualize it on the original photo. – By1 Apr 08 '23 at 08:35

3 Answers3

2

If I understand correctly, you can use:

a1 = np.array([[True, False, False],
               [True, False, False],
               [True, False, False]])

a2 = np.array([[True, True],
               [False, False],
               [False, False],])

arrays = [a1, a2]

# compute maximum shape
shape = np.maximum.reduce([a.shape for a in arrays])

# pad and count the number of True
n = np.hstack([np.pad(a, list(zip(np.zeros(a.ndim, dtype=int), shape-a.shape)))
               for a in arrays]).sum(axis=1)

# create output using broadcasting
out = np.arange(shape[1])<n[:,None]

NB. this can work with an arbitrary number of arrays. The maximum number of columns in the output is the maximum number of columns in the output, but you can change it to the number of True if needed with out = np.arange(max(shape[1], n.max()))<n[:,None].

Output:

array([[ True,  True,  True],
       [ True, False, False],
       [ True, False, False]])

other example

Input:

a1 = np.array([[True, False, False],
               [True, False, False]])

a2 = np.array([[True, True],
               [False, False],
               [False, False]])

Output:

array([[ True,  True,  True],
       [ True, False, False],
       [False, False, False]])
mozway
  • 194,879
  • 13
  • 39
  • 75
1

As long as the top-left corners of the two matrices align, it is easy:

Remember you are not adding, you are or-ring.Just use logical_or. This goes through elementwise.

  • Decide the output matrix size, based on the larger of the two matrices, for each dimension
  • Dreate an outpumt matrix of that size
  • Put one input matrix into it.
  • OR the other matrix into it.
import numpy as np

A = np.array([[True, False, False],
              [True, False, False],
              [True, False, False]])

B = np.array([[True, True],
              [False, False],
              [False, False]])

n_rows = max(A.shape[0], B.shape[0])
n_cols = max(A.shape[1], B.shape[1])

C = np.zeros((n_rows, n_cols), dtype=bool)

C[:A.shape[0], :A.shape[1]] = A
C[:B.shape[0], :B.shape[1]] = np.logical_or(C[:B.shape[0], :B.shape[1]], B)

print(C)

ProfDFrancis
  • 8,816
  • 1
  • 17
  • 26
  • Thanks for the comment! However, when running the code provided I do not get the wanted output - as the top-left corner in my example is a different one for each matrix. Is there a way to use this logic but to adjust NumPy to 'skip' true values, meaning to look only for false values and then the apply the magic? – By1 Apr 08 '23 at 08:50
0

You cannot add matrix of different size programmatically. You could come up with a system that changes the boolean values ​​by working on the indices of the single vectors (row or column), but the function must be built by excluding the values you don't want to change. In essence it's an algorithm that works in a specific and not a generic way, therefore the concrete functioning depends on how you want the function to work based on the specific case