source: git/Singular/mpr_inout.cc @ bad9f3

spielwiese
Last change on this file since bad9f3 was bad9f3, checked in by Wilfred Pohl <pohl@…>, 23 years ago
change setGMPFloatDigits git-svn-id: file:///usr/local/Singular/svn/trunk@4959 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 17.0 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4
5/* $Id: mpr_inout.cc,v 1.12 2000-12-20 10:54:25 pohl Exp $ */
6
7/*
8* ABSTRACT - multipolynomial resultant
9*/
10
11#include "mod2.h"
12//#ifdef HAVE_MPR
13
14//-> includes
15#include "tok.h"
16#include "structs.h"
17#include "subexpr.h"
18#include "polys.h"
19#include "ideals.h"
20#include "ring.h"
21#include "ipid.h"
22#include "ipshell.h"
23#include "febase.h"
24#include "omalloc.h"
25#include "numbers.h"
26#include "lists.h"
27#include "matpol.h"
28
29#include <math.h>
30
31#include "mpr_global.h"
32#include "mpr_inout.h"
33#include "mpr_base.h"
34#include "mpr_numeric.h"
35
36// to get detailed timigs, define MPR_TIMING
37#ifdef MPR_TIMING
38#define TIMING
39#endif
40#include "../factory/timing.h"
41TIMING_DEFINE_PRINT(mpr_overall)
42TIMING_DEFINE_PRINT(mpr_check)
43TIMING_DEFINE_PRINT(mpr_constr)
44TIMING_DEFINE_PRINT(mpr_ures)
45TIMING_DEFINE_PRINT(mpr_mures)
46TIMING_DEFINE_PRINT(mpr_arrange)
47TIMING_DEFINE_PRINT(mpr_solver)
48
49#define TIMING_EPR(t,msg) TIMING_END_AND_PRINT(t,msg);TIMING_RESET(t);
50
51enum mprState
52{
53    mprOk,
54    mprWrongRType,
55    mprHasOne,
56    mprInfNumOfVars,
57    mprNotReduced,
58    mprNotZeroDim,
59    mprNotHomog,
60    mprUnSupField
61};
62
63extern size_t gmp_output_digits;
64//<-
65
66//-> nPrint(number n)
67void nPrint(number n)
68{
69  poly o=pOne();
70  pSetCoeff(o, nCopy(n) );
71  pWrite0( o );
72  pDelete( &o );
73}
74//<-
75
76//------------------------------------------------------------------------------
77
78//-> void mprPrintError( mprState state )
79void mprPrintError( mprState state, const char * name )
80{
81  switch (state)
82  {
83  case mprWrongRType:
84    WerrorS("Unknown resultant matrix type choosen!");
85    break;
86  case mprHasOne:
87    Werror("One element of the ideal %s is constant!",name);
88    break;
89  case mprInfNumOfVars:
90    Werror("Numer of elements in given ideal %s must be equal to %d!",
91           name,pVariables+1);
92    break;
93  case mprNotZeroDim:
94    Werror("The given ideal %s must 0-dimensional!",name);
95    break;
96  case mprNotHomog:
97    Werror("The given ideal %s has to be homogeneous in"
98           " the first ring variable!",name);
99    break;
100  case mprNotReduced:
101    Werror("The given ideal %s has to reduced!",name);
102    break;
103  case mprUnSupField:
104    WerrorS("Ground field not implemented!");
105    break;
106  default:
107    break;
108  }
109}
110//<-
111
112//-> mprState mprIdealCheck()
113mprState mprIdealCheck( const ideal theIdeal,
114                        const char * name,
115                        uResultant::resMatType mtype,
116                        BOOLEAN rmatrix= false )
117{
118  mprState state = mprOk;
119  int power;
120  int k;
121
122  int numOfVars= mtype == uResultant::denseResMat?pVariables-1:pVariables;
123  if ( rmatrix ) numOfVars++;
124
125  if ( mtype == uResultant::none )
126    state= mprWrongRType;
127
128  if ( IDELEMS(theIdeal) != numOfVars )
129    state= mprInfNumOfVars;
130
131  for ( k= IDELEMS(theIdeal) - 1; (state == mprOk) && (k >= 0); k-- )
132  {
133    poly p = (theIdeal->m)[k];
134    if ( pIsConstant(p) ) state= mprHasOne;
135    else
136    if ( (mtype == uResultant::denseResMat) && !pIsHomogeneous(p) )
137      state=mprNotHomog;
138  }
139
140  if ( !(rField_is_R()||
141         rField_is_Q()||
142         rField_is_long_R()||
143         rField_is_long_C()||
144         (rmatrix && rField_is_Q_a())) )
145    state= mprUnSupField;
146
147  if ( state != mprOk ) mprPrintError( state, "" /* name */ );
148
149  return state;
150}
151//<-
152
153//-> uResultant::resMatType determineMType( int imtype )
154uResultant::resMatType determineMType( int imtype )
155{
156  switch ( imtype )
157  {
158  case MPR_DENSE:
159    return uResultant::denseResMat;
160  case 0:
161  case MPR_SPARSE:
162    return uResultant::sparseResMat;
163  default:
164    return uResultant::none;
165  }
166}
167//<-
168
169//-> BOOLEAN nuUResSolve( leftv res, leftv args )
170BOOLEAN nuUResSolve( leftv res, leftv args )
171{
172  leftv v= args;
173
174  ideal gls;
175  int imtype;
176  int howclean;
177
178  // get ideal
179  if ( v->Typ() != IDEAL_CMD )
180    return TRUE;
181  else gls= (ideal)(v->Data());
182  v= v->next;
183
184  // get resultant matrix type to use (0,1)
185  if ( v->Typ() != INT_CMD )
186    return TRUE;
187  else imtype= (int)v->Data();
188  v= v->next;
189
190  // get and set precision in digits ( > 0 )
191  if ( v->Typ() != INT_CMD )
192    return TRUE;
193  else if ( !(rField_is_R()||rField_is_long_R()||rField_is_long_C()) )
194  {
195    unsigned long int ii=(unsigned long int)v->Data();
196    setGMPFloatDigits( ii, ii );
197  }
198  v= v->next;
199
200  // get interpolation steps (0,1,2)
201  if ( v->Typ() != INT_CMD )
202    return TRUE;
203  else howclean= (int)v->Data();
204
205  uResultant::resMatType mtype= determineMType( imtype );
206  int i,c,count;
207  lists listofroots= NULL;
208  lists emptylist;
209  number smv= NULL;
210  BOOLEAN interpolate_det= (mtype==uResultant::denseResMat)?TRUE:FALSE;
211
212  //emptylist= (lists)omAlloc( sizeof(slists) );
213  //emptylist->Init( 0 );
214
215  //res->rtyp = LIST_CMD;
216  //res->data= (void *)emptylist;
217
218  TIMING_START(mpr_overall);
219
220  // check input ideal ( = polynomial system )
221  if ( mprIdealCheck( gls, args->Name(), mtype ) != mprOk )
222  {
223    return TRUE;
224  }
225
226  uResultant * ures;
227  rootContainer ** iproots;
228  rootContainer ** muiproots;
229  rootArranger * arranger;
230
231  // main task 1: setup of resultant matrix
232  TIMING_START(mpr_constr);
233  ures= new uResultant( gls, mtype );
234  if ( ures->accessResMat()->initState() != resMatrixBase::ready )
235  {
236    WerrorS("Error occurred during matrix setup!");
237    return TRUE;
238  }
239  TIMING_EPR(mpr_constr, "construction\t\t")
240
241  // if dense resultant, check if minor nonsingular
242  TIMING_START(mpr_check);
243  if ( mtype == uResultant::denseResMat )
244  {
245    smv= ures->accessResMat()->getSubDet();
246#ifdef mprDEBUG_PROT
247    PrintS("// Determinant of submatrix: ");nPrint(smv);PrintLn();
248#endif
249    if ( nIsZero(smv) )
250    {
251      WerrorS("Unsuitable input ideal: Minor of resultant matrix is singular!");
252      return TRUE;
253    }
254  }
255  TIMING_EPR(mpr_check,  "input check\t\t")
256
257  // main task 2: Interpolate specialized resultant polynomials
258  TIMING_START(mpr_ures);
259  if ( interpolate_det )
260    iproots= ures->interpolateDenseSP( false, smv );
261  else
262    iproots= ures->specializeInU( false, smv );
263  TIMING_EPR(mpr_ures,   "interpolation ures\t")
264
265  // main task 3: Interpolate specialized resultant polynomials
266  TIMING_START(mpr_mures);
267  if ( interpolate_det )
268    muiproots= ures->interpolateDenseSP( true, smv );
269  else
270    muiproots= ures->specializeInU( true, smv );
271  TIMING_EPR(mpr_mures,  "interpolation mures\t")
272
273#ifdef mprDEBUG_PROT
274  c= iproots[0]->getAnzElems();
275  for (i=0; i < c; i++) pWrite(iproots[i]->getPoly());
276  c= muiproots[0]->getAnzElems();
277  for (i=0; i < c; i++) pWrite(muiproots[i]->getPoly());
278#endif
279
280  // main task 4: Compute roots of specialized polys and match them up
281  arranger= new rootArranger( iproots, muiproots, howclean );
282  TIMING_START(mpr_solver);
283  arranger->solve_all();
284  TIMING_EPR(mpr_solver, "solver time\t\t");
285
286  // get list of roots
287  if ( arranger->success() )
288  {
289    TIMING_START(mpr_arrange);
290    arranger->arrange();
291    TIMING_EPR(mpr_arrange, "arrange time\t\t");
292    listofroots= arranger->listOfRoots( gmp_output_digits );
293  }
294  else
295  {
296    WerrorS("Solver was unable to find any roots!");
297    return TRUE;
298  }
299
300  // free everything
301  count= iproots[0]->getAnzElems();
302  for (i=0; i < count; i++) delete iproots[i];
303  omFreeSize( (ADDRESS) iproots, count * sizeof(rootContainer*) );
304  count= muiproots[0]->getAnzElems();
305  for (i=0; i < count; i++) delete muiproots[i];
306  omFreeSize( (ADDRESS) muiproots, count * sizeof(rootContainer*) );
307
308  delete ures;
309  delete arranger;
310  nDelete( &smv );
311
312  res->data= (void *)listofroots;
313
314  //emptylist->Clean();
315  //  omFreeSize( (ADDRESS) emptylist, sizeof(slists) );
316
317  TIMING_EPR(mpr_overall,"overall time\t\t")
318
319  return FALSE;
320}
321//<-
322
323//-> BOOLEAN nuMPResMat( leftv res, leftv arg1, leftv arg2 )
324BOOLEAN nuMPResMat( leftv res, leftv arg1, leftv arg2 )
325{
326  ideal gls = (ideal)(arg1->Data());
327  int imtype= (int)arg2->Data();
328
329  uResultant::resMatType mtype= determineMType( imtype );
330
331  // check input ideal ( = polynomial system )
332  if ( mprIdealCheck( gls, arg1->Name(), mtype, true ) != mprOk )
333  {
334    return TRUE;
335  }
336
337  uResultant *resMat= new uResultant( gls, mtype, false );
338
339  res->rtyp = MODUL_CMD;
340  res->data= (void*)resMat->accessResMat()->getMatrix();
341
342  delete resMat;
343
344  return FALSE;
345}
346//<-
347
348//-> BOOLEAN nuLagSolve( leftv res, leftv arg1, leftv arg2, leftv arg3 )
349BOOLEAN nuLagSolve( leftv res, leftv arg1, leftv arg2, leftv arg3 )
350{
351
352  poly gls;
353  gls= (poly)(arg1->Data());
354  int howclean= (int)arg3->Data();
355
356  if ( !(rField_is_R() ||
357         rField_is_Q() ||
358         rField_is_long_R() ||
359         rField_is_long_C()) )
360  {
361    WerrorS("Ground field not implemented!");
362    return TRUE;
363  }
364
365  if ( !(rField_is_R()||rField_is_long_R()||rField_is_long_C()) )
366  {
367    unsigned long int ii = (unsigned long int)arg2->Data();
368    setGMPFloatDigits( ii, ii );
369  }
370
371  if ( gls == NULL || pIsConstant( gls ) )
372  {
373    WerrorS("Input polynomial is constant!");
374    return TRUE;
375  }
376
377  int deg= pTotaldegree( gls );
378  //  int deg= pDeg( gls );
379  int len= pLength( gls );
380  int i,vpos;
381  poly piter;
382  lists elist;
383  lists rlist;
384
385  elist= (lists)omAlloc( sizeof(slists) );
386  elist->Init( 0 );
387
388  if ( pVariables > 1 )
389  {
390    piter= gls;
391    for ( i= 1; i <= pVariables; i++ )
392      if ( pGetExp( piter, i ) )
393      {
394        vpos= i;
395        break;
396      }
397    while ( piter )
398    {
399      for ( i= 1; i <= pVariables; i++ )
400        if ( (vpos != i) && (pGetExp( piter, i ) != 0) )
401        {
402          WerrorS("The input polynomial must be univariate!");
403          return TRUE;
404        }
405      pIter( piter );
406    }
407  }
408
409  rootContainer * roots= new rootContainer();
410  number * pcoeffs= (number *)omAlloc( (deg+1) * sizeof( number ) );
411  piter= gls;
412  for ( i= deg; i >= 0; i-- )
413  {
414    //if ( piter ) Print("deg %d, pDeg(piter) %d\n",i,pTotaldegree(piter));
415    if ( piter && pTotaldegree(piter) == i )
416    {
417      pcoeffs[i]= nCopy( pGetCoeff( piter ) );
418      //nPrint( pcoeffs[i] );PrintS("  ");
419      pIter( piter );
420    }
421    else
422    {
423      pcoeffs[i]= nInit(0);
424    }
425  }
426
427#ifdef mprDEBUG_PROT
428  for (i=deg; i >= 0; i--)
429  {
430    nPrint( pcoeffs[i] );PrintS("  ");
431  }
432  PrintLn();
433#endif
434
435  TIMING_START(mpr_solver);
436  roots->fillContainer( pcoeffs, NULL, 1, deg, rootContainer::onepoly, 1 );
437  roots->solver( howclean );
438  TIMING_EPR(mpr_solver, "solver time\t\t");
439
440  int elem= roots->getAnzRoots();
441  char *out;
442  char *dummy;
443  int j;
444
445  rlist= (lists)omAlloc( sizeof(slists) );
446  rlist->Init( elem );
447
448  if (rField_is_long_C())
449  {
450    for ( j= 0; j < elem; j++ )
451    {
452      rlist->m[j].rtyp=NUMBER_CMD;
453      rlist->m[j].data=(void *)nCopy((number)(roots->getRoot(j)));
454      //rlist->m[j].data=(void *)(number)(roots->getRoot(j));
455    }
456  }
457  else
458  {
459    for ( j= 0; j < elem; j++ )
460    {
461      dummy = complexToStr( (*roots)[j], gmp_output_digits );
462      rlist->m[j].rtyp=STRING_CMD;
463      rlist->m[j].data=(void *)dummy;
464    }
465  }
466
467  elist->Clean();
468  //omFreeSize( (ADDRESS) elist, sizeof(slists) );
469
470  for ( i= deg; i >= 0; i-- ) nDelete( &pcoeffs[i] );
471  omFreeSize( (ADDRESS) pcoeffs, (deg+1) * sizeof( number ) );
472
473  res->rtyp= LIST_CMD;
474  res->data= (void*)rlist;
475
476  return FALSE;
477}
478//<-
479
480//-> BOOLEAN nuVanderSys( leftv res, leftv arg1, leftv arg2 )
481BOOLEAN nuVanderSys( leftv res, leftv arg1, leftv arg2, leftv arg3)
482{
483  int i;
484  ideal p,w;
485  p= (ideal)arg1->Data();
486  w= (ideal)arg2->Data();
487
488  // w[0] = f(p^0)
489  // w[1] = f(p^1)
490  // ...
491  // p can be a vector of numbers (multivariate polynom)
492  //   or one number (univariate polynom)
493  // tdg = deg(f)
494
495  int n= IDELEMS( p );
496  int m= IDELEMS( w );
497  int tdg= (int)arg3->Data();
498
499  res->data= (void*)NULL;
500
501  // check the input
502  if ( tdg < 1 )
503  {
504    WerrorS("Last input parameter must be > 0!");
505    return TRUE;
506  }
507  if ( n != pVariables )
508  {
509    Werror("Size of first input ideal must be equal to %d!",pVariables);
510    return TRUE;
511  }
512  if ( m != (int)pow((double)tdg+1,(int)n) )
513  {
514    Werror("Size of second input ideal must be equal to %d!",
515      (int)pow((double)tdg+1,(int)n));
516    return TRUE;
517  }
518  if ( !(rField_is_Q() /* ||
519         rField_is_R() || rField_is_long_R() ||
520         rField_is_long_C()*/ ) )
521         {
522    WerrorS("Ground field not implemented!");
523    return TRUE;
524  }
525
526  number tmp;
527  number *pevpoint= (number *)omAlloc( n * sizeof( number ) );
528  for ( i= 0; i < n; i++ )
529  {
530    pevpoint[i]=nInit(0);
531    if (  (p->m)[i] )
532    {
533      tmp = pGetCoeff( (p->m)[i] );
534      if ( nIsZero(tmp) || nIsOne(tmp) || nIsMOne(tmp) )
535      {
536        omFreeSize( (ADDRESS)pevpoint, n * sizeof( number ) );
537        WerrorS("Elements of first input ideal must not be equal to -1, 0, 1!");
538        return TRUE;
539      }
540    } else tmp= NULL;
541    if ( !nIsZero(tmp) )
542    {
543      if ( !pIsConstant((p->m)[i]))
544      {
545        omFreeSize( (ADDRESS)pevpoint, n * sizeof( number ) );
546        WerrorS("Elements of first input ideal must be numbers!");
547        return TRUE;
548      }
549      pevpoint[i]= nCopy( tmp );
550    }
551  }
552
553  number *wresults= (number *)omAlloc( m * sizeof( number ) );
554  for ( i= 0; i < m; i++ )
555  {
556    wresults[i]= nInit(0);
557    if ( (w->m)[i] && !nIsZero(pGetCoeff((w->m)[i])) )
558    {
559      if ( !pIsConstant((w->m)[i]))
560      {
561        omFreeSize( (ADDRESS)pevpoint, n * sizeof( number ) );
562        omFreeSize( (ADDRESS)wresults, m * sizeof( number ) );
563        WerrorS("Elements of second input ideal must be numbers!");
564        return TRUE;
565      }
566      wresults[i]= nCopy(pGetCoeff((w->m)[i]));
567    }
568  }
569
570  vandermonde vm( m, n, tdg, pevpoint, FALSE );
571  number *ncpoly= vm.interpolateDense( wresults );
572  // do not free ncpoly[]!!
573  poly rpoly= vm.numvec2poly( ncpoly );
574
575  omFreeSize( (ADDRESS)pevpoint, n * sizeof( number ) );
576  omFreeSize( (ADDRESS)wresults, m * sizeof( number ) );
577
578  res->data= (void*)rpoly;
579  return FALSE;
580}
581//<-
582
583//-> function u_resultant_det
584poly u_resultant_det( ideal gls, int imtype )
585{
586  uResultant::resMatType mtype= determineMType( imtype );
587  poly resdet;
588  poly emptypoly= pInit();
589  number smv= NULL;
590
591  TIMING_START(mpr_overall);
592
593  // check input ideal ( = polynomial system )
594  if ( mprIdealCheck( gls, "", mtype ) != mprOk )
595  {
596    return emptypoly;
597  }
598
599  uResultant *ures;
600
601  // main task 1: setup of resultant matrix
602  TIMING_START(mpr_constr);
603  ures= new uResultant( gls, mtype );
604  TIMING_EPR(mpr_constr,"construction");
605
606  // if dense resultant, check if minor nonsingular
607  if ( mtype == uResultant::denseResMat )
608  {
609    smv= ures->accessResMat()->getSubDet();
610#ifdef mprDEBUG_PROT
611    PrintS("// Determinant of submatrix: ");nPrint(smv); PrintLn();
612#endif
613    if ( nIsZero(smv) )
614    {
615      WerrorS("Unsuitable input ideal: Minor of resultant matrix is singular!");
616      return emptypoly;
617    }
618  }
619
620  // main task 2: Interpolate resultant polynomial
621  TIMING_START(mpr_ures);
622  resdet= ures->interpolateDense( smv );
623  TIMING_EPR(mpr_ures,"ures");
624
625  // free mem
626  delete ures;
627  nDelete( &smv );
628  pDelete( &emptypoly );
629
630  TIMING_EPR(mpr_overall,"overall");
631
632  return ( resdet );
633}
634//<-
635
636//-> BOOLEAN loNewtonP( leftv res, leftv arg1 )
637BOOLEAN loNewtonP( leftv res, leftv arg1 )
638{
639  res->data= (void*)loNewtonPolytope( (ideal)arg1->Data() );
640  return FALSE;
641}
642//<-
643
644//-> BOOLEAN loSimplex( leftv res, leftv args )
645BOOLEAN loSimplex( leftv res, leftv args )
646{
647  if ( !(rField_is_long_R()) )
648  {
649    WerrorS("Ground field not implemented!");
650    return TRUE;
651  }
652
653  simplex * LP;
654  matrix m;
655
656  leftv v= args;
657  if ( v->Typ() != MATRIX_CMD ) // 1: matrix
658    return TRUE;
659  else
660    m= (matrix)(v->Data());
661
662  LP = new simplex(MATROWS(m),MATCOLS(m));
663  LP->mapFromMatrix(m);
664
665  v= v->next;
666  if ( v->Typ() != INT_CMD )    // 2: m = number of constraints
667    return TRUE;
668  else
669    LP->m= (int)(v->Data());
670
671  v= v->next;
672  if ( v->Typ() != INT_CMD )    // 3: n = number of variables
673    return TRUE;
674  else
675    LP->n= (int)(v->Data());
676
677  v= v->next;
678  if ( v->Typ() != INT_CMD )    // 4: m1 = number of <= constraints
679    return TRUE;
680  else
681    LP->m1= (int)(v->Data());
682
683  v= v->next;
684  if ( v->Typ() != INT_CMD )    // 5: m2 = number of >= constraints
685    return TRUE;
686  else
687    LP->m2= (int)(v->Data());
688
689  v= v->next;
690  if ( v->Typ() != INT_CMD )    // 6: m3 = number of == constraints
691    return TRUE;
692  else
693    LP->m3= (int)(v->Data());
694
695#ifdef mprDEBUG_PROT
696  Print("m (constraints) %d\n",LP->m);
697  Print("n (columns) %d\n",LP->n);
698  Print("m1 (<=) %d\n",LP->m1);
699  Print("m2 (>=) %d\n",LP->m2);
700  Print("m3 (==) %d\n",LP->m3);
701#endif
702
703  LP->compute();
704
705  lists lres= (lists)omAlloc( sizeof(slists) );
706  lres->Init( 6 );
707
708  lres->m[0].rtyp= MATRIX_CMD; // output matrix
709  lres->m[0].data=(void*)LP->mapToMatrix(m);
710
711  lres->m[1].rtyp= INT_CMD;   // found a solution?
712  lres->m[1].data=(void*)LP->icase;
713
714  lres->m[2].rtyp= INTVEC_CMD;
715  lres->m[2].data=(void*)LP->posvToIV();
716
717  lres->m[3].rtyp= INTVEC_CMD;
718  lres->m[3].data=(void*)LP->zrovToIV();
719
720  lres->m[4].rtyp= INT_CMD;
721  lres->m[4].data=(void*)LP->m;
722
723  lres->m[5].rtyp= INT_CMD;
724  lres->m[5].data=(void*)LP->n;
725
726  res->data= (void*)lres;
727
728  return FALSE;
729}
730//<-
731
732//-----------------------------------------------------------------------------
733
734//#endif // HAVE_MPR
735
736// local Variables: ***
737// folded-file: t ***
738// compile-command-1: "make installg" ***
739// compile-command-2: "make install" ***
740// End: ***
741
742// in folding: C-c x
743// leave fold: C-c y
744//   foldmode: F10
Note: See TracBrowser for help on using the repository browser.