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"
13 Diagonal_storage::dim()const
18 Diagonal_storage::Diagonal_storage()
23 Diagonal_storage::rows() const
29 Diagonal_storage::cols() const
35 Diagonal_storage::band_size_i()const
37 return (band_.cols()-1)/2;
41 Diagonal_storage::set_band_size(int s)
43 Full_storage f(dim(), 2*s+1);
44 for (int i=0; i < dim(); i++) {
46 for ( ; k < -band_size_i(); k++)
47 f.elem(i,k + s) = 0.0;
48 for ( ; k <= band_size_i()&& k<=s ; k++)
49 f.elem(i, k + s) = band_.elem(i,k+ band_size_i());
51 f.elem(i, k + s) =0.0;
63 Diagonal_storage::insert_row(int )
69 Diagonal_storage::delete_row(int )
75 Diagonal_storage::resize(int,int)
80 Diagonal_storage::resize(int)
85 Diagonal_storage::delete_column(int )
90 Diagonal_storage::~Diagonal_storage()
96 Diagonal_storage::band_elt_b(int i,int j)const
98 return abs(i-j) <= band_size_i();
102 Diagonal_storage::assert_valid(int i,int j )const
104 assert( band_elt_b(i,j) );
105 assert( i >=0 && j >=0 && i < dim() && j < dim());
110 Diagonal_storage::resize_dim(int d)
112 Full_storage f(d, 2*band_size_i()+1);
113 for (int i=0; i < d&& i < dim(); i++) {
114 for ( int k=0; k < 2*band_size_i(); k++)
115 f.elem(i,k) = elem(i,k);
124 Diagonal_storage::mult_ok(int i,int )const
130 Diagonal_storage::mult_next(int &i, int &j)const
133 if ( j < i - band_size_i() )
134 j = i- band_size_i();
135 if ( j > i + band_size_i() || j >= dim() ) {
137 j = i - band_size_i();
144 Diagonal_storage::trans_ok(int ,int j)const
150 Diagonal_storage::trans_next(int &i, int& j)const
153 if ( i < j - band_size_i())
156 if ( i >= dim() || i > j + band_size_i() ) {
158 i = j - band_size_i();
164 static Real nul_entry=0.0;
167 Diagonal_storage::elem(int i, int j)const
169 if (abs ( i-j ) > band_size_i())
172 return band_.elem(i, j - i +band_size_i());
176 Diagonal_storage::elem(int i, int j)
179 if this fails, the previous call fucked up
182 if (abs ( i-j ) > band_size_i())
185 return band_.elem(i, j - i + band_size_i());
189 Hairy routine to try to save some fp-ops
193 Diagonal_storage::try_right_multiply(Matrix_storage*dest,
194 const Matrix_storage*right)const
196 if ( right->name() != Diagonal_storage::static_name() )
199 const Diagonal_storage* diag = (Diagonal_storage const*)right;
200 int band2 = diag->band_size_i();
203 should check if dest is a Diagonal_storage of sufficient size too.
205 for (int i=0; i < n; i++) {
206 for (int j = 0; j < n; j++) {
207 int startk = i - band_size_i() >? 0 >? j - band2;
208 int stopk = i + band_size_i() <? n-1 <? j + band2;
209 int relk = startk + band_size_i() -i;
211 for ( int k = startk; k <= stopk; k++)
212 sum += band_.elem(i, relk) * diag->elem(relk, j);
213 dest->elem(i, j) = sum;
220 IMPLEMENT_IS_TYPE_B1(Diagonal_storage, Matrix_storage);
223 Diagonal_storage::Diagonal_storage(Matrix_storage*stor_l, int band_i)
225 set_band_size(band_i);
226 resize_dim(stor_l->dim());
228 for ( int i=0,j=0; mult_ok(i,j); mult_next(i,j))
229 band_.elem(i, j + band_i -i ) = stor_l->elem(i,j);
233 Diagonal_storage::OK() const