/* =================================================================== * Copyright(C) LinBox 2008 * Written by Jean-Guillaume Dumas * Triangular Solve * * ========LICENCE======== * This file is part of the library LinBox. * * LinBox is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ========LICENCE======== *. * Time-stamp: <01 Oct 09 15:38:25 Jean-Guillaume.Dumas@imag.fr> * =================================================================== */ #ifndef __LINBOX_tri_solve_gf2_INL #define __LINBOX_tri_solve_gf2_INL #include "linbox/vector/vector-domain.h" #include "linbox/field/gf2.h" namespace LinBox { template Vector1& upperTriangularSolveBinary (Vector1& x, const _Matrix &U, const Vector2& b) { // linbox_check( x.size() == U.coldim() ); // linbox_check( b.size() == U.rowdim() ); typedef _Matrix Matrix; typedef GF2 Field; const GF2 F2; commentator().start ("Sparse Elimination Upper Triangular Solve over GF(2)", "utrsmGF2"); typename Vector2::const_iterator vec=b.begin(); typename Vector1::iterator res=x.begin(); typename Matrix::const_iterator row=U.begin(); // Find last constrained values of x, U and b // for( ; (res != x.end()) && (row != U.rowEnd()); ++res, ++row, ++vec) { } size_t last = x.size(); if( b.size() < last ) last = b.size(); res += (ptrdiff_t)last; row += (ptrdiff_t)last; vec += (ptrdiff_t) last; VectorCategories::DenseZeroOneVectorTag DZOtag; VectorCategories::SparseZeroOneVectorTag SZOtag; bool consistant = true; for(typename Vector2::const_iterator bcheck=vec; bcheck != b.end(); ++bcheck) { if( ! F2.isZero(*bcheck) ) { consistant = false; break; } } if (consistant) { --vec; --res; --row; VectorDomain VD(F2); for( ; row != U.begin(); --row, --vec, --res) { F2.assign(*res, F2.zero); if (row->size()) { typename Field::Element tmp; VD.dotSpecialized(tmp, x, *row, DZOtag, SZOtag); F2.addin(tmp,*vec); F2.assign(*res,tmp); } else { // Consistency check if( ! F2.isZero(*vec) ) { consistant = false; break; } } } F2.assign(*res, F2.zero); if (row->size()) { typename Field::Element tmp; VD.dotSpecialized(tmp, x, *row, DZOtag, SZOtag); F2.addin(tmp,*vec); F2.assign(*res,tmp); } else { // Consistency check if( ! F2.isZero(*vec) ) consistant = false; } } // if (! consistant) throw LinboxError ("upperTriangularSolveBinary returned INCONSISTENT"); linbox_check( consistant ); commentator().stop ("done", NULL, "utrsmGF2"); return x; } template Vector1& lowerTriangularUnitarySolveBinary (Vector1& x, const _Matrix &L, const Vector2& b) { linbox_check( b.size() == L.coldim() ); typedef _Matrix Matrix; const GF2 F2; commentator().start ("Sparse Elimination Lower Triangular Unitary Solve over GF2", "ltrsmGF2"); typename Vector2::const_iterator vec=b.begin(); typename Vector1::iterator res=x.begin(); typename Matrix::const_iterator row=L.begin(); VectorCategories::DenseZeroOneVectorTag DZOtag; VectorCategories::SparseZeroOneVectorTag SZOtag; VectorDomain VD(F2); for( ; row != L.end(); ++row, ++vec, ++res) { F2.assign(*res, F2.zero); GF2::Element tmp; VD.dotSpecialized(tmp, *row, x, SZOtag, DZOtag); F2.negin(tmp); F2.addin(tmp,*vec); F2.assign(*res,tmp); } commentator().stop ("done", NULL, "ltrsmGF2"); return x; } } #endif //__LINBOX_tri_solve_gf2_INL // Local Variables: // mode: C++ // tab-width: 4 // indent-tabs-mode: nil // c-basic-offset: 4 // End: // vim:sts=4:sw=4:ts=4:et:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s