00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "vs.h"
00037
00038 extern MEM_POOL LNO_local_pool;
00039
00040 #ifndef vs_CXX
00041 #define vs_CXX "vs.cxx"
00042 static char *vs_template_rcs_id = vs_CXX "$Revision$";
00043 #endif
00044
00045 #ifndef __GNUC__
00046
00047
00048
00049 template <class T>
00050 VECTOR_SPACE<T>& VECTOR_SPACE<T>::operator = (const VECTOR_SPACE& vs) {
00051 _bv = vs._bv;
00052 _lud_is_valid = vs._lud_is_valid;
00053 if (_lud)
00054 CXX_DELETE(_lud, _pool);
00055 if (_lud_is_valid)
00056 _lud = CXX_NEW(LU_MAT<T>(*vs._lud, _pool), _pool);
00057 else
00058 _lud = NULL;
00059 return *this;
00060 }
00061
00062 template <class T>
00063 void VECTOR_SPACE<T>::Make_Bv_Aux() const
00064 {
00065 Is_True(_lud_is_valid, ("Bad call to Make_Bv_Aux()"));
00066
00067 ((VECTOR_SPACE<T>*)this)->_bv = _lud->Unfactor().Trans();
00068 ((VECTOR_SPACE<T>*)this)->_lud_is_valid = FALSE;
00069 #ifdef Is_True_On
00070 Sanity_Check();
00071 #endif
00072 }
00073
00074 template <class T>
00075 void VECTOR_SPACE<T>::Make_Lu_Aux() const
00076 {
00077 Is_True(!_lud_is_valid, ("Bad call to Make_Bv_Aux()"));
00078
00079 #ifdef Is_True_On
00080 Sanity_Check();
00081 #endif
00082
00083 if (_lud == NULL)
00084 ((VECTOR_SPACE<T>*)this)->_lud = CXX_NEW(LU_MAT<T>(_bv.Trans(), _pool),
00085 _pool);
00086 else
00087 *((VECTOR_SPACE<T>*)this)->_lud = LU_MAT<T>(_bv.Trans(), &LNO_local_pool);
00088
00089 ((VECTOR_SPACE<T>*)this)->_lud_is_valid = TRUE;
00090 }
00091
00092 template <class T>
00093 void VECTOR_SPACE<T>::Print(FILE *f, BOOL leave_lu) const
00094 {
00095 if (leave_lu && _lud_is_valid) {
00096 _lud->Print(f);
00097 return;
00098 }
00099
00100 Make_Bv();
00101
00102 fprintf(f, "basis vectors: {");
00103 for (INT i = 0; i < _bv.Rows(); i++) {
00104 if (i > 0)
00105 fprintf(f, ",(");
00106 else fprintf (f, "(");
00107 for (INT j = 0; j < _bv.Cols(); j++) {
00108 if (j > 0)
00109 fprintf(f, ",");
00110 Print_Element(f, _bv(i,j));
00111 }
00112 fprintf(f, ")");
00113 }
00114 fprintf(f, "}\n");
00115 }
00116
00117 template <class T>
00118 INT VECTOR_SPACE<T>::In(const T* w) const
00119 {
00120 Make_Lu();
00121
00122 INT r = _lud->LU_Matrix().Rows();
00123 INT c = _lud->LU_Matrix().Cols();
00124
00125
00126 for (INT i = 0; i < r; i++)
00127 if(w[i] != 0)
00128 break;
00129 if (i == r)
00130 return TRUE;
00131
00132
00133 INT curpivrow = 0;
00134 for (i = 0; i < c; i++)
00135 curpivrow += _lud->Is_Pivot(i);
00136 if (curpivrow == r)
00137 return TRUE;
00138
00139 T *hold = CXX_NEW_ARRAY(T, r, &LNO_local_pool);
00140 for (i = 0; i < r; i++)
00141 hold[i] = w[i];
00142
00143 _lud->Cfactor(hold, curpivrow);
00144
00145 BOOL rval = hold[curpivrow] == 0;
00146 CXX_DELETE_ARRAY(hold, &LNO_local_pool);
00147 return rval;
00148 }
00149
00150 template <class T>
00151 BOOL VECTOR_SPACE<T>::Insert(T* w)
00152 {
00153 Make_Lu();
00154 Reduce_Row(w, _bv.Cols());
00155 BOOL inserted = _lud->Cfactor_And_Insert(w, TRUE);
00156 return inserted;
00157 }
00158
00159 template <class T>
00160 VECTOR_SPACE<T>& VECTOR_SPACE<T>::operator +=(const VECTOR_SPACE<T>& v)
00161 {
00162 v.Make_Bv();
00163 const MAT<T>& mat = &v.Basis();
00164 for (INT i = 0; i < mat.Rows(); i++) {
00165 const T* w = &mat(i,0);
00166 Insert(w);
00167 }
00168 return *this;
00169 }
00170
00171 template <class T>
00172 MAT<T> VECTOR_SPACE<T>::Proj_Matrix() const
00173 {
00174
00175
00176 Make_Bv();
00177
00178 MAT<T> mt(_bv);
00179 MAT<T> m = mt.Trans();
00180 MAT<T> mtm = mt * m;
00181 MAT<T> mtm_inv = mtm.Inv();
00182 MAT<T> rv = m * mtm_inv * mt;
00183
00184 return rv;
00185 }
00186
00187 template <class T>
00188 VECTOR_SPACE<T>& VECTOR_SPACE<T>::operator -=(const VECTOR_SPACE<T>& vs)
00189 {
00190 if (D() == 0 || vs.D() == 0)
00191 return *this;
00192
00193 Make_Bv();
00194 MAT<T> pm = vs.Proj_Matrix();
00195
00196 VECTOR_SPACE<T> ret(_bv.Cols(), &LNO_local_pool);
00197
00198 T* space = CXX_NEW_ARRAY(T, vs.N(), &LNO_local_pool);
00199
00200 vs.Make_Bv();
00201 for (INT i = 0; i < D(); i++) {
00202 const T* v = &_bv(i,0);
00203 BOOL non_zero = FALSE;
00204 for (INT j = 0; j < vs.N(); j++) {
00205 space[j] = v[j];
00206 for (INT k = 0; k < vs.N(); k++)
00207 space[j] -= pm(j,k) * v[k];
00208 if (space[j] != 0)
00209 non_zero = TRUE;
00210 }
00211 if (non_zero)
00212 ret.Insert(space);
00213 }
00214
00215 CXX_DELETE_ARRAY(space, &LNO_local_pool);
00216
00217 *this = ret;
00218
00219 return *this;
00220 }
00221
00222 template <class T>
00223 BOOL VECTOR_SPACE<T>::Has_Only_Elemetary_Basis_Vectors() const
00224 {
00225 Make_Bv();
00226
00227 for (INT i = 0; i < _bv.Rows(); i++) {
00228 const T* w = &_bv(i,0);
00229 BOOL seen_one = FALSE;
00230 for (INT j = 0; j < _bv.Cols(); j++) {
00231 if (w[j] == 1) {
00232 if (seen_one == TRUE)
00233 return FALSE;
00234 seen_one = TRUE;
00235 }
00236 else if (w[j] != 0)
00237 return FALSE;
00238 }
00239 FmtAssert(seen_one, ("Zero basis vector"));
00240 }
00241
00242 return TRUE;
00243 }
00244
00245 template <class T>
00246 VECTOR_SPACE<T>& VECTOR_SPACE<T>::operator *=(const VECTOR_SPACE<T>& vs)
00247 {
00248 FmtAssert(N() == vs.N(), ("Illegal intersection %d, %d", N(), vs.N()));
00249
00250 INT n = N();
00251
00252
00253
00254 if (D() == 0)
00255 return *this;
00256 else if (vs.D() == 0)
00257 return *this = vs;
00258
00259 Make_Bv();
00260 vs.Make_Bv();
00261
00262
00263
00264
00265 if (Has_Only_Elemetary_Basis_Vectors() &&
00266 vs.Has_Only_Elemetary_Basis_Vectors()) {
00267 for (INT i = 0; i < _bv.Rows(); ) {
00268 const T* w = &_bv(i,0);
00269 for (INT j = 0; j < _bv.Cols(); j++) {
00270 if (w[j] == 1)
00271 break;
00272 }
00273 FmtAssert(j < _bv.Cols(), ("Bad elementary vector in *this"));
00274 for (INT ii = 0; ii < vs._bv.Rows(); ii++) {
00275 if (vs._bv(ii,j) == 1)
00276 break;
00277 }
00278 if (ii == vs._bv.Rows()) {
00279 if (i != _bv.Rows()-1)
00280 _bv.D_Swap_Rows(i, _bv.Rows()-1);
00281 _bv.D_Subtract_Rows(1);
00282 }
00283 else
00284 i++;
00285 }
00286 return *this;
00287 }
00288
00289
00290
00291
00292
00293
00294 MAT<T> Q(n, D() + vs.D(), &LNO_local_pool);
00295 for (INT i = 0; i < D(); i++) {
00296 for (INT j = 0; j < n; j++)
00297 Q(j,i) = _bv(i,j);
00298 }
00299 for (i = 0; i < vs.D(); i++) {
00300 for (INT j = 0; j < n; j++)
00301 Q(j,D()+i) = vs._bv(i,j);
00302 }
00303
00304
00305
00306 LU_MAT<T> luQ(Q, &LNO_local_pool);
00307 VECTOR_SPACE<T> kerQ(luQ, &LNO_local_pool);
00308 kerQ.Make_Bv();
00309
00310
00311
00312
00313 VECTOR_SPACE<T> answer(N(), &LNO_local_pool, FALSE);
00314
00315 FRAC* tmp = CXX_NEW_ARRAY(FRAC, n, &LNO_local_pool);
00316 for (i = 0; i < kerQ.D(); i++) {
00317
00318 for(INT j = 0; j < n; j++)
00319 tmp[j] = FRAC(0);
00320 for (INT ii = 0; ii < D(); ii++) {
00321 for (INT j = 0; j < n; j++)
00322 tmp[j] += kerQ._bv(i,ii) * _bv(ii,j);
00323 }
00324 FmtAssert(answer.In(tmp) == FALSE, ("Bug in intersection"));
00325 answer.Insert(tmp);
00326 }
00327 CXX_DELETE_ARRAY(tmp, &LNO_local_pool);
00328
00329 answer.Beautify();
00330 return *this = answer;
00331 }
00332
00333
00334
00335
00336 template <class T>
00337 VECTOR_SPACE<T>::VECTOR_SPACE(const LU_MAT<T>& lu, MEM_POOL *pool) :
00338 _bv(lu.LU_Matrix().Cols(), lu.LU_Matrix().Cols(), pool), _lud(NULL),
00339 _lud_is_valid(FALSE), _pool(pool)
00340 {
00341 T* x = CXX_NEW_ARRAY(T, lu.LU_Matrix().Rows(), &LNO_local_pool);
00342 T* zeros = CXX_NEW_ARRAY(T, lu.LU_Matrix().Rows(), &LNO_local_pool);
00343 T* ans = CXX_NEW_ARRAY(T, lu.LU_Matrix().Cols(), &LNO_local_pool);
00344
00345 _bv.D_Subtract_Rows(_bv.Rows());
00346
00347 for (INT i = 0; i < lu.LU_Matrix().Rows(); i++)
00348 zeros[i] = T(0);
00349
00350 for(INT f = 0; f < lu.LU_Matrix().Cols(); f++) {
00351
00352 if (!lu.Is_Pivot(f)) {
00353 if (!lu.U_Solve(zeros, ans, f))
00354 FmtAssert(0, ("Bad usolve in kernel computation"));
00355 if (!Insert(ans)) {
00356 FmtAssert(0, ("Bad insert in kernel computation"));
00357 }
00358 }
00359 }
00360
00361 CXX_DELETE_ARRAY(x, &LNO_local_pool);
00362 CXX_DELETE_ARRAY(zeros, &LNO_local_pool);
00363 CXX_DELETE_ARRAY(ans, &LNO_local_pool);
00364 }
00365
00366 template <class T>
00367 void VECTOR_SPACE<T>::Beautify() const
00368 {
00369 INT i;
00370 INT j;
00371
00372 T* x = CXX_NEW_ARRAY(T, N(), &LNO_local_pool);
00373
00374 VECTOR_SPACE hold(N(), &LNO_local_pool);
00375
00376
00377
00378
00379
00380 BOOL fine = TRUE;
00381
00382 Make_Bv();
00383 for (i = 0; fine && i < D(); i++) {
00384 INT the_non_zero = -1;
00385 for (j = 0; j < N(); j++) {
00386 if (_bv(i,j) != 0) {
00387 if (the_non_zero == -1)
00388 the_non_zero = j;
00389 else
00390 fine = FALSE;
00391 }
00392 }
00393 if (fine)
00394
00395 (*(MAT<T>*)&_bv)(i,the_non_zero) = T(1);
00396 }
00397 if (fine)
00398 return;
00399
00400
00401
00402 for (j = 0; j < N(); j++) {
00403 for(i = 0; i < N(); i++)
00404 x[i] = T(i==j);
00405 if (In(x))
00406 hold.Insert(x);
00407 }
00408
00409 *(VECTOR_SPACE<T>*)this -= hold;
00410
00411 Make_Bv();
00412 hold.Make_Bv();
00413 for (i = 0; i < hold.D(); i++)
00414 ((VECTOR_SPACE<T>*)this)->_bv.D_Add_Row(&hold._bv(i,0));
00415
00416 CXX_DELETE_ARRAY(x, &LNO_local_pool);
00417
00418 Reduce_Magnitude();
00419 }
00420
00421 template <class T>
00422 VECTOR_SPACE<T>* Read_VS(const char* cp, T dummy, MEM_POOL* pool)
00423 {
00424 VECTOR_SPACE<T>* rval = NULL;
00425 INT dim = -1;
00426
00427 cp = _Skip_Whitespace(cp);
00428 Is_True(*cp != '{', ("Bad Read input"));
00429 c++;
00430 while ((cp = _Skip_Whitespace(cp)), *cp == '(') {
00431 T entry[32];
00432 cp++;
00433 for (i = 0; i < 32; i++) {
00434 entry[i] = atoi(cp);
00435 while (*cp != ',' && *cp != ')')
00436 cp++;
00437 if (*cp == ')') {
00438 cp++;
00439 while (*cp != '}' && *cp != '(')
00440 cp++;
00441 break;
00442 }
00443 }
00444 if (rval == NULL) {
00445 dim = i;
00446 rval = CXX_NEW(VECTOR_SPACE(i, pool), pool);
00447 }
00448 else {
00449 FmtAssert(dim == i, ("Bug, dim != i"));
00450 }
00451 rval->Insert(entry);
00452 }
00453 FmtAssert(*cp == '}', ("expected '}'"));
00454 }
00455
00456 template <class T>
00457 void VECTOR_SPACE<T>::Sanity_Check() const
00458 {
00459 Make_Bv();
00460
00461 for (INT i = 0; i < _bv.Rows(); i++) {
00462 for (INT j = 0; j < _bv.Cols(); j++) {
00463 if (_bv(i,j) != 0)
00464 break;
00465 }
00466 FmtAssert(j < _bv.Cols(), ("Sanity check failed vector space!"));
00467 }
00468 }
00469
00470 template <class T>
00471 void VECTOR_SPACE<T>::Reduce_Magnitude() const
00472 {
00473 INT i;
00474
00475 Make_Bv();
00476
00477 for (i = 0; i < _bv.Rows(); i++) {
00478 Reduce_Row((T*)&_bv(i,0), _bv.Cols());
00479 }
00480 }
00481
00482 #endif