Declarations of functions associated with group_D.
Version of Thursday 26 September 2024.
The next two functions are different notations for exactly the same calculation, which can be regarded as function application, and in some ways might be regarded as resembling multiplication. Parameter b is interpreted as instructions for how to rearrange the elements of *this. The pipleline operator offers a simpler notation for when the function is deeply nested.
For a background on these operations, see this discussion.
/* D1 */ permzbi operator() (permzbi const & b) const; /* D1 */ permzbi operator| (permzbi const & b) const; /* D1 */ permzbi & operator|= (permzbi const & b); // power is repeated use of operator|. The exponent // may be any positive, negative, or zero integer. /* D1 */ permzbi power (int const e) const; // The expression P(P.inverse()) yields an identity permutation: /* D1 */ permzbi inverse (permzbi const & a);
Comment. In an earlier version of this program, operator* and operator*= were the symbols used instead of operator| and operator|= respectively, precisely because function application of permutations does resemble multiplication. Later, when the outer product (discussed below) was developed and added to class permzbi, it was felt to be more deserving of symbols operator* and operator*=, so they were moved to the outer product. Function application then was given the replacements operator| and operator|=.
In the operator symbols for the direct and skew sums:
When they are invoked, *this will be the operand on the left, as with:
R = P << Q; | equivalently | R = P.operator<< (Q); |
direct sum: the elements of Q will be increased | ||
S = P >> Q; | equivalently | R = P.operator>> (Q); |
skew sum: the elements of P will be increased |
Their declarations:
// direct sum /* D2 */ permzbi & operator<<= (permzbi const & b); /* D2 */ permzbi operator<< (permzbi const & b) const; // skew sum /* D2 */ permzbi & operator>>= (permzbi const & b); /* D2 */ permzbi operator>> (permzbi const & b) const; // true if *this can be written as a direct sum // that has a_size elements in the first operand /* D2 */ bool operator<< (int const a_size) const; // true if *this can be written as a skew sum // that has a_size elements in the first operand /* D2 */ bool operator>> (int const a_size) const;
The last two functions above tell whether a separation into the addends of a direct or skew sum is possible, but they do not provide it. The two functions below are how to get each permzbi separately.
/* D3 */ permzbi retain_front (int const length) const; /* D3 */ permzbi retain_back (int const length) const;
The next two functions deliver the outer product, which accepts any two permzbis as operands; they need not be the same size.
/* D3 */ permzbi operator* (permzbi const & b) const; /* D3 */ permzbi & operator*= (permzbi const & b);
Next is reduce, which creates a new permzbi from an old one by removing all components greater then or equal to new_length.
/* D3 */ permzbi reduce (int const new_length) const;
/* D4 */ int sign () const; /* D4 */ int local_inversions () const; /* D4 */ int global_inversions () const; /* D4 */ SVSVI ascend_run () const; /* D4 */ SVSVI descend_run () const;
With the last two of these functions, if the std::vectors within the SVSVI are catenated, the original permzbi is obtained.
In matters of operator precedence, consider the following four functions:
/* D2 */ permzbi operator<< (permzbi const & b) const; /* D2 */ permzbi operator>> (permzbi const & b) const; /* S1 */ std::ostream & operator<< (std::ostream & text_out, permzbi const & p); /* S1 */ std::istream & operator>> (std::istream & text_in, permzbi & p);
A rule of C++, inherited from the C programming language, is that for objects of any combination of types, A << B << C means (A << B) << C. If P and Q are permzbis:
cout << P << Q;
and (cout << P) << Q; |
are equivalent to | cout << P; cout << Q; |
cout << (P << Q); | is equivalent to | auto R = P << Q; cout << R; |
Similarly, if S and T are non-const permzbis:
cin >> S >> T;
and (cin >> S) >> T; |
are equivalent to | cin >> S; cin >> T; |
cin >> (S >> T); | is illegal, because (S >> T) is not an l-value. |