source: git/Singular/eigenval_ip.cc @ c90500

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