source: git/Singular/mpr_inout.cc @ da408f

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