source: git/Singular/mpsr_GetMisc.cc @ 6725bc3

fieker-DuValspielwiese
Last change on this file since 6725bc3 was 762407, checked in by Oleksandr Motsak <motsak@…>, 12 years ago
config.h is for sources files only FIX: config.h should only be used by source (not from inside kernel/mod2.h!) NOTE: each source file should better include mod2.h right after config.h, while headers should better not include mod2.h.
  • Property mode set to 100644
File size: 10.9 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id$ */
5
6/***************************************************************
7 *
8 * File:       mpsr_GetMisc.cc
9 * Purpose:    Miscellanous routines which are needed by mpsr_Get
10 * Author:     Olaf Bachmann (10/95)
11 *
12 * Change History (most recent first):
13 *
14 ***************************************************************/
15
16#include "config.h"
17#include <kernel/mod2.h>
18
19#ifdef HAVE_MPSR
20
21#include <Singular/mpsr_Get.h>
22//#include "kernel/longalg.h"
23#include <Singular/tok.h>
24#include <polys/monomials/maps.h>
25#include <Singular/lists.h>
26
27BOOLEAN currComplete = FALSE;
28
29static ring mpsr_rDefault(short ch, const char *name);
30static char* GenerateRingName();
31
32
33// use the varname so that they are compatible with the ones generated
34// by GetRingAnnots
35#define MPSR_DEFAULT_VARNAME "x(1)"
36
37// returns some default ring
38int mpsr_rDefault(short ch, const char *name, ring &r)
39{
40  // check for currRing
41  if (currRing != NULL && rInternalChar(currRing) == ch)
42  // orig: currRing->ch==ch ???
43  {
44    int i, n = currRing->N;
45    char **names = currRing->names;
46
47    for (i=0; i<n; i++)
48    {
49      if (strcmp(names[i], name) == 0)
50      {
51        (currRing->ref)++;
52        r = currRing;
53        return i;
54      }
55    }
56  }
57  r = mpsr_rDefault(ch, name);
58  return 0;
59}
60
61ring mpsr_rDefault(short ch)
62{
63  if (currRing != NULL && rInternalChar(currRing) == ch)
64  // orig: currRing->ch==ch ???
65  {
66    (currRing->ref)++;
67    return currRing;
68  }
69  else
70    return mpsr_rDefault(ch, MPSR_DEFAULT_VARNAME);
71}
72
73static ring mpsr_rDefault(short ch, const char *name)
74{
75  ring r = (ring) omAlloc0Bin(sip_sring_bin);
76  r->ch = ch;
77  r->N = 1;
78  r->names = (char **) omAlloc0Bin(char_ptr_bin);
79  r->names[0] = omStrDup(name);
80
81  r->wvhdl = (int **)omAlloc0(3 * sizeof(int *));
82  /*order: dp,C,0*/
83  r->order = (int *) omAlloc(3 * sizeof(int *));
84  r->block0 = (int *)omAlloc(3 * sizeof(int *));
85  r->block1 = (int *)omAlloc(3 * sizeof(int *));
86  /* ringorder dp for the first block: var 1..3 */
87  r->order[0]  = ringorder_unspec;
88  r->block0[0] = 1;
89  r->block1[0] = 1;
90  /* ringorder C for the second block: no vars */
91  r->order[1]  = ringorder_C;
92  r->block0[1] = 0;
93  r->block1[1] = 0;
94  /* the last block: everything is 0 */
95  r->order[2]  = 0;
96  r->block0[2] = 0;
97  r->block1[2] = 0;
98  rComplete(r);
99  return r;
100}
101
102// returns TRUE, if r1 less or equals r2
103// FALSE, otherwise
104// Less or equal means that r1 is a strong subring of r2
105static inline BOOLEAN RingLessEqual(ring r1, ring r2)
106{
107  int i, j;
108
109  if (r1 == r2) return 1;
110
111  if (r1 == NULL) return 1;
112
113  if (r2 == NULL) return 0;
114
115  if ((r1->N > r2->N) || (r1->OrdSgn != r2->OrdSgn) || (rPar(r1) > rPar(r2)))
116    return 0;
117
118  if (!rField_is_Q(r1) && rInternalChar(r1) != rInternalChar(r2)) return 0;
119  // orig: if (r1->ch != 0 && r1->ch != r2->ch) return 0;
120
121  for (i=0, j=0; j<r1->N && i<r2->N; i++)
122    if (strcmp(r1->names[j], r2->names[i]) == 0) j++;
123  if (j < r1->N) return 0;
124
125  // for ordering, suppose that they are only simple orderings
126  if (r1->order[2] != 0 || r2->order[2] != 0 ||
127      (r1->order[0] != r2->order[0] && r1->order[0] != ringorder_unspec) ||
128      r1->order[1] != r2->order[1])
129    return 0;
130
131  for (i=0; i<rPar(r1);i++)
132  {
133      if (strcmp(r1->parameter[i], r2->parameter[i])!=0)
134        return 0;
135  }
136  // r1->parameter == NULL && r2->parameter != NULL  is ok
137
138  if (r1->minpoly != NULL)
139  {
140    if (r2->minpoly == NULL) return 0;
141    mpsr_SetCurrRing(r1, FALSE);
142    if (! naEqual(r1->minpoly, r2->minpoly)) return 0;
143  }
144  return 1;
145}
146
147// returns MP_Success and lv2 appended to lv1, both over the same ring,
148// or MP_Failure
149mpsr_Status_t mpsr_MergeLeftv(mpsr_leftv mlv1, mpsr_leftv mlv2)
150{
151  ring r, r1 = mlv1->r, r2 = mlv2->r;
152  leftv lv;
153
154  if (rEqual(r1,r2))
155  {
156    if (r2 != NULL) rKill(r2);
157    r = r1;
158  }
159  else if (RingLessEqual(r1, r2))
160  {
161    r = r2;
162    if (r1 != NULL)
163    {
164      mpsr_MapLeftv(mlv1->lv, r1, r);
165      rKill(r1);
166    }
167  }
168  else if (RingLessEqual(r2, r1))
169  {
170    r = r1;
171    if (r2 != NULL)
172    {
173      mpsr_MapLeftv(mlv2->lv, r2, r);
174      rKill(r2);
175    }
176  }
177  else if (rSum(r1, r2, r) >= 0)
178  {
179    mpsr_MapLeftv(mlv1->lv, r1, r);
180    mpsr_MapLeftv(mlv2->lv, r2, r);
181    rKill(r1);
182    rKill(r2);
183  }
184  else return mpsr_Failure;
185
186  lv = mlv1->lv;
187  while (lv->next != NULL) lv = lv->next;
188
189  lv->next = mlv2->lv;
190  mlv1->r = r;
191
192#ifdef RDEBUG
193  if (r!= NULL) rTest(r);
194#endif
195  // this is an optimization for the mpsr_rDefault routines
196  currRing = r;
197  return mpsr_Success;
198}
199
200void mpsr_MapLeftv(leftv l, ring from_ring, ring to_ring)
201{
202  int i, n;
203
204  while (l != NULL)
205  {
206    short typ = l->Typ();
207
208    switch(typ)
209    {
210        case POLY_CMD:
211        case VECTOR_CMD:
212        {
213          poly p = (poly) l->data;
214          mpsr_SetCurrRing(to_ring, TRUE);
215          l->data = (void *) maIMap(from_ring, (poly) l->data);
216          p_Delete(&p, from_ring);
217          break;
218        }
219
220        case MODUL_CMD:
221        case IDEAL_CMD:
222        case MATRIX_CMD:
223        case MAP_CMD:
224        {
225          ideal id = (ideal) l->Data();
226          n = IDELEMS(id);
227          poly *m = id->m, *m1 = (poly *) omAlloc(n*sizeof(poly));
228          mpsr_SetCurrRing(to_ring, TRUE);
229          for (i=0; i<n; i++)
230          {
231            m1[i] = m[i];
232            m[i] = maIMap(from_ring, m[i]);
233          }
234          mpsr_SetCurrRing(from_ring, FALSE);
235          for (i=0; i<n; i++) pDelete(&(m1[i]));
236          omFreeSize(m1, n*sizeof(poly));
237          break;
238        }
239
240        case LIST_CMD:
241        {
242          lists ll = (lists) l->Data();
243          n = ll->nr + 1;
244          for (i=0; i<n; i++) mpsr_MapLeftv(&(ll->m[i]), from_ring, to_ring);
245          break;
246        }
247
248        case COMMAND:
249        {
250          command cmd = (command) l->Data();
251          if (cmd->op == PROC_CMD && cmd->argc == 2)
252            mpsr_MapLeftv(&(cmd->arg2), from_ring, to_ring);
253          else if (cmd->argc > 0)
254          {
255            mpsr_MapLeftv(&(cmd->arg1), from_ring, to_ring);
256            if (cmd->argc > 1)
257            {
258              mpsr_MapLeftv(&(cmd->arg2), from_ring, to_ring);
259              if (cmd->argc > 2)
260                mpsr_MapLeftv(&(cmd->arg3), from_ring, to_ring);
261            }
262          }
263          break;
264        }
265
266        case NUMBER_CMD:
267        {
268          number nn = (number) l->data;
269          mpsr_SetCurrRing(to_ring, TRUE);
270          nMapFunc nMap=nSetMap(from_ring);
271          l->data = (void *) nMap(nn);
272          mpsr_SetCurrRing(from_ring, FALSE);
273          nDelete(&nn);
274        }
275    }
276    l = l->next;
277  }
278}
279
280
281// searches for a ring handle which has a ring which is equal to r
282// if one is found, then this one is set to the new global ring
283// otherwise, a ring name is generated, and a new idhdl is created
284void mpsr_SetCurrRingHdl(mpsr_leftv mlv)
285{
286  idhdl h = IDROOT, rh = NULL;
287  ring r = mlv->r;
288
289  if (r == NULL)
290  {
291    if (currRingHdl != NULL && currRing != IDRING(currRingHdl))
292      mpsr_SetCurrRing(IDRING(currRingHdl), TRUE);
293    return;
294  }
295
296  rTest(r);
297  // try to find an idhdl which is an equal ring
298  while (h != NULL)
299  {
300    if ((IDTYP(h) == RING_CMD || IDTYP(h) == QRING_CMD) &&
301        (rEqual(IDRING(h), r)))
302    {
303      // found one
304      rh = h;
305      break;
306    }
307    h = h->next;
308  }
309
310  if (rh != NULL)
311  {
312    // found an idhdl to an equal ring
313    // we better reset currRing, so that rSetHdl does not choke (see
314    // sLastPrinted)
315    if (currRingHdl != NULL && IDRING(currRingHdl) != currRing)
316      mpsr_SetCurrRing(IDRING(currRingHdl), TRUE);
317
318    // reset debug field so that RingOfLm does not complain
319    // this does nothing on !PDEBUG
320    p_SetRingOfLeftv(mlv->lv, IDRING(rh));
321
322    rSetHdl(rh);
323
324    if (currRing != r)
325    {
326      mpsr_assume(r->ref <= 0);
327      rKill(r);
328    }
329  }
330  else
331  {
332    rh = mpsr_InitIdhdl((r->qideal == NULL ? (short) RING_CMD
333                         : (short) QRING_CMD),
334                        (void *) r, GenerateRingName());
335    // reset currRing for reasons explained above
336    if (currRingHdl != NULL) mpsr_SetCurrRing(IDRING(currRingHdl), TRUE);
337    rSetHdl(rh);
338    rh->next = IDROOT;
339    IDROOT = rh;
340    r->ref = 0;
341  }
342}
343
344
345static int gringcounter = 0;
346static char grname[14];
347
348static char* GenerateRingName()
349{
350  sprintf(grname, "mpsr_r%d", gringcounter++);
351  return grname;
352}
353
354// searches through the Singular namespace for a matching name:
355// the first found is returned together witht the respective ring
356idhdl mpsr_FindIdhdl(char *name, ring &r)
357{
358  idhdl h = (IDROOT != NULL ? IDROOT->get(name, 0): (idhdl) NULL), h2;
359  r = NULL;
360
361  if (h != NULL)
362  {
363    r = NULL;
364    return h;
365  }
366
367  h = IDROOT;
368  while ( h != NULL)
369  {
370    if (IDTYP(h) == RING_CMD || IDTYP(h) == QRING_CMD)
371    {
372      h2 = (IDRING(h)->idroot!=NULL ?IDRING(h)->idroot->get(name, 0) :
373            (idhdl) NULL);
374
375      if (h2 != NULL)
376      {
377        r = IDRING(h);
378        r->ref++;
379        return h2;
380      }
381    }
382    h = h->next;
383  }
384  return NULL;
385}
386
387
388/***************************************************************
389 *
390 * Stuff which deals with External Data
391 *
392 ***************************************************************/
393
394void mpsr_DeleteExternalData(MPT_ExternalData_t edata)
395{
396  mpsr_leftv mlv = (mpsr_leftv) edata;
397
398  if (edata != NULL)
399  {
400    if (mlv->r != NULL) mpsr_SetCurrRing(mlv->r, FALSE);
401    if (mlv->lv != NULL)
402    {
403      mlv->lv->CleanUp();
404      omFreeBin(mlv->lv, sleftv_bin);
405    }
406    if (mlv->r != NULL) rKill(mlv->r);
407  }
408  omFreeBin(mlv, mpsr_sleftv_bin);
409}
410
411void mpsr_CopyExternalData(MPT_ExternalData_t *dest,
412                           MPT_ExternalData_t src)
413{
414  mpsr_leftv slv = (mpsr_leftv) src, dlv;
415
416  if (slv != NULL)
417  {
418    dlv = (mpsr_leftv) omAlloc0Bin(mpsr_sleftv_bin);
419    dlv->r = rCopy(slv->r);
420    dlv->lv = (leftv) omAlloc0Bin(sleftv_bin);
421    if (slv->lv != NULL) dlv->lv->Copy(slv->lv);
422    else dlv->lv = NULL;
423
424    *dest = (MPT_ExternalData_t) dlv;
425  }
426  else
427    *dest = NULL;
428}
429
430/***************************************************************
431 *
432 * mpsr initialization
433 *
434 ***************************************************************/
435#undef malloc
436#undef free
437#undef freeSize
438
439#include "mmalloc.h"
440
441static int mpsr_is_initialized = 0;
442
443LINKAGE void mpsr_Init()
444{
445  if (mpsr_is_initialized) return;
446  // memory management functions of MP (and MPT)
447#if defined(OMALLOC_USES_MALLOC) || defined(X_OMALLOC)
448  IMP_RawMemAllocFnc = omMallocFunc;
449  IMP_RawMemFreeFnc = omFreeFunc;
450  IMP_MemAllocFnc = omMallocFunc;
451  IMP_MemFreeFnc = omFreeSizeFunc;
452#else
453  IMP_RawMemAllocFnc = malloc;
454  IMP_RawMemFreeFnc = free;
455  IMP_MemAllocFnc = malloc;
456  IMP_MemFreeFnc = freeSize;
457#endif
458
459  // Init of the MPT External Data functions
460  MPT_GetExternalData = mpsr_GetExternalData;
461  MPT_DeleteExternalData = mpsr_DeleteExternalData;
462
463#ifdef  PARI_BIGINT_TEST
464  init(4000000, 2);
465#endif
466}
467
468#ifdef MPSR_DEBUG
469// this is just a dummy function, where we can set a debugger breakpoint
470void mpsr_Break()
471{
472  Werror("mpsr_Error");
473}
474#endif
475
476#endif // HAVE_MPSR
Note: See TracBrowser for help on using the repository browser.