Sorting Network Verify and Draw
Check Whether Comparator Networks Sort and Draw Them
ComparatorNetwork.cpp
Go to the documentation of this file.
1
3
4// MIT License
5//
6// Copyright (c) 2022 Ian Parberry
7//
8// Permission is hereby granted, free of charge, to any person obtaining a copy
9// of this software and associated documentation files (the "Software"), to deal
10// in the Software without restriction, including without limitation the rights
11// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12// copies of the Software, and to permit persons to whom the Software is
13// furnished to do so, subject to the following conditions:
14//
15// The above copyright notice and this permission notice shall be included in all
16// copies or substantial portions of the Software.
17//
18// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24// SOFTWARE.
25
26#include <fstream>
27#include <sstream>
28#include <string>
29
30#include "Includes.h"
31#include "Helpers.h"
32#include "ComparatorNetwork.h"
33
35
37 if(m_nMatch){ //safety
38 for(UINT i=0; i<m_nDepth; i++)
39 delete [] m_nMatch[i];
40 delete [] m_nMatch;
41 } //if
42} //destructor
43
53
54bool CComparatorNetwork::Read(LPWSTR lpwstr){
55 std::ifstream infile(lpwstr); //input file stream
56 bool bSuccess = (bool)infile; //should always be true
57
58 if(bSuccess){
59 const UINT nOldDepth = m_nDepth; //old depth
60
61 UINT nInputs = 0; //number of inputs seen so far
62 UINT nDepth = 0; //depth seen so far
63 UINT nSize = 0; //number of comparators seen so far
64
65 std::vector<std::vector<UINT>> vMatching; //unprocessed matchings from input
66 std::string strLine; //current input line
67 std::vector<UINT> vEmptyVec; //the empty vector
68
69 //load vMatching from file
70
71 while(std::getline(infile, strLine)){ //for each line
72 std::istringstream iss(strLine); //prepare for processing
73 vMatching.push_back(vEmptyVec); //new level, empty so far
74 UINT a, b; //pair of channels for a comparator
75
76 while(iss >> a >> b){ //grab each comparator
77 nInputs = max(max(nInputs, a), b); //adjust inputs seen
78 vMatching[nDepth].push_back(a); //append to current level
79 vMatching[nDepth].push_back(b); //append to current level
80 nSize++; //one more comparator
81 } //while
82
83 nDepth++; //one more level
84 } //while
85
86 nInputs++; //number of inputs is one more than the maximum channel
87
88 //process temporary array nMatch into m_nMatch
89
90 if(bSuccess){
91 CreateMatchArray(nInputs, nDepth);
92 m_nSize = nSize;
93
94 //convert matching from vMatching to match array m_nMatch
95
96 for(UINT i=0; i<vMatching.size(); i++)
97 for(UINT j=0; j<vMatching[i].size(); j+=2){
98 const UINT j0 = vMatching[i][j]; //one end of comparator
99
100 if(j < vMatching[i].size() - 1){
101 const UINT j1 = vMatching[i][j + 1]; //the other end of comparator
102
103 if(j0 < m_nInputs && j1 < m_nInputs){
104 m_nMatch[i][j0] = j1;
105 m_nMatch[i][j1] = j0;
106 } //if
107 } //if
108 } //for
109 } //if
110 } //if
111
112 return bSuccess;
113} //Read
114
119
120void CComparatorNetwork::InsertComparator(UINT nLevel, UINT i, UINT j){
121 if(nLevel < m_nDepth && i < m_nInputs && j < m_nInputs){
122 m_nMatch[nLevel][i] = j;
123 m_nMatch[nLevel][j] = i;
124 } //if
125} //InsertComparator
126
131
132void CComparatorNetwork::Prune(const UINT n){
133 if(n < 2 || n >= m_nInputs)return; //safety
134
135 //delete comparators attached to pruned channels
136
137 for(UINT i=0; i<m_nDepth; i++)
138 for(UINT j=0; j<n; j++)
139 if(m_nMatch[i][j] >= n){
140 m_nMatch[i][j] = j;
141 } //if
142
143 m_nInputs = n; //reset the mumber of inputs
144
145 //recompute the size (number of comparators)
146
147 m_nSize = 0;
148
149 for(UINT i=0; i<m_nDepth; i++)
150 for(UINT j=0; j<m_nInputs; j++)
151 if(m_nMatch[i][j] > j)
152 m_nSize++;
153} //Prune
154
159
160void CComparatorNetwork::CreateMatchArray(UINT nInputs, UINT nDepth){
161 if(m_nMatch){ //there's already one, so delete it
162 for(UINT i=0; i<nDepth; i++)
163 delete [] m_nMatch[i];
164 delete [] m_nMatch;
165 } //if
166
167 m_nInputs = nInputs;
168 m_nDepth = nDepth;
169
170 m_nMatch = new UINT*[m_nDepth];
171
172 for(UINT i=0; i<m_nDepth; i++){
173 m_nMatch[i] = new UINT[m_nInputs];
174 for(UINT j=0; j<m_nInputs; j++)
175 m_nMatch[i][j] = j; //default is unused
176 } //for
177} //CreateMatchArray
178
182
184 m_nSize = 0;
185
186 if(m_nMatch)
187 for(UINT i=0; i<m_nDepth; i++){
188 for(UINT j=0; j<m_nInputs; j++)
189 if(m_nMatch[i][j] > j)
190 m_nSize++;
191 } //for
192} //ComputeSize
193
196
198 return m_nInputs;
199} //GetNumInputs
200
203
205 return m_nDepth;
206} //GetDepth
207
210
212 return m_nSize;
213} //GetSize
214
225
227 if(m_nMatch == nullptr)return false; //bail and fail
228 if(m_nMatch[0] == nullptr)return false; //bail and fail
229
230 bool ok = true; //true if nothing is inconsistent with first normal form so far
231
232 for(UINT j=0; j<m_nInputs-1 && ok; j+=2) //comparators on consecutive channels
233 ok = ok && m_nMatch[0][j] == j + 1 && m_nMatch[0][j + 1] == j;
234
235 if(ok && odd(m_nInputs)) //last channel is empty
236 ok = ok && m_nMatch[0][m_nInputs - 1] == m_nInputs - 1;
237
238 return ok;
239} //FirstNormalForm
Interface for the comparator network CComparatorNetwork.
bool odd(const UINT n)
Parity test.
Definition: Helpers.cpp:32
Header for useful helper functions.
Useful includes.
UINT ** m_nMatch
Matchings at each level.
~CComparatorNetwork()
Destructor.
const UINT GetDepth() const
Get depth.
void Prune(const UINT)
Prune down number of inputs.
virtual bool Read(LPWSTR)
Read from file.
const bool FirstNormalForm() const
Test for first normal form.
void InsertComparator(UINT, UINT, UINT)
Insert comparator.
void ComputeSize()
Compute size.
const UINT GetSize() const
Get size.
const UINT GetNumInputs() const
Get number of inputs.
UINT m_nInputs
Number of inputs.
void CreateMatchArray(UINT, UINT)
Create match array.