source: git/Singular/janet.cc @ 65dea3

spielwiese
Last change on this file since 65dea3 was 65dea3, checked in by Michael Brickenstein <bricken@…>, 20 years ago
*bricken: removed duplicate default argument git-svn-id: file:///usr/local/Singular/svn/trunk@6914 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100755
File size: 15.3 KB
Line 
1#include "mod2.h"
2#include "febase.h"
3#include "janet.h"
4#include "polys.h"
5#include "numbers.h"
6#include "ring.h"
7#include "ideals.h"
8#include "subexpr.h"
9#include "longrat.h"
10#include "kutil.h"
11
12//#define DebugPrint
13
14#define pow_(x) pTotaldegree((x))
15
16static int ProdCrit, ChainCrit;
17
18void Debug()
19{
20        LCI it=T->root;
21
22        Print("T==================================\n");
23        while (it)
24        {
25                pWrite(it->info->root);
26                it=it->next;
27        }
28
29        it=Q->root;
30
31        Print("Q==================================\n");
32        while (it)
33        {
34                if (it->info->root) pWrite(it->info->root);
35                else
36                {
37                        Print("%d.........",it->info->prolonged);
38                        pWrite(it->info->history);
39                }
40                it=it->next;
41        }
42        Print("===================================\n");
43}
44
45int ReducePolyLead(Poly *x,Poly *y)
46{
47        if (!x->root || !y->root)
48                return 0;
49
50/*      poly b1=pDivide(x->root,y->root);
51
52        number gcd=nGcd(pGetCoeff(x->root),pGetCoeff(y->root),currRing);
53
54        number a1=nDiv(pGetCoeff(y->root),gcd);
55        pGetCoeff(b1)=nDiv(pGetCoeff(x->root),gcd);
56
57        x->root=pMult_nn(x->root,a1);
58        nDelete(&a1);
59
60        x->root=pMinus_mm_Mult_qq(x->root,b1,y->root);
61
62        pDelete(&b1);*/
63
64        x->root=ksOldSpolyRed(y->root,x->root,NULL);   
65
66//      if (x->root) pContent(x->root);
67
68        return 1;
69}
70
71int ReducePoly(Poly *x,poly from,Poly *y)
72{
73        if (!x->root || !y->root)
74                return 0;
75
76/*      poly b1=pDivide(from,y->root);
77
78        number gcd=nGcd(pGetCoeff(from),pGetCoeff(y->root),currRing);
79
80        number a1=nDiv(pGetCoeff(y->root),gcd);
81        pGetCoeff(b1)=nDiv(pGetCoeff(from),gcd);
82
83        x->root=pMult_nn(x->root,a1);
84        nDelete(&a1);*/
85
86//      x->root=pMinus_mm_Mult_qq(x->root,b1,y->root);
87//      pDelete(&b1);
88
89        ksOldSpolyTail(y->root,x->root,from,NULL,currRing);
90
91        return 1;
92}
93
94void PNF(Poly *p, TreeM *F)
95{
96        Poly *f;
97
98        if (!p->root) return;
99
100        poly temp=p->root;
101
102        while(temp->next)
103        {
104                f=is_div_(F,temp->next);
105                if (f)
106                {
107                        if (ReducePoly(p,temp,f)) //temp->next
108                        {
109                                ;
110                        }
111                }       
112                else
113                        temp=temp->next;
114        };
115
116//      pCleardenom(p->root);
117        pContent(p->root);
118        pTest(p->root);
119}
120
121void NFL(Poly *p, TreeM *F)
122{
123        Poly *f;
124        int g1,f1,gg;
125
126
127        if ((f=is_div_(F,p->lead))==NULL) return;
128
129        int pX=pow_(p->lead);
130        int phX=pow_(p->history);
131               
132        if (pX!=phX)
133        {
134                int phF=pow_(f->history);
135                if (!rIsPluralRing(currRing))
136                {
137                   /* Product Criterion */
138                  if (pX >= (phX+phF))
139                  {
140                    //            Print("ProdCrit Works!");
141                    ProdCrit++;
142                    pDelete(&p->root);
143                    p->root=NULL;
144                    return;
145                  }
146                }
147
148                int gg=0; int i=0;
149                for(i=0; i<currRing->N;i++)
150                {
151                  g1=pGetExp(p->history,i+1);
152                  f1=pGetExp(f->history,i+1);
153                  if (g1 > f1)  { gg=gg+g1; }
154                  else { gg=gg+f1; }
155                }
156                if (pX > gg)
157                {                 
158                  //              Print("ChainCrit Works!");
159                  ChainCrit++;
160                  pDelete(&p->root);
161                  //x->root=NULL;
162                  return;
163                }
164                int pF=pow_(f->lead);
165
166                if ((pX == pF) && (pF == phF))
167                {
168                        pLmDelete(&f->history);
169                        f->history=pCopy(p->history);
170                }
171        }
172
173        while(f && p->root)
174        {
175//              Print("R");
176                if (ReducePolyLead(p,f) == 0) break;
177                if (p->root) f=is_div_(F,p->root);
178        }
179
180        if (!p->root) 
181                return;
182
183        InitHistory(p);
184        InitProl(p);
185        InitLead(p);
186        p->changed=1;
187
188//      pCleardenom(p->root);
189        pContent(p->root);
190        pTest(p->root);
191}
192
193int ValidatePoly(Poly *x, TreeM *F)
194{
195        Poly *f,*g;
196        int g1,f1;
197
198        if (x->root) return 1;
199 
200        g=is_present(T,x->history); //it's a prolongation - do we have a parent ?
201
202        if (!g)  return 0; //if not - kill him !
203
204        poly lmX=pDivide(x->lead,g->root);
205        pSetCoeff(lmX,nInit(1));
206
207/*      if ((f=is_div_(F,lmX)) != NULL)
208        {
209                int pX=pow_(lmX);
210                int phX=pow_(x->history);
211
212                if (pX!=phX)
213                {
214                        int phF=pow_(f->history);
215                        if (pX >= (phX+phF))
216                        {
217                                pLmDelete(&lmX);
218                                //x->root=NULL;
219                                return 0;
220                        }
221
222                        for(int i=0, gg=0 ; i<currRing->N;i++)
223                                if ((g1=pGetExp(x->history,i+1)) > (f1=pGetExp(f->history,i+1)))
224                                        gg+=g1;
225                                else gg+=f1; 
226
227                        if (pX > gg)
228                        {
229                                pLmDelete(&lmX);
230                                //x->root=NULL;
231                                return 0;
232                        }
233                        int pF=pow_(f->root);
234
235                        if ((pX == pF) && (pF == phF))
236                                f->history=x->history;
237                }
238        }
239
240        pLmDelete(&lmX);
241
242*/      x->root=pCopy(g->root);
243
244        x->root=pMult(lmX,x->root);
245
246        pTest(x->root);
247
248        x->prolonged=-1;
249
250        return 1;
251}
252
253Poly *NewPoly(poly p)
254{
255        Poly *beg=(Poly *)GCM(sizeof(Poly));
256
257        beg->root=p;//(p == NULL ? pInit() : p);
258        beg->history=NULL;//pInit();
259        beg->lead=NULL;
260        beg->mult=(char *)GCMA(sizeof(char)*2*offset);
261
262        for (int i=0; i < currRing->N; i++)
263        {
264                ClearMult(beg,i);
265                ClearProl(beg,i);
266        };
267
268        beg->prolonged=-1;
269
270        return beg;
271}
272
273void DestroyPoly(Poly *x)
274{
275        pDelete(&x->root);
276        pDelete(&x->history);
277        if (x->lead) pDelete(&x->lead);
278        GCF(x->mult);
279        GCF(x);
280}
281
282void ControlProlong(Poly *x)
283{
284        for (int i = 0; i< offset; i++)
285        {
286                (x->mult+offset)[i]&=~((x->mult)[i]);
287//              if (!GetMult(x,i) && !GetProl(x,i))
288//                      ProlVar(x,i);
289        }
290}
291
292void InitHistory(Poly *p)
293{
294        if (p->history) pDelete(&p->history);
295        p->history=pLmInit(p->root);
296        p->changed=0;
297}
298
299void InitLead(Poly *p)
300{
301        if (p->lead) pDelete(&p->lead);
302        p->lead=pLmInit(p->root);
303        p->prolonged=-1;
304}
305
306void InitProl(Poly *p)
307{
308        memset(p->mult+offset,0,sizeof(char)*offset);
309}
310
311int GetMult(Poly *x,int i)
312{
313        return x->mult[i/8] & Mask[i%8];
314}
315
316void SetMult(Poly *x,int i)
317{
318        x->mult[i/8] |= Mask[i%8];
319}
320
321void ClearMult(Poly *x,int i)
322{
323        x->mult[i/8] &= ~Mask[i%8];
324}
325
326int GetProl(Poly *x, int i)
327{
328        return (x->mult+offset)[i/8] & Mask[i%8];
329}
330
331void SetProl(Poly *x, int i)
332{
333        (x->mult+offset)[i/8] |= Mask[i%8];
334}
335
336void ClearProl(Poly *x, int i)
337{
338        (x->mult+offset)[i/8] &= ~Mask[i%8];
339}
340
341int LengthCompare(poly p1,poly p2)
342{
343        do
344        {
345                if (p1 == NULL) return 1;
346                if (p2 == NULL) return 0;
347                pIter(p1);
348                pIter(p2);
349        }while(p1 && p2);
350        return 1;
351}
352
353int ProlCompare(Poly *item1, Poly *item2)
354{
355        switch(pLmCmp(item1->lead,item2->lead))
356        {
357                case -1:
358                        return 1;
359
360                case 1: 
361                        return 0;
362
363                default:
364                        return LengthCompare(item1->root,item2->root);
365        }
366}
367
368void ProlVar(Poly *temp,int i)
369{
370        Poly *Pr;
371
372        if (!GetProl(temp,i) && !GetMult(temp,i))
373        {
374                Pr=NewPoly();
375                SetProl(temp,i);
376
377                Pr->prolonged=i;
378                Pr->history=pLmInit(temp->history);
379                Pr->lead=pLmInit(temp->lead);
380                pIncrExp(Pr->lead,i+1);
381                pSetm(Pr->lead);
382                InitProl(temp);
383
384                Pr->changed=0;
385//              pTest(Pr->root);
386                InsertInCount(Q,Pr);
387        }
388}
389
390void DestroyListNode(ListNode *x)
391{
392        DestroyPoly(x->info);
393        GCF(x);
394}
395
396ListNode* CreateListNode(Poly *x)
397{
398        ListNode* ret=(ListNode *)GCM(sizeof(ListNode));
399        ret->info=x;
400        ret->next=NULL;
401        return ret;
402}
403
404
405Poly *FindMinList(jList *L)
406{
407        LI min=&(L->root);
408        LI l;
409        LCI xl;
410        Poly *x;
411
412        if (degree_compatible)
413        {
414                while ((*min) && ((*min)->info->root == NULL))
415                        min=&((*min)->next);           
416        }
417
418        if (!(*min)) return NULL;
419
420        l=&((*min)->next);
421 
422        while (*l)
423        {
424                if ((*l)->info->root != NULL)
425                {
426                        if (ProlCompare((*l)->info,(*min)->info))
427                                min=l;
428                }
429               
430                l=&((*l)->next);
431        }
432        x=(*min)->info;
433        xl=*min;
434        *min=(*min)->next;
435        GCF(xl);
436 
437        return x;
438}
439
440void InsertInList(jList *x,Poly *y)
441{
442        ListNode *ins;
443        LI ix=&(x->root);
444
445        while (*ix)
446        {
447                if (pLmCmp(y->lead,(*ix)->info->lead) == -1) 
448                        ix=(ListNode **)&((*ix)->next);
449                else 
450                        break;
451        }
452
453        ins=CreateListNode(y);
454        ins->next=(ListNode *)(*ix);
455        *ix=ins;
456        return;
457}
458
459void InsertInCount(jList *x,Poly *y)
460{
461        ListNode *ins;
462        LI ix=&(x->root);
463 
464        ins=CreateListNode(y);
465        ins->next=(ListNode *)(*ix);
466        *ix=ins;
467        return;
468}
469
470int ListGreatMoveOrder(jList *A,jList *B,poly x)
471{
472        LCI y=A->root;
473
474        if (!y || pLmCmp(y->info->lead,x) < 0) return 0;
475
476        while(y && pLmCmp(y->info->lead,x) >= 0)
477        {
478                InsertInCount(B,y->info);
479                A->root=y->next;
480                GCF(y);
481                y=A->root;
482        }
483 
484        return 1;
485}
486
487int ListGreatMoveDegree(jList *A,jList *B,poly x)
488{
489        LCI y=A->root;
490        int pow_x=pow_(x);
491
492        if (!y || pow_(y->info->lead) <= pow_x) return 0;
493
494        while(y && pow_(y->info->lead) > pow_x)
495        {
496                InsertInCount(B,y->info);
497                A->root=y->next;
498                GCF(y);
499                y=A->root;
500        }
501 
502        return 1;
503}
504
505int CountList(jList *Q)
506{
507        int i=0;
508        LCI y=Q->root;
509 
510        while(y)
511        {
512                i++;
513                y=y->next;
514        }
515 
516        return i;
517}
518
519void NFListQ()
520{
521        LCI ll;
522        int p,p1;
523        LI l;
524 
525        do
526        {
527                if (!Q->root) break;
528
529                ll=Q->root;
530 
531                p=pow_(Q->root->info->lead);
532 
533                while (ll)
534                {
535                        int ploc=pow_(ll->info->lead);
536                        if (ploc < p) p=ploc;
537                        ll=ll->next;
538                }
539 
540                p1=1;
541
542                l=&(Q->root);
543 
544                while (*l)
545                { 
546//                      Print("*");
547                        int ploc=pow_((*l)->info->lead);
548
549                        if (ploc == p)
550                        {
551                                if (!ValidatePoly((*l)->info,G))
552                                {
553                                        ll=(*l);
554                                        *l=(*l)->next;
555                                        DestroyListNode(ll);
556                                        continue;
557                                };
558
559                                (*l)->info->changed=0;
560//                              Print("!");
561                                NFL((*l)->info,G);
562//                                Print("$");
563                                if (!(*l)->info->root)
564                                {
565                                        ll=(*l);
566                                        *l=(*l)->next;
567                                        DestroyListNode(ll);
568                                        continue;
569                                };
570                                p1=0;
571                        }
572
573                        l=&((*l)->next);
574                }
575        }while(p1);
576//      Print("\n");
577}
578
579
580void ForEachPNF(jList *x,int i)
581{
582        LCI y=x->root;
583
584        while(y)
585        {
586                if (pow_(y->info->root) == i) PNF(y->info,G);
587                y=y->next;
588        }
589}
590
591void ForEachControlProlong(jList *x)
592{
593        LCI y=x->root;
594
595        while(y)
596        {
597                ControlProlong(y->info);
598                y=y->next;
599        }
600}
601
602void DestroyList(jList *x)
603{
604        LCI y=x->root,z;
605
606        while(y)
607        {
608                z=y->next;
609                DestroyPoly(y->info);
610                GCF(y);
611                y=z;
612        }
613
614        GCF(x);
615}
616
617Poly* is_present(jList *F,poly x)
618{
619        LCI iF=F->root;
620        while(iF)
621                if (pLmCmp(iF->info->root,x) == 0)
622                        return iF->info;
623                else iF=iF->next;
624
625        return NULL;
626}
627
628int GB_length()
629{
630        LCI iT=T->root;
631        int l=0;
632 
633        while(iT) 
634        {
635                if (pow_(iT->info->lead) == pow_(iT->info->history))
636                        ++l;
637                iT=iT->next;
638        }
639       
640        return l;
641}
642
643static Poly *temp_l;
644
645NodeM* create()
646{
647        NodeM *y;
648
649        if (FreeNodes == NULL)
650        {
651                y=(NodeM *)GCM(sizeof(NodeM));
652        }
653        else
654        {
655                y=FreeNodes;
656                FreeNodes=FreeNodes->left;
657        }
658       
659        y->left=y->right=NULL;
660        y->ended=NULL;
661        return y;
662}
663
664void DestroyFreeNodes()
665{
666        NodeM *y;
667   
668        while((y=FreeNodes)!=NULL)
669        {
670                FreeNodes=FreeNodes->left;
671                GCF(y);
672        }
673}
674
675static void go_right(NodeM *current,poly_function disp)
676{
677        if (current)
678        {
679                go_right(current->left,disp);
680                if (current->ended) disp(current->ended);
681                go_right(current->right,disp);
682        }
683}
684
685void ForEach(TreeM *t,poly_function disp)
686{
687        go_right(t->root,disp);
688}
689
690void DestroyTree(NodeM *G)
691{
692        if (G)
693        {
694                DestroyTree(G->left);
695                DestroyTree(G->right);
696                G->left=FreeNodes;
697                FreeNodes=G;
698        }
699}
700
701void Define(TreeM **G)
702{
703        *G=(TreeM *)GCM(sizeof(TreeM));
704        (*G)->root=create();
705}
706
707int sp_div(poly m1,poly m2,int from)
708{
709
710        if (pow_(m2) == 0 && pow_(m1)) return 0;
711
712        for(int k=from; k < currRing->N; k++)
713                if (pGetExp(m1,k+1) < pGetExp(m2,k+1)) return 0;
714
715        return 1;
716}
717
718void div_l(poly item, NodeM *x,int from)
719{
720        if (x && !temp_l)
721        { 
722                div_l(item,x->left,from);
723                if ((x->ended) && sp_div(item,x->ended->root,from))
724                {
725                        temp_l=x->ended;
726                        return;
727                };
728                div_l(item,x->right,from);
729        }
730}
731
732Poly* is_div_upper(poly item, NodeM *x,int from)
733{
734        temp_l=NULL;
735        div_l(item,x,from);
736        return temp_l;
737}
738
739Poly* is_div_(TreeM *tree, poly item)
740{
741        int power_tmp,i,i_con=currRing->N-1;
742        NodeM *curr=tree->root;
743
744        if (!curr) return NULL;
745        if (pow_(item) == 0) return NULL;
746
747        for ( ; i_con>=0 && !pGetExp(item,i_con+1) ; i_con--)
748                ;
749
750        for (i=0; i <= i_con ; i++)
751        {
752                power_tmp=pGetExp(item,i+1);
753
754                while (power_tmp)
755                {
756                        if (curr->ended) return curr->ended;
757
758                        if (!curr->left) 
759                        {
760                                if (curr->right) 
761                                        return is_div_upper(item,curr->right,i); //??????
762                                return NULL;
763                        };
764     
765                        curr=curr->left;
766                        power_tmp--;
767                };
768
769                if (curr->ended) return curr->ended;
770
771                if (!curr->right) return NULL;
772
773                curr=curr->right;
774        }
775
776        if (curr->ended) return curr->ended;
777        else return NULL;
778}
779
780static void ClearMultiplicative(NodeM *xx,int i)
781{
782        if (!xx) return;
783 
784        while (xx->left) 
785        {
786                ClearMultiplicative(xx->right, i);
787                xx = xx->left;
788        }
789        if ((xx->ended) && (GetMult(xx->ended,i)))
790        {
791                ClearMult(xx->ended,i);
792                ProlVar(xx->ended,i);
793        }
794        else
795                ClearMultiplicative(xx->right,i);
796}
797//======================================================
798void insert_(TreeM **tree, Poly *item)
799{
800 int power_tmp,i,i_con=currRing->N-1;
801 NodeM *curr=(*tree)->root;
802 
803 for ( ; (i_con>=0) && !pGetExp(item->root,i_con+1) ; i_con--)
804  SetMult(item,i_con);
805 
806 for (i = 0; i<= i_con; i++)
807 //<=
808 {
809  power_tmp=pGetExp(item->root,i+1);
810
811  ClearMult(item,i);
812
813  while (power_tmp)
814  {
815   if (!curr->left)
816   {   
817     SetMult(item,i);
818     ClearMultiplicative(curr->right,i);
819     curr->left=create();
820   };
821   curr=curr->left;
822   power_tmp--;
823  };
824
825  if (i<i_con)
826  {
827   if (!curr->left) SetMult(item,i);
828   if (!curr->right) curr->right=create();
829   curr=curr->right;
830
831   ProlVar(item,i);
832  }
833 }
834
835 curr->ended=item;
836}
837
838void Initialization(char *Ord)
839{
840  ProdCrit=0;
841  ChainCrit=0;
842  offset=(currRing->N % 8 == 0) ? (currRing->N/8)*8 : (currRing->N/8+1)*8;
843  if (strstr(Ord,"dp\0") || strstr(Ord,"Dp\0"))
844  {
845    degree_compatible=1;
846    ListGreatMove=ListGreatMoveDegree;
847  }
848  else
849  {
850    degree_compatible=0;
851    ListGreatMove=ListGreatMoveOrder;
852  }
853 
854  Define(&G);
855};
856
857static Poly *h,*f;
858
859void insert_in_G(Poly *x)
860{
861 insert_(&G,x);
862}
863
864void T2G();
865
866void Q2TG()
867{
868        LCI t;
869        Poly *x;
870
871        while (Q->root)
872        {
873                t=Q->root;
874                x=t->info;
875                insert_(&G,x);
876                InsertInList(T,x);
877                Q->root=t->next;
878                GCF(t);
879        }
880}
881
882int ComputeBasis(jList *_T, jList *_Q)
883{
884  int gb_l,i,ret_value=1;
885
886  T=_T; Q=_Q;
887
888  //  Debug();
889
890  while( (h=FindMinList(Q)) != NULL )
891  {
892 
893    //  Print("New element\n");
894    //  Debug();
895
896    if (!degree_compatible)
897    {
898      if (!ValidatePoly(h,G))
899      {
900        DestroyPoly(h);
901        continue;
902      };
903     
904      h->changed=0;
905     
906      NFL(h,G);
907     
908      if (!h->root)
909      {
910        DestroyPoly(h);
911        continue;
912      };
913    }
914
915    if (h->root)
916    {
917      if (pIsConstant(h->root))
918      {
919        // WarnS("Constant in basis\n");
920        return 0;
921      }
922     
923      if (h->changed && ListGreatMove(T,Q,h->root))
924      {
925        // Print("<-\n");
926        DestroyTree(G->root);
927        G->root=create();
928        T2G();
929      }
930    }
931   
932    //  Print("PNF\n");
933    PNF(h,G);
934    if (TEST_OPT_PROT)
935    {
936      Print("s%d",pow_(h->root));
937    }
938    insert_(&G,h);
939    InsertInList(T,h);
940   
941    //  Print("For each PNF\n");
942    if (degree_compatible)
943      ForEachPNF(T,pow_(h->root));
944   
945    //  Print("Control of prolongations\n");
946    if (h->changed)
947      ForEachControlProlong(T);
948    else
949      ControlProlong(h);
950   
951    //  Debug();
952   
953    //  Print("NFListQ\n");
954    if (degree_compatible)
955      NFListQ();
956    //Debug();
957  }
958 
959  //    gb_l=GB_length();
960 
961  if (TEST_OPT_PROT)
962  {
963    Print("\nLength of Janet basis: %d", CountList(T));
964    Print("\nproduct criterion:%d chain criterion:%d\n", ProdCrit, ChainCrit);
965    //    Print("Length of Groebner basis:    %d\n",gb_l);
966  }
967 
968  DestroyTree(G->root);
969  GCF(G);
970  DestroyFreeNodes();
971 
972  return 1;
973}
974
975void T2G()
976{
977 LCI i=T->root;
978 while (i)
979 {
980  insert_(&G,i->info);
981  i=i->next;
982 }
983}
Note: See TracBrowser for help on using the repository browser.