Mercurial > octave
comparison liboctave/dSparse.cc @ 5275:23b37da9fd5b
[project @ 2005-04-08 16:07:35 by jwe]
author | jwe |
---|---|
date | Fri, 08 Apr 2005 16:07:37 +0000 |
parents | 90a9058de7e8 |
children | 4c8a2e4e0717 |
comparison
equal
deleted
inserted
replaced
5274:eae7b40388e9 | 5275:23b37da9fd5b |
---|---|
50 | 50 |
51 // Fortran functions we call. | 51 // Fortran functions we call. |
52 extern "C" | 52 extern "C" |
53 { | 53 { |
54 F77_RET_T | 54 F77_RET_T |
55 F77_FUNC (dgbtrf, DGBTRF) (const int&, const int&, const int&, | 55 F77_FUNC (dgbtrf, DGBTRF) (const octave_idx_type&, const int&, const octave_idx_type&, |
56 const int&, double*, const int&, int*, int&); | 56 const octave_idx_type&, double*, const octave_idx_type&, octave_idx_type*, octave_idx_type&); |
57 | 57 |
58 F77_RET_T | 58 F77_RET_T |
59 F77_FUNC (dgbtrs, DGBTRS) (F77_CONST_CHAR_ARG_DECL, const int&, | 59 F77_FUNC (dgbtrs, DGBTRS) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, |
60 const int&, const int&, const int&, | 60 const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, |
61 const double*, const int&, | 61 const double*, const octave_idx_type&, |
62 const int*, double*, const int&, int& | 62 const octave_idx_type*, double*, const octave_idx_type&, octave_idx_type& |
63 F77_CHAR_ARG_LEN_DECL); | 63 F77_CHAR_ARG_LEN_DECL); |
64 | 64 |
65 F77_RET_T | 65 F77_RET_T |
66 F77_FUNC (dgbcon, DGBCON) (F77_CONST_CHAR_ARG_DECL, const int&, | 66 F77_FUNC (dgbcon, DGBCON) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, |
67 const int&, const int&, double*, | 67 const octave_idx_type&, const octave_idx_type&, double*, |
68 const int&, const int*, const double&, | 68 const octave_idx_type&, const octave_idx_type*, const double&, |
69 double&, double*, int*, int& | 69 double&, double*, octave_idx_type*, octave_idx_type& |
70 F77_CHAR_ARG_LEN_DECL); | 70 F77_CHAR_ARG_LEN_DECL); |
71 | 71 |
72 F77_RET_T | 72 F77_RET_T |
73 F77_FUNC (dpbtrf, DPBTRF) (F77_CONST_CHAR_ARG_DECL, const int&, | 73 F77_FUNC (dpbtrf, DPBTRF) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, |
74 const int&, double*, const int&, int& | 74 const octave_idx_type&, double*, const octave_idx_type&, octave_idx_type& |
75 F77_CHAR_ARG_LEN_DECL); | 75 F77_CHAR_ARG_LEN_DECL); |
76 | 76 |
77 F77_RET_T | 77 F77_RET_T |
78 F77_FUNC (dpbtrs, DPBTRS) (F77_CONST_CHAR_ARG_DECL, const int&, | 78 F77_FUNC (dpbtrs, DPBTRS) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, |
79 const int&, const int&, double*, const int&, | 79 const octave_idx_type&, const octave_idx_type&, double*, const octave_idx_type&, |
80 double*, const int&, int& | 80 double*, const octave_idx_type&, octave_idx_type& |
81 F77_CHAR_ARG_LEN_DECL); | 81 F77_CHAR_ARG_LEN_DECL); |
82 | 82 |
83 F77_RET_T | 83 F77_RET_T |
84 F77_FUNC (dpbcon, DPBCON) (F77_CONST_CHAR_ARG_DECL, const int&, | 84 F77_FUNC (dpbcon, DPBCON) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, |
85 const int&, double*, const int&, | 85 const octave_idx_type&, double*, const octave_idx_type&, |
86 const double&, double&, double*, int*, int& | 86 const double&, double&, double*, octave_idx_type*, octave_idx_type& |
87 F77_CHAR_ARG_LEN_DECL); | 87 F77_CHAR_ARG_LEN_DECL); |
88 F77_RET_T | 88 F77_RET_T |
89 F77_FUNC (dptsv, DPTSV) (const int&, const int&, double*, double*, | 89 F77_FUNC (dptsv, DPTSV) (const octave_idx_type&, const octave_idx_type&, double*, double*, |
90 double*, const int&, int&); | 90 double*, const octave_idx_type&, octave_idx_type&); |
91 | 91 |
92 F77_RET_T | 92 F77_RET_T |
93 F77_FUNC (dgtsv, DGTSV) (const int&, const int&, double*, double*, | 93 F77_FUNC (dgtsv, DGTSV) (const octave_idx_type&, const octave_idx_type&, double*, double*, |
94 double*, double*, const int&, int&); | 94 double*, double*, const octave_idx_type&, octave_idx_type&); |
95 | 95 |
96 F77_RET_T | 96 F77_RET_T |
97 F77_FUNC (dgttrf, DGTTRF) (const int&, double*, double*, double*, double*, | 97 F77_FUNC (dgttrf, DGTTRF) (const octave_idx_type&, double*, double*, double*, double*, |
98 int*, int&); | 98 octave_idx_type*, octave_idx_type&); |
99 | 99 |
100 F77_RET_T | 100 F77_RET_T |
101 F77_FUNC (dgttrs, DGTTRS) (F77_CONST_CHAR_ARG_DECL, const int&, | 101 F77_FUNC (dgttrs, DGTTRS) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, |
102 const int&, const double*, const double*, | 102 const octave_idx_type&, const double*, const double*, |
103 const double*, const double*, const int*, | 103 const double*, const double*, const octave_idx_type*, |
104 double *, const int&, int& | 104 double *, const octave_idx_type&, octave_idx_type& |
105 F77_CHAR_ARG_LEN_DECL); | 105 F77_CHAR_ARG_LEN_DECL); |
106 | 106 |
107 F77_RET_T | 107 F77_RET_T |
108 F77_FUNC (zptsv, ZPTSV) (const int&, const int&, Complex*, Complex*, | 108 F77_FUNC (zptsv, ZPTSV) (const octave_idx_type&, const octave_idx_type&, Complex*, Complex*, |
109 Complex*, const int&, int&); | 109 Complex*, const octave_idx_type&, octave_idx_type&); |
110 | 110 |
111 F77_RET_T | 111 F77_RET_T |
112 F77_FUNC (zgtsv, ZGTSV) (const int&, const int&, Complex*, Complex*, | 112 F77_FUNC (zgtsv, ZGTSV) (const octave_idx_type&, const octave_idx_type&, Complex*, Complex*, |
113 Complex*, Complex*, const int&, int&); | 113 Complex*, Complex*, const octave_idx_type&, octave_idx_type&); |
114 | 114 |
115 } | 115 } |
116 | 116 |
117 SparseMatrix::SparseMatrix (const SparseBoolMatrix &a) | 117 SparseMatrix::SparseMatrix (const SparseBoolMatrix &a) |
118 : MSparse<double> (a.rows (), a.cols (), a.nnz ()) | 118 : MSparse<double> (a.rows (), a.cols (), a.nnz ()) |
119 { | 119 { |
120 int nc = cols (); | 120 octave_idx_type nc = cols (); |
121 int nz = nnz (); | 121 octave_idx_type nz = nnz (); |
122 | 122 |
123 for (int i = 0; i < nc + 1; i++) | 123 for (octave_idx_type i = 0; i < nc + 1; i++) |
124 cidx (i) = a.cidx (i); | 124 cidx (i) = a.cidx (i); |
125 | 125 |
126 for (int i = 0; i < nz; i++) | 126 for (octave_idx_type i = 0; i < nz; i++) |
127 { | 127 { |
128 data (i) = a.data (i); | 128 data (i) = a.data (i); |
129 ridx (i) = a.ridx (i); | 129 ridx (i) = a.ridx (i); |
130 } | 130 } |
131 } | 131 } |
132 | 132 |
133 bool | 133 bool |
134 SparseMatrix::operator == (const SparseMatrix& a) const | 134 SparseMatrix::operator == (const SparseMatrix& a) const |
135 { | 135 { |
136 int nr = rows (); | 136 octave_idx_type nr = rows (); |
137 int nc = cols (); | 137 octave_idx_type nc = cols (); |
138 int nz = nnz (); | 138 octave_idx_type nz = nnz (); |
139 int nr_a = a.rows (); | 139 octave_idx_type nr_a = a.rows (); |
140 int nc_a = a.cols (); | 140 octave_idx_type nc_a = a.cols (); |
141 int nz_a = a.nnz (); | 141 octave_idx_type nz_a = a.nnz (); |
142 | 142 |
143 if (nr != nr_a || nc != nc_a || nz != nz_a) | 143 if (nr != nr_a || nc != nc_a || nz != nz_a) |
144 return false; | 144 return false; |
145 | 145 |
146 for (int i = 0; i < nc + 1; i++) | 146 for (octave_idx_type i = 0; i < nc + 1; i++) |
147 if (cidx(i) != a.cidx(i)) | 147 if (cidx(i) != a.cidx(i)) |
148 return false; | 148 return false; |
149 | 149 |
150 for (int i = 0; i < nz; i++) | 150 for (octave_idx_type i = 0; i < nz; i++) |
151 if (data(i) != a.data(i) || ridx(i) != a.ridx(i)) | 151 if (data(i) != a.data(i) || ridx(i) != a.ridx(i)) |
152 return false; | 152 return false; |
153 | 153 |
154 return true; | 154 return true; |
155 } | 155 } |
163 bool | 163 bool |
164 SparseMatrix::is_symmetric (void) const | 164 SparseMatrix::is_symmetric (void) const |
165 { | 165 { |
166 if (is_square () && rows () > 0) | 166 if (is_square () && rows () > 0) |
167 { | 167 { |
168 for (int i = 0; i < rows (); i++) | 168 for (octave_idx_type i = 0; i < rows (); i++) |
169 for (int j = i+1; j < cols (); j++) | 169 for (octave_idx_type j = i+1; j < cols (); j++) |
170 if (elem (i, j) != elem (j, i)) | 170 if (elem (i, j) != elem (j, i)) |
171 return false; | 171 return false; |
172 | 172 |
173 return true; | 173 return true; |
174 } | 174 } |
175 | 175 |
176 return false; | 176 return false; |
177 } | 177 } |
178 | 178 |
179 SparseMatrix& | 179 SparseMatrix& |
180 SparseMatrix::insert (const SparseMatrix& a, int r, int c) | 180 SparseMatrix::insert (const SparseMatrix& a, octave_idx_type r, octave_idx_type c) |
181 { | 181 { |
182 MSparse<double>::insert (a, r, c); | 182 MSparse<double>::insert (a, r, c); |
183 return *this; | 183 return *this; |
184 } | 184 } |
185 | 185 |
186 SparseMatrix | 186 SparseMatrix |
187 SparseMatrix::max (int dim) const | 187 SparseMatrix::max (int dim) const |
188 { | 188 { |
189 Array2<int> dummy_idx; | 189 Array2<octave_idx_type> dummy_idx; |
190 return max (dummy_idx, dim); | 190 return max (dummy_idx, dim); |
191 } | 191 } |
192 | 192 |
193 SparseMatrix | 193 SparseMatrix |
194 SparseMatrix::max (Array2<int>& idx_arg, int dim) const | 194 SparseMatrix::max (Array2<octave_idx_type>& idx_arg, int dim) const |
195 { | 195 { |
196 SparseMatrix result; | 196 SparseMatrix result; |
197 dim_vector dv = dims (); | 197 dim_vector dv = dims (); |
198 | 198 |
199 if (dv.numel () == 0 || dim > dv.length () || dim < 0) | 199 if (dv.numel () == 0 || dim > dv.length () || dim < 0) |
200 return result; | 200 return result; |
201 | 201 |
202 int nr = dv(0); | 202 octave_idx_type nr = dv(0); |
203 int nc = dv(1); | 203 octave_idx_type nc = dv(1); |
204 | 204 |
205 if (dim == 0) | 205 if (dim == 0) |
206 { | 206 { |
207 idx_arg.resize (1, nc); | 207 idx_arg.resize (1, nc); |
208 int nel = 0; | 208 octave_idx_type nel = 0; |
209 for (int j = 0; j < nc; j++) | 209 for (octave_idx_type j = 0; j < nc; j++) |
210 { | 210 { |
211 double tmp_max = octave_NaN; | 211 double tmp_max = octave_NaN; |
212 int idx_j = 0; | 212 octave_idx_type idx_j = 0; |
213 for (int i = cidx(j); i < cidx(j+1); i++) | 213 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
214 { | 214 { |
215 if (ridx(i) != idx_j) | 215 if (ridx(i) != idx_j) |
216 break; | 216 break; |
217 else | 217 else |
218 idx_j++; | 218 idx_j++; |
219 } | 219 } |
220 | 220 |
221 if (idx_j != nr) | 221 if (idx_j != nr) |
222 tmp_max = 0.; | 222 tmp_max = 0.; |
223 | 223 |
224 for (int i = cidx(j); i < cidx(j+1); i++) | 224 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
225 { | 225 { |
226 double tmp = data (i); | 226 double tmp = data (i); |
227 | 227 |
228 if (octave_is_NaN_or_NA (tmp)) | 228 if (octave_is_NaN_or_NA (tmp)) |
229 continue; | 229 continue; |
240 nel++; | 240 nel++; |
241 } | 241 } |
242 | 242 |
243 result = SparseMatrix (1, nc, nel); | 243 result = SparseMatrix (1, nc, nel); |
244 | 244 |
245 int ii = 0; | 245 octave_idx_type ii = 0; |
246 result.xcidx (0) = 0; | 246 result.xcidx (0) = 0; |
247 for (int j = 0; j < nc; j++) | 247 for (octave_idx_type j = 0; j < nc; j++) |
248 { | 248 { |
249 double tmp = elem (idx_arg(j), j); | 249 double tmp = elem (idx_arg(j), j); |
250 if (tmp != 0.) | 250 if (tmp != 0.) |
251 { | 251 { |
252 result.xdata (ii) = tmp; | 252 result.xdata (ii) = tmp; |
258 } | 258 } |
259 else | 259 else |
260 { | 260 { |
261 idx_arg.resize (nr, 1, 0); | 261 idx_arg.resize (nr, 1, 0); |
262 | 262 |
263 for (int i = cidx(0); i < cidx(1); i++) | 263 for (octave_idx_type i = cidx(0); i < cidx(1); i++) |
264 idx_arg.elem(ridx(i)) = -1; | 264 idx_arg.elem(ridx(i)) = -1; |
265 | 265 |
266 for (int j = 0; j < nc; j++) | 266 for (octave_idx_type j = 0; j < nc; j++) |
267 for (int i = 0; i < nr; i++) | 267 for (octave_idx_type i = 0; i < nr; i++) |
268 { | 268 { |
269 if (idx_arg.elem(i) != -1) | 269 if (idx_arg.elem(i) != -1) |
270 continue; | 270 continue; |
271 bool found = false; | 271 bool found = false; |
272 for (int k = cidx(j); k < cidx(j+1); k++) | 272 for (octave_idx_type k = cidx(j); k < cidx(j+1); k++) |
273 if (ridx(k) == i) | 273 if (ridx(k) == i) |
274 { | 274 { |
275 found = true; | 275 found = true; |
276 break; | 276 break; |
277 } | 277 } |
279 if (!found) | 279 if (!found) |
280 idx_arg.elem(i) = j; | 280 idx_arg.elem(i) = j; |
281 | 281 |
282 } | 282 } |
283 | 283 |
284 for (int j = 0; j < nc; j++) | 284 for (octave_idx_type j = 0; j < nc; j++) |
285 { | 285 { |
286 for (int i = cidx(j); i < cidx(j+1); i++) | 286 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
287 { | 287 { |
288 int ir = ridx (i); | 288 octave_idx_type ir = ridx (i); |
289 int ix = idx_arg.elem (ir); | 289 octave_idx_type ix = idx_arg.elem (ir); |
290 double tmp = data (i); | 290 double tmp = data (i); |
291 | 291 |
292 if (octave_is_NaN_or_NA (tmp)) | 292 if (octave_is_NaN_or_NA (tmp)) |
293 continue; | 293 continue; |
294 else if (ix == -1 || tmp > elem (ir, ix)) | 294 else if (ix == -1 || tmp > elem (ir, ix)) |
295 idx_arg.elem (ir) = j; | 295 idx_arg.elem (ir) = j; |
296 } | 296 } |
297 } | 297 } |
298 | 298 |
299 int nel = 0; | 299 octave_idx_type nel = 0; |
300 for (int j = 0; j < nr; j++) | 300 for (octave_idx_type j = 0; j < nr; j++) |
301 if (idx_arg.elem(j) == -1 || elem (j, idx_arg.elem (j)) != 0.) | 301 if (idx_arg.elem(j) == -1 || elem (j, idx_arg.elem (j)) != 0.) |
302 nel++; | 302 nel++; |
303 | 303 |
304 result = SparseMatrix (nr, 1, nel); | 304 result = SparseMatrix (nr, 1, nel); |
305 | 305 |
306 int ii = 0; | 306 octave_idx_type ii = 0; |
307 result.xcidx (0) = 0; | 307 result.xcidx (0) = 0; |
308 result.xcidx (1) = nel; | 308 result.xcidx (1) = nel; |
309 for (int j = 0; j < nr; j++) | 309 for (octave_idx_type j = 0; j < nr; j++) |
310 { | 310 { |
311 if (idx_arg(j) == -1) | 311 if (idx_arg(j) == -1) |
312 { | 312 { |
313 idx_arg(j) = 0; | 313 idx_arg(j) = 0; |
314 result.xdata (ii) = octave_NaN; | 314 result.xdata (ii) = octave_NaN; |
330 } | 330 } |
331 | 331 |
332 SparseMatrix | 332 SparseMatrix |
333 SparseMatrix::min (int dim) const | 333 SparseMatrix::min (int dim) const |
334 { | 334 { |
335 Array2<int> dummy_idx; | 335 Array2<octave_idx_type> dummy_idx; |
336 return min (dummy_idx, dim); | 336 return min (dummy_idx, dim); |
337 } | 337 } |
338 | 338 |
339 SparseMatrix | 339 SparseMatrix |
340 SparseMatrix::min (Array2<int>& idx_arg, int dim) const | 340 SparseMatrix::min (Array2<octave_idx_type>& idx_arg, int dim) const |
341 { | 341 { |
342 SparseMatrix result; | 342 SparseMatrix result; |
343 dim_vector dv = dims (); | 343 dim_vector dv = dims (); |
344 | 344 |
345 if (dv.numel () == 0 || dim > dv.length () || dim < 0) | 345 if (dv.numel () == 0 || dim > dv.length () || dim < 0) |
346 return result; | 346 return result; |
347 | 347 |
348 int nr = dv(0); | 348 octave_idx_type nr = dv(0); |
349 int nc = dv(1); | 349 octave_idx_type nc = dv(1); |
350 | 350 |
351 if (dim == 0) | 351 if (dim == 0) |
352 { | 352 { |
353 idx_arg.resize (1, nc); | 353 idx_arg.resize (1, nc); |
354 int nel = 0; | 354 octave_idx_type nel = 0; |
355 for (int j = 0; j < nc; j++) | 355 for (octave_idx_type j = 0; j < nc; j++) |
356 { | 356 { |
357 double tmp_min = octave_NaN; | 357 double tmp_min = octave_NaN; |
358 int idx_j = 0; | 358 octave_idx_type idx_j = 0; |
359 for (int i = cidx(j); i < cidx(j+1); i++) | 359 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
360 { | 360 { |
361 if (ridx(i) != idx_j) | 361 if (ridx(i) != idx_j) |
362 break; | 362 break; |
363 else | 363 else |
364 idx_j++; | 364 idx_j++; |
365 } | 365 } |
366 | 366 |
367 if (idx_j != nr) | 367 if (idx_j != nr) |
368 tmp_min = 0.; | 368 tmp_min = 0.; |
369 | 369 |
370 for (int i = cidx(j); i < cidx(j+1); i++) | 370 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
371 { | 371 { |
372 double tmp = data (i); | 372 double tmp = data (i); |
373 | 373 |
374 if (octave_is_NaN_or_NA (tmp)) | 374 if (octave_is_NaN_or_NA (tmp)) |
375 continue; | 375 continue; |
386 nel++; | 386 nel++; |
387 } | 387 } |
388 | 388 |
389 result = SparseMatrix (1, nc, nel); | 389 result = SparseMatrix (1, nc, nel); |
390 | 390 |
391 int ii = 0; | 391 octave_idx_type ii = 0; |
392 result.xcidx (0) = 0; | 392 result.xcidx (0) = 0; |
393 for (int j = 0; j < nc; j++) | 393 for (octave_idx_type j = 0; j < nc; j++) |
394 { | 394 { |
395 double tmp = elem (idx_arg(j), j); | 395 double tmp = elem (idx_arg(j), j); |
396 if (tmp != 0.) | 396 if (tmp != 0.) |
397 { | 397 { |
398 result.xdata (ii) = tmp; | 398 result.xdata (ii) = tmp; |
404 } | 404 } |
405 else | 405 else |
406 { | 406 { |
407 idx_arg.resize (nr, 1, 0); | 407 idx_arg.resize (nr, 1, 0); |
408 | 408 |
409 for (int i = cidx(0); i < cidx(1); i++) | 409 for (octave_idx_type i = cidx(0); i < cidx(1); i++) |
410 idx_arg.elem(ridx(i)) = -1; | 410 idx_arg.elem(ridx(i)) = -1; |
411 | 411 |
412 for (int j = 0; j < nc; j++) | 412 for (octave_idx_type j = 0; j < nc; j++) |
413 for (int i = 0; i < nr; i++) | 413 for (octave_idx_type i = 0; i < nr; i++) |
414 { | 414 { |
415 if (idx_arg.elem(i) != -1) | 415 if (idx_arg.elem(i) != -1) |
416 continue; | 416 continue; |
417 bool found = false; | 417 bool found = false; |
418 for (int k = cidx(j); k < cidx(j+1); k++) | 418 for (octave_idx_type k = cidx(j); k < cidx(j+1); k++) |
419 if (ridx(k) == i) | 419 if (ridx(k) == i) |
420 { | 420 { |
421 found = true; | 421 found = true; |
422 break; | 422 break; |
423 } | 423 } |
425 if (!found) | 425 if (!found) |
426 idx_arg.elem(i) = j; | 426 idx_arg.elem(i) = j; |
427 | 427 |
428 } | 428 } |
429 | 429 |
430 for (int j = 0; j < nc; j++) | 430 for (octave_idx_type j = 0; j < nc; j++) |
431 { | 431 { |
432 for (int i = cidx(j); i < cidx(j+1); i++) | 432 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
433 { | 433 { |
434 int ir = ridx (i); | 434 octave_idx_type ir = ridx (i); |
435 int ix = idx_arg.elem (ir); | 435 octave_idx_type ix = idx_arg.elem (ir); |
436 double tmp = data (i); | 436 double tmp = data (i); |
437 | 437 |
438 if (octave_is_NaN_or_NA (tmp)) | 438 if (octave_is_NaN_or_NA (tmp)) |
439 continue; | 439 continue; |
440 else if (ix == -1 || tmp < elem (ir, ix)) | 440 else if (ix == -1 || tmp < elem (ir, ix)) |
441 idx_arg.elem (ir) = j; | 441 idx_arg.elem (ir) = j; |
442 } | 442 } |
443 } | 443 } |
444 | 444 |
445 int nel = 0; | 445 octave_idx_type nel = 0; |
446 for (int j = 0; j < nr; j++) | 446 for (octave_idx_type j = 0; j < nr; j++) |
447 if (idx_arg.elem(j) == -1 || elem (j, idx_arg.elem (j)) != 0.) | 447 if (idx_arg.elem(j) == -1 || elem (j, idx_arg.elem (j)) != 0.) |
448 nel++; | 448 nel++; |
449 | 449 |
450 result = SparseMatrix (nr, 1, nel); | 450 result = SparseMatrix (nr, 1, nel); |
451 | 451 |
452 int ii = 0; | 452 octave_idx_type ii = 0; |
453 result.xcidx (0) = 0; | 453 result.xcidx (0) = 0; |
454 result.xcidx (1) = nel; | 454 result.xcidx (1) = nel; |
455 for (int j = 0; j < nr; j++) | 455 for (octave_idx_type j = 0; j < nr; j++) |
456 { | 456 { |
457 if (idx_arg(j) == -1) | 457 if (idx_arg(j) == -1) |
458 { | 458 { |
459 idx_arg(j) = 0; | 459 idx_arg(j) = 0; |
460 result.xdata (ii) = octave_NaN; | 460 result.xdata (ii) = octave_NaN; |
474 | 474 |
475 return result; | 475 return result; |
476 } | 476 } |
477 | 477 |
478 SparseMatrix | 478 SparseMatrix |
479 SparseMatrix::concat (const SparseMatrix& rb, const Array<int>& ra_idx) | 479 SparseMatrix::concat (const SparseMatrix& rb, const Array<octave_idx_type>& ra_idx) |
480 { | 480 { |
481 // Don't use numel to avoid all possiblity of an overflow | 481 // Don't use numel to avoid all possiblity of an overflow |
482 if (rb.rows () > 0 && rb.cols () > 0) | 482 if (rb.rows () > 0 && rb.cols () > 0) |
483 insert (rb, ra_idx(0), ra_idx(1)); | 483 insert (rb, ra_idx(0), ra_idx(1)); |
484 return *this; | 484 return *this; |
485 } | 485 } |
486 | 486 |
487 SparseComplexMatrix | 487 SparseComplexMatrix |
488 SparseMatrix::concat (const SparseComplexMatrix& rb, const Array<int>& ra_idx) | 488 SparseMatrix::concat (const SparseComplexMatrix& rb, const Array<octave_idx_type>& ra_idx) |
489 { | 489 { |
490 SparseComplexMatrix retval (*this); | 490 SparseComplexMatrix retval (*this); |
491 if (rb.rows () > 0 && rb.cols () > 0) | 491 if (rb.rows () > 0 && rb.cols () > 0) |
492 retval.insert (rb, ra_idx(0), ra_idx(1)); | 492 retval.insert (rb, ra_idx(0), ra_idx(1)); |
493 return retval; | 493 return retval; |
494 } | 494 } |
495 | 495 |
496 SparseMatrix | 496 SparseMatrix |
497 real (const SparseComplexMatrix& a) | 497 real (const SparseComplexMatrix& a) |
498 { | 498 { |
499 int nr = a.rows (); | 499 octave_idx_type nr = a.rows (); |
500 int nc = a.cols (); | 500 octave_idx_type nc = a.cols (); |
501 int nz = a.nnz (); | 501 octave_idx_type nz = a.nnz (); |
502 SparseMatrix r (nr, nc, nz); | 502 SparseMatrix r (nr, nc, nz); |
503 | 503 |
504 for (int i = 0; i < nc +1; i++) | 504 for (octave_idx_type i = 0; i < nc +1; i++) |
505 r.cidx(i) = a.cidx(i); | 505 r.cidx(i) = a.cidx(i); |
506 | 506 |
507 for (int i = 0; i < nz; i++) | 507 for (octave_idx_type i = 0; i < nz; i++) |
508 { | 508 { |
509 r.data(i) = std::real (a.data(i)); | 509 r.data(i) = std::real (a.data(i)); |
510 r.ridx(i) = a.ridx(i); | 510 r.ridx(i) = a.ridx(i); |
511 } | 511 } |
512 | 512 |
514 } | 514 } |
515 | 515 |
516 SparseMatrix | 516 SparseMatrix |
517 imag (const SparseComplexMatrix& a) | 517 imag (const SparseComplexMatrix& a) |
518 { | 518 { |
519 int nr = a.rows (); | 519 octave_idx_type nr = a.rows (); |
520 int nc = a.cols (); | 520 octave_idx_type nc = a.cols (); |
521 int nz = a.nnz (); | 521 octave_idx_type nz = a.nnz (); |
522 SparseMatrix r (nr, nc, nz); | 522 SparseMatrix r (nr, nc, nz); |
523 | 523 |
524 for (int i = 0; i < nc +1; i++) | 524 for (octave_idx_type i = 0; i < nc +1; i++) |
525 r.cidx(i) = a.cidx(i); | 525 r.cidx(i) = a.cidx(i); |
526 | 526 |
527 for (int i = 0; i < nz; i++) | 527 for (octave_idx_type i = 0; i < nz; i++) |
528 { | 528 { |
529 r.data(i) = std::imag (a.data(i)); | 529 r.data(i) = std::imag (a.data(i)); |
530 r.ridx(i) = a.ridx(i); | 530 r.ridx(i) = a.ridx(i); |
531 } | 531 } |
532 | 532 |
534 } | 534 } |
535 | 535 |
536 SparseMatrix | 536 SparseMatrix |
537 atan2 (const double& x, const SparseMatrix& y) | 537 atan2 (const double& x, const SparseMatrix& y) |
538 { | 538 { |
539 int nr = y.rows (); | 539 octave_idx_type nr = y.rows (); |
540 int nc = y.cols (); | 540 octave_idx_type nc = y.cols (); |
541 | 541 |
542 if (x == 0.) | 542 if (x == 0.) |
543 return SparseMatrix (nr, nc); | 543 return SparseMatrix (nr, nc); |
544 else | 544 else |
545 { | 545 { |
546 // Its going to be basically full, so this is probably the | 546 // Its going to be basically full, so this is probably the |
547 // best way to handle it. | 547 // best way to handle it. |
548 Matrix tmp (nr, nc, atan2 (x, 0.)); | 548 Matrix tmp (nr, nc, atan2 (x, 0.)); |
549 | 549 |
550 for (int j = 0; j < nc; j++) | 550 for (octave_idx_type j = 0; j < nc; j++) |
551 for (int i = y.cidx (j); i < y.cidx (j+1); i++) | 551 for (octave_idx_type i = y.cidx (j); i < y.cidx (j+1); i++) |
552 tmp.elem (y.ridx(i), j) = atan2 (x, y.data(i)); | 552 tmp.elem (y.ridx(i), j) = atan2 (x, y.data(i)); |
553 | 553 |
554 return SparseMatrix (tmp); | 554 return SparseMatrix (tmp); |
555 } | 555 } |
556 } | 556 } |
557 | 557 |
558 SparseMatrix | 558 SparseMatrix |
559 atan2 (const SparseMatrix& x, const double& y) | 559 atan2 (const SparseMatrix& x, const double& y) |
560 { | 560 { |
561 int nr = x.rows (); | 561 octave_idx_type nr = x.rows (); |
562 int nc = x.cols (); | 562 octave_idx_type nc = x.cols (); |
563 int nz = x.nnz (); | 563 octave_idx_type nz = x.nnz (); |
564 | 564 |
565 SparseMatrix retval (nr, nc, nz); | 565 SparseMatrix retval (nr, nc, nz); |
566 | 566 |
567 int ii = 0; | 567 octave_idx_type ii = 0; |
568 retval.xcidx(0) = 0; | 568 retval.xcidx(0) = 0; |
569 for (int i = 0; i < nc; i++) | 569 for (octave_idx_type i = 0; i < nc; i++) |
570 { | 570 { |
571 for (int j = x.cidx(i); j < x.cidx(i+1); j++) | 571 for (octave_idx_type j = x.cidx(i); j < x.cidx(i+1); j++) |
572 { | 572 { |
573 double tmp = atan2 (x.data(j), y); | 573 double tmp = atan2 (x.data(j), y); |
574 if (tmp != 0.) | 574 if (tmp != 0.) |
575 { | 575 { |
576 retval.xdata (ii) = tmp; | 576 retval.xdata (ii) = tmp; |
581 } | 581 } |
582 | 582 |
583 if (ii != nz) | 583 if (ii != nz) |
584 { | 584 { |
585 SparseMatrix retval2 (nr, nc, ii); | 585 SparseMatrix retval2 (nr, nc, ii); |
586 for (int i = 0; i < nc+1; i++) | 586 for (octave_idx_type i = 0; i < nc+1; i++) |
587 retval2.xcidx (i) = retval.cidx (i); | 587 retval2.xcidx (i) = retval.cidx (i); |
588 for (int i = 0; i < ii; i++) | 588 for (octave_idx_type i = 0; i < ii; i++) |
589 { | 589 { |
590 retval2.xdata (i) = retval.data (i); | 590 retval2.xdata (i) = retval.data (i); |
591 retval2.xridx (i) = retval.ridx (i); | 591 retval2.xridx (i) = retval.ridx (i); |
592 } | 592 } |
593 return retval2; | 593 return retval2; |
601 { | 601 { |
602 SparseMatrix r; | 602 SparseMatrix r; |
603 | 603 |
604 if ((x.rows() == y.rows()) && (x.cols() == y.cols())) | 604 if ((x.rows() == y.rows()) && (x.cols() == y.cols())) |
605 { | 605 { |
606 int x_nr = x.rows (); | 606 octave_idx_type x_nr = x.rows (); |
607 int x_nc = x.cols (); | 607 octave_idx_type x_nc = x.cols (); |
608 | 608 |
609 int y_nr = y.rows (); | 609 octave_idx_type y_nr = y.rows (); |
610 int y_nc = y.cols (); | 610 octave_idx_type y_nc = y.cols (); |
611 | 611 |
612 if (x_nr != y_nr || x_nc != y_nc) | 612 if (x_nr != y_nr || x_nc != y_nc) |
613 gripe_nonconformant ("atan2", x_nr, x_nc, y_nr, y_nc); | 613 gripe_nonconformant ("atan2", x_nr, x_nc, y_nr, y_nc); |
614 else | 614 else |
615 { | 615 { |
616 r = SparseMatrix (x_nr, x_nc, (x.nnz () + y.nnz ())); | 616 r = SparseMatrix (x_nr, x_nc, (x.nnz () + y.nnz ())); |
617 | 617 |
618 int jx = 0; | 618 octave_idx_type jx = 0; |
619 r.cidx (0) = 0; | 619 r.cidx (0) = 0; |
620 for (int i = 0 ; i < x_nc ; i++) | 620 for (octave_idx_type i = 0 ; i < x_nc ; i++) |
621 { | 621 { |
622 int ja = x.cidx(i); | 622 octave_idx_type ja = x.cidx(i); |
623 int ja_max = x.cidx(i+1); | 623 octave_idx_type ja_max = x.cidx(i+1); |
624 bool ja_lt_max= ja < ja_max; | 624 bool ja_lt_max= ja < ja_max; |
625 | 625 |
626 int jb = y.cidx(i); | 626 octave_idx_type jb = y.cidx(i); |
627 int jb_max = y.cidx(i+1); | 627 octave_idx_type jb_max = y.cidx(i+1); |
628 bool jb_lt_max = jb < jb_max; | 628 bool jb_lt_max = jb < jb_max; |
629 | 629 |
630 while (ja_lt_max || jb_lt_max ) | 630 while (ja_lt_max || jb_lt_max ) |
631 { | 631 { |
632 OCTAVE_QUIT; | 632 OCTAVE_QUIT; |
673 } | 673 } |
674 | 674 |
675 SparseMatrix | 675 SparseMatrix |
676 SparseMatrix::inverse (void) const | 676 SparseMatrix::inverse (void) const |
677 { | 677 { |
678 int info; | 678 octave_idx_type info; |
679 double rcond; | 679 double rcond; |
680 return inverse (info, rcond, 0, 0); | 680 return inverse (info, rcond, 0, 0); |
681 } | 681 } |
682 | 682 |
683 SparseMatrix | 683 SparseMatrix |
684 SparseMatrix::inverse (int& info) const | 684 SparseMatrix::inverse (octave_idx_type& info) const |
685 { | 685 { |
686 double rcond; | 686 double rcond; |
687 return inverse (info, rcond, 0, 0); | 687 return inverse (info, rcond, 0, 0); |
688 } | 688 } |
689 | 689 |
690 SparseMatrix | 690 SparseMatrix |
691 SparseMatrix::inverse (int& info, double& rcond, int force, int calc_cond) const | 691 SparseMatrix::inverse (octave_idx_type& info, double& rcond, int force, int calc_cond) const |
692 { | 692 { |
693 info = -1; | 693 info = -1; |
694 (*current_liboctave_error_handler) | 694 (*current_liboctave_error_handler) |
695 ("SparseMatrix::inverse not implemented yet"); | 695 ("SparseMatrix::inverse not implemented yet"); |
696 return SparseMatrix (); | 696 return SparseMatrix (); |
697 } | 697 } |
698 | 698 |
699 DET | 699 DET |
700 SparseMatrix::determinant (void) const | 700 SparseMatrix::determinant (void) const |
701 { | 701 { |
702 int info; | 702 octave_idx_type info; |
703 double rcond; | 703 double rcond; |
704 return determinant (info, rcond, 0); | 704 return determinant (info, rcond, 0); |
705 } | 705 } |
706 | 706 |
707 DET | 707 DET |
708 SparseMatrix::determinant (int& info) const | 708 SparseMatrix::determinant (octave_idx_type& info) const |
709 { | 709 { |
710 double rcond; | 710 double rcond; |
711 return determinant (info, rcond, 0); | 711 return determinant (info, rcond, 0); |
712 } | 712 } |
713 | 713 |
714 DET | 714 DET |
715 SparseMatrix::determinant (int& err, double& rcond, int) const | 715 SparseMatrix::determinant (octave_idx_type& err, double& rcond, int) const |
716 { | 716 { |
717 DET retval; | 717 DET retval; |
718 | 718 |
719 #ifdef HAVE_UMFPACK | 719 #ifdef HAVE_UMFPACK |
720 int nr = rows (); | 720 octave_idx_type nr = rows (); |
721 int nc = cols (); | 721 octave_idx_type nc = cols (); |
722 | 722 |
723 if (nr == 0 || nc == 0 || nr != nc) | 723 if (nr == 0 || nc == 0 || nr != nc) |
724 { | 724 { |
725 double d[2]; | 725 double d[2]; |
726 d[0] = 1.0; | 726 d[0] = 1.0; |
755 // Turn-off UMFPACK scaling for LU | 755 // Turn-off UMFPACK scaling for LU |
756 Control (UMFPACK_SCALE) = UMFPACK_SCALE_NONE; | 756 Control (UMFPACK_SCALE) = UMFPACK_SCALE_NONE; |
757 | 757 |
758 umfpack_di_report_control (control); | 758 umfpack_di_report_control (control); |
759 | 759 |
760 const int *Ap = cidx (); | 760 const octave_idx_type *Ap = cidx (); |
761 const int *Ai = ridx (); | 761 const octave_idx_type *Ai = ridx (); |
762 const double *Ax = data (); | 762 const double *Ax = data (); |
763 | 763 |
764 umfpack_di_report_matrix (nr, nc, Ap, Ai, Ax, 1, control); | 764 umfpack_di_report_matrix (nr, nc, Ap, Ai, Ax, 1, control); |
765 | 765 |
766 void *Symbolic; | 766 void *Symbolic; |
830 | 830 |
831 return retval; | 831 return retval; |
832 } | 832 } |
833 | 833 |
834 Matrix | 834 Matrix |
835 SparseMatrix::dsolve (SparseType &mattype, const Matrix& b, int& err, | 835 SparseMatrix::dsolve (SparseType &mattype, const Matrix& b, octave_idx_type& err, |
836 double& rcond, solve_singularity_handler) const | 836 double& rcond, solve_singularity_handler) const |
837 { | 837 { |
838 Matrix retval; | 838 Matrix retval; |
839 | 839 |
840 int nr = rows (); | 840 octave_idx_type nr = rows (); |
841 int nc = cols (); | 841 octave_idx_type nc = cols (); |
842 err = 0; | 842 err = 0; |
843 | 843 |
844 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) | 844 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) |
845 (*current_liboctave_error_handler) | 845 (*current_liboctave_error_handler) |
846 ("matrix dimension mismatch solution of linear equations"); | 846 ("matrix dimension mismatch solution of linear equations"); |
853 if (typ == SparseType::Diagonal || | 853 if (typ == SparseType::Diagonal || |
854 typ == SparseType::Permuted_Diagonal) | 854 typ == SparseType::Permuted_Diagonal) |
855 { | 855 { |
856 retval.resize (b.rows (), b.cols()); | 856 retval.resize (b.rows (), b.cols()); |
857 if (typ == SparseType::Diagonal) | 857 if (typ == SparseType::Diagonal) |
858 for (int j = 0; j < b.cols(); j++) | 858 for (octave_idx_type j = 0; j < b.cols(); j++) |
859 for (int i = 0; i < nr; i++) | 859 for (octave_idx_type i = 0; i < nr; i++) |
860 retval(i,j) = b(i,j) / data (i); | 860 retval(i,j) = b(i,j) / data (i); |
861 else | 861 else |
862 for (int j = 0; j < b.cols(); j++) | 862 for (octave_idx_type j = 0; j < b.cols(); j++) |
863 for (int i = 0; i < nr; i++) | 863 for (octave_idx_type i = 0; i < nr; i++) |
864 retval(i,j) = b(ridx(i),j) / data (i); | 864 retval(i,j) = b(ridx(i),j) / data (i); |
865 | 865 |
866 double dmax = 0., dmin = octave_Inf; | 866 double dmax = 0., dmin = octave_Inf; |
867 for (int i = 0; i < nr; i++) | 867 for (octave_idx_type i = 0; i < nr; i++) |
868 { | 868 { |
869 double tmp = fabs(data(i)); | 869 double tmp = fabs(data(i)); |
870 if (tmp > dmax) | 870 if (tmp > dmax) |
871 dmax = tmp; | 871 dmax = tmp; |
872 if (tmp < dmin) | 872 if (tmp < dmin) |
880 | 880 |
881 return retval; | 881 return retval; |
882 } | 882 } |
883 | 883 |
884 SparseMatrix | 884 SparseMatrix |
885 SparseMatrix::dsolve (SparseType &mattype, const SparseMatrix& b, int& err, | 885 SparseMatrix::dsolve (SparseType &mattype, const SparseMatrix& b, octave_idx_type& err, |
886 double& rcond, solve_singularity_handler) const | 886 double& rcond, solve_singularity_handler) const |
887 { | 887 { |
888 SparseMatrix retval; | 888 SparseMatrix retval; |
889 | 889 |
890 int nr = rows (); | 890 octave_idx_type nr = rows (); |
891 int nc = cols (); | 891 octave_idx_type nc = cols (); |
892 err = 0; | 892 err = 0; |
893 | 893 |
894 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) | 894 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) |
895 (*current_liboctave_error_handler) | 895 (*current_liboctave_error_handler) |
896 ("matrix dimension mismatch solution of linear equations"); | 896 ("matrix dimension mismatch solution of linear equations"); |
901 mattype.info (); | 901 mattype.info (); |
902 | 902 |
903 if (typ == SparseType::Diagonal || | 903 if (typ == SparseType::Diagonal || |
904 typ == SparseType::Permuted_Diagonal) | 904 typ == SparseType::Permuted_Diagonal) |
905 { | 905 { |
906 int b_nr = b.rows (); | 906 octave_idx_type b_nr = b.rows (); |
907 int b_nc = b.cols (); | 907 octave_idx_type b_nc = b.cols (); |
908 int b_nz = b.nnz (); | 908 octave_idx_type b_nz = b.nnz (); |
909 retval = SparseMatrix (b_nr, b_nc, b_nz); | 909 retval = SparseMatrix (b_nr, b_nc, b_nz); |
910 | 910 |
911 retval.xcidx(0) = 0; | 911 retval.xcidx(0) = 0; |
912 int ii = 0; | 912 octave_idx_type ii = 0; |
913 if (typ == SparseType::Diagonal) | 913 if (typ == SparseType::Diagonal) |
914 for (int j = 0; j < b.cols(); j++) | 914 for (octave_idx_type j = 0; j < b.cols(); j++) |
915 { | 915 { |
916 for (int i = b.cidx(j); i < b.cidx(j+1); i++) | 916 for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) |
917 { | 917 { |
918 retval.xridx (ii) = b.ridx(i); | 918 retval.xridx (ii) = b.ridx(i); |
919 retval.xdata (ii++) = b.data(i) / data (b.ridx (i)); | 919 retval.xdata (ii++) = b.data(i) / data (b.ridx (i)); |
920 } | 920 } |
921 retval.xcidx(j+1) = ii; | 921 retval.xcidx(j+1) = ii; |
922 } | 922 } |
923 else | 923 else |
924 for (int j = 0; j < b.cols(); j++) | 924 for (octave_idx_type j = 0; j < b.cols(); j++) |
925 { | 925 { |
926 for (int i = 0; i < nr; i++) | 926 for (octave_idx_type i = 0; i < nr; i++) |
927 { | 927 { |
928 bool found = false; | 928 bool found = false; |
929 int k; | 929 octave_idx_type k; |
930 for (k = b.cidx(j); k < b.cidx(j+1); k++) | 930 for (k = b.cidx(j); k < b.cidx(j+1); k++) |
931 if (ridx(i) == b.ridx(k)) | 931 if (ridx(i) == b.ridx(k)) |
932 { | 932 { |
933 found = true; | 933 found = true; |
934 break; | 934 break; |
941 } | 941 } |
942 retval.xcidx(j+1) = ii; | 942 retval.xcidx(j+1) = ii; |
943 } | 943 } |
944 | 944 |
945 double dmax = 0., dmin = octave_Inf; | 945 double dmax = 0., dmin = octave_Inf; |
946 for (int i = 0; i < nr; i++) | 946 for (octave_idx_type i = 0; i < nr; i++) |
947 { | 947 { |
948 double tmp = fabs(data(i)); | 948 double tmp = fabs(data(i)); |
949 if (tmp > dmax) | 949 if (tmp > dmax) |
950 dmax = tmp; | 950 dmax = tmp; |
951 if (tmp < dmin) | 951 if (tmp < dmin) |
959 | 959 |
960 return retval; | 960 return retval; |
961 } | 961 } |
962 | 962 |
963 ComplexMatrix | 963 ComplexMatrix |
964 SparseMatrix::dsolve (SparseType &mattype, const ComplexMatrix& b, int& err, | 964 SparseMatrix::dsolve (SparseType &mattype, const ComplexMatrix& b, octave_idx_type& err, |
965 double& rcond, solve_singularity_handler) const | 965 double& rcond, solve_singularity_handler) const |
966 { | 966 { |
967 ComplexMatrix retval; | 967 ComplexMatrix retval; |
968 | 968 |
969 int nr = rows (); | 969 octave_idx_type nr = rows (); |
970 int nc = cols (); | 970 octave_idx_type nc = cols (); |
971 err = 0; | 971 err = 0; |
972 | 972 |
973 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) | 973 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) |
974 (*current_liboctave_error_handler) | 974 (*current_liboctave_error_handler) |
975 ("matrix dimension mismatch solution of linear equations"); | 975 ("matrix dimension mismatch solution of linear equations"); |
982 if (typ == SparseType::Diagonal || | 982 if (typ == SparseType::Diagonal || |
983 typ == SparseType::Permuted_Diagonal) | 983 typ == SparseType::Permuted_Diagonal) |
984 { | 984 { |
985 retval.resize (b.rows (), b.cols()); | 985 retval.resize (b.rows (), b.cols()); |
986 if (typ == SparseType::Diagonal) | 986 if (typ == SparseType::Diagonal) |
987 for (int j = 0; j < b.cols(); j++) | 987 for (octave_idx_type j = 0; j < b.cols(); j++) |
988 for (int i = 0; i < nr; i++) | 988 for (octave_idx_type i = 0; i < nr; i++) |
989 retval(i,j) = b(i,j) / data (i); | 989 retval(i,j) = b(i,j) / data (i); |
990 else | 990 else |
991 for (int j = 0; j < b.cols(); j++) | 991 for (octave_idx_type j = 0; j < b.cols(); j++) |
992 for (int i = 0; i < nr; i++) | 992 for (octave_idx_type i = 0; i < nr; i++) |
993 retval(i,j) = b(ridx(i),j) / data (i); | 993 retval(i,j) = b(ridx(i),j) / data (i); |
994 | 994 |
995 double dmax = 0., dmin = octave_Inf; | 995 double dmax = 0., dmin = octave_Inf; |
996 for (int i = 0; i < nr; i++) | 996 for (octave_idx_type i = 0; i < nr; i++) |
997 { | 997 { |
998 double tmp = fabs(data(i)); | 998 double tmp = fabs(data(i)); |
999 if (tmp > dmax) | 999 if (tmp > dmax) |
1000 dmax = tmp; | 1000 dmax = tmp; |
1001 if (tmp < dmin) | 1001 if (tmp < dmin) |
1010 return retval; | 1010 return retval; |
1011 } | 1011 } |
1012 | 1012 |
1013 SparseComplexMatrix | 1013 SparseComplexMatrix |
1014 SparseMatrix::dsolve (SparseType &mattype, const SparseComplexMatrix& b, | 1014 SparseMatrix::dsolve (SparseType &mattype, const SparseComplexMatrix& b, |
1015 int& err, double& rcond, | 1015 octave_idx_type& err, double& rcond, |
1016 solve_singularity_handler) const | 1016 solve_singularity_handler) const |
1017 { | 1017 { |
1018 SparseComplexMatrix retval; | 1018 SparseComplexMatrix retval; |
1019 | 1019 |
1020 int nr = rows (); | 1020 octave_idx_type nr = rows (); |
1021 int nc = cols (); | 1021 octave_idx_type nc = cols (); |
1022 err = 0; | 1022 err = 0; |
1023 | 1023 |
1024 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) | 1024 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) |
1025 (*current_liboctave_error_handler) | 1025 (*current_liboctave_error_handler) |
1026 ("matrix dimension mismatch solution of linear equations"); | 1026 ("matrix dimension mismatch solution of linear equations"); |
1031 mattype.info (); | 1031 mattype.info (); |
1032 | 1032 |
1033 if (typ == SparseType::Diagonal || | 1033 if (typ == SparseType::Diagonal || |
1034 typ == SparseType::Permuted_Diagonal) | 1034 typ == SparseType::Permuted_Diagonal) |
1035 { | 1035 { |
1036 int b_nr = b.rows (); | 1036 octave_idx_type b_nr = b.rows (); |
1037 int b_nc = b.cols (); | 1037 octave_idx_type b_nc = b.cols (); |
1038 int b_nz = b.nnz (); | 1038 octave_idx_type b_nz = b.nnz (); |
1039 retval = SparseComplexMatrix (b_nr, b_nc, b_nz); | 1039 retval = SparseComplexMatrix (b_nr, b_nc, b_nz); |
1040 | 1040 |
1041 retval.xcidx(0) = 0; | 1041 retval.xcidx(0) = 0; |
1042 int ii = 0; | 1042 octave_idx_type ii = 0; |
1043 if (typ == SparseType::Diagonal) | 1043 if (typ == SparseType::Diagonal) |
1044 for (int j = 0; j < b.cols(); j++) | 1044 for (octave_idx_type j = 0; j < b.cols(); j++) |
1045 { | 1045 { |
1046 for (int i = b.cidx(j); i < b.cidx(j+1); i++) | 1046 for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) |
1047 { | 1047 { |
1048 retval.xridx (ii) = b.ridx(i); | 1048 retval.xridx (ii) = b.ridx(i); |
1049 retval.xdata (ii++) = b.data(i) / data (b.ridx (i)); | 1049 retval.xdata (ii++) = b.data(i) / data (b.ridx (i)); |
1050 } | 1050 } |
1051 retval.xcidx(j+1) = ii; | 1051 retval.xcidx(j+1) = ii; |
1052 } | 1052 } |
1053 else | 1053 else |
1054 for (int j = 0; j < b.cols(); j++) | 1054 for (octave_idx_type j = 0; j < b.cols(); j++) |
1055 { | 1055 { |
1056 for (int i = 0; i < nr; i++) | 1056 for (octave_idx_type i = 0; i < nr; i++) |
1057 { | 1057 { |
1058 bool found = false; | 1058 bool found = false; |
1059 int k; | 1059 octave_idx_type k; |
1060 for (k = b.cidx(j); k < b.cidx(j+1); k++) | 1060 for (k = b.cidx(j); k < b.cidx(j+1); k++) |
1061 if (ridx(i) == b.ridx(k)) | 1061 if (ridx(i) == b.ridx(k)) |
1062 { | 1062 { |
1063 found = true; | 1063 found = true; |
1064 break; | 1064 break; |
1071 } | 1071 } |
1072 retval.xcidx(j+1) = ii; | 1072 retval.xcidx(j+1) = ii; |
1073 } | 1073 } |
1074 | 1074 |
1075 double dmax = 0., dmin = octave_Inf; | 1075 double dmax = 0., dmin = octave_Inf; |
1076 for (int i = 0; i < nr; i++) | 1076 for (octave_idx_type i = 0; i < nr; i++) |
1077 { | 1077 { |
1078 double tmp = fabs(data(i)); | 1078 double tmp = fabs(data(i)); |
1079 if (tmp > dmax) | 1079 if (tmp > dmax) |
1080 dmax = tmp; | 1080 dmax = tmp; |
1081 if (tmp < dmin) | 1081 if (tmp < dmin) |
1089 | 1089 |
1090 return retval; | 1090 return retval; |
1091 } | 1091 } |
1092 | 1092 |
1093 Matrix | 1093 Matrix |
1094 SparseMatrix::utsolve (SparseType &mattype, const Matrix& b, int& err, | 1094 SparseMatrix::utsolve (SparseType &mattype, const Matrix& b, octave_idx_type& err, |
1095 double& rcond, | 1095 double& rcond, |
1096 solve_singularity_handler sing_handler) const | 1096 solve_singularity_handler sing_handler) const |
1097 { | 1097 { |
1098 Matrix retval; | 1098 Matrix retval; |
1099 | 1099 |
1100 int nr = rows (); | 1100 octave_idx_type nr = rows (); |
1101 int nc = cols (); | 1101 octave_idx_type nc = cols (); |
1102 err = 0; | 1102 err = 0; |
1103 | 1103 |
1104 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) | 1104 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) |
1105 (*current_liboctave_error_handler) | 1105 (*current_liboctave_error_handler) |
1106 ("matrix dimension mismatch solution of linear equations"); | 1106 ("matrix dimension mismatch solution of linear equations"); |
1113 if (typ == SparseType::Permuted_Upper || | 1113 if (typ == SparseType::Permuted_Upper || |
1114 typ == SparseType::Upper) | 1114 typ == SparseType::Upper) |
1115 { | 1115 { |
1116 double anorm = 0.; | 1116 double anorm = 0.; |
1117 double ainvnorm = 0.; | 1117 double ainvnorm = 0.; |
1118 int b_cols = b.cols (); | 1118 octave_idx_type b_cols = b.cols (); |
1119 rcond = 0.; | 1119 rcond = 0.; |
1120 | 1120 |
1121 // Calculate the 1-norm of matrix for rcond calculation | 1121 // Calculate the 1-norm of matrix for rcond calculation |
1122 for (int j = 0; j < nr; j++) | 1122 for (octave_idx_type j = 0; j < nr; j++) |
1123 { | 1123 { |
1124 double atmp = 0.; | 1124 double atmp = 0.; |
1125 for (int i = cidx(j); i < cidx(j+1); i++) | 1125 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
1126 atmp += fabs(data(i)); | 1126 atmp += fabs(data(i)); |
1127 if (atmp > anorm) | 1127 if (atmp > anorm) |
1128 anorm = atmp; | 1128 anorm = atmp; |
1129 } | 1129 } |
1130 | 1130 |
1131 if (typ == SparseType::Permuted_Upper) | 1131 if (typ == SparseType::Permuted_Upper) |
1132 { | 1132 { |
1133 retval.resize (b.rows (), b.cols ()); | 1133 retval.resize (b.rows (), b.cols ()); |
1134 OCTAVE_LOCAL_BUFFER (double, work, nr); | 1134 OCTAVE_LOCAL_BUFFER (double, work, nr); |
1135 int *p_perm = mattype.triangular_row_perm (); | 1135 octave_idx_type *p_perm = mattype.triangular_row_perm (); |
1136 int *q_perm = mattype.triangular_col_perm (); | 1136 octave_idx_type *q_perm = mattype.triangular_col_perm (); |
1137 | 1137 |
1138 (*current_liboctave_warning_handler) | 1138 (*current_liboctave_warning_handler) |
1139 ("SparseMatrix::solve XXX FIXME XXX permuted triangular code not tested"); | 1139 ("SparseMatrix::solve XXX FIXME XXX permuted triangular code not tested"); |
1140 | 1140 |
1141 for (int j = 0; j < b_cols; j++) | 1141 for (octave_idx_type j = 0; j < b_cols; j++) |
1142 { | 1142 { |
1143 for (int i = 0; i < nr; i++) | 1143 for (octave_idx_type i = 0; i < nr; i++) |
1144 work[i] = b(i,j); | 1144 work[i] = b(i,j); |
1145 | 1145 |
1146 for (int k = nr-1; k >= 0; k--) | 1146 for (octave_idx_type k = nr-1; k >= 0; k--) |
1147 { | 1147 { |
1148 int iidx = q_perm[k]; | 1148 octave_idx_type iidx = q_perm[k]; |
1149 if (work[iidx] != 0.) | 1149 if (work[iidx] != 0.) |
1150 { | 1150 { |
1151 if (ridx(cidx(iidx+1)-1) != iidx) | 1151 if (ridx(cidx(iidx+1)-1) != iidx) |
1152 { | 1152 { |
1153 err = -2; | 1153 err = -2; |
1154 goto triangular_error; | 1154 goto triangular_error; |
1155 } | 1155 } |
1156 | 1156 |
1157 double tmp = work[iidx] / data(cidx(iidx+1)-1); | 1157 double tmp = work[iidx] / data(cidx(iidx+1)-1); |
1158 work[iidx] = tmp; | 1158 work[iidx] = tmp; |
1159 for (int i = cidx(iidx); i < cidx(iidx+1)-1; i++) | 1159 for (octave_idx_type i = cidx(iidx); i < cidx(iidx+1)-1; i++) |
1160 { | 1160 { |
1161 int idx2 = q_perm[ridx(i)]; | 1161 octave_idx_type idx2 = q_perm[ridx(i)]; |
1162 work[idx2] = | 1162 work[idx2] = |
1163 work[idx2] - tmp * data(i); | 1163 work[idx2] - tmp * data(i); |
1164 } | 1164 } |
1165 } | 1165 } |
1166 } | 1166 } |
1167 | 1167 |
1168 for (int i = 0; i < nr; i++) | 1168 for (octave_idx_type i = 0; i < nr; i++) |
1169 retval (i, j) = work[p_perm[i]]; | 1169 retval (i, j) = work[p_perm[i]]; |
1170 } | 1170 } |
1171 | 1171 |
1172 // Calculation of 1-norm of inv(*this) | 1172 // Calculation of 1-norm of inv(*this) |
1173 for (int i = 0; i < nr; i++) | 1173 for (octave_idx_type i = 0; i < nr; i++) |
1174 work[i] = 0.; | 1174 work[i] = 0.; |
1175 | 1175 |
1176 for (int j = 0; j < nr; j++) | 1176 for (octave_idx_type j = 0; j < nr; j++) |
1177 { | 1177 { |
1178 work[q_perm[j]] = 1.; | 1178 work[q_perm[j]] = 1.; |
1179 | 1179 |
1180 for (int k = j; k >= 0; k--) | 1180 for (octave_idx_type k = j; k >= 0; k--) |
1181 { | 1181 { |
1182 int iidx = q_perm[k]; | 1182 octave_idx_type iidx = q_perm[k]; |
1183 | 1183 |
1184 if (work[iidx] != 0.) | 1184 if (work[iidx] != 0.) |
1185 { | 1185 { |
1186 double tmp = work[iidx] / data(cidx(iidx+1)-1); | 1186 double tmp = work[iidx] / data(cidx(iidx+1)-1); |
1187 work[iidx] = tmp; | 1187 work[iidx] = tmp; |
1188 for (int i = cidx(iidx); i < cidx(iidx+1)-1; i++) | 1188 for (octave_idx_type i = cidx(iidx); i < cidx(iidx+1)-1; i++) |
1189 { | 1189 { |
1190 int idx2 = q_perm[ridx(i)]; | 1190 octave_idx_type idx2 = q_perm[ridx(i)]; |
1191 work[idx2] = work[idx2] - tmp * data(i); | 1191 work[idx2] = work[idx2] - tmp * data(i); |
1192 } | 1192 } |
1193 } | 1193 } |
1194 } | 1194 } |
1195 double atmp = 0; | 1195 double atmp = 0; |
1196 for (int i = 0; i < j+1; i++) | 1196 for (octave_idx_type i = 0; i < j+1; i++) |
1197 { | 1197 { |
1198 atmp += fabs(work[i]); | 1198 atmp += fabs(work[i]); |
1199 work[i] = 0.; | 1199 work[i] = 0.; |
1200 } | 1200 } |
1201 if (atmp > ainvnorm) | 1201 if (atmp > ainvnorm) |
1205 else | 1205 else |
1206 { | 1206 { |
1207 retval = b; | 1207 retval = b; |
1208 double *x_vec = retval.fortran_vec (); | 1208 double *x_vec = retval.fortran_vec (); |
1209 | 1209 |
1210 for (int j = 0; j < b_cols; j++) | 1210 for (octave_idx_type j = 0; j < b_cols; j++) |
1211 { | 1211 { |
1212 int offset = j * nr; | 1212 octave_idx_type offset = j * nr; |
1213 for (int k = nr-1; k >= 0; k--) | 1213 for (octave_idx_type k = nr-1; k >= 0; k--) |
1214 { | 1214 { |
1215 if (x_vec[k+offset] != 0.) | 1215 if (x_vec[k+offset] != 0.) |
1216 { | 1216 { |
1217 if (ridx(cidx(k+1)-1) != k) | 1217 if (ridx(cidx(k+1)-1) != k) |
1218 { | 1218 { |
1221 } | 1221 } |
1222 | 1222 |
1223 double tmp = x_vec[k+offset] / | 1223 double tmp = x_vec[k+offset] / |
1224 data(cidx(k+1)-1); | 1224 data(cidx(k+1)-1); |
1225 x_vec[k+offset] = tmp; | 1225 x_vec[k+offset] = tmp; |
1226 for (int i = cidx(k); i < cidx(k+1)-1; i++) | 1226 for (octave_idx_type i = cidx(k); i < cidx(k+1)-1; i++) |
1227 { | 1227 { |
1228 int iidx = ridx(i); | 1228 octave_idx_type iidx = ridx(i); |
1229 x_vec[iidx+offset] = | 1229 x_vec[iidx+offset] = |
1230 x_vec[iidx+offset] - tmp * data(i); | 1230 x_vec[iidx+offset] - tmp * data(i); |
1231 } | 1231 } |
1232 } | 1232 } |
1233 } | 1233 } |
1234 } | 1234 } |
1235 | 1235 |
1236 // Calculation of 1-norm of inv(*this) | 1236 // Calculation of 1-norm of inv(*this) |
1237 OCTAVE_LOCAL_BUFFER (double, work, nr); | 1237 OCTAVE_LOCAL_BUFFER (double, work, nr); |
1238 for (int i = 0; i < nr; i++) | 1238 for (octave_idx_type i = 0; i < nr; i++) |
1239 work[i] = 0.; | 1239 work[i] = 0.; |
1240 | 1240 |
1241 for (int j = 0; j < nr; j++) | 1241 for (octave_idx_type j = 0; j < nr; j++) |
1242 { | 1242 { |
1243 work[j] = 1.; | 1243 work[j] = 1.; |
1244 | 1244 |
1245 for (int k = j; k >= 0; k--) | 1245 for (octave_idx_type k = j; k >= 0; k--) |
1246 { | 1246 { |
1247 if (work[k] != 0.) | 1247 if (work[k] != 0.) |
1248 { | 1248 { |
1249 double tmp = work[k] / data(cidx(k+1)-1); | 1249 double tmp = work[k] / data(cidx(k+1)-1); |
1250 work[k] = tmp; | 1250 work[k] = tmp; |
1251 for (int i = cidx(k); i < cidx(k+1)-1; i++) | 1251 for (octave_idx_type i = cidx(k); i < cidx(k+1)-1; i++) |
1252 { | 1252 { |
1253 int iidx = ridx(i); | 1253 octave_idx_type iidx = ridx(i); |
1254 work[iidx] = work[iidx] - tmp * data(i); | 1254 work[iidx] = work[iidx] - tmp * data(i); |
1255 } | 1255 } |
1256 } | 1256 } |
1257 } | 1257 } |
1258 double atmp = 0; | 1258 double atmp = 0; |
1259 for (int i = 0; i < j+1; i++) | 1259 for (octave_idx_type i = 0; i < j+1; i++) |
1260 { | 1260 { |
1261 atmp += fabs(work[i]); | 1261 atmp += fabs(work[i]); |
1262 work[i] = 0.; | 1262 work[i] = 0.; |
1263 } | 1263 } |
1264 if (atmp > ainvnorm) | 1264 if (atmp > ainvnorm) |
1299 | 1299 |
1300 return retval; | 1300 return retval; |
1301 } | 1301 } |
1302 | 1302 |
1303 SparseMatrix | 1303 SparseMatrix |
1304 SparseMatrix::utsolve (SparseType &mattype, const SparseMatrix& b, int& err, | 1304 SparseMatrix::utsolve (SparseType &mattype, const SparseMatrix& b, octave_idx_type& err, |
1305 double& rcond, solve_singularity_handler sing_handler) const | 1305 double& rcond, solve_singularity_handler sing_handler) const |
1306 { | 1306 { |
1307 SparseMatrix retval; | 1307 SparseMatrix retval; |
1308 | 1308 |
1309 int nr = rows (); | 1309 octave_idx_type nr = rows (); |
1310 int nc = cols (); | 1310 octave_idx_type nc = cols (); |
1311 err = 0; | 1311 err = 0; |
1312 | 1312 |
1313 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) | 1313 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) |
1314 (*current_liboctave_error_handler) | 1314 (*current_liboctave_error_handler) |
1315 ("matrix dimension mismatch solution of linear equations"); | 1315 ("matrix dimension mismatch solution of linear equations"); |
1325 double anorm = 0.; | 1325 double anorm = 0.; |
1326 double ainvnorm = 0.; | 1326 double ainvnorm = 0.; |
1327 rcond = 0.; | 1327 rcond = 0.; |
1328 | 1328 |
1329 // Calculate the 1-norm of matrix for rcond calculation | 1329 // Calculate the 1-norm of matrix for rcond calculation |
1330 for (int j = 0; j < nr; j++) | 1330 for (octave_idx_type j = 0; j < nr; j++) |
1331 { | 1331 { |
1332 double atmp = 0.; | 1332 double atmp = 0.; |
1333 for (int i = cidx(j); i < cidx(j+1); i++) | 1333 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
1334 atmp += fabs(data(i)); | 1334 atmp += fabs(data(i)); |
1335 if (atmp > anorm) | 1335 if (atmp > anorm) |
1336 anorm = atmp; | 1336 anorm = atmp; |
1337 } | 1337 } |
1338 | 1338 |
1339 int b_nr = b.rows (); | 1339 octave_idx_type b_nr = b.rows (); |
1340 int b_nc = b.cols (); | 1340 octave_idx_type b_nc = b.cols (); |
1341 int b_nz = b.nnz (); | 1341 octave_idx_type b_nz = b.nnz (); |
1342 retval = SparseMatrix (b_nr, b_nc, b_nz); | 1342 retval = SparseMatrix (b_nr, b_nc, b_nz); |
1343 retval.xcidx(0) = 0; | 1343 retval.xcidx(0) = 0; |
1344 int ii = 0; | 1344 octave_idx_type ii = 0; |
1345 int x_nz = b_nz; | 1345 octave_idx_type x_nz = b_nz; |
1346 | 1346 |
1347 if (typ == SparseType::Permuted_Upper) | 1347 if (typ == SparseType::Permuted_Upper) |
1348 { | 1348 { |
1349 OCTAVE_LOCAL_BUFFER (double, work, nr); | 1349 OCTAVE_LOCAL_BUFFER (double, work, nr); |
1350 int *p_perm = mattype.triangular_row_perm (); | 1350 octave_idx_type *p_perm = mattype.triangular_row_perm (); |
1351 int *q_perm = mattype.triangular_col_perm (); | 1351 octave_idx_type *q_perm = mattype.triangular_col_perm (); |
1352 | 1352 |
1353 (*current_liboctave_warning_handler) | 1353 (*current_liboctave_warning_handler) |
1354 ("SparseMatrix::solve XXX FIXME XXX permuted triangular code not tested"); | 1354 ("SparseMatrix::solve XXX FIXME XXX permuted triangular code not tested"); |
1355 | 1355 |
1356 for (int j = 0; j < b_nc; j++) | 1356 for (octave_idx_type j = 0; j < b_nc; j++) |
1357 { | 1357 { |
1358 for (int i = 0; i < nr; i++) | 1358 for (octave_idx_type i = 0; i < nr; i++) |
1359 work[i] = 0.; | 1359 work[i] = 0.; |
1360 for (int i = b.cidx(j); i < b.cidx(j+1); i++) | 1360 for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) |
1361 work[b.ridx(i)] = b.data(i); | 1361 work[b.ridx(i)] = b.data(i); |
1362 | 1362 |
1363 for (int k = nr-1; k >= 0; k--) | 1363 for (octave_idx_type k = nr-1; k >= 0; k--) |
1364 { | 1364 { |
1365 int iidx = q_perm[k]; | 1365 octave_idx_type iidx = q_perm[k]; |
1366 if (work[iidx] != 0.) | 1366 if (work[iidx] != 0.) |
1367 { | 1367 { |
1368 if (ridx(cidx(iidx+1)-1) != iidx) | 1368 if (ridx(cidx(iidx+1)-1) != iidx) |
1369 { | 1369 { |
1370 err = -2; | 1370 err = -2; |
1371 goto triangular_error; | 1371 goto triangular_error; |
1372 } | 1372 } |
1373 | 1373 |
1374 double tmp = work[iidx] / data(cidx(iidx+1)-1); | 1374 double tmp = work[iidx] / data(cidx(iidx+1)-1); |
1375 work[iidx] = tmp; | 1375 work[iidx] = tmp; |
1376 for (int i = cidx(iidx); i < cidx(iidx+1)-1; i++) | 1376 for (octave_idx_type i = cidx(iidx); i < cidx(iidx+1)-1; i++) |
1377 { | 1377 { |
1378 int idx2 = q_perm[ridx(i)]; | 1378 octave_idx_type idx2 = q_perm[ridx(i)]; |
1379 work[idx2] = | 1379 work[idx2] = |
1380 work[idx2] - tmp * data(i); | 1380 work[idx2] - tmp * data(i); |
1381 } | 1381 } |
1382 } | 1382 } |
1383 } | 1383 } |
1384 | 1384 |
1385 // Count non-zeros in work vector and adjust space in | 1385 // Count non-zeros in work vector and adjust space in |
1386 // retval if needed | 1386 // retval if needed |
1387 int new_nnz = 0; | 1387 octave_idx_type new_nnz = 0; |
1388 for (int i = 0; i < nr; i++) | 1388 for (octave_idx_type i = 0; i < nr; i++) |
1389 if (work[i] != 0.) | 1389 if (work[i] != 0.) |
1390 new_nnz++; | 1390 new_nnz++; |
1391 | 1391 |
1392 if (ii + new_nnz > x_nz) | 1392 if (ii + new_nnz > x_nz) |
1393 { | 1393 { |
1394 // Resize the sparse matrix | 1394 // Resize the sparse matrix |
1395 int sz = new_nnz * (b_nc - j) + x_nz; | 1395 octave_idx_type sz = new_nnz * (b_nc - j) + x_nz; |
1396 retval.change_capacity (sz); | 1396 retval.change_capacity (sz); |
1397 x_nz = sz; | 1397 x_nz = sz; |
1398 } | 1398 } |
1399 | 1399 |
1400 for (int i = 0; i < nr; i++) | 1400 for (octave_idx_type i = 0; i < nr; i++) |
1401 if (work[p_perm[i]] != 0.) | 1401 if (work[p_perm[i]] != 0.) |
1402 { | 1402 { |
1403 retval.xridx(ii) = i; | 1403 retval.xridx(ii) = i; |
1404 retval.xdata(ii++) = work[p_perm[i]]; | 1404 retval.xdata(ii++) = work[p_perm[i]]; |
1405 } | 1405 } |
1407 } | 1407 } |
1408 | 1408 |
1409 retval.maybe_compress (); | 1409 retval.maybe_compress (); |
1410 | 1410 |
1411 // Calculation of 1-norm of inv(*this) | 1411 // Calculation of 1-norm of inv(*this) |
1412 for (int i = 0; i < nr; i++) | 1412 for (octave_idx_type i = 0; i < nr; i++) |
1413 work[i] = 0.; | 1413 work[i] = 0.; |
1414 | 1414 |
1415 for (int j = 0; j < nr; j++) | 1415 for (octave_idx_type j = 0; j < nr; j++) |
1416 { | 1416 { |
1417 work[q_perm[j]] = 1.; | 1417 work[q_perm[j]] = 1.; |
1418 | 1418 |
1419 for (int k = j; k >= 0; k--) | 1419 for (octave_idx_type k = j; k >= 0; k--) |
1420 { | 1420 { |
1421 int iidx = q_perm[k]; | 1421 octave_idx_type iidx = q_perm[k]; |
1422 | 1422 |
1423 if (work[iidx] != 0.) | 1423 if (work[iidx] != 0.) |
1424 { | 1424 { |
1425 double tmp = work[iidx] / data(cidx(iidx+1)-1); | 1425 double tmp = work[iidx] / data(cidx(iidx+1)-1); |
1426 work[iidx] = tmp; | 1426 work[iidx] = tmp; |
1427 for (int i = cidx(iidx); i < cidx(iidx+1)-1; i++) | 1427 for (octave_idx_type i = cidx(iidx); i < cidx(iidx+1)-1; i++) |
1428 { | 1428 { |
1429 int idx2 = q_perm[ridx(i)]; | 1429 octave_idx_type idx2 = q_perm[ridx(i)]; |
1430 work[idx2] = work[idx2] - tmp * data(i); | 1430 work[idx2] = work[idx2] - tmp * data(i); |
1431 } | 1431 } |
1432 } | 1432 } |
1433 } | 1433 } |
1434 double atmp = 0; | 1434 double atmp = 0; |
1435 for (int i = 0; i < j+1; i++) | 1435 for (octave_idx_type i = 0; i < j+1; i++) |
1436 { | 1436 { |
1437 atmp += fabs(work[i]); | 1437 atmp += fabs(work[i]); |
1438 work[i] = 0.; | 1438 work[i] = 0.; |
1439 } | 1439 } |
1440 if (atmp > ainvnorm) | 1440 if (atmp > ainvnorm) |
1443 } | 1443 } |
1444 else | 1444 else |
1445 { | 1445 { |
1446 OCTAVE_LOCAL_BUFFER (double, work, nr); | 1446 OCTAVE_LOCAL_BUFFER (double, work, nr); |
1447 | 1447 |
1448 for (int j = 0; j < b_nc; j++) | 1448 for (octave_idx_type j = 0; j < b_nc; j++) |
1449 { | 1449 { |
1450 for (int i = 0; i < nr; i++) | 1450 for (octave_idx_type i = 0; i < nr; i++) |
1451 work[i] = 0.; | 1451 work[i] = 0.; |
1452 for (int i = b.cidx(j); i < b.cidx(j+1); i++) | 1452 for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) |
1453 work[b.ridx(i)] = b.data(i); | 1453 work[b.ridx(i)] = b.data(i); |
1454 | 1454 |
1455 for (int k = nr-1; k >= 0; k--) | 1455 for (octave_idx_type k = nr-1; k >= 0; k--) |
1456 { | 1456 { |
1457 if (work[k] != 0.) | 1457 if (work[k] != 0.) |
1458 { | 1458 { |
1459 if (ridx(cidx(k+1)-1) != k) | 1459 if (ridx(cidx(k+1)-1) != k) |
1460 { | 1460 { |
1462 goto triangular_error; | 1462 goto triangular_error; |
1463 } | 1463 } |
1464 | 1464 |
1465 double tmp = work[k] / data(cidx(k+1)-1); | 1465 double tmp = work[k] / data(cidx(k+1)-1); |
1466 work[k] = tmp; | 1466 work[k] = tmp; |
1467 for (int i = cidx(k); i < cidx(k+1)-1; i++) | 1467 for (octave_idx_type i = cidx(k); i < cidx(k+1)-1; i++) |
1468 { | 1468 { |
1469 int iidx = ridx(i); | 1469 octave_idx_type iidx = ridx(i); |
1470 work[iidx] = work[iidx] - tmp * data(i); | 1470 work[iidx] = work[iidx] - tmp * data(i); |
1471 } | 1471 } |
1472 } | 1472 } |
1473 } | 1473 } |
1474 | 1474 |
1475 // Count non-zeros in work vector and adjust space in | 1475 // Count non-zeros in work vector and adjust space in |
1476 // retval if needed | 1476 // retval if needed |
1477 int new_nnz = 0; | 1477 octave_idx_type new_nnz = 0; |
1478 for (int i = 0; i < nr; i++) | 1478 for (octave_idx_type i = 0; i < nr; i++) |
1479 if (work[i] != 0.) | 1479 if (work[i] != 0.) |
1480 new_nnz++; | 1480 new_nnz++; |
1481 | 1481 |
1482 if (ii + new_nnz > x_nz) | 1482 if (ii + new_nnz > x_nz) |
1483 { | 1483 { |
1484 // Resize the sparse matrix | 1484 // Resize the sparse matrix |
1485 int sz = new_nnz * (b_nc - j) + x_nz; | 1485 octave_idx_type sz = new_nnz * (b_nc - j) + x_nz; |
1486 retval.change_capacity (sz); | 1486 retval.change_capacity (sz); |
1487 x_nz = sz; | 1487 x_nz = sz; |
1488 } | 1488 } |
1489 | 1489 |
1490 for (int i = 0; i < nr; i++) | 1490 for (octave_idx_type i = 0; i < nr; i++) |
1491 if (work[i] != 0.) | 1491 if (work[i] != 0.) |
1492 { | 1492 { |
1493 retval.xridx(ii) = i; | 1493 retval.xridx(ii) = i; |
1494 retval.xdata(ii++) = work[i]; | 1494 retval.xdata(ii++) = work[i]; |
1495 } | 1495 } |
1497 } | 1497 } |
1498 | 1498 |
1499 retval.maybe_compress (); | 1499 retval.maybe_compress (); |
1500 | 1500 |
1501 // Calculation of 1-norm of inv(*this) | 1501 // Calculation of 1-norm of inv(*this) |
1502 for (int i = 0; i < nr; i++) | 1502 for (octave_idx_type i = 0; i < nr; i++) |
1503 work[i] = 0.; | 1503 work[i] = 0.; |
1504 | 1504 |
1505 for (int j = 0; j < nr; j++) | 1505 for (octave_idx_type j = 0; j < nr; j++) |
1506 { | 1506 { |
1507 work[j] = 1.; | 1507 work[j] = 1.; |
1508 | 1508 |
1509 for (int k = j; k >= 0; k--) | 1509 for (octave_idx_type k = j; k >= 0; k--) |
1510 { | 1510 { |
1511 if (work[k] != 0.) | 1511 if (work[k] != 0.) |
1512 { | 1512 { |
1513 double tmp = work[k] / data(cidx(k+1)-1); | 1513 double tmp = work[k] / data(cidx(k+1)-1); |
1514 work[k] = tmp; | 1514 work[k] = tmp; |
1515 for (int i = cidx(k); i < cidx(k+1)-1; i++) | 1515 for (octave_idx_type i = cidx(k); i < cidx(k+1)-1; i++) |
1516 { | 1516 { |
1517 int iidx = ridx(i); | 1517 octave_idx_type iidx = ridx(i); |
1518 work[iidx] = work[iidx] - tmp * data(i); | 1518 work[iidx] = work[iidx] - tmp * data(i); |
1519 } | 1519 } |
1520 } | 1520 } |
1521 } | 1521 } |
1522 double atmp = 0; | 1522 double atmp = 0; |
1523 for (int i = 0; i < j+1; i++) | 1523 for (octave_idx_type i = 0; i < j+1; i++) |
1524 { | 1524 { |
1525 atmp += fabs(work[i]); | 1525 atmp += fabs(work[i]); |
1526 work[i] = 0.; | 1526 work[i] = 0.; |
1527 } | 1527 } |
1528 if (atmp > ainvnorm) | 1528 if (atmp > ainvnorm) |
1562 } | 1562 } |
1563 return retval; | 1563 return retval; |
1564 } | 1564 } |
1565 | 1565 |
1566 ComplexMatrix | 1566 ComplexMatrix |
1567 SparseMatrix::utsolve (SparseType &mattype, const ComplexMatrix& b, int& err, | 1567 SparseMatrix::utsolve (SparseType &mattype, const ComplexMatrix& b, octave_idx_type& err, |
1568 double& rcond, solve_singularity_handler sing_handler) const | 1568 double& rcond, solve_singularity_handler sing_handler) const |
1569 { | 1569 { |
1570 ComplexMatrix retval; | 1570 ComplexMatrix retval; |
1571 | 1571 |
1572 int nr = rows (); | 1572 octave_idx_type nr = rows (); |
1573 int nc = cols (); | 1573 octave_idx_type nc = cols (); |
1574 err = 0; | 1574 err = 0; |
1575 | 1575 |
1576 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) | 1576 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) |
1577 (*current_liboctave_error_handler) | 1577 (*current_liboctave_error_handler) |
1578 ("matrix dimension mismatch solution of linear equations"); | 1578 ("matrix dimension mismatch solution of linear equations"); |
1585 if (typ == SparseType::Permuted_Upper || | 1585 if (typ == SparseType::Permuted_Upper || |
1586 typ == SparseType::Upper) | 1586 typ == SparseType::Upper) |
1587 { | 1587 { |
1588 double anorm = 0.; | 1588 double anorm = 0.; |
1589 double ainvnorm = 0.; | 1589 double ainvnorm = 0.; |
1590 int b_nc = b.cols (); | 1590 octave_idx_type b_nc = b.cols (); |
1591 rcond = 0.; | 1591 rcond = 0.; |
1592 | 1592 |
1593 // Calculate the 1-norm of matrix for rcond calculation | 1593 // Calculate the 1-norm of matrix for rcond calculation |
1594 for (int j = 0; j < nr; j++) | 1594 for (octave_idx_type j = 0; j < nr; j++) |
1595 { | 1595 { |
1596 double atmp = 0.; | 1596 double atmp = 0.; |
1597 for (int i = cidx(j); i < cidx(j+1); i++) | 1597 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
1598 atmp += fabs(data(i)); | 1598 atmp += fabs(data(i)); |
1599 if (atmp > anorm) | 1599 if (atmp > anorm) |
1600 anorm = atmp; | 1600 anorm = atmp; |
1601 } | 1601 } |
1602 | 1602 |
1603 if (typ == SparseType::Permuted_Upper) | 1603 if (typ == SparseType::Permuted_Upper) |
1604 { | 1604 { |
1605 retval.resize (b.rows (), b.cols ()); | 1605 retval.resize (b.rows (), b.cols ()); |
1606 OCTAVE_LOCAL_BUFFER (Complex, work, nr); | 1606 OCTAVE_LOCAL_BUFFER (Complex, work, nr); |
1607 int *p_perm = mattype.triangular_row_perm (); | 1607 octave_idx_type *p_perm = mattype.triangular_row_perm (); |
1608 int *q_perm = mattype.triangular_col_perm (); | 1608 octave_idx_type *q_perm = mattype.triangular_col_perm (); |
1609 | 1609 |
1610 (*current_liboctave_warning_handler) | 1610 (*current_liboctave_warning_handler) |
1611 ("SparseMatrix::solve XXX FIXME XXX permuted triangular code not tested"); | 1611 ("SparseMatrix::solve XXX FIXME XXX permuted triangular code not tested"); |
1612 | 1612 |
1613 for (int j = 0; j < b_nc; j++) | 1613 for (octave_idx_type j = 0; j < b_nc; j++) |
1614 { | 1614 { |
1615 for (int i = 0; i < nr; i++) | 1615 for (octave_idx_type i = 0; i < nr; i++) |
1616 work[i] = b(i,j); | 1616 work[i] = b(i,j); |
1617 | 1617 |
1618 for (int k = nr-1; k >= 0; k--) | 1618 for (octave_idx_type k = nr-1; k >= 0; k--) |
1619 { | 1619 { |
1620 int iidx = q_perm[k]; | 1620 octave_idx_type iidx = q_perm[k]; |
1621 if (work[iidx] != 0.) | 1621 if (work[iidx] != 0.) |
1622 { | 1622 { |
1623 if (ridx(cidx(iidx+1)-1) != iidx) | 1623 if (ridx(cidx(iidx+1)-1) != iidx) |
1624 { | 1624 { |
1625 err = -2; | 1625 err = -2; |
1626 goto triangular_error; | 1626 goto triangular_error; |
1627 } | 1627 } |
1628 | 1628 |
1629 Complex tmp = work[iidx] / data(cidx(iidx+1)-1); | 1629 Complex tmp = work[iidx] / data(cidx(iidx+1)-1); |
1630 work[iidx] = tmp; | 1630 work[iidx] = tmp; |
1631 for (int i = cidx(iidx); i < cidx(iidx+1)-1; i++) | 1631 for (octave_idx_type i = cidx(iidx); i < cidx(iidx+1)-1; i++) |
1632 { | 1632 { |
1633 int idx2 = q_perm[ridx(i)]; | 1633 octave_idx_type idx2 = q_perm[ridx(i)]; |
1634 work[idx2] = | 1634 work[idx2] = |
1635 work[idx2] - tmp * data(i); | 1635 work[idx2] - tmp * data(i); |
1636 } | 1636 } |
1637 } | 1637 } |
1638 } | 1638 } |
1639 | 1639 |
1640 for (int i = 0; i < nr; i++) | 1640 for (octave_idx_type i = 0; i < nr; i++) |
1641 retval (i, j) = work[p_perm[i]]; | 1641 retval (i, j) = work[p_perm[i]]; |
1642 | 1642 |
1643 } | 1643 } |
1644 | 1644 |
1645 // Calculation of 1-norm of inv(*this) | 1645 // Calculation of 1-norm of inv(*this) |
1646 OCTAVE_LOCAL_BUFFER (double, work2, nr); | 1646 OCTAVE_LOCAL_BUFFER (double, work2, nr); |
1647 for (int i = 0; i < nr; i++) | 1647 for (octave_idx_type i = 0; i < nr; i++) |
1648 work2[i] = 0.; | 1648 work2[i] = 0.; |
1649 | 1649 |
1650 for (int j = 0; j < nr; j++) | 1650 for (octave_idx_type j = 0; j < nr; j++) |
1651 { | 1651 { |
1652 work2[q_perm[j]] = 1.; | 1652 work2[q_perm[j]] = 1.; |
1653 | 1653 |
1654 for (int k = j; k >= 0; k--) | 1654 for (octave_idx_type k = j; k >= 0; k--) |
1655 { | 1655 { |
1656 int iidx = q_perm[k]; | 1656 octave_idx_type iidx = q_perm[k]; |
1657 | 1657 |
1658 if (work2[iidx] != 0.) | 1658 if (work2[iidx] != 0.) |
1659 { | 1659 { |
1660 double tmp = work2[iidx] / data(cidx(iidx+1)-1); | 1660 double tmp = work2[iidx] / data(cidx(iidx+1)-1); |
1661 work2[iidx] = tmp; | 1661 work2[iidx] = tmp; |
1662 for (int i = cidx(iidx); i < cidx(iidx+1)-1; i++) | 1662 for (octave_idx_type i = cidx(iidx); i < cidx(iidx+1)-1; i++) |
1663 { | 1663 { |
1664 int idx2 = q_perm[ridx(i)]; | 1664 octave_idx_type idx2 = q_perm[ridx(i)]; |
1665 work2[idx2] = work2[idx2] - tmp * data(i); | 1665 work2[idx2] = work2[idx2] - tmp * data(i); |
1666 } | 1666 } |
1667 } | 1667 } |
1668 } | 1668 } |
1669 double atmp = 0; | 1669 double atmp = 0; |
1670 for (int i = 0; i < j+1; i++) | 1670 for (octave_idx_type i = 0; i < j+1; i++) |
1671 { | 1671 { |
1672 atmp += fabs(work2[i]); | 1672 atmp += fabs(work2[i]); |
1673 work2[i] = 0.; | 1673 work2[i] = 0.; |
1674 } | 1674 } |
1675 if (atmp > ainvnorm) | 1675 if (atmp > ainvnorm) |
1679 else | 1679 else |
1680 { | 1680 { |
1681 retval = b; | 1681 retval = b; |
1682 Complex *x_vec = retval.fortran_vec (); | 1682 Complex *x_vec = retval.fortran_vec (); |
1683 | 1683 |
1684 for (int j = 0; j < b_nc; j++) | 1684 for (octave_idx_type j = 0; j < b_nc; j++) |
1685 { | 1685 { |
1686 int offset = j * nr; | 1686 octave_idx_type offset = j * nr; |
1687 for (int k = nr-1; k >= 0; k--) | 1687 for (octave_idx_type k = nr-1; k >= 0; k--) |
1688 { | 1688 { |
1689 if (x_vec[k+offset] != 0.) | 1689 if (x_vec[k+offset] != 0.) |
1690 { | 1690 { |
1691 if (ridx(cidx(k+1)-1) != k) | 1691 if (ridx(cidx(k+1)-1) != k) |
1692 { | 1692 { |
1695 } | 1695 } |
1696 | 1696 |
1697 Complex tmp = x_vec[k+offset] / | 1697 Complex tmp = x_vec[k+offset] / |
1698 data(cidx(k+1)-1); | 1698 data(cidx(k+1)-1); |
1699 x_vec[k+offset] = tmp; | 1699 x_vec[k+offset] = tmp; |
1700 for (int i = cidx(k); i < cidx(k+1)-1; i++) | 1700 for (octave_idx_type i = cidx(k); i < cidx(k+1)-1; i++) |
1701 { | 1701 { |
1702 int iidx = ridx(i); | 1702 octave_idx_type iidx = ridx(i); |
1703 x_vec[iidx+offset] = | 1703 x_vec[iidx+offset] = |
1704 x_vec[iidx+offset] - tmp * data(i); | 1704 x_vec[iidx+offset] - tmp * data(i); |
1705 } | 1705 } |
1706 } | 1706 } |
1707 } | 1707 } |
1708 } | 1708 } |
1709 | 1709 |
1710 // Calculation of 1-norm of inv(*this) | 1710 // Calculation of 1-norm of inv(*this) |
1711 OCTAVE_LOCAL_BUFFER (double, work, nr); | 1711 OCTAVE_LOCAL_BUFFER (double, work, nr); |
1712 for (int i = 0; i < nr; i++) | 1712 for (octave_idx_type i = 0; i < nr; i++) |
1713 work[i] = 0.; | 1713 work[i] = 0.; |
1714 | 1714 |
1715 for (int j = 0; j < nr; j++) | 1715 for (octave_idx_type j = 0; j < nr; j++) |
1716 { | 1716 { |
1717 work[j] = 1.; | 1717 work[j] = 1.; |
1718 | 1718 |
1719 for (int k = j; k >= 0; k--) | 1719 for (octave_idx_type k = j; k >= 0; k--) |
1720 { | 1720 { |
1721 if (work[k] != 0.) | 1721 if (work[k] != 0.) |
1722 { | 1722 { |
1723 double tmp = work[k] / data(cidx(k+1)-1); | 1723 double tmp = work[k] / data(cidx(k+1)-1); |
1724 work[k] = tmp; | 1724 work[k] = tmp; |
1725 for (int i = cidx(k); i < cidx(k+1)-1; i++) | 1725 for (octave_idx_type i = cidx(k); i < cidx(k+1)-1; i++) |
1726 { | 1726 { |
1727 int iidx = ridx(i); | 1727 octave_idx_type iidx = ridx(i); |
1728 work[iidx] = work[iidx] - tmp * data(i); | 1728 work[iidx] = work[iidx] - tmp * data(i); |
1729 } | 1729 } |
1730 } | 1730 } |
1731 } | 1731 } |
1732 double atmp = 0; | 1732 double atmp = 0; |
1733 for (int i = 0; i < j+1; i++) | 1733 for (octave_idx_type i = 0; i < j+1; i++) |
1734 { | 1734 { |
1735 atmp += fabs(work[i]); | 1735 atmp += fabs(work[i]); |
1736 work[i] = 0.; | 1736 work[i] = 0.; |
1737 } | 1737 } |
1738 if (atmp > ainvnorm) | 1738 if (atmp > ainvnorm) |
1774 return retval; | 1774 return retval; |
1775 } | 1775 } |
1776 | 1776 |
1777 SparseComplexMatrix | 1777 SparseComplexMatrix |
1778 SparseMatrix::utsolve (SparseType &mattype, const SparseComplexMatrix& b, | 1778 SparseMatrix::utsolve (SparseType &mattype, const SparseComplexMatrix& b, |
1779 int& err, double& rcond, | 1779 octave_idx_type& err, double& rcond, |
1780 solve_singularity_handler sing_handler) const | 1780 solve_singularity_handler sing_handler) const |
1781 { | 1781 { |
1782 SparseComplexMatrix retval; | 1782 SparseComplexMatrix retval; |
1783 | 1783 |
1784 int nr = rows (); | 1784 octave_idx_type nr = rows (); |
1785 int nc = cols (); | 1785 octave_idx_type nc = cols (); |
1786 err = 0; | 1786 err = 0; |
1787 | 1787 |
1788 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) | 1788 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) |
1789 (*current_liboctave_error_handler) | 1789 (*current_liboctave_error_handler) |
1790 ("matrix dimension mismatch solution of linear equations"); | 1790 ("matrix dimension mismatch solution of linear equations"); |
1800 double anorm = 0.; | 1800 double anorm = 0.; |
1801 double ainvnorm = 0.; | 1801 double ainvnorm = 0.; |
1802 rcond = 0.; | 1802 rcond = 0.; |
1803 | 1803 |
1804 // Calculate the 1-norm of matrix for rcond calculation | 1804 // Calculate the 1-norm of matrix for rcond calculation |
1805 for (int j = 0; j < nr; j++) | 1805 for (octave_idx_type j = 0; j < nr; j++) |
1806 { | 1806 { |
1807 double atmp = 0.; | 1807 double atmp = 0.; |
1808 for (int i = cidx(j); i < cidx(j+1); i++) | 1808 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
1809 atmp += fabs(data(i)); | 1809 atmp += fabs(data(i)); |
1810 if (atmp > anorm) | 1810 if (atmp > anorm) |
1811 anorm = atmp; | 1811 anorm = atmp; |
1812 } | 1812 } |
1813 | 1813 |
1814 int b_nr = b.rows (); | 1814 octave_idx_type b_nr = b.rows (); |
1815 int b_nc = b.cols (); | 1815 octave_idx_type b_nc = b.cols (); |
1816 int b_nz = b.nnz (); | 1816 octave_idx_type b_nz = b.nnz (); |
1817 retval = SparseComplexMatrix (b_nr, b_nc, b_nz); | 1817 retval = SparseComplexMatrix (b_nr, b_nc, b_nz); |
1818 retval.xcidx(0) = 0; | 1818 retval.xcidx(0) = 0; |
1819 int ii = 0; | 1819 octave_idx_type ii = 0; |
1820 int x_nz = b_nz; | 1820 octave_idx_type x_nz = b_nz; |
1821 | 1821 |
1822 if (typ == SparseType::Permuted_Upper) | 1822 if (typ == SparseType::Permuted_Upper) |
1823 { | 1823 { |
1824 OCTAVE_LOCAL_BUFFER (Complex, work, nr); | 1824 OCTAVE_LOCAL_BUFFER (Complex, work, nr); |
1825 int *p_perm = mattype.triangular_row_perm (); | 1825 octave_idx_type *p_perm = mattype.triangular_row_perm (); |
1826 int *q_perm = mattype.triangular_col_perm (); | 1826 octave_idx_type *q_perm = mattype.triangular_col_perm (); |
1827 | 1827 |
1828 (*current_liboctave_warning_handler) | 1828 (*current_liboctave_warning_handler) |
1829 ("SparseMatrix::solve XXX FIXME XXX permuted triangular code not tested"); | 1829 ("SparseMatrix::solve XXX FIXME XXX permuted triangular code not tested"); |
1830 | 1830 |
1831 for (int j = 0; j < b_nc; j++) | 1831 for (octave_idx_type j = 0; j < b_nc; j++) |
1832 { | 1832 { |
1833 for (int i = 0; i < nr; i++) | 1833 for (octave_idx_type i = 0; i < nr; i++) |
1834 work[i] = 0.; | 1834 work[i] = 0.; |
1835 for (int i = b.cidx(j); i < b.cidx(j+1); i++) | 1835 for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) |
1836 work[b.ridx(i)] = b.data(i); | 1836 work[b.ridx(i)] = b.data(i); |
1837 | 1837 |
1838 for (int k = nr-1; k >= 0; k--) | 1838 for (octave_idx_type k = nr-1; k >= 0; k--) |
1839 { | 1839 { |
1840 int iidx = q_perm[k]; | 1840 octave_idx_type iidx = q_perm[k]; |
1841 if (work[iidx] != 0.) | 1841 if (work[iidx] != 0.) |
1842 { | 1842 { |
1843 if (ridx(cidx(iidx+1)-1) != iidx) | 1843 if (ridx(cidx(iidx+1)-1) != iidx) |
1844 { | 1844 { |
1845 err = -2; | 1845 err = -2; |
1846 goto triangular_error; | 1846 goto triangular_error; |
1847 } | 1847 } |
1848 | 1848 |
1849 Complex tmp = work[iidx] / data(cidx(iidx+1)-1); | 1849 Complex tmp = work[iidx] / data(cidx(iidx+1)-1); |
1850 work[iidx] = tmp; | 1850 work[iidx] = tmp; |
1851 for (int i = cidx(iidx); i < cidx(iidx+1)-1; i++) | 1851 for (octave_idx_type i = cidx(iidx); i < cidx(iidx+1)-1; i++) |
1852 { | 1852 { |
1853 int idx2 = q_perm[ridx(i)]; | 1853 octave_idx_type idx2 = q_perm[ridx(i)]; |
1854 work[idx2] = | 1854 work[idx2] = |
1855 work[idx2] - tmp * data(i); | 1855 work[idx2] - tmp * data(i); |
1856 } | 1856 } |
1857 } | 1857 } |
1858 } | 1858 } |
1859 | 1859 |
1860 // Count non-zeros in work vector and adjust space in | 1860 // Count non-zeros in work vector and adjust space in |
1861 // retval if needed | 1861 // retval if needed |
1862 int new_nnz = 0; | 1862 octave_idx_type new_nnz = 0; |
1863 for (int i = 0; i < nr; i++) | 1863 for (octave_idx_type i = 0; i < nr; i++) |
1864 if (work[i] != 0.) | 1864 if (work[i] != 0.) |
1865 new_nnz++; | 1865 new_nnz++; |
1866 | 1866 |
1867 if (ii + new_nnz > x_nz) | 1867 if (ii + new_nnz > x_nz) |
1868 { | 1868 { |
1869 // Resize the sparse matrix | 1869 // Resize the sparse matrix |
1870 int sz = new_nnz * (b_nc - j) + x_nz; | 1870 octave_idx_type sz = new_nnz * (b_nc - j) + x_nz; |
1871 retval.change_capacity (sz); | 1871 retval.change_capacity (sz); |
1872 x_nz = sz; | 1872 x_nz = sz; |
1873 } | 1873 } |
1874 | 1874 |
1875 for (int i = 0; i < nr; i++) | 1875 for (octave_idx_type i = 0; i < nr; i++) |
1876 if (work[p_perm[i]] != 0.) | 1876 if (work[p_perm[i]] != 0.) |
1877 { | 1877 { |
1878 retval.xridx(ii) = i; | 1878 retval.xridx(ii) = i; |
1879 retval.xdata(ii++) = work[p_perm[i]]; | 1879 retval.xdata(ii++) = work[p_perm[i]]; |
1880 } | 1880 } |
1883 | 1883 |
1884 retval.maybe_compress (); | 1884 retval.maybe_compress (); |
1885 | 1885 |
1886 OCTAVE_LOCAL_BUFFER (double, work2, nr); | 1886 OCTAVE_LOCAL_BUFFER (double, work2, nr); |
1887 // Calculation of 1-norm of inv(*this) | 1887 // Calculation of 1-norm of inv(*this) |
1888 for (int i = 0; i < nr; i++) | 1888 for (octave_idx_type i = 0; i < nr; i++) |
1889 work2[i] = 0.; | 1889 work2[i] = 0.; |
1890 | 1890 |
1891 for (int j = 0; j < nr; j++) | 1891 for (octave_idx_type j = 0; j < nr; j++) |
1892 { | 1892 { |
1893 work2[q_perm[j]] = 1.; | 1893 work2[q_perm[j]] = 1.; |
1894 | 1894 |
1895 for (int k = j; k >= 0; k--) | 1895 for (octave_idx_type k = j; k >= 0; k--) |
1896 { | 1896 { |
1897 int iidx = q_perm[k]; | 1897 octave_idx_type iidx = q_perm[k]; |
1898 | 1898 |
1899 if (work2[iidx] != 0.) | 1899 if (work2[iidx] != 0.) |
1900 { | 1900 { |
1901 double tmp = work2[iidx] / data(cidx(iidx+1)-1); | 1901 double tmp = work2[iidx] / data(cidx(iidx+1)-1); |
1902 work2[iidx] = tmp; | 1902 work2[iidx] = tmp; |
1903 for (int i = cidx(iidx); i < cidx(iidx+1)-1; i++) | 1903 for (octave_idx_type i = cidx(iidx); i < cidx(iidx+1)-1; i++) |
1904 { | 1904 { |
1905 int idx2 = q_perm[ridx(i)]; | 1905 octave_idx_type idx2 = q_perm[ridx(i)]; |
1906 work2[idx2] = work2[idx2] - tmp * data(i); | 1906 work2[idx2] = work2[idx2] - tmp * data(i); |
1907 } | 1907 } |
1908 } | 1908 } |
1909 } | 1909 } |
1910 double atmp = 0; | 1910 double atmp = 0; |
1911 for (int i = 0; i < j+1; i++) | 1911 for (octave_idx_type i = 0; i < j+1; i++) |
1912 { | 1912 { |
1913 atmp += fabs(work2[i]); | 1913 atmp += fabs(work2[i]); |
1914 work2[i] = 0.; | 1914 work2[i] = 0.; |
1915 } | 1915 } |
1916 if (atmp > ainvnorm) | 1916 if (atmp > ainvnorm) |
1919 } | 1919 } |
1920 else | 1920 else |
1921 { | 1921 { |
1922 OCTAVE_LOCAL_BUFFER (Complex, work, nr); | 1922 OCTAVE_LOCAL_BUFFER (Complex, work, nr); |
1923 | 1923 |
1924 for (int j = 0; j < b_nc; j++) | 1924 for (octave_idx_type j = 0; j < b_nc; j++) |
1925 { | 1925 { |
1926 for (int i = 0; i < nr; i++) | 1926 for (octave_idx_type i = 0; i < nr; i++) |
1927 work[i] = 0.; | 1927 work[i] = 0.; |
1928 for (int i = b.cidx(j); i < b.cidx(j+1); i++) | 1928 for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) |
1929 work[b.ridx(i)] = b.data(i); | 1929 work[b.ridx(i)] = b.data(i); |
1930 | 1930 |
1931 for (int k = nr-1; k >= 0; k--) | 1931 for (octave_idx_type k = nr-1; k >= 0; k--) |
1932 { | 1932 { |
1933 if (work[k] != 0.) | 1933 if (work[k] != 0.) |
1934 { | 1934 { |
1935 if (ridx(cidx(k+1)-1) != k) | 1935 if (ridx(cidx(k+1)-1) != k) |
1936 { | 1936 { |
1938 goto triangular_error; | 1938 goto triangular_error; |
1939 } | 1939 } |
1940 | 1940 |
1941 Complex tmp = work[k] / data(cidx(k+1)-1); | 1941 Complex tmp = work[k] / data(cidx(k+1)-1); |
1942 work[k] = tmp; | 1942 work[k] = tmp; |
1943 for (int i = cidx(k); i < cidx(k+1)-1; i++) | 1943 for (octave_idx_type i = cidx(k); i < cidx(k+1)-1; i++) |
1944 { | 1944 { |
1945 int iidx = ridx(i); | 1945 octave_idx_type iidx = ridx(i); |
1946 work[iidx] = work[iidx] - tmp * data(i); | 1946 work[iidx] = work[iidx] - tmp * data(i); |
1947 } | 1947 } |
1948 } | 1948 } |
1949 } | 1949 } |
1950 | 1950 |
1951 // Count non-zeros in work vector and adjust space in | 1951 // Count non-zeros in work vector and adjust space in |
1952 // retval if needed | 1952 // retval if needed |
1953 int new_nnz = 0; | 1953 octave_idx_type new_nnz = 0; |
1954 for (int i = 0; i < nr; i++) | 1954 for (octave_idx_type i = 0; i < nr; i++) |
1955 if (work[i] != 0.) | 1955 if (work[i] != 0.) |
1956 new_nnz++; | 1956 new_nnz++; |
1957 | 1957 |
1958 if (ii + new_nnz > x_nz) | 1958 if (ii + new_nnz > x_nz) |
1959 { | 1959 { |
1960 // Resize the sparse matrix | 1960 // Resize the sparse matrix |
1961 int sz = new_nnz * (b_nc - j) + x_nz; | 1961 octave_idx_type sz = new_nnz * (b_nc - j) + x_nz; |
1962 retval.change_capacity (sz); | 1962 retval.change_capacity (sz); |
1963 x_nz = sz; | 1963 x_nz = sz; |
1964 } | 1964 } |
1965 | 1965 |
1966 for (int i = 0; i < nr; i++) | 1966 for (octave_idx_type i = 0; i < nr; i++) |
1967 if (work[i] != 0.) | 1967 if (work[i] != 0.) |
1968 { | 1968 { |
1969 retval.xridx(ii) = i; | 1969 retval.xridx(ii) = i; |
1970 retval.xdata(ii++) = work[i]; | 1970 retval.xdata(ii++) = work[i]; |
1971 } | 1971 } |
1974 | 1974 |
1975 retval.maybe_compress (); | 1975 retval.maybe_compress (); |
1976 | 1976 |
1977 // Calculation of 1-norm of inv(*this) | 1977 // Calculation of 1-norm of inv(*this) |
1978 OCTAVE_LOCAL_BUFFER (double, work2, nr); | 1978 OCTAVE_LOCAL_BUFFER (double, work2, nr); |
1979 for (int i = 0; i < nr; i++) | 1979 for (octave_idx_type i = 0; i < nr; i++) |
1980 work2[i] = 0.; | 1980 work2[i] = 0.; |
1981 | 1981 |
1982 for (int j = 0; j < nr; j++) | 1982 for (octave_idx_type j = 0; j < nr; j++) |
1983 { | 1983 { |
1984 work2[j] = 1.; | 1984 work2[j] = 1.; |
1985 | 1985 |
1986 for (int k = j; k >= 0; k--) | 1986 for (octave_idx_type k = j; k >= 0; k--) |
1987 { | 1987 { |
1988 if (work2[k] != 0.) | 1988 if (work2[k] != 0.) |
1989 { | 1989 { |
1990 double tmp = work2[k] / data(cidx(k+1)-1); | 1990 double tmp = work2[k] / data(cidx(k+1)-1); |
1991 work2[k] = tmp; | 1991 work2[k] = tmp; |
1992 for (int i = cidx(k); i < cidx(k+1)-1; i++) | 1992 for (octave_idx_type i = cidx(k); i < cidx(k+1)-1; i++) |
1993 { | 1993 { |
1994 int iidx = ridx(i); | 1994 octave_idx_type iidx = ridx(i); |
1995 work2[iidx] = work2[iidx] - tmp * data(i); | 1995 work2[iidx] = work2[iidx] - tmp * data(i); |
1996 } | 1996 } |
1997 } | 1997 } |
1998 } | 1998 } |
1999 double atmp = 0; | 1999 double atmp = 0; |
2000 for (int i = 0; i < j+1; i++) | 2000 for (octave_idx_type i = 0; i < j+1; i++) |
2001 { | 2001 { |
2002 atmp += fabs(work2[i]); | 2002 atmp += fabs(work2[i]); |
2003 work2[i] = 0.; | 2003 work2[i] = 0.; |
2004 } | 2004 } |
2005 if (atmp > ainvnorm) | 2005 if (atmp > ainvnorm) |
2040 | 2040 |
2041 return retval; | 2041 return retval; |
2042 } | 2042 } |
2043 | 2043 |
2044 Matrix | 2044 Matrix |
2045 SparseMatrix::ltsolve (SparseType &mattype, const Matrix& b, int& err, | 2045 SparseMatrix::ltsolve (SparseType &mattype, const Matrix& b, octave_idx_type& err, |
2046 double& rcond, | 2046 double& rcond, |
2047 solve_singularity_handler sing_handler) const | 2047 solve_singularity_handler sing_handler) const |
2048 { | 2048 { |
2049 Matrix retval; | 2049 Matrix retval; |
2050 | 2050 |
2051 int nr = rows (); | 2051 octave_idx_type nr = rows (); |
2052 int nc = cols (); | 2052 octave_idx_type nc = cols (); |
2053 err = 0; | 2053 err = 0; |
2054 | 2054 |
2055 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) | 2055 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) |
2056 (*current_liboctave_error_handler) | 2056 (*current_liboctave_error_handler) |
2057 ("matrix dimension mismatch solution of linear equations"); | 2057 ("matrix dimension mismatch solution of linear equations"); |
2064 if (typ == SparseType::Permuted_Lower || | 2064 if (typ == SparseType::Permuted_Lower || |
2065 typ == SparseType::Lower) | 2065 typ == SparseType::Lower) |
2066 { | 2066 { |
2067 double anorm = 0.; | 2067 double anorm = 0.; |
2068 double ainvnorm = 0.; | 2068 double ainvnorm = 0.; |
2069 int b_cols = b.cols (); | 2069 octave_idx_type b_cols = b.cols (); |
2070 rcond = 0.; | 2070 rcond = 0.; |
2071 | 2071 |
2072 // Calculate the 1-norm of matrix for rcond calculation | 2072 // Calculate the 1-norm of matrix for rcond calculation |
2073 for (int j = 0; j < nr; j++) | 2073 for (octave_idx_type j = 0; j < nr; j++) |
2074 { | 2074 { |
2075 double atmp = 0.; | 2075 double atmp = 0.; |
2076 for (int i = cidx(j); i < cidx(j+1); i++) | 2076 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
2077 atmp += fabs(data(i)); | 2077 atmp += fabs(data(i)); |
2078 if (atmp > anorm) | 2078 if (atmp > anorm) |
2079 anorm = atmp; | 2079 anorm = atmp; |
2080 } | 2080 } |
2081 | 2081 |
2082 if (typ == SparseType::Permuted_Lower) | 2082 if (typ == SparseType::Permuted_Lower) |
2083 { | 2083 { |
2084 retval.resize (b.rows (), b.cols ()); | 2084 retval.resize (b.rows (), b.cols ()); |
2085 OCTAVE_LOCAL_BUFFER (double, work, nr); | 2085 OCTAVE_LOCAL_BUFFER (double, work, nr); |
2086 int *p_perm = mattype.triangular_row_perm (); | 2086 octave_idx_type *p_perm = mattype.triangular_row_perm (); |
2087 int *q_perm = mattype.triangular_col_perm (); | 2087 octave_idx_type *q_perm = mattype.triangular_col_perm (); |
2088 | 2088 |
2089 (*current_liboctave_warning_handler) | 2089 (*current_liboctave_warning_handler) |
2090 ("SparseMatrix::solve XXX FIXME XXX permuted triangular code not tested"); | 2090 ("SparseMatrix::solve XXX FIXME XXX permuted triangular code not tested"); |
2091 | 2091 |
2092 for (int j = 0; j < b_cols; j++) | 2092 for (octave_idx_type j = 0; j < b_cols; j++) |
2093 { | 2093 { |
2094 for (int i = 0; i < nr; i++) | 2094 for (octave_idx_type i = 0; i < nr; i++) |
2095 work[i] = b(i,j); | 2095 work[i] = b(i,j); |
2096 | 2096 |
2097 for (int k = 0; k < nr; k++) | 2097 for (octave_idx_type k = 0; k < nr; k++) |
2098 { | 2098 { |
2099 int iidx = q_perm[k]; | 2099 octave_idx_type iidx = q_perm[k]; |
2100 if (work[iidx] != 0.) | 2100 if (work[iidx] != 0.) |
2101 { | 2101 { |
2102 if (ridx(cidx(iidx)) != iidx) | 2102 if (ridx(cidx(iidx)) != iidx) |
2103 { | 2103 { |
2104 err = -2; | 2104 err = -2; |
2105 goto triangular_error; | 2105 goto triangular_error; |
2106 } | 2106 } |
2107 | 2107 |
2108 double tmp = work[iidx] / data(cidx(iidx+1)-1); | 2108 double tmp = work[iidx] / data(cidx(iidx+1)-1); |
2109 work[iidx] = tmp; | 2109 work[iidx] = tmp; |
2110 for (int i = cidx(iidx)+1; i < cidx(iidx+1); i++) | 2110 for (octave_idx_type i = cidx(iidx)+1; i < cidx(iidx+1); i++) |
2111 { | 2111 { |
2112 int idx2 = q_perm[ridx(i)]; | 2112 octave_idx_type idx2 = q_perm[ridx(i)]; |
2113 work[idx2] = | 2113 work[idx2] = |
2114 work[idx2] - tmp * data(i); | 2114 work[idx2] - tmp * data(i); |
2115 } | 2115 } |
2116 } | 2116 } |
2117 } | 2117 } |
2118 | 2118 |
2119 for (int i = 0; i < nr; i++) | 2119 for (octave_idx_type i = 0; i < nr; i++) |
2120 retval (i, j) = work[p_perm[i]]; | 2120 retval (i, j) = work[p_perm[i]]; |
2121 | 2121 |
2122 } | 2122 } |
2123 | 2123 |
2124 // Calculation of 1-norm of inv(*this) | 2124 // Calculation of 1-norm of inv(*this) |
2125 for (int i = 0; i < nr; i++) | 2125 for (octave_idx_type i = 0; i < nr; i++) |
2126 work[i] = 0.; | 2126 work[i] = 0.; |
2127 | 2127 |
2128 for (int j = 0; j < nr; j++) | 2128 for (octave_idx_type j = 0; j < nr; j++) |
2129 { | 2129 { |
2130 work[q_perm[j]] = 1.; | 2130 work[q_perm[j]] = 1.; |
2131 | 2131 |
2132 for (int k = 0; k < nr; k++) | 2132 for (octave_idx_type k = 0; k < nr; k++) |
2133 { | 2133 { |
2134 int iidx = q_perm[k]; | 2134 octave_idx_type iidx = q_perm[k]; |
2135 | 2135 |
2136 if (work[iidx] != 0.) | 2136 if (work[iidx] != 0.) |
2137 { | 2137 { |
2138 double tmp = work[iidx] / data(cidx(iidx+1)-1); | 2138 double tmp = work[iidx] / data(cidx(iidx+1)-1); |
2139 work[iidx] = tmp; | 2139 work[iidx] = tmp; |
2140 for (int i = cidx(iidx)+1; i < cidx(iidx+1); i++) | 2140 for (octave_idx_type i = cidx(iidx)+1; i < cidx(iidx+1); i++) |
2141 { | 2141 { |
2142 int idx2 = q_perm[ridx(i)]; | 2142 octave_idx_type idx2 = q_perm[ridx(i)]; |
2143 work[idx2] = work[idx2] - tmp * data(i); | 2143 work[idx2] = work[idx2] - tmp * data(i); |
2144 } | 2144 } |
2145 } | 2145 } |
2146 } | 2146 } |
2147 double atmp = 0; | 2147 double atmp = 0; |
2148 for (int i = 0; i < j+1; i++) | 2148 for (octave_idx_type i = 0; i < j+1; i++) |
2149 { | 2149 { |
2150 atmp += fabs(work[i]); | 2150 atmp += fabs(work[i]); |
2151 work[i] = 0.; | 2151 work[i] = 0.; |
2152 } | 2152 } |
2153 if (atmp > ainvnorm) | 2153 if (atmp > ainvnorm) |
2157 else | 2157 else |
2158 { | 2158 { |
2159 retval = b; | 2159 retval = b; |
2160 double *x_vec = retval.fortran_vec (); | 2160 double *x_vec = retval.fortran_vec (); |
2161 | 2161 |
2162 for (int j = 0; j < b_cols; j++) | 2162 for (octave_idx_type j = 0; j < b_cols; j++) |
2163 { | 2163 { |
2164 int offset = j * nr; | 2164 octave_idx_type offset = j * nr; |
2165 for (int k = 0; k < nr; k++) | 2165 for (octave_idx_type k = 0; k < nr; k++) |
2166 { | 2166 { |
2167 if (x_vec[k+offset] != 0.) | 2167 if (x_vec[k+offset] != 0.) |
2168 { | 2168 { |
2169 if (ridx(cidx(k)) != k) | 2169 if (ridx(cidx(k)) != k) |
2170 { | 2170 { |
2173 } | 2173 } |
2174 | 2174 |
2175 double tmp = x_vec[k+offset] / | 2175 double tmp = x_vec[k+offset] / |
2176 data(cidx(k)); | 2176 data(cidx(k)); |
2177 x_vec[k+offset] = tmp; | 2177 x_vec[k+offset] = tmp; |
2178 for (int i = cidx(k)+1; i < cidx(k+1); i++) | 2178 for (octave_idx_type i = cidx(k)+1; i < cidx(k+1); i++) |
2179 { | 2179 { |
2180 int iidx = ridx(i); | 2180 octave_idx_type iidx = ridx(i); |
2181 x_vec[iidx+offset] = | 2181 x_vec[iidx+offset] = |
2182 x_vec[iidx+offset] - tmp * data(i); | 2182 x_vec[iidx+offset] - tmp * data(i); |
2183 } | 2183 } |
2184 } | 2184 } |
2185 } | 2185 } |
2186 } | 2186 } |
2187 | 2187 |
2188 // Calculation of 1-norm of inv(*this) | 2188 // Calculation of 1-norm of inv(*this) |
2189 OCTAVE_LOCAL_BUFFER (double, work, nr); | 2189 OCTAVE_LOCAL_BUFFER (double, work, nr); |
2190 for (int i = 0; i < nr; i++) | 2190 for (octave_idx_type i = 0; i < nr; i++) |
2191 work[i] = 0.; | 2191 work[i] = 0.; |
2192 | 2192 |
2193 for (int j = 0; j < nr; j++) | 2193 for (octave_idx_type j = 0; j < nr; j++) |
2194 { | 2194 { |
2195 work[j] = 1.; | 2195 work[j] = 1.; |
2196 | 2196 |
2197 for (int k = j; k < nr; k++) | 2197 for (octave_idx_type k = j; k < nr; k++) |
2198 { | 2198 { |
2199 | 2199 |
2200 if (work[k] != 0.) | 2200 if (work[k] != 0.) |
2201 { | 2201 { |
2202 double tmp = work[k] / data(cidx(k)); | 2202 double tmp = work[k] / data(cidx(k)); |
2203 work[k] = tmp; | 2203 work[k] = tmp; |
2204 for (int i = cidx(k)+1; i < cidx(k+1); i++) | 2204 for (octave_idx_type i = cidx(k)+1; i < cidx(k+1); i++) |
2205 { | 2205 { |
2206 int iidx = ridx(i); | 2206 octave_idx_type iidx = ridx(i); |
2207 work[iidx] = work[iidx] - tmp * data(i); | 2207 work[iidx] = work[iidx] - tmp * data(i); |
2208 } | 2208 } |
2209 } | 2209 } |
2210 } | 2210 } |
2211 double atmp = 0; | 2211 double atmp = 0; |
2212 for (int i = j; i < nr; i++) | 2212 for (octave_idx_type i = j; i < nr; i++) |
2213 { | 2213 { |
2214 atmp += fabs(work[i]); | 2214 atmp += fabs(work[i]); |
2215 work[i] = 0.; | 2215 work[i] = 0.; |
2216 } | 2216 } |
2217 if (atmp > ainvnorm) | 2217 if (atmp > ainvnorm) |
2253 | 2253 |
2254 return retval; | 2254 return retval; |
2255 } | 2255 } |
2256 | 2256 |
2257 SparseMatrix | 2257 SparseMatrix |
2258 SparseMatrix::ltsolve (SparseType &mattype, const SparseMatrix& b, int& err, | 2258 SparseMatrix::ltsolve (SparseType &mattype, const SparseMatrix& b, octave_idx_type& err, |
2259 double& rcond, solve_singularity_handler sing_handler) const | 2259 double& rcond, solve_singularity_handler sing_handler) const |
2260 { | 2260 { |
2261 SparseMatrix retval; | 2261 SparseMatrix retval; |
2262 | 2262 |
2263 int nr = rows (); | 2263 octave_idx_type nr = rows (); |
2264 int nc = cols (); | 2264 octave_idx_type nc = cols (); |
2265 err = 0; | 2265 err = 0; |
2266 | 2266 |
2267 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) | 2267 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) |
2268 (*current_liboctave_error_handler) | 2268 (*current_liboctave_error_handler) |
2269 ("matrix dimension mismatch solution of linear equations"); | 2269 ("matrix dimension mismatch solution of linear equations"); |
2279 double anorm = 0.; | 2279 double anorm = 0.; |
2280 double ainvnorm = 0.; | 2280 double ainvnorm = 0.; |
2281 rcond = 0.; | 2281 rcond = 0.; |
2282 | 2282 |
2283 // Calculate the 1-norm of matrix for rcond calculation | 2283 // Calculate the 1-norm of matrix for rcond calculation |
2284 for (int j = 0; j < nr; j++) | 2284 for (octave_idx_type j = 0; j < nr; j++) |
2285 { | 2285 { |
2286 double atmp = 0.; | 2286 double atmp = 0.; |
2287 for (int i = cidx(j); i < cidx(j+1); i++) | 2287 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
2288 atmp += fabs(data(i)); | 2288 atmp += fabs(data(i)); |
2289 if (atmp > anorm) | 2289 if (atmp > anorm) |
2290 anorm = atmp; | 2290 anorm = atmp; |
2291 } | 2291 } |
2292 | 2292 |
2293 int b_nr = b.rows (); | 2293 octave_idx_type b_nr = b.rows (); |
2294 int b_nc = b.cols (); | 2294 octave_idx_type b_nc = b.cols (); |
2295 int b_nz = b.nnz (); | 2295 octave_idx_type b_nz = b.nnz (); |
2296 retval = SparseMatrix (b_nr, b_nc, b_nz); | 2296 retval = SparseMatrix (b_nr, b_nc, b_nz); |
2297 retval.xcidx(0) = 0; | 2297 retval.xcidx(0) = 0; |
2298 int ii = 0; | 2298 octave_idx_type ii = 0; |
2299 int x_nz = b_nz; | 2299 octave_idx_type x_nz = b_nz; |
2300 | 2300 |
2301 if (typ == SparseType::Permuted_Lower) | 2301 if (typ == SparseType::Permuted_Lower) |
2302 { | 2302 { |
2303 OCTAVE_LOCAL_BUFFER (double, work, nr); | 2303 OCTAVE_LOCAL_BUFFER (double, work, nr); |
2304 int *p_perm = mattype.triangular_row_perm (); | 2304 octave_idx_type *p_perm = mattype.triangular_row_perm (); |
2305 int *q_perm = mattype.triangular_col_perm (); | 2305 octave_idx_type *q_perm = mattype.triangular_col_perm (); |
2306 | 2306 |
2307 (*current_liboctave_warning_handler) | 2307 (*current_liboctave_warning_handler) |
2308 ("SparseMatrix::solve XXX FIXME XXX permuted triangular code not tested"); | 2308 ("SparseMatrix::solve XXX FIXME XXX permuted triangular code not tested"); |
2309 | 2309 |
2310 for (int j = 0; j < b_nc; j++) | 2310 for (octave_idx_type j = 0; j < b_nc; j++) |
2311 { | 2311 { |
2312 for (int i = 0; i < nr; i++) | 2312 for (octave_idx_type i = 0; i < nr; i++) |
2313 work[i] = 0.; | 2313 work[i] = 0.; |
2314 for (int i = b.cidx(j); i < b.cidx(j+1); i++) | 2314 for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) |
2315 work[b.ridx(i)] = b.data(i); | 2315 work[b.ridx(i)] = b.data(i); |
2316 | 2316 |
2317 for (int k = 0; k < nr; k++) | 2317 for (octave_idx_type k = 0; k < nr; k++) |
2318 { | 2318 { |
2319 int iidx = q_perm[k]; | 2319 octave_idx_type iidx = q_perm[k]; |
2320 if (work[iidx] != 0.) | 2320 if (work[iidx] != 0.) |
2321 { | 2321 { |
2322 if (ridx(cidx(iidx)) != iidx) | 2322 if (ridx(cidx(iidx)) != iidx) |
2323 { | 2323 { |
2324 err = -2; | 2324 err = -2; |
2325 goto triangular_error; | 2325 goto triangular_error; |
2326 } | 2326 } |
2327 | 2327 |
2328 double tmp = work[iidx] / data(cidx(iidx+1)-1); | 2328 double tmp = work[iidx] / data(cidx(iidx+1)-1); |
2329 work[iidx] = tmp; | 2329 work[iidx] = tmp; |
2330 for (int i = cidx(iidx)+1; i < cidx(iidx+1); i++) | 2330 for (octave_idx_type i = cidx(iidx)+1; i < cidx(iidx+1); i++) |
2331 { | 2331 { |
2332 int idx2 = q_perm[ridx(i)]; | 2332 octave_idx_type idx2 = q_perm[ridx(i)]; |
2333 work[idx2] = | 2333 work[idx2] = |
2334 work[idx2] - tmp * data(i); | 2334 work[idx2] - tmp * data(i); |
2335 } | 2335 } |
2336 } | 2336 } |
2337 } | 2337 } |
2338 | 2338 |
2339 // Count non-zeros in work vector and adjust space in | 2339 // Count non-zeros in work vector and adjust space in |
2340 // retval if needed | 2340 // retval if needed |
2341 int new_nnz = 0; | 2341 octave_idx_type new_nnz = 0; |
2342 for (int i = 0; i < nr; i++) | 2342 for (octave_idx_type i = 0; i < nr; i++) |
2343 if (work[i] != 0.) | 2343 if (work[i] != 0.) |
2344 new_nnz++; | 2344 new_nnz++; |
2345 | 2345 |
2346 if (ii + new_nnz > x_nz) | 2346 if (ii + new_nnz > x_nz) |
2347 { | 2347 { |
2348 // Resize the sparse matrix | 2348 // Resize the sparse matrix |
2349 int sz = new_nnz * (b_nc - j) + x_nz; | 2349 octave_idx_type sz = new_nnz * (b_nc - j) + x_nz; |
2350 retval.change_capacity (sz); | 2350 retval.change_capacity (sz); |
2351 x_nz = sz; | 2351 x_nz = sz; |
2352 } | 2352 } |
2353 | 2353 |
2354 for (int i = 0; i < nr; i++) | 2354 for (octave_idx_type i = 0; i < nr; i++) |
2355 if (work[p_perm[i]] != 0.) | 2355 if (work[p_perm[i]] != 0.) |
2356 { | 2356 { |
2357 retval.xridx(ii) = i; | 2357 retval.xridx(ii) = i; |
2358 retval.xdata(ii++) = work[p_perm[i]]; | 2358 retval.xdata(ii++) = work[p_perm[i]]; |
2359 } | 2359 } |
2361 } | 2361 } |
2362 | 2362 |
2363 retval.maybe_compress (); | 2363 retval.maybe_compress (); |
2364 | 2364 |
2365 // Calculation of 1-norm of inv(*this) | 2365 // Calculation of 1-norm of inv(*this) |
2366 for (int i = 0; i < nr; i++) | 2366 for (octave_idx_type i = 0; i < nr; i++) |
2367 work[i] = 0.; | 2367 work[i] = 0.; |
2368 | 2368 |
2369 for (int j = 0; j < nr; j++) | 2369 for (octave_idx_type j = 0; j < nr; j++) |
2370 { | 2370 { |
2371 work[q_perm[j]] = 1.; | 2371 work[q_perm[j]] = 1.; |
2372 | 2372 |
2373 for (int k = 0; k < nr; k++) | 2373 for (octave_idx_type k = 0; k < nr; k++) |
2374 { | 2374 { |
2375 int iidx = q_perm[k]; | 2375 octave_idx_type iidx = q_perm[k]; |
2376 | 2376 |
2377 if (work[iidx] != 0.) | 2377 if (work[iidx] != 0.) |
2378 { | 2378 { |
2379 double tmp = work[iidx] / data(cidx(iidx+1)-1); | 2379 double tmp = work[iidx] / data(cidx(iidx+1)-1); |
2380 work[iidx] = tmp; | 2380 work[iidx] = tmp; |
2381 for (int i = cidx(iidx)+1; i < cidx(iidx+1); i++) | 2381 for (octave_idx_type i = cidx(iidx)+1; i < cidx(iidx+1); i++) |
2382 { | 2382 { |
2383 int idx2 = q_perm[ridx(i)]; | 2383 octave_idx_type idx2 = q_perm[ridx(i)]; |
2384 work[idx2] = work[idx2] - tmp * data(i); | 2384 work[idx2] = work[idx2] - tmp * data(i); |
2385 } | 2385 } |
2386 } | 2386 } |
2387 } | 2387 } |
2388 double atmp = 0; | 2388 double atmp = 0; |
2389 for (int i = 0; i < j+1; i++) | 2389 for (octave_idx_type i = 0; i < j+1; i++) |
2390 { | 2390 { |
2391 atmp += fabs(work[i]); | 2391 atmp += fabs(work[i]); |
2392 work[i] = 0.; | 2392 work[i] = 0.; |
2393 } | 2393 } |
2394 if (atmp > ainvnorm) | 2394 if (atmp > ainvnorm) |
2397 } | 2397 } |
2398 else | 2398 else |
2399 { | 2399 { |
2400 OCTAVE_LOCAL_BUFFER (double, work, nr); | 2400 OCTAVE_LOCAL_BUFFER (double, work, nr); |
2401 | 2401 |
2402 for (int j = 0; j < b_nc; j++) | 2402 for (octave_idx_type j = 0; j < b_nc; j++) |
2403 { | 2403 { |
2404 for (int i = 0; i < nr; i++) | 2404 for (octave_idx_type i = 0; i < nr; i++) |
2405 work[i] = 0.; | 2405 work[i] = 0.; |
2406 for (int i = b.cidx(j); i < b.cidx(j+1); i++) | 2406 for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) |
2407 work[b.ridx(i)] = b.data(i); | 2407 work[b.ridx(i)] = b.data(i); |
2408 | 2408 |
2409 for (int k = 0; k < nr; k++) | 2409 for (octave_idx_type k = 0; k < nr; k++) |
2410 { | 2410 { |
2411 if (work[k] != 0.) | 2411 if (work[k] != 0.) |
2412 { | 2412 { |
2413 if (ridx(cidx(k)) != k) | 2413 if (ridx(cidx(k)) != k) |
2414 { | 2414 { |
2416 goto triangular_error; | 2416 goto triangular_error; |
2417 } | 2417 } |
2418 | 2418 |
2419 double tmp = work[k] / data(cidx(k)); | 2419 double tmp = work[k] / data(cidx(k)); |
2420 work[k] = tmp; | 2420 work[k] = tmp; |
2421 for (int i = cidx(k)+1; i < cidx(k+1); i++) | 2421 for (octave_idx_type i = cidx(k)+1; i < cidx(k+1); i++) |
2422 { | 2422 { |
2423 int iidx = ridx(i); | 2423 octave_idx_type iidx = ridx(i); |
2424 work[iidx] = work[iidx] - tmp * data(i); | 2424 work[iidx] = work[iidx] - tmp * data(i); |
2425 } | 2425 } |
2426 } | 2426 } |
2427 } | 2427 } |
2428 | 2428 |
2429 // Count non-zeros in work vector and adjust space in | 2429 // Count non-zeros in work vector and adjust space in |
2430 // retval if needed | 2430 // retval if needed |
2431 int new_nnz = 0; | 2431 octave_idx_type new_nnz = 0; |
2432 for (int i = 0; i < nr; i++) | 2432 for (octave_idx_type i = 0; i < nr; i++) |
2433 if (work[i] != 0.) | 2433 if (work[i] != 0.) |
2434 new_nnz++; | 2434 new_nnz++; |
2435 | 2435 |
2436 if (ii + new_nnz > x_nz) | 2436 if (ii + new_nnz > x_nz) |
2437 { | 2437 { |
2438 // Resize the sparse matrix | 2438 // Resize the sparse matrix |
2439 int sz = new_nnz * (b_nc - j) + x_nz; | 2439 octave_idx_type sz = new_nnz * (b_nc - j) + x_nz; |
2440 retval.change_capacity (sz); | 2440 retval.change_capacity (sz); |
2441 x_nz = sz; | 2441 x_nz = sz; |
2442 } | 2442 } |
2443 | 2443 |
2444 for (int i = 0; i < nr; i++) | 2444 for (octave_idx_type i = 0; i < nr; i++) |
2445 if (work[i] != 0.) | 2445 if (work[i] != 0.) |
2446 { | 2446 { |
2447 retval.xridx(ii) = i; | 2447 retval.xridx(ii) = i; |
2448 retval.xdata(ii++) = work[i]; | 2448 retval.xdata(ii++) = work[i]; |
2449 } | 2449 } |
2451 } | 2451 } |
2452 | 2452 |
2453 retval.maybe_compress (); | 2453 retval.maybe_compress (); |
2454 | 2454 |
2455 // Calculation of 1-norm of inv(*this) | 2455 // Calculation of 1-norm of inv(*this) |
2456 for (int i = 0; i < nr; i++) | 2456 for (octave_idx_type i = 0; i < nr; i++) |
2457 work[i] = 0.; | 2457 work[i] = 0.; |
2458 | 2458 |
2459 for (int j = 0; j < nr; j++) | 2459 for (octave_idx_type j = 0; j < nr; j++) |
2460 { | 2460 { |
2461 work[j] = 1.; | 2461 work[j] = 1.; |
2462 | 2462 |
2463 for (int k = j; k < nr; k++) | 2463 for (octave_idx_type k = j; k < nr; k++) |
2464 { | 2464 { |
2465 | 2465 |
2466 if (work[k] != 0.) | 2466 if (work[k] != 0.) |
2467 { | 2467 { |
2468 double tmp = work[k] / data(cidx(k)); | 2468 double tmp = work[k] / data(cidx(k)); |
2469 work[k] = tmp; | 2469 work[k] = tmp; |
2470 for (int i = cidx(k)+1; i < cidx(k+1); i++) | 2470 for (octave_idx_type i = cidx(k)+1; i < cidx(k+1); i++) |
2471 { | 2471 { |
2472 int iidx = ridx(i); | 2472 octave_idx_type iidx = ridx(i); |
2473 work[iidx] = work[iidx] - tmp * data(i); | 2473 work[iidx] = work[iidx] - tmp * data(i); |
2474 } | 2474 } |
2475 } | 2475 } |
2476 } | 2476 } |
2477 double atmp = 0; | 2477 double atmp = 0; |
2478 for (int i = j; i < nr; i++) | 2478 for (octave_idx_type i = j; i < nr; i++) |
2479 { | 2479 { |
2480 atmp += fabs(work[i]); | 2480 atmp += fabs(work[i]); |
2481 work[i] = 0.; | 2481 work[i] = 0.; |
2482 } | 2482 } |
2483 if (atmp > ainvnorm) | 2483 if (atmp > ainvnorm) |
2519 | 2519 |
2520 return retval; | 2520 return retval; |
2521 } | 2521 } |
2522 | 2522 |
2523 ComplexMatrix | 2523 ComplexMatrix |
2524 SparseMatrix::ltsolve (SparseType &mattype, const ComplexMatrix& b, int& err, | 2524 SparseMatrix::ltsolve (SparseType &mattype, const ComplexMatrix& b, octave_idx_type& err, |
2525 double& rcond, solve_singularity_handler sing_handler) const | 2525 double& rcond, solve_singularity_handler sing_handler) const |
2526 { | 2526 { |
2527 ComplexMatrix retval; | 2527 ComplexMatrix retval; |
2528 | 2528 |
2529 int nr = rows (); | 2529 octave_idx_type nr = rows (); |
2530 int nc = cols (); | 2530 octave_idx_type nc = cols (); |
2531 err = 0; | 2531 err = 0; |
2532 | 2532 |
2533 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) | 2533 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) |
2534 (*current_liboctave_error_handler) | 2534 (*current_liboctave_error_handler) |
2535 ("matrix dimension mismatch solution of linear equations"); | 2535 ("matrix dimension mismatch solution of linear equations"); |
2542 if (typ == SparseType::Permuted_Lower || | 2542 if (typ == SparseType::Permuted_Lower || |
2543 typ == SparseType::Lower) | 2543 typ == SparseType::Lower) |
2544 { | 2544 { |
2545 double anorm = 0.; | 2545 double anorm = 0.; |
2546 double ainvnorm = 0.; | 2546 double ainvnorm = 0.; |
2547 int b_nc = b.cols (); | 2547 octave_idx_type b_nc = b.cols (); |
2548 rcond = 0.; | 2548 rcond = 0.; |
2549 | 2549 |
2550 // Calculate the 1-norm of matrix for rcond calculation | 2550 // Calculate the 1-norm of matrix for rcond calculation |
2551 for (int j = 0; j < nr; j++) | 2551 for (octave_idx_type j = 0; j < nr; j++) |
2552 { | 2552 { |
2553 double atmp = 0.; | 2553 double atmp = 0.; |
2554 for (int i = cidx(j); i < cidx(j+1); i++) | 2554 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
2555 atmp += fabs(data(i)); | 2555 atmp += fabs(data(i)); |
2556 if (atmp > anorm) | 2556 if (atmp > anorm) |
2557 anorm = atmp; | 2557 anorm = atmp; |
2558 } | 2558 } |
2559 | 2559 |
2560 if (typ == SparseType::Permuted_Lower) | 2560 if (typ == SparseType::Permuted_Lower) |
2561 { | 2561 { |
2562 retval.resize (b.rows (), b.cols ()); | 2562 retval.resize (b.rows (), b.cols ()); |
2563 OCTAVE_LOCAL_BUFFER (Complex, work, nr); | 2563 OCTAVE_LOCAL_BUFFER (Complex, work, nr); |
2564 int *p_perm = mattype.triangular_row_perm (); | 2564 octave_idx_type *p_perm = mattype.triangular_row_perm (); |
2565 int *q_perm = mattype.triangular_col_perm (); | 2565 octave_idx_type *q_perm = mattype.triangular_col_perm (); |
2566 | 2566 |
2567 (*current_liboctave_warning_handler) | 2567 (*current_liboctave_warning_handler) |
2568 ("SparseMatrix::solve XXX FIXME XXX permuted triangular code not tested"); | 2568 ("SparseMatrix::solve XXX FIXME XXX permuted triangular code not tested"); |
2569 | 2569 |
2570 for (int j = 0; j < b_nc; j++) | 2570 for (octave_idx_type j = 0; j < b_nc; j++) |
2571 { | 2571 { |
2572 for (int i = 0; i < nr; i++) | 2572 for (octave_idx_type i = 0; i < nr; i++) |
2573 work[i] = b(i,j); | 2573 work[i] = b(i,j); |
2574 | 2574 |
2575 for (int k = 0; k < nr; k++) | 2575 for (octave_idx_type k = 0; k < nr; k++) |
2576 { | 2576 { |
2577 int iidx = q_perm[k]; | 2577 octave_idx_type iidx = q_perm[k]; |
2578 if (work[iidx] != 0.) | 2578 if (work[iidx] != 0.) |
2579 { | 2579 { |
2580 if (ridx(cidx(iidx)) != iidx) | 2580 if (ridx(cidx(iidx)) != iidx) |
2581 { | 2581 { |
2582 err = -2; | 2582 err = -2; |
2583 goto triangular_error; | 2583 goto triangular_error; |
2584 } | 2584 } |
2585 | 2585 |
2586 Complex tmp = work[iidx] / data(cidx(iidx+1)-1); | 2586 Complex tmp = work[iidx] / data(cidx(iidx+1)-1); |
2587 work[iidx] = tmp; | 2587 work[iidx] = tmp; |
2588 for (int i = cidx(iidx)+1; i < cidx(iidx+1); i++) | 2588 for (octave_idx_type i = cidx(iidx)+1; i < cidx(iidx+1); i++) |
2589 { | 2589 { |
2590 int idx2 = q_perm[ridx(i)]; | 2590 octave_idx_type idx2 = q_perm[ridx(i)]; |
2591 work[idx2] = | 2591 work[idx2] = |
2592 work[idx2] - tmp * data(i); | 2592 work[idx2] - tmp * data(i); |
2593 } | 2593 } |
2594 } | 2594 } |
2595 } | 2595 } |
2596 | 2596 |
2597 for (int i = 0; i < nr; i++) | 2597 for (octave_idx_type i = 0; i < nr; i++) |
2598 retval (i, j) = work[p_perm[i]]; | 2598 retval (i, j) = work[p_perm[i]]; |
2599 | 2599 |
2600 } | 2600 } |
2601 | 2601 |
2602 // Calculation of 1-norm of inv(*this) | 2602 // Calculation of 1-norm of inv(*this) |
2603 OCTAVE_LOCAL_BUFFER (double, work2, nr); | 2603 OCTAVE_LOCAL_BUFFER (double, work2, nr); |
2604 for (int i = 0; i < nr; i++) | 2604 for (octave_idx_type i = 0; i < nr; i++) |
2605 work2[i] = 0.; | 2605 work2[i] = 0.; |
2606 | 2606 |
2607 for (int j = 0; j < nr; j++) | 2607 for (octave_idx_type j = 0; j < nr; j++) |
2608 { | 2608 { |
2609 work2[q_perm[j]] = 1.; | 2609 work2[q_perm[j]] = 1.; |
2610 | 2610 |
2611 for (int k = 0; k < nr; k++) | 2611 for (octave_idx_type k = 0; k < nr; k++) |
2612 { | 2612 { |
2613 int iidx = q_perm[k]; | 2613 octave_idx_type iidx = q_perm[k]; |
2614 | 2614 |
2615 if (work2[iidx] != 0.) | 2615 if (work2[iidx] != 0.) |
2616 { | 2616 { |
2617 double tmp = work2[iidx] / data(cidx(iidx+1)-1); | 2617 double tmp = work2[iidx] / data(cidx(iidx+1)-1); |
2618 work2[iidx] = tmp; | 2618 work2[iidx] = tmp; |
2619 for (int i = cidx(iidx)+1; i < cidx(iidx+1); i++) | 2619 for (octave_idx_type i = cidx(iidx)+1; i < cidx(iidx+1); i++) |
2620 { | 2620 { |
2621 int idx2 = q_perm[ridx(i)]; | 2621 octave_idx_type idx2 = q_perm[ridx(i)]; |
2622 work2[idx2] = work2[idx2] - tmp * data(i); | 2622 work2[idx2] = work2[idx2] - tmp * data(i); |
2623 } | 2623 } |
2624 } | 2624 } |
2625 } | 2625 } |
2626 double atmp = 0; | 2626 double atmp = 0; |
2627 for (int i = 0; i < j+1; i++) | 2627 for (octave_idx_type i = 0; i < j+1; i++) |
2628 { | 2628 { |
2629 atmp += fabs(work2[i]); | 2629 atmp += fabs(work2[i]); |
2630 work2[i] = 0.; | 2630 work2[i] = 0.; |
2631 } | 2631 } |
2632 if (atmp > ainvnorm) | 2632 if (atmp > ainvnorm) |
2636 else | 2636 else |
2637 { | 2637 { |
2638 retval = b; | 2638 retval = b; |
2639 Complex *x_vec = retval.fortran_vec (); | 2639 Complex *x_vec = retval.fortran_vec (); |
2640 | 2640 |
2641 for (int j = 0; j < b_nc; j++) | 2641 for (octave_idx_type j = 0; j < b_nc; j++) |
2642 { | 2642 { |
2643 int offset = j * nr; | 2643 octave_idx_type offset = j * nr; |
2644 for (int k = 0; k < nr; k++) | 2644 for (octave_idx_type k = 0; k < nr; k++) |
2645 { | 2645 { |
2646 if (x_vec[k+offset] != 0.) | 2646 if (x_vec[k+offset] != 0.) |
2647 { | 2647 { |
2648 if (ridx(cidx(k)) != k) | 2648 if (ridx(cidx(k)) != k) |
2649 { | 2649 { |
2652 } | 2652 } |
2653 | 2653 |
2654 Complex tmp = x_vec[k+offset] / | 2654 Complex tmp = x_vec[k+offset] / |
2655 data(cidx(k)); | 2655 data(cidx(k)); |
2656 x_vec[k+offset] = tmp; | 2656 x_vec[k+offset] = tmp; |
2657 for (int i = cidx(k)+1; i < cidx(k+1); i++) | 2657 for (octave_idx_type i = cidx(k)+1; i < cidx(k+1); i++) |
2658 { | 2658 { |
2659 int iidx = ridx(i); | 2659 octave_idx_type iidx = ridx(i); |
2660 x_vec[iidx+offset] = | 2660 x_vec[iidx+offset] = |
2661 x_vec[iidx+offset] - tmp * data(i); | 2661 x_vec[iidx+offset] - tmp * data(i); |
2662 } | 2662 } |
2663 } | 2663 } |
2664 } | 2664 } |
2665 } | 2665 } |
2666 | 2666 |
2667 // Calculation of 1-norm of inv(*this) | 2667 // Calculation of 1-norm of inv(*this) |
2668 OCTAVE_LOCAL_BUFFER (double, work, nr); | 2668 OCTAVE_LOCAL_BUFFER (double, work, nr); |
2669 for (int i = 0; i < nr; i++) | 2669 for (octave_idx_type i = 0; i < nr; i++) |
2670 work[i] = 0.; | 2670 work[i] = 0.; |
2671 | 2671 |
2672 for (int j = 0; j < nr; j++) | 2672 for (octave_idx_type j = 0; j < nr; j++) |
2673 { | 2673 { |
2674 work[j] = 1.; | 2674 work[j] = 1.; |
2675 | 2675 |
2676 for (int k = j; k < nr; k++) | 2676 for (octave_idx_type k = j; k < nr; k++) |
2677 { | 2677 { |
2678 | 2678 |
2679 if (work[k] != 0.) | 2679 if (work[k] != 0.) |
2680 { | 2680 { |
2681 double tmp = work[k] / data(cidx(k)); | 2681 double tmp = work[k] / data(cidx(k)); |
2682 work[k] = tmp; | 2682 work[k] = tmp; |
2683 for (int i = cidx(k)+1; i < cidx(k+1); i++) | 2683 for (octave_idx_type i = cidx(k)+1; i < cidx(k+1); i++) |
2684 { | 2684 { |
2685 int iidx = ridx(i); | 2685 octave_idx_type iidx = ridx(i); |
2686 work[iidx] = work[iidx] - tmp * data(i); | 2686 work[iidx] = work[iidx] - tmp * data(i); |
2687 } | 2687 } |
2688 } | 2688 } |
2689 } | 2689 } |
2690 double atmp = 0; | 2690 double atmp = 0; |
2691 for (int i = j; i < nr; i++) | 2691 for (octave_idx_type i = j; i < nr; i++) |
2692 { | 2692 { |
2693 atmp += fabs(work[i]); | 2693 atmp += fabs(work[i]); |
2694 work[i] = 0.; | 2694 work[i] = 0.; |
2695 } | 2695 } |
2696 if (atmp > ainvnorm) | 2696 if (atmp > ainvnorm) |
2733 return retval; | 2733 return retval; |
2734 } | 2734 } |
2735 | 2735 |
2736 SparseComplexMatrix | 2736 SparseComplexMatrix |
2737 SparseMatrix::ltsolve (SparseType &mattype, const SparseComplexMatrix& b, | 2737 SparseMatrix::ltsolve (SparseType &mattype, const SparseComplexMatrix& b, |
2738 int& err, double& rcond, | 2738 octave_idx_type& err, double& rcond, |
2739 solve_singularity_handler sing_handler) const | 2739 solve_singularity_handler sing_handler) const |
2740 { | 2740 { |
2741 SparseComplexMatrix retval; | 2741 SparseComplexMatrix retval; |
2742 | 2742 |
2743 int nr = rows (); | 2743 octave_idx_type nr = rows (); |
2744 int nc = cols (); | 2744 octave_idx_type nc = cols (); |
2745 err = 0; | 2745 err = 0; |
2746 | 2746 |
2747 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) | 2747 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) |
2748 (*current_liboctave_error_handler) | 2748 (*current_liboctave_error_handler) |
2749 ("matrix dimension mismatch solution of linear equations"); | 2749 ("matrix dimension mismatch solution of linear equations"); |
2759 double anorm = 0.; | 2759 double anorm = 0.; |
2760 double ainvnorm = 0.; | 2760 double ainvnorm = 0.; |
2761 rcond = 0.; | 2761 rcond = 0.; |
2762 | 2762 |
2763 // Calculate the 1-norm of matrix for rcond calculation | 2763 // Calculate the 1-norm of matrix for rcond calculation |
2764 for (int j = 0; j < nr; j++) | 2764 for (octave_idx_type j = 0; j < nr; j++) |
2765 { | 2765 { |
2766 double atmp = 0.; | 2766 double atmp = 0.; |
2767 for (int i = cidx(j); i < cidx(j+1); i++) | 2767 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
2768 atmp += fabs(data(i)); | 2768 atmp += fabs(data(i)); |
2769 if (atmp > anorm) | 2769 if (atmp > anorm) |
2770 anorm = atmp; | 2770 anorm = atmp; |
2771 } | 2771 } |
2772 | 2772 |
2773 int b_nr = b.rows (); | 2773 octave_idx_type b_nr = b.rows (); |
2774 int b_nc = b.cols (); | 2774 octave_idx_type b_nc = b.cols (); |
2775 int b_nz = b.nnz (); | 2775 octave_idx_type b_nz = b.nnz (); |
2776 retval = SparseComplexMatrix (b_nr, b_nc, b_nz); | 2776 retval = SparseComplexMatrix (b_nr, b_nc, b_nz); |
2777 retval.xcidx(0) = 0; | 2777 retval.xcidx(0) = 0; |
2778 int ii = 0; | 2778 octave_idx_type ii = 0; |
2779 int x_nz = b_nz; | 2779 octave_idx_type x_nz = b_nz; |
2780 | 2780 |
2781 if (typ == SparseType::Permuted_Lower) | 2781 if (typ == SparseType::Permuted_Lower) |
2782 { | 2782 { |
2783 OCTAVE_LOCAL_BUFFER (Complex, work, nr); | 2783 OCTAVE_LOCAL_BUFFER (Complex, work, nr); |
2784 int *p_perm = mattype.triangular_row_perm (); | 2784 octave_idx_type *p_perm = mattype.triangular_row_perm (); |
2785 int *q_perm = mattype.triangular_col_perm (); | 2785 octave_idx_type *q_perm = mattype.triangular_col_perm (); |
2786 | 2786 |
2787 (*current_liboctave_warning_handler) | 2787 (*current_liboctave_warning_handler) |
2788 ("SparseMatrix::solve XXX FIXME XXX permuted triangular code not tested"); | 2788 ("SparseMatrix::solve XXX FIXME XXX permuted triangular code not tested"); |
2789 | 2789 |
2790 for (int j = 0; j < b_nc; j++) | 2790 for (octave_idx_type j = 0; j < b_nc; j++) |
2791 { | 2791 { |
2792 for (int i = 0; i < nr; i++) | 2792 for (octave_idx_type i = 0; i < nr; i++) |
2793 work[i] = 0.; | 2793 work[i] = 0.; |
2794 for (int i = b.cidx(j); i < b.cidx(j+1); i++) | 2794 for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) |
2795 work[b.ridx(i)] = b.data(i); | 2795 work[b.ridx(i)] = b.data(i); |
2796 | 2796 |
2797 for (int k = 0; k < nr; k++) | 2797 for (octave_idx_type k = 0; k < nr; k++) |
2798 { | 2798 { |
2799 int iidx = q_perm[k]; | 2799 octave_idx_type iidx = q_perm[k]; |
2800 if (work[iidx] != 0.) | 2800 if (work[iidx] != 0.) |
2801 { | 2801 { |
2802 if (ridx(cidx(iidx)) != iidx) | 2802 if (ridx(cidx(iidx)) != iidx) |
2803 { | 2803 { |
2804 err = -2; | 2804 err = -2; |
2805 goto triangular_error; | 2805 goto triangular_error; |
2806 } | 2806 } |
2807 | 2807 |
2808 Complex tmp = work[iidx] / data(cidx(iidx+1)-1); | 2808 Complex tmp = work[iidx] / data(cidx(iidx+1)-1); |
2809 work[iidx] = tmp; | 2809 work[iidx] = tmp; |
2810 for (int i = cidx(iidx)+1; i < cidx(iidx+1); i++) | 2810 for (octave_idx_type i = cidx(iidx)+1; i < cidx(iidx+1); i++) |
2811 { | 2811 { |
2812 int idx2 = q_perm[ridx(i)]; | 2812 octave_idx_type idx2 = q_perm[ridx(i)]; |
2813 work[idx2] = | 2813 work[idx2] = |
2814 work[idx2] - tmp * data(i); | 2814 work[idx2] - tmp * data(i); |
2815 } | 2815 } |
2816 } | 2816 } |
2817 } | 2817 } |
2818 | 2818 |
2819 // Count non-zeros in work vector and adjust space in | 2819 // Count non-zeros in work vector and adjust space in |
2820 // retval if needed | 2820 // retval if needed |
2821 int new_nnz = 0; | 2821 octave_idx_type new_nnz = 0; |
2822 for (int i = 0; i < nr; i++) | 2822 for (octave_idx_type i = 0; i < nr; i++) |
2823 if (work[i] != 0.) | 2823 if (work[i] != 0.) |
2824 new_nnz++; | 2824 new_nnz++; |
2825 | 2825 |
2826 if (ii + new_nnz > x_nz) | 2826 if (ii + new_nnz > x_nz) |
2827 { | 2827 { |
2828 // Resize the sparse matrix | 2828 // Resize the sparse matrix |
2829 int sz = new_nnz * (b_nc - j) + x_nz; | 2829 octave_idx_type sz = new_nnz * (b_nc - j) + x_nz; |
2830 retval.change_capacity (sz); | 2830 retval.change_capacity (sz); |
2831 x_nz = sz; | 2831 x_nz = sz; |
2832 } | 2832 } |
2833 | 2833 |
2834 for (int i = 0; i < nr; i++) | 2834 for (octave_idx_type i = 0; i < nr; i++) |
2835 if (work[p_perm[i]] != 0.) | 2835 if (work[p_perm[i]] != 0.) |
2836 { | 2836 { |
2837 retval.xridx(ii) = i; | 2837 retval.xridx(ii) = i; |
2838 retval.xdata(ii++) = work[p_perm[i]]; | 2838 retval.xdata(ii++) = work[p_perm[i]]; |
2839 } | 2839 } |
2842 | 2842 |
2843 retval.maybe_compress (); | 2843 retval.maybe_compress (); |
2844 | 2844 |
2845 // Calculation of 1-norm of inv(*this) | 2845 // Calculation of 1-norm of inv(*this) |
2846 OCTAVE_LOCAL_BUFFER (double, work2, nr); | 2846 OCTAVE_LOCAL_BUFFER (double, work2, nr); |
2847 for (int i = 0; i < nr; i++) | 2847 for (octave_idx_type i = 0; i < nr; i++) |
2848 work2[i] = 0.; | 2848 work2[i] = 0.; |
2849 | 2849 |
2850 for (int j = 0; j < nr; j++) | 2850 for (octave_idx_type j = 0; j < nr; j++) |
2851 { | 2851 { |
2852 work2[q_perm[j]] = 1.; | 2852 work2[q_perm[j]] = 1.; |
2853 | 2853 |
2854 for (int k = 0; k < nr; k++) | 2854 for (octave_idx_type k = 0; k < nr; k++) |
2855 { | 2855 { |
2856 int iidx = q_perm[k]; | 2856 octave_idx_type iidx = q_perm[k]; |
2857 | 2857 |
2858 if (work2[iidx] != 0.) | 2858 if (work2[iidx] != 0.) |
2859 { | 2859 { |
2860 double tmp = work2[iidx] / data(cidx(iidx+1)-1); | 2860 double tmp = work2[iidx] / data(cidx(iidx+1)-1); |
2861 work2[iidx] = tmp; | 2861 work2[iidx] = tmp; |
2862 for (int i = cidx(iidx)+1; i < cidx(iidx+1); i++) | 2862 for (octave_idx_type i = cidx(iidx)+1; i < cidx(iidx+1); i++) |
2863 { | 2863 { |
2864 int idx2 = q_perm[ridx(i)]; | 2864 octave_idx_type idx2 = q_perm[ridx(i)]; |
2865 work2[idx2] = work2[idx2] - tmp * data(i); | 2865 work2[idx2] = work2[idx2] - tmp * data(i); |
2866 } | 2866 } |
2867 } | 2867 } |
2868 } | 2868 } |
2869 double atmp = 0; | 2869 double atmp = 0; |
2870 for (int i = 0; i < j+1; i++) | 2870 for (octave_idx_type i = 0; i < j+1; i++) |
2871 { | 2871 { |
2872 atmp += fabs(work2[i]); | 2872 atmp += fabs(work2[i]); |
2873 work2[i] = 0.; | 2873 work2[i] = 0.; |
2874 } | 2874 } |
2875 if (atmp > ainvnorm) | 2875 if (atmp > ainvnorm) |
2878 } | 2878 } |
2879 else | 2879 else |
2880 { | 2880 { |
2881 OCTAVE_LOCAL_BUFFER (Complex, work, nr); | 2881 OCTAVE_LOCAL_BUFFER (Complex, work, nr); |
2882 | 2882 |
2883 for (int j = 0; j < b_nc; j++) | 2883 for (octave_idx_type j = 0; j < b_nc; j++) |
2884 { | 2884 { |
2885 for (int i = 0; i < nr; i++) | 2885 for (octave_idx_type i = 0; i < nr; i++) |
2886 work[i] = 0.; | 2886 work[i] = 0.; |
2887 for (int i = b.cidx(j); i < b.cidx(j+1); i++) | 2887 for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) |
2888 work[b.ridx(i)] = b.data(i); | 2888 work[b.ridx(i)] = b.data(i); |
2889 | 2889 |
2890 for (int k = 0; k < nr; k++) | 2890 for (octave_idx_type k = 0; k < nr; k++) |
2891 { | 2891 { |
2892 if (work[k] != 0.) | 2892 if (work[k] != 0.) |
2893 { | 2893 { |
2894 if (ridx(cidx(k)) != k) | 2894 if (ridx(cidx(k)) != k) |
2895 { | 2895 { |
2897 goto triangular_error; | 2897 goto triangular_error; |
2898 } | 2898 } |
2899 | 2899 |
2900 Complex tmp = work[k] / data(cidx(k)); | 2900 Complex tmp = work[k] / data(cidx(k)); |
2901 work[k] = tmp; | 2901 work[k] = tmp; |
2902 for (int i = cidx(k)+1; i < cidx(k+1); i++) | 2902 for (octave_idx_type i = cidx(k)+1; i < cidx(k+1); i++) |
2903 { | 2903 { |
2904 int iidx = ridx(i); | 2904 octave_idx_type iidx = ridx(i); |
2905 work[iidx] = work[iidx] - tmp * data(i); | 2905 work[iidx] = work[iidx] - tmp * data(i); |
2906 } | 2906 } |
2907 } | 2907 } |
2908 } | 2908 } |
2909 | 2909 |
2910 // Count non-zeros in work vector and adjust space in | 2910 // Count non-zeros in work vector and adjust space in |
2911 // retval if needed | 2911 // retval if needed |
2912 int new_nnz = 0; | 2912 octave_idx_type new_nnz = 0; |
2913 for (int i = 0; i < nr; i++) | 2913 for (octave_idx_type i = 0; i < nr; i++) |
2914 if (work[i] != 0.) | 2914 if (work[i] != 0.) |
2915 new_nnz++; | 2915 new_nnz++; |
2916 | 2916 |
2917 if (ii + new_nnz > x_nz) | 2917 if (ii + new_nnz > x_nz) |
2918 { | 2918 { |
2919 // Resize the sparse matrix | 2919 // Resize the sparse matrix |
2920 int sz = new_nnz * (b_nc - j) + x_nz; | 2920 octave_idx_type sz = new_nnz * (b_nc - j) + x_nz; |
2921 retval.change_capacity (sz); | 2921 retval.change_capacity (sz); |
2922 x_nz = sz; | 2922 x_nz = sz; |
2923 } | 2923 } |
2924 | 2924 |
2925 for (int i = 0; i < nr; i++) | 2925 for (octave_idx_type i = 0; i < nr; i++) |
2926 if (work[i] != 0.) | 2926 if (work[i] != 0.) |
2927 { | 2927 { |
2928 retval.xridx(ii) = i; | 2928 retval.xridx(ii) = i; |
2929 retval.xdata(ii++) = work[i]; | 2929 retval.xdata(ii++) = work[i]; |
2930 } | 2930 } |
2933 | 2933 |
2934 retval.maybe_compress (); | 2934 retval.maybe_compress (); |
2935 | 2935 |
2936 // Calculation of 1-norm of inv(*this) | 2936 // Calculation of 1-norm of inv(*this) |
2937 OCTAVE_LOCAL_BUFFER (double, work2, nr); | 2937 OCTAVE_LOCAL_BUFFER (double, work2, nr); |
2938 for (int i = 0; i < nr; i++) | 2938 for (octave_idx_type i = 0; i < nr; i++) |
2939 work2[i] = 0.; | 2939 work2[i] = 0.; |
2940 | 2940 |
2941 for (int j = 0; j < nr; j++) | 2941 for (octave_idx_type j = 0; j < nr; j++) |
2942 { | 2942 { |
2943 work2[j] = 1.; | 2943 work2[j] = 1.; |
2944 | 2944 |
2945 for (int k = j; k < nr; k++) | 2945 for (octave_idx_type k = j; k < nr; k++) |
2946 { | 2946 { |
2947 | 2947 |
2948 if (work2[k] != 0.) | 2948 if (work2[k] != 0.) |
2949 { | 2949 { |
2950 double tmp = work2[k] / data(cidx(k)); | 2950 double tmp = work2[k] / data(cidx(k)); |
2951 work2[k] = tmp; | 2951 work2[k] = tmp; |
2952 for (int i = cidx(k)+1; i < cidx(k+1); i++) | 2952 for (octave_idx_type i = cidx(k)+1; i < cidx(k+1); i++) |
2953 { | 2953 { |
2954 int iidx = ridx(i); | 2954 octave_idx_type iidx = ridx(i); |
2955 work2[iidx] = work2[iidx] - tmp * data(i); | 2955 work2[iidx] = work2[iidx] - tmp * data(i); |
2956 } | 2956 } |
2957 } | 2957 } |
2958 } | 2958 } |
2959 double atmp = 0; | 2959 double atmp = 0; |
2960 for (int i = j; i < nr; i++) | 2960 for (octave_idx_type i = j; i < nr; i++) |
2961 { | 2961 { |
2962 atmp += fabs(work2[i]); | 2962 atmp += fabs(work2[i]); |
2963 work2[i] = 0.; | 2963 work2[i] = 0.; |
2964 } | 2964 } |
2965 if (atmp > ainvnorm) | 2965 if (atmp > ainvnorm) |
3001 | 3001 |
3002 return retval; | 3002 return retval; |
3003 } | 3003 } |
3004 | 3004 |
3005 Matrix | 3005 Matrix |
3006 SparseMatrix::trisolve (SparseType &mattype, const Matrix& b, int& err, | 3006 SparseMatrix::trisolve (SparseType &mattype, const Matrix& b, octave_idx_type& err, |
3007 double& rcond, | 3007 double& rcond, |
3008 solve_singularity_handler sing_handler) const | 3008 solve_singularity_handler sing_handler) const |
3009 { | 3009 { |
3010 Matrix retval; | 3010 Matrix retval; |
3011 | 3011 |
3012 int nr = rows (); | 3012 octave_idx_type nr = rows (); |
3013 int nc = cols (); | 3013 octave_idx_type nc = cols (); |
3014 err = 0; | 3014 err = 0; |
3015 | 3015 |
3016 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) | 3016 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) |
3017 (*current_liboctave_error_handler) | 3017 (*current_liboctave_error_handler) |
3018 ("matrix dimension mismatch solution of linear equations"); | 3018 ("matrix dimension mismatch solution of linear equations"); |
3027 OCTAVE_LOCAL_BUFFER (double, D, nr); | 3027 OCTAVE_LOCAL_BUFFER (double, D, nr); |
3028 OCTAVE_LOCAL_BUFFER (double, DL, nr - 1); | 3028 OCTAVE_LOCAL_BUFFER (double, DL, nr - 1); |
3029 | 3029 |
3030 if (mattype.is_dense ()) | 3030 if (mattype.is_dense ()) |
3031 { | 3031 { |
3032 int ii = 0; | 3032 octave_idx_type ii = 0; |
3033 | 3033 |
3034 for (int j = 0; j < nc-1; j++) | 3034 for (octave_idx_type j = 0; j < nc-1; j++) |
3035 { | 3035 { |
3036 D[j] = data(ii++); | 3036 D[j] = data(ii++); |
3037 DL[j] = data(ii); | 3037 DL[j] = data(ii); |
3038 ii += 2; | 3038 ii += 2; |
3039 } | 3039 } |
3040 D[nc-1] = data(ii); | 3040 D[nc-1] = data(ii); |
3041 } | 3041 } |
3042 else | 3042 else |
3043 { | 3043 { |
3044 D[0] = 0.; | 3044 D[0] = 0.; |
3045 for (int i = 0; i < nr - 1; i++) | 3045 for (octave_idx_type i = 0; i < nr - 1; i++) |
3046 { | 3046 { |
3047 D[i+1] = 0.; | 3047 D[i+1] = 0.; |
3048 DL[i] = 0.; | 3048 DL[i] = 0.; |
3049 } | 3049 } |
3050 | 3050 |
3051 for (int j = 0; j < nc; j++) | 3051 for (octave_idx_type j = 0; j < nc; j++) |
3052 for (int i = cidx(j); i < cidx(j+1); i++) | 3052 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
3053 { | 3053 { |
3054 if (ridx(i) == j) | 3054 if (ridx(i) == j) |
3055 D[j] = data(i); | 3055 D[j] = data(i); |
3056 else if (ridx(i) == j + 1) | 3056 else if (ridx(i) == j + 1) |
3057 DL[j] = data(i); | 3057 DL[j] = data(i); |
3058 } | 3058 } |
3059 } | 3059 } |
3060 | 3060 |
3061 int b_nc = b.cols(); | 3061 octave_idx_type b_nc = b.cols(); |
3062 retval = b; | 3062 retval = b; |
3063 double *result = retval.fortran_vec (); | 3063 double *result = retval.fortran_vec (); |
3064 | 3064 |
3065 F77_XFCN (dptsv, DPTSV, (nr, b_nc, D, DL, result, | 3065 F77_XFCN (dptsv, DPTSV, (nr, b_nc, D, DL, result, |
3066 b.rows(), err)); | 3066 b.rows(), err)); |
3084 OCTAVE_LOCAL_BUFFER (double, D, nr); | 3084 OCTAVE_LOCAL_BUFFER (double, D, nr); |
3085 OCTAVE_LOCAL_BUFFER (double, DL, nr - 1); | 3085 OCTAVE_LOCAL_BUFFER (double, DL, nr - 1); |
3086 | 3086 |
3087 if (mattype.is_dense ()) | 3087 if (mattype.is_dense ()) |
3088 { | 3088 { |
3089 int ii = 0; | 3089 octave_idx_type ii = 0; |
3090 | 3090 |
3091 for (int j = 0; j < nc-1; j++) | 3091 for (octave_idx_type j = 0; j < nc-1; j++) |
3092 { | 3092 { |
3093 D[j] = data(ii++); | 3093 D[j] = data(ii++); |
3094 DL[j] = data(ii++); | 3094 DL[j] = data(ii++); |
3095 DU[j] = data(ii++); | 3095 DU[j] = data(ii++); |
3096 } | 3096 } |
3097 D[nc-1] = data(ii); | 3097 D[nc-1] = data(ii); |
3098 } | 3098 } |
3099 else | 3099 else |
3100 { | 3100 { |
3101 D[0] = 0.; | 3101 D[0] = 0.; |
3102 for (int i = 0; i < nr - 1; i++) | 3102 for (octave_idx_type i = 0; i < nr - 1; i++) |
3103 { | 3103 { |
3104 D[i+1] = 0.; | 3104 D[i+1] = 0.; |
3105 DL[i] = 0.; | 3105 DL[i] = 0.; |
3106 DU[i] = 0.; | 3106 DU[i] = 0.; |
3107 } | 3107 } |
3108 | 3108 |
3109 for (int j = 0; j < nc; j++) | 3109 for (octave_idx_type j = 0; j < nc; j++) |
3110 for (int i = cidx(j); i < cidx(j+1); i++) | 3110 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
3111 { | 3111 { |
3112 if (ridx(i) == j) | 3112 if (ridx(i) == j) |
3113 D[j] = data(i); | 3113 D[j] = data(i); |
3114 else if (ridx(i) == j + 1) | 3114 else if (ridx(i) == j + 1) |
3115 DL[j] = data(i); | 3115 DL[j] = data(i); |
3116 else if (ridx(i) == j - 1) | 3116 else if (ridx(i) == j - 1) |
3117 DU[j] = data(i); | 3117 DU[j] = data(i); |
3118 } | 3118 } |
3119 } | 3119 } |
3120 | 3120 |
3121 int b_nc = b.cols(); | 3121 octave_idx_type b_nc = b.cols(); |
3122 retval = b; | 3122 retval = b; |
3123 double *result = retval.fortran_vec (); | 3123 double *result = retval.fortran_vec (); |
3124 | 3124 |
3125 F77_XFCN (dgtsv, DGTSV, (nr, b_nc, DL, D, DU, result, | 3125 F77_XFCN (dgtsv, DGTSV, (nr, b_nc, DL, D, DU, result, |
3126 b.rows(), err)); | 3126 b.rows(), err)); |
3149 | 3149 |
3150 return retval; | 3150 return retval; |
3151 } | 3151 } |
3152 | 3152 |
3153 SparseMatrix | 3153 SparseMatrix |
3154 SparseMatrix::trisolve (SparseType &mattype, const SparseMatrix& b, int& err, | 3154 SparseMatrix::trisolve (SparseType &mattype, const SparseMatrix& b, octave_idx_type& err, |
3155 double& rcond, solve_singularity_handler sing_handler) const | 3155 double& rcond, solve_singularity_handler sing_handler) const |
3156 { | 3156 { |
3157 SparseMatrix retval; | 3157 SparseMatrix retval; |
3158 | 3158 |
3159 int nr = rows (); | 3159 octave_idx_type nr = rows (); |
3160 int nc = cols (); | 3160 octave_idx_type nc = cols (); |
3161 err = 0; | 3161 err = 0; |
3162 | 3162 |
3163 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) | 3163 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) |
3164 (*current_liboctave_error_handler) | 3164 (*current_liboctave_error_handler) |
3165 ("matrix dimension mismatch solution of linear equations"); | 3165 ("matrix dimension mismatch solution of linear equations"); |
3175 { | 3175 { |
3176 OCTAVE_LOCAL_BUFFER (double, DU2, nr - 2); | 3176 OCTAVE_LOCAL_BUFFER (double, DU2, nr - 2); |
3177 OCTAVE_LOCAL_BUFFER (double, DU, nr - 1); | 3177 OCTAVE_LOCAL_BUFFER (double, DU, nr - 1); |
3178 OCTAVE_LOCAL_BUFFER (double, D, nr); | 3178 OCTAVE_LOCAL_BUFFER (double, D, nr); |
3179 OCTAVE_LOCAL_BUFFER (double, DL, nr - 1); | 3179 OCTAVE_LOCAL_BUFFER (double, DL, nr - 1); |
3180 Array<int> ipvt (nr); | 3180 Array<octave_idx_type> ipvt (nr); |
3181 int *pipvt = ipvt.fortran_vec (); | 3181 octave_idx_type *pipvt = ipvt.fortran_vec (); |
3182 | 3182 |
3183 if (mattype.is_dense ()) | 3183 if (mattype.is_dense ()) |
3184 { | 3184 { |
3185 int ii = 0; | 3185 octave_idx_type ii = 0; |
3186 | 3186 |
3187 for (int j = 0; j < nc-1; j++) | 3187 for (octave_idx_type j = 0; j < nc-1; j++) |
3188 { | 3188 { |
3189 D[j] = data(ii++); | 3189 D[j] = data(ii++); |
3190 DL[j] = data(ii++); | 3190 DL[j] = data(ii++); |
3191 DU[j] = data(ii++); | 3191 DU[j] = data(ii++); |
3192 } | 3192 } |
3193 D[nc-1] = data(ii); | 3193 D[nc-1] = data(ii); |
3194 } | 3194 } |
3195 else | 3195 else |
3196 { | 3196 { |
3197 D[0] = 0.; | 3197 D[0] = 0.; |
3198 for (int i = 0; i < nr - 1; i++) | 3198 for (octave_idx_type i = 0; i < nr - 1; i++) |
3199 { | 3199 { |
3200 D[i+1] = 0.; | 3200 D[i+1] = 0.; |
3201 DL[i] = 0.; | 3201 DL[i] = 0.; |
3202 DU[i] = 0.; | 3202 DU[i] = 0.; |
3203 } | 3203 } |
3204 | 3204 |
3205 for (int j = 0; j < nc; j++) | 3205 for (octave_idx_type j = 0; j < nc; j++) |
3206 for (int i = cidx(j); i < cidx(j+1); i++) | 3206 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
3207 { | 3207 { |
3208 if (ridx(i) == j) | 3208 if (ridx(i) == j) |
3209 D[j] = data(i); | 3209 D[j] = data(i); |
3210 else if (ridx(i) == j + 1) | 3210 else if (ridx(i) == j + 1) |
3211 DL[j] = data(i); | 3211 DL[j] = data(i); |
3234 | 3234 |
3235 } | 3235 } |
3236 else | 3236 else |
3237 { | 3237 { |
3238 char job = 'N'; | 3238 char job = 'N'; |
3239 volatile int x_nz = b.nnz (); | 3239 volatile octave_idx_type x_nz = b.nnz (); |
3240 int b_nc = b.cols (); | 3240 octave_idx_type b_nc = b.cols (); |
3241 retval = SparseMatrix (nr, b_nc, x_nz); | 3241 retval = SparseMatrix (nr, b_nc, x_nz); |
3242 retval.xcidx(0) = 0; | 3242 retval.xcidx(0) = 0; |
3243 volatile int ii = 0; | 3243 volatile octave_idx_type ii = 0; |
3244 | 3244 |
3245 OCTAVE_LOCAL_BUFFER (double, work, nr); | 3245 OCTAVE_LOCAL_BUFFER (double, work, nr); |
3246 | 3246 |
3247 for (volatile int j = 0; j < b_nc; j++) | 3247 for (volatile octave_idx_type j = 0; j < b_nc; j++) |
3248 { | 3248 { |
3249 for (int i = 0; i < nr; i++) | 3249 for (octave_idx_type i = 0; i < nr; i++) |
3250 work[i] = 0.; | 3250 work[i] = 0.; |
3251 for (int i = b.cidx(j); i < b.cidx(j+1); i++) | 3251 for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) |
3252 work[b.ridx(i)] = b.data(i); | 3252 work[b.ridx(i)] = b.data(i); |
3253 | 3253 |
3254 F77_XFCN (dgttrs, DGTTRS, | 3254 F77_XFCN (dgttrs, DGTTRS, |
3255 (F77_CONST_CHAR_ARG2 (&job, 1), | 3255 (F77_CONST_CHAR_ARG2 (&job, 1), |
3256 nr, 1, DL, D, DU, DU2, pipvt, | 3256 nr, 1, DL, D, DU, DU2, pipvt, |
3264 break; | 3264 break; |
3265 } | 3265 } |
3266 | 3266 |
3267 // Count non-zeros in work vector and adjust | 3267 // Count non-zeros in work vector and adjust |
3268 // space in retval if needed | 3268 // space in retval if needed |
3269 int new_nnz = 0; | 3269 octave_idx_type new_nnz = 0; |
3270 for (int i = 0; i < nr; i++) | 3270 for (octave_idx_type i = 0; i < nr; i++) |
3271 if (work[i] != 0.) | 3271 if (work[i] != 0.) |
3272 new_nnz++; | 3272 new_nnz++; |
3273 | 3273 |
3274 if (ii + new_nnz > x_nz) | 3274 if (ii + new_nnz > x_nz) |
3275 { | 3275 { |
3276 // Resize the sparse matrix | 3276 // Resize the sparse matrix |
3277 int sz = new_nnz * (b_nc - j) + x_nz; | 3277 octave_idx_type sz = new_nnz * (b_nc - j) + x_nz; |
3278 retval.change_capacity (sz); | 3278 retval.change_capacity (sz); |
3279 x_nz = sz; | 3279 x_nz = sz; |
3280 } | 3280 } |
3281 | 3281 |
3282 for (int i = 0; i < nr; i++) | 3282 for (octave_idx_type i = 0; i < nr; i++) |
3283 if (work[i] != 0.) | 3283 if (work[i] != 0.) |
3284 { | 3284 { |
3285 retval.xridx(ii) = i; | 3285 retval.xridx(ii) = i; |
3286 retval.xdata(ii++) = work[i]; | 3286 retval.xdata(ii++) = work[i]; |
3287 } | 3287 } |
3298 | 3298 |
3299 return retval; | 3299 return retval; |
3300 } | 3300 } |
3301 | 3301 |
3302 ComplexMatrix | 3302 ComplexMatrix |
3303 SparseMatrix::trisolve (SparseType &mattype, const ComplexMatrix& b, int& err, | 3303 SparseMatrix::trisolve (SparseType &mattype, const ComplexMatrix& b, octave_idx_type& err, |
3304 double& rcond, solve_singularity_handler sing_handler) const | 3304 double& rcond, solve_singularity_handler sing_handler) const |
3305 { | 3305 { |
3306 ComplexMatrix retval; | 3306 ComplexMatrix retval; |
3307 | 3307 |
3308 int nr = rows (); | 3308 octave_idx_type nr = rows (); |
3309 int nc = cols (); | 3309 octave_idx_type nc = cols (); |
3310 err = 0; | 3310 err = 0; |
3311 | 3311 |
3312 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) | 3312 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) |
3313 (*current_liboctave_error_handler) | 3313 (*current_liboctave_error_handler) |
3314 ("matrix dimension mismatch solution of linear equations"); | 3314 ("matrix dimension mismatch solution of linear equations"); |
3324 OCTAVE_LOCAL_BUFFER (Complex, D, nr); | 3324 OCTAVE_LOCAL_BUFFER (Complex, D, nr); |
3325 OCTAVE_LOCAL_BUFFER (Complex, DL, nr - 1); | 3325 OCTAVE_LOCAL_BUFFER (Complex, DL, nr - 1); |
3326 | 3326 |
3327 if (mattype.is_dense ()) | 3327 if (mattype.is_dense ()) |
3328 { | 3328 { |
3329 int ii = 0; | 3329 octave_idx_type ii = 0; |
3330 | 3330 |
3331 for (int j = 0; j < nc-1; j++) | 3331 for (octave_idx_type j = 0; j < nc-1; j++) |
3332 { | 3332 { |
3333 D[j] = data(ii++); | 3333 D[j] = data(ii++); |
3334 DL[j] = data(ii); | 3334 DL[j] = data(ii); |
3335 ii += 2; | 3335 ii += 2; |
3336 } | 3336 } |
3337 D[nc-1] = data(ii); | 3337 D[nc-1] = data(ii); |
3338 } | 3338 } |
3339 else | 3339 else |
3340 { | 3340 { |
3341 D[0] = 0.; | 3341 D[0] = 0.; |
3342 for (int i = 0; i < nr - 1; i++) | 3342 for (octave_idx_type i = 0; i < nr - 1; i++) |
3343 { | 3343 { |
3344 D[i+1] = 0.; | 3344 D[i+1] = 0.; |
3345 DL[i] = 0.; | 3345 DL[i] = 0.; |
3346 } | 3346 } |
3347 | 3347 |
3348 for (int j = 0; j < nc; j++) | 3348 for (octave_idx_type j = 0; j < nc; j++) |
3349 for (int i = cidx(j); i < cidx(j+1); i++) | 3349 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
3350 { | 3350 { |
3351 if (ridx(i) == j) | 3351 if (ridx(i) == j) |
3352 D[j] = data(i); | 3352 D[j] = data(i); |
3353 else if (ridx(i) == j + 1) | 3353 else if (ridx(i) == j + 1) |
3354 DL[j] = data(i); | 3354 DL[j] = data(i); |
3355 } | 3355 } |
3356 } | 3356 } |
3357 | 3357 |
3358 int b_nr = b.rows (); | 3358 octave_idx_type b_nr = b.rows (); |
3359 int b_nc = b.cols(); | 3359 octave_idx_type b_nc = b.cols(); |
3360 rcond = 1.; | 3360 rcond = 1.; |
3361 | 3361 |
3362 retval = b; | 3362 retval = b; |
3363 Complex *result = retval.fortran_vec (); | 3363 Complex *result = retval.fortran_vec (); |
3364 | 3364 |
3385 OCTAVE_LOCAL_BUFFER (Complex, D, nr); | 3385 OCTAVE_LOCAL_BUFFER (Complex, D, nr); |
3386 OCTAVE_LOCAL_BUFFER (Complex, DL, nr - 1); | 3386 OCTAVE_LOCAL_BUFFER (Complex, DL, nr - 1); |
3387 | 3387 |
3388 if (mattype.is_dense ()) | 3388 if (mattype.is_dense ()) |
3389 { | 3389 { |
3390 int ii = 0; | 3390 octave_idx_type ii = 0; |
3391 | 3391 |
3392 for (int j = 0; j < nc-1; j++) | 3392 for (octave_idx_type j = 0; j < nc-1; j++) |
3393 { | 3393 { |
3394 D[j] = data(ii++); | 3394 D[j] = data(ii++); |
3395 DL[j] = data(ii++); | 3395 DL[j] = data(ii++); |
3396 DU[j] = data(ii++); | 3396 DU[j] = data(ii++); |
3397 } | 3397 } |
3398 D[nc-1] = data(ii); | 3398 D[nc-1] = data(ii); |
3399 } | 3399 } |
3400 else | 3400 else |
3401 { | 3401 { |
3402 D[0] = 0.; | 3402 D[0] = 0.; |
3403 for (int i = 0; i < nr - 1; i++) | 3403 for (octave_idx_type i = 0; i < nr - 1; i++) |
3404 { | 3404 { |
3405 D[i+1] = 0.; | 3405 D[i+1] = 0.; |
3406 DL[i] = 0.; | 3406 DL[i] = 0.; |
3407 DU[i] = 0.; | 3407 DU[i] = 0.; |
3408 } | 3408 } |
3409 | 3409 |
3410 for (int j = 0; j < nc; j++) | 3410 for (octave_idx_type j = 0; j < nc; j++) |
3411 for (int i = cidx(j); i < cidx(j+1); i++) | 3411 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
3412 { | 3412 { |
3413 if (ridx(i) == j) | 3413 if (ridx(i) == j) |
3414 D[j] = data(i); | 3414 D[j] = data(i); |
3415 else if (ridx(i) == j + 1) | 3415 else if (ridx(i) == j + 1) |
3416 DL[j] = data(i); | 3416 DL[j] = data(i); |
3417 else if (ridx(i) == j - 1) | 3417 else if (ridx(i) == j - 1) |
3418 DU[j] = data(i); | 3418 DU[j] = data(i); |
3419 } | 3419 } |
3420 } | 3420 } |
3421 | 3421 |
3422 int b_nr = b.rows(); | 3422 octave_idx_type b_nr = b.rows(); |
3423 int b_nc = b.cols(); | 3423 octave_idx_type b_nc = b.cols(); |
3424 rcond = 1.; | 3424 rcond = 1.; |
3425 | 3425 |
3426 retval = b; | 3426 retval = b; |
3427 Complex *result = retval.fortran_vec (); | 3427 Complex *result = retval.fortran_vec (); |
3428 | 3428 |
3454 return retval; | 3454 return retval; |
3455 } | 3455 } |
3456 | 3456 |
3457 SparseComplexMatrix | 3457 SparseComplexMatrix |
3458 SparseMatrix::trisolve (SparseType &mattype, const SparseComplexMatrix& b, | 3458 SparseMatrix::trisolve (SparseType &mattype, const SparseComplexMatrix& b, |
3459 int& err, double& rcond, | 3459 octave_idx_type& err, double& rcond, |
3460 solve_singularity_handler sing_handler) const | 3460 solve_singularity_handler sing_handler) const |
3461 { | 3461 { |
3462 SparseComplexMatrix retval; | 3462 SparseComplexMatrix retval; |
3463 | 3463 |
3464 int nr = rows (); | 3464 octave_idx_type nr = rows (); |
3465 int nc = cols (); | 3465 octave_idx_type nc = cols (); |
3466 err = 0; | 3466 err = 0; |
3467 | 3467 |
3468 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) | 3468 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) |
3469 (*current_liboctave_error_handler) | 3469 (*current_liboctave_error_handler) |
3470 ("matrix dimension mismatch solution of linear equations"); | 3470 ("matrix dimension mismatch solution of linear equations"); |
3480 { | 3480 { |
3481 OCTAVE_LOCAL_BUFFER (double, DU2, nr - 2); | 3481 OCTAVE_LOCAL_BUFFER (double, DU2, nr - 2); |
3482 OCTAVE_LOCAL_BUFFER (double, DU, nr - 1); | 3482 OCTAVE_LOCAL_BUFFER (double, DU, nr - 1); |
3483 OCTAVE_LOCAL_BUFFER (double, D, nr); | 3483 OCTAVE_LOCAL_BUFFER (double, D, nr); |
3484 OCTAVE_LOCAL_BUFFER (double, DL, nr - 1); | 3484 OCTAVE_LOCAL_BUFFER (double, DL, nr - 1); |
3485 Array<int> ipvt (nr); | 3485 Array<octave_idx_type> ipvt (nr); |
3486 int *pipvt = ipvt.fortran_vec (); | 3486 octave_idx_type *pipvt = ipvt.fortran_vec (); |
3487 | 3487 |
3488 if (mattype.is_dense ()) | 3488 if (mattype.is_dense ()) |
3489 { | 3489 { |
3490 int ii = 0; | 3490 octave_idx_type ii = 0; |
3491 | 3491 |
3492 for (int j = 0; j < nc-1; j++) | 3492 for (octave_idx_type j = 0; j < nc-1; j++) |
3493 { | 3493 { |
3494 D[j] = data(ii++); | 3494 D[j] = data(ii++); |
3495 DL[j] = data(ii++); | 3495 DL[j] = data(ii++); |
3496 DU[j] = data(ii++); | 3496 DU[j] = data(ii++); |
3497 } | 3497 } |
3498 D[nc-1] = data(ii); | 3498 D[nc-1] = data(ii); |
3499 } | 3499 } |
3500 else | 3500 else |
3501 { | 3501 { |
3502 D[0] = 0.; | 3502 D[0] = 0.; |
3503 for (int i = 0; i < nr - 1; i++) | 3503 for (octave_idx_type i = 0; i < nr - 1; i++) |
3504 { | 3504 { |
3505 D[i+1] = 0.; | 3505 D[i+1] = 0.; |
3506 DL[i] = 0.; | 3506 DL[i] = 0.; |
3507 DU[i] = 0.; | 3507 DU[i] = 0.; |
3508 } | 3508 } |
3509 | 3509 |
3510 for (int j = 0; j < nc; j++) | 3510 for (octave_idx_type j = 0; j < nc; j++) |
3511 for (int i = cidx(j); i < cidx(j+1); i++) | 3511 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
3512 { | 3512 { |
3513 if (ridx(i) == j) | 3513 if (ridx(i) == j) |
3514 D[j] = data(i); | 3514 D[j] = data(i); |
3515 else if (ridx(i) == j + 1) | 3515 else if (ridx(i) == j + 1) |
3516 DL[j] = data(i); | 3516 DL[j] = data(i); |
3539 } | 3539 } |
3540 else | 3540 else |
3541 { | 3541 { |
3542 rcond = 1.; | 3542 rcond = 1.; |
3543 char job = 'N'; | 3543 char job = 'N'; |
3544 int b_nr = b.rows (); | 3544 octave_idx_type b_nr = b.rows (); |
3545 int b_nc = b.cols (); | 3545 octave_idx_type b_nc = b.cols (); |
3546 OCTAVE_LOCAL_BUFFER (double, Bx, b_nr); | 3546 OCTAVE_LOCAL_BUFFER (double, Bx, b_nr); |
3547 OCTAVE_LOCAL_BUFFER (double, Bz, b_nr); | 3547 OCTAVE_LOCAL_BUFFER (double, Bz, b_nr); |
3548 | 3548 |
3549 // Take a first guess that the number of non-zero terms | 3549 // Take a first guess that the number of non-zero terms |
3550 // will be as many as in b | 3550 // will be as many as in b |
3551 volatile int x_nz = b.nnz (); | 3551 volatile octave_idx_type x_nz = b.nnz (); |
3552 volatile int ii = 0; | 3552 volatile octave_idx_type ii = 0; |
3553 retval = SparseComplexMatrix (b_nr, b_nc, x_nz); | 3553 retval = SparseComplexMatrix (b_nr, b_nc, x_nz); |
3554 | 3554 |
3555 retval.xcidx(0) = 0; | 3555 retval.xcidx(0) = 0; |
3556 for (volatile int j = 0; j < b_nc; j++) | 3556 for (volatile octave_idx_type j = 0; j < b_nc; j++) |
3557 { | 3557 { |
3558 | 3558 |
3559 for (int i = 0; i < b_nr; i++) | 3559 for (octave_idx_type i = 0; i < b_nr; i++) |
3560 { | 3560 { |
3561 Complex c = b (i,j); | 3561 Complex c = b (i,j); |
3562 Bx[i] = std::real (c); | 3562 Bx[i] = std::real (c); |
3563 Bz[i] = std::imag (c); | 3563 Bz[i] = std::imag (c); |
3564 } | 3564 } |
3608 break; | 3608 break; |
3609 } | 3609 } |
3610 | 3610 |
3611 // Count non-zeros in work vector and adjust | 3611 // Count non-zeros in work vector and adjust |
3612 // space in retval if needed | 3612 // space in retval if needed |
3613 int new_nnz = 0; | 3613 octave_idx_type new_nnz = 0; |
3614 for (int i = 0; i < nr; i++) | 3614 for (octave_idx_type i = 0; i < nr; i++) |
3615 if (Bx[i] != 0. || Bz[i] != 0.) | 3615 if (Bx[i] != 0. || Bz[i] != 0.) |
3616 new_nnz++; | 3616 new_nnz++; |
3617 | 3617 |
3618 if (ii + new_nnz > x_nz) | 3618 if (ii + new_nnz > x_nz) |
3619 { | 3619 { |
3620 // Resize the sparse matrix | 3620 // Resize the sparse matrix |
3621 int sz = new_nnz * (b_nc - j) + x_nz; | 3621 octave_idx_type sz = new_nnz * (b_nc - j) + x_nz; |
3622 retval.change_capacity (sz); | 3622 retval.change_capacity (sz); |
3623 x_nz = sz; | 3623 x_nz = sz; |
3624 } | 3624 } |
3625 | 3625 |
3626 for (int i = 0; i < nr; i++) | 3626 for (octave_idx_type i = 0; i < nr; i++) |
3627 if (Bx[i] != 0. || Bz[i] != 0.) | 3627 if (Bx[i] != 0. || Bz[i] != 0.) |
3628 { | 3628 { |
3629 retval.xridx(ii) = i; | 3629 retval.xridx(ii) = i; |
3630 retval.xdata(ii++) = | 3630 retval.xdata(ii++) = |
3631 Complex (Bx[i], Bz[i]); | 3631 Complex (Bx[i], Bz[i]); |
3644 | 3644 |
3645 return retval; | 3645 return retval; |
3646 } | 3646 } |
3647 | 3647 |
3648 Matrix | 3648 Matrix |
3649 SparseMatrix::bsolve (SparseType &mattype, const Matrix& b, int& err, | 3649 SparseMatrix::bsolve (SparseType &mattype, const Matrix& b, octave_idx_type& err, |
3650 double& rcond, | 3650 double& rcond, |
3651 solve_singularity_handler sing_handler) const | 3651 solve_singularity_handler sing_handler) const |
3652 { | 3652 { |
3653 Matrix retval; | 3653 Matrix retval; |
3654 | 3654 |
3655 int nr = rows (); | 3655 octave_idx_type nr = rows (); |
3656 int nc = cols (); | 3656 octave_idx_type nc = cols (); |
3657 err = 0; | 3657 err = 0; |
3658 | 3658 |
3659 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) | 3659 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) |
3660 (*current_liboctave_error_handler) | 3660 (*current_liboctave_error_handler) |
3661 ("matrix dimension mismatch solution of linear equations"); | 3661 ("matrix dimension mismatch solution of linear equations"); |
3665 volatile int typ = mattype.type (); | 3665 volatile int typ = mattype.type (); |
3666 mattype.info (); | 3666 mattype.info (); |
3667 | 3667 |
3668 if (typ == SparseType::Banded_Hermitian) | 3668 if (typ == SparseType::Banded_Hermitian) |
3669 { | 3669 { |
3670 int n_lower = mattype.nlower (); | 3670 octave_idx_type n_lower = mattype.nlower (); |
3671 int ldm = n_lower + 1; | 3671 octave_idx_type ldm = n_lower + 1; |
3672 Matrix m_band (ldm, nc); | 3672 Matrix m_band (ldm, nc); |
3673 double *tmp_data = m_band.fortran_vec (); | 3673 double *tmp_data = m_band.fortran_vec (); |
3674 | 3674 |
3675 if (! mattype.is_dense ()) | 3675 if (! mattype.is_dense ()) |
3676 { | 3676 { |
3677 int ii = 0; | 3677 octave_idx_type ii = 0; |
3678 | 3678 |
3679 for (int j = 0; j < ldm; j++) | 3679 for (octave_idx_type j = 0; j < ldm; j++) |
3680 for (int i = 0; i < nc; i++) | 3680 for (octave_idx_type i = 0; i < nc; i++) |
3681 tmp_data[ii++] = 0.; | 3681 tmp_data[ii++] = 0.; |
3682 } | 3682 } |
3683 | 3683 |
3684 for (int j = 0; j < nc; j++) | 3684 for (octave_idx_type j = 0; j < nc; j++) |
3685 for (int i = cidx(j); i < cidx(j+1); i++) | 3685 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
3686 { | 3686 { |
3687 int ri = ridx (i); | 3687 octave_idx_type ri = ridx (i); |
3688 if (ri >= j) | 3688 if (ri >= j) |
3689 m_band(ri - j, j) = data(i); | 3689 m_band(ri - j, j) = data(i); |
3690 } | 3690 } |
3691 | 3691 |
3692 // Calculate the norm of the matrix, for later use. | 3692 // Calculate the norm of the matrix, for later use. |
3756 | 3756 |
3757 rcond = 1.; | 3757 rcond = 1.; |
3758 retval = b; | 3758 retval = b; |
3759 double *result = retval.fortran_vec (); | 3759 double *result = retval.fortran_vec (); |
3760 | 3760 |
3761 int b_nc = b.cols (); | 3761 octave_idx_type b_nc = b.cols (); |
3762 | 3762 |
3763 F77_XFCN (dpbtrs, DPBTRS, | 3763 F77_XFCN (dpbtrs, DPBTRS, |
3764 (F77_CONST_CHAR_ARG2 (&job, 1), | 3764 (F77_CONST_CHAR_ARG2 (&job, 1), |
3765 nr, n_lower, b_nc, tmp_data, | 3765 nr, n_lower, b_nc, tmp_data, |
3766 ldm, result, b.rows(), err | 3766 ldm, result, b.rows(), err |
3790 Matrix m_band (ldm, nc); | 3790 Matrix m_band (ldm, nc); |
3791 double *tmp_data = m_band.fortran_vec (); | 3791 double *tmp_data = m_band.fortran_vec (); |
3792 | 3792 |
3793 if (! mattype.is_dense ()) | 3793 if (! mattype.is_dense ()) |
3794 { | 3794 { |
3795 int ii = 0; | 3795 octave_idx_type ii = 0; |
3796 | 3796 |
3797 for (int j = 0; j < ldm; j++) | 3797 for (octave_idx_type j = 0; j < ldm; j++) |
3798 for (int i = 0; i < nc; i++) | 3798 for (octave_idx_type i = 0; i < nc; i++) |
3799 tmp_data[ii++] = 0.; | 3799 tmp_data[ii++] = 0.; |
3800 } | 3800 } |
3801 | 3801 |
3802 for (int j = 0; j < nc; j++) | 3802 for (octave_idx_type j = 0; j < nc; j++) |
3803 for (int i = cidx(j); i < cidx(j+1); i++) | 3803 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
3804 m_band(ridx(i) - j + n_lower + n_upper, j) = data(i); | 3804 m_band(ridx(i) - j + n_lower + n_upper, j) = data(i); |
3805 | 3805 |
3806 Array<int> ipvt (nr); | 3806 Array<octave_idx_type> ipvt (nr); |
3807 int *pipvt = ipvt.fortran_vec (); | 3807 octave_idx_type *pipvt = ipvt.fortran_vec (); |
3808 | 3808 |
3809 F77_XFCN (dgbtrf, DGBTRF, (nr, nr, n_lower, n_upper, tmp_data, | 3809 F77_XFCN (dgbtrf, DGBTRF, (nr, nr, n_lower, n_upper, tmp_data, |
3810 ldm, pipvt, err)); | 3810 ldm, pipvt, err)); |
3811 | 3811 |
3812 if (f77_exception_encountered) | 3812 if (f77_exception_encountered) |
3869 | 3869 |
3870 rcond = 1.; | 3870 rcond = 1.; |
3871 retval = b; | 3871 retval = b; |
3872 double *result = retval.fortran_vec (); | 3872 double *result = retval.fortran_vec (); |
3873 | 3873 |
3874 int b_nc = b.cols (); | 3874 octave_idx_type b_nc = b.cols (); |
3875 | 3875 |
3876 job = 'N'; | 3876 job = 'N'; |
3877 F77_XFCN (dgbtrs, DGBTRS, | 3877 F77_XFCN (dgbtrs, DGBTRS, |
3878 (F77_CONST_CHAR_ARG2 (&job, 1), | 3878 (F77_CONST_CHAR_ARG2 (&job, 1), |
3879 nr, n_lower, n_upper, b_nc, tmp_data, | 3879 nr, n_lower, n_upper, b_nc, tmp_data, |
3892 | 3892 |
3893 return retval; | 3893 return retval; |
3894 } | 3894 } |
3895 | 3895 |
3896 SparseMatrix | 3896 SparseMatrix |
3897 SparseMatrix::bsolve (SparseType &mattype, const SparseMatrix& b, int& err, | 3897 SparseMatrix::bsolve (SparseType &mattype, const SparseMatrix& b, octave_idx_type& err, |
3898 double& rcond, solve_singularity_handler sing_handler) const | 3898 double& rcond, solve_singularity_handler sing_handler) const |
3899 { | 3899 { |
3900 SparseMatrix retval; | 3900 SparseMatrix retval; |
3901 | 3901 |
3902 int nr = rows (); | 3902 octave_idx_type nr = rows (); |
3903 int nc = cols (); | 3903 octave_idx_type nc = cols (); |
3904 err = 0; | 3904 err = 0; |
3905 | 3905 |
3906 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) | 3906 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) |
3907 (*current_liboctave_error_handler) | 3907 (*current_liboctave_error_handler) |
3908 ("matrix dimension mismatch solution of linear equations"); | 3908 ("matrix dimension mismatch solution of linear equations"); |
3920 Matrix m_band (ldm, nc); | 3920 Matrix m_band (ldm, nc); |
3921 double *tmp_data = m_band.fortran_vec (); | 3921 double *tmp_data = m_band.fortran_vec (); |
3922 | 3922 |
3923 if (! mattype.is_dense ()) | 3923 if (! mattype.is_dense ()) |
3924 { | 3924 { |
3925 int ii = 0; | 3925 octave_idx_type ii = 0; |
3926 | 3926 |
3927 for (int j = 0; j < ldm; j++) | 3927 for (octave_idx_type j = 0; j < ldm; j++) |
3928 for (int i = 0; i < nc; i++) | 3928 for (octave_idx_type i = 0; i < nc; i++) |
3929 tmp_data[ii++] = 0.; | 3929 tmp_data[ii++] = 0.; |
3930 } | 3930 } |
3931 | 3931 |
3932 for (int j = 0; j < nc; j++) | 3932 for (octave_idx_type j = 0; j < nc; j++) |
3933 for (int i = cidx(j); i < cidx(j+1); i++) | 3933 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
3934 { | 3934 { |
3935 int ri = ridx (i); | 3935 octave_idx_type ri = ridx (i); |
3936 if (ri >= j) | 3936 if (ri >= j) |
3937 m_band(ri - j, j) = data(i); | 3937 m_band(ri - j, j) = data(i); |
3938 } | 3938 } |
3939 | 3939 |
3940 char job = 'L'; | 3940 char job = 'L'; |
3955 err = 0; | 3955 err = 0; |
3956 } | 3956 } |
3957 else | 3957 else |
3958 { | 3958 { |
3959 rcond = 1.; | 3959 rcond = 1.; |
3960 int b_nr = b.rows (); | 3960 octave_idx_type b_nr = b.rows (); |
3961 int b_nc = b.cols (); | 3961 octave_idx_type b_nc = b.cols (); |
3962 OCTAVE_LOCAL_BUFFER (double, Bx, b_nr); | 3962 OCTAVE_LOCAL_BUFFER (double, Bx, b_nr); |
3963 | 3963 |
3964 // Take a first guess that the number of non-zero terms | 3964 // Take a first guess that the number of non-zero terms |
3965 // will be as many as in b | 3965 // will be as many as in b |
3966 volatile int x_nz = b.nnz (); | 3966 volatile octave_idx_type x_nz = b.nnz (); |
3967 volatile int ii = 0; | 3967 volatile octave_idx_type ii = 0; |
3968 retval = SparseMatrix (b_nr, b_nc, x_nz); | 3968 retval = SparseMatrix (b_nr, b_nc, x_nz); |
3969 | 3969 |
3970 retval.xcidx(0) = 0; | 3970 retval.xcidx(0) = 0; |
3971 for (volatile int j = 0; j < b_nc; j++) | 3971 for (volatile octave_idx_type j = 0; j < b_nc; j++) |
3972 { | 3972 { |
3973 for (int i = 0; i < b_nr; i++) | 3973 for (octave_idx_type i = 0; i < b_nr; i++) |
3974 Bx[i] = b.elem (i, j); | 3974 Bx[i] = b.elem (i, j); |
3975 | 3975 |
3976 F77_XFCN (dpbtrs, DPBTRS, | 3976 F77_XFCN (dpbtrs, DPBTRS, |
3977 (F77_CONST_CHAR_ARG2 (&job, 1), | 3977 (F77_CONST_CHAR_ARG2 (&job, 1), |
3978 nr, n_lower, 1, tmp_data, | 3978 nr, n_lower, 1, tmp_data, |
3993 ("SparseMatrix::solve solve failed"); | 3993 ("SparseMatrix::solve solve failed"); |
3994 err = -1; | 3994 err = -1; |
3995 break; | 3995 break; |
3996 } | 3996 } |
3997 | 3997 |
3998 for (int i = 0; i < b_nr; i++) | 3998 for (octave_idx_type i = 0; i < b_nr; i++) |
3999 { | 3999 { |
4000 double tmp = Bx[i]; | 4000 double tmp = Bx[i]; |
4001 if (tmp != 0.0) | 4001 if (tmp != 0.0) |
4002 { | 4002 { |
4003 if (ii == x_nz) | 4003 if (ii == x_nz) |
4004 { | 4004 { |
4005 // Resize the sparse matrix | 4005 // Resize the sparse matrix |
4006 int sz = x_nz * (b_nc - j) / b_nc; | 4006 octave_idx_type sz = x_nz * (b_nc - j) / b_nc; |
4007 sz = (sz > 10 ? sz : 10) + x_nz; | 4007 sz = (sz > 10 ? sz : 10) + x_nz; |
4008 retval.change_capacity (sz); | 4008 retval.change_capacity (sz); |
4009 x_nz = sz; | 4009 x_nz = sz; |
4010 } | 4010 } |
4011 retval.xdata(ii) = tmp; | 4011 retval.xdata(ii) = tmp; |
4021 } | 4021 } |
4022 | 4022 |
4023 if (typ == SparseType::Banded) | 4023 if (typ == SparseType::Banded) |
4024 { | 4024 { |
4025 // Create the storage for the banded form of the sparse matrix | 4025 // Create the storage for the banded form of the sparse matrix |
4026 int n_upper = mattype.nupper (); | 4026 octave_idx_type n_upper = mattype.nupper (); |
4027 int n_lower = mattype.nlower (); | 4027 octave_idx_type n_lower = mattype.nlower (); |
4028 int ldm = n_upper + 2 * n_lower + 1; | 4028 octave_idx_type ldm = n_upper + 2 * n_lower + 1; |
4029 | 4029 |
4030 Matrix m_band (ldm, nc); | 4030 Matrix m_band (ldm, nc); |
4031 double *tmp_data = m_band.fortran_vec (); | 4031 double *tmp_data = m_band.fortran_vec (); |
4032 | 4032 |
4033 if (! mattype.is_dense ()) | 4033 if (! mattype.is_dense ()) |
4034 { | 4034 { |
4035 int ii = 0; | 4035 octave_idx_type ii = 0; |
4036 | 4036 |
4037 for (int j = 0; j < ldm; j++) | 4037 for (octave_idx_type j = 0; j < ldm; j++) |
4038 for (int i = 0; i < nc; i++) | 4038 for (octave_idx_type i = 0; i < nc; i++) |
4039 tmp_data[ii++] = 0.; | 4039 tmp_data[ii++] = 0.; |
4040 } | 4040 } |
4041 | 4041 |
4042 for (int j = 0; j < nc; j++) | 4042 for (octave_idx_type j = 0; j < nc; j++) |
4043 for (int i = cidx(j); i < cidx(j+1); i++) | 4043 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
4044 m_band(ridx(i) - j + n_lower + n_upper, j) = data(i); | 4044 m_band(ridx(i) - j + n_lower + n_upper, j) = data(i); |
4045 | 4045 |
4046 Array<int> ipvt (nr); | 4046 Array<octave_idx_type> ipvt (nr); |
4047 int *pipvt = ipvt.fortran_vec (); | 4047 octave_idx_type *pipvt = ipvt.fortran_vec (); |
4048 | 4048 |
4049 F77_XFCN (dgbtrf, DGBTRF, (nr, nr, n_lower, n_upper, tmp_data, | 4049 F77_XFCN (dgbtrf, DGBTRF, (nr, nr, n_lower, n_upper, tmp_data, |
4050 ldm, pipvt, err)); | 4050 ldm, pipvt, err)); |
4051 | 4051 |
4052 if (f77_exception_encountered) | 4052 if (f77_exception_encountered) |
4067 | 4067 |
4068 } | 4068 } |
4069 else | 4069 else |
4070 { | 4070 { |
4071 char job = 'N'; | 4071 char job = 'N'; |
4072 volatile int x_nz = b.nnz (); | 4072 volatile octave_idx_type x_nz = b.nnz (); |
4073 int b_nc = b.cols (); | 4073 octave_idx_type b_nc = b.cols (); |
4074 retval = SparseMatrix (nr, b_nc, x_nz); | 4074 retval = SparseMatrix (nr, b_nc, x_nz); |
4075 retval.xcidx(0) = 0; | 4075 retval.xcidx(0) = 0; |
4076 volatile int ii = 0; | 4076 volatile octave_idx_type ii = 0; |
4077 | 4077 |
4078 OCTAVE_LOCAL_BUFFER (double, work, nr); | 4078 OCTAVE_LOCAL_BUFFER (double, work, nr); |
4079 | 4079 |
4080 for (volatile int j = 0; j < b_nc; j++) | 4080 for (volatile octave_idx_type j = 0; j < b_nc; j++) |
4081 { | 4081 { |
4082 for (int i = 0; i < nr; i++) | 4082 for (octave_idx_type i = 0; i < nr; i++) |
4083 work[i] = 0.; | 4083 work[i] = 0.; |
4084 for (int i = b.cidx(j); i < b.cidx(j+1); i++) | 4084 for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) |
4085 work[b.ridx(i)] = b.data(i); | 4085 work[b.ridx(i)] = b.data(i); |
4086 | 4086 |
4087 F77_XFCN (dgbtrs, DGBTRS, | 4087 F77_XFCN (dgbtrs, DGBTRS, |
4088 (F77_CONST_CHAR_ARG2 (&job, 1), | 4088 (F77_CONST_CHAR_ARG2 (&job, 1), |
4089 nr, n_lower, n_upper, 1, tmp_data, | 4089 nr, n_lower, n_upper, 1, tmp_data, |
4097 break; | 4097 break; |
4098 } | 4098 } |
4099 | 4099 |
4100 // Count non-zeros in work vector and adjust | 4100 // Count non-zeros in work vector and adjust |
4101 // space in retval if needed | 4101 // space in retval if needed |
4102 int new_nnz = 0; | 4102 octave_idx_type new_nnz = 0; |
4103 for (int i = 0; i < nr; i++) | 4103 for (octave_idx_type i = 0; i < nr; i++) |
4104 if (work[i] != 0.) | 4104 if (work[i] != 0.) |
4105 new_nnz++; | 4105 new_nnz++; |
4106 | 4106 |
4107 if (ii + new_nnz > x_nz) | 4107 if (ii + new_nnz > x_nz) |
4108 { | 4108 { |
4109 // Resize the sparse matrix | 4109 // Resize the sparse matrix |
4110 int sz = new_nnz * (b_nc - j) + x_nz; | 4110 octave_idx_type sz = new_nnz * (b_nc - j) + x_nz; |
4111 retval.change_capacity (sz); | 4111 retval.change_capacity (sz); |
4112 x_nz = sz; | 4112 x_nz = sz; |
4113 } | 4113 } |
4114 | 4114 |
4115 for (int i = 0; i < nr; i++) | 4115 for (octave_idx_type i = 0; i < nr; i++) |
4116 if (work[i] != 0.) | 4116 if (work[i] != 0.) |
4117 { | 4117 { |
4118 retval.xridx(ii) = i; | 4118 retval.xridx(ii) = i; |
4119 retval.xdata(ii++) = work[i]; | 4119 retval.xdata(ii++) = work[i]; |
4120 } | 4120 } |
4131 | 4131 |
4132 return retval; | 4132 return retval; |
4133 } | 4133 } |
4134 | 4134 |
4135 ComplexMatrix | 4135 ComplexMatrix |
4136 SparseMatrix::bsolve (SparseType &mattype, const ComplexMatrix& b, int& err, | 4136 SparseMatrix::bsolve (SparseType &mattype, const ComplexMatrix& b, octave_idx_type& err, |
4137 double& rcond, solve_singularity_handler sing_handler) const | 4137 double& rcond, solve_singularity_handler sing_handler) const |
4138 { | 4138 { |
4139 ComplexMatrix retval; | 4139 ComplexMatrix retval; |
4140 | 4140 |
4141 int nr = rows (); | 4141 octave_idx_type nr = rows (); |
4142 int nc = cols (); | 4142 octave_idx_type nc = cols (); |
4143 err = 0; | 4143 err = 0; |
4144 | 4144 |
4145 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) | 4145 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) |
4146 (*current_liboctave_error_handler) | 4146 (*current_liboctave_error_handler) |
4147 ("matrix dimension mismatch solution of linear equations"); | 4147 ("matrix dimension mismatch solution of linear equations"); |
4151 volatile int typ = mattype.type (); | 4151 volatile int typ = mattype.type (); |
4152 mattype.info (); | 4152 mattype.info (); |
4153 | 4153 |
4154 if (typ == SparseType::Banded_Hermitian) | 4154 if (typ == SparseType::Banded_Hermitian) |
4155 { | 4155 { |
4156 int n_lower = mattype.nlower (); | 4156 octave_idx_type n_lower = mattype.nlower (); |
4157 int ldm = n_lower + 1; | 4157 octave_idx_type ldm = n_lower + 1; |
4158 | 4158 |
4159 Matrix m_band (ldm, nc); | 4159 Matrix m_band (ldm, nc); |
4160 double *tmp_data = m_band.fortran_vec (); | 4160 double *tmp_data = m_band.fortran_vec (); |
4161 | 4161 |
4162 if (! mattype.is_dense ()) | 4162 if (! mattype.is_dense ()) |
4163 { | 4163 { |
4164 int ii = 0; | 4164 octave_idx_type ii = 0; |
4165 | 4165 |
4166 for (int j = 0; j < ldm; j++) | 4166 for (octave_idx_type j = 0; j < ldm; j++) |
4167 for (int i = 0; i < nc; i++) | 4167 for (octave_idx_type i = 0; i < nc; i++) |
4168 tmp_data[ii++] = 0.; | 4168 tmp_data[ii++] = 0.; |
4169 } | 4169 } |
4170 | 4170 |
4171 for (int j = 0; j < nc; j++) | 4171 for (octave_idx_type j = 0; j < nc; j++) |
4172 for (int i = cidx(j); i < cidx(j+1); i++) | 4172 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
4173 { | 4173 { |
4174 int ri = ridx (i); | 4174 octave_idx_type ri = ridx (i); |
4175 if (ri >= j) | 4175 if (ri >= j) |
4176 m_band(ri - j, j) = data(i); | 4176 m_band(ri - j, j) = data(i); |
4177 } | 4177 } |
4178 | 4178 |
4179 char job = 'L'; | 4179 char job = 'L'; |
4196 err = 0; | 4196 err = 0; |
4197 } | 4197 } |
4198 else | 4198 else |
4199 { | 4199 { |
4200 rcond = 1.; | 4200 rcond = 1.; |
4201 int b_nr = b.rows (); | 4201 octave_idx_type b_nr = b.rows (); |
4202 int b_nc = b.cols (); | 4202 octave_idx_type b_nc = b.cols (); |
4203 | 4203 |
4204 OCTAVE_LOCAL_BUFFER (double, Bx, b_nr); | 4204 OCTAVE_LOCAL_BUFFER (double, Bx, b_nr); |
4205 OCTAVE_LOCAL_BUFFER (double, Bz, b_nr); | 4205 OCTAVE_LOCAL_BUFFER (double, Bz, b_nr); |
4206 | 4206 |
4207 retval.resize (b_nr, b_nc); | 4207 retval.resize (b_nr, b_nc); |
4208 | 4208 |
4209 for (volatile int j = 0; j < b_nc; j++) | 4209 for (volatile octave_idx_type j = 0; j < b_nc; j++) |
4210 { | 4210 { |
4211 for (int i = 0; i < b_nr; i++) | 4211 for (octave_idx_type i = 0; i < b_nr; i++) |
4212 { | 4212 { |
4213 Complex c = b (i,j); | 4213 Complex c = b (i,j); |
4214 Bx[i] = std::real (c); | 4214 Bx[i] = std::real (c); |
4215 Bz[i] = std::imag (c); | 4215 Bz[i] = std::imag (c); |
4216 } | 4216 } |
4257 ("SparseMatrix::solve solve failed"); | 4257 ("SparseMatrix::solve solve failed"); |
4258 err = -1; | 4258 err = -1; |
4259 break; | 4259 break; |
4260 } | 4260 } |
4261 | 4261 |
4262 for (int i = 0; i < b_nr; i++) | 4262 for (octave_idx_type i = 0; i < b_nr; i++) |
4263 retval (i, j) = Complex (Bx[i], Bz[i]); | 4263 retval (i, j) = Complex (Bx[i], Bz[i]); |
4264 } | 4264 } |
4265 } | 4265 } |
4266 } | 4266 } |
4267 } | 4267 } |
4276 Matrix m_band (ldm, nc); | 4276 Matrix m_band (ldm, nc); |
4277 double *tmp_data = m_band.fortran_vec (); | 4277 double *tmp_data = m_band.fortran_vec (); |
4278 | 4278 |
4279 if (! mattype.is_dense ()) | 4279 if (! mattype.is_dense ()) |
4280 { | 4280 { |
4281 int ii = 0; | 4281 octave_idx_type ii = 0; |
4282 | 4282 |
4283 for (int j = 0; j < ldm; j++) | 4283 for (octave_idx_type j = 0; j < ldm; j++) |
4284 for (int i = 0; i < nc; i++) | 4284 for (octave_idx_type i = 0; i < nc; i++) |
4285 tmp_data[ii++] = 0.; | 4285 tmp_data[ii++] = 0.; |
4286 } | 4286 } |
4287 | 4287 |
4288 for (int j = 0; j < nc; j++) | 4288 for (octave_idx_type j = 0; j < nc; j++) |
4289 for (int i = cidx(j); i < cidx(j+1); i++) | 4289 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
4290 m_band(ridx(i) - j + n_lower + n_upper, j) = data(i); | 4290 m_band(ridx(i) - j + n_lower + n_upper, j) = data(i); |
4291 | 4291 |
4292 Array<int> ipvt (nr); | 4292 Array<octave_idx_type> ipvt (nr); |
4293 int *pipvt = ipvt.fortran_vec (); | 4293 octave_idx_type *pipvt = ipvt.fortran_vec (); |
4294 | 4294 |
4295 F77_XFCN (dgbtrf, DGBTRF, (nr, nr, n_lower, n_upper, tmp_data, | 4295 F77_XFCN (dgbtrf, DGBTRF, (nr, nr, n_lower, n_upper, tmp_data, |
4296 ldm, pipvt, err)); | 4296 ldm, pipvt, err)); |
4297 | 4297 |
4298 if (f77_exception_encountered) | 4298 if (f77_exception_encountered) |
4313 | 4313 |
4314 } | 4314 } |
4315 else | 4315 else |
4316 { | 4316 { |
4317 char job = 'N'; | 4317 char job = 'N'; |
4318 int b_nc = b.cols (); | 4318 octave_idx_type b_nc = b.cols (); |
4319 retval.resize (nr,b_nc); | 4319 retval.resize (nr,b_nc); |
4320 | 4320 |
4321 OCTAVE_LOCAL_BUFFER (double, Bz, nr); | 4321 OCTAVE_LOCAL_BUFFER (double, Bz, nr); |
4322 OCTAVE_LOCAL_BUFFER (double, Bx, nr); | 4322 OCTAVE_LOCAL_BUFFER (double, Bx, nr); |
4323 | 4323 |
4324 for (volatile int j = 0; j < b_nc; j++) | 4324 for (volatile octave_idx_type j = 0; j < b_nc; j++) |
4325 { | 4325 { |
4326 for (int i = 0; i < nr; i++) | 4326 for (octave_idx_type i = 0; i < nr; i++) |
4327 { | 4327 { |
4328 Complex c = b (i, j); | 4328 Complex c = b (i, j); |
4329 Bx[i] = std::real (c); | 4329 Bx[i] = std::real (c); |
4330 Bz[i] = std::imag (c); | 4330 Bz[i] = std::imag (c); |
4331 } | 4331 } |
4354 (*current_liboctave_error_handler) | 4354 (*current_liboctave_error_handler) |
4355 ("unrecoverable error in dgbtrs"); | 4355 ("unrecoverable error in dgbtrs"); |
4356 break; | 4356 break; |
4357 } | 4357 } |
4358 | 4358 |
4359 for (int i = 0; i < nr; i++) | 4359 for (octave_idx_type i = 0; i < nr; i++) |
4360 retval (i, j) = Complex (Bx[i], Bz[i]); | 4360 retval (i, j) = Complex (Bx[i], Bz[i]); |
4361 } | 4361 } |
4362 } | 4362 } |
4363 } | 4363 } |
4364 } | 4364 } |
4369 return retval; | 4369 return retval; |
4370 } | 4370 } |
4371 | 4371 |
4372 SparseComplexMatrix | 4372 SparseComplexMatrix |
4373 SparseMatrix::bsolve (SparseType &mattype, const SparseComplexMatrix& b, | 4373 SparseMatrix::bsolve (SparseType &mattype, const SparseComplexMatrix& b, |
4374 int& err, double& rcond, | 4374 octave_idx_type& err, double& rcond, |
4375 solve_singularity_handler sing_handler) const | 4375 solve_singularity_handler sing_handler) const |
4376 { | 4376 { |
4377 SparseComplexMatrix retval; | 4377 SparseComplexMatrix retval; |
4378 | 4378 |
4379 int nr = rows (); | 4379 octave_idx_type nr = rows (); |
4380 int nc = cols (); | 4380 octave_idx_type nc = cols (); |
4381 err = 0; | 4381 err = 0; |
4382 | 4382 |
4383 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) | 4383 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) |
4384 (*current_liboctave_error_handler) | 4384 (*current_liboctave_error_handler) |
4385 ("matrix dimension mismatch solution of linear equations"); | 4385 ("matrix dimension mismatch solution of linear equations"); |
4397 Matrix m_band (ldm, nc); | 4397 Matrix m_band (ldm, nc); |
4398 double *tmp_data = m_band.fortran_vec (); | 4398 double *tmp_data = m_band.fortran_vec (); |
4399 | 4399 |
4400 if (! mattype.is_dense ()) | 4400 if (! mattype.is_dense ()) |
4401 { | 4401 { |
4402 int ii = 0; | 4402 octave_idx_type ii = 0; |
4403 | 4403 |
4404 for (int j = 0; j < ldm; j++) | 4404 for (octave_idx_type j = 0; j < ldm; j++) |
4405 for (int i = 0; i < nc; i++) | 4405 for (octave_idx_type i = 0; i < nc; i++) |
4406 tmp_data[ii++] = 0.; | 4406 tmp_data[ii++] = 0.; |
4407 } | 4407 } |
4408 | 4408 |
4409 for (int j = 0; j < nc; j++) | 4409 for (octave_idx_type j = 0; j < nc; j++) |
4410 for (int i = cidx(j); i < cidx(j+1); i++) | 4410 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
4411 { | 4411 { |
4412 int ri = ridx (i); | 4412 octave_idx_type ri = ridx (i); |
4413 if (ri >= j) | 4413 if (ri >= j) |
4414 m_band(ri - j, j) = data(i); | 4414 m_band(ri - j, j) = data(i); |
4415 } | 4415 } |
4416 | 4416 |
4417 char job = 'L'; | 4417 char job = 'L'; |
4435 err = 0; | 4435 err = 0; |
4436 } | 4436 } |
4437 else | 4437 else |
4438 { | 4438 { |
4439 rcond = 1.; | 4439 rcond = 1.; |
4440 int b_nr = b.rows (); | 4440 octave_idx_type b_nr = b.rows (); |
4441 int b_nc = b.cols (); | 4441 octave_idx_type b_nc = b.cols (); |
4442 OCTAVE_LOCAL_BUFFER (double, Bx, b_nr); | 4442 OCTAVE_LOCAL_BUFFER (double, Bx, b_nr); |
4443 OCTAVE_LOCAL_BUFFER (double, Bz, b_nr); | 4443 OCTAVE_LOCAL_BUFFER (double, Bz, b_nr); |
4444 | 4444 |
4445 // Take a first guess that the number of non-zero terms | 4445 // Take a first guess that the number of non-zero terms |
4446 // will be as many as in b | 4446 // will be as many as in b |
4447 volatile int x_nz = b.nnz (); | 4447 volatile octave_idx_type x_nz = b.nnz (); |
4448 volatile int ii = 0; | 4448 volatile octave_idx_type ii = 0; |
4449 retval = SparseComplexMatrix (b_nr, b_nc, x_nz); | 4449 retval = SparseComplexMatrix (b_nr, b_nc, x_nz); |
4450 | 4450 |
4451 retval.xcidx(0) = 0; | 4451 retval.xcidx(0) = 0; |
4452 for (volatile int j = 0; j < b_nc; j++) | 4452 for (volatile octave_idx_type j = 0; j < b_nc; j++) |
4453 { | 4453 { |
4454 | 4454 |
4455 for (int i = 0; i < b_nr; i++) | 4455 for (octave_idx_type i = 0; i < b_nr; i++) |
4456 { | 4456 { |
4457 Complex c = b (i,j); | 4457 Complex c = b (i,j); |
4458 Bx[i] = std::real (c); | 4458 Bx[i] = std::real (c); |
4459 Bz[i] = std::imag (c); | 4459 Bz[i] = std::imag (c); |
4460 } | 4460 } |
4504 break; | 4504 break; |
4505 } | 4505 } |
4506 | 4506 |
4507 // Count non-zeros in work vector and adjust | 4507 // Count non-zeros in work vector and adjust |
4508 // space in retval if needed | 4508 // space in retval if needed |
4509 int new_nnz = 0; | 4509 octave_idx_type new_nnz = 0; |
4510 for (int i = 0; i < nr; i++) | 4510 for (octave_idx_type i = 0; i < nr; i++) |
4511 if (Bx[i] != 0. || Bz[i] != 0.) | 4511 if (Bx[i] != 0. || Bz[i] != 0.) |
4512 new_nnz++; | 4512 new_nnz++; |
4513 | 4513 |
4514 if (ii + new_nnz > x_nz) | 4514 if (ii + new_nnz > x_nz) |
4515 { | 4515 { |
4516 // Resize the sparse matrix | 4516 // Resize the sparse matrix |
4517 int sz = new_nnz * (b_nc - j) + x_nz; | 4517 octave_idx_type sz = new_nnz * (b_nc - j) + x_nz; |
4518 retval.change_capacity (sz); | 4518 retval.change_capacity (sz); |
4519 x_nz = sz; | 4519 x_nz = sz; |
4520 } | 4520 } |
4521 | 4521 |
4522 for (int i = 0; i < nr; i++) | 4522 for (octave_idx_type i = 0; i < nr; i++) |
4523 if (Bx[i] != 0. || Bz[i] != 0.) | 4523 if (Bx[i] != 0. || Bz[i] != 0.) |
4524 { | 4524 { |
4525 retval.xridx(ii) = i; | 4525 retval.xridx(ii) = i; |
4526 retval.xdata(ii++) = | 4526 retval.xdata(ii++) = |
4527 Complex (Bx[i], Bz[i]); | 4527 Complex (Bx[i], Bz[i]); |
4545 Matrix m_band (ldm, nc); | 4545 Matrix m_band (ldm, nc); |
4546 double *tmp_data = m_band.fortran_vec (); | 4546 double *tmp_data = m_band.fortran_vec (); |
4547 | 4547 |
4548 if (! mattype.is_dense ()) | 4548 if (! mattype.is_dense ()) |
4549 { | 4549 { |
4550 int ii = 0; | 4550 octave_idx_type ii = 0; |
4551 | 4551 |
4552 for (int j = 0; j < ldm; j++) | 4552 for (octave_idx_type j = 0; j < ldm; j++) |
4553 for (int i = 0; i < nc; i++) | 4553 for (octave_idx_type i = 0; i < nc; i++) |
4554 tmp_data[ii++] = 0.; | 4554 tmp_data[ii++] = 0.; |
4555 } | 4555 } |
4556 | 4556 |
4557 for (int j = 0; j < nc; j++) | 4557 for (octave_idx_type j = 0; j < nc; j++) |
4558 for (int i = cidx(j); i < cidx(j+1); i++) | 4558 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
4559 m_band(ridx(i) - j + n_lower + n_upper, j) = data(i); | 4559 m_band(ridx(i) - j + n_lower + n_upper, j) = data(i); |
4560 | 4560 |
4561 Array<int> ipvt (nr); | 4561 Array<octave_idx_type> ipvt (nr); |
4562 int *pipvt = ipvt.fortran_vec (); | 4562 octave_idx_type *pipvt = ipvt.fortran_vec (); |
4563 | 4563 |
4564 F77_XFCN (dgbtrf, DGBTRF, (nr, nr, n_lower, n_upper, tmp_data, | 4564 F77_XFCN (dgbtrf, DGBTRF, (nr, nr, n_lower, n_upper, tmp_data, |
4565 ldm, pipvt, err)); | 4565 ldm, pipvt, err)); |
4566 | 4566 |
4567 if (f77_exception_encountered) | 4567 if (f77_exception_encountered) |
4582 | 4582 |
4583 } | 4583 } |
4584 else | 4584 else |
4585 { | 4585 { |
4586 char job = 'N'; | 4586 char job = 'N'; |
4587 volatile int x_nz = b.nnz (); | 4587 volatile octave_idx_type x_nz = b.nnz (); |
4588 int b_nc = b.cols (); | 4588 octave_idx_type b_nc = b.cols (); |
4589 retval = SparseComplexMatrix (nr, b_nc, x_nz); | 4589 retval = SparseComplexMatrix (nr, b_nc, x_nz); |
4590 retval.xcidx(0) = 0; | 4590 retval.xcidx(0) = 0; |
4591 volatile int ii = 0; | 4591 volatile octave_idx_type ii = 0; |
4592 | 4592 |
4593 OCTAVE_LOCAL_BUFFER (double, Bx, nr); | 4593 OCTAVE_LOCAL_BUFFER (double, Bx, nr); |
4594 OCTAVE_LOCAL_BUFFER (double, Bz, nr); | 4594 OCTAVE_LOCAL_BUFFER (double, Bz, nr); |
4595 | 4595 |
4596 for (volatile int j = 0; j < b_nc; j++) | 4596 for (volatile octave_idx_type j = 0; j < b_nc; j++) |
4597 { | 4597 { |
4598 for (int i = 0; i < nr; i++) | 4598 for (octave_idx_type i = 0; i < nr; i++) |
4599 { | 4599 { |
4600 Bx[i] = 0.; | 4600 Bx[i] = 0.; |
4601 Bz[i] = 0.; | 4601 Bz[i] = 0.; |
4602 } | 4602 } |
4603 for (int i = b.cidx(j); i < b.cidx(j+1); i++) | 4603 for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) |
4604 { | 4604 { |
4605 Complex c = b.data(i); | 4605 Complex c = b.data(i); |
4606 Bx[b.ridx(i)] = std::real (c); | 4606 Bx[b.ridx(i)] = std::real (c); |
4607 Bz[b.ridx(i)] = std::imag (c); | 4607 Bz[b.ridx(i)] = std::imag (c); |
4608 } | 4608 } |
4633 break; | 4633 break; |
4634 } | 4634 } |
4635 | 4635 |
4636 // Count non-zeros in work vector and adjust | 4636 // Count non-zeros in work vector and adjust |
4637 // space in retval if needed | 4637 // space in retval if needed |
4638 int new_nnz = 0; | 4638 octave_idx_type new_nnz = 0; |
4639 for (int i = 0; i < nr; i++) | 4639 for (octave_idx_type i = 0; i < nr; i++) |
4640 if (Bx[i] != 0. || Bz[i] != 0.) | 4640 if (Bx[i] != 0. || Bz[i] != 0.) |
4641 new_nnz++; | 4641 new_nnz++; |
4642 | 4642 |
4643 if (ii + new_nnz > x_nz) | 4643 if (ii + new_nnz > x_nz) |
4644 { | 4644 { |
4645 // Resize the sparse matrix | 4645 // Resize the sparse matrix |
4646 int sz = new_nnz * (b_nc - j) + x_nz; | 4646 octave_idx_type sz = new_nnz * (b_nc - j) + x_nz; |
4647 retval.change_capacity (sz); | 4647 retval.change_capacity (sz); |
4648 x_nz = sz; | 4648 x_nz = sz; |
4649 } | 4649 } |
4650 | 4650 |
4651 for (int i = 0; i < nr; i++) | 4651 for (octave_idx_type i = 0; i < nr; i++) |
4652 if (Bx[i] != 0. || Bz[i] != 0.) | 4652 if (Bx[i] != 0. || Bz[i] != 0.) |
4653 { | 4653 { |
4654 retval.xridx(ii) = i; | 4654 retval.xridx(ii) = i; |
4655 retval.xdata(ii++) = | 4655 retval.xdata(ii++) = |
4656 Complex (Bx[i], Bz[i]); | 4656 Complex (Bx[i], Bz[i]); |
4668 | 4668 |
4669 return retval; | 4669 return retval; |
4670 } | 4670 } |
4671 | 4671 |
4672 void * | 4672 void * |
4673 SparseMatrix::factorize (int& err, double &rcond, Matrix &Control, Matrix &Info, | 4673 SparseMatrix::factorize (octave_idx_type& err, double &rcond, Matrix &Control, Matrix &Info, |
4674 solve_singularity_handler sing_handler) const | 4674 solve_singularity_handler sing_handler) const |
4675 { | 4675 { |
4676 // The return values | 4676 // The return values |
4677 void *Numeric; | 4677 void *Numeric; |
4678 err = 0; | 4678 err = 0; |
4698 if (!xisnan (tmp)) | 4698 if (!xisnan (tmp)) |
4699 Control (UMFPACK_FIXQ) = tmp; | 4699 Control (UMFPACK_FIXQ) = tmp; |
4700 | 4700 |
4701 umfpack_di_report_control (control); | 4701 umfpack_di_report_control (control); |
4702 | 4702 |
4703 const int *Ap = cidx (); | 4703 const octave_idx_type *Ap = cidx (); |
4704 const int *Ai = ridx (); | 4704 const octave_idx_type *Ai = ridx (); |
4705 const double *Ax = data (); | 4705 const double *Ax = data (); |
4706 int nr = rows (); | 4706 octave_idx_type nr = rows (); |
4707 int nc = cols (); | 4707 octave_idx_type nc = cols (); |
4708 | 4708 |
4709 umfpack_di_report_matrix (nr, nc, Ap, Ai, Ax, 1, control); | 4709 umfpack_di_report_matrix (nr, nc, Ap, Ai, Ax, 1, control); |
4710 | 4710 |
4711 void *Symbolic; | 4711 void *Symbolic; |
4712 Info = Matrix (1, UMFPACK_INFO); | 4712 Info = Matrix (1, UMFPACK_INFO); |
4779 | 4779 |
4780 return Numeric; | 4780 return Numeric; |
4781 } | 4781 } |
4782 | 4782 |
4783 Matrix | 4783 Matrix |
4784 SparseMatrix::fsolve (SparseType &mattype, const Matrix& b, int& err, | 4784 SparseMatrix::fsolve (SparseType &mattype, const Matrix& b, octave_idx_type& err, |
4785 double& rcond, | 4785 double& rcond, |
4786 solve_singularity_handler sing_handler) const | 4786 solve_singularity_handler sing_handler) const |
4787 { | 4787 { |
4788 Matrix retval; | 4788 Matrix retval; |
4789 | 4789 |
4790 int nr = rows (); | 4790 octave_idx_type nr = rows (); |
4791 int nc = cols (); | 4791 octave_idx_type nc = cols (); |
4792 err = 0; | 4792 err = 0; |
4793 | 4793 |
4794 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) | 4794 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) |
4795 (*current_liboctave_error_handler) | 4795 (*current_liboctave_error_handler) |
4796 ("matrix dimension mismatch solution of linear equations"); | 4796 ("matrix dimension mismatch solution of linear equations"); |
4822 if (err == 0) | 4822 if (err == 0) |
4823 { | 4823 { |
4824 const double *Bx = b.fortran_vec (); | 4824 const double *Bx = b.fortran_vec (); |
4825 retval.resize (b.rows (), b.cols()); | 4825 retval.resize (b.rows (), b.cols()); |
4826 double *result = retval.fortran_vec (); | 4826 double *result = retval.fortran_vec (); |
4827 int b_nr = b.rows (); | 4827 octave_idx_type b_nr = b.rows (); |
4828 int b_nc = b.cols (); | 4828 octave_idx_type b_nc = b.cols (); |
4829 int status = 0; | 4829 int status = 0; |
4830 double *control = Control.fortran_vec (); | 4830 double *control = Control.fortran_vec (); |
4831 double *info = Info.fortran_vec (); | 4831 double *info = Info.fortran_vec (); |
4832 const int *Ap = cidx (); | 4832 const octave_idx_type *Ap = cidx (); |
4833 const int *Ai = ridx (); | 4833 const octave_idx_type *Ai = ridx (); |
4834 const double *Ax = data (); | 4834 const double *Ax = data (); |
4835 | 4835 |
4836 for (int j = 0, iidx = 0; j < b_nc; j++, iidx += b_nr) | 4836 for (octave_idx_type j = 0, iidx = 0; j < b_nc; j++, iidx += b_nr) |
4837 { | 4837 { |
4838 status = umfpack_di_solve (UMFPACK_A, Ap, Ai, Ax, | 4838 status = umfpack_di_solve (UMFPACK_A, Ap, Ai, Ax, |
4839 &result[iidx], &Bx[iidx], | 4839 &result[iidx], &Bx[iidx], |
4840 Numeric, control, info); | 4840 Numeric, control, info); |
4841 if (status < 0) | 4841 if (status < 0) |
4884 | 4884 |
4885 return retval; | 4885 return retval; |
4886 } | 4886 } |
4887 | 4887 |
4888 SparseMatrix | 4888 SparseMatrix |
4889 SparseMatrix::fsolve (SparseType &mattype, const SparseMatrix& b, int& err, double& rcond, | 4889 SparseMatrix::fsolve (SparseType &mattype, const SparseMatrix& b, octave_idx_type& err, double& rcond, |
4890 solve_singularity_handler sing_handler) const | 4890 solve_singularity_handler sing_handler) const |
4891 { | 4891 { |
4892 SparseMatrix retval; | 4892 SparseMatrix retval; |
4893 | 4893 |
4894 int nr = rows (); | 4894 octave_idx_type nr = rows (); |
4895 int nc = cols (); | 4895 octave_idx_type nc = cols (); |
4896 err = 0; | 4896 err = 0; |
4897 | 4897 |
4898 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) | 4898 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) |
4899 (*current_liboctave_error_handler) | 4899 (*current_liboctave_error_handler) |
4900 ("matrix dimension mismatch solution of linear equations"); | 4900 ("matrix dimension mismatch solution of linear equations"); |
4923 void *Numeric = factorize (err, rcond, Control, Info, | 4923 void *Numeric = factorize (err, rcond, Control, Info, |
4924 sing_handler); | 4924 sing_handler); |
4925 | 4925 |
4926 if (err == 0) | 4926 if (err == 0) |
4927 { | 4927 { |
4928 int b_nr = b.rows (); | 4928 octave_idx_type b_nr = b.rows (); |
4929 int b_nc = b.cols (); | 4929 octave_idx_type b_nc = b.cols (); |
4930 int status = 0; | 4930 int status = 0; |
4931 double *control = Control.fortran_vec (); | 4931 double *control = Control.fortran_vec (); |
4932 double *info = Info.fortran_vec (); | 4932 double *info = Info.fortran_vec (); |
4933 const int *Ap = cidx (); | 4933 const octave_idx_type *Ap = cidx (); |
4934 const int *Ai = ridx (); | 4934 const octave_idx_type *Ai = ridx (); |
4935 const double *Ax = data (); | 4935 const double *Ax = data (); |
4936 | 4936 |
4937 OCTAVE_LOCAL_BUFFER (double, Bx, b_nr); | 4937 OCTAVE_LOCAL_BUFFER (double, Bx, b_nr); |
4938 OCTAVE_LOCAL_BUFFER (double, Xx, b_nr); | 4938 OCTAVE_LOCAL_BUFFER (double, Xx, b_nr); |
4939 | 4939 |
4940 // Take a first guess that the number of non-zero terms | 4940 // Take a first guess that the number of non-zero terms |
4941 // will be as many as in b | 4941 // will be as many as in b |
4942 int x_nz = b.nnz (); | 4942 octave_idx_type x_nz = b.nnz (); |
4943 int ii = 0; | 4943 octave_idx_type ii = 0; |
4944 retval = SparseMatrix (b_nr, b_nc, x_nz); | 4944 retval = SparseMatrix (b_nr, b_nc, x_nz); |
4945 | 4945 |
4946 retval.xcidx(0) = 0; | 4946 retval.xcidx(0) = 0; |
4947 for (int j = 0; j < b_nc; j++) | 4947 for (octave_idx_type j = 0; j < b_nc; j++) |
4948 { | 4948 { |
4949 | 4949 |
4950 for (int i = 0; i < b_nr; i++) | 4950 for (octave_idx_type i = 0; i < b_nr; i++) |
4951 Bx[i] = b.elem (i, j); | 4951 Bx[i] = b.elem (i, j); |
4952 | 4952 |
4953 status = umfpack_di_solve (UMFPACK_A, Ap, Ai, Ax, Xx, | 4953 status = umfpack_di_solve (UMFPACK_A, Ap, Ai, Ax, Xx, |
4954 Bx, Numeric, control, | 4954 Bx, Numeric, control, |
4955 info); | 4955 info); |
4963 err = -1; | 4963 err = -1; |
4964 | 4964 |
4965 break; | 4965 break; |
4966 } | 4966 } |
4967 | 4967 |
4968 for (int i = 0; i < b_nr; i++) | 4968 for (octave_idx_type i = 0; i < b_nr; i++) |
4969 { | 4969 { |
4970 double tmp = Xx[i]; | 4970 double tmp = Xx[i]; |
4971 if (tmp != 0.0) | 4971 if (tmp != 0.0) |
4972 { | 4972 { |
4973 if (ii == x_nz) | 4973 if (ii == x_nz) |
4974 { | 4974 { |
4975 // Resize the sparse matrix | 4975 // Resize the sparse matrix |
4976 int sz = x_nz * (b_nc - j) / b_nc; | 4976 octave_idx_type sz = x_nz * (b_nc - j) / b_nc; |
4977 sz = (sz > 10 ? sz : 10) + x_nz; | 4977 sz = (sz > 10 ? sz : 10) + x_nz; |
4978 retval.change_capacity (sz); | 4978 retval.change_capacity (sz); |
4979 x_nz = sz; | 4979 x_nz = sz; |
4980 } | 4980 } |
4981 retval.xdata(ii) = tmp; | 4981 retval.xdata(ii) = tmp; |
5020 | 5020 |
5021 return retval; | 5021 return retval; |
5022 } | 5022 } |
5023 | 5023 |
5024 ComplexMatrix | 5024 ComplexMatrix |
5025 SparseMatrix::fsolve (SparseType &mattype, const ComplexMatrix& b, int& err, double& rcond, | 5025 SparseMatrix::fsolve (SparseType &mattype, const ComplexMatrix& b, octave_idx_type& err, double& rcond, |
5026 solve_singularity_handler sing_handler) const | 5026 solve_singularity_handler sing_handler) const |
5027 { | 5027 { |
5028 ComplexMatrix retval; | 5028 ComplexMatrix retval; |
5029 | 5029 |
5030 int nr = rows (); | 5030 octave_idx_type nr = rows (); |
5031 int nc = cols (); | 5031 octave_idx_type nc = cols (); |
5032 err = 0; | 5032 err = 0; |
5033 | 5033 |
5034 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) | 5034 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) |
5035 (*current_liboctave_error_handler) | 5035 (*current_liboctave_error_handler) |
5036 ("matrix dimension mismatch solution of linear equations"); | 5036 ("matrix dimension mismatch solution of linear equations"); |
5059 void *Numeric = factorize (err, rcond, Control, Info, | 5059 void *Numeric = factorize (err, rcond, Control, Info, |
5060 sing_handler); | 5060 sing_handler); |
5061 | 5061 |
5062 if (err == 0) | 5062 if (err == 0) |
5063 { | 5063 { |
5064 int b_nr = b.rows (); | 5064 octave_idx_type b_nr = b.rows (); |
5065 int b_nc = b.cols (); | 5065 octave_idx_type b_nc = b.cols (); |
5066 int status = 0; | 5066 int status = 0; |
5067 double *control = Control.fortran_vec (); | 5067 double *control = Control.fortran_vec (); |
5068 double *info = Info.fortran_vec (); | 5068 double *info = Info.fortran_vec (); |
5069 const int *Ap = cidx (); | 5069 const octave_idx_type *Ap = cidx (); |
5070 const int *Ai = ridx (); | 5070 const octave_idx_type *Ai = ridx (); |
5071 const double *Ax = data (); | 5071 const double *Ax = data (); |
5072 | 5072 |
5073 OCTAVE_LOCAL_BUFFER (double, Bx, b_nr); | 5073 OCTAVE_LOCAL_BUFFER (double, Bx, b_nr); |
5074 OCTAVE_LOCAL_BUFFER (double, Bz, b_nr); | 5074 OCTAVE_LOCAL_BUFFER (double, Bz, b_nr); |
5075 | 5075 |
5076 retval.resize (b_nr, b_nc); | 5076 retval.resize (b_nr, b_nc); |
5077 | 5077 |
5078 OCTAVE_LOCAL_BUFFER (double, Xx, b_nr); | 5078 OCTAVE_LOCAL_BUFFER (double, Xx, b_nr); |
5079 OCTAVE_LOCAL_BUFFER (double, Xz, b_nr); | 5079 OCTAVE_LOCAL_BUFFER (double, Xz, b_nr); |
5080 | 5080 |
5081 for (int j = 0; j < b_nc; j++) | 5081 for (octave_idx_type j = 0; j < b_nc; j++) |
5082 { | 5082 { |
5083 for (int i = 0; i < b_nr; i++) | 5083 for (octave_idx_type i = 0; i < b_nr; i++) |
5084 { | 5084 { |
5085 Complex c = b (i,j); | 5085 Complex c = b (i,j); |
5086 Bx[i] = std::real (c); | 5086 Bx[i] = std::real (c); |
5087 Bz[i] = std::imag (c); | 5087 Bz[i] = std::imag (c); |
5088 } | 5088 } |
5104 err = -1; | 5104 err = -1; |
5105 | 5105 |
5106 break; | 5106 break; |
5107 } | 5107 } |
5108 | 5108 |
5109 for (int i = 0; i < b_nr; i++) | 5109 for (octave_idx_type i = 0; i < b_nr; i++) |
5110 retval (i, j) = Complex (Xx[i], Xz[i]); | 5110 retval (i, j) = Complex (Xx[i], Xz[i]); |
5111 } | 5111 } |
5112 | 5112 |
5113 #ifndef HAVE_LSSOLVE | 5113 #ifndef HAVE_LSSOLVE |
5114 rcond = Info (UMFPACK_RCOND); | 5114 rcond = Info (UMFPACK_RCOND); |
5144 return retval; | 5144 return retval; |
5145 } | 5145 } |
5146 | 5146 |
5147 SparseComplexMatrix | 5147 SparseComplexMatrix |
5148 SparseMatrix::fsolve (SparseType &mattype, const SparseComplexMatrix& b, | 5148 SparseMatrix::fsolve (SparseType &mattype, const SparseComplexMatrix& b, |
5149 int& err, double& rcond, | 5149 octave_idx_type& err, double& rcond, |
5150 solve_singularity_handler sing_handler) const | 5150 solve_singularity_handler sing_handler) const |
5151 { | 5151 { |
5152 SparseComplexMatrix retval; | 5152 SparseComplexMatrix retval; |
5153 | 5153 |
5154 int nr = rows (); | 5154 octave_idx_type nr = rows (); |
5155 int nc = cols (); | 5155 octave_idx_type nc = cols (); |
5156 err = 0; | 5156 err = 0; |
5157 | 5157 |
5158 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) | 5158 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) |
5159 (*current_liboctave_error_handler) | 5159 (*current_liboctave_error_handler) |
5160 ("matrix dimension mismatch solution of linear equations"); | 5160 ("matrix dimension mismatch solution of linear equations"); |
5183 void *Numeric = factorize (err, rcond, Control, Info, | 5183 void *Numeric = factorize (err, rcond, Control, Info, |
5184 sing_handler); | 5184 sing_handler); |
5185 | 5185 |
5186 if (err == 0) | 5186 if (err == 0) |
5187 { | 5187 { |
5188 int b_nr = b.rows (); | 5188 octave_idx_type b_nr = b.rows (); |
5189 int b_nc = b.cols (); | 5189 octave_idx_type b_nc = b.cols (); |
5190 int status = 0; | 5190 int status = 0; |
5191 double *control = Control.fortran_vec (); | 5191 double *control = Control.fortran_vec (); |
5192 double *info = Info.fortran_vec (); | 5192 double *info = Info.fortran_vec (); |
5193 const int *Ap = cidx (); | 5193 const octave_idx_type *Ap = cidx (); |
5194 const int *Ai = ridx (); | 5194 const octave_idx_type *Ai = ridx (); |
5195 const double *Ax = data (); | 5195 const double *Ax = data (); |
5196 | 5196 |
5197 OCTAVE_LOCAL_BUFFER (double, Bx, b_nr); | 5197 OCTAVE_LOCAL_BUFFER (double, Bx, b_nr); |
5198 OCTAVE_LOCAL_BUFFER (double, Bz, b_nr); | 5198 OCTAVE_LOCAL_BUFFER (double, Bz, b_nr); |
5199 | 5199 |
5200 // Take a first guess that the number of non-zero terms | 5200 // Take a first guess that the number of non-zero terms |
5201 // will be as many as in b | 5201 // will be as many as in b |
5202 int x_nz = b.nnz (); | 5202 octave_idx_type x_nz = b.nnz (); |
5203 int ii = 0; | 5203 octave_idx_type ii = 0; |
5204 retval = SparseComplexMatrix (b_nr, b_nc, x_nz); | 5204 retval = SparseComplexMatrix (b_nr, b_nc, x_nz); |
5205 | 5205 |
5206 OCTAVE_LOCAL_BUFFER (double, Xx, b_nr); | 5206 OCTAVE_LOCAL_BUFFER (double, Xx, b_nr); |
5207 OCTAVE_LOCAL_BUFFER (double, Xz, b_nr); | 5207 OCTAVE_LOCAL_BUFFER (double, Xz, b_nr); |
5208 | 5208 |
5209 retval.xcidx(0) = 0; | 5209 retval.xcidx(0) = 0; |
5210 for (int j = 0; j < b_nc; j++) | 5210 for (octave_idx_type j = 0; j < b_nc; j++) |
5211 { | 5211 { |
5212 for (int i = 0; i < b_nr; i++) | 5212 for (octave_idx_type i = 0; i < b_nr; i++) |
5213 { | 5213 { |
5214 Complex c = b (i,j); | 5214 Complex c = b (i,j); |
5215 Bx[i] = std::real (c); | 5215 Bx[i] = std::real (c); |
5216 Bz[i] = std::imag (c); | 5216 Bz[i] = std::imag (c); |
5217 } | 5217 } |
5233 err = -1; | 5233 err = -1; |
5234 | 5234 |
5235 break; | 5235 break; |
5236 } | 5236 } |
5237 | 5237 |
5238 for (int i = 0; i < b_nr; i++) | 5238 for (octave_idx_type i = 0; i < b_nr; i++) |
5239 { | 5239 { |
5240 Complex tmp = Complex (Xx[i], Xz[i]); | 5240 Complex tmp = Complex (Xx[i], Xz[i]); |
5241 if (tmp != 0.0) | 5241 if (tmp != 0.0) |
5242 { | 5242 { |
5243 if (ii == x_nz) | 5243 if (ii == x_nz) |
5244 { | 5244 { |
5245 // Resize the sparse matrix | 5245 // Resize the sparse matrix |
5246 int sz = x_nz * (b_nc - j) / b_nc; | 5246 octave_idx_type sz = x_nz * (b_nc - j) / b_nc; |
5247 sz = (sz > 10 ? sz : 10) + x_nz; | 5247 sz = (sz > 10 ? sz : 10) + x_nz; |
5248 retval.change_capacity (sz); | 5248 retval.change_capacity (sz); |
5249 x_nz = sz; | 5249 x_nz = sz; |
5250 } | 5250 } |
5251 retval.xdata(ii) = tmp; | 5251 retval.xdata(ii) = tmp; |
5292 } | 5292 } |
5293 | 5293 |
5294 Matrix | 5294 Matrix |
5295 SparseMatrix::solve (SparseType &mattype, const Matrix& b) const | 5295 SparseMatrix::solve (SparseType &mattype, const Matrix& b) const |
5296 { | 5296 { |
5297 int info; | 5297 octave_idx_type info; |
5298 double rcond; | 5298 double rcond; |
5299 return solve (mattype, b, info, rcond, 0); | 5299 return solve (mattype, b, info, rcond, 0); |
5300 } | 5300 } |
5301 | 5301 |
5302 Matrix | 5302 Matrix |
5303 SparseMatrix::solve (SparseType &mattype, const Matrix& b, int& info) const | 5303 SparseMatrix::solve (SparseType &mattype, const Matrix& b, octave_idx_type& info) const |
5304 { | 5304 { |
5305 double rcond; | 5305 double rcond; |
5306 return solve (mattype, b, info, rcond, 0); | 5306 return solve (mattype, b, info, rcond, 0); |
5307 } | 5307 } |
5308 | 5308 |
5309 Matrix | 5309 Matrix |
5310 SparseMatrix::solve (SparseType &mattype, const Matrix& b, int& info, | 5310 SparseMatrix::solve (SparseType &mattype, const Matrix& b, octave_idx_type& info, |
5311 double& rcond) const | 5311 double& rcond) const |
5312 { | 5312 { |
5313 return solve (mattype, b, info, rcond, 0); | 5313 return solve (mattype, b, info, rcond, 0); |
5314 } | 5314 } |
5315 | 5315 |
5316 Matrix | 5316 Matrix |
5317 SparseMatrix::solve (SparseType &mattype, const Matrix& b, int& err, | 5317 SparseMatrix::solve (SparseType &mattype, const Matrix& b, octave_idx_type& err, |
5318 double& rcond, | 5318 double& rcond, |
5319 solve_singularity_handler sing_handler) const | 5319 solve_singularity_handler sing_handler) const |
5320 { | 5320 { |
5321 int typ = mattype.type (); | 5321 int typ = mattype.type (); |
5322 | 5322 |
5345 } | 5345 } |
5346 | 5346 |
5347 SparseMatrix | 5347 SparseMatrix |
5348 SparseMatrix::solve (SparseType &mattype, const SparseMatrix& b) const | 5348 SparseMatrix::solve (SparseType &mattype, const SparseMatrix& b) const |
5349 { | 5349 { |
5350 int info; | 5350 octave_idx_type info; |
5351 double rcond; | 5351 double rcond; |
5352 return solve (mattype, b, info, rcond, 0); | 5352 return solve (mattype, b, info, rcond, 0); |
5353 } | 5353 } |
5354 | 5354 |
5355 SparseMatrix | 5355 SparseMatrix |
5356 SparseMatrix::solve (SparseType &mattype, const SparseMatrix& b, | 5356 SparseMatrix::solve (SparseType &mattype, const SparseMatrix& b, |
5357 int& info) const | 5357 octave_idx_type& info) const |
5358 { | 5358 { |
5359 double rcond; | 5359 double rcond; |
5360 return solve (mattype, b, info, rcond, 0); | 5360 return solve (mattype, b, info, rcond, 0); |
5361 } | 5361 } |
5362 | 5362 |
5363 SparseMatrix | 5363 SparseMatrix |
5364 SparseMatrix::solve (SparseType &mattype, const SparseMatrix& b, | 5364 SparseMatrix::solve (SparseType &mattype, const SparseMatrix& b, |
5365 int& info, double& rcond) const | 5365 octave_idx_type& info, double& rcond) const |
5366 { | 5366 { |
5367 return solve (mattype, b, info, rcond, 0); | 5367 return solve (mattype, b, info, rcond, 0); |
5368 } | 5368 } |
5369 | 5369 |
5370 SparseMatrix | 5370 SparseMatrix |
5371 SparseMatrix::solve (SparseType &mattype, const SparseMatrix& b, | 5371 SparseMatrix::solve (SparseType &mattype, const SparseMatrix& b, |
5372 int& err, double& rcond, | 5372 octave_idx_type& err, double& rcond, |
5373 solve_singularity_handler sing_handler) const | 5373 solve_singularity_handler sing_handler) const |
5374 { | 5374 { |
5375 int typ = mattype.type (); | 5375 int typ = mattype.type (); |
5376 | 5376 |
5377 if (typ == SparseType::Unknown) | 5377 if (typ == SparseType::Unknown) |
5399 } | 5399 } |
5400 | 5400 |
5401 ComplexMatrix | 5401 ComplexMatrix |
5402 SparseMatrix::solve (SparseType &mattype, const ComplexMatrix& b) const | 5402 SparseMatrix::solve (SparseType &mattype, const ComplexMatrix& b) const |
5403 { | 5403 { |
5404 int info; | 5404 octave_idx_type info; |
5405 double rcond; | 5405 double rcond; |
5406 return solve (mattype, b, info, rcond, 0); | 5406 return solve (mattype, b, info, rcond, 0); |
5407 } | 5407 } |
5408 | 5408 |
5409 ComplexMatrix | 5409 ComplexMatrix |
5410 SparseMatrix::solve (SparseType &mattype, const ComplexMatrix& b, | 5410 SparseMatrix::solve (SparseType &mattype, const ComplexMatrix& b, |
5411 int& info) const | 5411 octave_idx_type& info) const |
5412 { | 5412 { |
5413 double rcond; | 5413 double rcond; |
5414 return solve (mattype, b, info, rcond, 0); | 5414 return solve (mattype, b, info, rcond, 0); |
5415 } | 5415 } |
5416 | 5416 |
5417 ComplexMatrix | 5417 ComplexMatrix |
5418 SparseMatrix::solve (SparseType &mattype, const ComplexMatrix& b, | 5418 SparseMatrix::solve (SparseType &mattype, const ComplexMatrix& b, |
5419 int& info, double& rcond) const | 5419 octave_idx_type& info, double& rcond) const |
5420 { | 5420 { |
5421 return solve (mattype, b, info, rcond, 0); | 5421 return solve (mattype, b, info, rcond, 0); |
5422 } | 5422 } |
5423 | 5423 |
5424 ComplexMatrix | 5424 ComplexMatrix |
5425 SparseMatrix::solve (SparseType &mattype, const ComplexMatrix& b, | 5425 SparseMatrix::solve (SparseType &mattype, const ComplexMatrix& b, |
5426 int& err, double& rcond, | 5426 octave_idx_type& err, double& rcond, |
5427 solve_singularity_handler sing_handler) const | 5427 solve_singularity_handler sing_handler) const |
5428 { | 5428 { |
5429 int typ = mattype.type (); | 5429 int typ = mattype.type (); |
5430 | 5430 |
5431 if (typ == SparseType::Unknown) | 5431 if (typ == SparseType::Unknown) |
5453 } | 5453 } |
5454 | 5454 |
5455 SparseComplexMatrix | 5455 SparseComplexMatrix |
5456 SparseMatrix::solve (SparseType &mattype, const SparseComplexMatrix& b) const | 5456 SparseMatrix::solve (SparseType &mattype, const SparseComplexMatrix& b) const |
5457 { | 5457 { |
5458 int info; | 5458 octave_idx_type info; |
5459 double rcond; | 5459 double rcond; |
5460 return solve (mattype, b, info, rcond, 0); | 5460 return solve (mattype, b, info, rcond, 0); |
5461 } | 5461 } |
5462 | 5462 |
5463 SparseComplexMatrix | 5463 SparseComplexMatrix |
5464 SparseMatrix::solve (SparseType &mattype, const SparseComplexMatrix& b, | 5464 SparseMatrix::solve (SparseType &mattype, const SparseComplexMatrix& b, |
5465 int& info) const | 5465 octave_idx_type& info) const |
5466 { | 5466 { |
5467 double rcond; | 5467 double rcond; |
5468 return solve (mattype, b, info, rcond, 0); | 5468 return solve (mattype, b, info, rcond, 0); |
5469 } | 5469 } |
5470 | 5470 |
5471 SparseComplexMatrix | 5471 SparseComplexMatrix |
5472 SparseMatrix::solve (SparseType &mattype, const SparseComplexMatrix& b, | 5472 SparseMatrix::solve (SparseType &mattype, const SparseComplexMatrix& b, |
5473 int& info, double& rcond) const | 5473 octave_idx_type& info, double& rcond) const |
5474 { | 5474 { |
5475 return solve (mattype, b, info, rcond, 0); | 5475 return solve (mattype, b, info, rcond, 0); |
5476 } | 5476 } |
5477 | 5477 |
5478 SparseComplexMatrix | 5478 SparseComplexMatrix |
5479 SparseMatrix::solve (SparseType &mattype, const SparseComplexMatrix& b, | 5479 SparseMatrix::solve (SparseType &mattype, const SparseComplexMatrix& b, |
5480 int& err, double& rcond, | 5480 octave_idx_type& err, double& rcond, |
5481 solve_singularity_handler sing_handler) const | 5481 solve_singularity_handler sing_handler) const |
5482 { | 5482 { |
5483 int typ = mattype.type (); | 5483 int typ = mattype.type (); |
5484 | 5484 |
5485 if (typ == SparseType::Unknown) | 5485 if (typ == SparseType::Unknown) |
5507 } | 5507 } |
5508 | 5508 |
5509 ColumnVector | 5509 ColumnVector |
5510 SparseMatrix::solve (SparseType &mattype, const ColumnVector& b) const | 5510 SparseMatrix::solve (SparseType &mattype, const ColumnVector& b) const |
5511 { | 5511 { |
5512 int info; double rcond; | 5512 octave_idx_type info; double rcond; |
5513 return solve (mattype, b, info, rcond); | 5513 return solve (mattype, b, info, rcond); |
5514 } | 5514 } |
5515 | 5515 |
5516 ColumnVector | 5516 ColumnVector |
5517 SparseMatrix::solve (SparseType &mattype, const ColumnVector& b, int& info) const | 5517 SparseMatrix::solve (SparseType &mattype, const ColumnVector& b, octave_idx_type& info) const |
5518 { | 5518 { |
5519 double rcond; | 5519 double rcond; |
5520 return solve (mattype, b, info, rcond); | 5520 return solve (mattype, b, info, rcond); |
5521 } | 5521 } |
5522 | 5522 |
5523 ColumnVector | 5523 ColumnVector |
5524 SparseMatrix::solve (SparseType &mattype, const ColumnVector& b, int& info, double& rcond) const | 5524 SparseMatrix::solve (SparseType &mattype, const ColumnVector& b, octave_idx_type& info, double& rcond) const |
5525 { | 5525 { |
5526 return solve (mattype, b, info, rcond, 0); | 5526 return solve (mattype, b, info, rcond, 0); |
5527 } | 5527 } |
5528 | 5528 |
5529 ColumnVector | 5529 ColumnVector |
5530 SparseMatrix::solve (SparseType &mattype, const ColumnVector& b, int& info, double& rcond, | 5530 SparseMatrix::solve (SparseType &mattype, const ColumnVector& b, octave_idx_type& info, double& rcond, |
5531 solve_singularity_handler sing_handler) const | 5531 solve_singularity_handler sing_handler) const |
5532 { | 5532 { |
5533 Matrix tmp (b); | 5533 Matrix tmp (b); |
5534 return solve (mattype, tmp, info, rcond, sing_handler).column (0); | 5534 return solve (mattype, tmp, info, rcond, sing_handler).column (static_cast<octave_idx_type> (0)); |
5535 } | 5535 } |
5536 | 5536 |
5537 ComplexColumnVector | 5537 ComplexColumnVector |
5538 SparseMatrix::solve (SparseType &mattype, const ComplexColumnVector& b) const | 5538 SparseMatrix::solve (SparseType &mattype, const ComplexColumnVector& b) const |
5539 { | 5539 { |
5540 int info; | 5540 octave_idx_type info; |
5541 double rcond; | 5541 double rcond; |
5542 return solve (mattype, b, info, rcond, 0); | 5542 return solve (mattype, b, info, rcond, 0); |
5543 } | 5543 } |
5544 | 5544 |
5545 ComplexColumnVector | 5545 ComplexColumnVector |
5546 SparseMatrix::solve (SparseType &mattype, const ComplexColumnVector& b, int& info) const | 5546 SparseMatrix::solve (SparseType &mattype, const ComplexColumnVector& b, octave_idx_type& info) const |
5547 { | 5547 { |
5548 double rcond; | 5548 double rcond; |
5549 return solve (mattype, b, info, rcond, 0); | 5549 return solve (mattype, b, info, rcond, 0); |
5550 } | 5550 } |
5551 | 5551 |
5552 ComplexColumnVector | 5552 ComplexColumnVector |
5553 SparseMatrix::solve (SparseType &mattype, const ComplexColumnVector& b, int& info, | 5553 SparseMatrix::solve (SparseType &mattype, const ComplexColumnVector& b, octave_idx_type& info, |
5554 double& rcond) const | 5554 double& rcond) const |
5555 { | 5555 { |
5556 return solve (mattype, b, info, rcond, 0); | 5556 return solve (mattype, b, info, rcond, 0); |
5557 } | 5557 } |
5558 | 5558 |
5559 ComplexColumnVector | 5559 ComplexColumnVector |
5560 SparseMatrix::solve (SparseType &mattype, const ComplexColumnVector& b, int& info, double& rcond, | 5560 SparseMatrix::solve (SparseType &mattype, const ComplexColumnVector& b, octave_idx_type& info, double& rcond, |
5561 solve_singularity_handler sing_handler) const | 5561 solve_singularity_handler sing_handler) const |
5562 { | 5562 { |
5563 ComplexMatrix tmp (b); | 5563 ComplexMatrix tmp (b); |
5564 return solve (mattype, tmp, info, rcond, sing_handler).column (0); | 5564 return solve (mattype, tmp, info, rcond, sing_handler).column (static_cast<octave_idx_type> (0)); |
5565 } | 5565 } |
5566 | 5566 |
5567 Matrix | 5567 Matrix |
5568 SparseMatrix::solve (const Matrix& b) const | 5568 SparseMatrix::solve (const Matrix& b) const |
5569 { | 5569 { |
5570 int info; | 5570 octave_idx_type info; |
5571 double rcond; | 5571 double rcond; |
5572 return solve (b, info, rcond, 0); | 5572 return solve (b, info, rcond, 0); |
5573 } | 5573 } |
5574 | 5574 |
5575 Matrix | 5575 Matrix |
5576 SparseMatrix::solve (const Matrix& b, int& info) const | 5576 SparseMatrix::solve (const Matrix& b, octave_idx_type& info) const |
5577 { | 5577 { |
5578 double rcond; | 5578 double rcond; |
5579 return solve (b, info, rcond, 0); | 5579 return solve (b, info, rcond, 0); |
5580 } | 5580 } |
5581 | 5581 |
5582 Matrix | 5582 Matrix |
5583 SparseMatrix::solve (const Matrix& b, int& info, | 5583 SparseMatrix::solve (const Matrix& b, octave_idx_type& info, |
5584 double& rcond) const | 5584 double& rcond) const |
5585 { | 5585 { |
5586 return solve (b, info, rcond, 0); | 5586 return solve (b, info, rcond, 0); |
5587 } | 5587 } |
5588 | 5588 |
5589 Matrix | 5589 Matrix |
5590 SparseMatrix::solve (const Matrix& b, int& err, | 5590 SparseMatrix::solve (const Matrix& b, octave_idx_type& err, |
5591 double& rcond, | 5591 double& rcond, |
5592 solve_singularity_handler sing_handler) const | 5592 solve_singularity_handler sing_handler) const |
5593 { | 5593 { |
5594 SparseType mattype (*this); | 5594 SparseType mattype (*this); |
5595 return solve (mattype, b, err, rcond, sing_handler); | 5595 return solve (mattype, b, err, rcond, sing_handler); |
5596 } | 5596 } |
5597 | 5597 |
5598 SparseMatrix | 5598 SparseMatrix |
5599 SparseMatrix::solve (const SparseMatrix& b) const | 5599 SparseMatrix::solve (const SparseMatrix& b) const |
5600 { | 5600 { |
5601 int info; | 5601 octave_idx_type info; |
5602 double rcond; | 5602 double rcond; |
5603 return solve (b, info, rcond, 0); | 5603 return solve (b, info, rcond, 0); |
5604 } | 5604 } |
5605 | 5605 |
5606 SparseMatrix | 5606 SparseMatrix |
5607 SparseMatrix::solve (const SparseMatrix& b, | 5607 SparseMatrix::solve (const SparseMatrix& b, |
5608 int& info) const | 5608 octave_idx_type& info) const |
5609 { | 5609 { |
5610 double rcond; | 5610 double rcond; |
5611 return solve (b, info, rcond, 0); | 5611 return solve (b, info, rcond, 0); |
5612 } | 5612 } |
5613 | 5613 |
5614 SparseMatrix | 5614 SparseMatrix |
5615 SparseMatrix::solve (const SparseMatrix& b, | 5615 SparseMatrix::solve (const SparseMatrix& b, |
5616 int& info, double& rcond) const | 5616 octave_idx_type& info, double& rcond) const |
5617 { | 5617 { |
5618 return solve (b, info, rcond, 0); | 5618 return solve (b, info, rcond, 0); |
5619 } | 5619 } |
5620 | 5620 |
5621 SparseMatrix | 5621 SparseMatrix |
5622 SparseMatrix::solve (const SparseMatrix& b, | 5622 SparseMatrix::solve (const SparseMatrix& b, |
5623 int& err, double& rcond, | 5623 octave_idx_type& err, double& rcond, |
5624 solve_singularity_handler sing_handler) const | 5624 solve_singularity_handler sing_handler) const |
5625 { | 5625 { |
5626 SparseType mattype (*this); | 5626 SparseType mattype (*this); |
5627 return solve (mattype, b, err, rcond, sing_handler); | 5627 return solve (mattype, b, err, rcond, sing_handler); |
5628 } | 5628 } |
5629 | 5629 |
5630 ComplexMatrix | 5630 ComplexMatrix |
5631 SparseMatrix::solve (const ComplexMatrix& b, | 5631 SparseMatrix::solve (const ComplexMatrix& b, |
5632 int& info) const | 5632 octave_idx_type& info) const |
5633 { | 5633 { |
5634 double rcond; | 5634 double rcond; |
5635 return solve (b, info, rcond, 0); | 5635 return solve (b, info, rcond, 0); |
5636 } | 5636 } |
5637 | 5637 |
5638 ComplexMatrix | 5638 ComplexMatrix |
5639 SparseMatrix::solve (const ComplexMatrix& b, | 5639 SparseMatrix::solve (const ComplexMatrix& b, |
5640 int& info, double& rcond) const | 5640 octave_idx_type& info, double& rcond) const |
5641 { | 5641 { |
5642 return solve (b, info, rcond, 0); | 5642 return solve (b, info, rcond, 0); |
5643 } | 5643 } |
5644 | 5644 |
5645 ComplexMatrix | 5645 ComplexMatrix |
5646 SparseMatrix::solve (const ComplexMatrix& b, | 5646 SparseMatrix::solve (const ComplexMatrix& b, |
5647 int& err, double& rcond, | 5647 octave_idx_type& err, double& rcond, |
5648 solve_singularity_handler sing_handler) const | 5648 solve_singularity_handler sing_handler) const |
5649 { | 5649 { |
5650 SparseType mattype (*this); | 5650 SparseType mattype (*this); |
5651 return solve (mattype, b, err, rcond, sing_handler); | 5651 return solve (mattype, b, err, rcond, sing_handler); |
5652 } | 5652 } |
5653 | 5653 |
5654 SparseComplexMatrix | 5654 SparseComplexMatrix |
5655 SparseMatrix::solve (const SparseComplexMatrix& b) const | 5655 SparseMatrix::solve (const SparseComplexMatrix& b) const |
5656 { | 5656 { |
5657 int info; | 5657 octave_idx_type info; |
5658 double rcond; | 5658 double rcond; |
5659 return solve (b, info, rcond, 0); | 5659 return solve (b, info, rcond, 0); |
5660 } | 5660 } |
5661 | 5661 |
5662 SparseComplexMatrix | 5662 SparseComplexMatrix |
5663 SparseMatrix::solve (const SparseComplexMatrix& b, | 5663 SparseMatrix::solve (const SparseComplexMatrix& b, |
5664 int& info) const | 5664 octave_idx_type& info) const |
5665 { | 5665 { |
5666 double rcond; | 5666 double rcond; |
5667 return solve (b, info, rcond, 0); | 5667 return solve (b, info, rcond, 0); |
5668 } | 5668 } |
5669 | 5669 |
5670 SparseComplexMatrix | 5670 SparseComplexMatrix |
5671 SparseMatrix::solve (const SparseComplexMatrix& b, | 5671 SparseMatrix::solve (const SparseComplexMatrix& b, |
5672 int& info, double& rcond) const | 5672 octave_idx_type& info, double& rcond) const |
5673 { | 5673 { |
5674 return solve (b, info, rcond, 0); | 5674 return solve (b, info, rcond, 0); |
5675 } | 5675 } |
5676 | 5676 |
5677 SparseComplexMatrix | 5677 SparseComplexMatrix |
5678 SparseMatrix::solve (const SparseComplexMatrix& b, | 5678 SparseMatrix::solve (const SparseComplexMatrix& b, |
5679 int& err, double& rcond, | 5679 octave_idx_type& err, double& rcond, |
5680 solve_singularity_handler sing_handler) const | 5680 solve_singularity_handler sing_handler) const |
5681 { | 5681 { |
5682 SparseType mattype (*this); | 5682 SparseType mattype (*this); |
5683 return solve (mattype, b, err, rcond, sing_handler); | 5683 return solve (mattype, b, err, rcond, sing_handler); |
5684 } | 5684 } |
5685 | 5685 |
5686 ColumnVector | 5686 ColumnVector |
5687 SparseMatrix::solve (const ColumnVector& b) const | 5687 SparseMatrix::solve (const ColumnVector& b) const |
5688 { | 5688 { |
5689 int info; double rcond; | 5689 octave_idx_type info; double rcond; |
5690 return solve (b, info, rcond); | 5690 return solve (b, info, rcond); |
5691 } | 5691 } |
5692 | 5692 |
5693 ColumnVector | 5693 ColumnVector |
5694 SparseMatrix::solve (const ColumnVector& b, int& info) const | 5694 SparseMatrix::solve (const ColumnVector& b, octave_idx_type& info) const |
5695 { | 5695 { |
5696 double rcond; | 5696 double rcond; |
5697 return solve (b, info, rcond); | 5697 return solve (b, info, rcond); |
5698 } | 5698 } |
5699 | 5699 |
5700 ColumnVector | 5700 ColumnVector |
5701 SparseMatrix::solve (const ColumnVector& b, int& info, double& rcond) const | 5701 SparseMatrix::solve (const ColumnVector& b, octave_idx_type& info, double& rcond) const |
5702 { | 5702 { |
5703 return solve (b, info, rcond, 0); | 5703 return solve (b, info, rcond, 0); |
5704 } | 5704 } |
5705 | 5705 |
5706 ColumnVector | 5706 ColumnVector |
5707 SparseMatrix::solve (const ColumnVector& b, int& info, double& rcond, | 5707 SparseMatrix::solve (const ColumnVector& b, octave_idx_type& info, double& rcond, |
5708 solve_singularity_handler sing_handler) const | 5708 solve_singularity_handler sing_handler) const |
5709 { | 5709 { |
5710 Matrix tmp (b); | 5710 Matrix tmp (b); |
5711 return solve (tmp, info, rcond, sing_handler).column (0); | 5711 return solve (tmp, info, rcond, sing_handler).column (static_cast<octave_idx_type> (0)); |
5712 } | 5712 } |
5713 | 5713 |
5714 ComplexColumnVector | 5714 ComplexColumnVector |
5715 SparseMatrix::solve (const ComplexColumnVector& b) const | 5715 SparseMatrix::solve (const ComplexColumnVector& b) const |
5716 { | 5716 { |
5717 int info; | 5717 octave_idx_type info; |
5718 double rcond; | 5718 double rcond; |
5719 return solve (b, info, rcond, 0); | 5719 return solve (b, info, rcond, 0); |
5720 } | 5720 } |
5721 | 5721 |
5722 ComplexColumnVector | 5722 ComplexColumnVector |
5723 SparseMatrix::solve (const ComplexColumnVector& b, int& info) const | 5723 SparseMatrix::solve (const ComplexColumnVector& b, octave_idx_type& info) const |
5724 { | 5724 { |
5725 double rcond; | 5725 double rcond; |
5726 return solve (b, info, rcond, 0); | 5726 return solve (b, info, rcond, 0); |
5727 } | 5727 } |
5728 | 5728 |
5729 ComplexColumnVector | 5729 ComplexColumnVector |
5730 SparseMatrix::solve (const ComplexColumnVector& b, int& info, | 5730 SparseMatrix::solve (const ComplexColumnVector& b, octave_idx_type& info, |
5731 double& rcond) const | 5731 double& rcond) const |
5732 { | 5732 { |
5733 return solve (b, info, rcond, 0); | 5733 return solve (b, info, rcond, 0); |
5734 } | 5734 } |
5735 | 5735 |
5736 ComplexColumnVector | 5736 ComplexColumnVector |
5737 SparseMatrix::solve (const ComplexColumnVector& b, int& info, double& rcond, | 5737 SparseMatrix::solve (const ComplexColumnVector& b, octave_idx_type& info, double& rcond, |
5738 solve_singularity_handler sing_handler) const | 5738 solve_singularity_handler sing_handler) const |
5739 { | 5739 { |
5740 ComplexMatrix tmp (b); | 5740 ComplexMatrix tmp (b); |
5741 return solve (tmp, info, rcond, sing_handler).column (0); | 5741 return solve (tmp, info, rcond, sing_handler).column (static_cast<octave_idx_type> (0)); |
5742 } | 5742 } |
5743 | 5743 |
5744 Matrix | 5744 Matrix |
5745 SparseMatrix::lssolve (const Matrix& b) const | 5745 SparseMatrix::lssolve (const Matrix& b) const |
5746 { | 5746 { |
5747 int info; | 5747 octave_idx_type info; |
5748 int rank; | 5748 octave_idx_type rank; |
5749 return lssolve (b, info, rank); | 5749 return lssolve (b, info, rank); |
5750 } | 5750 } |
5751 | 5751 |
5752 Matrix | 5752 Matrix |
5753 SparseMatrix::lssolve (const Matrix& b, int& info) const | 5753 SparseMatrix::lssolve (const Matrix& b, octave_idx_type& info) const |
5754 { | 5754 { |
5755 int rank; | 5755 octave_idx_type rank; |
5756 return lssolve (b, info, rank); | 5756 return lssolve (b, info, rank); |
5757 } | 5757 } |
5758 | 5758 |
5759 Matrix | 5759 Matrix |
5760 SparseMatrix::lssolve (const Matrix& b, int& info, int& rank) const | 5760 SparseMatrix::lssolve (const Matrix& b, octave_idx_type& info, octave_idx_type& rank) const |
5761 { | 5761 { |
5762 info = -1; | 5762 info = -1; |
5763 (*current_liboctave_error_handler) | 5763 (*current_liboctave_error_handler) |
5764 ("SparseMatrix::lssolve not implemented yet"); | 5764 ("SparseMatrix::lssolve not implemented yet"); |
5765 return Matrix (); | 5765 return Matrix (); |
5766 } | 5766 } |
5767 | 5767 |
5768 SparseMatrix | 5768 SparseMatrix |
5769 SparseMatrix::lssolve (const SparseMatrix& b) const | 5769 SparseMatrix::lssolve (const SparseMatrix& b) const |
5770 { | 5770 { |
5771 int info; | 5771 octave_idx_type info; |
5772 int rank; | 5772 octave_idx_type rank; |
5773 return lssolve (b, info, rank); | 5773 return lssolve (b, info, rank); |
5774 } | 5774 } |
5775 | 5775 |
5776 SparseMatrix | 5776 SparseMatrix |
5777 SparseMatrix::lssolve (const SparseMatrix& b, int& info) const | 5777 SparseMatrix::lssolve (const SparseMatrix& b, octave_idx_type& info) const |
5778 { | 5778 { |
5779 int rank; | 5779 octave_idx_type rank; |
5780 return lssolve (b, info, rank); | 5780 return lssolve (b, info, rank); |
5781 } | 5781 } |
5782 | 5782 |
5783 SparseMatrix | 5783 SparseMatrix |
5784 SparseMatrix::lssolve (const SparseMatrix& b, int& info, int& rank) const | 5784 SparseMatrix::lssolve (const SparseMatrix& b, octave_idx_type& info, octave_idx_type& rank) const |
5785 { | 5785 { |
5786 info = -1; | 5786 info = -1; |
5787 (*current_liboctave_error_handler) | 5787 (*current_liboctave_error_handler) |
5788 ("SparseMatrix::lssolve not implemented yet"); | 5788 ("SparseMatrix::lssolve not implemented yet"); |
5789 return SparseMatrix (); | 5789 return SparseMatrix (); |
5790 } | 5790 } |
5791 | 5791 |
5792 ComplexMatrix | 5792 ComplexMatrix |
5793 SparseMatrix::lssolve (const ComplexMatrix& b) const | 5793 SparseMatrix::lssolve (const ComplexMatrix& b) const |
5794 { | 5794 { |
5795 int info; | 5795 octave_idx_type info; |
5796 int rank; | 5796 octave_idx_type rank; |
5797 return lssolve (b, info, rank); | 5797 return lssolve (b, info, rank); |
5798 } | 5798 } |
5799 | 5799 |
5800 ComplexMatrix | 5800 ComplexMatrix |
5801 SparseMatrix::lssolve (const ComplexMatrix& b, int& info) const | 5801 SparseMatrix::lssolve (const ComplexMatrix& b, octave_idx_type& info) const |
5802 { | 5802 { |
5803 int rank; | 5803 octave_idx_type rank; |
5804 return lssolve (b, info, rank); | 5804 return lssolve (b, info, rank); |
5805 } | 5805 } |
5806 | 5806 |
5807 ComplexMatrix | 5807 ComplexMatrix |
5808 SparseMatrix::lssolve (const ComplexMatrix& b, int& info, int& rank) const | 5808 SparseMatrix::lssolve (const ComplexMatrix& b, octave_idx_type& info, octave_idx_type& rank) const |
5809 { | 5809 { |
5810 info = -1; | 5810 info = -1; |
5811 (*current_liboctave_error_handler) | 5811 (*current_liboctave_error_handler) |
5812 ("SparseMatrix::lssolve not implemented yet"); | 5812 ("SparseMatrix::lssolve not implemented yet"); |
5813 return ComplexMatrix (); | 5813 return ComplexMatrix (); |
5814 } | 5814 } |
5815 | 5815 |
5816 SparseComplexMatrix | 5816 SparseComplexMatrix |
5817 SparseMatrix::lssolve (const SparseComplexMatrix& b) const | 5817 SparseMatrix::lssolve (const SparseComplexMatrix& b) const |
5818 { | 5818 { |
5819 int info; | 5819 octave_idx_type info; |
5820 int rank; | 5820 octave_idx_type rank; |
5821 return lssolve (b, info, rank); | 5821 return lssolve (b, info, rank); |
5822 } | 5822 } |
5823 | 5823 |
5824 SparseComplexMatrix | 5824 SparseComplexMatrix |
5825 SparseMatrix::lssolve (const SparseComplexMatrix& b, int& info) const | 5825 SparseMatrix::lssolve (const SparseComplexMatrix& b, octave_idx_type& info) const |
5826 { | 5826 { |
5827 int rank; | 5827 octave_idx_type rank; |
5828 return lssolve (b, info, rank); | 5828 return lssolve (b, info, rank); |
5829 } | 5829 } |
5830 | 5830 |
5831 SparseComplexMatrix | 5831 SparseComplexMatrix |
5832 SparseMatrix::lssolve (const SparseComplexMatrix& b, int& info, | 5832 SparseMatrix::lssolve (const SparseComplexMatrix& b, octave_idx_type& info, |
5833 int& rank) const | 5833 octave_idx_type& rank) const |
5834 { | 5834 { |
5835 info = -1; | 5835 info = -1; |
5836 (*current_liboctave_error_handler) | 5836 (*current_liboctave_error_handler) |
5837 ("SparseMatrix::lssolve not implemented yet"); | 5837 ("SparseMatrix::lssolve not implemented yet"); |
5838 return SparseComplexMatrix (); | 5838 return SparseComplexMatrix (); |
5839 } | 5839 } |
5840 | 5840 |
5841 ColumnVector | 5841 ColumnVector |
5842 SparseMatrix::lssolve (const ColumnVector& b) const | 5842 SparseMatrix::lssolve (const ColumnVector& b) const |
5843 { | 5843 { |
5844 int info; | 5844 octave_idx_type info; |
5845 int rank; | 5845 octave_idx_type rank; |
5846 return lssolve (b, info, rank); | 5846 return lssolve (b, info, rank); |
5847 } | 5847 } |
5848 | 5848 |
5849 ColumnVector | 5849 ColumnVector |
5850 SparseMatrix::lssolve (const ColumnVector& b, int& info) const | 5850 SparseMatrix::lssolve (const ColumnVector& b, octave_idx_type& info) const |
5851 { | 5851 { |
5852 int rank; | 5852 octave_idx_type rank; |
5853 return lssolve (b, info, rank); | 5853 return lssolve (b, info, rank); |
5854 } | 5854 } |
5855 | 5855 |
5856 ColumnVector | 5856 ColumnVector |
5857 SparseMatrix::lssolve (const ColumnVector& b, int& info, int& rank) const | 5857 SparseMatrix::lssolve (const ColumnVector& b, octave_idx_type& info, octave_idx_type& rank) const |
5858 { | 5858 { |
5859 Matrix tmp (b); | 5859 Matrix tmp (b); |
5860 return lssolve (tmp, info, rank).column (0); | 5860 return lssolve (tmp, info, rank).column (static_cast<octave_idx_type> (0)); |
5861 } | 5861 } |
5862 | 5862 |
5863 ComplexColumnVector | 5863 ComplexColumnVector |
5864 SparseMatrix::lssolve (const ComplexColumnVector& b) const | 5864 SparseMatrix::lssolve (const ComplexColumnVector& b) const |
5865 { | 5865 { |
5866 int info; | 5866 octave_idx_type info; |
5867 int rank; | 5867 octave_idx_type rank; |
5868 return lssolve (b, info, rank); | 5868 return lssolve (b, info, rank); |
5869 } | 5869 } |
5870 | 5870 |
5871 ComplexColumnVector | 5871 ComplexColumnVector |
5872 SparseMatrix::lssolve (const ComplexColumnVector& b, int& info) const | 5872 SparseMatrix::lssolve (const ComplexColumnVector& b, octave_idx_type& info) const |
5873 { | 5873 { |
5874 int rank; | 5874 octave_idx_type rank; |
5875 return lssolve (b, info, rank); | 5875 return lssolve (b, info, rank); |
5876 } | 5876 } |
5877 | 5877 |
5878 ComplexColumnVector | 5878 ComplexColumnVector |
5879 SparseMatrix::lssolve (const ComplexColumnVector& b, int& info, | 5879 SparseMatrix::lssolve (const ComplexColumnVector& b, octave_idx_type& info, |
5880 int& rank) const | 5880 octave_idx_type& rank) const |
5881 { | 5881 { |
5882 ComplexMatrix tmp (b); | 5882 ComplexMatrix tmp (b); |
5883 return lssolve (tmp, info, rank).column (0); | 5883 return lssolve (tmp, info, rank).column (static_cast<octave_idx_type> (0)); |
5884 } | 5884 } |
5885 | 5885 |
5886 // other operations. | 5886 // other operations. |
5887 | 5887 |
5888 SparseMatrix | 5888 SparseMatrix |
5889 SparseMatrix::map (d_d_Mapper f) const | 5889 SparseMatrix::map (d_d_Mapper f) const |
5890 { | 5890 { |
5891 int nr = rows (); | 5891 octave_idx_type nr = rows (); |
5892 int nc = cols (); | 5892 octave_idx_type nc = cols (); |
5893 int nz = nnz (); | 5893 octave_idx_type nz = nnz (); |
5894 bool f_zero = (f(0.0) == 0.0); | 5894 bool f_zero = (f(0.0) == 0.0); |
5895 | 5895 |
5896 // Count number of non-zero elements | 5896 // Count number of non-zero elements |
5897 int nel = (f_zero ? 0 : nr*nc - nz); | 5897 octave_idx_type nel = (f_zero ? 0 : nr*nc - nz); |
5898 for (int i = 0; i < nz; i++) | 5898 for (octave_idx_type i = 0; i < nz; i++) |
5899 if (f (data(i)) != 0.0) | 5899 if (f (data(i)) != 0.0) |
5900 nel++; | 5900 nel++; |
5901 | 5901 |
5902 SparseMatrix retval (nr, nc, nel); | 5902 SparseMatrix retval (nr, nc, nel); |
5903 | 5903 |
5904 if (f_zero) | 5904 if (f_zero) |
5905 { | 5905 { |
5906 int ii = 0; | 5906 octave_idx_type ii = 0; |
5907 for (int j = 0; j < nc; j++) | 5907 for (octave_idx_type j = 0; j < nc; j++) |
5908 { | 5908 { |
5909 for (int i = 0; i < nr; i++) | 5909 for (octave_idx_type i = 0; i < nr; i++) |
5910 { | 5910 { |
5911 double tmp = f (elem (i, j)); | 5911 double tmp = f (elem (i, j)); |
5912 if (tmp != 0.0) | 5912 if (tmp != 0.0) |
5913 { | 5913 { |
5914 retval.data(ii) = tmp; | 5914 retval.data(ii) = tmp; |
5918 retval.cidx(j+1) = ii; | 5918 retval.cidx(j+1) = ii; |
5919 } | 5919 } |
5920 } | 5920 } |
5921 else | 5921 else |
5922 { | 5922 { |
5923 int ii = 0; | 5923 octave_idx_type ii = 0; |
5924 for (int j = 0; j < nc; j++) | 5924 for (octave_idx_type j = 0; j < nc; j++) |
5925 { | 5925 { |
5926 for (int i = cidx(j); i < cidx(j+1); i++) | 5926 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
5927 { | 5927 { |
5928 retval.data(ii) = f (elem(i)); | 5928 retval.data(ii) = f (elem(i)); |
5929 retval.ridx(ii++) = ridx(i); | 5929 retval.ridx(ii++) = ridx(i); |
5930 } | 5930 } |
5931 retval.cidx(j+1) = ii; | 5931 retval.cidx(j+1) = ii; |
5936 } | 5936 } |
5937 | 5937 |
5938 SparseBoolMatrix | 5938 SparseBoolMatrix |
5939 SparseMatrix::map (b_d_Mapper f) const | 5939 SparseMatrix::map (b_d_Mapper f) const |
5940 { | 5940 { |
5941 int nr = rows (); | 5941 octave_idx_type nr = rows (); |
5942 int nc = cols (); | 5942 octave_idx_type nc = cols (); |
5943 int nz = nnz (); | 5943 octave_idx_type nz = nnz (); |
5944 bool f_zero = f(0.0); | 5944 bool f_zero = f(0.0); |
5945 | 5945 |
5946 // Count number of non-zero elements | 5946 // Count number of non-zero elements |
5947 int nel = (f_zero ? 0 : nr*nc - nz); | 5947 octave_idx_type nel = (f_zero ? 0 : nr*nc - nz); |
5948 for (int i = 0; i < nz; i++) | 5948 for (octave_idx_type i = 0; i < nz; i++) |
5949 if (f (data(i)) != 0.0) | 5949 if (f (data(i)) != 0.0) |
5950 nel++; | 5950 nel++; |
5951 | 5951 |
5952 SparseBoolMatrix retval (nr, nc, nel); | 5952 SparseBoolMatrix retval (nr, nc, nel); |
5953 | 5953 |
5954 if (f_zero) | 5954 if (f_zero) |
5955 { | 5955 { |
5956 int ii = 0; | 5956 octave_idx_type ii = 0; |
5957 for (int j = 0; j < nc; j++) | 5957 for (octave_idx_type j = 0; j < nc; j++) |
5958 { | 5958 { |
5959 for (int i = 0; i < nr; i++) | 5959 for (octave_idx_type i = 0; i < nr; i++) |
5960 { | 5960 { |
5961 bool tmp = f (elem (i, j)); | 5961 bool tmp = f (elem (i, j)); |
5962 if (tmp) | 5962 if (tmp) |
5963 { | 5963 { |
5964 retval.data(ii) = tmp; | 5964 retval.data(ii) = tmp; |
5968 retval.cidx(j+1) = ii; | 5968 retval.cidx(j+1) = ii; |
5969 } | 5969 } |
5970 } | 5970 } |
5971 else | 5971 else |
5972 { | 5972 { |
5973 int ii = 0; | 5973 octave_idx_type ii = 0; |
5974 for (int j = 0; j < nc; j++) | 5974 for (octave_idx_type j = 0; j < nc; j++) |
5975 { | 5975 { |
5976 for (int i = cidx(j); i < cidx(j+1); i++) | 5976 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
5977 { | 5977 { |
5978 retval.data(ii) = f (elem(i)); | 5978 retval.data(ii) = f (elem(i)); |
5979 retval.ridx(ii++) = ridx(i); | 5979 retval.ridx(ii++) = ridx(i); |
5980 } | 5980 } |
5981 retval.cidx(j+1) = ii; | 5981 retval.cidx(j+1) = ii; |
5993 } | 5993 } |
5994 | 5994 |
5995 bool | 5995 bool |
5996 SparseMatrix::any_element_is_negative (bool neg_zero) const | 5996 SparseMatrix::any_element_is_negative (bool neg_zero) const |
5997 { | 5997 { |
5998 int nel = nnz (); | 5998 octave_idx_type nel = nnz (); |
5999 | 5999 |
6000 if (neg_zero) | 6000 if (neg_zero) |
6001 { | 6001 { |
6002 for (int i = 0; i < nel; i++) | 6002 for (octave_idx_type i = 0; i < nel; i++) |
6003 if (lo_ieee_signbit (data (i))) | 6003 if (lo_ieee_signbit (data (i))) |
6004 return true; | 6004 return true; |
6005 } | 6005 } |
6006 else | 6006 else |
6007 { | 6007 { |
6008 for (int i = 0; i < nel; i++) | 6008 for (octave_idx_type i = 0; i < nel; i++) |
6009 if (data (i) < 0) | 6009 if (data (i) < 0) |
6010 return true; | 6010 return true; |
6011 } | 6011 } |
6012 | 6012 |
6013 return false; | 6013 return false; |
6014 } | 6014 } |
6015 | 6015 |
6016 bool | 6016 bool |
6017 SparseMatrix::any_element_is_inf_or_nan (void) const | 6017 SparseMatrix::any_element_is_inf_or_nan (void) const |
6018 { | 6018 { |
6019 int nel = nnz (); | 6019 octave_idx_type nel = nnz (); |
6020 | 6020 |
6021 for (int i = 0; i < nel; i++) | 6021 for (octave_idx_type i = 0; i < nel; i++) |
6022 { | 6022 { |
6023 double val = data (i); | 6023 double val = data (i); |
6024 if (xisinf (val) || xisnan (val)) | 6024 if (xisinf (val) || xisnan (val)) |
6025 return true; | 6025 return true; |
6026 } | 6026 } |
6029 } | 6029 } |
6030 | 6030 |
6031 bool | 6031 bool |
6032 SparseMatrix::all_elements_are_int_or_inf_or_nan (void) const | 6032 SparseMatrix::all_elements_are_int_or_inf_or_nan (void) const |
6033 { | 6033 { |
6034 int nel = nnz (); | 6034 octave_idx_type nel = nnz (); |
6035 | 6035 |
6036 for (int i = 0; i < nel; i++) | 6036 for (octave_idx_type i = 0; i < nel; i++) |
6037 { | 6037 { |
6038 double val = data (i); | 6038 double val = data (i); |
6039 if (xisnan (val) || D_NINT (val) == val) | 6039 if (xisnan (val) || D_NINT (val) == val) |
6040 continue; | 6040 continue; |
6041 else | 6041 else |
6049 // the largest and smallest values and return them in MAX_VAL and MIN_VAL. | 6049 // the largest and smallest values and return them in MAX_VAL and MIN_VAL. |
6050 | 6050 |
6051 bool | 6051 bool |
6052 SparseMatrix::all_integers (double& max_val, double& min_val) const | 6052 SparseMatrix::all_integers (double& max_val, double& min_val) const |
6053 { | 6053 { |
6054 int nel = nnz (); | 6054 octave_idx_type nel = nnz (); |
6055 | 6055 |
6056 if (nel == 0) | 6056 if (nel == 0) |
6057 return false; | 6057 return false; |
6058 | 6058 |
6059 max_val = data (0); | 6059 max_val = data (0); |
6060 min_val = data (0); | 6060 min_val = data (0); |
6061 | 6061 |
6062 for (int i = 0; i < nel; i++) | 6062 for (octave_idx_type i = 0; i < nel; i++) |
6063 { | 6063 { |
6064 double val = data (i); | 6064 double val = data (i); |
6065 | 6065 |
6066 if (val > max_val) | 6066 if (val > max_val) |
6067 max_val = val; | 6067 max_val = val; |
6077 } | 6077 } |
6078 | 6078 |
6079 bool | 6079 bool |
6080 SparseMatrix::too_large_for_float (void) const | 6080 SparseMatrix::too_large_for_float (void) const |
6081 { | 6081 { |
6082 int nel = nnz (); | 6082 octave_idx_type nel = nnz (); |
6083 | 6083 |
6084 for (int i = 0; i < nel; i++) | 6084 for (octave_idx_type i = 0; i < nel; i++) |
6085 { | 6085 { |
6086 double val = data (i); | 6086 double val = data (i); |
6087 | 6087 |
6088 if (val > FLT_MAX || val < FLT_MIN) | 6088 if (val > FLT_MAX || val < FLT_MIN) |
6089 return true; | 6089 return true; |
6093 } | 6093 } |
6094 | 6094 |
6095 SparseBoolMatrix | 6095 SparseBoolMatrix |
6096 SparseMatrix::operator ! (void) const | 6096 SparseMatrix::operator ! (void) const |
6097 { | 6097 { |
6098 int nr = rows (); | 6098 octave_idx_type nr = rows (); |
6099 int nc = cols (); | 6099 octave_idx_type nc = cols (); |
6100 int nz1 = nnz (); | 6100 octave_idx_type nz1 = nnz (); |
6101 int nz2 = nr*nc - nz1; | 6101 octave_idx_type nz2 = nr*nc - nz1; |
6102 | 6102 |
6103 SparseBoolMatrix r (nr, nc, nz2); | 6103 SparseBoolMatrix r (nr, nc, nz2); |
6104 | 6104 |
6105 int ii = 0; | 6105 octave_idx_type ii = 0; |
6106 int jj = 0; | 6106 octave_idx_type jj = 0; |
6107 r.cidx (0) = 0; | 6107 r.cidx (0) = 0; |
6108 for (int i = 0; i < nc; i++) | 6108 for (octave_idx_type i = 0; i < nc; i++) |
6109 { | 6109 { |
6110 for (int j = 0; j < nr; j++) | 6110 for (octave_idx_type j = 0; j < nr; j++) |
6111 { | 6111 { |
6112 if (jj < cidx(i+1) && ridx(jj) == j) | 6112 if (jj < cidx(i+1) && ridx(jj) == j) |
6113 jj++; | 6113 jj++; |
6114 else | 6114 else |
6115 { | 6115 { |
6181 } | 6181 } |
6182 | 6182 |
6183 SparseMatrix | 6183 SparseMatrix |
6184 SparseMatrix::abs (void) const | 6184 SparseMatrix::abs (void) const |
6185 { | 6185 { |
6186 int nz = nnz (); | 6186 octave_idx_type nz = nnz (); |
6187 | 6187 |
6188 SparseMatrix retval (*this); | 6188 SparseMatrix retval (*this); |
6189 | 6189 |
6190 for (int i = 0; i < nz; i++) | 6190 for (octave_idx_type i = 0; i < nz; i++) |
6191 retval.data(i) = fabs(retval.data(i)); | 6191 retval.data(i) = fabs(retval.data(i)); |
6192 | 6192 |
6193 return retval; | 6193 return retval; |
6194 } | 6194 } |
6195 | 6195 |
6196 SparseMatrix | 6196 SparseMatrix |
6197 SparseMatrix::diag (int k) const | 6197 SparseMatrix::diag (octave_idx_type k) const |
6198 { | 6198 { |
6199 int nnr = rows (); | 6199 octave_idx_type nnr = rows (); |
6200 int nnc = cols (); | 6200 octave_idx_type nnc = cols (); |
6201 | 6201 |
6202 if (k > 0) | 6202 if (k > 0) |
6203 nnc -= k; | 6203 nnc -= k; |
6204 else if (k < 0) | 6204 else if (k < 0) |
6205 nnr += k; | 6205 nnr += k; |
6206 | 6206 |
6207 SparseMatrix d; | 6207 SparseMatrix d; |
6208 | 6208 |
6209 if (nnr > 0 && nnc > 0) | 6209 if (nnr > 0 && nnc > 0) |
6210 { | 6210 { |
6211 int ndiag = (nnr < nnc) ? nnr : nnc; | 6211 octave_idx_type ndiag = (nnr < nnc) ? nnr : nnc; |
6212 | 6212 |
6213 // Count the number of non-zero elements | 6213 // Count the number of non-zero elements |
6214 int nel = 0; | 6214 octave_idx_type nel = 0; |
6215 if (k > 0) | 6215 if (k > 0) |
6216 { | 6216 { |
6217 for (int i = 0; i < ndiag; i++) | 6217 for (octave_idx_type i = 0; i < ndiag; i++) |
6218 if (elem (i, i+k) != 0.) | 6218 if (elem (i, i+k) != 0.) |
6219 nel++; | 6219 nel++; |
6220 } | 6220 } |
6221 else if ( k < 0) | 6221 else if ( k < 0) |
6222 { | 6222 { |
6223 for (int i = 0; i < ndiag; i++) | 6223 for (octave_idx_type i = 0; i < ndiag; i++) |
6224 if (elem (i-k, i) != 0.) | 6224 if (elem (i-k, i) != 0.) |
6225 nel++; | 6225 nel++; |
6226 } | 6226 } |
6227 else | 6227 else |
6228 { | 6228 { |
6229 for (int i = 0; i < ndiag; i++) | 6229 for (octave_idx_type i = 0; i < ndiag; i++) |
6230 if (elem (i, i) != 0.) | 6230 if (elem (i, i) != 0.) |
6231 nel++; | 6231 nel++; |
6232 } | 6232 } |
6233 | 6233 |
6234 d = SparseMatrix (ndiag, 1, nel); | 6234 d = SparseMatrix (ndiag, 1, nel); |
6235 d.xcidx (0) = 0; | 6235 d.xcidx (0) = 0; |
6236 d.xcidx (1) = nel; | 6236 d.xcidx (1) = nel; |
6237 | 6237 |
6238 int ii = 0; | 6238 octave_idx_type ii = 0; |
6239 if (k > 0) | 6239 if (k > 0) |
6240 { | 6240 { |
6241 for (int i = 0; i < ndiag; i++) | 6241 for (octave_idx_type i = 0; i < ndiag; i++) |
6242 { | 6242 { |
6243 double tmp = elem (i, i+k); | 6243 double tmp = elem (i, i+k); |
6244 if (tmp != 0.) | 6244 if (tmp != 0.) |
6245 { | 6245 { |
6246 d.xdata (ii) = tmp; | 6246 d.xdata (ii) = tmp; |
6248 } | 6248 } |
6249 } | 6249 } |
6250 } | 6250 } |
6251 else if ( k < 0) | 6251 else if ( k < 0) |
6252 { | 6252 { |
6253 for (int i = 0; i < ndiag; i++) | 6253 for (octave_idx_type i = 0; i < ndiag; i++) |
6254 { | 6254 { |
6255 double tmp = elem (i-k, i); | 6255 double tmp = elem (i-k, i); |
6256 if (tmp != 0.) | 6256 if (tmp != 0.) |
6257 { | 6257 { |
6258 d.xdata (ii) = tmp; | 6258 d.xdata (ii) = tmp; |
6260 } | 6260 } |
6261 } | 6261 } |
6262 } | 6262 } |
6263 else | 6263 else |
6264 { | 6264 { |
6265 for (int i = 0; i < ndiag; i++) | 6265 for (octave_idx_type i = 0; i < ndiag; i++) |
6266 { | 6266 { |
6267 double tmp = elem (i, i); | 6267 double tmp = elem (i, i); |
6268 if (tmp != 0.) | 6268 if (tmp != 0.) |
6269 { | 6269 { |
6270 d.xdata (ii) = tmp; | 6270 d.xdata (ii) = tmp; |
6281 } | 6281 } |
6282 | 6282 |
6283 Matrix | 6283 Matrix |
6284 SparseMatrix::matrix_value (void) const | 6284 SparseMatrix::matrix_value (void) const |
6285 { | 6285 { |
6286 int nr = rows (); | 6286 octave_idx_type nr = rows (); |
6287 int nc = cols (); | 6287 octave_idx_type nc = cols (); |
6288 | 6288 |
6289 Matrix retval (nr, nc, 0.0); | 6289 Matrix retval (nr, nc, 0.0); |
6290 for (int j = 0; j < nc; j++) | 6290 for (octave_idx_type j = 0; j < nc; j++) |
6291 for (int i = cidx(j); i < cidx(j+1); i++) | 6291 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
6292 retval.elem (ridx(i), j) = data (i); | 6292 retval.elem (ridx(i), j) = data (i); |
6293 | 6293 |
6294 return retval; | 6294 return retval; |
6295 } | 6295 } |
6296 | 6296 |
6297 std::ostream& | 6297 std::ostream& |
6298 operator << (std::ostream& os, const SparseMatrix& a) | 6298 operator << (std::ostream& os, const SparseMatrix& a) |
6299 { | 6299 { |
6300 int nc = a.cols (); | 6300 octave_idx_type nc = a.cols (); |
6301 | 6301 |
6302 // add one to the printed indices to go from | 6302 // add one to the printed indices to go from |
6303 // zero-based to one-based arrays | 6303 // zero-based to one-based arrays |
6304 for (int j = 0; j < nc; j++) { | 6304 for (octave_idx_type j = 0; j < nc; j++) { |
6305 OCTAVE_QUIT; | 6305 OCTAVE_QUIT; |
6306 for (int i = a.cidx(j); i < a.cidx(j+1); i++) { | 6306 for (octave_idx_type i = a.cidx(j); i < a.cidx(j+1); i++) { |
6307 os << a.ridx(i) + 1 << " " << j + 1 << " "; | 6307 os << a.ridx(i) + 1 << " " << j + 1 << " "; |
6308 octave_write_double (os, a.data(i)); | 6308 octave_write_double (os, a.data(i)); |
6309 os << "\n"; | 6309 os << "\n"; |
6310 } | 6310 } |
6311 } | 6311 } |
6314 } | 6314 } |
6315 | 6315 |
6316 std::istream& | 6316 std::istream& |
6317 operator >> (std::istream& is, SparseMatrix& a) | 6317 operator >> (std::istream& is, SparseMatrix& a) |
6318 { | 6318 { |
6319 int nr = a.rows (); | 6319 octave_idx_type nr = a.rows (); |
6320 int nc = a.cols (); | 6320 octave_idx_type nc = a.cols (); |
6321 int nz = a.nnz (); | 6321 octave_idx_type nz = a.nnz (); |
6322 | 6322 |
6323 if (nr < 1 || nc < 1) | 6323 if (nr < 1 || nc < 1) |
6324 is.clear (std::ios::badbit); | 6324 is.clear (std::ios::badbit); |
6325 else | 6325 else |
6326 { | 6326 { |
6327 int itmp, jtmp, jold = 0; | 6327 octave_idx_type itmp, jtmp, jold = 0; |
6328 double tmp; | 6328 double tmp; |
6329 int ii = 0; | 6329 octave_idx_type ii = 0; |
6330 | 6330 |
6331 a.cidx (0) = 0; | 6331 a.cidx (0) = 0; |
6332 for (int i = 0; i < nz; i++) | 6332 for (octave_idx_type i = 0; i < nz; i++) |
6333 { | 6333 { |
6334 is >> itmp; | 6334 is >> itmp; |
6335 itmp--; | 6335 itmp--; |
6336 is >> jtmp; | 6336 is >> jtmp; |
6337 jtmp--; | 6337 jtmp--; |
6339 | 6339 |
6340 if (is) | 6340 if (is) |
6341 { | 6341 { |
6342 if (jold != jtmp) | 6342 if (jold != jtmp) |
6343 { | 6343 { |
6344 for (int j = jold; j < jtmp; j++) | 6344 for (octave_idx_type j = jold; j < jtmp; j++) |
6345 a.cidx(j+1) = ii; | 6345 a.cidx(j+1) = ii; |
6346 | 6346 |
6347 jold = jtmp; | 6347 jold = jtmp; |
6348 } | 6348 } |
6349 a.data (ii) = tmp; | 6349 a.data (ii) = tmp; |
6351 } | 6351 } |
6352 else | 6352 else |
6353 goto done; | 6353 goto done; |
6354 } | 6354 } |
6355 | 6355 |
6356 for (int j = jold; j < nc; j++) | 6356 for (octave_idx_type j = jold; j < nc; j++) |
6357 a.cidx(j+1) = ii; | 6357 a.cidx(j+1) = ii; |
6358 } | 6358 } |
6359 | 6359 |
6360 done: | 6360 done: |
6361 | 6361 |
6391 { | 6391 { |
6392 return MSparse<double>::reshape (new_dims); | 6392 return MSparse<double>::reshape (new_dims); |
6393 } | 6393 } |
6394 | 6394 |
6395 SparseMatrix | 6395 SparseMatrix |
6396 SparseMatrix::permute (const Array<int>& vec, bool inv) const | 6396 SparseMatrix::permute (const Array<octave_idx_type>& vec, bool inv) const |
6397 { | 6397 { |
6398 return MSparse<double>::permute (vec, inv); | 6398 return MSparse<double>::permute (vec, inv); |
6399 } | 6399 } |
6400 | 6400 |
6401 SparseMatrix | 6401 SparseMatrix |
6402 SparseMatrix::ipermute (const Array<int>& vec) const | 6402 SparseMatrix::ipermute (const Array<octave_idx_type>& vec) const |
6403 { | 6403 { |
6404 return MSparse<double>::ipermute (vec); | 6404 return MSparse<double>::ipermute (vec); |
6405 } | 6405 } |
6406 | 6406 |
6407 // matrix by matrix -> matrix operations | 6407 // matrix by matrix -> matrix operations |
6427 SparseMatrix | 6427 SparseMatrix |
6428 min (double d, const SparseMatrix& m) | 6428 min (double d, const SparseMatrix& m) |
6429 { | 6429 { |
6430 SparseMatrix result; | 6430 SparseMatrix result; |
6431 | 6431 |
6432 int nr = m.rows (); | 6432 octave_idx_type nr = m.rows (); |
6433 int nc = m.columns (); | 6433 octave_idx_type nc = m.columns (); |
6434 | 6434 |
6435 EMPTY_RETURN_CHECK (SparseMatrix); | 6435 EMPTY_RETURN_CHECK (SparseMatrix); |
6436 | 6436 |
6437 // Count the number of non-zero elements | 6437 // Count the number of non-zero elements |
6438 if (d < 0.) | 6438 if (d < 0.) |
6439 { | 6439 { |
6440 result = SparseMatrix (nr, nc, d); | 6440 result = SparseMatrix (nr, nc, d); |
6441 for (int j = 0; j < nc; j++) | 6441 for (octave_idx_type j = 0; j < nc; j++) |
6442 for (int i = m.cidx(j); i < m.cidx(j+1); i++) | 6442 for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++) |
6443 { | 6443 { |
6444 double tmp = xmin (d, m.data (i)); | 6444 double tmp = xmin (d, m.data (i)); |
6445 if (tmp != 0.) | 6445 if (tmp != 0.) |
6446 { | 6446 { |
6447 int idx = m.ridx(i) + j * nr; | 6447 octave_idx_type idx = m.ridx(i) + j * nr; |
6448 result.xdata(idx) = tmp; | 6448 result.xdata(idx) = tmp; |
6449 result.xridx(idx) = m.ridx(i); | 6449 result.xridx(idx) = m.ridx(i); |
6450 } | 6450 } |
6451 } | 6451 } |
6452 } | 6452 } |
6453 else | 6453 else |
6454 { | 6454 { |
6455 int nel = 0; | 6455 octave_idx_type nel = 0; |
6456 for (int j = 0; j < nc; j++) | 6456 for (octave_idx_type j = 0; j < nc; j++) |
6457 for (int i = m.cidx(j); i < m.cidx(j+1); i++) | 6457 for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++) |
6458 if (xmin (d, m.data (i)) != 0.) | 6458 if (xmin (d, m.data (i)) != 0.) |
6459 nel++; | 6459 nel++; |
6460 | 6460 |
6461 result = SparseMatrix (nr, nc, nel); | 6461 result = SparseMatrix (nr, nc, nel); |
6462 | 6462 |
6463 int ii = 0; | 6463 octave_idx_type ii = 0; |
6464 result.xcidx(0) = 0; | 6464 result.xcidx(0) = 0; |
6465 for (int j = 0; j < nc; j++) | 6465 for (octave_idx_type j = 0; j < nc; j++) |
6466 { | 6466 { |
6467 for (int i = m.cidx(j); i < m.cidx(j+1); i++) | 6467 for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++) |
6468 { | 6468 { |
6469 double tmp = xmin (d, m.data (i)); | 6469 double tmp = xmin (d, m.data (i)); |
6470 | 6470 |
6471 if (tmp != 0.) | 6471 if (tmp != 0.) |
6472 { | 6472 { |
6492 { | 6492 { |
6493 SparseMatrix r; | 6493 SparseMatrix r; |
6494 | 6494 |
6495 if ((a.rows() == b.rows()) && (a.cols() == b.cols())) | 6495 if ((a.rows() == b.rows()) && (a.cols() == b.cols())) |
6496 { | 6496 { |
6497 int a_nr = a.rows (); | 6497 octave_idx_type a_nr = a.rows (); |
6498 int a_nc = a.cols (); | 6498 octave_idx_type a_nc = a.cols (); |
6499 | 6499 |
6500 int b_nr = b.rows (); | 6500 octave_idx_type b_nr = b.rows (); |
6501 int b_nc = b.cols (); | 6501 octave_idx_type b_nc = b.cols (); |
6502 | 6502 |
6503 if (a_nr != b_nr || a_nc != b_nc) | 6503 if (a_nr != b_nr || a_nc != b_nc) |
6504 gripe_nonconformant ("min", a_nr, a_nc, b_nr, b_nc); | 6504 gripe_nonconformant ("min", a_nr, a_nc, b_nr, b_nc); |
6505 else | 6505 else |
6506 { | 6506 { |
6507 r = SparseMatrix (a_nr, a_nc, (a.nnz () + b.nnz ())); | 6507 r = SparseMatrix (a_nr, a_nc, (a.nnz () + b.nnz ())); |
6508 | 6508 |
6509 int jx = 0; | 6509 octave_idx_type jx = 0; |
6510 r.cidx (0) = 0; | 6510 r.cidx (0) = 0; |
6511 for (int i = 0 ; i < a_nc ; i++) | 6511 for (octave_idx_type i = 0 ; i < a_nc ; i++) |
6512 { | 6512 { |
6513 int ja = a.cidx(i); | 6513 octave_idx_type ja = a.cidx(i); |
6514 int ja_max = a.cidx(i+1); | 6514 octave_idx_type ja_max = a.cidx(i+1); |
6515 bool ja_lt_max= ja < ja_max; | 6515 bool ja_lt_max= ja < ja_max; |
6516 | 6516 |
6517 int jb = b.cidx(i); | 6517 octave_idx_type jb = b.cidx(i); |
6518 int jb_max = b.cidx(i+1); | 6518 octave_idx_type jb_max = b.cidx(i+1); |
6519 bool jb_lt_max = jb < jb_max; | 6519 bool jb_lt_max = jb < jb_max; |
6520 | 6520 |
6521 while (ja_lt_max || jb_lt_max ) | 6521 while (ja_lt_max || jb_lt_max ) |
6522 { | 6522 { |
6523 OCTAVE_QUIT; | 6523 OCTAVE_QUIT; |
6577 SparseMatrix | 6577 SparseMatrix |
6578 max (double d, const SparseMatrix& m) | 6578 max (double d, const SparseMatrix& m) |
6579 { | 6579 { |
6580 SparseMatrix result; | 6580 SparseMatrix result; |
6581 | 6581 |
6582 int nr = m.rows (); | 6582 octave_idx_type nr = m.rows (); |
6583 int nc = m.columns (); | 6583 octave_idx_type nc = m.columns (); |
6584 | 6584 |
6585 EMPTY_RETURN_CHECK (SparseMatrix); | 6585 EMPTY_RETURN_CHECK (SparseMatrix); |
6586 | 6586 |
6587 // Count the number of non-zero elements | 6587 // Count the number of non-zero elements |
6588 if (d > 0.) | 6588 if (d > 0.) |
6589 { | 6589 { |
6590 result = SparseMatrix (nr, nc, d); | 6590 result = SparseMatrix (nr, nc, d); |
6591 for (int j = 0; j < nc; j++) | 6591 for (octave_idx_type j = 0; j < nc; j++) |
6592 for (int i = m.cidx(j); i < m.cidx(j+1); i++) | 6592 for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++) |
6593 { | 6593 { |
6594 double tmp = xmax (d, m.data (i)); | 6594 double tmp = xmax (d, m.data (i)); |
6595 | 6595 |
6596 if (tmp != 0.) | 6596 if (tmp != 0.) |
6597 { | 6597 { |
6598 int idx = m.ridx(i) + j * nr; | 6598 octave_idx_type idx = m.ridx(i) + j * nr; |
6599 result.xdata(idx) = tmp; | 6599 result.xdata(idx) = tmp; |
6600 result.xridx(idx) = m.ridx(i); | 6600 result.xridx(idx) = m.ridx(i); |
6601 } | 6601 } |
6602 } | 6602 } |
6603 } | 6603 } |
6604 else | 6604 else |
6605 { | 6605 { |
6606 int nel = 0; | 6606 octave_idx_type nel = 0; |
6607 for (int j = 0; j < nc; j++) | 6607 for (octave_idx_type j = 0; j < nc; j++) |
6608 for (int i = m.cidx(j); i < m.cidx(j+1); i++) | 6608 for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++) |
6609 if (xmax (d, m.data (i)) != 0.) | 6609 if (xmax (d, m.data (i)) != 0.) |
6610 nel++; | 6610 nel++; |
6611 | 6611 |
6612 result = SparseMatrix (nr, nc, nel); | 6612 result = SparseMatrix (nr, nc, nel); |
6613 | 6613 |
6614 int ii = 0; | 6614 octave_idx_type ii = 0; |
6615 result.xcidx(0) = 0; | 6615 result.xcidx(0) = 0; |
6616 for (int j = 0; j < nc; j++) | 6616 for (octave_idx_type j = 0; j < nc; j++) |
6617 { | 6617 { |
6618 for (int i = m.cidx(j); i < m.cidx(j+1); i++) | 6618 for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++) |
6619 { | 6619 { |
6620 double tmp = xmax (d, m.data (i)); | 6620 double tmp = xmax (d, m.data (i)); |
6621 if (tmp != 0.) | 6621 if (tmp != 0.) |
6622 { | 6622 { |
6623 result.xdata(ii) = tmp; | 6623 result.xdata(ii) = tmp; |
6642 { | 6642 { |
6643 SparseMatrix r; | 6643 SparseMatrix r; |
6644 | 6644 |
6645 if ((a.rows() == b.rows()) && (a.cols() == b.cols())) | 6645 if ((a.rows() == b.rows()) && (a.cols() == b.cols())) |
6646 { | 6646 { |
6647 int a_nr = a.rows (); | 6647 octave_idx_type a_nr = a.rows (); |
6648 int a_nc = a.cols (); | 6648 octave_idx_type a_nc = a.cols (); |
6649 | 6649 |
6650 int b_nr = b.rows (); | 6650 octave_idx_type b_nr = b.rows (); |
6651 int b_nc = b.cols (); | 6651 octave_idx_type b_nc = b.cols (); |
6652 | 6652 |
6653 if (a_nr != b_nr || a_nc != b_nc) | 6653 if (a_nr != b_nr || a_nc != b_nc) |
6654 gripe_nonconformant ("min", a_nr, a_nc, b_nr, b_nc); | 6654 gripe_nonconformant ("min", a_nr, a_nc, b_nr, b_nc); |
6655 else | 6655 else |
6656 { | 6656 { |
6657 r = SparseMatrix (a_nr, a_nc, (a.nnz () + b.nnz ())); | 6657 r = SparseMatrix (a_nr, a_nc, (a.nnz () + b.nnz ())); |
6658 | 6658 |
6659 int jx = 0; | 6659 octave_idx_type jx = 0; |
6660 r.cidx (0) = 0; | 6660 r.cidx (0) = 0; |
6661 for (int i = 0 ; i < a_nc ; i++) | 6661 for (octave_idx_type i = 0 ; i < a_nc ; i++) |
6662 { | 6662 { |
6663 int ja = a.cidx(i); | 6663 octave_idx_type ja = a.cidx(i); |
6664 int ja_max = a.cidx(i+1); | 6664 octave_idx_type ja_max = a.cidx(i+1); |
6665 bool ja_lt_max= ja < ja_max; | 6665 bool ja_lt_max= ja < ja_max; |
6666 | 6666 |
6667 int jb = b.cidx(i); | 6667 octave_idx_type jb = b.cidx(i); |
6668 int jb_max = b.cidx(i+1); | 6668 octave_idx_type jb_max = b.cidx(i+1); |
6669 bool jb_lt_max = jb < jb_max; | 6669 bool jb_lt_max = jb < jb_max; |
6670 | 6670 |
6671 while (ja_lt_max || jb_lt_max ) | 6671 while (ja_lt_max || jb_lt_max ) |
6672 { | 6672 { |
6673 OCTAVE_QUIT; | 6673 OCTAVE_QUIT; |