source: git/Singular/eigenval.cc @ 110345

spielwiese
Last change on this file since 110345 was 15d67db, checked in by Mathias Schulze <mschulze@…>, 22 years ago
*** empty log message *** git-svn-id: file:///usr/local/Singular/svn/trunk@5903 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 7.5 KB
Line 
1/*****************************************
2*  Computer Algebra System SINGULAR      *
3*****************************************/
4/* $Id: eigenval.cc,v 1.11 2002-02-20 17:32:12 mschulze Exp $ */
5/*
6* ABSTRACT: eigenvalues of constant square matrices
7*/
8
9#include "mod2.h"
10
11#ifdef HAVE_EIGENVAL
12
13#include "febase.h"
14#include "tok.h"
15#include "ipid.h"
16#include "intvec.h"
17#include "numbers.h"
18#include "polys.h"
19#include "ideals.h"
20#include "lists.h"
21#include "matpol.h"
22#include "clapsing.h"
23#include "eigenval.h"
24
25
26matrix evSwap(matrix M,int i,int j)
27{
28  if(i==j)
29    return(M);
30
31  for(int k=1;k<=MATROWS(M);k++)
32  {
33    poly p=MATELEM(M,i,k);
34    MATELEM(M,i,k)=MATELEM(M,j,k);
35    MATELEM(M,j,k)=p;
36  }
37
38  for(int k=1;k<=MATCOLS(M);k++)
39  {
40    poly p=MATELEM(M,k,i);
41    MATELEM(M,k,i)=MATELEM(M,k,j);
42    MATELEM(M,k,j)=p;
43  }
44
45  return(M);
46}
47
48
49BOOLEAN evSwap(leftv res,leftv h)
50{
51  if(currRingHdl)
52  {
53    if(h&&h->Typ()==MATRIX_CMD)
54    {
55      matrix M=(matrix)h->Data();
56      h=h->next;
57      if(h&&h->Typ()==INT_CMD)
58      {
59        int i=(int)h->Data();
60        h=h->next;
61        if(h&&h->Typ()==INT_CMD)
62        {
63          int j=(int)h->Data();
64          res->rtyp=MATRIX_CMD;
65          res->data=(void *)evSwap(mpCopy(M),i,j);
66          return FALSE;
67        }
68      }
69    }
70    WerrorS("<matrix>,<int>,<int> expected");
71    return TRUE;
72  }
73  WerrorS("no ring active");
74  return TRUE;
75}
76
77
78matrix evRowElim(matrix M,int i,int j,int k)
79{
80  if(MATELEM(M,i,k)==NULL||MATELEM(M,j,k)==NULL)
81    return(M);
82
83  poly p=pNSet(nDiv(pGetCoeff(MATELEM(M,i,k)),pGetCoeff(MATELEM(M,j,k))));
84  pNormalize(p);
85
86  for(int l=1;l<=MATCOLS(M);l++)
87  {
88    MATELEM(M,i,l)=pSub(MATELEM(M,i,l),ppMult_qq(p,MATELEM(M,j,l)));
89    pNormalize(MATELEM(M,i,l));
90  }
91  for(int l=1;l<=MATROWS(M);l++)
92  {
93    MATELEM(M,l,j)=pAdd(MATELEM(M,l,j),ppMult_qq(p,MATELEM(M,l,i)));
94    pNormalize(MATELEM(M,l,j));
95  }
96
97  pDelete(&p);
98
99  return(M);
100}
101
102
103BOOLEAN evRowElim(leftv res,leftv h)
104{
105  if(currRingHdl)
106  {
107    if(h&&h->Typ()==MATRIX_CMD)
108    {
109      matrix M=(matrix)h->Data();
110      h=h->next;
111      if(h&&h->Typ()==INT_CMD)
112      {
113        int i=(int)h->Data();
114        h=h->next;
115        if(h&&h->Typ()==INT_CMD)
116        {
117          int j=(int)h->Data();
118          h=h->next;
119          if(h&&h->Typ()==INT_CMD)
120          {
121            int k=(int)h->Data();
122            res->rtyp=MATRIX_CMD;
123            res->data=(void *)evRowElim(mpCopy(M),i,j,k);
124            return FALSE;
125          }
126        }
127      }
128    }
129    WerrorS("<matrix>,<int>,<int>,<int> expected");
130    return TRUE;
131  }
132  WerrorS("no ring active");
133  return TRUE;
134}
135
136
137matrix evColElim(matrix M,int i,int j,int k)
138{
139  if(MATELEM(M,k,i)==0||MATELEM(M,k,j)==0)
140    return(M);
141
142  poly p=pNSet(nDiv(pGetCoeff(MATELEM(M,k,i)),pGetCoeff(MATELEM(M,k,j))));
143  pNormalize(p);
144
145  for(int l=1;l<=MATROWS(M);l++)
146  {
147    MATELEM(M,l,i)=pSub(MATELEM(M,l,i),ppMult_qq(p,MATELEM(M,l,j)));
148    pNormalize(MATELEM(M,l,i));
149  }
150  for(int l=1;l<=MATCOLS(M);l++)
151  {
152    MATELEM(M,j,l)=pAdd(MATELEM(M,j,l),ppMult_qq(p,MATELEM(M,i,l)));
153    pNormalize(MATELEM(M,j,l));
154  }
155
156  pDelete(&p);
157
158  return(M);
159}
160
161
162BOOLEAN evColElim(leftv res,leftv h)
163{
164  if(currRingHdl)
165  {
166    if(h&&h->Typ()==MATRIX_CMD)
167    {
168      matrix M=(matrix)h->Data();
169      h=h->next;
170      if(h&&h->Typ()==INT_CMD)
171      {
172        int i=(int)h->Data();
173        h=h->next;
174        if(h&&h->Typ()==INT_CMD)
175        {
176          int j=(int)h->Data();
177          h=h->next;
178          if(h&&h->Typ()==INT_CMD)
179          {
180            int k=(int)h->Data();
181            res->rtyp=MATRIX_CMD;
182            res->data=(void *)evColElim(mpCopy(M),i,j,k);
183            return FALSE;
184          }
185        }
186      }
187    }
188    WerrorS("<matrix>,<int>,<int>,<int> expected");
189    return TRUE;
190  }
191  WerrorS("no ring active");
192  return TRUE;
193}
194
195
196matrix evHessenberg(matrix M)
197{
198  int n=MATROWS(M);
199
200  for(int k=1,j=2;k<n-1;k++,j=k+1)
201  {
202    while(j<=n&&MATELEM(M,j,k)==0)
203      j++;
204
205    if(j<=n)
206    {
207      M=evSwap(M,j,k+1);
208
209      for(int i=j+1;i<=n;i++)
210        M=evRowElim(M,i,k+1,k);
211    }
212  }
213
214  return(M);
215}
216
217
218BOOLEAN evHessenberg(leftv res,leftv h)
219{
220  if(currRingHdl)
221  {
222    if(h&&h->Typ()==MATRIX_CMD)
223    {
224      matrix M=(matrix)h->Data();
225      res->rtyp=MATRIX_CMD;
226      res->data=(void *)evHessenberg(mpCopy(M));
227      return FALSE;
228    }
229    WerrorS("<matrix> expected");
230    return TRUE;
231  }
232  WerrorS("no ring active");
233  return TRUE;
234}
235
236
237lists evEigenvals(matrix M)
238{
239  lists l=(lists)omAllocBin(slists_bin);
240  if(MATROWS(M)!=MATCOLS(M))
241  {
242    l->Init(0);
243    return(l);
244  }
245
246  M=evHessenberg((matrix)idJet((ideal)M,0));
247
248  int n=MATROWS(M);
249  ideal e=idInit(n,1);
250  intvec *m=new intvec(n);
251
252  poly t=pOne();
253  pSetExp(t,1,1);
254  pSetm(t);
255
256  for(int j0=1,j=2,k=0;j<=n+1;j0=j,j++)
257  {
258    while(j<=n&&MATELEM(M,j,j-1)!=NULL)
259      j++;
260    if(j==j0+1)
261    {
262      e->m[k]=pHead(MATELEM(M,j0,j0));
263      (*m)[k]=1;
264      k++;
265    }
266    else
267    {
268      int n0=j-j0;
269      matrix M0=mpNew(n0,n0);
270
271      j0--;
272      for(int i=1;i<=n0;i++)
273        for(int j=1;j<=n0;j++)
274          MATELEM(M0,i,j)=pCopy(MATELEM(M,j0+i,j0+j));
275      for(int i=1;i<=n0;i++)
276        MATELEM(M0,i,i)=pSub(MATELEM(M0,i,i),pCopy(t));
277
278      intvec *m0;
279      ideal e0=singclap_factorize(mpDetBareiss(M0),&m0,2);
280
281      for(int i=0;i<IDELEMS(e0);i++)
282      {
283        if(pNext(e0->m[i])==NULL)
284        {
285          (*m)[k]=(*m0)[i];
286          k++;
287        }
288        else
289        if(pGetExp(e0->m[i],1)<2&&pGetExp(pNext(e0->m[i]),1)<2&&
290           pNext(pNext(e0->m[i]))==NULL)
291        {
292          number e1=nNeg(pGetCoeff(e0->m[i]));
293          if(pGetExp(pNext(e0->m[i]),1)==0)
294            e->m[k]=pNSet(nDiv(pGetCoeff(pNext(e0->m[i])),e1));
295          else
296            e->m[k]=pNSet(nDiv(e1,pGetCoeff(pNext(e0->m[i]))));
297          nDelete(&e1);
298          pNormalize(e->m[k]);
299          (*m)[k]=(*m0)[i];
300          k++;
301        }
302        else
303        {
304          e->m[k]=e0->m[i];
305          pNormalize(e->m[k]);
306          e0->m[i]=NULL;
307          (*m)[k]=(*m0)[i];
308          k++;
309        }
310      }
311
312      delete(m0);
313      idDelete(&e0);
314    }
315  }
316
317  pDelete(&t);
318  idDelete((ideal *)&M);
319
320  for(int i0=0;i0<n-1;i0++)
321  {
322    for(int i1=i0+1;i1<n;i1++)
323    {
324      if(pEqualPolys(e->m[i0],e->m[i1]))
325      {
326        (*m)[i0]+=(*m)[i1];
327        (*m)[i1]=0;
328      }
329      else
330      {
331        if(e->m[i0]==NULL&&!nGreaterZero(pGetCoeff(e->m[i1]))||
332           e->m[i1]==NULL&&
333          (nGreaterZero(pGetCoeff(e->m[i0]))||pNext(e->m[i0])!=NULL)||
334           e->m[i0]!=NULL&&e->m[i1]!=NULL&&
335          (pNext(e->m[i0])!=NULL&&pNext(e->m[i1])==NULL||
336           pNext(e->m[i0])==NULL&&pNext(e->m[i1])==NULL&&
337           nGreater(pGetCoeff(e->m[i0]),pGetCoeff(e->m[i1]))))
338        {
339          poly e1=e->m[i0];
340          e->m[i0]=e->m[i1];
341          e->m[i1]=e1;
342          int m1=(*m)[i0];
343          (*m)[i0]=(*m)[i1];
344          (*m)[i1]=m1;
345        }
346      }
347    }
348  }
349
350  int n0=0;
351  for(int i=0;i<n;i++)
352    if((*m)[i]>0)
353      n0++;
354
355  ideal e0=idInit(n0,1);
356  intvec *m0=new intvec(n0);
357
358  for(int i=0,i0=0;i<n;i++)
359    if((*m)[i]>0)
360    {
361      e0->m[i0]=e->m[i];
362      e->m[i]=NULL;
363      (*m0)[i0]=(*m)[i];
364      i0++;
365    }
366
367  idDelete(&e);
368  delete(m);
369
370  l->Init(2);
371  l->m[0].rtyp=IDEAL_CMD;
372  l->m[0].data=e0;
373  l->m[1].rtyp=INTVEC_CMD;
374  l->m[1].data=m0;
375
376  return(l);
377}
378
379
380BOOLEAN evEigenvals(leftv res,leftv h)
381{
382  if(currRingHdl)
383  {
384    if(h&&h->Typ()==MATRIX_CMD)
385    {
386      matrix M=(matrix)h->Data();
387      res->rtyp=LIST_CMD;
388      res->data=(void *)evEigenvals(mpCopy(M));
389      return FALSE;
390    }
391    WerrorS("<matrix> expected");
392    return TRUE;
393  }
394  WerrorS("no ring active");
395  return TRUE;
396}
397
398#endif /* HAVE_EIGENVAL */
Note: See TracBrowser for help on using the repository browser.