class_docstr: This is a utility class that combines a model, a masker object, and a current input.
  
  The combination of a model, a masker object, and a current input produces a binary set
  function that can be called to mask out any set of inputs. This class attempts to be smart
  about only evaluating the model for background samples when the inputs changed (note this
  requires the masker object to have a .invariants method).
class_docstr_tok: ["This","is","a","utility","class","that","combines","a","model",",","a","masker","object",",","and","a","current","input",".","The","combination","of","a","model",",","a","masker","object",",","and","a","current","input","produces","a","binary","set","function","that","can","be","called","to","mask","out","any","set","of","inputs",".","This","class","attempts","to","be","smart","about","only","evaluating","the","model","for","background","samples","when","the","inputs","changed","(","note","this","requires","the","masker","object","to","have","a",".invariants","method",")","."]
code: def __init__(self, model, masker, link, linearize_link, *args):
      self.model = model
      self.masker = masker
      self.link = link
      self.linearize_link = linearize_link
      self.args = args
  
      # if the masker supports it, save what positions vary from the background
      if callable(getattr(self.masker, "invariants", None)):
          self._variants = ~self.masker.invariants(*args)
          self._variants_column_sums = self._variants.sum(0)
          self._variants_row_inds = [
              self._variants[:, i]
              for i in range(self._variants.shape[1])
          ]
      else:
          self._variants = None
  
      # compute the length of the mask (and hence our length)
      if hasattr(self.masker, "shape"):
          if callable(self.masker.shape):
              mshape = self.masker.shape(*self.args)
              self._masker_rows = mshape[0]
              self._masker_cols = mshape[1]
          else:
              mshape = self.masker.shape
              self._masker_rows = mshape[0]
              self._masker_cols = mshape[1]
      else:
          self._masker_rows = None  # # just assuming...
          self._masker_cols = sum(np.prod(a.shape) for a in self.args)
  
      self._linearizing_weights = None
  
imports: import copy
  import numpy
  import scipy.sparse
  from numba import njit
  from ..None import links
label_desc: Use image node_id 1 to create a new MaskedModel object  with example: obj = MaskedModel(model, masker, link, linearize_link)