source: git/Singular/eigenval_ip.cc @ 06c0b3

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