nodes: 0, module; 1, function_definition; 2, function_name:lapmod; 3, parameters; 4, block; 5, identifier:n; 6, identifier:cc; 7, identifier:ii; 8, identifier:kk; 9, default_parameter; 10, default_parameter; 11, default_parameter; 12, expression_statement; 13, comment:# log = logging.getLogger('lapmod'); 14, expression_statement; 15, if_statement; 16, if_statement; 17, identifier:fast; 18, True; 19, identifier:return_cost; 20, True; 21, identifier:fp_version; 22, identifier:FP_DYNAMIC; 23, comment:"""Solve sparse linear assignment problem using Jonker-Volgenant algorithm.
  
      n: number of rows of the assignment cost matrix
      cc: 1D array of all finite elements of the assignement cost matrix
      ii: 1D array of indices of the row starts in cc. The following must hold:
              ii[0] = 0 and ii[n+1] = len(cc).
      kk: 1D array of the column indices so that:
              cost[i, kk[ii[i] + k]] == cc[ii[i] + k].
          Indices within one row must be sorted.
      extend_cost: whether or not extend a non-square matrix [default: False]
      cost_limit: an upper limit for a cost of a single assignment
                  [default: np.inf]
      return_cost: whether or not to return the assignment cost
  
      Returns (opt, x, y) where:
        opt: cost of the assignment
        x: vector of columns assigned to rows
        y: vector of rows assigned to columns
      or (x, y) if return_cost is not True.
  
      When extend_cost and/or cost_limit is set, all unmatched entries will be
      marked by -1 in x/y.
      """; 24, call; 25, comparison_operator:fast is True; 26, comment:# log.debug('[----CR & RT & ARR & augmentation ----]'); 27, block; 28, else_clause; 29, comparison_operator:return_cost is True; 30, block; 31, else_clause; 32, identifier:check_cost; 33, argument_list; 34, identifier:fast; 35, True; 36, expression_statement; 37, block; 38, identifier:return_cost; 39, True; 40, return_statement; 41, block; 42, identifier:n; 43, identifier:cc; 44, identifier:ii; 45, identifier:kk; 46, assignment; 47, expression_statement; 48, expression_statement; 49, expression_statement; 50, expression_statement; 51, expression_statement; 52, expression_statement; 53, expression_statement; 54, comment:# log.debug('[----Column reduction & reduction transfer----]'); 55, expression_statement; 56, comment:# log.debug(; 57, comment:#     'free, x, y, v: %s %s %s %s', free_rows[:n_free_rows], x, y, v); 58, if_statement; 59, for_statement; 60, comment:# log.info('[----Augmentation----]'); 61, expression_statement; 62, comment:# log.debug('x, y, v: %s %s %s', x, y, v); 63, expression_list; 64, return_statement; 65, pattern_list; 66, call; 67, assignment; 68, assignment; 69, assignment; 70, assignment; 71, assignment; 72, assignment; 73, assignment; 74, assignment; 75, comparison_operator:n_free_rows == 0; 76, comment:# log.info('Reduction solved it.'); 77, block; 78, identifier:it; 79, call; 80, comment:# log.debug('[---Augmenting row reduction (iteration: %d)---]', it); 81, block; 82, call; 83, call; 84, identifier:x; 85, identifier:y; 86, expression_list; 87, identifier:x; 88, identifier:y; 89, identifier:_lapmod; 90, argument_list; 91, identifier:cc; 92, call; 93, identifier:ii; 94, call; 95, identifier:kk; 96, call; 97, identifier:x; 98, call; 99, identifier:y; 100, call; 101, identifier:v; 102, call; 103, identifier:free_rows; 104, call; 105, identifier:n_free_rows; 106, call; 107, identifier:n_free_rows; 108, integer:0; 109, if_statement; 110, identifier:range; 111, argument_list; 112, expression_statement; 113, comment:# log.debug(; 114, comment:#   'free, x, y, v: %s %s %s %s', free_rows[:n_free_rows], x, y, v); 115, if_statement; 116, identifier:_pya; 117, argument_list; 118, identifier:get_cost; 119, argument_list; 120, identifier:x; 121, identifier:y; 122, identifier:n; 123, identifier:cc; 124, identifier:ii; 125, identifier:kk; 126, keyword_argument; 127, attribute; 128, argument_list; 129, attribute; 130, argument_list; 131, attribute; 132, argument_list; 133, attribute; 134, argument_list; 135, attribute; 136, argument_list; 137, attribute; 138, argument_list; 139, attribute; 140, argument_list; 141, identifier:_pycrrt; 142, argument_list; 143, comparison_operator:return_cost is True; 144, block; 145, else_clause; 146, integer:2; 147, assignment; 148, comparison_operator:n_free_rows == 0; 149, comment:# log.info('Augmenting row reduction solved it.'); 150, block; 151, identifier:n; 152, identifier:cc; 153, identifier:ii; 154, identifier:kk; 155, identifier:n_free_rows; 156, identifier:free_rows; 157, identifier:x; 158, identifier:y; 159, identifier:v; 160, identifier:n; 161, identifier:cc; 162, identifier:ii; 163, identifier:kk; 164, identifier:x; 165, identifier:fp_version; 166, identifier:fp_version; 167, identifier:np; 168, identifier:ascontiguousarray; 169, identifier:cc; 170, keyword_argument; 171, identifier:np; 172, identifier:ascontiguousarray; 173, identifier:ii; 174, keyword_argument; 175, identifier:np; 176, identifier:ascontiguousarray; 177, identifier:kk; 178, keyword_argument; 179, identifier:np; 180, identifier:empty; 181, tuple; 182, keyword_argument; 183, identifier:np; 184, identifier:empty; 185, tuple; 186, keyword_argument; 187, identifier:np; 188, identifier:empty; 189, tuple; 190, keyword_argument; 191, identifier:np; 192, identifier:empty; 193, tuple; 194, keyword_argument; 195, identifier:n; 196, identifier:cc; 197, identifier:ii; 198, identifier:kk; 199, identifier:free_rows; 200, identifier:x; 201, identifier:y; 202, identifier:v; 203, identifier:return_cost; 204, True; 205, return_statement; 206, block; 207, identifier:n_free_rows; 208, call; 209, identifier:n_free_rows; 210, integer:0; 211, if_statement; 212, identifier:dtype; 213, attribute; 214, identifier:dtype; 215, attribute; 216, identifier:dtype; 217, attribute; 218, identifier:n; 219, identifier:dtype; 220, attribute; 221, identifier:n; 222, identifier:dtype; 223, attribute; 224, identifier:n; 225, identifier:dtype; 226, attribute; 227, identifier:n; 228, identifier:dtype; 229, attribute; 230, expression_list; 231, return_statement; 232, identifier:_pyarr; 233, argument_list; 234, comparison_operator:return_cost is True; 235, block; 236, else_clause; 237, identifier:np; 238, identifier:float64; 239, identifier:np; 240, identifier:int32; 241, identifier:np; 242, identifier:int32; 243, identifier:np; 244, identifier:int32; 245, identifier:np; 246, identifier:int32; 247, identifier:np; 248, identifier:float64; 249, identifier:np; 250, identifier:int32; 251, call; 252, identifier:x; 253, identifier:y; 254, expression_list; 255, identifier:n; 256, identifier:cc; 257, identifier:ii; 258, identifier:kk; 259, identifier:n_free_rows; 260, identifier:free_rows; 261, identifier:x; 262, identifier:y; 263, identifier:v; 264, identifier:return_cost; 265, True; 266, return_statement; 267, block; 268, identifier:get_cost; 269, argument_list; 270, identifier:x; 271, identifier:y; 272, expression_list; 273, return_statement; 274, identifier:n; 275, identifier:cc; 276, identifier:ii; 277, identifier:kk; 278, identifier:x; 279, call; 280, identifier:x; 281, identifier:y; 282, expression_list; 283, identifier:get_cost; 284, argument_list; 285, identifier:x; 286, identifier:y; 287, identifier:n; 288, identifier:cc; 289, identifier:ii; 290, identifier:kk; 291, identifier:x
code: def lapmod(n, cc, ii, kk, fast=True, return_cost=True,
             fp_version=FP_DYNAMIC):
      """Solve sparse linear assignment problem using Jonker-Volgenant algorithm.
  
      n: number of rows of the assignment cost matrix
      cc: 1D array of all finite elements of the assignement cost matrix
      ii: 1D array of indices of the row starts in cc. The following must hold:
              ii[0] = 0 and ii[n+1] = len(cc).
      kk: 1D array of the column indices so that:
              cost[i, kk[ii[i] + k]] == cc[ii[i] + k].
          Indices within one row must be sorted.
      extend_cost: whether or not extend a non-square matrix [default: False]
      cost_limit: an upper limit for a cost of a single assignment
                  [default: np.inf]
      return_cost: whether or not to return the assignment cost
  
      Returns (opt, x, y) where:
        opt: cost of the assignment
        x: vector of columns assigned to rows
        y: vector of rows assigned to columns
      or (x, y) if return_cost is not True.
  
      When extend_cost and/or cost_limit is set, all unmatched entries will be
      marked by -1 in x/y.
      """
      # log = logging.getLogger('lapmod')
  
      check_cost(n, cc, ii, kk)
  
      if fast is True:
          # log.debug('[----CR & RT & ARR & augmentation ----]')
          x, y = _lapmod(n, cc, ii, kk, fp_version=fp_version)
      else:
          cc = np.ascontiguousarray(cc, dtype=np.float64)
          ii = np.ascontiguousarray(ii, dtype=np.int32)
          kk = np.ascontiguousarray(kk, dtype=np.int32)
          x = np.empty((n,), dtype=np.int32)
          y = np.empty((n,), dtype=np.int32)
          v = np.empty((n,), dtype=np.float64)
          free_rows = np.empty((n,), dtype=np.int32)
          # log.debug('[----Column reduction & reduction transfer----]')
          n_free_rows = _pycrrt(n, cc, ii, kk, free_rows, x, y, v)
          # log.debug(
          #     'free, x, y, v: %s %s %s %s', free_rows[:n_free_rows], x, y, v)
          if n_free_rows == 0:
              # log.info('Reduction solved it.')
              if return_cost is True:
                  return get_cost(n, cc, ii, kk, x), x, y
              else:
                  return x, y
          for it in range(2):
              # log.debug('[---Augmenting row reduction (iteration: %d)---]', it)
              n_free_rows = _pyarr(
                      n, cc, ii, kk, n_free_rows, free_rows, x, y, v)
              # log.debug(
              #   'free, x, y, v: %s %s %s %s', free_rows[:n_free_rows], x, y, v)
              if n_free_rows == 0:
                  # log.info('Augmenting row reduction solved it.')
                  if return_cost is True:
                      return get_cost(n, cc, ii, kk, x), x, y
                  else:
                      return x, y
          # log.info('[----Augmentation----]')
          _pya(n, cc, ii, kk, n_free_rows, free_rows, x, y, v)
          # log.debug('x, y, v: %s %s %s', x, y, v)
      if return_cost is True:
          return get_cost(n, cc, ii, kk, x), x, y
      else:
          return x, y