source: git/Singular/eigenval_ip.cc @ abb12f

spielwiese
Last change on this file since abb12f was ba5e9e, checked in by Oleksandr Motsak <motsak@…>, 11 years ago
Changed configure-scripts to generate individual public config files for each package: resources, libpolys, singular (main) fix: sources should include correct corresponding config headers.
  • Property mode set to 100644
File size: 6.3 KB
Line 
1/*****************************************
2*  Computer Algebra System SINGULAR      *
3*****************************************/
4/*
5* ABSTRACT: eigenvalues of constant square matrices
6*/
7
8#ifdef HAVE_CONFIG_H
9#include "singularconfig.h"
10#endif /* HAVE_CONFIG_H */
11#include <kernel/mod2.h>
12
13#ifdef HAVE_EIGENVAL
14
15#include <kernel/febase.h>
16#include <Singular/tok.h>
17#include <Singular/ipid.h>
18#include <misc/intvec.h>
19#include <coeffs/numbers.h>
20#include <kernel/polys.h>
21#include <kernel/ideals.h>
22#include <Singular/lists.h>
23#include <polys/matpol.h>
24#include <polys/clapsing.h>
25#include <kernel/eigenval.h>
26#include <Singular/eigenval_ip.h>
27
28
29BOOLEAN evSwap(leftv res,leftv h)
30{
31  if(currRing)
32  {
33    if(h&&h->Typ()==MATRIX_CMD)
34    {
35      matrix M=(matrix)h->Data();
36      h=h->next;
37      if(h&&h->Typ()==INT_CMD)
38      {
39        int i=(int)(long)h->Data();
40        h=h->next;
41        if(h&&h->Typ()==INT_CMD)
42        {
43          int j=(int)(long)h->Data();
44          res->rtyp=MATRIX_CMD;
45          res->data=(void *)evSwap(mp_Copy(M, currRing),i,j);
46          return FALSE;
47        }
48      }
49    }
50    WerrorS("<matrix>,<int>,<int> expected");
51    return TRUE;
52  }
53  WerrorS("no ring active");
54  return TRUE;
55}
56
57BOOLEAN evRowElim(leftv res,leftv h)
58{
59  if(currRing)
60  {
61    if(h&&h->Typ()==MATRIX_CMD)
62    {
63      matrix M=(matrix)h->Data();
64      h=h->next;
65      if(h&&h->Typ()==INT_CMD)
66      {
67        int i=(int)(long)h->Data();
68        h=h->next;
69        if(h&&h->Typ()==INT_CMD)
70        {
71          int j=(int)(long)h->Data();
72          h=h->next;
73          if(h&&h->Typ()==INT_CMD)
74          {
75            int k=(int)(long)h->Data();
76            res->rtyp=MATRIX_CMD;
77            res->data=(void *)evRowElim(mp_Copy(M, currRing),i,j,k);
78            return FALSE;
79          }
80        }
81      }
82    }
83    WerrorS("<matrix>,<int>,<int>,<int> expected");
84    return TRUE;
85  }
86  WerrorS("no ring active");
87  return TRUE;
88}
89
90BOOLEAN evColElim(leftv res,leftv h)
91{
92  if(currRing)
93  {
94    if(h&&h->Typ()==MATRIX_CMD)
95    {
96      matrix M=(matrix)h->Data();
97      h=h->next;
98      if(h&&h->Typ()==INT_CMD)
99      {
100        int i=(int)(long)h->Data();
101        h=h->next;
102        if(h&&h->Typ()==INT_CMD)
103        {
104          int j=(int)(long)h->Data();
105          h=h->next;
106          if(h&&h->Typ()==INT_CMD)
107          {
108            int k=(int)(long)h->Data();
109            res->rtyp=MATRIX_CMD;
110            res->data=(void *)evColElim(mp_Copy(M, currRing),i,j,k);
111            return FALSE;
112          }
113        }
114      }
115    }
116    WerrorS("<matrix>,<int>,<int>,<int> expected");
117    return TRUE;
118  }
119  WerrorS("no ring active");
120  return TRUE;
121}
122
123BOOLEAN evHessenberg(leftv res,leftv h)
124{
125  if(currRing)
126  {
127    if(h&&h->Typ()==MATRIX_CMD)
128    {
129      matrix M=(matrix)h->Data();
130      res->rtyp=MATRIX_CMD;
131      res->data=(void *)evHessenberg(mp_Copy(M, currRing));
132      return FALSE;
133    }
134    WerrorS("<matrix> expected");
135    return TRUE;
136  }
137  WerrorS("no ring active");
138  return TRUE;
139}
140
141
142lists evEigenvals(matrix M)
143{
144  lists l=(lists)omAllocBin(slists_bin);
145  if(MATROWS(M)!=MATCOLS(M))
146  {
147    l->Init(0);
148    return(l);
149  }
150
151  M=evHessenberg((matrix)id_Jet((ideal)M,0,currRing));
152
153  int n=MATROWS(M);
154  ideal e=idInit(n,1);
155  intvec *m=new intvec(n);
156
157  poly t=pOne();
158  pSetExp(t,1,1);
159  pSetm(t);
160
161  for(int j0=1,j=2,k=0;j<=n+1;j0=j,j++)
162  {
163    while(j<=n&&MATELEM(M,j,j-1)!=NULL)
164      j++;
165    if(j==j0+1)
166    {
167      e->m[k]=pHead(MATELEM(M,j0,j0));
168      (*m)[k]=1;
169      k++;
170    }
171    else
172    {
173      int n0=j-j0;
174      matrix M0=mpNew(n0,n0);
175
176      j0--;
177      for(int i=1;i<=n0;i++)
178        for(int j=1;j<=n0;j++)
179          MATELEM(M0,i,j)=pCopy(MATELEM(M,j0+i,j0+j));
180      for(int i=1;i<=n0;i++)
181        MATELEM(M0,i,i)=pSub(MATELEM(M0,i,i),pCopy(t));
182
183      intvec *m0;
184#ifdef HAVE_FACTORY     
185      ideal e0=singclap_factorize(mp_DetBareiss(M,currRing),&m0,2, currRing);
186#else
187      WarnS("cannot factorize due to missing module 'factory'");
188      ideal e0=NULL;
189#endif
190     
191      if (e0==NULL)
192      {
193        l->Init(0);
194        return(l);
195      }
196
197      for(int i=0;i<IDELEMS(e0);i++)
198      {
199        if(pNext(e0->m[i])==NULL)
200        {
201          (*m)[k]=(*m0)[i];
202          k++;
203        }
204        else
205        if(pGetExp(e0->m[i],1)<2&&pGetExp(pNext(e0->m[i]),1)<2&&
206           pNext(pNext(e0->m[i]))==NULL)
207        {
208          number e1=nNeg(nCopy(pGetCoeff(e0->m[i])));
209          if(pGetExp(pNext(e0->m[i]),1)==0)
210            e->m[k]=pNSet(nDiv(pGetCoeff(pNext(e0->m[i])),e1));
211          else
212            e->m[k]=pNSet(nDiv(e1,pGetCoeff(pNext(e0->m[i]))));
213          nDelete(&e1);
214          pNormalize(e->m[k]);
215          (*m)[k]=(*m0)[i];
216          k++;
217        }
218        else
219        {
220          e->m[k]=e0->m[i];
221          pNormalize(e->m[k]);
222          e0->m[i]=NULL;
223          (*m)[k]=(*m0)[i];
224          k++;
225        }
226      }
227
228      delete(m0);
229      idDelete(&e0);
230    }
231  }
232
233  pDelete(&t);
234  idDelete((ideal *)&M);
235
236  for(int i0=0;i0<n-1;i0++)
237  {
238    for(int i1=i0+1;i1<n;i1++)
239    {
240      if(pEqualPolys(e->m[i0],e->m[i1]))
241      {
242        (*m)[i0]+=(*m)[i1];
243        (*m)[i1]=0;
244      }
245      else
246      {
247        if(e->m[i0]==NULL&&!nGreaterZero(pGetCoeff(e->m[i1]))||
248           e->m[i1]==NULL&&
249          (nGreaterZero(pGetCoeff(e->m[i0]))||pNext(e->m[i0])!=NULL)||
250           e->m[i0]!=NULL&&e->m[i1]!=NULL&&
251          (pNext(e->m[i0])!=NULL&&pNext(e->m[i1])==NULL||
252           pNext(e->m[i0])==NULL&&pNext(e->m[i1])==NULL&&
253           nGreater(pGetCoeff(e->m[i0]),pGetCoeff(e->m[i1]))))
254        {
255          poly e1=e->m[i0];
256          e->m[i0]=e->m[i1];
257          e->m[i1]=e1;
258          int m1=(*m)[i0];
259          (*m)[i0]=(*m)[i1];
260          (*m)[i1]=m1;
261        }
262      }
263    }
264  }
265
266  int n0=0;
267  for(int i=0;i<n;i++)
268    if((*m)[i]>0)
269      n0++;
270
271  ideal e0=idInit(n0,1);
272  intvec *m0=new intvec(n0);
273
274  for(int i=0,i0=0;i<n;i++)
275    if((*m)[i]>0)
276    {
277      e0->m[i0]=e->m[i];
278      e->m[i]=NULL;
279      (*m0)[i0]=(*m)[i];
280      i0++;
281    }
282
283  idDelete(&e);
284  delete(m);
285
286  l->Init(2);
287  l->m[0].rtyp=IDEAL_CMD;
288  l->m[0].data=e0;
289  l->m[1].rtyp=INTVEC_CMD;
290  l->m[1].data=m0;
291
292  return(l);
293}
294
295
296BOOLEAN evEigenvals(leftv res,leftv h)
297{
298  if(currRing)
299  {
300    if(h&&h->Typ()==MATRIX_CMD)
301    {
302      matrix M=(matrix)h->Data();
303      res->rtyp=LIST_CMD;
304      res->data=(void *)evEigenvals(mp_Copy(M, currRing));
305      return FALSE;
306    }
307    WerrorS("<matrix> expected");
308    return TRUE;
309  }
310  WerrorS("no ring active");
311  return TRUE;
312}
313
314#endif /* HAVE_EIGENVAL */
Note: See TracBrowser for help on using the repository browser.