2 diagonal-storage.cc -- implement Diagonal_storage
4 source file of the Flower Library
6 (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
10 #include "diagonal-storage.hh"
19 #include "full-storage.icc"
22 Diagonal_storage::dim()const
27 Diagonal_storage::Diagonal_storage()
32 Diagonal_storage::rows() const
38 Diagonal_storage::cols() const
44 Diagonal_storage::band_size_i()const
46 return (band_.cols()-1)/2;
50 Diagonal_storage::set_band_size(int s)
53 Full_storage f(dim(), 2*s+1);
54 for (int i=0; i < dim(); i++) {
56 for ( ; k < -band_size_i(); k++)
57 f.elem(i,k + s) = 0.0;
58 for ( ; k <= band_size_i()&& k<=s ; k++)
59 f.elem(i, k + s) = band_.elem(i,k+ band_size_i());
61 f.elem(i, k + s) =0.0;
73 Diagonal_storage::insert_row(int )
79 Diagonal_storage::delete_row(int )
85 Diagonal_storage::resize(int,int)
90 Diagonal_storage::resize(int)
95 Diagonal_storage::delete_column(int )
100 Diagonal_storage::~Diagonal_storage()
106 Diagonal_storage::band_elt_b(int i,int j)const
108 return abs(i-j) <= band_size_i();
112 Diagonal_storage::assert_valid(int i,int j )const
114 assert( band_elt_b(i,j) );
115 assert( i >=0 && j >=0 && i < dim() && j < dim());
120 Diagonal_storage::resize_dim(int d)
122 Full_storage f(d, 2*band_size_i()+1);
123 for (int i=0; i < d && i < dim(); i++) {
124 for ( int k=0; k < 2*band_size_i(); k++)
125 f.elem(i,k) = elem(i,k);
134 Diagonal_storage::mult_ok(int i,int )const
140 Diagonal_storage::mult_next(int &i, int &j)const
143 if ( j < i - band_size_i() )
144 j = i- band_size_i();
145 if ( j > i + band_size_i() || j >= dim() ) {
147 j = 0 >? i - band_size_i();
152 Diagonal_storage::trans_ok(int ,int j)const
158 Diagonal_storage::trans_next(int &i, int& j)const
161 if ( i < j - band_size_i())
164 if ( i >= dim() || i > j + band_size_i() ) {
166 i = 0 >? j - band_size_i();
170 static Real nul_entry=0.0;
173 Diagonal_storage::elem(int i, int j)const
175 if (abs ( i-j ) > band_size_i())
178 return band_.elem(i, j - i +band_size_i());
182 Diagonal_storage::elem(int i, int j)
185 if this fails, the previous call fucked up
189 if (abs ( i-j ) > band_size_i())
192 return band_.elem(i, j - i + band_size_i());
196 Hairy routine to try to save some fp-ops
200 Diagonal_storage::try_right_multiply(Matrix_storage*dest,
201 const Matrix_storage*right)const
203 if ( right->name() != Diagonal_storage::static_name() )
206 const Diagonal_storage* right_diag = (Diagonal_storage const*)right;
207 int band2 = right_diag->band_size_i();
210 should check if dest is a Diagonal_storage of sufficient size too.
212 for (int i=0; i < n; i++) {
213 for (int j = 0; j < n; j++) {
214 int startk = i - band_size_i() >? 0 >? j - band2;
215 int stopk = i + band_size_i() <? n-1 <? j + band2;
216 int relk = startk + band_size_i() -i;
218 for ( int k = startk; k <= stopk; k++)
219 sum += band_.elem(i, relk++) * right_diag->elem(k, j);
220 dest->elem(i, j) = sum;
227 IMPLEMENT_IS_TYPE_B1(Diagonal_storage, Matrix_storage);
230 Diagonal_storage::Diagonal_storage(Matrix_storage*stor_l, int band_i)
232 set_band_size(band_i);
233 resize_dim(stor_l->dim());
235 for ( int i=0,j=0; mult_ok(i,j); mult_next(i,j))
236 band_.elem(i, j + band_i -i ) = stor_l->elem(i,j);
240 Diagonal_storage::OK() const
245 IMPLEMENT_VIRTUAL_COPY_CONS(Diagonal_storage, Matrix_storage);