Mantid
Loading...
Searching...
No Matches
Acomp.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
10#include "MantidKernel/Logger.h"
11#include "MantidKernel/Matrix.h"
13
14#include <algorithm>
15#include <functional>
16#include <iterator>
17#include <ostream>
18
19namespace Mantid {
20
21namespace {
22Kernel::Logger logger("Acomp");
23}
24namespace Geometry {
25
26using Kernel::Matrix;
27
28// Friend function
29std::ostream &operator<<(std::ostream &OX, const Acomp &A)
37{
38 OX << A.display();
39 return OX;
40}
41
42void split(const int A, int &S, int &V)
50{
51 if (A >= 0) {
52 S = 1;
53 V = A;
54 } else {
55 S = -1;
56 V = -A;
57 }
58}
59
60//
61// ------------- ACOMP ----------------
62//
63
64Acomp::Acomp(const int Tx)
65 : Intersect(Tx)
70{}
71
72bool Acomp::operator!=(const Acomp &A) const
78{
79 return !(this->operator==(A));
80}
81
82bool Acomp::operator==(const Acomp &A) const
90{
91 // Size not equal then definately not equal
92 if (A.Units.size() != Units.size())
93 return false;
94 if (A.Comp.size() != Comp.size())
95 return false;
96 // Intersect not the same (unless size==1)
97 if (A.Intersect != Intersect && Units.size() + Comp.size() != 1) // Intersect type is not relevent
98 return false; // if singular.
99
100 // If Units not empty compare each and determine
101 // if equal.
102 if (!Units.empty()) {
103 std::vector<int>::const_iterator vc, xc;
104 xc = A.Units.begin();
105 for (vc = Units.begin(); vc != Units.end(); ++xc, ++vc)
106 if (*vc != *xc)
107 return false;
108 }
109
110 // Both Empty :: thus equal
111 if (Comp.empty())
112 return true;
113
114 // Assume that comp Units are sorted.
115 return A.Comp == Comp;
116}
117
118bool Acomp::operator<(const Acomp &A) const
132{
133 // PROCESS Singular
134 const int TS = isSingle(); // is this one component
135 const int AS = A.isSingle();
136 if (TS != AS)
137 return TS > AS;
138 // PROCESS Intersection/Union
139 if (!TS && Intersect != A.Intersect) {
140 // Union==0 therefore this > A
141 return Intersect > 0;
142 }
143
144 // PROCESS Units. (order : then size)
145 std::vector<int>::const_iterator uc, ac;
146 ac = A.Units.begin();
147 uc = Units.begin();
148 for (; ac != A.Units.end() && uc != Units.end(); ++uc, ++ac)
149 if (*uc != *ac)
150 return (*uc < *ac);
151
152 if (ac != A.Units.end())
153 return false;
154 if (uc != Units.end())
155 return true;
156
157 // PROCESS CompUnits.
158 std::vector<Acomp>::const_iterator ux, ax;
159 ux = Comp.begin();
160 ax = A.Comp.begin();
161 for (; ux != Comp.end() && ax != A.Comp.end(); ++ux, ++ax) {
162 if (*ax != *ux)
163 return (*ux < *ax);
164 }
165 return false;
166}
167
174{
175 if (Intersect) // If this is an intersection
176 { // we need to have a union
177 Acomp Ax = Acomp(*this); // make copy
178 Units.clear(); // remove everthing else
179 Comp.clear();
180 Intersect = 0; // make this into a Union
181 addComp(Ax); // add oldThis to the list
182 }
183 // Now add A to the union.
184 if (!A.Intersect) // Can add components
185 copySimilar(A);
186 else
187 addComp(A); // add components
188
189 removeEqComp(); // remove equal units
190 joinDepth(); // Up shift suitable objects.
191 return *this;
192}
193
204{
205
206 std::vector<Acomp> Fparts; // Parts in This
207 std::vector<Acomp> Gparts; // Parts in A
208 if (!getDNFpart(Fparts) || !A.getDNFpart(Gparts))
209 return *this;
210
211 std::vector<Acomp> Outparts; // Parts in F not in G
212 std::vector<Acomp> NegParts; // Parts in G not in F
213
214 // Have DNF parts and will return the same...
215 // Sort the components of the list
216 std::for_each(Fparts.begin(), Fparts.end(), std::mem_fn(&Acomp::Sort));
217 std::for_each(Gparts.begin(), Gparts.end(), std::mem_fn(&Acomp::Sort));
218
219 // Sort the list itself...
220 std::sort(Gparts.begin(), Gparts.end());
221 std::sort(Fparts.begin(), Fparts.end());
222
223 // Process Components:
224 std::vector<Acomp>::const_iterator fc, gc;
225 gc = Gparts.begin();
226 for (fc = Fparts.begin(); gc != Gparts.end() && fc != Fparts.end(); ++fc) {
227 while (gc != Gparts.end() && (*gc < *fc)) {
228 NegParts.emplace_back(*gc);
229 ++gc;
230 }
231
232 if (gc != Gparts.end() && *gc == *fc) // match
233 ++gc;
234 else // ok that didn't work so add to us
235 Outparts.emplace_back(*fc);
236 }
237 // add extra bits from Gparts onto NegParts
238 for (; gc != Gparts.end(); ++gc)
239 NegParts.emplace_back(*gc);
240
241 // Clear This to put in Outparts.
242 Units.clear();
243 Comp.clear();
244 Intersect = 0;
245 for (fc = Outparts.begin(); fc != Outparts.end(); ++fc)
246 addComp(*fc);
247 joinDepth();
248 removeEqComp(); // move equal items.
249 // Now add any components from g but need to be as intersections
250 std::vector<Acomp>::iterator negX;
251 for (negX = NegParts.begin(); negX != NegParts.end(); ++negX) {
252 negX->complement();
253 this->operator*=(*negX);
254 }
255 removeEqComp();
256 return *this;
257}
258
259bool Acomp::operator>(const Acomp &A) const
267{
268 return A.operator<(*this);
269}
270
278{
279 if (!Intersect) // If this is an intersection
280 { // we need to have a union
281 Acomp Ax = Acomp(*this); // make copy
282 Units.clear(); // remove everthing else
283 Comp.clear();
284 Intersect = 1; // make this into a Union
285 addComp(Ax); // add oldThis to the list
286 }
287 if (A.Intersect) // can add components
288 copySimilar(A);
289 else
290 addComp(A); // combine components
291 removeEqComp();
292 joinDepth();
293 return *this;
294}
295
296// ---------------------------------------------------
297// PRIVATE FUNCTIONS
298// ---------------------------------------------------
299
304{
305 Comp.clear();
306}
307
308void Acomp::addComp(const Acomp &AX)
316{
317 std::pair<int, int> Stype = AX.size();
318 if (Stype.first + Stype.second == 0)
319 throw std::runtime_error("Pair Count wrong in AddComp");
320
321 if (AX.isSingle() || AX.Intersect == Intersect) // single unit component/Conjoint
322 {
323 std::vector<int>::const_iterator aup;
324 for (aup = AX.Units.begin(); aup != AX.Units.end(); ++aup) {
325 std::vector<int>::iterator ipt;
326 ipt = std::lower_bound(Units.begin(), Units.end(), *aup);
327 if (ipt == Units.end() || *ipt != *aup) // Only insert if new
328 Units.insert(ipt, *aup);
329 }
330 std::vector<Acomp>::const_iterator acp;
331 for (acp = AX.Comp.begin(); acp != AX.Comp.end(); ++acp) {
332 std::vector<Acomp>::iterator cpt;
333 cpt = std::lower_bound(Comp.begin(), Comp.end(), *acp);
334 if (cpt == Comp.end() || (AX.Units.end() != aup && *cpt != *aup)) // Only insert if new
335 Comp.insert(cpt, *acp);
336 }
337 return;
338 }
339 // Type different insertion
340 std::vector<Acomp>::iterator cpt;
341 cpt = std::lower_bound(Comp.begin(), Comp.end(), AX);
342 if (cpt == Comp.end() || *cpt != AX) // Only insert if new
343 Comp.insert(cpt, AX);
344}
345
346void Acomp::addUnitItem(const int Item)
351{
352 // Quick and cheesy insertion if big.
353 std::vector<int>::iterator ipt;
354 ipt = std::lower_bound(Units.begin(), Units.end(), Item);
355 if (ipt == Units.end() || *ipt != Item) // Only insert if new
356 Units.insert(ipt, Item);
357}
358
359void Acomp::processIntersection(const std::string &Ln)
368{
369 std::string Bexpress; // bracket expression
370 int blevel = 0; // this should already be zero!!
371 // find first Component to add
372 // std::cerr<<"Process Inter:"<<Ln<<'\n';
373 int numItem(0);
374 for (unsigned int iu = 0; iu < Ln.length(); iu++) {
375 if (blevel) // we are in a bracket then...
376 {
377 if (Ln[iu] == ')') // maybe closing outward..
378 blevel--;
379 else if (Ln[iu] == '(')
380 blevel++;
381 if (blevel)
382 Bexpress += Ln[iu];
383 else // Process end: of Brackets
384 {
385 Acomp AX;
386 try {
387 AX.setString(Bexpress);
388 } catch (...) {
389 logger.error() << "Error in string creation\n";
390 }
391 Bexpress.erase(); // reset string
392 addComp(AX); // add components
393 }
394 } else // Not in a bracket (currently)
395 {
396 if (Ln[iu] == '(')
397 blevel++;
398 else if (isalpha(Ln[iu]) || Ln[iu] == '%') {
399 if (Ln[iu] == '%') {
400 iu++;
401 const int Nmove = Mantid::Kernel::Strings::convPartNum(Ln.substr(iu), numItem);
402 if (!Nmove)
403 throw std::invalid_argument("Acomp::procIntersection error in line Ln\"" + Ln + "\"");
404 numItem += 52;
405 iu += Nmove;
406 } else {
407 numItem = (islower(Ln[iu])) ? static_cast<int>(1 + Ln[iu] - 'a') : static_cast<int>(27 + Ln[iu] - 'A');
408 iu++;
409 }
410 if (iu < Ln.length() && Ln[iu] == '\'') {
411 addUnitItem(-numItem);
412 } else {
413 addUnitItem(numItem);
414 iu--;
415 }
416 }
417 }
418 }
419}
420
421void Acomp::processUnion(const std::string &Ln)
430{
431 std::string Express; // Intersection Expression
432 int blevel = 0;
433 int bextra = 0;
434 // find first Component to add
435 // std::cerr<<"Process Union:"<<Ln<<'\n';
436 for (char iu : Ln) {
437 if (blevel) // we are in a bracket then...
438 {
439 if (iu == ')') // maybe closing outward..
440 blevel--;
441 else if (iu == '(')
442 blevel++;
443 if (blevel || bextra)
444 Express += iu;
445 } else {
446 if (iu == '+') {
447 Acomp AX;
448 try {
449 AX.setString(Express);
450 } catch (...) {
451 logger.error() << "Error in string \n";
452 throw;
453 }
454 Express.erase(); // reset string
455 addComp(AX); // add components
456 } else if (iu == '(') {
457 blevel++;
458 if (Express.length()) {
459 Express += '(';
460 bextra = 1;
461 } else
462 bextra = 0;
463 } else
464 Express += iu;
465 }
466 }
467 if (!Express.empty()) {
468 Acomp AX;
469 try {
470 AX.setString(Express);
471 } catch (...) {
472 logger.error() << "Error in bracket ::\n";
473 throw;
474 }
475 addComp(AX); // add component
476 }
477}
478
487{
488 // copy units and components
489 if (Intersect != A.Intersect)
490 return -1;
491
492 if (!A.Units.empty()) {
493 Units.resize(Units.size() + A.Units.size());
494 copy(A.Units.begin(), A.Units.end(), back_inserter(Units));
495 std::sort(Units.begin(), Units.end());
496 }
497
498 // Add components
499 std::vector<Acomp>::const_iterator vc;
500 for (vc = A.Comp.begin(); vc != A.Comp.end(); ++vc)
501 addComp(*vc);
502 return 0;
503}
504
505void Acomp::addUnit(const std::vector<int> &Index, const BnId &BX)
512{
513 int S, V;
514 for (int i = 0; i < static_cast<int>(BX.Size()); i++) {
515 int flag = BX[i];
516 if (flag) {
517 split(flag, S, V);
518 if (V >= static_cast<int>(Index.size()))
519 throw std::runtime_error("Error with addUnit::Index");
520 Units.emplace_back(S * Index[i]);
521 }
522 }
523 std::sort(Units.begin(), Units.end());
524}
525
526void Acomp::assignDNF(const std::vector<int> &Index, const std::vector<BnId> &A)
533{
534 Units.clear();
535 deleteComp();
536 if (A.empty())
537 return;
538
539 if (A.size() == 1) // special case for single intersection
540 {
541 Intersect = 1;
542 addUnit(Index, A[0]);
543 return;
544 }
545
546 Intersect = 0; // union of intersection
547 std::vector<BnId>::const_iterator vc;
548 for (vc = A.begin(); vc != A.end(); ++vc) {
549 Acomp Px(1); // Intersection
550 Px.addUnit(Index, *vc);
551 addComp(Px);
552 }
553}
554
555void Acomp::assignCNF(const std::vector<int> &Index, const std::vector<BnId> &A)
562{
563 Units.clear();
564 deleteComp();
565 if (A.empty())
566 return;
567
568 if (A.size() == 1) // special case for single union
569 {
570 Intersect = 0;
571 addUnit(Index, A[0]);
572 return;
573 }
574
575 Intersect = 1; // intersection of union
576 std::vector<BnId>::const_iterator vc;
577 for (vc = A.begin(); vc != A.end(); ++vc) {
578 Acomp Px(0); // Union
579 // std::cout<<"Item == "<<*vc<<'\n';
580 BnId X = *vc;
581 X.reverse();
582 Px.addUnit(Index, X);
583 addComp(Px);
584 }
585}
586
587// -------------------------------------
588// PUBLIC FUNCTIONS
589// -------------------------------------
590
596{
597 std::sort(Units.begin(), Units.end());
598 // Sort each decending object first
599 std::for_each(Comp.begin(), Comp.end(), std::mem_fn(&Acomp::Sort));
600 // use the sorted components to sort our component list
601 std::sort(Comp.begin(), Comp.end());
602}
603
612{
613 std::map<int, int> LitSet;
614 getLiterals(LitSet);
615 /* // Process DNF
616 if (isDNF())
617 return makeReadOnceForDNF();
618 if (isCNF())
619 return makeReadOnceForCNF();
620 return 0;
621 */
622 return 0;
623}
624
625int Acomp::logicalEqual(const Acomp &A) const
632{
633 std::map<int, int> litMap; // keynumber :: number of occurances
634 getAbsLiterals(litMap);
635
636 A.getAbsLiterals(litMap);
637 std::map<int, int> Base; // keynumber :: number of occurances
638 std::vector<int> keyNumbers;
639
640 std::map<int, int>::const_iterator mc;
641 for (mc = litMap.begin(); mc != litMap.end(); ++mc) {
642 Base[mc->first] = 1; // Insert and Set to true
643 keyNumbers.emplace_back(mc->first);
644 }
645
646 BnId State(Base.size(), 0); // zero base
647 do {
648 State.mapState(keyNumbers, Base);
649 if (isTrue(Base) != A.isTrue(Base))
650 return 0;
651 } while (++State);
652 return 1;
653}
654
655int Acomp::isNull() const
659{
660 return ((Units.empty() && Comp.empty()) ? 1 : 0);
661}
662
663int Acomp::isDNF() const
671{
672 // If an intersect (single component)
673 if (Intersect) {
674 return (Comp.empty()) ? 1 : 0;
675 }
676 const auto it = std::find_if(Comp.cbegin(), Comp.cend(),
677 [](const auto &acomp) { return acomp.isInter() == 0 || !acomp.isSimple(); });
678 if (it != Comp.cend()) {
679 return 0;
680 }
681 return 1;
682}
683
684int Acomp::isCNF() const
692{
693 // If an intersect (single component)
694 if (!Intersect) {
695 return (Comp.empty()) ? 1 : 0;
696 }
697 const auto it = std::find_if(Comp.cbegin(), Comp.cend(),
698 [](const auto &acomp) { return acomp.isInter() == 1 || !acomp.isSimple(); });
699 if (it != Comp.cend()) {
700 return 0;
701 }
702 return 1;
703}
704
705void Acomp::getAbsLiterals(std::map<int, int> &literalMap) const
713{
714 std::vector<int>::const_iterator uc;
715 std::map<int, int>::iterator mc;
716 int S, V;
717 for (uc = Units.begin(); uc != Units.end(); ++uc) {
718 split(*uc, S, V);
719 mc = literalMap.find(V);
720 if (mc != literalMap.end())
721 mc->second++;
722 else
723 literalMap.emplace(V, 1);
724 }
725 std::vector<Acomp>::const_iterator cc;
726 for (cc = Comp.begin(); cc != Comp.end(); ++cc)
727 cc->getAbsLiterals(literalMap);
728}
729
730void Acomp::getLiterals(std::map<int, int> &literalMap) const
738{
739 std::vector<int>::const_iterator uc;
740 std::map<int, int>::iterator mc;
741 for (uc = Units.begin(); uc != Units.end(); ++uc) {
742 mc = literalMap.find(*uc);
743 if (mc != literalMap.end())
744 mc->second++;
745 else
746 literalMap.emplace(*uc, 1);
747 }
748 std::vector<Acomp>::const_iterator cc;
749 for (cc = Comp.begin(); cc != Comp.end(); ++cc) {
750 cc->getLiterals(literalMap);
751 }
752}
753
760{
761 return (Comp.empty() ? 1 : 0);
762}
763
770{
771 return (Comp.size() + Units.size() > 1 ? 0 : 1);
772}
773
779{
780 // First check all the Comp units:
781 int cnt(0);
782 std::vector<Acomp>::iterator dx;
783 sort(Comp.begin(), Comp.end());
784 dx = std::unique(Comp.begin(), Comp.end());
785 cnt += static_cast<int>(std::distance(dx, Comp.end()));
786 Comp.erase(dx, Comp.end());
787
788 // Units are sorted
789
790 sort(Units.begin(), Units.end());
791 auto ux = unique(Units.begin(), Units.end());
792 cnt += static_cast<int>(std::distance(ux, Units.end()));
793 Units.erase(ux, Units.end());
794 return cnt;
795}
796
797int Acomp::makePI(std::vector<BnId> &DNFobj) const
807{
808 if (DNFobj.empty()) // no work to do return.
809 return 0;
810 // Note: need to store PI components separately
811 // since we don't want to loop continuously through them
812 std::vector<BnId> Work; // Working copy
813 std::vector<BnId> PIComp; // Store for PI componends
814 std::vector<BnId> Tmod; // store modified components
815 std::vector<BnId>::iterator uend; // itor to remove unique
816 // Need to make an initial copy.
817 Work = DNFobj;
818
819 do {
820 // Deal with tri-state objects ??
821 sort(Work.begin(), Work.end());
822 uend = unique(Work.begin(), Work.end());
823 Work.erase(uend, Work.end());
824 Tmod.clear(); // erase all at the start
825 // set PI status to 1
826 using std::placeholders::_1;
827 for_each(Work.begin(), Work.end(), std::bind(std::mem_fn(&BnId::setPI), _1, 1));
828
829 // Collect into pairs which have a difference of +/- one
830 // object
831 // Can sort this realive to
832 std::vector<BnId>::iterator vc;
833 for (vc = Work.begin(); vc != Work.end(); ++vc) {
834 const int GrpIndex(vc->TrueCount() + 1);
835 for (auto oc = vc + 1; oc != Work.end(); ++oc) {
836 const int OCnt = oc->TrueCount();
837 if (OCnt > GrpIndex)
838 break;
839 if (OCnt == GrpIndex) {
840 std::pair<int, BnId> cVal = vc->makeCombination(*oc);
841 if (cVal.first == 1) // was complementary
842 {
843 Tmod.emplace_back(cVal.second);
844 oc->setPI(0);
845 vc->setPI(0);
846 }
847 }
848 }
849 }
850
851 for (vc = Work.begin(); vc != Work.end(); ++vc)
852 if (vc->PIstatus() == 1)
853 PIComp.emplace_back(*vc);
854 Work = Tmod;
855
856 } while (!Tmod.empty());
857 // Copy over the unit.
858
859 return makeEPI(DNFobj, PIComp);
860}
861
862int Acomp::makeEPI(std::vector<BnId> &DNFobj, std::vector<BnId> &PIform) const
873{
874 if (PIform.empty())
875 return 0;
876
877 std::vector<BnId> EPI; // Created Here.
878
879 // Make zeroed matrix.
880 Kernel::Matrix<int> Grid(PIform.size(), DNFobj.size());
881 std::vector<int> DNFactive(DNFobj.size()); // DNF that active
882 std::vector<int> PIactive(PIform.size()); // PI that are active
883 std::vector<int> DNFscore(DNFobj.size()); // Number in each channel
884 std::vector<int> PIscore(DNFobj.size()); // Number in each channel
885
886 // Populate
887 for (int pc = 0; pc != static_cast<int>(PIform.size()); pc++) {
888 PIactive[pc] = pc;
889 }
890 for (int ic = 0; ic != static_cast<int>(DNFobj.size()); ic++) {
891 DNFactive[ic] = ic; // populate (avoid a loop)
892 for (int pc = 0; pc != static_cast<int>(PIform.size()); pc++) {
893 if (PIform[pc].equivalent(DNFobj[ic])) {
894 Grid[pc][ic] = 1;
895 DNFscore[ic]++;
896 }
897 }
898 if (DNFscore[ic] == 0) {
899 logger.error() << "PIForm:\n";
900 copy(PIform.begin(), PIform.end(), std::ostream_iterator<BnId>(logger.error(), "\n"));
901 logger.error() << "Error with DNF / EPI determination at " << ic << '\n';
902 logger.error() << " Items " << DNFobj[ic] << '\n';
903 return 0;
904 }
905 }
906
907 std::vector<int>::iterator dx, ddx; // DNF active iterator
908 std::vector<int>::const_iterator px; // PIactive iterator
909
910 //
911 // First remove singlets:
912 //
913 for (dx = DNFactive.begin(); dx != DNFactive.end(); ++dx) {
914 if (*dx >= 0 && DNFscore[*dx] == 1) // EPI (definately)
915 {
916 px = std::find_if(PIactive.cbegin(), PIactive.cend(), [&](const int pi) { return Grid[pi][*dx]; });
917
918 if (PIactive.cend() == px)
919 continue;
920
921 EPI.emplace_back(PIform[*px]);
922 // remove all minterm that the EPI covered
923 for (ddx = DNFactive.begin(); ddx != DNFactive.end(); ++ddx)
924 if (*ddx >= 0 && Grid[*px][*ddx])
925 *ddx = -1; // mark for deletion (later)
926 // Can remove PIactive now.
927 PIactive.erase(px, px + 1);
928 }
929 }
930 // Remove dead items from active list
931 using std::placeholders::_1;
932 DNFactive.erase(remove_if(DNFactive.begin(), DNFactive.end(), std::bind(std::less<int>(), _1, 0)), DNFactive.end());
933
934 // Ok -- now the hard work...
935 // need to find shortest "combination" that spans
936 // the remaining table.
937
938 // First Make a new matrix for speed. Useful ???
939 Kernel::Matrix<int> Cmat(PIactive.size(),
940 DNFactive.size()); // corrolation matrix
941 int cm(0);
942 for (px = PIactive.begin(); px != PIactive.end(); ++px) {
943 int dm(0);
944 for (ddx = DNFactive.begin(); ddx != DNFactive.end(); ++ddx) {
945 if (Grid[*px][*ddx])
946 Cmat[cm][dm] = 1;
947 dm++;
948 }
949 cm++;
950 }
951
952 const auto Dsize(static_cast<int>(DNFactive.size()));
953 const auto Psize(static_cast<int>(PIactive.size()));
954 // icount == depth of search ie
955 int vecI, di; // variable for later
956 for (int Icount = 1; Icount < Psize; Icount++) {
957 // This counter is a ripple counter, ie 1,2,3 where no numbers
958 // are the same. BUT it is acutally 0->N 0->N 0->N
959 // index by A, A+1 ,A+2 etc
960 RotaryCounter Index(Icount, Psize);
961 do {
962
963 for (di = 0; di < Dsize; di++) // check each orignal position
964 {
965 for (vecI = 0; vecI < Icount; vecI++) {
966 if (Cmat[Index[vecI]][di])
967 break;
968 }
969 if (vecI == Icount)
970 break;
971 }
972 if (di == Dsize) // SUCCESS!!!!!
973 {
974 for (int iout = 0; iout < Icount; iout++) {
975 EPI.emplace_back(PIform[Index[iout]]);
976 }
977 DNFobj = EPI;
978 return 1;
979 }
980 } while (!(++Index));
981 }
982
983 // OH well that means every PIactive is a EPI :-(
984 for (px = PIactive.begin(); px != PIactive.end(); ++px)
985 EPI.emplace_back(PIform[*px]);
986 DNFobj = EPI;
987 return 1;
988}
989
990std::vector<int> Acomp::getKeys() const
995{
996 std::map<int, int> litMap; // keynumber :: number of occurances
997 std::vector<int> keyNumbers;
998 getAbsLiterals(litMap);
999 std::map<int, int>::const_iterator mc;
1000 for (mc = litMap.begin(); mc != litMap.end(); ++mc)
1001 keyNumbers.emplace_back(mc->first);
1002
1003 return keyNumbers;
1004}
1005
1006int Acomp::getDNFobject(std::vector<int> &keyNumbers, std::vector<BnId> &DNFobj) const
1018{
1019 std::map<int, int> litMap; // keynumber :: number of occurances
1020 std::map<int, int> Base; // keynumber :: value
1021 getAbsLiterals(litMap);
1022
1023 if (litMap.empty())
1024 return -1;
1025
1026 keyNumbers.clear();
1027 std::map<int, int>::iterator mc;
1028
1029 for (mc = litMap.begin(); mc != litMap.end(); ++mc) {
1030 Base[mc->first] = 1; // Set to true
1031 keyNumbers.emplace_back(mc->first);
1032 }
1033
1034 DNFobj.clear();
1035 BnId State(Base.size(), 0); // zero base
1036 do {
1037 State.mapState(keyNumbers, Base);
1038 if (isTrue(Base)) {
1039 DNFobj.emplace_back(State);
1040 }
1041 } while (++State);
1042
1043 return 0;
1044}
1045
1052{
1053 std::vector<BnId> DNFobj;
1054 std::vector<int> keyNumbers;
1055 if (!getDNFobject(keyNumbers, DNFobj)) {
1056 if (makePI(DNFobj))
1057 assignDNF(keyNumbers, DNFobj);
1058 return static_cast<int>(DNFobj.size());
1059 }
1060 return 0;
1061}
1062
1069{
1070 std::vector<BnId> CNFobj;
1071 std::vector<int> keyNumbers;
1072 if (!getCNFobject(keyNumbers, CNFobj)) {
1073 if (makePI(CNFobj))
1074 assignCNF(keyNumbers, CNFobj);
1075 return static_cast<int>(CNFobj.size());
1076 }
1077 return 0;
1078}
1079
1080int Acomp::getDNFpart(std::vector<Acomp> &Parts) const
1088{
1089 // If this is DNF then we don't want to calculate the DNF but just use it
1090 if (isDNF()) {
1091 Parts.clear();
1092 Parts.reserve(Units.size() + Comp.size());
1093 for (const auto &item : Units) {
1094 Acomp Aitem(1); // Intersection (doesn't matter since 1 object)
1095 Aitem.addUnitItem(item);
1096 Parts.emplace_back(Aitem);
1097 }
1098 std::copy(Comp.cbegin(), Comp.cend(), std::back_inserter(Parts));
1099 return static_cast<int>(Parts.size());
1100 }
1101
1102 std::vector<int> keyNumbers;
1103 std::vector<BnId> DNFobj;
1104 if (!getDNFobject(keyNumbers, DNFobj)) {
1105 if (makePI(DNFobj)) {
1106 for (const auto &obj : DNFobj) {
1107 Acomp Aitem(1); // make an intersection and add components
1108 Aitem.addUnit(keyNumbers, obj);
1109 Parts.emplace_back(Aitem);
1110 }
1111 }
1112 return static_cast<int>(Parts.size());
1113 }
1114 return 0;
1115}
1116
1117int Acomp::getCNFobject(std::vector<int> &keyNumbers, std::vector<BnId> &CNFobj) const
1129{
1130 std::map<int, int> litMap; // keynumber :: number of occurances
1131 std::map<int, int> Base; // keynumber :: value
1132 getAbsLiterals(litMap);
1133
1134 if (litMap.empty())
1135 return -1;
1136
1137 keyNumbers.clear();
1138 std::map<int, int>::iterator mc;
1139 int cnt(0);
1140
1141 for (mc = litMap.begin(); mc != litMap.end(); ++mc) {
1142 mc->second = cnt++;
1143 Base[mc->first] = 1; // Set to true
1144 keyNumbers.emplace_back(mc->first);
1145 }
1146
1147 CNFobj.clear();
1148 BnId State(Base.size(), 0); // zero base
1149 do {
1150 State.mapState(keyNumbers, Base);
1151 if (!isTrue(Base))
1152 CNFobj.emplace_back(State);
1153 } while (++State);
1154
1155 return 0;
1156}
1157
1158int Acomp::isTrue(const std::map<int, int> &Base) const
1165{
1166 if (Units.empty() && Comp.empty())
1167 return 1;
1168
1169 // Deal with case of a single object (then join
1170 // doesn't matter
1171 auto retJoin = static_cast<int>(Units.size() + Comp.size());
1172 if (retJoin != 1) // single unit is alway ok
1173 retJoin = 1 - Intersect;
1174
1175 int S, V;
1176 std::map<int, int>::const_iterator bv;
1177 std::vector<int>::const_iterator uc;
1178 // e.g. a'b 1 1 (retJoin ==1)
1179 for (uc = Units.begin(); uc != Units.end(); ++uc) {
1180 split(*uc, S, V);
1181 bv = Base.find(V);
1182 if (bv == Base.end())
1183 throw std::runtime_error("Base unit not found");
1184 int aimTruth = (S < 0) ? 1 - retJoin : retJoin;
1185
1186 if (bv->second == aimTruth) // any true then return true
1187 return retJoin;
1188 }
1189
1190 const auto it =
1191 std::find_if(Comp.cbegin(), Comp.cend(), [&](const auto &acomp) { return acomp.isTrue(Base) == retJoin; });
1192 if (it != Comp.cend()) {
1193 return retJoin;
1194 }
1195
1196 // Finally not true then
1197 return 1 - retJoin;
1198}
1199
1200std::pair<Acomp, Acomp> Acomp::algDiv(const Acomp &G)
1206{
1207 // First make completely DNF (if necessary)
1208 if (!isDNF() && !makeDNFobject())
1209 return std::pair<Acomp, Acomp>(Acomp(), Acomp());
1210
1211 std::map<int, int> Gmap; // get map of literals and frequency
1212 G.getLiterals(Gmap);
1213 if (Gmap.empty()) {
1214 return std::pair<Acomp, Acomp>(Acomp(), Acomp());
1215 }
1216 // Make two lists.
1217 // U == set of elements in F (item to be divided) (this)
1218 // V == set of elements in G
1219 // U is ste to be
1220 std::vector<Acomp> U;
1221 std::vector<Acomp> V;
1222 // Only have First level components to consider
1223 std::vector<Acomp>::const_iterator cc;
1224
1225 std::vector<Acomp> Flist, Glist;
1226 if (!getDNFpart(Flist) || !G.getDNFpart(Glist))
1227 return std::pair<Acomp, Acomp>(Acomp(), Acomp());
1228
1229 for (cc = Flist.begin(); cc != Flist.end(); ++cc) {
1230 int itemCnt(0);
1231 U.emplace_back(Acomp(0)); // intersection Unit
1232 V.emplace_back(Acomp(0)); // intersection Unit
1233 Acomp &Uitem = U.back();
1234 Acomp &Vitem = V.back();
1235 int cell;
1236 while ((cell = cc->itemN(itemCnt))) {
1237 if (Gmap.find(cell) != Gmap.end())
1238 Uitem.addUnitItem(cell);
1239 else
1240 Vitem.addUnitItem(cell);
1241 itemCnt++;
1242 }
1243 }
1244 Acomp H(1); // H is an intersection group
1245 Acomp Hpart(0); // Hpart is a union group
1246 /*
1247 std::cerr<<"U == ";
1248 copy(U.begin(),U.end(),std::ostream_iterator<Acomp>(std::cerr,":"));
1249 std::cerr<<'\n';
1250 std::cerr<<"V == ";
1251 copy(V.begin(),V.end(),std::ostream_iterator<Acomp>(std::cerr,":"));
1252 std::cerr<<'\n';
1253 */
1254 for (cc = Glist.begin(); cc != Glist.end(); ++cc) {
1255 std::vector<Acomp>::const_iterator ux, vx;
1256 vx = V.begin();
1257 for (ux = U.begin(); ux != U.end() && vx != V.end(); ++vx, ++ux) {
1258 if (!vx->isNull() && ux->contains(*cc)) {
1259 Hpart.addComp(*vx);
1260 }
1261 }
1262 // H exists then combine (note: must do this if a composite divisor)
1263 if (!Hpart.isNull()) {
1264 H *= Hpart;
1265 H.joinDepth(); // Up shift suitable objects.
1266 Hpart.Comp.clear();
1267 Hpart.Units.clear(); // Just in case
1268 }
1269 }
1270 if (!H.isDNF())
1271 H.makeDNFobject();
1272 Acomp Rem(*this);
1273 Acomp Factor(H);
1274 Factor *= G;
1275 Rem -= Factor;
1276 return std::pair<Acomp, Acomp>(H, Rem);
1277}
1278
1279int Acomp::contains(const Acomp &A) const
1287{
1288 std::vector<int>::const_iterator vc, tc;
1289 tc = Units.begin();
1290 for (vc = A.Units.begin(); vc != A.Units.end(); ++vc) {
1291 while (tc != Units.end() && *tc < *vc)
1292 ++tc;
1293 if (tc == Units.end() || *tc != *vc)
1294 return 0;
1295 }
1296 return 1;
1297}
1298
1306{
1307
1308 // Deal with case that this is a singular object::
1309 std::pair<int, int> Stype = size();
1310 if (Stype.first + Stype.second == 0)
1311 throw std::runtime_error("Pair Count wrong");
1312 // SINGULAR
1313 int cnt(0); // number upgraded
1314 if (Stype.first == 0 && Stype.second == 1) // Comp to up-premote
1315 {
1316 const Acomp *Lower = itemC(0); // returns pointer
1317 Units.clear();
1318 Intersect = Lower->Intersect;
1319 if (!Lower->Units.empty()) {
1320 Units.resize(Lower->Units.size());
1321 copy(Lower->Units.begin(), Lower->Units.end(), Units.begin());
1322 }
1323 if (!Lower->Comp.empty()) {
1324 Comp.resize(Lower->Comp.size() + 1); // +1 has space for our initial object
1325 copy(Lower->Comp.begin(), Lower->Comp.end(), Comp.begin() + 1);
1326 }
1327 Comp.erase(Comp.begin(), Comp.begin() + 1);
1328 cnt++;
1329 }
1330 // Loop over each component. (if identical type upshift and remove)
1331 for (unsigned int ix = 0; ix < Comp.size(); ix++) {
1332 Acomp &AX = Comp[ix];
1333 Stype = AX.size();
1334 if (Stype.first + Stype.second == 0)
1335 throw std::runtime_error("Pair Count wrong");
1336
1337 // If Singular then can be up premoted.
1338 if (Stype.first + Stype.second == 1) // single unit component.
1339 {
1340 if (Stype.first == 1)
1341 Units.emplace_back(AX.itemN(0));
1342 else
1343 Comp.emplace_back(*AX.itemC(0));
1344 // delete memory and the component.
1345 Comp.erase(Comp.begin() + ix, Comp.begin() + ix + 1);
1346 ix--;
1347 cnt++;
1348 } else if (Intersect == AX.Intersect) // Same type thus use the bits.
1349 {
1350 Units.resize(Units.size() + AX.Units.size());
1351 copy(AX.Units.begin(), AX.Units.end(), Units.end() - AX.Units.size());
1352 Comp.resize(Comp.size() + AX.Comp.size());
1353 copy(AX.Comp.begin(), AX.Comp.end(), Comp.end() - AX.Comp.size());
1354
1355 Comp.erase(Comp.begin() + ix, Comp.begin() + ix + 1);
1356 ix--;
1357 cnt++;
1358 }
1359 }
1360 if (cnt) {
1361 Sort();
1362 removeEqComp();
1363 }
1364 std::vector<Acomp>::iterator xc;
1365 for (xc = Comp.begin(); xc != Comp.end(); ++xc)
1366 cnt += xc->joinDepth();
1367
1368 return cnt;
1369}
1370
1371void Acomp::setString(const std::string &Line)
1377{
1378 Acomp CM;
1379 // DELETE ALL
1380 deleteComp();
1381 Units.clear();
1382 Intersect = 1;
1383 //
1384 // Process #( ) sub units
1385 //
1386 std::string Ln = Line;
1387 std::string::size_type sPos = Ln.find('#');
1388
1389 // REMOVE ALL COMPLEMENTS
1390 while (sPos != std::string::npos && Ln[sPos + 1] == '(') {
1391 int bLevel(1);
1392 int ePos;
1393 for (ePos = static_cast<int>(sPos) + 2; bLevel > 0 && ePos < static_cast<int>(Ln.size()); ePos++) {
1394 if (Ln[ePos] == '(')
1395 bLevel++;
1396 else if (Ln[ePos] == ')')
1397 bLevel--;
1398 }
1399 if (bLevel)
1400 throw std::invalid_argument("Acomp::setString error in line Ln\"" + Ln + "\"");
1401 // std::string Part= Ln.substr(sPos,ePos-sPos);
1402 CM.setString(Ln.substr(sPos + 2, ePos - sPos - 3));
1403 CM.complement();
1404 Ln.replace(sPos, ePos - sPos, "(" + CM.display() + ")");
1405 sPos = Ln.find('#');
1406 }
1407
1408 //
1409 // First:: Union take presidence over Intersection
1410 // :: check brackets
1411 int blevel = 0; // bracket level
1412 for (char i : Ln) {
1413 if (i == '(')
1414 blevel++;
1415 if (i == ')') {
1416 if (!blevel) // error condition
1417 {
1418 deleteComp();
1419 throw std::runtime_error(Ln);
1420 }
1421 blevel--;
1422 }
1423 if (i == '+' && !blevel) // must be union
1424 Intersect = 0;
1425 }
1426 if (blevel != 0)
1427 throw std::runtime_error(Ln);
1428
1429 if (Intersect)
1431 else
1432 processUnion(Ln);
1433 sort(Units.begin(), Units.end());
1434}
1435
1436std::pair<int, int> Acomp::size() const
1441{
1442 return std::pair<int, int>(static_cast<int>(Units.size()), static_cast<int>(Comp.size()));
1443}
1444
1445int Acomp::itemN(const int Index) const
1451{
1452 if (Index >= 0 && Index < static_cast<int>(Units.size()))
1453 return Units[Index];
1454 return 0;
1455}
1456
1457const Acomp *Acomp::itemC(const int Index) const
1463{
1464 if (Index < 0 || Index >= static_cast<int>(Comp.size()))
1465 return nullptr;
1466 return &Comp[Index];
1467}
1468
1476{
1477 Intersect = 1 - Intersect;
1478 using std::placeholders::_1;
1479 transform(Units.begin(), Units.end(), Units.begin(), std::bind(std::multiplies<int>(), _1, -1));
1480 sort(Units.begin(), Units.end());
1481
1482 for_each(Comp.begin(), Comp.end(), std::mem_fn(&Acomp::complement));
1483 sort(Comp.begin(), Comp.end());
1484}
1485
1486void Acomp::writeFull(std::ostream &OXF, const int Indent) const
1492{
1493 for (int i = 0; i < Indent; i++)
1494 OXF << " ";
1495 OXF << ((Intersect == 1) ? "Inter" : "Union");
1496 OXF << " " << Units.size() << " " << Comp.size() << '\n';
1497 for (int i = 0; i < Indent; i++)
1498 OXF << " ";
1499 OXF << display() << '\n';
1500 std::vector<Acomp>::const_iterator vc;
1501 for (vc = Comp.begin(); vc != Comp.end(); ++vc) {
1502 vc->writeFull(OXF, Indent + 2);
1503 }
1504}
1505
1506std::string Acomp::display() const
1511{
1512 // std::string out;
1513 std::stringstream cx;
1514 std::vector<int>::const_iterator ic;
1515 int sign, val; // sign and value of unit
1516 for (ic = Units.begin(); ic != Units.end(); ++ic) {
1517 if (!Intersect && ic != Units.begin())
1518 cx << '+';
1519 split(*ic, sign, val);
1520 if (val < 27)
1521 cx << static_cast<char>(static_cast<int>('a') + (val - 1));
1522 else if (val < 53)
1523 cx << static_cast<char>(static_cast<int>('A') + (val - 27));
1524 else
1525 cx << "%" << val - 52;
1526 if (sign < 0)
1527 cx << '\'';
1528 }
1529 // Now do composites
1530 std::vector<Acomp>::const_iterator vc;
1531 for (vc = Comp.begin(); vc != Comp.end(); ++vc) {
1532 if (!Intersect && (vc != Comp.begin() || !Units.empty()))
1533 cx << '+';
1534 cx << '(' << vc->display() << ')';
1535 }
1536 return cx.str();
1537}
1538
1539std::string Acomp::displayDepth(const int dval) const
1545{
1546 // std::string out;
1547 std::stringstream cx;
1548 std::vector<int>::const_iterator ic;
1549 int sign, val; // sign and value of unit
1550 for (ic = Units.begin(); ic != Units.end(); ++ic) {
1551 if (!Intersect && ic != Units.begin())
1552 cx << '+';
1553 split(*ic, sign, val);
1554 if (val < 27)
1555 cx << static_cast<char>(static_cast<int>('a') + (val - 1));
1556 else if (val < 53)
1557 cx << static_cast<char>(static_cast<int>('A') + (val - 27));
1558 else
1559 cx << "%" << val - 52;
1560 if (sign < 0)
1561 cx << '\'';
1562 }
1563 // Now do composites
1564 std::vector<Acomp>::const_iterator vc;
1565 for (vc = Comp.begin(); vc != Comp.end(); ++vc) {
1566 if (!Intersect && (vc != Comp.begin() || !Units.empty()))
1567 cx << '+';
1568 // if ( join && (*vc)->type() )
1569 if (!vc->Intersect)
1570 cx << "D" << dval << " " << '(' << vc->displayDepth(dval + 1) << ')' << " " << dval << "E";
1571 else
1572 cx << "D" << dval << " " << vc->displayDepth(dval + 1) << " " << dval << "E";
1573 }
1574 return cx.str();
1575}
1576
1577void Acomp::printImplicates(const std::vector<BnId> &PIform, const Kernel::Matrix<int> &Grid) const
1585{
1586 const std::pair<size_t, size_t> RX = Grid.size();
1587 for (size_t pc = 0; pc != PIform.size(); pc++) {
1588 logger.debug() << PIform[pc] << ":";
1589 for (size_t ic = 0; ic != RX.second; ic++)
1590 logger.debug() << ((Grid[pc][ic]) ? " 1" : " 0");
1591 logger.debug() << '\n';
1592 }
1593}
1594
1595} // NAMESPACE Geometry
1596
1597} // NAMESPACE Mantid
const Kernel::DblMatrix & cm
double obj
the value of the quadratic function
Holds a state point in the decision tree.
Definition Acomp.h:43
std::string displayDepth(int const =0) const
Really pretty print statment of tree.
Definition Acomp.cpp:1539
void writeFull(std::ostream &, int const =0) const
Full write out to determine state.
Definition Acomp.cpp:1486
void assignDNF(const std::vector< int > &, const std::vector< BnId > &)
Assigns the Comp with the DNF.
Definition Acomp.cpp:526
int logicalEqual(const Acomp &) const
Test that the system that is logically the same:
Definition Acomp.cpp:625
void Sort()
Sort the Units+Comp items.
Definition Acomp.cpp:591
int removeEqComp()
Remove non-unique items.
Definition Acomp.cpp:774
std::vector< int > Units
Units in list.
Definition Acomp.h:47
int getDNFobject(std::vector< int > &, std::vector< BnId > &) const
Creates the DNF items (ie the binary list of true statements) It forms a sum of products.
Definition Acomp.cpp:1006
int makeReadOnce()
Factorize into a read once function.
Definition Acomp.cpp:604
int isSingle() const
only one part
Definition Acomp.cpp:764
void processIntersection(const std::string &)
Helper function :: assumes that Ln has been checked for bracket consistency.
Definition Acomp.cpp:359
std::pair< int, int > size() const
get the size of the units and the Acomp sub-comp
Definition Acomp.cpp:1436
int isDNF() const
is Units only in union
Definition Acomp.cpp:663
int isCNF() const
is Units only in intersections
Definition Acomp.cpp:684
void deleteComp()
delete all of the Comp list
Definition Acomp.cpp:300
void addComp(const Acomp &)
add a Component intelligently
Definition Acomp.cpp:308
int itemN(int const) const
returns an integer to Units (or zero)
Definition Acomp.cpp:1445
void assignCNF(const std::vector< int > &, const std::vector< BnId > &)
Assigns the Comp with the DNF.
Definition Acomp.cpp:555
Acomp & operator+=(const Acomp &)
Operator + (union addition)
Definition Acomp.cpp:168
std::vector< int > getKeys() const
Get the key numbers in the system.
Definition Acomp.cpp:990
int copySimilar(const Acomp &)
Join two componenet of similar type.
Definition Acomp.cpp:479
int makeDNFobject()
Make the object into DNF form (Sum of Products)
Definition Acomp.cpp:1046
const Acomp * itemC(int const) const
returns a pointer to Comp (or zero)
Definition Acomp.cpp:1457
Acomp & operator*=(const Acomp &)
This carries out the intersection operation with A.
Definition Acomp.cpp:271
int makeEPI(std::vector< BnId > &, std::vector< BnId > &) const
Creates an essentual PI list (note: this is not unique).
Definition Acomp.cpp:862
void addUnitItem(int const)
add an Unit intellgently
Definition Acomp.cpp:346
int isSimple() const
true if only Units
Definition Acomp.cpp:754
int contains(const Acomp &) const
Checks the Units of A to see if they are in this->Units.
Definition Acomp.cpp:1279
bool operator==(const Acomp &) const
Equals operator requires that the Units are equal and the Comp units are equal.
Definition Acomp.cpp:82
void getLiterals(std::map< int, int > &) const
Get literals (+/- different)
Definition Acomp.cpp:730
int joinDepth()
Search table to uplift objects.
Definition Acomp.cpp:1299
int getCNFobject(std::vector< int > &, std::vector< BnId > &) const
Creates the CNF items (ie the binary list of false statements) It forms a sum of products.
Definition Acomp.cpp:1117
Acomp(int const =0)
Standard Constructor.
Definition Acomp.cpp:64
void processUnion(const std::string &)
Helper function :: assumes that Ln has been checked for bracket consistency Units are sorted after th...
Definition Acomp.cpp:421
bool operator!=(const Acomp &) const
Complementary operator.
Definition Acomp.cpp:72
void getAbsLiterals(std::map< int, int > &) const
Get literals (positve)
Definition Acomp.cpp:705
bool operator<(const Acomp &) const
Comparitor operator:: Comparies the unit list (which is already sorted) part by part.
Definition Acomp.cpp:118
Acomp & operator-=(const Acomp &)
Operator - (removal) This operation can be carried out in many ways.
Definition Acomp.cpp:194
std::string display() const
Pretty print statment.
Definition Acomp.cpp:1506
std::pair< Acomp, Acomp > algDiv(const Acomp &)
Carry out Algebric division.
Definition Acomp.cpp:1200
int makePI(std::vector< BnId > &) const
Calculate Principal Components.
Definition Acomp.cpp:797
void complement()
Take complement of component.
Definition Acomp.cpp:1469
int getDNFpart(std::vector< Acomp > &) const
get the DNF parts (as Acomp)
Definition Acomp.cpp:1080
int isNull() const
is nothing in the comp.
Definition Acomp.cpp:655
int makeCNFobject()
Make the object into CNF form (Product of Sums)
Definition Acomp.cpp:1063
int isTrue(const std::map< int, int > &) const
Determine if the rule is true.
Definition Acomp.cpp:1158
void printImplicates(const std::vector< BnId > &, const Kernel::Matrix< int > &) const
Debug function to print out PI and Grid :
Definition Acomp.cpp:1577
int Intersect
Union/Intersection (0,1)
Definition Acomp.h:46
void addUnit(const std::vector< int > &, const BnId &)
Adds a Binary state to the Component.
Definition Acomp.cpp:505
std::vector< Acomp > Comp
Components in list.
Definition Acomp.h:48
void setString(const std::string &)
Processes a line of type abc'+efg.
Definition Acomp.cpp:1371
bool operator>(const Acomp &) const
Operator> takes first to last precidence.
Definition Acomp.cpp:259
Tri-state variable.
Definition BnId.h:37
void setPI(const int A)
PI accessor.
Definition BnId.h:64
size_t Size() const
returns number of variables / size
Definition BnId.h:71
void mapState(const std::vector< int > &, std::map< int, int > &) const
Sets the components within base with true/false.
Definition BnId.cpp:247
void reverse()
Swap -1 to 1 adn leaver the zeros.
Definition BnId.cpp:312
Impliments a line.
Definition Line.h:43
Simple multilevel-cyclic counter.
Definition RotCounter.h:28
Numerical Matrix class.
Definition Matrix.h:42
void split(const int A, int &S, int &V)
Split a number into the sign and positive value.
Definition Acomp.cpp:42
MANTID_GEOMETRY_DLL bool operator==(const Group_const_sptr &lhs, const Group_const_sptr &rhs)
Equality operator for shared pointers.
Definition Group.cpp:266
MANTID_GEOMETRY_DLL std::ostream & operator<<(std::ostream &stream, const PointGroup &self)
Returns a streamed representation of the PointGroup object.
int convPartNum(const std::string &A, T &out)
Takes a character string and evaluates the first [typename T] object.
Definition Strings.cpp:670
Helper class which provides the Collimation Length for SANS instruments.