source: git/Singular/eigenval.cc @ f2dff02

fieker-DuValspielwiese
Last change on this file since f2dff02 was 5589c0, checked in by Hans Schönemann <hannes@…>, 23 years ago
*hannes: 2-1-patches git-svn-id: file:///usr/local/Singular/svn/trunk@5331 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 5.4 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: eigenval.cc,v 1.3 2001-03-22 19:10:59 Singular Exp $ */
5/*
6* ABSTRACT: eigenvalues of constant square matrices
7*/
8
9#include "mod2.h"
10
11#ifdef HAVE_EIGENVAL
12
13#include "tok.h"
14#include "febase.h"
15#include "numbers.h"
16#include "polys.h"
17#include "ideals.h"
18#include "matpol.h"
19#include "clapsing.h"
20
21matrix swap(matrix M,int i,int j)
22{
23  if(i==j)
24    return M;
25  poly p;
26  for(int k=1;k<=MATROWS(M);k++)
27  {
28    p=MATELEM(M,i,k);
29    MATELEM(M,i,k)=MATELEM(M,j,k);
30    MATELEM(M,j,k)=p;
31  }
32  for(int k=1;k<=MATCOLS(M);k++)
33  {
34    p=MATELEM(M,k,i);
35    MATELEM(M,k,i)=MATELEM(M,k,j);
36    MATELEM(M,k,j)=p;
37  }
38  return(M);
39}
40
41matrix rowelim(matrix M,int i, int j, int k)
42{
43  if(MATELEM(M,i,k)==NULL||MATELEM(M,j,k)==NULL)
44    return M;
45  number n=nDiv(nCopy(pGetCoeff(MATELEM(M,i,k))),
46                nCopy(pGetCoeff(MATELEM(M,j,k))));
47  for(int l=1;l<=MATCOLS(M);l++)
48  {
49    MATELEM(M,i,l)=pSub(MATELEM(M,i,l),pMult_nn(pCopy(MATELEM(M,j,l)),n));
50  }
51  for(int l=1;l<=MATROWS(M);l++)
52  {
53    MATELEM(M,l,j)=pAdd(MATELEM(M,l,j),pMult_nn(pCopy(MATELEM(M,l,i)),n));
54  }
55  nDelete(&n);
56  return M;
57}
58
59matrix colelim(matrix M,int i, int j, int k)
60{
61  if(MATELEM(M,k,i)==NULL||MATELEM(M,k,j)==NULL)
62    return M;
63  number n=nDiv(nCopy(pGetCoeff(MATELEM(M,k,i))),
64                nCopy(pGetCoeff(MATELEM(M,k,j))));
65  for(int l=1;l<=MATROWS(M);l++)
66  {
67    MATELEM(M,l,i)=pSub(MATELEM(M,l,i),pMult_nn(pCopy(MATELEM(M,l,j)),n));
68  }
69  for(int l=1;l<=MATCOLS(M);l++)
70  {
71    MATELEM(M,j,l)=pAdd(MATELEM(M,j,l),pMult_nn(pCopy(MATELEM(M,i,l)),n));
72  }
73  nDelete(&n);
74  return M;
75}
76
77matrix tridiag(matrix M)
78{
79  int n=MATCOLS(M);
80  for(int k=1;k<=n-2;k++)
81  {
82    int j=k+1;
83    while(j<=n&&MATELEM(M,j,k)==NULL)
84    {
85      j++;
86    }
87    if(j<=n)
88    {
89      for(int i=j+1;i<=n;i++)
90      {
91        M=rowelim(M,i,j,k);
92      }
93      M=swap(M,j,k+1);
94    }
95    j=k+1;
96    while(j<=n&&MATELEM(M,k,j)==NULL)
97    {
98      j++;
99    }
100    if(j<=n)
101    {
102      for(int i=j+1;i<=n;i++)
103      {
104        M=colelim(M,i,j,k);
105      }
106      M=swap(M,j,k+1);
107    }
108  }
109  return(M);
110}
111
112lists addval(lists l,poly e0,int m0)
113{
114  ideal ee=(ideal)l->m[0].data;
115  intvec *mm=(intvec*)l->m[1].data;
116  int n=0;
117  if(ee!=NULL)
118    n=IDELEMS(ee);
119  for(int i=n-1;i>=0;i--)
120  {
121    if(pEqualPolys(ee->m[i],e0))
122    {
123      (*mm)[i]+=m0;
124      return l;
125    }
126  }
127  ideal e=idInit(n+1,1);
128  for(int i=n-1;i>=0;i--)
129  {
130    e->m[i]=ee->m[i];
131    ee->m[i]=NULL;
132  }
133  e->m[n]=e0;
134  l->m[0].data=e;
135  if(ee!=NULL)
136    idDelete(&ee);
137  mm->resize(n+1);
138  (*mm)[n]=m0;
139  return l;
140}
141
142lists sortval(lists l)
143{
144  ideal ee=(ideal)l->m[0].data;
145  intvec *mm=(intvec*)l->m[1].data;
146  int n=IDELEMS(ee);
147  for(int i=n-1;i>=1;i--)
148    for(int j=i-1;j>=0;j--)
149      if(nGreater(pGetCoeff(ee->m[j]),pGetCoeff(ee->m[i])))
150      {
151        poly e=ee->m[i];
152        ee->m[i]=ee->m[j];
153        ee->m[j]=e;
154        int m=(*mm)[i];
155        (*mm)[i]=(*mm)[j];
156        (*mm)[j]=m;
157      }
158  return l;
159}
160
161lists eigenval(matrix M)
162{
163  M=tridiag(M);
164  int n=MATCOLS(M);
165  lists l=(lists)omAllocBin(slists_bin);
166  l->Init(2);
167  l->m[0].rtyp=IDEAL_CMD;
168  l->m[0].data=NULL;
169  l->m[1].rtyp=INTVEC_CMD;
170  l->m[1].data=new intvec;
171  int j=1;
172  while(j<=n)
173  {
174    while(j<n&&(MATELEM(M,j,j+1)==NULL||MATELEM(M,j+1,j)==NULL)||j==n)
175    {
176      l=addval(l,MATELEM(M,j,j),1);
177      MATELEM(M,j,j)=NULL;
178      j++;
179    }
180    if(j<n)
181    {
182      poly t=pOne();
183      pSetExp(t,1,1);
184      poly d0=pSub(MATELEM(M,j,j),t);
185      MATELEM(M,j,j)=NULL;
186      j++;
187      poly d1=pOne();
188      poly d2=NULL;
189      while(j<=n&&MATELEM(M,j,j-1)!=NULL&&MATELEM(M,j-1,j)!=NULL)
190      {
191        d2=d1;
192        d1=pCopy(d0);
193        poly t=pOne();
194        pSetExp(t,1,1);
195        d0=pSub(pMult(d0,pSub(MATELEM(M,j,j),t)),
196                pMult(pMult(d2,MATELEM(M,j-1,j)),MATELEM(M,j,j-1)));
197        MATELEM(M,j,j)=NULL;
198        MATELEM(M,j-1,j)=NULL;
199        MATELEM(M,j,j-1)=NULL;
200        j++;
201      }
202      pDelete(&d1);
203      intvec *m0=NULL;
204      ideal e0=singclap_factorize(d0,&m0,0);
205      pDelete(&d0);
206      for(int i=IDELEMS(e0)-1;i>=1;i--)
207      {
208        poly p=e0->m[i];
209        e0->m[i]=NULL;
210        poly p0,p1;
211        poly pp=p;
212        while(pp!=NULL&&pGetExp(pp,1)<=1)
213        {
214          if(pGetExp(pp,1)==0)
215            p0=pp;
216          else
217          if(pGetExp(pp,1)==1)
218            p1=pp;
219          pp=pNext(pp);
220        }
221        if(pp==NULL)
222        {
223          pp=p;
224          p=pNSet(nNeg(nDiv(nCopy(pGetCoeff(p0)),nCopy(pGetCoeff(p1)))));
225          pDelete(&pp);
226        }
227        else
228        {
229          p=pMult_nn(p,pGetCoeff(e0->m[0]));
230        }
231        l=addval(l,p,(*m0)[i]);
232      }
233      delete m0;
234      idDelete(&e0);
235    }
236  }
237  idDelete((ideal*)&M);
238  return sortval(l);
239}
240
241BOOLEAN tridiag(leftv res,leftv h)
242{
243  if(h!=NULL&&h->Typ()==MATRIX_CMD)
244  {
245    matrix M=(matrix)h->Data();
246    if(MATCOLS(M)!=MATROWS(M))
247    {
248      WerrorS("square matrix expected");
249    }
250    res->rtyp=MATRIX_CMD;
251    res->data=(void*)tridiag(mpCopy(M));
252    return FALSE;
253  }
254  WerrorS("<matrix> expected");
255}
256
257BOOLEAN eigenval(leftv res,leftv h)
258{
259  if(h!=NULL&&h->Typ()==MATRIX_CMD)
260  {
261    matrix M=(matrix)h->Data();
262    if(MATCOLS(M)!=MATROWS(M))
263    {
264      WerrorS("square matrix expected");
265    }
266    res->rtyp=LIST_CMD;
267    res->data=(void*)eigenval(mpCopy(M));
268    return FALSE;
269  }
270  WerrorS("<matrix> expected");
271}
272
273#endif
Note: See TracBrowser for help on using the repository browser.