 
(* 

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Domain Constructor "Distributive Nest represented Polys"

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


Data structure:
---------------
   
A Distributive Nest represented Poly over a domain
of monomials is a Nest of the form  

   DNP[ ] 
  
   or

   DNP[ m,  dnp]
             
   where m is from the domain of monomials
   dnp is a Distributive Nest represented Poly 
   and m is >  than all monomials
   occurring in dnp.
                  
*)    

LeadingMonomial[ DNP[ m_, dnp_]] := m    

RemainingPolynomial[ DNP[ m_, dnp_]] := dnp  

LeadingPowerProduct[ DNP[ m_, dnp_]] := PowerProduct[ m]

LeadingPolynomial[ DNP[ m_, dnp_]] := DNP[ m, DNP[ ]]

NumberOfVariables[ DNP[ m_, dnp_]] :=
  NumberOfVariables[ m]         

ExpandedByIndeterminate[ dnp_DNP] :=
  ComponentWiseN[ ExpandedByIndeterminate, dnp]
            
RabinovichExpanded[ dnp_DNP] :=
  ExpandedByIndeterminate[ dnp] *
  NewIndeterminate[ LeadingMonomial[ dnp]] -
  ExpandedByIndeterminate[ One[ dnp]]     

                                         

DNP/:        
DNP[ m1_, dnp1_] == DNP[ m2_, dnp2_] :=  
  m1 == m2  &&   dnp1 == dnp2   

DNP/:
DNP[ ] == DNP[ m_, dnp_] := False
      
DNP/:
DNP[ m_, dnp_] == DNP[ ] := False
  
DNP/:
DNP[ ] == DNP[ ] := True
     
    
DNP/:
dnp1_DNP != dnp2_DNP := Not[ dnp1 == dnp2]
                        

Zero[ dnp_DNP] := DNP[ ]
 
 
One[ DNP[ m_, dnp_]] := 
  DNP[ One[ m], DNP[ ]]
                     
