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 uc != Units.end();
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 auto Ept = Units.end();
494 Units.resize(Units.size() + A.Units.size());
495 copy(A.Units.begin(), A.Units.end(), Ept);
496 std::sort(Units.begin(), Units.end());
497 }
498
499 // Add components
500 std::vector<Acomp>::const_iterator vc;
501 for (vc = A.Comp.begin(); vc != A.Comp.end(); ++vc)
502 addComp(*vc);
503 return 0;
504}
505
506void Acomp::addUnit(const std::vector<int> &Index, const BnId &BX)
513{
514 int S, V;
515 for (int i = 0; i < static_cast<int>(BX.Size()); i++) {
516 int flag = BX[i];
517 if (flag) {
518 split(flag, S, V);
519 if (V >= static_cast<int>(Index.size()))
520 throw std::runtime_error("Error with addUnit::Index");
521 Units.emplace_back(S * Index[i]);
522 }
523 }
524 std::sort(Units.begin(), Units.end());
525}
526
527void Acomp::assignDNF(const std::vector<int> &Index, const std::vector<BnId> &A)
534{
535 Units.clear();
536 deleteComp();
537 if (A.empty())
538 return;
539
540 if (A.size() == 1) // special case for single intersection
541 {
542 Intersect = 1;
543 addUnit(Index, A[0]);
544 return;
545 }
546
547 Intersect = 0; // union of intersection
548 std::vector<BnId>::const_iterator vc;
549 for (vc = A.begin(); vc != A.end(); ++vc) {
550 Acomp Px(1); // Intersection
551 Px.addUnit(Index, *vc);
552 addComp(Px);
553 }
554}
555
556void Acomp::assignCNF(const std::vector<int> &Index, const std::vector<BnId> &A)
563{
564 Units.clear();
565 deleteComp();
566 if (A.empty())
567 return;
568
569 if (A.size() == 1) // special case for single union
570 {
571 Intersect = 0;
572 addUnit(Index, A[0]);
573 return;
574 }
575
576 Intersect = 1; // intersection of union
577 std::vector<BnId>::const_iterator vc;
578 for (vc = A.begin(); vc != A.end(); ++vc) {
579 Acomp Px(0); // Union
580 // std::cout<<"Item == "<<*vc<<'\n';
581 BnId X = *vc;
582 X.reverse();
583 Px.addUnit(Index, X);
584 addComp(Px);
585 }
586}
587
588// -------------------------------------
589// PUBLIC FUNCTIONS
590// -------------------------------------
591
597{
598 std::sort(Units.begin(), Units.end());
599 // Sort each decending object first
600 std::for_each(Comp.begin(), Comp.end(), std::mem_fn(&Acomp::Sort));
601 // use the sorted components to sort our component list
602 std::sort(Comp.begin(), Comp.end());
603}
604
613{
614 std::map<int, int> LitSet;
615 getLiterals(LitSet);
616 /* // Process DNF
617 if (isDNF())
618 return makeReadOnceForDNF();
619 if (isCNF())
620 return makeReadOnceForCNF();
621 return 0;
622 */
623 return 0;
624}
625
626int Acomp::logicalEqual(const Acomp &A) const
633{
634 std::map<int, int> litMap; // keynumber :: number of occurances
635 getAbsLiterals(litMap);
636
637 A.getAbsLiterals(litMap);
638 std::map<int, int> Base; // keynumber :: number of occurances
639 std::vector<int> keyNumbers;
640
641 std::map<int, int>::const_iterator mc;
642 for (mc = litMap.begin(); mc != litMap.end(); ++mc) {
643 Base[mc->first] = 1; // Insert and Set to true
644 keyNumbers.emplace_back(mc->first);
645 }
646
647 BnId State(Base.size(), 0); // zero base
648 do {
649 State.mapState(keyNumbers, Base);
650 if (isTrue(Base) != A.isTrue(Base))
651 return 0;
652 } while (++State);
653 return 1;
654}
655
656int Acomp::isNull() const
660{
661 return ((Units.empty() && Comp.empty()) ? 1 : 0);
662}
663
664int Acomp::isDNF() const
672{
673 // If an intersect (single component)
674 if (Intersect)
675 return (Comp.empty()) ? 1 : 0;
676 // Else needs to be union of Intersections.
677 std::vector<Acomp>::const_iterator cc;
678 for (cc = Comp.begin(); cc != Comp.end(); ++cc)
679 if (cc->Intersect == 0 || !cc->isSimple())
680 return 0;
681
682 return 1;
683}
684
685int Acomp::isCNF() const
693{
694 // If an intersect (single component)
695 if (!Intersect)
696 return (Comp.empty()) ? 1 : 0;
697 // Else needs to be intersection of unions
698 std::vector<Acomp>::const_iterator cc;
699 for (cc = Comp.begin(); cc != Comp.end(); ++cc)
700 if (cc->Intersect == 1 || !cc->isSimple())
701 return 0;
702
703 return 1;
704}
705
706void Acomp::getAbsLiterals(std::map<int, int> &literalMap) const
714{
715 std::vector<int>::const_iterator uc;
716 std::map<int, int>::iterator mc;
717 int S, V;
718 for (uc = Units.begin(); uc != Units.end(); ++uc) {
719 split(*uc, S, V);
720 mc = literalMap.find(V);
721 if (mc != literalMap.end())
722 mc->second++;
723 else
724 literalMap.emplace(V, 1);
725 }
726 std::vector<Acomp>::const_iterator cc;
727 for (cc = Comp.begin(); cc != Comp.end(); ++cc)
728 cc->getAbsLiterals(literalMap);
729}
730
731void Acomp::getLiterals(std::map<int, int> &literalMap) const
739{
740 std::vector<int>::const_iterator uc;
741 std::map<int, int>::iterator mc;
742 for (uc = Units.begin(); uc != Units.end(); ++uc) {
743 mc = literalMap.find(*uc);
744 if (mc != literalMap.end())
745 mc->second++;
746 else
747 literalMap.emplace(*uc, 1);
748 }
749 std::vector<Acomp>::const_iterator cc;
750 for (cc = Comp.begin(); cc != Comp.end(); ++cc) {
751 cc->getLiterals(literalMap);
752 }
753}
754
761{
762 return (Comp.empty() ? 1 : 0);
763}
764
771{
772 return (Comp.size() + Units.size() > 1 ? 0 : 1);
773}
774
780{
781 // First check all the Comp units:
782 int cnt(0);
783 std::vector<Acomp>::iterator dx;
784 sort(Comp.begin(), Comp.end());
785 dx = std::unique(Comp.begin(), Comp.end());
786 cnt += static_cast<int>(std::distance(dx, Comp.end()));
787 Comp.erase(dx, Comp.end());
788
789 // Units are sorted
790
791 sort(Units.begin(), Units.end());
792 auto ux = unique(Units.begin(), Units.end());
793 cnt += static_cast<int>(std::distance(ux, Units.end()));
794 Units.erase(ux, Units.end());
795 return cnt;
796}
797
798int Acomp::makePI(std::vector<BnId> &DNFobj) const
808{
809 if (DNFobj.empty()) // no work to do return.
810 return 0;
811 // Note: need to store PI components separately
812 // since we don't want to loop continuously through them
813 std::vector<BnId> Work; // Working copy
814 std::vector<BnId> PIComp; // Store for PI componends
815 std::vector<BnId> Tmod; // store modified components
816 int changeCount(0); // Number change
817 std::vector<BnId>::iterator uend; // itor to remove unique
818 // Need to make an initial copy.
819 Work = DNFobj;
820
821 int cnt(0);
822 do {
823 cnt++;
824 // Deal with tri-state objects ??
825 sort(Work.begin(), Work.end());
826 uend = unique(Work.begin(), Work.end());
827 Work.erase(uend, Work.end());
828 Tmod.clear(); // erase all at the start
829 // set PI status to 1
830 using std::placeholders::_1;
831 for_each(Work.begin(), Work.end(), std::bind(std::mem_fn(&BnId::setPI), _1, 1));
832
833 // Collect into pairs which have a difference of +/- one
834 // object
835 // Can sort this realive to
836 std::vector<BnId>::iterator vc;
837 for (vc = Work.begin(); vc != Work.end(); ++vc) {
838 const int GrpIndex(vc->TrueCount() + 1);
839 for (auto oc = vc + 1; oc != Work.end(); ++oc) {
840 const int OCnt = oc->TrueCount();
841 if (OCnt > GrpIndex)
842 break;
843 if (OCnt == GrpIndex) {
844 std::pair<int, BnId> cVal = vc->makeCombination(*oc);
845 if (cVal.first == 1) // was complementary
846 {
847 Tmod.emplace_back(cVal.second);
848 oc->setPI(0);
849 vc->setPI(0);
850 changeCount++; // 1 changed
851 }
852 }
853 }
854 }
855
856 for (vc = Work.begin(); vc != Work.end(); ++vc)
857 if (vc->PIstatus() == 1)
858 PIComp.emplace_back(*vc);
859 Work = Tmod;
860
861 } while (!Tmod.empty());
862 // Copy over the unit.
863
864 return makeEPI(DNFobj, PIComp);
865}
866
867int Acomp::makeEPI(std::vector<BnId> &DNFobj, std::vector<BnId> &PIform) const
878{
879 if (PIform.empty())
880 return 0;
881
882 std::vector<BnId> EPI; // Created Here.
883
884 // Make zeroed matrix.
885 Kernel::Matrix<int> Grid(PIform.size(), DNFobj.size());
886 std::vector<int> DNFactive(DNFobj.size()); // DNF that active
887 std::vector<int> PIactive(PIform.size()); // PI that are active
888 std::vector<int> DNFscore(DNFobj.size()); // Number in each channel
889 std::vector<int> PIscore(DNFobj.size()); // Number in each channel
890
891 // Populate
892 for (int pc = 0; pc != static_cast<int>(PIform.size()); pc++) {
893 PIactive[pc] = pc;
894 }
895 for (int ic = 0; ic != static_cast<int>(DNFobj.size()); ic++) {
896 DNFactive[ic] = ic; // populate (avoid a loop)
897 for (int pc = 0; pc != static_cast<int>(PIform.size()); pc++) {
898 if (PIform[pc].equivalent(DNFobj[ic])) {
899 Grid[pc][ic] = 1;
900 DNFscore[ic]++;
901 }
902 }
903 if (DNFscore[ic] == 0) {
904 logger.error() << "PIForm:\n";
905 copy(PIform.begin(), PIform.end(), std::ostream_iterator<BnId>(logger.error(), "\n"));
906 logger.error() << "Error with DNF / EPI determination at " << ic << '\n';
907 logger.error() << " Items " << DNFobj[ic] << '\n';
908 return 0;
909 }
910 }
911
912 std::vector<int>::iterator dx, ddx; // DNF active iterator
913 std::vector<int>::iterator px; // PIactive iterator
914
915 //
916 // First remove singlets:
917 //
918 for (dx = DNFactive.begin(); dx != DNFactive.end(); ++dx) {
919 if (*dx >= 0 && DNFscore[*dx] == 1) // EPI (definately)
920 {
921 for (px = PIactive.begin(); px != PIactive.end(); ++px) {
922 if (Grid[*px][*dx])
923 break;
924 }
925
926 if (PIactive.end() == px)
927 continue;
928
929 EPI.emplace_back(PIform[*px]);
930 // remove all minterm that the EPI covered
931 for (ddx = DNFactive.begin(); ddx != DNFactive.end(); ++ddx)
932 if (*ddx >= 0 && Grid[*px][*ddx])
933 *ddx = -1; // mark for deletion (later)
934 // Can remove PIactive now.
935 PIactive.erase(px, px + 1);
936 }
937 }
938 // Remove dead items from active list
939 using std::placeholders::_1;
940 DNFactive.erase(remove_if(DNFactive.begin(), DNFactive.end(), std::bind(std::less<int>(), _1, 0)), DNFactive.end());
941
942 // Ok -- now the hard work...
943 // need to find shortest "combination" that spans
944 // the remaining table.
945
946 // First Make a new matrix for speed. Useful ???
947 Kernel::Matrix<int> Cmat(PIactive.size(),
948 DNFactive.size()); // corrolation matrix
949 int cm(0);
950 for (px = PIactive.begin(); px != PIactive.end(); ++px) {
951 int dm(0);
952 for (ddx = DNFactive.begin(); ddx != DNFactive.end(); ++ddx) {
953 if (Grid[*px][*ddx])
954 Cmat[cm][dm] = 1;
955 dm++;
956 }
957 cm++;
958 }
959
960 const auto Dsize(static_cast<int>(DNFactive.size()));
961 const auto Psize(static_cast<int>(PIactive.size()));
962 // icount == depth of search ie
963 int vecI, di; // variable for later
964 for (int Icount = 1; Icount < Psize; Icount++) {
965 // This counter is a ripple counter, ie 1,2,3 where no numbers
966 // are the same. BUT it is acutally 0->N 0->N 0->N
967 // index by A, A+1 ,A+2 etc
968 RotaryCounter Index(Icount, Psize);
969 do {
970
971 for (di = 0; di < Dsize; di++) // check each orignal position
972 {
973 for (vecI = 0; vecI < Icount; vecI++) {
974 if (Cmat[Index[vecI]][di])
975 break;
976 }
977 if (vecI == Icount)
978 break;
979 }
980 if (di == Dsize) // SUCCESS!!!!!
981 {
982 for (int iout = 0; iout < Icount; iout++) {
983 EPI.emplace_back(PIform[Index[iout]]);
984 }
985 DNFobj = EPI;
986 return 1;
987 }
988 } while (!(++Index));
989 }
990
991 // OH well that means every PIactive is a EPI :-(
992 for (px = PIactive.begin(); px != PIactive.end(); ++px)
993 EPI.emplace_back(PIform[*px]);
994 DNFobj = EPI;
995 return 1;
996}
997
998std::vector<int> Acomp::getKeys() const
1003{
1004 std::map<int, int> litMap; // keynumber :: number of occurances
1005 std::vector<int> keyNumbers;
1006 getAbsLiterals(litMap);
1007 std::map<int, int>::const_iterator mc;
1008 for (mc = litMap.begin(); mc != litMap.end(); ++mc)
1009 keyNumbers.emplace_back(mc->first);
1010
1011 return keyNumbers;
1012}
1013
1014int Acomp::getDNFobject(std::vector<int> &keyNumbers, std::vector<BnId> &DNFobj) const
1026{
1027 std::map<int, int> litMap; // keynumber :: number of occurances
1028 std::map<int, int> Base; // keynumber :: value
1029 getAbsLiterals(litMap);
1030
1031 if (litMap.empty())
1032 return -1;
1033
1034 keyNumbers.clear();
1035 std::map<int, int>::iterator mc;
1036
1037 for (mc = litMap.begin(); mc != litMap.end(); ++mc) {
1038 Base[mc->first] = 1; // Set to true
1039 keyNumbers.emplace_back(mc->first);
1040 }
1041
1042 DNFobj.clear();
1043 BnId State(Base.size(), 0); // zero base
1044 do {
1045 State.mapState(keyNumbers, Base);
1046 if (isTrue(Base)) {
1047 DNFobj.emplace_back(State);
1048 }
1049 } while (++State);
1050
1051 return 0;
1052}
1053
1060{
1061 std::vector<BnId> DNFobj;
1062 std::vector<int> keyNumbers;
1063 if (!getDNFobject(keyNumbers, DNFobj)) {
1064 if (makePI(DNFobj))
1065 assignDNF(keyNumbers, DNFobj);
1066 return static_cast<int>(DNFobj.size());
1067 }
1068 return 0;
1069}
1070
1077{
1078 std::vector<BnId> CNFobj;
1079 std::vector<int> keyNumbers;
1080 if (!getCNFobject(keyNumbers, CNFobj)) {
1081 if (makePI(CNFobj))
1082 assignCNF(keyNumbers, CNFobj);
1083 return static_cast<int>(CNFobj.size());
1084 }
1085 return 0;
1086}
1087
1088int Acomp::getDNFpart(std::vector<Acomp> &Parts) const
1096{
1097 // If this is DNF then we don't want to calculate the DNF but just use it
1098 if (isDNF()) {
1099 Parts.clear();
1100 Parts.reserve(Units.size() + Comp.size());
1101 for (const auto &item : Units) {
1102 Acomp Aitem(1); // Intersection (doesn't matter since 1 object)
1103 Aitem.addUnitItem(item);
1104 Parts.emplace_back(Aitem);
1105 }
1106 std::copy(Comp.cbegin(), Comp.cend(), std::back_inserter(Parts));
1107 return static_cast<int>(Parts.size());
1108 }
1109
1110 std::vector<int> keyNumbers;
1111 std::vector<BnId> DNFobj;
1112 if (!getDNFobject(keyNumbers, DNFobj)) {
1113 if (makePI(DNFobj)) {
1114 for (auto &obj : DNFobj) {
1115 Acomp Aitem(1); // make an intersection and add components
1116 Aitem.addUnit(keyNumbers, obj);
1117 Parts.emplace_back(Aitem);
1118 }
1119 }
1120 return static_cast<int>(Parts.size());
1121 }
1122 return 0;
1123}
1124
1125int Acomp::getCNFobject(std::vector<int> &keyNumbers, std::vector<BnId> &CNFobj) const
1137{
1138 std::map<int, int> litMap; // keynumber :: number of occurances
1139 std::map<int, int> Base; // keynumber :: value
1140 getAbsLiterals(litMap);
1141
1142 if (litMap.empty())
1143 return -1;
1144
1145 keyNumbers.clear();
1146 std::map<int, int>::iterator mc;
1147 int cnt(0);
1148
1149 for (mc = litMap.begin(); mc != litMap.end(); ++mc) {
1150 mc->second = cnt++;
1151 Base[mc->first] = 1; // Set to true
1152 keyNumbers.emplace_back(mc->first);
1153 }
1154
1155 CNFobj.clear();
1156 BnId State(Base.size(), 0); // zero base
1157 do {
1158 State.mapState(keyNumbers, Base);
1159 if (!isTrue(Base))
1160 CNFobj.emplace_back(State);
1161 } while (++State);
1162
1163 return 0;
1164}
1165
1166int Acomp::isTrue(const std::map<int, int> &Base) const
1173{
1174 if (Units.empty() && Comp.empty())
1175 return 1;
1176
1177 // Deal with case of a single object (then join
1178 // doesn't matter
1179 auto retJoin = static_cast<int>(Units.size() + Comp.size());
1180 if (retJoin != 1) // single unit is alway ok
1181 retJoin = 1 - Intersect;
1182
1183 int S, V;
1184 std::map<int, int>::const_iterator bv;
1185 std::vector<int>::const_iterator uc;
1186 // e.g. a'b 1 1 (retJoin ==1)
1187 for (uc = Units.begin(); uc != Units.end(); ++uc) {
1188 split(*uc, S, V);
1189 bv = Base.find(V);
1190 if (bv == Base.end())
1191 throw std::runtime_error("Base unit not found");
1192 int aimTruth = (S < 0) ? 1 - retJoin : retJoin;
1193
1194 if (bv->second == aimTruth) // any true then return true
1195 return retJoin;
1196 }
1197
1198 std::vector<Acomp>::const_iterator cc;
1199 for (cc = Comp.begin(); cc != Comp.end(); ++cc)
1200 if (cc->isTrue(Base) == retJoin)
1201 return retJoin;
1202
1203 // Finally not true then
1204 return 1 - retJoin;
1205}
1206
1207std::pair<Acomp, Acomp> Acomp::algDiv(const Acomp &G)
1213{
1214 // First make completely DNF (if necessary)
1215 if (!isDNF() && !makeDNFobject())
1216 return std::pair<Acomp, Acomp>(Acomp(), Acomp());
1217
1218 std::map<int, int> Gmap; // get map of literals and frequency
1219 G.getLiterals(Gmap);
1220 if (Gmap.empty()) {
1221 return std::pair<Acomp, Acomp>(Acomp(), Acomp());
1222 }
1223 // Make two lists.
1224 // U == set of elements in F (item to be divided) (this)
1225 // V == set of elements in G
1226 // U is ste to be
1227 std::vector<Acomp> U;
1228 std::vector<Acomp> V;
1229 // Only have First level components to consider
1230 std::vector<Acomp>::const_iterator cc;
1231
1232 std::vector<Acomp> Flist, Glist;
1233 if (!getDNFpart(Flist) || !G.getDNFpart(Glist))
1234 return std::pair<Acomp, Acomp>(Acomp(), Acomp());
1235
1236 for (cc = Flist.begin(); cc != Flist.end(); ++cc) {
1237 int itemCnt(0);
1238 U.emplace_back(Acomp(0)); // intersection Unit
1239 V.emplace_back(Acomp(0)); // intersection Unit
1240 Acomp &Uitem = U.back();
1241 Acomp &Vitem = V.back();
1242 int cell;
1243 while ((cell = cc->itemN(itemCnt))) {
1244 if (Gmap.find(cell) != Gmap.end())
1245 Uitem.addUnitItem(cell);
1246 else
1247 Vitem.addUnitItem(cell);
1248 itemCnt++;
1249 }
1250 }
1251 Acomp H(1); // H is an intersection group
1252 Acomp Hpart(0); // Hpart is a union group
1253 /*
1254 std::cerr<<"U == ";
1255 copy(U.begin(),U.end(),std::ostream_iterator<Acomp>(std::cerr,":"));
1256 std::cerr<<'\n';
1257 std::cerr<<"V == ";
1258 copy(V.begin(),V.end(),std::ostream_iterator<Acomp>(std::cerr,":"));
1259 std::cerr<<'\n';
1260 */
1261 for (cc = Glist.begin(); cc != Glist.end(); ++cc) {
1262 std::vector<Acomp>::const_iterator ux, vx;
1263 vx = V.begin();
1264 for (ux = U.begin(); ux != U.end() && vx != V.end(); ++vx, ++ux) {
1265 if (!vx->isNull() && ux->contains(*cc)) {
1266 Hpart.addComp(*vx);
1267 }
1268 }
1269 // H exists then combine (note: must do this if a composite divisor)
1270 if (!Hpart.isNull()) {
1271 H *= Hpart;
1272 H.joinDepth(); // Up shift suitable objects.
1273 Hpart.Comp.clear();
1274 Hpart.Units.clear(); // Just in case
1275 }
1276 }
1277 if (!H.isDNF())
1278 H.makeDNFobject();
1279 Acomp Rem(*this);
1280 Acomp Factor(H);
1281 Factor *= G;
1282 Rem -= Factor;
1283 return std::pair<Acomp, Acomp>(H, Rem);
1284}
1285
1286int Acomp::contains(const Acomp &A) const
1294{
1295 std::vector<int>::const_iterator vc, tc;
1296 tc = Units.begin();
1297 for (vc = A.Units.begin(); vc != A.Units.end(); ++vc) {
1298 while (tc != Units.end() && *tc < *vc)
1299 ++tc;
1300 if (tc == Units.end() || *tc != *vc)
1301 return 0;
1302 }
1303 return 1;
1304}
1305
1313{
1314
1315 // Deal with case that this is a singular object::
1316 std::pair<int, int> Stype = size();
1317 if (Stype.first + Stype.second == 0)
1318 throw std::runtime_error("Pair Count wrong");
1319 // SINGULAR
1320 int cnt(0); // number upgraded
1321 if (Stype.first == 0 && Stype.second == 1) // Comp to up-premote
1322 {
1323 const Acomp *Lower = itemC(0); // returns pointer
1324 Units.clear();
1325 Intersect = Lower->Intersect;
1326 if (!Lower->Units.empty()) {
1327 Units.resize(Lower->Units.size());
1328 copy(Lower->Units.begin(), Lower->Units.end(), Units.begin());
1329 }
1330 if (!Lower->Comp.empty()) {
1331 Comp.resize(Lower->Comp.size() + 1); // +1 has space for our initial object
1332 copy(Lower->Comp.begin(), Lower->Comp.end(), Comp.begin() + 1);
1333 }
1334 Comp.erase(Comp.begin(), Comp.begin() + 1);
1335 cnt++;
1336 }
1337 // Loop over each component. (if identical type upshift and remove)
1338 for (unsigned int ix = 0; ix < Comp.size(); ix++) {
1339 Acomp &AX = Comp[ix];
1340 Stype = AX.size();
1341 if (Stype.first + Stype.second == 0)
1342 throw std::runtime_error("Pair Count wrong");
1343
1344 // If Singular then can be up premoted.
1345 if (Stype.first + Stype.second == 1) // single unit component.
1346 {
1347 if (Stype.first == 1)
1348 Units.emplace_back(AX.itemN(0));
1349 else
1350 Comp.emplace_back(*AX.itemC(0));
1351 // delete memory and the component.
1352 Comp.erase(Comp.begin() + ix, Comp.begin() + ix + 1);
1353 ix--;
1354 cnt++;
1355 } else if (Intersect == AX.Intersect) // Same type thus use the bits.
1356 {
1357 Units.resize(Units.size() + AX.Units.size());
1358 copy(AX.Units.begin(), AX.Units.end(), Units.end() - AX.Units.size());
1359 Comp.resize(Comp.size() + AX.Comp.size());
1360 copy(AX.Comp.begin(), AX.Comp.end(), Comp.end() - AX.Comp.size());
1361
1362 Comp.erase(Comp.begin() + ix, Comp.begin() + ix + 1);
1363 ix--;
1364 cnt++;
1365 }
1366 }
1367 if (cnt) {
1368 Sort();
1369 removeEqComp();
1370 }
1371 std::vector<Acomp>::iterator xc;
1372 for (xc = Comp.begin(); xc != Comp.end(); ++xc)
1373 cnt += xc->joinDepth();
1374
1375 return cnt;
1376}
1377
1378void Acomp::setString(const std::string &Line)
1384{
1385 Acomp CM;
1386 // DELETE ALL
1387 deleteComp();
1388 Units.clear();
1389 Intersect = 1;
1390 //
1391 // Process #( ) sub units
1392 //
1393 std::string Ln = Line;
1394 std::string::size_type sPos = Ln.find('#');
1395
1396 // REMOVE ALL COMPLEMENTS
1397 while (sPos != std::string::npos && Ln[sPos + 1] == '(') {
1398 int bLevel(1);
1399 int ePos;
1400 for (ePos = static_cast<int>(sPos) + 2; bLevel > 0 && ePos < static_cast<int>(Ln.size()); ePos++) {
1401 if (Ln[ePos] == '(')
1402 bLevel++;
1403 else if (Ln[ePos] == ')')
1404 bLevel--;
1405 }
1406 if (bLevel)
1407 throw std::invalid_argument("Acomp::setString error in line Ln\"" + Ln + "\"");
1408 // std::string Part= Ln.substr(sPos,ePos-sPos);
1409 CM.setString(Ln.substr(sPos + 2, ePos - sPos - 3));
1410 CM.complement();
1411 Ln.replace(sPos, ePos - sPos, "(" + CM.display() + ")");
1412 sPos = Ln.find('#');
1413 }
1414
1415 //
1416 // First:: Union take presidence over Intersection
1417 // :: check brackets
1418 int blevel = 0; // bracket level
1419 for (char i : Ln) {
1420 if (i == '(')
1421 blevel++;
1422 if (i == ')') {
1423 if (!blevel) // error condition
1424 {
1425 deleteComp();
1426 throw std::runtime_error(Ln);
1427 }
1428 blevel--;
1429 }
1430 if (i == '+' && !blevel) // must be union
1431 Intersect = 0;
1432 }
1433 if (blevel != 0)
1434 throw std::runtime_error(Ln);
1435
1436 if (Intersect)
1438 else
1439 processUnion(Ln);
1440 sort(Units.begin(), Units.end());
1441}
1442
1443std::pair<int, int> Acomp::size() const
1448{
1449 return std::pair<int, int>(static_cast<int>(Units.size()), static_cast<int>(Comp.size()));
1450}
1451
1452int Acomp::itemN(const int Index) const
1458{
1459 if (Index >= 0 && Index < static_cast<int>(Units.size()))
1460 return Units[Index];
1461 return 0;
1462}
1463
1464const Acomp *Acomp::itemC(const int Index) const
1470{
1471 if (Index < 0 || Index >= static_cast<int>(Comp.size()))
1472 return nullptr;
1473 return &Comp[Index];
1474}
1475
1483{
1484 Intersect = 1 - Intersect;
1485 using std::placeholders::_1;
1486 transform(Units.begin(), Units.end(), Units.begin(), std::bind(std::multiplies<int>(), _1, -1));
1487 sort(Units.begin(), Units.end());
1488
1489 for_each(Comp.begin(), Comp.end(), std::mem_fn(&Acomp::complement));
1490 sort(Comp.begin(), Comp.end());
1491}
1492
1493void Acomp::writeFull(std::ostream &OXF, const int Indent) const
1499{
1500 for (int i = 0; i < Indent; i++)
1501 OXF << " ";
1502 OXF << ((Intersect == 1) ? "Inter" : "Union");
1503 OXF << " " << Units.size() << " " << Comp.size() << '\n';
1504 for (int i = 0; i < Indent; i++)
1505 OXF << " ";
1506 OXF << display() << '\n';
1507 std::vector<Acomp>::const_iterator vc;
1508 for (vc = Comp.begin(); vc != Comp.end(); ++vc) {
1509 vc->writeFull(OXF, Indent + 2);
1510 }
1511}
1512
1513std::string Acomp::display() const
1518{
1519 // std::string out;
1520 std::stringstream cx;
1521 std::vector<int>::const_iterator ic;
1522 int sign, val; // sign and value of unit
1523 for (ic = Units.begin(); ic != Units.end(); ++ic) {
1524 if (!Intersect && ic != Units.begin())
1525 cx << '+';
1526 split(*ic, sign, val);
1527 if (val < 27)
1528 cx << static_cast<char>(static_cast<int>('a') + (val - 1));
1529 else if (val < 53)
1530 cx << static_cast<char>(static_cast<int>('A') + (val - 27));
1531 else
1532 cx << "%" << val - 52;
1533 if (sign < 0)
1534 cx << '\'';
1535 }
1536 // Now do composites
1537 std::vector<Acomp>::const_iterator vc;
1538 for (vc = Comp.begin(); vc != Comp.end(); ++vc) {
1539 if (!Intersect && (vc != Comp.begin() || !Units.empty()))
1540 cx << '+';
1541 cx << '(' << vc->display() << ')';
1542 }
1543 return cx.str();
1544}
1545
1546std::string Acomp::displayDepth(const int dval) const
1552{
1553 // std::string out;
1554 std::stringstream cx;
1555 std::vector<int>::const_iterator ic;
1556 int sign, val; // sign and value of unit
1557 for (ic = Units.begin(); ic != Units.end(); ++ic) {
1558 if (!Intersect && ic != Units.begin())
1559 cx << '+';
1560 split(*ic, sign, val);
1561 if (val < 27)
1562 cx << static_cast<char>(static_cast<int>('a') + (val - 1));
1563 else if (val < 53)
1564 cx << static_cast<char>(static_cast<int>('A') + (val - 27));
1565 else
1566 cx << "%" << val - 52;
1567 if (sign < 0)
1568 cx << '\'';
1569 }
1570 // Now do composites
1571 std::vector<Acomp>::const_iterator vc;
1572 for (vc = Comp.begin(); vc != Comp.end(); ++vc) {
1573 if (!Intersect && (vc != Comp.begin() || !Units.empty()))
1574 cx << '+';
1575 // if ( join && (*vc)->type() )
1576 if (!vc->Intersect)
1577 cx << "D" << dval << " " << '(' << vc->displayDepth(dval + 1) << ')' << " " << dval << "E";
1578 else
1579 cx << "D" << dval << " " << vc->displayDepth(dval + 1) << " " << dval << "E";
1580 }
1581 return cx.str();
1582}
1583
1584void Acomp::printImplicates(const std::vector<BnId> &PIform, const Kernel::Matrix<int> &Grid) const
1592{
1593 const std::pair<size_t, size_t> RX = Grid.size();
1594 for (size_t pc = 0; pc != PIform.size(); pc++) {
1595 logger.debug() << PIform[pc] << ":";
1596 for (size_t ic = 0; ic != RX.second; ic++)
1597 logger.debug() << ((Grid[pc][ic]) ? " 1" : " 0");
1598 logger.debug() << '\n';
1599 }
1600}
1601
1602} // NAMESPACE Geometry
1603
1604} // 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:1546
void writeFull(std::ostream &, int const =0) const
Full write out to determine state.
Definition: Acomp.cpp:1493
void assignDNF(const std::vector< int > &, const std::vector< BnId > &)
Assigns the Comp with the DNF.
Definition: Acomp.cpp:527
int logicalEqual(const Acomp &) const
Test that the system that is logically the same:
Definition: Acomp.cpp:626
void Sort()
Sort the Units+Comp items.
Definition: Acomp.cpp:592
int removeEqComp()
Remove non-unique items.
Definition: Acomp.cpp:775
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:1014
int makeReadOnce()
Factorize into a read once function.
Definition: Acomp.cpp:605
int isSingle() const
only one part
Definition: Acomp.cpp:765
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:1443
int isDNF() const
is Units only in union
Definition: Acomp.cpp:664
int isCNF() const
is Units only in intersections
Definition: Acomp.cpp:685
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:1452
void assignCNF(const std::vector< int > &, const std::vector< BnId > &)
Assigns the Comp with the DNF.
Definition: Acomp.cpp:556
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:998
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:1054
const Acomp * itemC(int const) const
returns a pointer to Comp (or zero)
Definition: Acomp.cpp:1464
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:867
void addUnitItem(int const)
add an Unit intellgently
Definition: Acomp.cpp:346
int isSimple() const
true if only Units
Definition: Acomp.cpp:755
int contains(const Acomp &) const
Checks the Units of A to see if they are in this->Units.
Definition: Acomp.cpp:1286
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:731
int joinDepth()
Search table to uplift objects.
Definition: Acomp.cpp:1306
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:1125
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:706
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:1513
std::pair< Acomp, Acomp > algDiv(const Acomp &)
Carry out Algebric division.
Definition: Acomp.cpp:1207
int makePI(std::vector< BnId > &) const
Calculate Principal Components.
Definition: Acomp.cpp:798
void complement()
Take complement of component.
Definition: Acomp.cpp:1476
int getDNFpart(std::vector< Acomp > &) const
get the DNF parts (as Acomp)
Definition: Acomp.cpp:1088
int isNull() const
is nothing in the comp.
Definition: Acomp.cpp:656
int makeCNFobject()
Make the object into CNF form (Product of Sums)
Definition: Acomp.cpp:1071
int isTrue(const std::map< int, int > &) const
Determine if the rule is true.
Definition: Acomp.cpp:1166
void printImplicates(const std::vector< BnId > &, const Kernel::Matrix< int > &) const
Debug function to print out PI and Grid :
Definition: Acomp.cpp:1584
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:506
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:1378
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
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.
Definition: PointGroup.cpp:312
int convPartNum(const std::string &A, T &out)
Takes a character string and evaluates the first [typename T] object.
Definition: Strings.cpp:639
Helper class which provides the Collimation Length for SANS instruments.