1 //   Copyright (c)  2005-2007,2011  John Abbott, Anna Bigatti and Massimo Caboara
2 
3 //   This file is part of the source of CoCoALib, the CoCoA Library.
4 
5 //   CoCoALib is free software: you can redistribute it and/or modify
6 //   it under the terms of the GNU General Public License as published by
7 //   the Free Software Foundation, either version 3 of the License, or
8 //   (at your option) any later version.
9 
10 //   CoCoALib is distributed in the hope that it will be useful,
11 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //   GNU General Public License for more details.
14 
15 //   You should have received a copy of the GNU General Public License
16 //   along with CoCoALib.  If not, see <http://www.gnu.org/licenses/>.
17 
18 #include "CoCoA/ModuleOrdering.H"
19 
20 #include "CoCoA/BigIntOps.H"
21 #include "CoCoA/error.H"
22 #include "CoCoA/assert.H"
23 #include "CoCoA/convert.H"
24 #include "CoCoA/OpenMath.H"
25 #include "CoCoA/VectorOps.H"  // for template to output a vector
26 
27 #include <iostream>
28 using std::ostream;
29 //#include <vector>
30 using std::vector;
31 
32 namespace CoCoA
33 {
34 
ModuleOrderingBase(const PPOrdering & PPO,const std::vector<degree> & shifts)35   ModuleOrderingBase::ModuleOrderingBase(const PPOrdering& PPO, const std::vector<degree>& shifts):
36     IntrusiveReferenceCount(),
37     myPPO(PPO)
38   {
39     const long n = len(shifts);
40     for ( long i=0 ; i < n ; ++i )
41       if ( GradingDim(PPO) != GradingDim(shifts[i]) )
42         CoCoA_THROW_ERROR("GradingDim(PPO)!=GradingDim(shifts[i])", "ModuleOrderingBase");
43     myShiftsValue = shifts;
44   }
45 
46 
ModuleOrderingBase(const PPOrdering & PPO,const std::vector<degree> & shifts,const std::vector<long> & perm)47   ModuleOrderingBase::ModuleOrderingBase(const PPOrdering& PPO, const std::vector<degree>& shifts, const std::vector<long>& perm):
48     IntrusiveReferenceCount(),
49     myPPO(PPO)
50   {
51     const long n = len(shifts);
52     for ( long i=0 ; i < n ; ++i )
53       if ( GradingDim(PPO) != GradingDim(shifts[i]) )
54         CoCoA_THROW_ERROR("GradingDim(PPO)!=GradingDim(shifts[i])", "ModuleOrderingBase");
55     myShiftsValue = shifts;
56     if ( len(perm) != n )
57       CoCoA_THROW_ERROR("Shift list and permutation must have the same cardinality", "ModuleOrderingBase");
58     CoCoA_THROW_ERROR(ERR::NYI, "ModuleOrderingBase: check the entries of perm");
59     myPermutationValue = perm;
60   }
61 
62 
~ModuleOrderingBase()63   ModuleOrderingBase::~ModuleOrderingBase()
64   {}
65 
66 
67   //---------------------------------------------------------------------------
68 
69 
myShifts()70   const std::vector<degree>& ModuleOrderingBase::myShifts() const
71   { return myShiftsValue; }
72 
73 
myPerm()74   const std::vector<long>& ModuleOrderingBase::myPerm() const
75   { return myPermutationValue; }
76 
77 
myPPOrdering()78   const PPOrdering& ModuleOrderingBase::myPPOrdering() const
79   { return myPPO; }
80 
81 
myOutputSelf(std::ostream & out)82   void ModuleOrderingBase::myOutputSelf(std::ostream& out) const
83   {
84     if (!out) return;  // short-cut for bad ostreams
85 
86     myOutputName(out);
87     out << "(" << myPPO << ", " << myShiftsValue;
88     if ( !myPermutationValue.empty() )
89       out << ", " << myPermutationValue;
90     out << ")";
91   }
92 
93 
myOutputSelf(OpenMathOutput & OMOut)94   void ModuleOrderingBase::myOutputSelf(OpenMathOutput& OMOut) const
95   {
96     // missing shifts and permutation
97     OMOut->mySendApplyStart();
98     myOutputName(OMOut);
99     OMOut << myPPO;
100     OMOut->mySendApplyEnd();
101   }
102 
103 
104   //---------------------------------------------------------------------------
105   //  (ex-inline) non-member functions
106 
107   std::ostream& operator<<(std::ostream& out, const ModuleOrdering& MTO)
108   {
109     if (!out) return out;  // short-cut for bad ostreams
110     MTO->myOutputSelf(out);
111     return out;
112   }
113 
114 
115   OpenMathOutput& operator<<(OpenMathOutput& OMOut, const ModuleOrdering& MTO)
116   {
117     MTO->myOutputSelf(OMOut);
118     return OMOut;
119   }
120 
121 
shifts(const ModuleOrdering & MTO)122   const std::vector<degree>& shifts(const ModuleOrdering& MTO)
123   { return MTO->myShifts(); }
124 
125 
ModPPOrdering(const ModuleOrdering & MTO)126   const PPOrdering& ModPPOrdering(const ModuleOrdering& MTO)
127   { return (MTO->myPPOrdering()); }
128 
129 
NumComponents(const ModuleOrdering & MTO)130   long NumComponents(const ModuleOrdering& MTO)
131   { return len(shifts(MTO)); }
132 
133 
GradingDim(const ModuleOrdering & MTO)134   long GradingDim(const ModuleOrdering& MTO)
135   { return GradingDim(ModPPOrdering(MTO)); }
136 
137 
138   // ----------------- concrete classes ---------------------
139   namespace ModuleOrd
140   {
141 
142     class PosnOrdImpl: public ModuleOrderingBase
143     {
144     private:
145       friend ModuleOrdering CoCoA::NewPosnOrd(const PPOrdering& PPO, long NumComponents);
146       friend ModuleOrdering CoCoA::NewPosnOrd(const PPOrdering& PPO, const std::vector<degree>& shifts);
147     private:
148       PosnOrdImpl(const PPOrdering& PPO, const std::vector<degree>& shifts);
149       PosnOrdImpl(const PosnOrdImpl&);            ///< NEVER DEFINED -- copy ctor disabled
150       PosnOrdImpl& operator=(const PosnOrdImpl&); ///< NEVER DEFINED -- assignment disabled
151     public:
152       virtual void myOutputName(std::ostream& out) const;
153       virtual void myOutputName(OpenMathOutput& OMOut) const;
154     };
155 
156 
157     class OrdPosnImpl: public ModuleOrderingBase
158     {
159     private:
160       friend ModuleOrdering CoCoA::NewOrdPosn(const PPOrdering& PPO, long NumComponents);
161       friend ModuleOrdering CoCoA::NewOrdPosn(const PPOrdering& PPO, const std::vector<degree>& shifts);
162       friend ModuleOrdering CoCoA::NewOrdPosn(const PPOrdering& PPO, const std::vector<long>& perm);
163       friend ModuleOrdering CoCoA::NewOrdPosn(const PPOrdering& PPO, const std::vector<degree>& shifts, const std::vector<long>& perm);
164     private:
165       OrdPosnImpl(const PPOrdering& PPO, const std::vector<degree>& shifts);
166       OrdPosnImpl(const PPOrdering& PPO, const std::vector<degree>& shifts, const std::vector<long>& perm);
167       OrdPosnImpl(const OrdPosnImpl&);            ///< NEVER DEFINED -- copy ctor disabled
168       OrdPosnImpl& operator=(const OrdPosnImpl&); ///< NEVER DEFINED -- assignment disabled
169     public:
170       virtual void myOutputName(std::ostream& out) const;
171       virtual void myOutputName(OpenMathOutput& OMOut) const;
172     };
173 
174 
175     class WDegPosnOrdImpl: public ModuleOrderingBase
176     {
177     private:
178       friend ModuleOrdering CoCoA::NewWDegPosnOrd(const PPOrdering& PPO, long NumComponents);
179       friend ModuleOrdering CoCoA::NewWDegPosnOrd(const PPOrdering& PPO, const std::vector<degree>& shifts);
180       friend ModuleOrdering CoCoA::NewWDegPosnOrd(const PPOrdering& PPO, const std::vector<long>& perm);
181       friend ModuleOrdering CoCoA::NewWDegPosnOrd(const PPOrdering& PPO, const std::vector<degree>& shifts, const std::vector<long>& perm);
182     private:
183       WDegPosnOrdImpl(const PPOrdering& PPO, const std::vector<degree>& shifts);
184       WDegPosnOrdImpl(const PPOrdering& PPO, const std::vector<degree>& shifts, const std::vector<long>& perm);
185       WDegPosnOrdImpl(const PPOrdering& PPO, const WDegPosnOrdImpl&);            ///< NEVER DEFINED -- copy ctor disabled
186       WDegPosnOrdImpl& operator=(const WDegPosnOrdImpl&); ///< NEVER DEFINED -- assignment disabled
187     public:
188       virtual void myOutputName(std::ostream& out) const;
189       virtual void myOutputName(OpenMathOutput& OMOut) const;
190     };
191 
192 
193     //---------- PosnOrdImpl ----------------------------------------
194 
PosnOrdImpl(const PPOrdering & PPO,const std::vector<degree> & shifts)195     PosnOrdImpl::PosnOrdImpl(const PPOrdering& PPO, const std::vector<degree>& shifts):
196       ModuleOrderingBase(PPO, shifts)
197     {}
198 
199 
myOutputName(std::ostream & out)200     void PosnOrdImpl::myOutputName(std::ostream& out) const
201     {
202       if (!out) return;  // short-cut for bad ostreams
203       out << "ModuleOrderingOrdPosn";
204     }
205 
myOutputName(OpenMathOutput & OMOut)206     void PosnOrdImpl::myOutputName(OpenMathOutput& OMOut) const
207     {  OMOut << OpenMathSymbol("cocoa", "ModuleOrderingOrdPosn"); }
208 
209 
210     //---------- OrdPosnImpl ----------------------------------------
211 
OrdPosnImpl(const PPOrdering & PPO,const std::vector<degree> & shifts)212     OrdPosnImpl::OrdPosnImpl(const PPOrdering& PPO, const std::vector<degree>& shifts):
213       ModuleOrderingBase(PPO, shifts)
214     {}
215 
216 
OrdPosnImpl(const PPOrdering & PPO,const std::vector<degree> & shifts,const std::vector<long> & perm)217     OrdPosnImpl::OrdPosnImpl(const PPOrdering& PPO, const std::vector<degree>& shifts, const std::vector<long>& perm):
218       ModuleOrderingBase(PPO, shifts, perm)
219     {}
220 
221 
myOutputName(std::ostream & out)222     void OrdPosnImpl::myOutputName(std::ostream& out) const
223     {
224       if (!out) return;  // short-cut for bad ostreams
225       out << "ModuleOrderingOrdPosn";
226     }
227 
myOutputName(OpenMathOutput & OMOut)228     void OrdPosnImpl::myOutputName(OpenMathOutput& OMOut) const
229     {  OMOut << OpenMathSymbol("cocoa", "ModuleOrderingOrdPosn"); }
230 
231 
232     //---------- WDegPosnOrdImpl ----------------------------------------
233 
WDegPosnOrdImpl(const PPOrdering & PPO,const std::vector<degree> & shifts)234     WDegPosnOrdImpl::WDegPosnOrdImpl(const PPOrdering& PPO, const std::vector<degree>& shifts):
235       ModuleOrderingBase(PPO, shifts)
236     {}
237 
238 
WDegPosnOrdImpl(const PPOrdering & PPO,const std::vector<degree> & shifts,const std::vector<long> & perm)239     WDegPosnOrdImpl::WDegPosnOrdImpl(const PPOrdering& PPO, const std::vector<degree>& shifts, const std::vector<long>& perm):
240       ModuleOrderingBase(PPO, shifts, perm)
241     {}
242 
243 
myOutputName(std::ostream & out)244     void WDegPosnOrdImpl::myOutputName(std::ostream& out) const
245     {
246       if (!out) return;  // short-cut for bad ostreams
247       out << "ModuleOrderingOrdPosn";
248     }
249 
250 
myOutputName(OpenMathOutput & OMOut)251     void WDegPosnOrdImpl::myOutputName(OpenMathOutput& OMOut) const
252     {  OMOut << OpenMathSymbol("cocoa", "ModuleOrderingOrdPosn"); }
253 
254 
255     //------------------------------------------------------------//
256 
257 
258   } // end of namespace ModuleOrd
259 
260 
NewPosnOrd(const PPOrdering & PPO,long NumComponents)261   ModuleOrdering NewPosnOrd(const PPOrdering& PPO, long NumComponents)
262   {
263     if (NumComponents < 0) CoCoA_THROW_ERROR(ERR::BadArg, "NewPosnOrd");
264     return ModuleOrdering(new ModuleOrd::PosnOrdImpl(PPO, vector<degree>(NumComponents, degree(GradingDim(PPO)))));
265   }
266 
NewOrdPosn(const PPOrdering & PPO,long NumComponents)267   ModuleOrdering NewOrdPosn(const PPOrdering& PPO, long NumComponents)
268   {
269     if (NumComponents < 0) CoCoA_THROW_ERROR(ERR::BadArg, "NewOrdPosn");
270     return ModuleOrdering(new ModuleOrd::OrdPosnImpl(PPO, vector<degree>(NumComponents, degree(GradingDim(PPO)))));
271   }
272 
273 
NewWDegPosnOrd(const PPOrdering & PPO,long NumComponents)274   ModuleOrdering NewWDegPosnOrd(const PPOrdering& PPO, long NumComponents)
275   {
276     if (NumComponents < 0) CoCoA_THROW_ERROR(ERR::BadArg, "NewWDegPosnOrd");
277     return ModuleOrdering(new ModuleOrd::WDegPosnOrdImpl(PPO, vector<degree>(NumComponents, degree(GradingDim(PPO)))));
278   }
279 
280 
NewPosnOrd(const PPOrdering & PPO,const std::vector<degree> & shifts)281   ModuleOrdering NewPosnOrd(const PPOrdering& PPO, const std::vector<degree>& shifts)
282   {
283     return ModuleOrdering(new ModuleOrd::PosnOrdImpl(PPO, shifts));
284   }
285 
286 
NewOrdPosn(const PPOrdering & PPO,const std::vector<degree> & shifts)287   ModuleOrdering NewOrdPosn(const PPOrdering& PPO, const std::vector<degree>& shifts)
288   {
289     return ModuleOrdering(new ModuleOrd::OrdPosnImpl(PPO, shifts));
290   }
291 
292 
NewWDegPosnOrd(const PPOrdering & PPO,const std::vector<degree> & shifts)293   ModuleOrdering NewWDegPosnOrd(const PPOrdering& PPO, const std::vector<degree>& shifts)
294   {
295     return ModuleOrdering(new ModuleOrd::WDegPosnOrdImpl(PPO, shifts));
296   }
297 
298 
NewOrdPosn(const PPOrdering & PPO,const std::vector<long> & perm)299   ModuleOrdering NewOrdPosn(const PPOrdering& PPO, const std::vector<long>& perm)
300   {
301     return ModuleOrdering(new ModuleOrd::OrdPosnImpl(PPO, vector<degree>(len(perm), degree(GradingDim(PPO))), perm));
302   }
303 
304 
NewWDegPosnOrd(const PPOrdering & PPO,const std::vector<long> & perm)305   ModuleOrdering NewWDegPosnOrd(const PPOrdering& PPO, const std::vector<long>& perm)
306   {
307     return ModuleOrdering(new ModuleOrd::WDegPosnOrdImpl(PPO, vector<degree>(len(perm), degree(GradingDim(PPO))), perm));
308   }
309 
310 
NewOrdPosn(const PPOrdering & PPO,const std::vector<degree> & shifts,const std::vector<long> & perm)311   ModuleOrdering NewOrdPosn(const PPOrdering& PPO, const std::vector<degree>& shifts, const std::vector<long>& perm)
312   {
313     return ModuleOrdering(new ModuleOrd::OrdPosnImpl(PPO, shifts, perm));
314   }
315 
316 
NewWDegPosnOrd(const PPOrdering & PPO,const std::vector<degree> & shifts,const std::vector<long> & perm)317   ModuleOrdering NewWDegPosnOrd(const PPOrdering& PPO, const std::vector<degree>& shifts, const std::vector<long>& perm)
318   {
319     return ModuleOrdering(new ModuleOrd::WDegPosnOrdImpl(PPO, shifts, perm));
320   }
321 
322 
IsPosnOrd(const ModuleOrdering & MOrd)323   bool IsPosnOrd(const ModuleOrdering& MOrd)
324   {
325     if (dynamic_cast<const ModuleOrd::PosnOrdImpl*>(MOrd.myRawPtr())) return true;
326     // must decide whether the matrix is PosnWDeg..., possibly in disguise
327     return false;
328   }
329 
330 
IsOrdPosn(const ModuleOrdering & MOrd)331   bool IsOrdPosn(const ModuleOrdering& MOrd)
332   {
333     if (dynamic_cast<const ModuleOrd::OrdPosnImpl*>(MOrd.myRawPtr())) return true;
334     // must decide whether the matrix is WDeg..., possibly in disguise
335     return false;
336   }
337 
338 
IsWDegPosnOrd(const ModuleOrdering & MOrd)339   bool IsWDegPosnOrd(const ModuleOrdering& MOrd)
340   {
341     if (dynamic_cast<const ModuleOrd::WDegPosnOrdImpl*>(MOrd.myRawPtr())) return true;
342     // must decide whether the matrix is WDeg..., possibly in disguise
343     return false;
344   }
345 
346 
347   // STOPGAP Placeholder defn
operator()348   ModuleOrdering PosnOrdCtor::operator()(const PPOrdering& PPO, const std::vector<degree>& shifts) const
349   { CoCoA_THROW_ERROR(ERR::NYI, "PosnOrdCtor with shifts"); return operator()(PPO,0); }
350 
351 
352   //----- declaration of ordering ctors ---------------------------
353   OrdPosnCtor OrdPosn;
354   PosnOrdCtor PosnOrd;
355   WDegPosnOrdCtor WDegPosnOrd;
356   //----- declaration of ordering ctors ---------------------------
357 
358 } // end of namespace CoCoA
359 
360 
361 
362 // RCS header/log in the next few lines
363 // $Header: /Volumes/Home_1/cocoa/cvs-repository/CoCoALib-0.99/src/AlgebraicCore/ModuleOrdering.C,v 1.9 2020/06/17 15:49:24 abbott Exp $
364 // $Log: ModuleOrdering.C,v $
365 // Revision 1.9  2020/06/17 15:49:24  abbott
366 // Summary: Changed CoCoA_ERROR into CoCoA_THROW_ERROR
367 //
368 // Revision 1.8  2020/02/11 16:56:41  abbott
369 // Summary: Corrected last update (see redmine 969)
370 //
371 // Revision 1.7  2020/02/11 16:12:18  abbott
372 // Summary: Added some checks for bad ostream (even to mem fns myOutput); see redmine 969
373 //
374 // Revision 1.6  2018/05/18 12:15:04  bigatti
375 // -- renamed IntOperations --> BigIntOps
376 //
377 // Revision 1.5  2018/05/17 15:37:31  bigatti
378 // -- renamed VectorOperations --> VectorOps
379 //
380 // Revision 1.4  2016/11/11 14:15:32  abbott
381 // Summary: Added short-cut to operator<< when ostream is in bad state
382 //
383 // Revision 1.3  2015/12/01 13:11:00  abbott
384 // Summary: Changed mem fn PPOrderingCtor::myCtor into operator(); also for ModuleOrderingCtor; see issue 829
385 //
386 // Revision 1.2  2014/07/31 14:45:17  abbott
387 // Summary: Merged io.H and UtilsTemplate.H into new header VectorOperations.H
388 // Author: JAA
389 //
390 // Revision 1.1  2013/06/03 08:51:58  bigatti
391 // -- was ModuleTermOrdering
392 //
393 // Revision 1.6  2013/05/31 10:31:09  abbott
394 // Moved NYI impl body of PosnOrdCtor::myCtor to *.C file to avoid multiple compiler
395 // warnings about unused parameter.
396 //
397 // Revision 1.5  2013/05/27 16:35:05  bigatti
398 // -- major reorganisation of the implementation, changed names
399 // ---- WDegPosTO --> WDegPosnOrd,  WDegTOPos --> OrdPosn,  PosWDegTO --> PosnOrd
400 //
401 // Revision 1.4  2012/05/28 09:18:21  abbott
402 // Created IntOperations which gathers together all operations on
403 // integers (both big and small).  Many consequential changes.
404 //
405 // Revision 1.3  2011/03/10 16:39:34  abbott
406 // Replaced (very many) size_t by long in function interfaces (for rings,
407 // PPMonoids and modules).  Also replaced most size_t inside fn defns.
408 //
409 // Revision 1.2  2007/10/30 17:14:08  abbott
410 // Changed licence from GPL-2 only to GPL-3 or later.
411 // New version for such an important change.
412 //
413 // Revision 1.1.1.1  2007/03/09 15:16:11  abbott
414 // Imported files
415 //
416 // Revision 1.10  2007/03/08 18:22:29  cocoa
417 // Just whitespace cleaning.
418 //
419 // Revision 1.9  2007/02/10 18:44:03  cocoa
420 // Added "const" twice to each test and example.
421 // Eliminated dependency on io.H in several files.
422 // Improved BuildInfo, and added an example about how to use it.
423 // Some other minor cleaning.
424 //
425 // Revision 1.8  2007/01/18 15:34:04  cocoa
426 // -- changed namespace MTO into ModuleTermOrd
427 //
428 // Revision 1.7  2006/11/24 17:14:10  cocoa
429 // -- reorganized includes of header files
430 // -- SmartPtrIRC for reference counting
431 //
432 // Revision 1.6  2006/11/10 13:30:57  cocoa
433 // -- fixed: "const &" to PPOrdering arguments
434 // -- some more documentation
435 //
436 // Revision 1.5  2006/11/10 13:06:03  cocoa
437 // -- cleaned code
438 //
439 // Revision 1.4  2006/11/02 13:25:44  cocoa
440 // Simplification of header files: the OpenMath classes have been renamed.
441 // Many minor consequential changes.
442 //
443 // Revision 1.3  2006/10/06 15:11:01  cocoa
444 // -- removed commented out code
445 //
446 // Revision 1.2  2006/10/06 14:04:15  cocoa
447 // Corrected position of #ifndef in header files.
448 // Separated CoCoA_ASSERT into assert.H from config.H;
449 // many minor consequential changes (have to #include assert.H).
450 // A little tidying of #include directives (esp. in Max's code).
451 //
452 // Revision 1.1.1.1  2006/05/30 11:39:37  cocoa
453 // Imported files
454 //
455 // Revision 1.8  2006/05/12 16:10:58  cocoa
456 // Added OpenMathFwd.H, and tidied OpenMath.H.
457 // Many consequential but trivial changes.
458 //
459 // Revision 1.7  2006/05/11 15:59:23  cocoa
460 // -- changed reference count is done using SmartPtrIRC
461 //
462 // Revision 1.6  2006/05/04 14:19:02  cocoa
463 // -- moved some code from .H to .C
464 //
465 // Revision 1.5  2006/04/28 11:32:16  cocoa
466 // -- moved concrete class definition from .H to .C
467 //
468 // Revision 1.4  2006/03/15 18:09:31  cocoa
469 // Changed names of member functions which print out their object
470 // into myOutputSelf -- hope this will appease the Intel C++ compiler.
471 //
472 // Revision 1.3  2006/03/12 21:28:34  cocoa
473 // Major check in after many changes
474 //
475 // Revision 1.2  2005/11/24 17:06:40  cocoa
476 // -- fixed IsWDegTOPos, IsWDegPosTO, IsWDegTOPermPos, IsWDegPermPosTO
477 //
478 // Revision 1.1.1.1  2005/10/17 10:46:54  cocoa
479 // Imported files
480 //
481 // Revision 1.1  2005/09/28 11:50:34  cocoa
482 // -- new code for graded modules
483 //
484