1 /* 2 * Copyright(C) LinBox 3 * 4 * ========LICENCE======== 5 * This file is part of the library LinBox. 6 * 7 * LinBox is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 * ========LICENCE======== 21 * 22 * Written by Clément Pernet 23 */ 24 25 #pragma once 26 27 #include <linbox/matrix/dense-matrix.h> 28 #include <linbox/matrix/sparse-matrix.h> 29 #include <linbox/solutions/methods.h> 30 namespace LinBox { 31 // 32 // row echelon 33 // 34 35 /** 36 * \brief rowEchelon specialisation for DenseElimination with DenseMatrix and ModularTag. 37 */ 38 template <class Field> rowEchelon(DenseMatrix<Field> & E,const DenseMatrix<Field> & A,const RingCategories::ModularTag & tag,const Method::DenseElimination & M)39 inline size_t rowEchelon (DenseMatrix<Field>& E, const DenseMatrix<Field>& A, 40 const RingCategories::ModularTag& tag, const Method::DenseElimination& M) 41 { 42 linbox_check((A.coldim() == E.coldim()) && (A.rowdim() == E.rowdim())); 43 44 size_t m = A.rowdim(); 45 size_t n = A.coldim(); 46 size_t* P = new size_t[m]; 47 size_t* Q = new size_t[n]; 48 const Field& F = A.field(); 49 50 E = A; 51 52 size_t R = FFPACK::RowEchelonForm (F, m, n, E.getPointer(), E.getStride(), P, Q, false); 53 54 FFPACK::getEchelonForm (F, FFLAS::FflasUpper, FFLAS::FflasUnit, m, n, R, Q, 55 E.getPointer(), E.getStride()); 56 57 delete[] P; 58 delete[] Q; 59 return R; 60 } 61 62 63 /** 64 * \brief rowEchelon with transformation specialisation for DenseElimination with DenseMatrix and ModularTag. 65 */ 66 template <class Field> rowEchelon(DenseMatrix<Field> & E,DenseMatrix<Field> & T,const DenseMatrix<Field> & A,const RingCategories::ModularTag & tag,const Method::DenseElimination & M)67 inline size_t rowEchelon (DenseMatrix<Field>& E, DenseMatrix<Field>& T, const DenseMatrix<Field>& A, 68 const RingCategories::ModularTag& tag, const Method::DenseElimination& M) 69 { 70 linbox_check((A.coldim() == E.coldim()) && (A.rowdim() == E.rowdim()) && 71 (A.rowdim() == T.rowdim()) && (T.rowdim() == T.coldim()) ); 72 73 size_t m = A.rowdim(); 74 size_t n = A.coldim(); 75 size_t* P = new size_t[m]; 76 size_t* Q = new size_t[n]; 77 const Field& F = A.field(); 78 79 E = A; 80 81 size_t R = FFPACK::RowEchelonForm (F, m, n, E.getPointer(), E.getStride(), P, Q, false); 82 83 FFPACK::getEchelonTransform (F, FFLAS::FflasUpper, FFLAS::FflasUnit, m, n, R, P, Q, 84 E.getPointer(), E.getStride(), T.getPointer(), T.getStride()); 85 FFPACK::getEchelonForm (F, FFLAS::FflasUpper, FFLAS::FflasUnit, m, n, R, Q, 86 E.getPointer(), E.getStride()); 87 88 delete[] P; 89 delete[] Q; 90 return R; 91 } 92 93 // 94 // row echelonize 95 // 96 /** 97 * \brief rowEchelonize specialisation for DenseElimination with DenseMatrix and ModularTag. 98 */ 99 template <class Field> rowEchelonize(DenseMatrix<Field> & A,const RingCategories::ModularTag & tag,const Method::DenseElimination & M)100 inline size_t rowEchelonize (DenseMatrix<Field>& A, 101 const RingCategories::ModularTag& tag, const Method::DenseElimination& M) 102 { 103 104 size_t m = A.rowdim(); 105 size_t n = A.coldim(); 106 size_t* P = new size_t[m]; 107 size_t* Q = new size_t[n]; 108 const Field& F = A.field(); 109 110 size_t R = FFPACK::RowEchelonForm (F, m, n, A.getPointer(), A.getStride(), P, Q, false); 111 112 FFPACK::getEchelonForm (F, FFLAS::FflasUpper, FFLAS::FflasUnit, m, n, R, Q, 113 A.getPointer(), A.getStride()); 114 115 delete[] P; 116 delete[] Q; 117 return R; 118 } 119 120 /** 121 * \brief rowEchelonize with transformation specialisation for DenseElimination with DenseMatrix and ModularTag. 122 */ 123 template <class Field> rowEchelonize(DenseMatrix<Field> & A,DenseMatrix<Field> & T,const RingCategories::ModularTag & tag,const Method::DenseElimination & M)124 inline size_t rowEchelonize (DenseMatrix<Field>& A, DenseMatrix<Field>& T, 125 const RingCategories::ModularTag& tag, const Method::DenseElimination& M) 126 { 127 linbox_check((A.rowdim() == T.rowdim()) && (T.rowdim() == T.coldim())); 128 129 size_t m = A.rowdim(); 130 size_t n = A.coldim(); 131 size_t* P = new size_t[m]; 132 size_t* Q = new size_t[n]; 133 const Field& F = A.field(); 134 135 size_t R = FFPACK::RowEchelonForm (F, m, n, A.getPointer(), A.getStride(), P, Q, true); 136 137 FFPACK::getEchelonTransform (F, FFLAS::FflasUpper, FFLAS::FflasUnit, m, n, R, P, Q, 138 A.getPointer(), A.getStride(), T.getPointer(), T.getStride()); 139 FFPACK::getEchelonForm (F, FFLAS::FflasUpper, FFLAS::FflasUnit, m, n, R, Q, A.getPointer(), A.getStride()); 140 141 delete[] P; 142 delete[] Q; 143 return R; 144 } 145 146 // 147 // reduced row echelon 148 // 149 150 /** 151 * \brief reducedRowEchelon specialisation for DenseElimination with DenseMatrix and ModularTag. 152 */ 153 template <class Field> reducedRowEchelon(DenseMatrix<Field> & E,const DenseMatrix<Field> & A,const RingCategories::ModularTag & tag,const Method::DenseElimination & M)154 inline size_t reducedRowEchelon (DenseMatrix<Field>& E, const DenseMatrix<Field>& A, 155 const RingCategories::ModularTag& tag, const Method::DenseElimination& M) 156 { 157 linbox_check((A.coldim() == E.coldim()) && (A.rowdim() == E.rowdim())); 158 159 size_t m = A.rowdim(); 160 size_t n = A.coldim(); 161 size_t* P = new size_t[m]; 162 size_t* Q = new size_t[n]; 163 const Field& F = A.field(); 164 165 E = A; 166 167 size_t R = FFPACK::ReducedRowEchelonForm (F, m, n, E.getPointer(), E.getStride(), P, Q, false); 168 169 FFPACK::getReducedEchelonForm (F, FFLAS::FflasUpper, m, n, R, Q, E.getPointer(), E.getStride()); 170 171 delete[] P; 172 delete[] Q; 173 return R; 174 } 175 176 /** 177 * \brief reducedRowEchelon with transformation specialisation for DenseElimination with DenseMatrix and ModularTag. 178 */ 179 template <class Field> reducedRowEchelon(DenseMatrix<Field> & E,DenseMatrix<Field> & T,const DenseMatrix<Field> & A,const RingCategories::ModularTag & tag,const Method::DenseElimination & M)180 inline size_t reducedRowEchelon (DenseMatrix<Field>& E, DenseMatrix<Field>& T, const DenseMatrix<Field>& A, 181 const RingCategories::ModularTag& tag, const Method::DenseElimination& M) 182 { 183 linbox_check((A.coldim() == E.coldim()) && (A.rowdim() == E.rowdim()) && 184 (A.rowdim() == T.rowdim()) && (T.rowdim() == T.coldim()) ); 185 186 size_t m = A.rowdim(); 187 size_t n = A.coldim(); 188 size_t* P = new size_t[m]; 189 size_t* Q = new size_t[n]; 190 const Field& F = A.field(); 191 192 E = A; 193 194 size_t R = FFPACK::ReducedRowEchelonForm (F, m, n, E.getPointer(), E.getStride(), P, Q, false); 195 196 FFPACK::getReducedEchelonTransform (F, FFLAS::FflasUpper, FFLAS::FflasUnit, m, n, R, P, Q, 197 E.getPointer(), E.getStride(), T.getPointer(), T.getStride()); 198 FFPACK::getReducedEchelonForm (F, FFLAS::FflasUpper, m, n, R, Q, E.getPointer(), E.getStride()); 199 200 delete[] P; 201 delete[] Q; 202 return R; 203 } 204 205 // 206 // reduced row echelonize 207 // 208 209 /** 210 * \brief reducedRowEchelonize specialisation for DenseElimination with DenseMatrix and ModularTag. 211 */ 212 template <class Field> reducedRowEchelonize(DenseMatrix<Field> & A,const RingCategories::ModularTag & tag,const Method::DenseElimination & M)213 inline size_t reducedRowEchelonize (DenseMatrix<Field>& A, 214 const RingCategories::ModularTag& tag, const Method::DenseElimination& M) 215 { 216 size_t m = A.rowdim(); 217 size_t n = A.coldim(); 218 size_t* P = new size_t[m]; 219 size_t* Q = new size_t[n]; 220 const Field& F = A.field(); 221 222 size_t R = FFPACK::ReducedRowEchelonForm (F, m, n, A.getPointer(), A.getStride(), P, Q, false); 223 224 FFPACK::getReducedEchelonForm (F, FFLAS::FflasUpper, m, n, R, Q, 225 A.getPointer(), A.getStride()); 226 227 delete[] P; 228 delete[] Q; 229 return R; 230 } 231 232 /** 233 * \brief reducedRowEchelonize with transformation specialisation for DenseElimination with DenseMatrix and ModularTag. 234 */ 235 template <class Field> reducedRowEchelonize(DenseMatrix<Field> & A,DenseMatrix<Field> & T,const RingCategories::ModularTag & tag,const Method::DenseElimination & M)236 inline size_t reducedRowEchelonize (DenseMatrix<Field>& A, DenseMatrix<Field>& T, 237 const RingCategories::ModularTag& tag, const Method::DenseElimination& M) 238 { 239 linbox_check((A.rowdim() == T.rowdim()) && (T.rowdim() == T.coldim())); 240 241 size_t m = A.rowdim(); 242 size_t n = A.coldim(); 243 size_t* P = new size_t[m]; 244 size_t* Q = new size_t[n]; 245 const Field& F = A.field(); 246 247 size_t R = FFPACK::ReducedRowEchelonForm (F, m, n, A.getPointer(), A.getStride(), P, Q, true); 248 249 FFPACK::getReducedEchelonTransform (F, FFLAS::FflasUpper, FFLAS::FflasUnit, m, n, R, P, Q, 250 A.getPointer(), A.getStride(), T.getPointer(), T.getStride()); 251 FFPACK::getReducedEchelonForm (F, FFLAS::FflasUpper, m, n, R, Q, A.getPointer(), A.getStride()); 252 253 delete[] P; 254 delete[] Q; 255 return R; 256 } 257 258 // 259 // column echelon 260 // 261 262 /** 263 * \brief colEchelon specialisation for DenseElimination with DenseMatrix and ModularTag. 264 */ 265 template <class Field> colEchelon(DenseMatrix<Field> & E,const DenseMatrix<Field> & A,const RingCategories::ModularTag & tag,const Method::DenseElimination & M)266 inline size_t colEchelon (DenseMatrix<Field>& E, const DenseMatrix<Field>& A, 267 const RingCategories::ModularTag& tag, const Method::DenseElimination& M) 268 { 269 linbox_check((A.coldim() == E.coldim()) && (A.rowdim() == E.rowdim())); 270 271 size_t m = A.rowdim(); 272 size_t n = A.coldim(); 273 size_t* P = new size_t[n]; 274 size_t* Q = new size_t[m]; 275 const Field& F = A.field(); 276 277 E = A; 278 279 size_t R = FFPACK::ColumnEchelonForm (F, m, n, E.getPointer(), E.getStride(), P, Q, false); 280 281 FFPACK::getEchelonForm (F, FFLAS::FflasLower, FFLAS::FflasUnit, m, n, R, Q, 282 E.getPointer(), E.getStride()); 283 284 delete[] P; 285 delete[] Q; 286 return R; 287 } 288 289 290 /** 291 * \brief colEchelon with transformation specialisation for DenseElimination with DenseMatrix and ModularTag. 292 */ 293 template <class Field> colEchelon(DenseMatrix<Field> & E,DenseMatrix<Field> & T,const DenseMatrix<Field> & A,const RingCategories::ModularTag & tag,const Method::DenseElimination & M)294 inline size_t colEchelon (DenseMatrix<Field>& E, DenseMatrix<Field>& T, const DenseMatrix<Field>& A, 295 const RingCategories::ModularTag& tag, const Method::DenseElimination& M) 296 { 297 linbox_check((A.coldim() == E.coldim()) && (A.rowdim() == E.rowdim()) && 298 (A.coldim() == T.rowdim()) && (T.rowdim() == T.coldim()) ); 299 300 size_t m = A.rowdim(); 301 size_t n = A.coldim(); 302 size_t* P = new size_t[n]; 303 size_t* Q = new size_t[m]; 304 const Field& F = A.field(); 305 306 E = A; 307 308 size_t R = FFPACK::ColumnEchelonForm (F, m, n, E.getPointer(), E.getStride(), P, Q, false); 309 310 FFPACK::getEchelonTransform (F, FFLAS::FflasLower, FFLAS::FflasUnit, m, n, R, P, Q, 311 E.getPointer(), E.getStride(), T.getPointer(), T.getStride()); 312 FFPACK::getEchelonForm (F, FFLAS::FflasLower, FFLAS::FflasUnit, m, n, R, Q, 313 E.getPointer(), E.getStride()); 314 315 delete[] P; 316 delete[] Q; 317 return R; 318 } 319 320 // 321 // col echelonize 322 // 323 /** 324 * \brief colEchelonize specialisation for DenseElimination with DenseMatrix and ModularTag. 325 */ 326 template <class Field> colEchelonize(DenseMatrix<Field> & A,const RingCategories::ModularTag & tag,const Method::DenseElimination & M)327 inline size_t colEchelonize (DenseMatrix<Field>& A, 328 const RingCategories::ModularTag& tag, const Method::DenseElimination& M) 329 { 330 331 size_t m = A.rowdim(); 332 size_t n = A.coldim(); 333 size_t* P = new size_t[n]; 334 size_t* Q = new size_t[m]; 335 const Field& F = A.field(); 336 337 size_t R = FFPACK::ColumnEchelonForm (F, m, n, A.getPointer(), A.getStride(), P, Q, false); 338 339 FFPACK::getEchelonForm (F, FFLAS::FflasLower, FFLAS::FflasUnit, m, n, R, Q, 340 A.getPointer(), A.getStride()); 341 342 delete[] P; 343 delete[] Q; 344 return R; 345 } 346 347 /** 348 * \brief colEchelonize with transformation specialisation for DenseElimination with DenseMatrix and ModularTag. 349 */ 350 template <class Field> colEchelonize(DenseMatrix<Field> & A,DenseMatrix<Field> & T,const RingCategories::ModularTag & tag,const Method::DenseElimination & M)351 inline size_t colEchelonize (DenseMatrix<Field>& A, DenseMatrix<Field>& T, 352 const RingCategories::ModularTag& tag, const Method::DenseElimination& M) 353 { 354 linbox_check((A.coldim() == T.rowdim()) && (T.rowdim() == T.coldim())); 355 356 size_t m = A.rowdim(); 357 size_t n = A.coldim(); 358 size_t* P = new size_t[n]; 359 size_t* Q = new size_t[m]; 360 const Field& F = A.field(); 361 362 size_t R = FFPACK::ColumnEchelonForm (F, m, n, A.getPointer(), A.getStride(), P, Q, true); 363 364 FFPACK::getEchelonTransform (F, FFLAS::FflasLower, FFLAS::FflasUnit, m, n, R, P, Q, 365 A.getPointer(), A.getStride(), T.getPointer(), T.getStride()); 366 FFPACK::getEchelonForm (F, FFLAS::FflasLower, FFLAS::FflasUnit, m, n, R, Q, A.getPointer(), A.getStride()); 367 368 delete[] P; 369 delete[] Q; 370 return R; 371 } 372 373 // 374 // reduced col echelon 375 // 376 377 /** 378 * \brief reducedColEchelon specialisation for DenseElimination with DenseMatrix and ModularTag. 379 */ 380 template <class Field> reducedColEchelon(DenseMatrix<Field> & E,const DenseMatrix<Field> & A,const RingCategories::ModularTag & tag,const Method::DenseElimination & M)381 inline size_t reducedColEchelon (DenseMatrix<Field>& E, const DenseMatrix<Field>& A, 382 const RingCategories::ModularTag& tag, const Method::DenseElimination& M) 383 { 384 linbox_check((A.coldim() == E.coldim()) && (A.rowdim() == E.rowdim())); 385 386 size_t m = A.rowdim(); 387 size_t n = A.coldim(); 388 size_t* P = new size_t[n]; 389 size_t* Q = new size_t[m]; 390 const Field& F = A.field(); 391 392 E = A; 393 394 size_t R = FFPACK::ReducedColumnEchelonForm (F, m, n, E.getPointer(), E.getStride(), P, Q, false); 395 396 FFPACK::getReducedEchelonForm (F, FFLAS::FflasLower, m, n, R, Q, E.getPointer(), E.getStride()); 397 398 delete[] P; 399 delete[] Q; 400 return R; 401 } 402 403 /** 404 * \brief reducedColEchelon with transformation specialisation for DenseElimination with DenseMatrix and ModularTag. 405 */ 406 template <class Field> reducedColEchelon(DenseMatrix<Field> & E,DenseMatrix<Field> & T,const DenseMatrix<Field> & A,const RingCategories::ModularTag & tag,const Method::DenseElimination & M)407 inline size_t reducedColEchelon (DenseMatrix<Field>& E, DenseMatrix<Field>& T, const DenseMatrix<Field>& A, 408 const RingCategories::ModularTag& tag, const Method::DenseElimination& M) 409 { 410 linbox_check((A.coldim() == E.coldim()) && (A.rowdim() == E.rowdim()) && 411 (A.coldim() == T.rowdim()) && (T.rowdim() == T.coldim()) ); 412 413 size_t m = A.rowdim(); 414 size_t n = A.coldim(); 415 size_t* P = new size_t[n]; 416 size_t* Q = new size_t[m]; 417 const Field& F = A.field(); 418 419 E = A; 420 421 size_t R = FFPACK::ReducedColumnEchelonForm (F, m, n, E.getPointer(), E.getStride(), P, Q, false); 422 423 FFPACK::getReducedEchelonTransform (F, FFLAS::FflasLower, FFLAS::FflasUnit, m, n, R, P, Q, 424 E.getPointer(), E.getStride(), T.getPointer(), T.getStride()); 425 FFPACK::getReducedEchelonForm (F, FFLAS::FflasLower, m, n, R, Q, E.getPointer(), E.getStride()); 426 427 delete[] P; 428 delete[] Q; 429 return R; 430 } 431 432 // 433 // reduced col echelonize 434 // 435 436 /** 437 * \brief reducedColEchelonize specialisation for DenseElimination with DenseMatrix and ModularTag. 438 */ 439 template <class Field> reducedColEchelonize(DenseMatrix<Field> & A,const RingCategories::ModularTag & tag,const Method::DenseElimination & M)440 inline size_t reducedColEchelonize (DenseMatrix<Field>& A, 441 const RingCategories::ModularTag& tag, const Method::DenseElimination& M) 442 { 443 size_t m = A.rowdim(); 444 size_t n = A.coldim(); 445 size_t* P = new size_t[n]; 446 size_t* Q = new size_t[m]; 447 const Field& F = A.field(); 448 449 size_t R = FFPACK::ReducedColumnEchelonForm (F, m, n, A.getPointer(), A.getStride(), P, Q, false); 450 451 FFPACK::getReducedEchelonForm (F, FFLAS::FflasLower, m, n, R, Q, 452 A.getPointer(), A.getStride()); 453 454 delete[] P; 455 delete[] Q; 456 return R; 457 } 458 459 /** 460 * \brief reducedColEchelonize with transformation specialisation for DenseElimination with DenseMatrix and ModularTag. 461 */ 462 template <class Field> reducedColEchelonize(DenseMatrix<Field> & A,DenseMatrix<Field> & T,const RingCategories::ModularTag & tag,const Method::DenseElimination & M)463 inline size_t reducedColEchelonize (DenseMatrix<Field>& A, DenseMatrix<Field>& T, 464 const RingCategories::ModularTag& tag, const Method::DenseElimination& M) 465 { 466 linbox_check((A.coldim() == T.rowdim()) && (T.rowdim() == T.coldim())); 467 468 size_t m = A.rowdim(); 469 size_t n = A.coldim(); 470 size_t* P = new size_t[n]; 471 size_t* Q = new size_t[m]; 472 const Field& F = A.field(); 473 474 size_t R = FFPACK::ReducedColumnEchelonForm (F, m, n, A.getPointer(), A.getStride(), P, Q, true); 475 476 FFPACK::getReducedEchelonTransform (F, FFLAS::FflasLower, FFLAS::FflasUnit, m, n, R, P, Q, 477 A.getPointer(), A.getStride(), T.getPointer(), T.getStride()); 478 FFPACK::getReducedEchelonForm (F, FFLAS::FflasLower, m, n, R, Q, A.getPointer(), A.getStride()); 479 480 delete[] P; 481 delete[] Q; 482 return R; 483 } 484 } 485 /* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 486 // vim:sts=4:sw=4:ts=4:et:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s 487 488