source: git/factory/lgs.cc @ ee668e

spielwiese
Last change on this file since ee668e was e4fe2b, checked in by Oleksandr Motsak <motsak@…>, 13 years ago
FIX: Fixed huge BUG in cf_gmp.h CHG: starting to cleanup factory
  • Property mode set to 100644
File size: 7.5 KB
Line 
1/* ===================================================================
2    Dateiname:          lgs.cc
3   =================================================================== */
4#include "config.h"
5
6#include "lgs.h"
7#include "bifacConfig.h"
8
9#ifdef HAVE_BIFAC
10
11//--<>---------------------------------
12LGS::LGS( int r, int c, bool inv )// KONSTRUKTOR
13//--<>---------------------------------
14{
15  INVERSE = inv;
16
17  max_columns = c;
18  max_rows    = (r>c) ? c : r ;
19
20  if( INVERSE )
21  {
22    c *=2;
23  }
24
25  CFMatrix  AA(max_rows, c);
26  CFMatrix  bb(max_rows, 1);
27  A=AA;
28  b=bb;
29  pivot = new int [max_columns+1]; // We start with index 1 (easier)
30  for( int i=0; i<=max_columns; i++)    pivot[i]=0;
31  now_row = 1;   // We start counting in the first row
32}
33
34
35//--<>---------------------------------
36LGS::~LGS( void )// DESTRUKTOR
37//--<>---------------------------------
38{
39  delete[] pivot;
40}
41
42//--<>---------------------------------
43void LGS::reset(void)
44//--<>---------------------------------
45{ // Clear the matrix for a new computation
46  now_row=1;
47  for( int i=0; i<=max_columns; i++)
48    pivot[i]=0;
49}
50
51//--<>---------------------------------
52bool LGS::new_row( const CFMatrix Z, const CanonicalForm bb)
53//--<>---------------------------------
54{ // Insert a new row
55  ASSERT ( (1 <= now_row && now_row <=max_rows), "wrong number of rows => Matrix has max. rank");
56  int i;
57
58//    if (INVERSE)
59//    cout << "* Integriere Zeile "<<now_row << " (max " <<max_rows<<" x "
60//         <<  max_columns << ")\n"
61//         << "Z = " << Z << "\nb = " << bb << endl << flush;
62
63
64
65
66  // === Insert a new row ===
67  for(i=1; i<=max_columns; i++)
68    A(now_row, i) = Z(1,i);
69  b(now_row, 1) = bb;
70
71
72  //  cout << "* reduzierte Matrix (vor lin_dep) " << A << endl;
73  // === check linear dependency ===
74  if ( ! lin_dep() )
75    now_row++;
76  else
77    return(false);
78
79  // === Reduce the previous rows ===
80  for(i=1; i<now_row-1; i++)
81    reduce(now_row-1,i );
82
83
84  //  cout << "\n* Zeile Z =" << Z << " ist integriert!\n" << A << flush;
85
86//    if( INVERSE ) cout << A;
87//  cout << "* Verlasse new_row!\n" << "* Z = " << Z << endl << flush;
88  return(true); // row was linear independent
89}
90
91
92//--<>---------------------------------
93bool LGS::lin_dep( void )
94//--<>---------------------------------
95{ // check if new row is linear dependent of the former ones
96
97  int i;
98
99  // === Reduce the actual row ===
100  for(i=1; i<now_row; i++)
101    reduce(i, now_row);
102
103//  cerr << "* Bin noch in [lin_dep]\n" << flush;
104
105  // === Quest for a pivot ===
106  for ( i=1; i<=max_columns; i++)
107    if( A(now_row,i) != 0 )
108    {
109      pivot[now_row] = i;
110      break;//      i = max_columns;
111
112    }
113//  cout << "* pivot["<<now_row<<"] = " << pivot[now_row] << endl << flush;
114
115  // === Is the reduced row (0,...,0)? ====
116  if( pivot[now_row] == 0 )
117  {
118    if( INVERSE )
119      for ( i=1; i<=max_columns; i++)
120        A(now_row, max_columns+i) = 0;
121    return (true);
122  }
123  // === The row is linear independent ====
124//  cout << "* reduzierte Matrix (1) ist " << A << endl;
125  if( INVERSE )   // Identity matrix
126    A(now_row, now_row+max_columns) = 1;
127//  cout << "* reduzierte Matrix (2) ist " << A << endl;
128  return(false);
129}
130
131
132//--<>---------------------------------
133void LGS::reduce(int fix, int row)
134//--<>---------------------------------
135{ // Reduce the `rowŽ by means of row `fixŽ
136
137  if( A(row, pivot[fix]) == 0 ) return;
138
139  CanonicalForm mul =  A(row, pivot[fix]) / A(fix, pivot[fix]);
140
141//    cout << "* Multiplikationsfaktor ist " << mul << endl;
142//    cout << "* Aktuelle Matrix ist " << A
143//         << "\n  b = " << b << endl;
144//    cout << "max_columns = "<< max_columns << endl;
145//    cout << "* now_row = " << now_row <<", row=" << row << endl << flush;
146//    cout << "* Pivot[" << row << "] = " << pivot[row] << endl << flush;
147//    cout << "* Pivot[" << fix << "] = " << pivot[fix] << endl << flush;
148
149
150  for (int i=1; i<=max_columns; i++)
151    if( A(fix,i) != 0 )
152      A(row, i) -= mul* A(fix,i);
153  if( b(fix,1) != 0 )
154    b(row,1) -= mul * b(fix,1);
155
156
157  if ( INVERSE )
158    for (int i=max_columns+1; i<=2*max_columns; i++)
159      if( A(fix,i) != 0 )
160        A(row, i) -= (mul* A(fix,i));
161//      A(row,i) = 777;
162
163//   cout << "* reduzierte Matrix ist " << A << endl;
164//    cout << "* Verlasse [reduce]\n" << flush;
165
166}
167///////////////////////////////////////////////////////
168// The Matrix (A | I) has maximal rank and
169// the ŽAŽ part has to be normalized only
170//--<>---------------------------------
171void LGS::inverse( CFMatrix & I )
172//--<>---------------------------------
173{
174  int i,j;
175  CanonicalForm mul;
176
177//  cout << "* PRÄ-Invers:" << A << endl;
178  for(i=1; i<=max_rows; i++)
179  {
180    for( j=max_columns+1; j<=2*max_columns; j++)
181      if( A(i,j)!=0 )
182        A(i,j) /= A( i, pivot[i]);
183    A( i, pivot[i]) = 1;
184  }
185// cout << "* Inverse Matrix ist " << A << endl;
186
187  for(i=1; i<=max_rows; i++)
188  {
189//    cout << "pivot["<<i<<"] = " << pivot[i]<< endl;
190    for(j=1; j<=max_columns; j++)
191      I(pivot[i],j) = A(i, j+max_columns);
192  }
193}
194//--<>---------------------------------
195int LGS::rank(void)
196//--<>---------------------------------
197{ // Return the current rank of the matrix
198  return( now_row-1);
199}
200
201
202//--<>---------------------------------
203void LGS::print(void)
204//--<>---------------------------------
205{ // Return the current rank of the matrix
206#ifndef NOSTREAMIO
207  cout << "A = " << A << "\nb = " << b << endl;
208#endif
209}
210
211
212
213
214//--<>---------------------------------
215int LGS::corank(void)
216//--<>---------------------------------
217{ // Return the current rank of the matrix
218  return(  ( (max_rows < max_columns ) ? max_rows : max_columns )-now_row+1 );
219}
220
221//--<>---------------------------------
222int LGS::ErgCol(int row, int basis[])
223//--<>---------------------------------
224{
225  bool state = false;
226
227  for( int i=1; i<=max_columns; i++)
228  {
229    if( A(row,i) != 0 )
230    {
231      state = true;
232      for( int j=1; j<=basis[0]; j++)
233        if( i==basis[j] )
234          state = false;
235      if( state == true )
236        return (i);
237    }
238  }
239  // A row contains only pivot entry/-ies
240  for( int j=1; j<=basis[0]; j++)
241    if(  A(row, basis[j]) != 0 )
242      return( -basis[j] );
243
244
245  AUSGABE_LGS("Zeile ist " << row << endl);
246  AUSGABE_ERR("* Mistake in [lgs.cc]! Impossible result. Aborting!\n");
247  exit (1);
248}
249
250
251//--<>---------------------------------
252CFMatrix LGS::GetKernelBasis(void)
253//--<>---------------------------------
254{
255  int i,z;
256  int dim = corank();
257
258  bool* tmp_vec = new bool[max_columns+1];
259  int*  basis   = new int [dim+1];
260  basis[0]=1;
261  CFMatrix erg  (dim, max_columns); // Each row is one solution
262
263  // === Searching free parameters ===
264  for( i=1; i<=max_rows; i++)
265    tmp_vec[i]=false;
266  for( i=1; i<now_row; i++)
267    if( pivot[i] != 0 )
268      tmp_vec[pivot[i]] = true;
269
270  for( i=1; i<=max_columns; i++)
271    if(tmp_vec[i] == false)
272    {
273      basis[basis[0]]=i;
274      basis[0]++;
275    }
276  ASSERT(basis[0]-1==dim, "Wrong dimensions");
277
278
279//    cout << "* Freie Parameter sind:";
280//    for ( int k=1; k<basis[0]; k++) cout << basis[k] << ", ";
281//    cout << endl;
282
283// === Creating the basis vectors ===
284  for(z=1; z<now_row; z++)
285    for(i=1; i<=dim; i++)
286    {
287      erg(i, basis[i]) = 1;
288      erg(i, pivot[z]) = -(A(z, basis[i]) / A(z,pivot[z]));
289    }
290
291//  cout << "Kernbasis ist " << erg;
292  return erg;
293}
294
295//--<>---------------------------------
296CFMatrix LGS::GetSolutionVector(void)
297//--<>---------------------------------
298{ // Ax=b has exactly one solution vector x
299  int z;
300  CFMatrix erg  (1, max_columns);
301
302  // === Creating the basis vectors ===
303  for(z=1; z<=max_columns; z++)
304  {
305    erg(1,pivot[z])  = b(z,1);         // Vector b
306    erg(1,pivot[z]) /= A(z,pivot[z]);
307  }
308  return erg;
309}
310#endif /* #ifdef HAVE_BIFAC */
311
Note: See TracBrowser for help on using the repository browser.