lilypond-1.2.15
[lilypond.git] / flower / matrix.cc
blobb671238ac50527c1ebb2b289f544345eb4a18493
1 /*
2 matrix.cc -- implement Matrix
4 source file of the Flower Library
6 (c) 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
9 #include "matrix.hh"
10 #include "full-storage.hh"
12 Real
13 Matrix::norm() const
15 Real r =0.0;
16 for (int i=0, j=0; dat_->mult_ok (i,j); dat_->mult_next (i,j))
17 r += sqr (dat_->elem (i,j));
18 return sqrt (r);
21 void
22 Matrix::fill (Real r)
24 for (int i=0, j=0; dat_->mult_ok (i,j); dat_->mult_next (i,j))
25 dat_->elem (i,j)=r;
28 void
29 Matrix::set_diag (Real r)
31 for (int i=0, j=0; dat_->mult_ok (i,j); dat_->mult_next (i,j))
32 dat_->elem (i,j)=(i==j) ? r: 0.0;
35 void
36 Matrix::set_diag (Vector d)
38 for (int i=0, j=0; dat_->mult_ok (i,j); dat_->mult_next (i,j))
39 dat_->elem (i,j)=(i==j) ? d (i): 0.0;
42 void
43 Matrix::operator+=(Matrix const &m)
45 assert (m.cols() == cols ());
46 assert (m.rows() == rows ());
47 for (int i=0, j=0; dat_->mult_ok (i,j); dat_->mult_next (i,j))
48 dat_->elem (i,j) += m (i,j);
51 void
52 Matrix::operator-=(Matrix const &m)
54 assert (m.cols() == cols ());
55 assert (m.rows() == rows ());
56 for (int i=0, j=0; dat_->mult_ok (i,j); dat_->mult_next (i,j))
57 dat_->elem (i,j) -= m (i,j);
61 void
62 Matrix::operator*=(Real a)
64 for (int i=0, j=0; dat_->mult_ok (i,j); dat_->mult_next (i,j))
65 dat_->elem (i,j) *= a;
68 void
69 Matrix::operator=(Matrix const &m)
71 if (&m == this)
72 return ;
73 delete dat_;
74 dat_ = new Full_storage (*m.dat_);
78 int
79 Matrix::band_i () const
81 return dat_->band_i_;
84 void
85 Matrix::set_band ()
87 dat_->band_i_ = calc_band_i ();
90 int
91 Matrix::calc_band_i() const
93 int starty = dim();
94 while (starty >= 0)
96 for (int i = starty, j = 0; i < dim(); i++, j++)
97 if (dat_->elem (i,j))
98 goto gotcha;
99 for (int i=0, j = starty; j < dim(); i++,j++)
100 if (dat_->elem (i,j))
101 goto gotcha;
102 starty --;
104 gotcha:
105 return starty;
108 Matrix::Matrix (Matrix const &m)
110 dat_ = new Full_storage (*m.dat_);
114 Matrix::Matrix (int n, int m)
116 dat_ = new Full_storage(n,m);
117 fill (0);
121 Matrix::Matrix (int n)
123 dat_= new Full_storage (n,n);
124 fill (0);
127 Matrix::Matrix (Vector v, Vector w)
129 int n = v.dim();
130 int m = w.dim ();
131 dat_= new Full_storage (n,m);
132 for (int i=0; i < n; i++)
133 for (int j=0; j < m ; j++)
134 dat_->elem (i,j)=v (i)*w (j);
138 Vector
139 Matrix::row (int k) const
141 int n=cols();
144 Vector v (n);
145 for (int i=0; i < n; i++)
146 v (i)=dat_->elem (k,i);
148 return v;
151 Vector
152 Matrix::col (int k) const
154 int n=rows();
155 Vector v (n);
156 for (int i=0; i < n; i++)
157 v (i)=dat_->elem (i,k);
158 return v;
161 Vector
162 Matrix::left_multiply (Vector const & v) const
164 Vector dest (v.dim());
165 assert (dat_->cols()==v.dim ());
166 for (int i=0, j=0; dat_->mult_ok (i,j); dat_->mult_next (i,j))
167 dest (i)+= dat_->elem (j,i)*v (j);
168 return dest;
171 Vector
172 Matrix::operator *(Vector const & v) const
174 Vector dest (rows());
175 assert (dat_->cols()==v.dim ());
176 for (int i=0, j=0; dat_->mult_ok (i,j); dat_->mult_next (i,j))
177 dest (i)+= dat_->elem (i,j)*v (j);
178 return dest;
181 Matrix
182 operator /(Matrix const& m1,Real a)
184 Matrix m (m1);
185 m /= a;
186 return m;
190 ugh. Only works for square matrices.
192 void
193 Matrix::transpose()
195 for (int i=0, j=0; dat_->mult_ok (i,j); dat_->mult_next (i,j))
197 if (i >= j)
198 continue;
199 Real r=dat_->elem (i,j);
200 dat_->elem (i,j) = dat_->elem (j,i);
201 dat_->elem (j,i)=r;
205 Matrix
206 Matrix::operator-() const
208 OK();
209 Matrix m (*this);
210 m*=-1.0;
211 return m;
214 Matrix
215 Matrix::transposed() const
217 Matrix m (*this);
218 m.transpose();
219 return m;
222 Matrix
223 operator *(Matrix const &m1, Matrix const &m2)
225 Matrix result (m1.rows (), m2.cols ());
226 result.set_product (m1,m2);
227 return result;
232 void
233 Matrix::set_product (Matrix const &m1, Matrix const &m2)
235 assert (m1.cols()==m2.rows ());
236 assert (cols()==m2.cols () && rows ()==m1.rows ());
238 for (int i=0; i < rows (); i++)
239 for (int j=0; j < cols (); j++)
241 Real r=0.0;
242 for (int k = 0 >? i - m1.band_i () >? j - m2.band_i ();
243 k < m1.cols(); k++)
245 r += m1(i,k)*m2(k,j);
247 dat_->elem (i,j)=r;
251 void
252 Matrix::insert_row (Vector v, int k)
254 int c = cols();
255 assert (v.dim()==cols ());
256 dat_->insert_row (k);
257 for (int j=0; j < c; j++)
258 dat_->elem (k,j)=v (j);
262 void
263 Matrix::swap_columns (int c1, int c2)
265 assert (c1>=0&& c1 < cols()&&c2 < cols () && c2 >=0);
266 int r = rows();
267 for (int i=0; i< r; i++)
269 Real r=dat_->elem (i,c1);
270 dat_->elem (i,c1) = dat_->elem (i,c2);
271 dat_->elem (i,c2)=r;
275 void
276 Matrix::swap_rows (int c1, int c2)
278 assert (c1>=0&& c1 < rows()&&c2 < rows () && c2 >=0);
279 int c = cols();
280 for (int i=0; i< c; i++)
282 Real r=dat_->elem (c1,i);
283 dat_->elem (c1,i) = dat_->elem (c2,i);
284 dat_->elem (c2,i)=r;
290 Matrix::dim() const
292 assert (cols() == rows ());
293 return rows();
296 Matrix::~Matrix ()
298 delete dat_;