Exemplo n.º 1
0
//template <typename T>
std::vector< int64_t > rand_permute(const int64_t& N, std::default_random_engine& rand_gen)
{
  std::vector< int64_t > permuted(N, 0);
  std::vector< float64_t > permuted_probs(N, 0);
  std::uniform_real_distribution<float64_t> dist(0.0,  1.0); //Does NOT include B, i.e. [0, 1)
  for(size_t a=0; a<N; ++a)
    {
      permuted[a] = a;
      permuted_probs[a] =  dist(rand_gen);
    }
  
  //sort it
  sorter<float64_t> bob( &permuted_probs[0] , permuted_probs.size() );
  bob.add_l( &permuted[0] ); //lol must be int, what if we make size_T? Need to mod sorter algo?
  
  bob.runsort();
  
  //and now we check ordering of index values if we want...?
  return permuted;
}
Exemplo n.º 2
0
  bool sign_matrix(M& matrix, submatrix_indices* violator)
  {
    bool result = true;
    matrix_permuted <M> permuted(matrix);
    size_t handled_rows = 0;

    /// Go trough column by column.
    for (size_t handled_columns = 0; handled_columns < permuted.size2(); ++handled_columns)
    {
      if (find_nonzero_column(permuted, handled_columns, permuted.size2(), 0, handled_rows, handled_columns))
      {
        /// There is a non-zero column right of the already-handled submatrix.

        std::set <size_t> start_nodes;
        std::set <size_t> end_nodes;
        std::set <size_t> all_nodes;

        bipartite_graph_dimensions dim(handled_rows, handled_columns);
        for (size_t row = 0; row < handled_rows; ++row)
        {
          if (permuted(row, handled_columns) != 0)
          {
            size_t index = dim.row_to_index(row);
            if (start_nodes.empty())
              start_nodes.insert(index);
            else
              end_nodes.insert(index);
            all_nodes.insert(index);
          }
        }

        /// Start a BFS on bipartite graph of the submatrix and look for shortest paths from first 1 to all others

        std::vector <bipartite_graph_bfs_node> bfs_result;
        if (!bipartite_graph_bfs(permuted, dim, start_nodes, end_nodes, true, bfs_result))
          throw std::logic_error("Signing procedure: Did not reach all nodes via bfs!");

        /// Evaluate matrix-entries on the shortest paths
        std::map <size_t, bool> changes;
        for (typename std::set <size_t>::const_iterator iter = end_nodes.begin(); iter != end_nodes.end(); ++iter)
        {
          check_sign(permuted, bfs_result, dim, all_nodes, *iter, handled_columns, changes);
        }

        /// Checking changes
        for (std::map <size_t, bool>::iterator iter = changes.begin(); iter != changes.end(); ++iter)
        {
          if (!iter->second)
            continue;

          if (boost::is_const <M>::value)
          {
            if (violator)
            {
              /// Find the violator, going along the path
              std::set <size_t> violator_rows, violator_columns;

              size_t index = iter->first;
              do
              {
                if (dim.is_row(index))
                  violator_rows.insert(permuted.perm1()(dim.index_to_row(index)));
                else
                  violator_columns.insert(permuted.perm2()(dim.index_to_column(index)));

                index = bfs_result[index].predecessor;
              }
              while (all_nodes.find(index) == all_nodes.end());
              violator_rows.insert(permuted.perm1()(dim.index_to_row(index)));
              violator_columns.insert(permuted.perm2()(handled_columns));

              /// Fill violator data
              violator->rows = submatrix_indices::indirect_array_type(violator_rows.size());
              violator->columns = submatrix_indices::indirect_array_type(violator_columns.size());
              size_t i = 0;
              for (std::set <size_t>::const_iterator iter = violator_rows.begin(); iter != violator_rows.end(); ++iter)
                violator->rows[i++] = *iter;
              i = 0;
              for (std::set <size_t>::const_iterator iter = violator_columns.begin(); iter != violator_columns.end(); ++iter)
                violator->columns[i++] = *iter;
            }
            return false;
          }
          else
          {
            /// We are not just testing, so swap the sign on a one.
            size_t real_row = permuted.perm1()(dim.index_to_row(iter->first));
            size_t real_column = permuted.perm2()(handled_columns);
            matrix_set_value(matrix, real_row, real_column, -matrix(real_row, real_column));

            result = false;
          }
        }

        matrix_reorder_rows(permuted, handled_rows, permuted.size1(), handled_columns, permuted.size2(), abs_greater <int> ());

        /// Augment submatrix by rows with 1 in the new column.
        while (handled_rows < permuted.size1())
        {
          if (permuted(handled_rows, handled_columns) == 0)
            break;
          else
            ++handled_rows;
        }
      }
      else
      {
        /// Handled upper-left submatrix and lower-right submatrix are disconnected
        for (size_t column = handled_columns; column < permuted.size2(); ++column)
        {
          size_t count = 0;
          for (size_t row = handled_rows; row < permuted.size1(); ++row)
          {
            if (permuted(row, column) != 0)
              ++count;
          }

          /// A zero column can be skipped, as it is handled by definition.
          if (count > 0)
          {
            /// Found a nonzero column and swap ones to the top.
            matrix_reorder_rows(permuted, handled_rows, permuted.size1(), handled_columns, permuted.size2(), abs_greater <int> ());
            while (handled_rows < permuted.size1())
            {
              if (permuted(handled_rows, handled_columns) == 0)
                break;
              else
                ++handled_rows;
            }

            break;
          }
        }
      }
    }

    return result;
  }