source: git/Singular/mpr_inout.cc @ b7b08c

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