spot 2.16
Loading...
Searching...
No Matches
permute.hh
1// -*- coding: utf-8 -*-
2// Copyright (C) by the Spot authors, see the AUTHORS file for details.
3//
4// This file is part of Spot, a model checking library.
5//
6// Spot is free software; you can redistribute it and/or modify it
7// under the terms of the GNU General Public License as published by
8// the Free Software Foundation; either version 3 of the License, or
9// (at your option) any later version.
10//
11// Spot is distributed in the hope that it will be useful, but WITHOUT
12// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14// License for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <http://www.gnu.org/licenses/>.
18
19#pragma once
20
21#include <spot/misc/common.hh>
22#include <vector>
23#include <algorithm>
24
25namespace spot
26{
27
30 // Reorder `data` according the permutation in `indices` by
31 // following the cycles in the permutation. Additionally, if an
32 // index is -1, the corresponding value is moved to the end of the
33 // data.
34 //
35 // After running this algorithm, data[i] should be moved to
36 // data[indices[i]] or to the end of the data if indices[i] == -1U.
37 //
38 // If indices.size() != data.size(), the minimum of both size is
39 // used, and indices are expected to stay in this range.
40 template<typename values>
41 void permute_vector(std::vector<values>& data,
42 const std::vector<unsigned>& indices)
43 {
44 unsigned n = std::min(data.size(), indices.size());
45 if (n == 0)
46 return;
47 std::vector<bool> done(n, false);
48 unsigned end_of_data = n - 1; // index for the first -1
49 for (unsigned i = 0; i < n; ++i)
50 {
51 if (done[i] || indices[i] == i)
52 continue; // already done or identity
53 unsigned next = indices[i];
54 if (next == -1U)
55 {
56 next = end_of_data--;
57 if (next == i)
58 continue;
59 }
60 values tmp = std::move(data[i]);
61 while (next != i)
62 {
63 SPOT_ASSERT(next < n);
64 if (done[next])
65 throw std::invalid_argument
66 ("permute_vector: invalid permutation");
67 // this is a swap, but std::swap will not work
68 // when data[next] is a bool_reference.
69 values tmp2 = std::move(data[next]);
70 data[next] = std::move(tmp);
71 tmp = std::move(tmp2);
72 done[next] = true;
73
74 next = indices[next];
75 if (next == -1U)
76 next = end_of_data--;
77 }
78 data[i] = std::move(tmp);
79 done[i] = true;
80 }
81 }
82
83}
void permute_vector(std::vector< values > &data, const std::vector< unsigned > &indices)
Reorder data in place according to the permutation indices.
Definition permute.hh:41
Definition automata.hh:26

Please direct any question, comment, or bug report to the Spot mailing list at spot@lrde.epita.fr.
Generated on Fri Feb 27 2015 10:00:07 for spot by doxygen 1.9.8