source: git/Singular/mpr_inout.cc @ 0224c8

spielwiese
Last change on this file since 0224c8 was 93d305, checked in by Hans Schönemann <hannes@…>, 24 years ago
*hannes: minor fixes git-svn-id: file:///usr/local/Singular/svn/trunk@4641 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 16.9 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4
5/* $Id: mpr_inout.cc,v 1.11 2000-10-05 15:16:58 Singular 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    setGMPFloatDigits( (unsigned long int)v->Data() );
196  }
197  v= v->next;
198
199  // get interpolation steps (0,1,2)
200  if ( v->Typ() != INT_CMD )
201    return TRUE;
202  else howclean= (int)v->Data();
203
204  uResultant::resMatType mtype= determineMType( imtype );
205  int i,c,count;
206  lists listofroots= NULL;
207  lists emptylist;
208  number smv= NULL;
209  BOOLEAN interpolate_det= (mtype==uResultant::denseResMat)?TRUE:FALSE;
210
211  //emptylist= (lists)omAlloc( sizeof(slists) );
212  //emptylist->Init( 0 );
213
214  //res->rtyp = LIST_CMD;
215  //res->data= (void *)emptylist;
216
217  TIMING_START(mpr_overall);
218
219  // check input ideal ( = polynomial system )
220  if ( mprIdealCheck( gls, args->Name(), mtype ) != mprOk )
221  {
222    return TRUE;
223  }
224
225  uResultant * ures;
226  rootContainer ** iproots;
227  rootContainer ** muiproots;
228  rootArranger * arranger;
229
230  // main task 1: setup of resultant matrix
231  TIMING_START(mpr_constr);
232  ures= new uResultant( gls, mtype );
233  if ( ures->accessResMat()->initState() != resMatrixBase::ready )
234  {
235    WerrorS("Error occurred during matrix setup!");
236    return TRUE;
237  }
238  TIMING_EPR(mpr_constr, "construction\t\t")
239
240  // if dense resultant, check if minor nonsingular
241  TIMING_START(mpr_check);
242  if ( mtype == uResultant::denseResMat )
243  {
244    smv= ures->accessResMat()->getSubDet();
245#ifdef mprDEBUG_PROT
246    PrintS("// Determinant of submatrix: ");nPrint(smv);PrintLn();
247#endif
248    if ( nIsZero(smv) )
249    {
250      WerrorS("Unsuitable input ideal: Minor of resultant matrix is singular!");
251      return TRUE;
252    }
253  }
254  TIMING_EPR(mpr_check,  "input check\t\t")
255
256  // main task 2: Interpolate specialized resultant polynomials
257  TIMING_START(mpr_ures);
258  if ( interpolate_det )
259    iproots= ures->interpolateDenseSP( false, smv );
260  else
261    iproots= ures->specializeInU( false, smv );
262  TIMING_EPR(mpr_ures,   "interpolation ures\t")
263
264  // main task 3: Interpolate specialized resultant polynomials
265  TIMING_START(mpr_mures);
266  if ( interpolate_det )
267    muiproots= ures->interpolateDenseSP( true, smv );
268  else
269    muiproots= ures->specializeInU( true, smv );
270  TIMING_EPR(mpr_mures,  "interpolation mures\t")
271
272#ifdef mprDEBUG_PROT
273  c= iproots[0]->getAnzElems();
274  for (i=0; i < c; i++) pWrite(iproots[i]->getPoly());
275  c= muiproots[0]->getAnzElems();
276  for (i=0; i < c; i++) pWrite(muiproots[i]->getPoly());
277#endif
278
279  // main task 4: Compute roots of specialized polys and match them up
280  arranger= new rootArranger( iproots, muiproots, howclean );
281  TIMING_START(mpr_solver);
282  arranger->solve_all();
283  TIMING_EPR(mpr_solver, "solver time\t\t");
284
285  // get list of roots
286  if ( arranger->success() )
287  {
288    TIMING_START(mpr_arrange);
289    arranger->arrange();
290    TIMING_EPR(mpr_arrange, "arrange time\t\t");
291    listofroots= arranger->listOfRoots( gmp_output_digits );
292  }
293  else
294  {
295    WerrorS("Solver was unable to find any roots!");
296    return TRUE;
297  }
298
299  // free everything
300  count= iproots[0]->getAnzElems();
301  for (i=0; i < count; i++) delete iproots[i];
302  omFreeSize( (ADDRESS) iproots, count * sizeof(rootContainer*) );
303  count= muiproots[0]->getAnzElems();
304  for (i=0; i < count; i++) delete muiproots[i];
305  omFreeSize( (ADDRESS) muiproots, count * sizeof(rootContainer*) );
306
307  delete ures;
308  delete arranger;
309  nDelete( &smv );
310
311  res->data= (void *)listofroots;
312
313  //emptylist->Clean();
314  //  omFreeSize( (ADDRESS) emptylist, sizeof(slists) );
315
316  TIMING_EPR(mpr_overall,"overall time\t\t")
317
318  return FALSE;
319}
320//<-
321
322//-> BOOLEAN nuMPResMat( leftv res, leftv arg1, leftv arg2 )
323BOOLEAN nuMPResMat( leftv res, leftv arg1, leftv arg2 )
324{
325  ideal gls = (ideal)(arg1->Data());
326  int imtype= (int)arg2->Data();
327
328  uResultant::resMatType mtype= determineMType( imtype );
329
330  // check input ideal ( = polynomial system )
331  if ( mprIdealCheck( gls, arg1->Name(), mtype, true ) != mprOk )
332  {
333    return TRUE;
334  }
335
336  uResultant *resMat= new uResultant( gls, mtype, false );
337
338  res->rtyp = MODUL_CMD;
339  res->data= (void*)resMat->accessResMat()->getMatrix();
340
341  delete resMat;
342
343  return FALSE;
344}
345//<-
346
347//-> BOOLEAN nuLagSolve( leftv res, leftv arg1, leftv arg2, leftv arg3 )
348BOOLEAN nuLagSolve( leftv res, leftv arg1, leftv arg2, leftv arg3 )
349{
350
351  poly gls;
352  gls= (poly)(arg1->Data());
353  int howclean= (int)arg3->Data();
354
355  if ( !(rField_is_R() ||
356         rField_is_Q() ||
357         rField_is_long_R() ||
358         rField_is_long_C()) )
359  {
360    WerrorS("Ground field not implemented!");
361    return TRUE;
362  }
363
364  if ( !(rField_is_R()||rField_is_long_R()||rField_is_long_C()) )
365  {
366    setGMPFloatDigits( (unsigned long int)arg2->Data() );
367  }
368
369  if ( gls == NULL || pIsConstant( gls ) )
370  {
371    WerrorS("Input polynomial is constant!");
372    return TRUE;
373  }
374
375  int deg= pTotaldegree( gls );
376  //  int deg= pDeg( gls );
377  int len= pLength( gls );
378  int i,vpos;
379  poly piter;
380  lists elist;
381  lists rlist;
382
383  elist= (lists)omAlloc( sizeof(slists) );
384  elist->Init( 0 );
385
386  if ( pVariables > 1 )
387  {
388    piter= gls;
389    for ( i= 1; i <= pVariables; i++ )
390      if ( pGetExp( piter, i ) )
391      {
392        vpos= i;
393        break;
394      }
395    while ( piter )
396    {
397      for ( i= 1; i <= pVariables; i++ )
398        if ( (vpos != i) && (pGetExp( piter, i ) != 0) )
399        {
400          WerrorS("The input polynomial must be univariate!");
401          return TRUE;
402        }
403      pIter( piter );
404    }
405  }
406
407  rootContainer * roots= new rootContainer();
408  number * pcoeffs= (number *)omAlloc( (deg+1) * sizeof( number ) );
409  piter= gls;
410  for ( i= deg; i >= 0; i-- )
411  {
412    //if ( piter ) Print("deg %d, pDeg(piter) %d\n",i,pTotaldegree(piter));
413    if ( piter && pTotaldegree(piter) == i )
414    {
415      pcoeffs[i]= nCopy( pGetCoeff( piter ) );
416      //nPrint( pcoeffs[i] );PrintS("  ");
417      pIter( piter );
418    }
419    else
420    {
421      pcoeffs[i]= nInit(0);
422    }
423  }
424
425#ifdef mprDEBUG_PROT
426  for (i=deg; i >= 0; i--)
427  {
428    nPrint( pcoeffs[i] );PrintS("  ");
429  }
430  PrintLn();
431#endif
432
433  TIMING_START(mpr_solver);
434  roots->fillContainer( pcoeffs, NULL, 1, deg, rootContainer::onepoly, 1 );
435  roots->solver( howclean );
436  TIMING_EPR(mpr_solver, "solver time\t\t");
437
438  int elem= roots->getAnzRoots();
439  char *out;
440  char *dummy;
441  int j;
442
443  rlist= (lists)omAlloc( sizeof(slists) );
444  rlist->Init( elem );
445
446  if (rField_is_long_C())
447  {
448    for ( j= 0; j < elem; j++ )
449    {
450      rlist->m[j].rtyp=NUMBER_CMD;
451      rlist->m[j].data=(void *)nCopy((number)(roots->getRoot(j)));
452      //rlist->m[j].data=(void *)(number)(roots->getRoot(j));
453    }
454  }
455  else
456  {
457    for ( j= 0; j < elem; j++ )
458    {
459      dummy = complexToStr( (*roots)[j], gmp_output_digits );
460      rlist->m[j].rtyp=STRING_CMD;
461      rlist->m[j].data=(void *)dummy;
462    }
463  }
464
465  elist->Clean();
466  //omFreeSize( (ADDRESS) elist, sizeof(slists) );
467
468  for ( i= deg; i >= 0; i-- ) nDelete( &pcoeffs[i] );
469  omFreeSize( (ADDRESS) pcoeffs, (deg+1) * sizeof( number ) );
470
471  res->rtyp= LIST_CMD;
472  res->data= (void*)rlist;
473
474  return FALSE;
475}
476//<-
477
478//-> BOOLEAN nuVanderSys( leftv res, leftv arg1, leftv arg2 )
479BOOLEAN nuVanderSys( leftv res, leftv arg1, leftv arg2, leftv arg3)
480{
481  int i;
482  ideal p,w;
483  p= (ideal)arg1->Data();
484  w= (ideal)arg2->Data();
485
486  // w[0] = f(p^0)
487  // w[1] = f(p^1)
488  // ...
489  // p can be a vector of numbers (multivariate polynom)
490  //   or one number (univariate polynom)
491  // tdg = deg(f)
492
493  int n= IDELEMS( p );
494  int m= IDELEMS( w );
495  int tdg= (int)arg3->Data();
496
497  res->data= (void*)NULL;
498
499  // check the input
500  if ( tdg < 1 )
501  {
502    WerrorS("Last input parameter must be > 0!");
503    return TRUE;
504  }
505  if ( n != pVariables )
506  {
507    Werror("Size of first input ideal must be equal to %d!",pVariables);
508    return TRUE;
509  }
510  if ( m != (int)pow((double)tdg+1,(int)n) )
511  {
512    Werror("Size of second input ideal must be equal to %d!",
513      (int)pow((double)tdg+1,(int)n));
514    return TRUE;
515  }
516  if ( !(rField_is_Q() /* ||
517         rField_is_R() || rField_is_long_R() ||
518         rField_is_long_C()*/ ) )
519         {
520    WerrorS("Ground field not implemented!");
521    return TRUE;
522  }
523
524  number tmp;
525  number *pevpoint= (number *)omAlloc( n * sizeof( number ) );
526  for ( i= 0; i < n; i++ )
527  {
528    pevpoint[i]=nInit(0);
529    if (  (p->m)[i] )
530    {
531      tmp = pGetCoeff( (p->m)[i] );
532      if ( nIsZero(tmp) || nIsOne(tmp) || nIsMOne(tmp) )
533      {
534        omFreeSize( (ADDRESS)pevpoint, n * sizeof( number ) );
535        WerrorS("Elements of first input ideal must not be equal to -1, 0, 1!");
536        return TRUE;
537      }
538    } else tmp= NULL;
539    if ( !nIsZero(tmp) )
540    {
541      if ( !pIsConstant((p->m)[i]))
542      {
543        omFreeSize( (ADDRESS)pevpoint, n * sizeof( number ) );
544        WerrorS("Elements of first input ideal must be numbers!");
545        return TRUE;
546      }
547      pevpoint[i]= nCopy( tmp );
548    }
549  }
550
551  number *wresults= (number *)omAlloc( m * sizeof( number ) );
552  for ( i= 0; i < m; i++ )
553  {
554    wresults[i]= nInit(0);
555    if ( (w->m)[i] && !nIsZero(pGetCoeff((w->m)[i])) )
556    {
557      if ( !pIsConstant((w->m)[i]))
558      {
559        omFreeSize( (ADDRESS)pevpoint, n * sizeof( number ) );
560        omFreeSize( (ADDRESS)wresults, m * sizeof( number ) );
561        WerrorS("Elements of second input ideal must be numbers!");
562        return TRUE;
563      }
564      wresults[i]= nCopy(pGetCoeff((w->m)[i]));
565    }
566  }
567
568  vandermonde vm( m, n, tdg, pevpoint, FALSE );
569  number *ncpoly= vm.interpolateDense( wresults );
570  // do not free ncpoly[]!!
571  poly rpoly= vm.numvec2poly( ncpoly );
572
573  omFreeSize( (ADDRESS)pevpoint, n * sizeof( number ) );
574  omFreeSize( (ADDRESS)wresults, m * sizeof( number ) );
575
576  res->data= (void*)rpoly;
577  return FALSE;
578}
579//<-
580
581//-> function u_resultant_det
582poly u_resultant_det( ideal gls, int imtype )
583{
584  uResultant::resMatType mtype= determineMType( imtype );
585  poly resdet;
586  poly emptypoly= pInit();
587  number smv= NULL;
588
589  TIMING_START(mpr_overall);
590
591  // check input ideal ( = polynomial system )
592  if ( mprIdealCheck( gls, "", mtype ) != mprOk )
593  {
594    return emptypoly;
595  }
596
597  uResultant *ures;
598
599  // main task 1: setup of resultant matrix
600  TIMING_START(mpr_constr);
601  ures= new uResultant( gls, mtype );
602  TIMING_EPR(mpr_constr,"construction");
603
604  // if dense resultant, check if minor nonsingular
605  if ( mtype == uResultant::denseResMat )
606  {
607    smv= ures->accessResMat()->getSubDet();
608#ifdef mprDEBUG_PROT
609    PrintS("// Determinant of submatrix: ");nPrint(smv); PrintLn();
610#endif
611    if ( nIsZero(smv) )
612    {
613      WerrorS("Unsuitable input ideal: Minor of resultant matrix is singular!");
614      return emptypoly;
615    }
616  }
617
618  // main task 2: Interpolate resultant polynomial
619  TIMING_START(mpr_ures);
620  resdet= ures->interpolateDense( smv );
621  TIMING_EPR(mpr_ures,"ures");
622
623  // free mem
624  delete ures;
625  nDelete( &smv );
626  pDelete( &emptypoly );
627
628  TIMING_EPR(mpr_overall,"overall");
629
630  return ( resdet );
631}
632//<-
633
634//-> BOOLEAN loNewtonP( leftv res, leftv arg1 )
635BOOLEAN loNewtonP( leftv res, leftv arg1 )
636{
637  res->data= (void*)loNewtonPolytope( (ideal)arg1->Data() );
638  return FALSE;
639}
640//<-
641
642//-> BOOLEAN loSimplex( leftv res, leftv args )
643BOOLEAN loSimplex( leftv res, leftv args )
644{
645  if ( !(rField_is_long_R()) )
646  {
647    WerrorS("Ground field not implemented!");
648    return TRUE;
649  }
650
651  simplex * LP;
652  matrix m;
653
654  leftv v= args;
655  if ( v->Typ() != MATRIX_CMD ) // 1: matrix
656    return TRUE;
657  else
658    m= (matrix)(v->Data());
659
660  LP = new simplex(MATROWS(m),MATCOLS(m));
661  LP->mapFromMatrix(m);
662
663  v= v->next;
664  if ( v->Typ() != INT_CMD )    // 2: m = number of constraints
665    return TRUE;
666  else
667    LP->m= (int)(v->Data());
668
669  v= v->next;
670  if ( v->Typ() != INT_CMD )    // 3: n = number of variables
671    return TRUE;
672  else
673    LP->n= (int)(v->Data());
674
675  v= v->next;
676  if ( v->Typ() != INT_CMD )    // 4: m1 = number of <= constraints
677    return TRUE;
678  else
679    LP->m1= (int)(v->Data());
680
681  v= v->next;
682  if ( v->Typ() != INT_CMD )    // 5: m2 = number of >= constraints
683    return TRUE;
684  else
685    LP->m2= (int)(v->Data());
686
687  v= v->next;
688  if ( v->Typ() != INT_CMD )    // 6: m3 = number of == constraints
689    return TRUE;
690  else
691    LP->m3= (int)(v->Data());
692
693#ifdef mprDEBUG_PROT
694  Print("m (constraints) %d\n",LP->m);
695  Print("n (columns) %d\n",LP->n);
696  Print("m1 (<=) %d\n",LP->m1);
697  Print("m2 (>=) %d\n",LP->m2);
698  Print("m3 (==) %d\n",LP->m3);
699#endif
700
701  LP->compute();
702
703  lists lres= (lists)omAlloc( sizeof(slists) );
704  lres->Init( 6 );
705
706  lres->m[0].rtyp= MATRIX_CMD; // output matrix
707  lres->m[0].data=(void*)LP->mapToMatrix(m);
708
709  lres->m[1].rtyp= INT_CMD;   // found a solution?
710  lres->m[1].data=(void*)LP->icase;
711
712  lres->m[2].rtyp= INTVEC_CMD;
713  lres->m[2].data=(void*)LP->posvToIV();
714
715  lres->m[3].rtyp= INTVEC_CMD;
716  lres->m[3].data=(void*)LP->zrovToIV();
717
718  lres->m[4].rtyp= INT_CMD;
719  lres->m[4].data=(void*)LP->m;
720
721  lres->m[5].rtyp= INT_CMD;
722  lres->m[5].data=(void*)LP->n;
723
724  res->data= (void*)lres;
725
726  return FALSE;
727}
728//<-
729
730//-----------------------------------------------------------------------------
731
732//#endif // HAVE_MPR
733
734// local Variables: ***
735// folded-file: t ***
736// compile-command-1: "make installg" ***
737// compile-command-2: "make install" ***
738// End: ***
739
740// in folding: C-c x
741// leave fold: C-c y
742//   foldmode: F10
Note: See TracBrowser for help on using the repository browser.