DNP/:
dnp1_DNP + dnp2_DNP :=
  MergeN[ dnp1, dnp2, Greater, Greater, (#1 == - #2)&, Plus]
    

DNP/:
-  dnp_DNP := ComponentWiseN[ (- #)&, dnp] 
      
DNP/:
dnp_DNP - dnp_DNP := Zero[ dnp]


DNP/:
DNP[ m1_, dnp1_] *  dnp2_DNP :=
  m1 * dnp2 +  dnp1 * dnp2

DNP/:
DNP[ ] * dnp_DNP := DNP[ ]

DNP/:
dnp_DNP * DNP[ ] := DNP[ ]
         

DNP/:
monomial_  * dnp_DNP := 
  ComponentWiseN[  (monomial * #)&, dnp]


DNP/:
Power[ dnp_DNP, n_Integer] := 
  (* Assumption: n > 0. *)
  Block[ { r = dnp, i},
    For[ i=1, i<n, i++, r = r dnp];
    r
    ] 


SPolynomial[
  DNP[ m1_, dnp1_],
  DNP[ m2_, dnp2_]
  ] := 
  Block[ 
    { lcm = LCM[ m1, m2], u1, u2},
    u1 = lcm / m1;
    u2 = lcm / m2;
    u1  dnp1 -  u2 dnp2 
    ]

Normalized[ DNP[ m_, dnp_]] := 
  DNP[ Normalized[ m], Normalizer[m] dnp]

        
Labeled[ dnp_DNP] :=  LabP[ NewLabel[], dnp]  
  

NormalForm[ dnp_, pn_] :=  
  $NormalFormDNP[ dnp, pn]
  (*
    Alternatives:
      PartialNormalForm [ dnp, pn] 
      CompleteNormalForm [ dnp, pn].
   *)

   
PartialNormalForm[ DNP[ m_, dnp_], pn_PN] := 
  (* Block[ { dnp0 = DNP[ m, dnp]}, P[ dnp0];
       PartialNormalForm$[ dnp0, pn, pn]
       ] 
     *)
  PartialNormalForm$[ DNP[ m, dnp], pn, pn] 

PartialNormalForm[ DNP[ ], pn_PN] := 
  (* Block[ {}, P[ DNP[]]; DNP[ ]] *)  
  DNP[ ] 


PartialNormalForm$[ DNP[ m_, dnp_], PN[ pRed_, pnRest_],  pn_] :=   
  Block[ {lm = LeadingMonomial[ pRed],
    rp = RemainingPolynomial[ pRed]
    },
    Which[                               
      IsMultiple[ m, lm],
        (* Print["use "]; PLabel[ pRed]; *)
        PartialNormalForm[ dnp - (m / lm) rp, pn],
      lm > m, DNP[ m, dnp],
      True, PartialNormalForm$[ DNP[ m, dnp], pnRest, pn]
      ] 
    ]
       
PartialNormalForm$[ dnp_, PN[ ], pn_] := dnp
                                

CompleteNormalForm[ dnp_DNP, pn_] :=
  CompleteNormalForm$[ PartialNormalForm[ dnp, pn], pn] 
       
 
CompleteNormalForm$[ DNP[ m_, dnp_], pn_] := 
  (* Complete Normal Form under the assumption that
     the first argument is already partially reduced
     w.r.t. pn.
  *)
  DNP[ m, CompleteNormalForm[ dnp, pn]]
   
CompleteNormalForm$[ DNP[ ], pn_] := DNP[ ]    

    
      

HeadReduced[ DNP[ m_, dnp_], pn_] := 
  DNP[ m, CompleteNormalForm[ dnp, pn]]


DNP/:
Sort[ dnp_DNP] := SortN[ dnp, Greater]

   
P[ dnp_DNP] :=  
  Block[ {},
    Print[ "Distributive Nest Poly"]; 
    P[ dnp, Nest];
    Print[ "End of Distributive Nest Poly"]
    ]

P[ dnp_DNP, Q] :=
  Print[ "DNP Print Options: N, S, P, C, Sh, D"]

P[ dnp_DNP, N, Q] :=
  Print[ "Prints Number of monomials"]

P[ dnp_DNP, N] :=  
  Print[ "Number of monomials: ", LengthN[ dnp]]
                          
P[ dnp_DNP, S, Q] := 
  Print[ "Prints Structure (leading PP, maximal coefficient size,"]
  Print[ "number of monomials)."]

P[ dnp_DNP, S] := 
  Block[ {
    lpp = PowerProduct[ LeadingMonomial[ dnp]],
    mcl = MaximalCoefficientSize[ dnp],
    n = LengthN[ dnp]
    },
    Print[ "Leading PP: "]; P[ lpp];
    Print[ "Maximal Coefficient Size: ", mcl, ";Number of Monomials: ", n]  
    ]     

MaximalCoefficientSize[ DNP[ m_, dnp_]] := 
  Max[ CoefficientSize[ m], MaximalCoefficientSize[ dnp]] 

MaximalCoefficientSize[ DNP[ ]] := 0

P[ dnp_DNP, P, Q] := 
  Print[ "Prints all Power products."]
        
P[ dnp_DNP, P] := 
  Block[ {},
    Print[ "Distributive Nest Poly: Only Power Products"];
    P[ dnp, Nest, PowerProduct];
    Print[ "End of Distributive Nest Poly"]
    ]


P[ dnp_DNP, P, variables_MP] := 
  Block[ {},
    Print[ "Distributive Nest Poly: Only Power Products"];
    P[ dnp, Nest, C[ PowerProduct[ #], variables] & ];
    Print[ "End of Distributive Nest Poly"]
    ]

           
P[ dnp_DNP, C, Q] := 
  Print[ "Prints all monomials with Coefficient sizes."]
   
P[ dnp_DNP, C] := 
 Block[ {},
    Print[ "Distributive Nest Poly: Monomials with Coefficient Size"];
    DoForAllN[ dnp,  P[ #, C] & ];
    Print[ "End of Distributive Nest Poly"]
    ]
 
P[ dnp_DNP, C, variables_MP] :=  
  Block[ {},
    Print[ "Distributive Nest Poly: Monomials with Coefficient Size"];
    DoForAllN[ dnp, P[ #, C, variables] & ];
    Print[ "End of Distributive Nest Poly"]
    ]


P[ dnp_DNP, Sh, Q] := 
  Print[ "P[ dnp, Sh, MP[ var1, ...]] prints Mathematica Short form."
    ]

P[ dnp_DNP, Sh, variables_MP] := 
  Print[ Short[ C[ C[ dnp, variables], IMP]]]
    
P[ dnp_DNP, D, Q] := 
  Print[ "Prints Domain of coefficients."]

P[ dnp_DNP, D] := 
  Block[ {},
    Print[ "Coefficient Domain: "];
    P[ Coefficient[ LeadingMonomial[ dnp]], Domain]
    ]       
 

C[ dnp_DNP, perm_VarPerm] := 
  C[ dnp, DNP[ NestToNest, perm]]


C[ DNP[ m_, dnp_], variables_MP] := 
  C[ m, variables] + C[ dnp, variables]  

C[ DNP[ ], variables_MP] := MP[ 0]
                                     
                 
C[ dnp_DNP, LP] :=
  C[ dnp, LP[ NestToList, Identity]]
        

C[ dnp_DNP, RFDNP[ variableIndices_, variables_]] := 
  MonomialCondensed[ 
    Sort[
      C[ dnp,
        DNP[ NestToNest, RFMon[ variableIndices, variables]]
        ]
      ]
    ]    

MonomialCondensed[ DNP[ m1_, DNP[ m2_, dnp_]]] :=
  MonomialCondensed[ 
    DNP[ m1 + m2, dnp]
    ] /; IsPowerProductEqual[ m1, m2]

MonomialCondensed[ DNP[ m1_, DNP[ m2_, dnp_]]] :=
  DNP[ m1,
   MonomialCondensed[ DNP[ m2, dnp]]
   ]  /; ! IsPowerProductEqual[ m1, m2]

MonomialCondensed[ DNP[ m_, dnp_]] :=  
  MonomialCondensed[ dnp] /; HasZeroCoefficient[ m]

MonomialCondensed[ DNP[ m_, DNP[ ]]] := DNP[ m, DNP[ ]]

MonomialCondensed[ DNP[ ]] := DNP[ ]  



 

