• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

icsm-au / DynAdjust / 13494567994

24 Feb 2025 09:15AM UTC coverage: 81.168% (+2.0%) from 79.161%
13494567994

push

github

web-flow
Merge pull request #234 from icsm-au/1.2.8

Version 1.2.8 (fixes, ehnacements, improved datum management)

6131 of 8137 new or added lines in 90 files covered. (75.35%)

162 existing lines in 33 files now uncovered.

32214 of 39688 relevant lines covered (81.17%)

11775.25 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

76.02
/dynadjust/include/math/dnamatrix_contiguous.cpp
1
//============================================================================
2
// Name         : dnamatrix_contiguous.cpp
3
// Author       : Roger Fraser
4
// Contributors :
5
// Version      : 1.00
6
// Copyright    : Copyright 2017 Geoscience Australia
7
//
8
//                Licensed under the Apache License, Version 2.0 (the "License");
9
//                you may not use this file except in compliance with the License.
10
//                You may obtain a copy of the License at
11
//               
12
//                http ://www.apache.org/licenses/LICENSE-2.0
13
//               
14
//                Unless required by applicable law or agreed to in writing, software
15
//                distributed under the License is distributed on an "AS IS" BASIS,
16
//                WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
//                See the License for the specific language governing permissions and
18
//                limitations under the License.
19
//
20
// Description  : DynAdjust Matrix library
21
//                Matrices are stored as a contiguous 1 dimensional array [row * column]
22
//                Storage buffer is ordered column wise to achieve highest efficiency with
23
//                Intel MKL
24
//============================================================================
25

26
#include <include/math/dnamatrix_contiguous.hpp>
27

28
//#include <float.h>
29
//DBL_MIN;
30
//DBL_MAX;
31
//FLT_MIN;
32
//FLT_MAX;
33

34
//#include <limits>
35
//cout << "Float  max: " << numeric_limits<float>::max() << std::endl;
36
//cout << "Float  min: " << numeric_limits<float>::min() << std::endl;
37
//cout << "Double max: " << numeric_limits<double>::max() << std::endl;
38
//cout << "Double min: " << numeric_limits<double>::min() << std::endl;
39
//cout << "UINT16 max: " << numeric_limits<unsigned short>::min() << std::endl;
40
//cout << "UINT16 min: " << numeric_limits<unsigned short>::min() << std::endl;
41
//cout << "UINT32 max: " << numeric_limits<unsigned long>::min() << std::endl;
42
//cout << "UINT32 min: " << numeric_limits<unsigned long>::min() << std::endl;
43

44
namespace dynadjust { namespace math {        
45

46
std::ostream& operator<< (std::ostream& os, const matrix_2d& rhs)
389✔
47
{
48
        if (os.iword(0) == binary)
389✔
49
        {
50
                // Binary output
51
                
52
                // matrix type 
53
                os.write(reinterpret_cast<const char *>(&rhs._matrixType), sizeof(UINT32));
290✔
54
                
55
                // output rows and columns
56
                os.write(reinterpret_cast<const char *>(&rhs._rows), sizeof(UINT32));
290✔
57
                os.write(reinterpret_cast<const char *>(&rhs._cols), sizeof(UINT32));
290✔
58
                
59
                os.write(reinterpret_cast<const char *>(&rhs._mem_rows), sizeof(UINT32));
290✔
60
                os.write(reinterpret_cast<const char *>(&rhs._mem_cols), sizeof(UINT32));
290✔
61
                
62
                UINT32 c, r;
290✔
63

64
                switch (rhs._matrixType)
290✔
65
                {
66
                case mtx_lower:
54✔
67
                        // output lower triangular part of a square matrix
68
                        if (rhs._mem_rows != rhs._mem_cols)
54✔
NEW
69
                                throw boost::enable_current_exception(std::runtime_error("matrix_2d operator<< (): Matrix is not square."));
×
70
                        
71
                        // print each column
72
                        for (c=0; c<rhs._mem_cols; ++c)
4,212✔
73
                                os.write(reinterpret_cast<const char *>(rhs.getelementref(c, c)), (rhs._mem_rows - c) * sizeof(double));
4,158✔
74

75
                        break;
76
                case mtx_sparse:
77
                        break;
78
                case mtx_full:
79
                default:
80
                        // Output full matrix data
81
                        for (r=0; r<rhs._mem_rows; ++r)
17,833✔
82
                                for (c=0; c<rhs._mem_cols; ++c)
36,374✔
83
                                        os.write(reinterpret_cast<const char *>(rhs.getelementref(r,c)), sizeof(double));
18,777✔
84
                        break;
85
                }
86

87
                // output max value info
88
                os.write(reinterpret_cast<const char *>(&rhs._maxvalRow), sizeof(UINT32));
290✔
89
                os.write(reinterpret_cast<const char *>(&rhs._maxvalCol), sizeof(UINT32));
290✔
90
        }
91
        else
92
        {
93
                // ASCII output
94

95
                os << rhs._matrixType << " " << rhs._rows << " " << rhs._cols << " " << rhs._mem_rows << " " << rhs._mem_cols << std::endl;
99✔
96
                
97
                for (UINT32 c, r=0; r<rhs._mem_rows; ++r)  
33,564✔
98
                {
99
                        for (c=0; c<rhs._mem_cols; ++c) 
7,852,074✔
100
                                os << std::scientific << std::setprecision(16) << rhs.get(r,c) << " ";
7,818,609✔
101
                        os << std::endl;
33,465✔
102
                }
103
                os << rhs._maxvalRow << " " << rhs._maxvalCol << std::endl;
99✔
104
                os << std::endl;
99✔
105
        }
106
        return os;
389✔
107
}
108
        
109
// Commented IO operators which are useful but unused.
110
//ostream& operator<< (std::ostream& os, const matrix_2d* rhs)  
111
//{        
112
//        os << *rhs;
113
//        return os;
114
//}
115

116
//// Output to stream vectors of matrix_2d
117
//ostream& operator<< (std::ostream& os, const v_mat_2d& rhs)
118
//{
119
//        UINT32 vector_size(static_cast<UINT32>(rhs.size()));
120
//        if (os.iword(0) == binary)
121
//                os.write(reinterpret_cast<char *>(&vector_size), sizeof(UINT32));
122
//        else
123
//                os << vector_size << std::endl;
124
//        for (_it_v_mat_2d_const iter = rhs.begin(); iter != rhs.end(); ++iter)
125
//                os << *iter;        // calls ostream& operator<< (std::ostream& os, const matrix_2d& rhs)
126
//        return os;
127
//}
128

129
//// Output to stream vectors of matrix_2d
130
//ostream& operator<< (std::ostream& os, const v_mat_2d* rhs)
131
//{
132
//        os << *rhs;
133
//        return os;
134
//}
135

136
//istream& operator>> (istream& is, matrix_2d& rhs)
137
//{
138
//        if (is.iword(0) == binary)
139
//        {
140
//                // Binary input
141
//                                
142
//                // matrix type 
143
//                is.read(reinterpret_cast<char *>(&rhs._matrixType), sizeof(UINT32));
144
//                
145
//                // input rows and columns
146
//                is.read(reinterpret_cast<char *>(&rhs._rows), sizeof(UINT32));
147
//                is.read(reinterpret_cast<char *>(&rhs._cols), sizeof(UINT32));
148
//
149
//                is.read(reinterpret_cast<char *>(&rhs._mem_rows), sizeof(UINT32));
150
//                is.read(reinterpret_cast<char *>(&rhs._mem_cols), sizeof(UINT32));
151
//
152
//                // resize and populate the matrix
153
//                rhs.allocate(rhs._mem_rows, rhs._mem_cols);
154
//                UINT32 c, r;
155
//
156
//                switch (rhs._matrixType)
157
//                {
158
//                case mtx_lower:
159
//                        // output lower triangular part of a square matrix
160
//                        if (rhs._mem_rows != rhs._mem_cols)
161
//                                throw boost::enable_current_exception(std::runtime_error("matrix_2d operator>> (): Matrix is not square."));
162
//                        
163
//                        // retrieve each column
164
//                        for (c=0; c<rhs._mem_cols; ++c)
165
//                                is.read(reinterpret_cast<char *>(rhs.getelementref(c,c)), (rhs._mem_rows - c) * sizeof(double));
166
//                        
167
//                        rhs.fillupper();
168
//                        break;
169
//                case mtx_sparse:
170
//                case mtx_full:
171
//                default:
172
//                        // input full matrix data
173
//                        for (r=0; r<rhs._mem_rows; ++r)
174
//                                for (c=0; c<rhs._mem_cols; ++c)
175
//                                        is.read(reinterpret_cast<char *>(rhs.getelementref(r,c)), sizeof(double));
176
//                        break;
177
//                }
178
//
179
//                is.read(reinterpret_cast<char *>(&rhs._maxvalRow), sizeof(UINT32));
180
//                is.read(reinterpret_cast<char *>(&rhs._maxvalCol), sizeof(UINT32));
181
//        }
182
//        else
183
//        {
184
//                // ASCII input
185
//                //throw boost::enable_current_exception(std::runtime_error("istream& operator>> has not been tested"));
186
//                
187
//                std::string str;
188
//                UINT32 type;
189
//                is >> type;
190
//                rhs._matrixType = static_cast<mtxType>(type);
191
//                is >> rhs._rows >> rhs._cols >> rhs._mem_rows >> rhs._mem_cols;
192
//                rhs.allocate(rhs._mem_rows, rhs._mem_cols);
193
//
194
//                for (UINT32 c, r=0; r<rhs._mem_rows; ++r) 
195
//                        for (c=0; c<rhs._mem_cols; ++c) 
196
//                                is >> *(rhs.getelementref(r,c));
197
//
198
//                is >> rhs._maxvalRow >> rhs._maxvalCol;
199
//        }
200
//
201
//        return is;
202
//}
203

204

205
//istream& operator>> (istream& is, matrix_2d* rhs)
206
//{
207
//        is >> *rhs;
208
//        return is;
209
//}
210

211
//istream& operator>> (istream& is, v_mat_2d& rhs)
212
//{
213
//        UINT32 vector_size(0);
214
//        if (is.iword(0) == binary)
215
//                is.read(reinterpret_cast<char *>(&vector_size), sizeof(UINT32));
216
//        else
217
//        {
218
//                is >> vector_size;                // throws
219
//        }
220
//        
221
//        // resize the vector
222
//        rhs.resize(vector_size);
223
//        
224
//        // Now load up the matrices
225
//        for (_it_v_mat_2d iter = rhs.begin(); iter != rhs.end(); ++iter)
226
//                is >> *iter;        // calls istream& operator>> (istream& is, matrix_2d& rhs)
227
//
228
//        return is;
229
//}
230

231
//istream& operator>> (istream& is, v_mat_2d* rhs)
232
//{
233
//        is >> *rhs;
234
//        return is;
235
//}
236

237
        
238
UINT32 __row__;
239
UINT32 __col__;
240
//string _method_;
241

242
void out_of_memory_handler()
×
243
{
NEW
244
        std::stringstream ss("");
×
NEW
245
        UINT32 mem(std::max(__row__, __col__));
×
NEW
246
        mem *= std::min(__row__, __col__) * sizeof(UINT32);
×
247
        
248
        ss << "Insufficient memory available to create a " <<
×
249
                __row__ << " x " << __col__ << " matrix (" << 
×
NEW
250
                std::fixed << std::setprecision(2);
×
251

252
        if (mem < MEGABYTE_SIZE)
×
253
                ss << (mem/KILOBYTE_SIZE) << " KB).";
×
254
        else if (mem < GIGABYTE_SIZE)
×
255
                ss << (mem/MEGABYTE_SIZE) << " MB).";
×
256
        else // if (mem >= GIGABYTE_SIZE)
257
                ss << (mem/GIGABYTE_SIZE) << " GB).";
×
258
        
259
        throw boost::enable_current_exception(NetMemoryException(ss.str()));
×
260
}
×
261

262
matrix_2d::matrix_2d()
8,349✔
263
        : _mem_cols(0)
8,349✔
264
        , _mem_rows(0)
8,349✔
265
        , _cols(0)
8,349✔
266
        , _rows(0)
8,349✔
267
        , _buffer(0)
8,349✔
268
        , _maxvalCol(0)
8,349✔
269
        , _maxvalRow(0)
8,349✔
270
        , _matrixType(mtx_full)
8,349✔
271
{
272
        std::set_new_handler(out_of_memory_handler);
8,349✔
273

274
        // if this class were to be modified to use templates, each
275
        // instance could be tested for an invalid data type as follows
276
        // 
277
        //if (strcmp(typeid(a(1,1)).name(), "double") != 0 && 
278
        //        strcmp(typeid(a(1,1)).name(), "float") != 0 ) {
279
        //        throw boost::enable_current_exception(std::runtime_error("Not a floating point type"));
280
}
8,349✔
281

282
matrix_2d::matrix_2d(const UINT32& rows, const UINT32& columns)
669,578✔
283
        : _mem_cols(columns)
669,578✔
284
        , _mem_rows(rows)
669,578✔
285
        , _cols(columns)
669,578✔
286
        , _rows(rows)
669,578✔
287
        , _buffer(0)
669,578✔
288
        , _maxvalCol(0)
669,578✔
289
        , _maxvalRow(0)
669,578✔
290
        , _matrixType(mtx_full)
669,578✔
291
{
292
        std::set_new_handler(out_of_memory_handler);
669,578✔
293

294
        allocate(_rows, _cols);
669,578✔
295
}
669,578✔
296
        
297
matrix_2d::matrix_2d(const UINT32& rows, const UINT32& columns, 
345,861✔
298
        const double data[], const UINT32& data_size, const UINT32& matrix_type)
345,861✔
299
        : _mem_cols(columns)
345,861✔
300
        , _mem_rows(rows)
345,861✔
301
        , _cols(columns)
345,861✔
302
        , _rows(rows)
345,861✔
303
        , _buffer(0)
345,861✔
304
        , _maxvalCol(0)
345,861✔
305
        , _maxvalRow(0)
345,861✔
306
        , _matrixType(matrix_type)
345,861✔
307
{
308
        std::set_new_handler(out_of_memory_handler);
345,861✔
309

310
        std::stringstream ss;
345,861✔
311
        UINT32 upperMatrixElements(sumOfConsecutiveIntegers(rows));
345,861✔
312
        UINT32 j;
345,861✔
313

314
        const double* dataptr = &data[0];
345,861✔
315

316
        switch (matrix_type)
345,861✔
317
        {
318
        case mtx_lower:
827✔
319
                // Lower triangular part of a square matrix
320
                if (upperMatrixElements != data_size)
827✔
321
                {
322
                        ss << "Data size must be equivalent to upper matrix element count for " << rows << " x " << columns << ".";
×
NEW
323
                        throw boost::enable_current_exception(std::runtime_error(ss.str()));
×
324
                }
325

326
                // Create memory and store the data
327
                allocate(_rows, _cols);
827✔
328

329
                for (j=0; j<columns; ++j)
3,308✔
330
                {
331
                        memcpy(getelementref(j, j), dataptr, (rows - j) * sizeof(double));
2,481✔
332
                        dataptr += (rows - j);
2,481✔
333
                }
334

335
                fillupper();
827✔
336
                break;
337

338
        case mtx_sparse:
×
339
                ss << "matrix_2d(): A sparse matrix cannot be initialised with a double array.";
×
NEW
340
                throw boost::enable_current_exception(std::runtime_error(ss.str()));
×
341
                break;
345,034✔
342

343
        case mtx_full:
345,034✔
344
        default:
345,034✔
345
                // Full matrix
346
                if (data_size != rows * columns)
345,034✔
347
                {
348
                        ss << "Data size must be equivalent to matrix dimensions (" << rows << " x " << columns << ").";
×
NEW
349
                        throw boost::enable_current_exception(std::runtime_error(ss.str()));
×
350
                }
351

352
                // Create memory and store the data
353
                allocate(_rows, _cols);
345,034✔
354
                memcpy(_buffer, data, data_size * sizeof(double));
345,034✔
355

356
                break;
345,034✔
357
        }        
358

359
        
360
}
345,861✔
361

362
matrix_2d::matrix_2d(const matrix_2d& newmat)
410,875✔
363
        : _mem_cols(newmat.memColumns())
410,875✔
364
        , _mem_rows(newmat.memRows())
410,875✔
365
        , _cols(newmat.columns())
410,875✔
366
        , _rows(newmat.rows())
410,875✔
367
        , _buffer(0)
410,875✔
368
        , _maxvalCol(newmat.maxvalueCol())
410,875✔
369
        , _maxvalRow(newmat.maxvalueRow())
410,875✔
370
        , _matrixType(newmat.matrixType())
410,875✔
371
{
372
        std::set_new_handler(out_of_memory_handler);
410,875✔
373

374
        allocate(_mem_rows, _mem_cols);
410,875✔
375

376
        const double* ptr = newmat.getbuffer();
410,875✔
377
        
378
        // copy buffer
379
        memcpy(_buffer, ptr, newmat.buffersize());
410,875✔
380
}
410,875✔
381
        
382

383
matrix_2d::~matrix_2d()
1,437,729✔
384
{
385
        // Default destructor
386
        deallocate();
1,437,729✔
387
}        
1,437,729✔
388

389
std::size_t matrix_2d::get_size()
262✔
390
{
391
        size_t size =
262✔
392
                (7 * sizeof(UINT32));                //UINT32 _matrixType, _mem_cols, _mem_rows, _cols, _rows, _maxvalRow, _maxvalCol
393

394
        switch (_matrixType)
262✔
395
        {
396
        case mtx_lower:
89✔
397
                size += sumOfConsecutiveIntegers(_mem_rows) * sizeof(double);
89✔
398
                break;
89✔
399
        case mtx_sparse:
400
                break;
401
        case mtx_full:
165✔
402
        default:
165✔
403
                size += buffersize();
165✔
404
        }
405
        return size;
262✔
406
}
407
        
408

409
// Read data from memory mapped file
410
void matrix_2d::ReadMappedFileRegion(void* addr)
1,371✔
411
{
412
        // IMPORTANT
413
        // The following read statements must correspond
414
        // with that which is written in operator>> below.
415

416
        PUINT32 data_U = reinterpret_cast<PUINT32>(addr);
1,371✔
417
        _matrixType = *data_U++;
1,371✔
418
        _rows = *data_U++;
1,371✔
419
        _cols = *data_U++;
1,371✔
420

421
        switch (_matrixType)
1,371✔
422
        {
423
        case mtx_sparse:
×
424
                // _mem_cols and _mem_rows equal _cols and _rows
425
                _mem_rows = _rows;
×
426
                _mem_cols = _cols;
×
427
                break;
×
428
        case mtx_lower:
1,371✔
429
        case mtx_full:
1,371✔
430
        default:
1,371✔
431
                _mem_rows = *data_U++;
1,371✔
432
                _mem_cols = *data_U++;
1,371✔
433
                break;
1,371✔
434
        }
435

436
        allocate(_mem_rows, _mem_cols);
1,371✔
437

438
        double* data_d;
1,371✔
439
        int* data_i;
1,371✔
440

441
        UINT32 c, r, i;
1,371✔
442
        int ci;
1,371✔
443

444
        switch (_matrixType)
1,371✔
445
        {
446
        case mtx_sparse:
447
                data_i = reinterpret_cast<int*>(data_U);
448
                for (r=0; r<_rows; ++r)
×
449
                {
450
                        // A row corresponding to stations 1, 2 and 3
451
                        for (i=0; i<3; ++i)
×
452
                        {
453
                                // get column index of first element
454
                                ci = *data_i++;
×
455

456
                                // get elements
457
                                data_d = reinterpret_cast<double*>(data_i);
×
458
                        
459
                                if (ci < 0)
×
460
                                {
461
                                        data_d += 3;
×
462
                                        data_i = reinterpret_cast<int*>(data_d);
×
463
                                        continue;
×
464
                                }
465

466
                                memcpy(getelementref(r,ci), data_d, sizeof(double));                // xValue
×
467
                                data_d++;
×
468
                                memcpy(getelementref(r,ci+1), data_d, sizeof(double));        // yValue
×
469
                                data_d++;
×
470
                                memcpy(getelementref(r,ci+2), data_d, sizeof(double));        // zValue
×
471
                                data_d++;
×
472
                        
473
                                data_i = reinterpret_cast<int*>(data_d);
×
474
                        }
475
                }
476
                return;
1,371✔
477
                break;
478
        case mtx_lower:
479
                data_d = reinterpret_cast<double*>(data_U);
480
                
481
                // read each column
482
                for (c=0; c<_mem_cols; ++c)
25,022✔
483
                {
484
                        memcpy(getelementref(c, c), data_d, (_mem_rows - c) * sizeof(double));
24,702✔
485
                        data_d += (_mem_rows - c);
24,702✔
486
                }
487

488
                fillupper();
320✔
489
                break;
490
        case mtx_full:
1,051✔
491
        default:
1,051✔
492
                data_d = reinterpret_cast<double*>(data_U);
1,051✔
493
                
494
                // get contiguous block from memory
495
                memcpy(_buffer, data_d, buffersize());
1,051✔
496
                // skip to UINT32 elements
497
                data_d += _mem_rows * _mem_cols;
1,051✔
498
                break;
1,051✔
499
        }                
500

501
        // Get UINT pointer
502
        data_U = reinterpret_cast<UINT32*>(data_d);
1,371✔
503
        
504
        _maxvalRow = *data_U++;
1,371✔
505
        _maxvalCol = *data_U;
1,371✔
506
}
507
        
508

509
// Write data to memory mapped file
510
void matrix_2d::WriteMappedFileRegion(void* addr)
828✔
511
{
512
        // IMPORTANT
513
        // The following write statements must correspond 
514
        // with that which is written in operator<< above.
515

516
        PUINT32 data_U = reinterpret_cast<UINT32*>(addr);
828✔
517
        *data_U++ = _matrixType;
828✔
518
        *data_U++ = _rows;
828✔
519
        *data_U++ = _cols;
828✔
520

521
        switch (_matrixType)
828✔
522
        {
523
        case mtx_sparse:
524
                // _mem_cols and _mem_rows aren't written
525
                // because for sparse matrices they are the 
526
                // same size as _cols and _rows
527
                break;
528
        case mtx_lower:
828✔
529
        case mtx_full:
828✔
530
        default:
828✔
531
                *data_U++ = _mem_rows;
828✔
532
                *data_U++ = _mem_cols;
828✔
533
                break;
828✔
534
        }
535

536
        double* data_d;
828✔
537
        int* data_i;
828✔
538

539
        UINT32 c, r, i;
828✔
540
        int ci;
828✔
541

542
        switch (_matrixType)
828✔
543
        {
544
        case mtx_sparse:
545
                data_i = reinterpret_cast<int*>(data_U);
546
                for (r=0; r<_rows; ++r)
×
547
                {
548
                        // A row corresponding to stations 1, 2 and 3
549
                        for (i=0; i<3; ++i)
×
550
                        {
551
                                // get column index of first element
552
                                ci = *data_i++;
×
553

554
                                // write elements
555
                                data_d = reinterpret_cast<double*>(data_i);
×
556
                        
557
                                if (ci < 0)
×
558
                                {
559
                                        data_d += 3;
×
560
                                        data_i = reinterpret_cast<int*>(data_d);
×
561
                                        continue;
×
562
                                }
563

564
                                memcpy(data_d, getelementref(r,ci), sizeof(double));                // xValue
×
565
                                data_d++;
×
566
                                memcpy(data_d, getelementref(r,ci+1), sizeof(double));        // yValue
×
567
                                data_d++;
×
568
                                memcpy(data_d, getelementref(r,ci+2), sizeof(double));        // zValue
×
569
                                data_d++;
×
570
                        
571
                                data_i = reinterpret_cast<int*>(data_d);
×
572
                        }
573
                }
574
                return;
828✔
575
                break;
576
        case mtx_lower:
577
                data_d = reinterpret_cast<double*>(data_U);
578
                
579
                // print each column
580
                for (c=0; c<_mem_cols; ++c)
18,600✔
581
                {
582
                        memcpy(data_d, getbuffer(c, c), (_mem_rows - c) * sizeof(double));
18,336✔
583
                        data_d += (_mem_rows - c);
18,336✔
584
                }
585
                break;
586
        case mtx_full:
564✔
587
        default:
564✔
588
                data_d = reinterpret_cast<double*>(data_U);
564✔
589
                
590
                // write contiguous block to memory
591
                memcpy(data_d, _buffer, _mem_rows *_mem_cols * sizeof(double));
564✔
592
                // skip to UINT32 elements
593
                data_d += _mem_rows * _mem_cols;
564✔
594
                break;
564✔
595
        }
596

597
        // Get UINT pointer
598
        data_U = reinterpret_cast<UINT32*>(data_d);
828✔
599
        
600
        *data_U++ = _maxvalRow;
828✔
601
        *data_U = _maxvalCol;
828✔
602
}
603

604
void matrix_2d::allocate()
318✔
605
{
606
        allocate(_mem_rows, _mem_cols);
318✔
607
}
318✔
608

609
// creates memory for desired "memory size", not matrix dimensions
610
void matrix_2d::allocate(const UINT32& rows, const UINT32& columns)
1,436,205✔
611
{
612
        //_method_ = "allocate";
613

614
        deallocate();
1,436,205✔
615

616
        // an exception will be thrown by out_of_memory_handler
617
        // if memory cannot be allocated
618
        buy(rows, columns, &_buffer);
1,436,205✔
619
}
1,436,205✔
620
        
621

622
// creates memory for desired "memory size", not matrix dimensions
623
void matrix_2d::buy(const UINT32& rows, const UINT32& columns, double** mem_space)
1,436,205✔
624
{
625
        //_method_ = "buy";
626

627
        // set globals for new_memory_handler function
628
        __row__ = rows;
1,436,205✔
629
        __col__ = columns;
1,436,205✔
630

631
        // an exception will be thrown by out_of_memory_handler
632
        // if memory cannot be allocated
633
        (*mem_space) = new double[rows * columns];
1,436,205✔
634
        
635
        if ((*mem_space) == NULL)        
1,436,205✔
636
        {
NEW
637
                std::stringstream ss;
×
638
                ss << "Insufficient memory for a " << rows << " x " << columns << " matrix.";
×
639
                throw boost::enable_current_exception(NetMemoryException(ss.str()));
×
640
        }
×
641

642
        // an exception will be thrown by out_of_memory_handler
643
        // if memory cannot be allocated
644
        memset(*mem_space, 0, byteSize<double>(rows * columns));                // initialise to zero
1,436,205✔
645
}
1,436,205✔
646
        
647
void matrix_2d::deallocate()
2,882,203✔
648
{
649
        if (_buffer != NULL)
2,882,203✔
650
        {
651
                delete [] _buffer;
1,436,205✔
652
                _buffer = 0;
1,436,205✔
653
        }
654
}
2,882,203✔
655
        
656

657
matrix_2d matrix_2d::submatrix(const UINT32& row_begin, const UINT32& col_begin, 
104✔
658
        const UINT32& rows, const UINT32& columns) const
659
{
660
        matrix_2d b(rows, columns);
104✔
661
        submatrix(row_begin, col_begin, &b, rows, columns);
104✔
662
        return b;
104✔
663
}
×
664
        
665

666
void matrix_2d::submatrix(const UINT32& row_begin, const UINT32& col_begin, 
44,336✔
667
        matrix_2d* dest, const UINT32& subrows, const UINT32& subcolumns) const
668
{
669
        if (row_begin >= _rows) {
44,336✔
NEW
670
                std::stringstream ss;
×
671
                ss << row_begin << ", " << col_begin << " lies outside the range of the matrix (" << _rows << ", " << _cols << ").";
×
NEW
672
                throw boost::enable_current_exception(std::runtime_error(ss.str()));
×
673
        }
×
674
        
675
        if (col_begin >= _cols) {        
44,336✔
NEW
676
                std::stringstream ss;
×
677
                ss << row_begin << ", " << col_begin << " lies outside the range of the matrix (" << _rows << ", " << _cols << ").";
×
NEW
678
                throw boost::enable_current_exception(std::runtime_error(ss.str()));
×
679
        }
×
680

681
        if (subrows > dest->rows()) {
44,336✔
NEW
682
                std::stringstream ss;
×
683
                ss << subrows << ", " << subcolumns << " exceeds the size of the matrix (" << dest->rows() << ", " << dest->columns() << ").";
×
NEW
684
                throw boost::enable_current_exception(std::runtime_error(ss.str()));
×
685
        }
×
686

687
        if (subcolumns > dest->columns()) {
44,336✔
NEW
688
                std::stringstream ss;
×
689
                ss << subrows << ", " << subcolumns << " exceeds the size of the matrix (" << dest->rows() << ", " << dest->columns() << ").";
×
NEW
690
                throw boost::enable_current_exception(std::runtime_error(ss.str()));
×
691
        }
×
692

693
        if (row_begin + subrows > _rows) {        
44,336✔
NEW
694
                std::stringstream ss;
×
695
                ss << row_begin + subrows << ", " << col_begin + subcolumns << " lies outside the range of the matrix (" << _rows << ", " << _cols << ").";
×
NEW
696
                throw boost::enable_current_exception(std::runtime_error(ss.str()));
×
697
        }
×
698
        
699
        if (col_begin + subcolumns > _cols) {        
44,336✔
NEW
700
                std::stringstream ss;
×
701
                ss << row_begin + subrows << ", " << col_begin + subcolumns << " lies outside the range of the matrix (" << _rows << ", " << _cols << ").";
×
NEW
702
                throw boost::enable_current_exception(std::runtime_error(ss.str()));
×
703
        }
×
704
        
705
        UINT32 i, j, m(0), n(0), row_end(row_begin+subrows), col_end(col_begin+subcolumns);
706
        for (i=row_begin; i<row_end; ++i)
179,615✔
707
        {
708
                for (j=col_begin; j<col_end; ++j) {
543,600✔
709
                        dest->put(m, n, get(i,j));
408,321✔
710
                        n++;
408,321✔
711
                }
712
                n = 0;
135,279✔
713
                m++;
135,279✔
714
        }
715
}
44,336✔
716
        
717

718
void matrix_2d::redim(const UINT32& rows, const UINT32& columns)
710,391✔
719
{
720
        // if new matrix size is smaller than or equal to the previous 
721
        // matrix size, then simply change dimensions and return
722
        if (rows <= _mem_rows && columns <= _mem_cols) 
710,391✔
723
        {
724
                _rows = rows;
702,224✔
725
                _cols = columns;
702,224✔
726
                return;
702,224✔
727
        }
728
        
729
        //_method_ = "redim";
730

731
        //double* new_buffer;
732
        //buy(rows, columns, &new_buffer);
733
        //copybuffer(_rows, _cols, &new_buffer);
734
        //deallocate();
735
        //_buffer = new_buffer;
736

737
        std::set_new_handler(out_of_memory_handler);
8,167✔
738

739
        deallocate();
8,167✔
740
        allocate(rows, columns);
8,167✔
741

742
        _rows = _mem_rows = rows;
8,167✔
743
        _cols = _mem_cols = columns;
8,167✔
744
}
745
        
746

747
void matrix_2d::shrink(const UINT32& rows, const UINT32& columns)
196✔
748
{
749
        if (rows > _rows || columns > _cols)
196✔
750
        {
NEW
751
                std::stringstream ss;
×
NEW
752
                ss << " " << std::endl;
×
753
                if (rows >= _rows)
×
NEW
754
                        ss << "    Cannot shrink by " << rows << " rows on a matrix of " << _rows << " rows. " << std::endl;
×
755
                if (columns >= _cols)
×
756
                        ss << "    Cannot shrink by " << columns << " columns on a matrix of " << _cols << " columns.";
×
NEW
757
                throw boost::enable_current_exception(std::runtime_error(ss.str()));
×
758
        }
×
759

760
        _rows -= rows;
196✔
761
        _cols -= columns;
196✔
762
}
196✔
763
        
764

765
void matrix_2d::grow(const UINT32& rows, const UINT32& columns)
182✔
766
{
767
        if ((rows+_rows) > _mem_rows || (columns+_cols) > _mem_cols)
182✔
768
        {
NEW
769
                std::stringstream ss;
×
NEW
770
                ss << " " << std::endl;
×
771
                if (rows >= _rows)
×
772
                        ss << "    Cannot grow matrix by " << rows << " rows: growth exceeds row memory limit (" << _mem_rows << ").";
×
773
                if (columns >= _cols)
×
774
                        ss << "    Cannot grow matrix by " << columns << " columns: growth exceeds column memory limit (" << _mem_cols << ").";
×
NEW
775
                throw boost::enable_current_exception(std::runtime_error(ss.str()));
×
776
        }
×
777

778
        _rows += rows;
182✔
779
        _cols += columns;
182✔
780
}
182✔
781
        
782

783
void matrix_2d::setsize(const UINT32& rows, const UINT32& columns)
67✔
784
{
785
        deallocate();
67✔
786
        _rows = _mem_rows = rows;
67✔
787
        _cols = _mem_cols = columns;
67✔
788
}
67✔
789
        
790

791
//void matrix_2d::append(const matrix_2d& newmat)
792
//{
793
//        UINT32 rowstart(_rows), columnstart(_cols);
794
//        redim(_rows + newmat.rows(), _cols + newmat.columns());
795
//        copybuffer(rowstart, columnstart, newmat.rows(), newmat.columns(), newmat);
796
//}
797

798
//void matrix_2d::appendcolumns(const UINT32& columns)
799
//{
800
//        redim(_rows, _cols + columns);
801
//}
802

803

804
//void matrix_2d::appendrows(const UINT32& rows)
805
//{
806
//        redim(_rows + rows, _cols);
807
//}
808
        
809

810
void matrix_2d::replace(const UINT32& rowstart, const UINT32& columnstart, const matrix_2d& newmat)
4,452✔
811
{
812
        copybuffer(rowstart, columnstart, newmat.rows(), newmat.columns(), newmat);
4,452✔
813
}
4,452✔
814
        
815
//void matrix_2d::replacebuffer(const UINT32& rows, const UINT32& columns, double** new_buffer)
816
//{
817
//        UINT32 i, j;
818
//        for (i=0; i<rows; i++)
819
//                for (j=0; j<columns; j++)
820
//                        put(i, j, *new_buffer[i * columns + j]);
821
//}
822
//
823

824
//void matrix_2d::copybuffer(const UINT32& rows, const UINT32& columns, double** new_buffer)
825
//{
826
//        if (rows == _mem_rows && columns == _mem_cols)
827
//        {
828
//                memcpy(*new_buffer, _buffer, buffersize());
829
//                return;
830
//        }
831
//
832
//        UINT32 i, j;
833
//        for (i=0; i<rows; i++)
834
//                for (j=0; j<columns; j++)
835
//                        *new_buffer[i*columns + j] = get(i,j);
836
//}
837

838

839
void matrix_2d::copybuffer(const UINT32& rows, const UINT32& columns, const matrix_2d& oldmat)
267,809✔
840
{
841
        if (rows == _mem_rows && columns == _mem_cols)
267,809✔
842
        {
843
                memcpy(_buffer, oldmat.getbuffer(), buffersize());
267,809✔
844
                return;
267,809✔
845
        }
846

847
#if defined(DNAMATRIX_ROW_WISE)
848

849
        UINT32 row;
850
        for (row=0; row<rows; row++)
851
                memcpy(getelementref(row, 0), oldmat.getbuffer(row, 0), columns * sizeof(double));
852

853
#else // DNAMATRIX_COL_WISE
854

855
        UINT32 column;
856
        for (column=0; column<columns; column++)
×
857
                memcpy(getelementref(0, column), oldmat.getbuffer(0, column), rows * sizeof(double));
×
858

859
#endif
860
}
861
        
862
void matrix_2d::copybuffer(const UINT32& rowstart, const UINT32& columnstart, const UINT32& rows, const UINT32& columns, const matrix_2d& mat)
4,452✔
863
{
864
        UINT32 rowend(rowstart+rows), columnend(columnstart+columns);
4,452✔
865
        if (rowend > _rows || columnend > _cols)
4,452✔
866
        {
NEW
867
                std::stringstream ss;
×
NEW
868
                ss << " " << std::endl;
×
869
                if (rowend >= _rows)
×
NEW
870
                        ss << "    Row index " << rowend << " exceeds the matrix row count (" << _rows << "). " << std::endl;
×
871
                if (columnend >= _cols)
×
872
                        ss << "    Column index " << columnend << " exceeds the matrix column count (" << _cols << ").";
×
NEW
873
                throw boost::enable_current_exception(std::runtime_error(ss.str()));
×
874
        }
×
875

876
#if defined(DNAMATRIX_ROW_WISE)
877

878
        UINT32 row(0), r(0);
879
        for (row=rowstart; row<rowend; ++row, ++r)
880
                memcpy(getelementref(row, columnstart), mat.getbuffer(r, 0), columns * sizeof(double));
881

882
#else // DNAMATRIX_COL_WISE
883

884
        UINT32 column(0), c(0);
885
        for (column=columnstart; column<columnend; ++column, ++c)
17,808✔
886
                memcpy(getelementref(rowstart, column), mat.getbuffer(0, c), rows * sizeof(double));
13,356✔
887

888
#endif
889
        
890
}
4,452✔
891
                
892

893
void matrix_2d::copyelements(const UINT32& row_dest, const UINT32& column_dest, 
15,472✔
894
        const matrix_2d& src, const UINT32& row_src, const UINT32& column_src, const UINT32& rows, const UINT32& columns)
895
{
896
#if defined(DNAMATRIX_ROW_WISE)
897

898
        UINT32 rd(0), rs(0), rowend_dest(row_dest+rows);
899
        for (rd=row_dest, rs=row_src; rd<rowend_dest; ++rd, ++rs)
900
                memcpy(getelementref(rd, column_dest), src.getbuffer(rs, column_src), columns * sizeof(double));
901

902
#else // DNAMATRIX_COL_WISE
903

904
        UINT32 cd(0), cs(0), colend_dest(column_dest+columns);
15,472✔
905
        for (cd=column_dest, cs=column_src; cd<colend_dest; ++cd, ++cs)
65,064✔
906
                memcpy(getelementref(row_dest, cd), src.getbuffer(row_src, cs), rows * sizeof(double));
49,592✔
907

908
#endif
909
        
910
}
15,472✔
911
        
912

913
void matrix_2d::copyelements(const UINT32& row_dest, const UINT32& column_dest, 
10,536✔
914
        const matrix_2d* src, const UINT32& row_src, const UINT32& column_src, const UINT32& rows, const UINT32& columns)
915
{
916
        copyelements(row_dest, column_dest, *src, row_src, column_src, rows, columns);
10,536✔
917
}
10,536✔
918
        
919
#if defined(__SAFE_MATRIX_OPERATIONS__)
920
//void matrix_2d::copyelements(const UINT32& row_dest, const UINT32& column_dest, 
921
//        const UINT32& row_src, const UINT32& column_src, const UINT32& rows, const UINT32& columns)
922
//{
923
//        UINT32 i, j, rowend_dest(row_dest+rows), columnend_dest(column_dest+columns);
924
//        UINT32 rowend_src(row_src+rows), columnend_src(column_src+columns);
925
//        UINT32 m, n;
926
//        for (m=row_src, i=row_dest; i<rowend_dest; i++)
927
//        {
928
//                for (n=column_src, j=column_dest; j<columnend_dest; j++)
929
//                        put(i, j, get(m, n++));
930
//                m++;
931
//        }
932
//}
933
//void matrix_2d::copyelements_safe(const UINT32& row_dest, const UINT32& column_dest, const UINT32& row_src, const UINT32& column_src, const UINT32& rows, const UINT32& columns)
934
//{
935
//        UINT32 i, j, rowend_dest(row_dest+rows), columnend_dest(column_dest+columns);
936
//        UINT32 rowend_src(row_src+rows), columnend_src(column_src+columns);
937
//        if (rowend_src > _rows || columnend_src > _cols || rowend_dest > _rows || columnend_dest > _cols)
938
//        {
939
//                std::stringstream ss;
940
//                ss << "copyelements(): " << std::endl;
941
//                if (rowend_src >= _rows)
942
//                        ss << "    Row index (source) " << rowend_src << " exceeds the matrix row count (" << _rows << "). " << std::endl;
943
//                if (columnend_src >= _cols)
944
//                        ss << "    Column index (source) " << columnend_src << " exceeds the matrix column count (" << _cols << ").";
945
//                if (rowend_dest >= _rows)
946
//                        ss << "    Row index (destination) " << rowend_dest << " exceeds the matrix row count (" << _rows << "). " << std::endl;
947
//                if (columnend_dest >= _cols)
948
//                        ss << "    Column index (destination) " << columnend_dest << " exceeds the matrix column count (" << _cols << ").";
949
//                throw boost::enable_current_exception(std::runtime_error(ss.str()));
950
//        }
951
//
952
//        UINT32 m, n;
953
//        for (m=row_src, i=row_dest; i<rowend_dest; i++)
954
//        {
955
//                for (n=column_src, j=column_dest; j<columnend_dest; j++)
956
//                        put(i, j, get(m, n++));
957
//                m++;
958
//        }
959
//}
960
//        
961
//
962
//void matrix_2d::copyelements_safe(const UINT32& row_dest, const UINT32& column_dest, const matrix_2d& src, const UINT32& row_src, const UINT32& column_src, const UINT32& rows, const UINT32& columns)
963
//{
964
//        UINT32 i, j, rowend_dest(row_dest+rows), columnend_dest(column_dest+columns);
965
//        UINT32 rowend_src(row_src+rows), columnend_src(column_src+columns);
966
//        if (rowend_src > src.rows() || columnend_src > src.columns())
967
//        {
968
//                std::stringstream ss;
969
//                ss << "copyelements(): " << std::endl;
970
//                if (rowend_src >= src.rows())
971
//                        ss << "    Row index (source) " << rowend_src << " exceeds the matrix row count (" << src.rows() << "). " << std::endl;
972
//                if (columnend_src >= src.columns())
973
//                        ss << "    Column index (source) " << columnend_src << " exceeds the matrix column count (" << src.columns() << ").";
974
//                throw boost::enable_current_exception(std::runtime_error(ss.str()));
975
//        }
976
//
977
//        if (rowend_dest > _rows || columnend_dest > _cols)
978
//        {
979
//                std::stringstream ss;
980
//                ss << "copyelements(): " << std::endl;
981
//                if (rowend_dest >= _rows)
982
//                        ss << "    Row index (destination) " << rowend_dest << " exceeds the matrix row count (" << _rows << "). " << std::endl;
983
//                if (columnend_dest >= _cols)
984
//                        ss << "    Column index (destination) " << columnend_dest << " exceeds the matrix column count (" << _cols << ").";
985
//                throw boost::enable_current_exception(std::runtime_error(ss.str()));
986
//        }
987
//
988
//        UINT32 m, n;
989
//        for (m=row_src, i=row_dest; i<rowend_dest; i++)
990
//        {
991
//                for (n=column_src, j=column_dest; j<columnend_dest; j++)
992
//                        put(i, j, src.get(m, n++));
993
//                m++;
994
//        }
995
//}
996
//        
997
//
998
//double matrix_2d::get_safe(const UINT32& row, const UINT32& column) const
999
//{
1000
//        if (row >= _rows || column >= _cols)
1001
//        {
1002
//                std::stringstream ss;
1003
//                ss << " " << std::endl;
1004
//                if (row >= _rows)
1005
//                        ss << "    Row index " << row << " exceeds the matrix row count (" << _rows << "). " << std::endl;
1006
//                if (column >= _cols)
1007
//                        ss << "    Column index " << column << " exceeds the matrix column count (" << _cols << ").";
1008
//                throw boost::enable_current_exception(std::runtime_error(ss.str()));
1009
//        }
1010
//
1011
//        return get(row, column);
1012
//}
1013
//        
1014

1015
//void matrix_2d::put(const double data[], const UINT32& data_size)
1016
//{
1017
//        std::set_new_handler(out_of_memory_handler);
1018
//
1019
//        if (data_size != _rows * _cols)
1020
//        {
1021
//                std::stringstream ss;
1022
//                ss << "Data size must be equivalent to matrix dimensions (" << _rows << " x " << _cols << ").";
1023
//                throw boost::enable_current_exception(std::runtime_error(ss.str()));
1024
//        }
1025
//
1026
//        UINT32 i, j, k(0);
1027
//        for (i=0; i<_rows; i++)
1028
//                for (j=0; j<_cols; j++)
1029
//                        put(i, j, data[k++]);
1030
//}
1031
        
1032

1033
//void matrix_2d::put_safe(const UINT32& row, const UINT32& column, const double& value)
1034
//{
1035
//        if (row >= _rows || column >= _cols)
1036
//        {
1037
//                std::stringstream ss;
1038
//                ss << " " << std::endl;
1039
//                if (row >= _rows)
1040
//                        ss << "    Row index " << row << " exceeds the matrix row count (" << _rows << "). " << std::endl;
1041
//                if (column >= _cols)
1042
//                        ss << "    Column index " << column << " exceeds the matrix column count (" << _cols << ").";
1043
//                throw boost::enable_current_exception(std::runtime_error(ss.str()));
1044
//        }
1045
//
1046
//        put(row, column, value); 
1047
//}
1048
//        
1049

1050
//void matrix_2d::elementadd_safe(const UINT32& row, const UINT32& column, const double& increment)
1051
//{
1052
//        if (row >= _rows || column >= _cols) {
1053
//                std::stringstream ss;
1054
//                ss << row << ", " << column << " lies outside the range of the matrix (" << _rows << ", " << _cols << ").";
1055
//                throw boost::enable_current_exception(std::runtime_error(ss.str()));
1056
//        }
1057
//        elementadd(row, column, increment);
1058
//}
1059
        
1060
//void matrix_2d::blockadd_safe(const UINT32& row_dest, const UINT32& col_dest, const matrix_2d& mat_src, 
1061
//                                                 const UINT32& row_src, const UINT32& col_src, const UINT32& rows, const UINT32& cols)
1062
//{
1063
//        if (row_dest >= _rows || col_dest >= _cols) {
1064
//                std::stringstream ss;
1065
//                ss << row_dest << ", " << col_dest << " lies outside the range of the destination matrix (" << 
1066
//                        _rows << ", " << _cols << ").";
1067
//                throw boost::enable_current_exception(std::runtime_error(ss.str()));
1068
//        }
1069
//        if (row_dest+rows > _rows || col_dest+cols > _cols) {
1070
//                std::stringstream ss;
1071
//                ss << "Adding a " << rows << ", " << cols << " matrix extends beyond the range of the destination matrix (" << 
1072
//                        _rows << ", " << _cols << ").";
1073
//                throw boost::enable_current_exception(std::runtime_error(ss.str()));
1074
//        }
1075
//        if (row_src >= mat_src.rows() || col_src >= mat_src.columns()) {
1076
//                std::stringstream ss;
1077
//                ss << mat_src.rows() << ", " << mat_src.columns() << " lies outside the range of the source matrix (" << 
1078
//                        mat_src.rows() << ", " << mat_src.columns() << ").";
1079
//                throw boost::enable_current_exception(std::runtime_error(ss.str()));
1080
//        }
1081
//        if (row_src+rows > mat_src.rows() || col_src+cols > mat_src.columns()) {
1082
//                std::stringstream ss;
1083
//                ss << "Adding a " << rows << ", " << cols << " matrix extends beyond the range of the destination matrix (" << 
1084
//                        mat_src.rows() << ", " << mat_src.columns() << ").";
1085
//                throw boost::enable_current_exception(std::runtime_error(ss.str()));
1086
//        }
1087
//
1088
//        blockadd(row_dest, col_dest, mat_src, row_src, col_src, rows, cols);
1089
//}
1090
        
1091
//void matrix_2d::blockTadd_safe(const UINT32& row_dest, const UINT32& col_dest, const matrix_2d& mat_src, 
1092
//                                                 const UINT32& row_src, const UINT32& col_src, const UINT32& rows, const UINT32& cols)
1093
//{
1094
//        if (rows != cols)
1095
//                throw boost::enable_current_exception(std::runtime_error("The source matrix is not square."));
1096
//        if (row_dest >= _rows || col_dest >= _cols) {
1097
//                std::stringstream ss;
1098
//                ss << row_dest << ", " << col_dest << " lies outside the range of the destination matrix (" << 
1099
//                        _rows << ", " << _cols << ").";
1100
//                throw boost::enable_current_exception(std::runtime_error(ss.str()));
1101
//        }
1102
//        if (row_dest+rows > _rows || col_dest+cols > _cols) {
1103
//                std::stringstream ss;
1104
//                ss << "Adding a " << rows << ", " << cols << " matrix extends beyond the range of the destination matrix (" << 
1105
//                        _rows << ", " << _cols << ").";
1106
//                throw boost::enable_current_exception(std::runtime_error(ss.str()));
1107
//        }
1108
//        if (row_src >= mat_src.rows() || col_src >= mat_src.columns()) {
1109
//                std::stringstream ss;
1110
//                ss << mat_src.rows() << ", " << mat_src.columns() << " lies outside the range of the source matrix (" << 
1111
//                        mat_src.rows() << ", " << mat_src.columns() << ").";
1112
//                throw boost::enable_current_exception(std::runtime_error(ss.str()));
1113
//        }
1114
//        if (row_src+rows > mat_src.rows() || col_src+cols > mat_src.columns()) {
1115
//                std::stringstream ss;
1116
//                ss << "Adding a " << rows << ", " << cols << " matrix extends beyond the range of the destination matrix (" << 
1117
//                        mat_src.rows() << ", " << mat_src.columns() << ").";
1118
//                throw boost::enable_current_exception(std::runtime_error(ss.str()));
1119
//        }
1120
//
1121
//        blockTadd(row_dest, col_dest, mat_src, row_src, col_src, rows, cols);
1122
//}
1123
//        
1124

1125
//// scale()
1126
//matrix_2d matrix_2d::scale(const double& scalar, const UINT32& row_begin, const UINT32& col_begin, UINT32 rows, UINT32 columns)
1127
//{
1128
//        // comparison of unsigned expression < 0 is always false
1129
//        if (row_begin >= _rows) {
1130
//                std::stringstream ss;
1131
//                ss << row_begin << ", " << col_begin << " lies outside the range of the matrix (" << _rows << ", " << _cols << ").";
1132
//                throw boost::enable_current_exception(std::runtime_error(ss.str()));
1133
//        }
1134
//        // comparison of unsigned expression < 0 is always false
1135
//        if (col_begin >= _cols) {        
1136
//                std::stringstream ss;
1137
//                ss << row_begin << ", " << col_begin << " lies outside the range of the matrix (" << _rows << ", " << _cols << ").";
1138
//                throw boost::enable_current_exception(std::runtime_error(ss.str()));
1139
//        }
1140
//        if (rows < 1)
1141
//                rows = _rows - row_begin;                // apply scale from row_begin to end
1142
//        if (columns < 1)
1143
//                columns = _cols - col_begin; // apply scale from col_begin to end
1144
//
1145
//        if (row_begin + rows > _rows || rows < 0) {        
1146
//                std::stringstream ss;
1147
//                ss << row_begin + rows << ", " << col_begin + rows << " lies outside the range of the matrix (" << _rows << ", " << _cols << ").";
1148
//                throw boost::enable_current_exception(std::runtime_error(ss.str()));
1149
//        }
1150
//        if (col_begin + columns > _cols || columns < 0) {        
1151
//                std::stringstream ss;
1152
//                ss << row_begin + rows << ", " << col_begin + rows << " lies outside the range of the matrix (" << _rows << ", " << _cols << ").";
1153
//                throw boost::enable_current_exception(std::runtime_error(ss.str()));
1154
//        }
1155
//        
1156
//        UINT32 i, j, row_end(row_begin+rows), col_end(col_begin+columns);
1157
//        for (i=row_begin; i<row_end; ++i)
1158
//                for (j=col_begin; j<col_end; ++j) 
1159
//                        elementmultiply(i, j, scalar);
1160
//        return *this;
1161
//}
1162

1163
//// zero_safe()
1164
//void matrix_2d::zero_safe(const UINT32& row_begin, const UINT32& col_begin, const UINT32& rows, const UINT32& columns)
1165
//{
1166
//        if (row_begin >= _rows)
1167
//                return;
1168
//        if (col_begin >= _cols)        
1169
//                return;
1170
//        if (row_begin + rows > _rows)
1171
//                return;
1172
//        if (col_begin + columns > _cols)
1173
//                return;
1174
//
1175
//        UINT32 i, j, row_end(row_begin+rows), col_end(col_begin+columns);
1176
//
1177
//        for (i=row_begin; i<row_end; ++i)
1178
//                for (j=col_begin; j<col_end; ++j) 
1179
//                        put(i, j, 0.0);
1180
//}
1181
#endif
1182

1183

1184
//double matrix_2d::operator() (const UINT32& row, const UINT32& column)
1185
//{
1186
//        return get(row, column);
1187
//}
1188
        
1189

1190
void matrix_2d::sweep(UINT32 k1, UINT32 k2)
196✔
1191
{
1192
        double eps(1.0e-8), d;
196✔
1193
        UINT32 i, j, k, it;
196✔
1194
        
1195
        if (k2 < k1) { k = k1; k1 = k2; k2 = k; }
196✔
1196
                                                                                                                                                                        //        n = a.nrows();
1197
        for (k=k1; k<k2; k++)                                                                                                                        //        for (k = k1; k <= k2; k++)
1,093✔
1198
        {                                                                                                                                                                //        {
1199
                if (fabs(get(k, k)) < eps)                                                                                                        //                if ( fabs( a(k, k) ) < eps)
897✔
1200
                {
1201
                        for (it=0; it<_rows; it++)                                                                                                //                        for (it = 1; it <= n; it++)
×
1202
                        {
1203
                                put(it, k, 0.);
×
1204
                                put(k, it, 0.);                                                                                                                //                                a(it, k) = a(k, it) = 0.0;
×
1205
                        }
1206
                }
1207
                else {                                                                                                                                                //                else {
1208
                        d = 1.0 / get(k, k);                                                                                                        //                        d = 1.0 / a(k, k);
897✔
1209
                        put(k, k, d);                                                                                                                        //                        a(k, k) = d;
897✔
1210
                        for (i=0; i<_rows; i++)                                                                                                        //                        for (i = 1; i <= n; i++) 
7,278✔
1211
                                if (i!=k)                                                                                                                        //                                if (i != k) 
6,381✔
1212
                                        *getelementref(i, k) *= -d;                                                                                        //                                        a(i, k) *= (T) - d;
5,484✔
1213
                        for (j=0; j<_rows; j++)                                                                                                        //                        for (j = 1; j <= n; j++) 
7,278✔
1214
                                if (j != k)                                                                                                                        //                                if (j != k)
6,381✔
1215
                                        *getelementref(k, j) *= d;                                                                                                //                                        a(k, j) *= (T) d; 
5,484✔
1216
                        for (i=0; i<_rows; i++) {                                                                                                //                        for (i = 1; i <= n; i++) {
7,278✔
1217
                                if (i != k) {                                                                                                                //                                if (i != k) {
6,381✔
1218
                                        for (j=0; j<_rows; j++) {                                                                                //                                        for (j = 1; j <= n; j++) {
62,418✔
1219
                                                if (j != k)                                                                                                        //                                                if (j != k)
56,934✔
1220
                                                        *getelementref(i, j) += get(i, k) * get(k, j) / d;                //                                                        a(i, j) += a(i, k) *a(k, j) / d;
51,450✔
1221
                                        } // end for j                                                                                                        //                                        } // end for j
1222
                                } // end for i != k                                                                                                        //                                } // end for i != k
1223
                        } // end for i                                                                                                                        //                        } // end for i
1224
                } // end else                                                                                                                                //                } // end else
1225
        } // end for k                                                                                                                                        //        } // end for k
1226
}                                                                                                                                                                        
196✔
1227
        
1228

1229
matrix_2d matrix_2d::sweepinverse()
196✔
1230
{
1231
        if (_rows != _cols)
196✔
NEW
1232
                throw boost::enable_current_exception(std::runtime_error("sweepinverse(): Matrix is not square."));
×
1233

1234
        sweep(0, _rows);
196✔
1235
        return *this;        
196✔
1236
}
1237
        
1238

1239
//// gaussianinverse()
1240
////
1241
//// Calculates the inverse using Gaussian elimination.
1242
//// The following assumptions are made:
1243
////         - matrix is symmetric, and
1244
////         - matrix is upper triangular (or a full matrix). 
1245
////        
1246
//// The inversion does not destroy the contents of the matrix 
1247
//// passed to the function, instead it operates on a copy.
1248
//matrix_2d matrix_2d::gaussianinverse()
1249
//{
1250
//        if (_rows != _cols)
1251
//                throw boost::enable_current_exception(std::runtime_error("gaussinverse(): Matrix is not square."));
1252
//
1253
//        // create copy of upper triangular
1254
//        matrix_2d matcopy(*this);
1255
//        matcopy.clearlower();
1256
//
1257
//        identity();
1258
//        
1259
//        int nRow, nCol, k, columns(_cols);
1260
//        double dTemp;
1261
//        const double epsilon = PRECISION_1E35;
1262
//
1263
//        //        Gaussian Elimination, Forward pass:
1264
//   for (nRow = 0; nRow<columns-1; nRow++) 
1265
//        {
1266
//                for (nCol = nRow+1; nCol<columns; nCol++)
1267
//                {
1268
//                        if (fabs(matcopy.get(nRow, nRow)) < epsilon)
1269
//                                throw boost::enable_current_exception(std::runtime_error("gaussinverse(): Matrix inversion failed."));
1270
//                        
1271
//                        dTemp = matcopy.get(nRow, nCol) / matcopy.get(nRow, nRow);
1272
//                        
1273
//                        for (k = nCol; k<columns; k++)
1274
//                                matcopy.put(nCol, k, matcopy.get(nCol, k) - dTemp * matcopy.get(nRow, k));
1275
//                        
1276
//                        for (k = 0; k<nRow+1; k++)
1277
//                                put(k, nCol, get(k, nCol) - dTemp * get(k, nRow));
1278
//                        
1279
//                }
1280
//        }
1281
//
1282
//         //        Gaussian Elimination, Backward Pass:
1283
//        for (nRow = columns-1; nRow>=0; nRow--)
1284
//        {
1285
//                if (fabs(matcopy.get(nRow, nRow)) < epsilon)
1286
//                        throw boost::enable_current_exception(std::runtime_error("gaussinverse(): Matrix inversion failed."));
1287
//                
1288
//                for (nCol = 0; nCol<nRow+1; nCol++)
1289
//                        put(nCol, nRow, get(nCol, nRow) / matcopy.get(nRow, nRow));
1290
//                
1291
//                if (nRow == 0)
1292
//                        break;                // don't enter the following loop
1293
//
1294
//                for (nCol = nRow-1; nCol >= 0; nCol--)
1295
//                        for (k = 0; k < nCol+1; k++)
1296
//                                put(k, nCol, get(k, nCol) - get(k, nRow) * matcopy.get(nCol,nRow));
1297
//        }
1298
//
1299
//        // Copy upper triangle values to lower triangle:
1300
//        filllower();
1301
//
1302
//        return *this;
1303
//}
1304
        
1305

1306
// choleskyinverse_mkl()
1307
//
1308
// Inverts the calling matrix using MKL's implementation of the Cholesky method.
1309
// The following assumptions are made:
1310
//         - matrix is symmetric, and
1311
//         - matrix is upper triangular (or a full matrix). 
1312
//
1313
// The inversion does not destroy the contents of the matrix 
1314
// passed to the function, instead it operates on a copy.
1315
// Index pointers use UINT32
1316
matrix_2d matrix_2d::choleskyinverse_mkl(bool LOWER_IS_CLEARED /*=false*/)
7,507✔
1317
{
1318
        if (_rows < 1)
7,507✔
1319
                return *this;
×
1320

1321
        if (_rows != _cols)
7,507✔
NEW
1322
                throw boost::enable_current_exception(std::runtime_error("choleskyinverse_mkl(): Matrix is not square."));
×
1323

1324
        char uplo(LOWER_TRIANGLE);
7,507✔
1325

1326
        // Which triangle is filled - upper or lower?
1327
        if (LOWER_IS_CLEARED)
7,507✔
1328
                uplo = UPPER_TRIANGLE;
7,056✔
1329

1330
#if defined(_WIN64) || defined(__linux) || defined(sun) || defined(__unix__) || defined(__APPLE__)
1331
        long long info, n = _rows;
7,507✔
1332
#else // defined(_WIN32) || defined(__WIN32__)
1333
        int info, n = _rows;
1334
#endif        
1335

1336
        // Perform Cholesky factorisation
1337
        dpotrf(&uplo, &n, _buffer, &n, &info);
7,507✔
1338
        if(info != 0)
7,507✔
NEW
1339
                throw boost::enable_current_exception(std::runtime_error("choleskyinverse_mkl(): Cholesky factorisation failed."));
×
1340
        
1341
        // Perform Cholesky inverse
1342
        dpotri(&uplo, &n, _buffer, &n, &info); 
7,507✔
1343
        if(info != 0)
7,507✔
NEW
1344
                throw boost::enable_current_exception(std::runtime_error("choleskyinverse_mkl(): Cholesky inversion failed."));
×
1345

1346
        // Copy empty triangle part
1347
        if (LOWER_IS_CLEARED)
7,507✔
1348
                filllower();
7,056✔
1349
        else
1350
                fillupper();
451✔
1351

1352
        return *this;
7,507✔
1353
}
1354

1355
//// Choleskyinverse()
1356
////
1357
//// Inverts the calling matrix using the Cholesky method.
1358
//// Based upon Numerical Recipes code
1359
//// The following assumptions are made:
1360
////         - matrix is symmetric, and
1361
////         - matrix is upper triangular (or a full matrix). 
1362
////
1363
//// The inversion does not destroy the contents of the matrix 
1364
//// passed to the function, instead it operates on a copy.
1365
//// Index pointers use UINT32
1366
//matrix_2d matrix_2d::choleskyinverse(bool LOWER_IS_CLEARED /*=false*/)
1367
//{
1368
//        if (_rows != _cols)
1369
//                throw boost::enable_current_exception(std::runtime_error("choleskyinverse(): Matrix is not square."));
1370
//
1371
//        // fill lower triangle with zeros
1372
//        if (!LOWER_IS_CLEARED)
1373
//                clearlower();
1374
//        
1375
//        UINT32 i(0), j(0);
1376
//
1377
//        //trace("Matrix", "%.16G ");
1378
//
1379
//        double* _factors = new double[_rows];
1380
//
1381
//        // Condition matrix (the diagonal elements)
1382
//        for (i=0; i<_rows; i++)
1383
//        {
1384
//                if (get(i, i) < 0.)
1385
//                {
1386
//                        std::stringstream ss;
1387
//                        ss << "choleskyinverse(): Diagonal terms cannot be negative:" << std::endl <<
1388
//                                "  " << "element " << i << ", " << i << " = " << get(i, i);
1389
//                        throw boost::enable_current_exception(std::runtime_error(ss.str()));
1390
//                }
1391
//                _factors[i] = sqrt(get(i,i));
1392
//        }
1393
//
1394
//        // Apply factors
1395
//        for (i=0; i<_rows; i++)
1396
//                for (j=i; j<_rows; j++)
1397
//                        put(i, j, get(i, j) / (_factors[i] * _factors[j])); 
1398
//        
1399
//        // Cholesky Decomposition
1400
//        decomposeupper();
1401
//
1402
//        double tmp;
1403
//        UINT32 k(0), a(0);
1404
//
1405
//        // Form the w matrix
1406
//        i = _rows - 1;
1407
//        while (a++ < _rows)
1408
//        {
1409
//                j = _rows - 1;
1410
//                while (j - i >= 0)
1411
//                {
1412
//                        if (i == j)
1413
//                        {
1414
//                                put(i, i, 1.0 / get(i, i));
1415
//                                break;
1416
//                        }
1417
//                        else
1418
//                        {
1419
//                                tmp = 0.;
1420
//                                for (k = i + 1; k <= j; k++)
1421
//                                        tmp += get(i, k) * get(k, j);
1422
//                                put(i, j, -tmp / get(i, i));
1423
//                        }
1424
//                        j--;
1425
//                }
1426
//                i--;
1427
//        }
1428
//
1429
//        // form wwt (inverse)
1430
//        for (i=0; i<_rows; i++)
1431
//        {
1432
//                for (j=i; j<_rows; j++)
1433
//                {
1434
//                        tmp = 0.;
1435
//                        for (k=j; k<_rows; k++)
1436
//                                tmp += get(i, k) * get(j, k);
1437
//                        put(i, j, tmp / (_factors[i] * _factors[j]));
1438
//                }                                       
1439
//        }
1440
//
1441
//        delete []_factors;
1442
//
1443
//        // Copy upper triangle values to lower triangle:
1444
//        filllower();
1445
//
1446
//        //trace("Matrix", "%.16G ");
1447
//
1448
//        return *this;
1449
//}
1450
        
1451

1452
//// DecomposeUpper()
1453
////
1454
//void matrix_2d::decomposeupper()
1455
//{
1456
//        UINT32 i, j, k;
1457
//        double tmp;
1458
//        
1459
//        // for every row
1460
//        for (i=0; i<_rows; ++i)
1461
//        {
1462
//                // for every column in the row, commencing at 
1463
//                // the diagonal element
1464
//                for (j=i; j<_rows; ++j)
1465
//                {
1466
//                        if (i == j)
1467
//                        {
1468
//                                tmp = 0.;
1469
//                                for (k=0; k<i; k++)
1470
//                                        tmp += get(k, i) * get(k, i);
1471
//                                if ((get(i, j) - tmp) < -0.) 
1472
//                                {
1473
//                                        std::stringstream ss;
1474
//                                        ss << "choleskyinverse(): Matrix is not positive definite:" << std::endl <<
1475
//                                                "  " << "decomposition value (" << i << ", " << j << " = " << 
1476
//                                                scientific << std::setprecision(6) << (get(i, j) - tmp) << ")" <<
1477
//                                                "  must be greater than zero.";                        
1478
//                                        throw boost::enable_current_exception(
1479
//                                        std::runtime_error(ss.str()));
1480
//                                }
1481
//                                put(i, j, pow((get(i, j) - tmp), .5));
1482
//                        }
1483
//                        else
1484
//                        {
1485
//                                tmp = 0.;
1486
//                                for (k=0; k<i; k++)
1487
//                                        tmp += get(k, i) * get(k, j);
1488
//                                put(i, j, (get(i, j) - tmp) / get(i, i));
1489
//                        }
1490
//                }
1491
//        }
1492
//} // DecomposeUpper()
1493
        
1494

1495
// scale()
1496
//
1497
matrix_2d matrix_2d::scale(const double& scalar)
83✔
1498
{
1499
        UINT32 i, j;
83✔
1500
        for (i=0; i<_rows; ++i)
332✔
1501
                for (j=0; j<_cols; ++j)
1,896✔
1502
                        *getelementref(i, j) *= scalar;
1,647✔
1503
        return *this;
83✔
1504
}
1505
                        
1506
void matrix_2d::blockadd(const UINT32& row_dest, const UINT32& col_dest, const matrix_2d& mat_src, 
10,641✔
1507
                                                 const UINT32& row_src, const UINT32& col_src, const UINT32& rows, const UINT32& cols)
1508
{
1509
        UINT32 i_dest, j_dest, i_src, j_src;
10,641✔
1510
        UINT32 i_dest_end(row_dest+rows), j_dest_end(col_dest+cols);
10,641✔
1511

1512
        for (i_dest=row_dest, i_src=row_src; i_dest<i_dest_end; ++i_dest, ++i_src)
42,564✔
1513
                for (j_dest=col_dest, j_src=col_src; j_dest<j_dest_end; ++j_dest, ++j_src) 
129,492✔
1514
                        elementadd(i_dest, j_dest, mat_src.get(i_src, j_src));
97,569✔
1515
}
10,641✔
1516
        
1517

1518

1519
// Same as blockadd, but adds transpose.  mat_src must be square.
1520
void matrix_2d::blockTadd(const UINT32& row_dest, const UINT32& col_dest, const matrix_2d& mat_src, 
72✔
1521
                                                 const UINT32& row_src, const UINT32& col_src, const UINT32& rows, const UINT32& cols)
1522
{
1523
        UINT32 i_dest, j_dest, i_src, j_src;
72✔
1524
        UINT32 i_dest_end(row_dest+rows), j_dest_end(col_dest+cols);
72✔
1525

1526
        for (i_dest=row_dest, i_src=row_src; i_dest<i_dest_end; ++i_dest, ++i_src)
288✔
1527
                for (j_dest=col_dest, j_src=col_src; j_dest<j_dest_end; ++j_dest, ++j_src) 
864✔
1528
                        elementadd(i_dest, j_dest, mat_src.get(j_src, i_src));
648✔
1529
}
72✔
1530
        
1531

1532
void matrix_2d::blocksubtract(const UINT32& row_dest, const UINT32& col_dest, const matrix_2d& mat_src, 
36✔
1533
                                                 const UINT32& row_src, const UINT32& col_src, const UINT32& rows, const UINT32& cols)
1534
{
1535
        UINT32 i_dest, j_dest, i_src, j_src;
36✔
1536
        UINT32 i_dest_end(row_dest+rows), j_dest_end(col_dest+cols);
36✔
1537

1538
        for (i_dest=row_dest, i_src=row_src; i_dest<i_dest_end; ++i_dest, ++i_src)
144✔
1539
                for (j_dest=col_dest, j_src=col_src; j_dest<j_dest_end; ++j_dest, ++j_src) 
432✔
1540
                        elementsubtract(i_dest, j_dest, mat_src.get(i_src, j_src));
324✔
1541
}
36✔
1542
        
1543

1544
// clearlower()
1545
void matrix_2d::clearlower()
×
1546
{
1547
        // Sets lower triangle elements to zero
1548
        UINT32 col, row;
×
1549
        for (row=1, col=0; col<_mem_cols; ++col, ++row)
×
1550
                memset(getelementref(row, col), 0, (_mem_rows - row) * sizeof(double));
×
1551
}
×
1552

1553
// filllower()
1554
void matrix_2d::filllower()
8,351✔
1555
{
1556
        // copies upper triangle to lower triangle
1557
        UINT32 column, row;
8,351✔
1558
        for (row=1; row<_rows; row++)
26,819✔
1559
                for (column=0; column<row; column++)
56,445✔
1560
                        put(row, column, get(column, row));
37,977✔
1561
}
8,351✔
1562
        
1563

1564
// fillupper()
1565
void matrix_2d::fillupper()
2,432✔
1566
{
1567
        // copies lower triangle to upper triangle
1568
        UINT32 column, row;
2,432✔
1569
        for (row=1; row<_rows; row++)
53,663✔
1570
                for (column=0; column<row; column++)
5,620,663✔
1571
                        put(column, row, get(row, column));
5,569,432✔
1572
}
2,432✔
1573
        
1574

1575
// zero()
1576
void matrix_2d::zero()
10,035✔
1577
{
1578
        memset(_buffer, 0, buffersize());
10,035✔
1579
}
10,035✔
1580
        
1581

1582
// zero()
1583
void matrix_2d::zero(const UINT32& row_begin, const UINT32& col_begin, 
304✔
1584
        const UINT32& rows, const UINT32& columns)
1585
{
1586
        
1587
        UINT32 col(0), col_end(col_begin+columns);
304✔
1588
        for (col=col_begin; col<col_end; ++col)
2,254✔
1589
                memset(getelementref(row_begin, col), 0, rows * sizeof(double));
1,950✔
1590
}
304✔
1591

1592
//// identity()
1593
//void matrix_2d::identity()
1594
//{
1595
//        // Turn matrix into an identity matrix:
1596
//        if (_rows != _cols)
1597
//                throw boost::enable_current_exception(std::runtime_error("identity(): Matrix is not square."));
1598
//        zero();
1599
//        for (UINT32 row=0; row<_rows; row++)
1600
//                put(row, row, 1.0);
1601
//}
1602
        
1603

1604
//void matrix_2d::identity(const UINT32& row_begin, const UINT32& col_begin)
1605
//{
1606
//        if (_rows-row_begin != _cols-col_begin)
1607
//                throw boost::enable_current_exception(std::runtime_error("identity(): the sub-matrix from [rowstart,columnstart] to the end is not square."));
1608
//
1609
//        UINT32 row, column;
1610
//
1611
//        // It is faster to zero the entire matrix and re-write diagonal terms than it is
1612
//        // to test every element for diagonal condition (i.e. if (row == column)
1613
//        zero(row_begin, col_begin, _rows - row_begin, _cols - col_begin);
1614
//
1615
//        column=col_begin;
1616
//        for (row=row_begin; row<_rows && column<_cols; row++)
1617
//                put(row, column++, 1.0);
1618
//}
1619

1620

1621
//void matrix_2d::identity(const UINT32& rowstart, const UINT32& columnstart,        const UINT32& rows, const UINT32& columns)
1622
//{
1623
//        if (rows != columns)
1624
//                throw boost::enable_current_exception(std::runtime_error("identity(): the specified sub-matrix is not square."));
1625
//
1626
//        UINT32 rowend(rowstart+rows), columnend(columnstart+columns);
1627
//
1628
//        if (rowend > _rows || columnend > _cols)
1629
//        {
1630
//                std::stringstream ss;
1631
//                ss << "identity(): " << std::endl;
1632
//                if (rowend >= _rows)
1633
//                        ss << "    Row index (destination) " << rowend << " exceeds the matrix row count (" << _rows << "). " << std::endl;
1634
//                if (columnend >= _cols)
1635
//                        ss << "    Column index (destination) " << columnend << " exceeds the matrix column count (" << _cols << ").";
1636
//                throw boost::enable_current_exception(std::runtime_error(ss.str()));
1637
//        }
1638
//
1639
//        UINT32 row, column;
1640
//
1641
//        // It is faster to zero the entire matrix and re-write diagonal terms than it is
1642
//        // to test every element for diagonal condition (i.e. if (row == column)
1643
//        for (row=rowstart; row<rowend; row++)
1644
//                for (column=columnstart; column<columnend; column++)
1645
//                        put(row, column, 0.0);
1646
//
1647
//        column=columnstart;
1648
//        for (row=rowstart; row<rowend && column<columnend; row++)
1649
//                put(row, column++, 1.0);
1650
//}
1651
        
1652

1653

1654
//// coutMatrix()
1655
////
1656
//void matrix_2d::coutmatrix(const std::string& sTitle, const short& precision) const
1657
//{
1658
//        std::cout << sTitle << " (" << _rows << "x" << _cols << ")" << std::endl;
1659
//        UINT32 column, row;
1660
//        std::stringstream ss;
1661
//        for (row=0; row<_rows; row++) {
1662
//                for (column=0; column<_cols; column++) {
1663
//                        ss.str("");
1664
//                        ss << std::fixed << std::setprecision(precision) << get(row, column) << " ";
1665
//                        if (precision < 1)
1666
//                                std::cout << std::setw(3) << ss.str();
1667
//                        else
1668
//                                std::cout << std::setw(precision + 4) << std::right << ss.str();
1669
//
1670
//                        if (column > 20)
1671
//                                break;
1672
//                }
1673
//                std::cout << std::endl;
1674
//                if (row > 20)
1675
//                        break;
1676
//                
1677
//        }
1678
//        std::cout << std::endl;
1679
//
1680
//} // coutMatrix()
1681
        
1682

1683
matrix_2d matrix_2d::operator=(const matrix_2d& rhs)
267,809✔
1684
{
1685
        // Overloaded assignment operator
1686
        if (this == &rhs)
267,809✔
1687
                return *this;
×
1688
        
1689
        // If rhs data can fit within limits of this matrix, copy
1690
        // and return. Otherwise, allocate new memory
1691
        if (_mem_rows >= rhs.rows() || _mem_cols >= rhs.columns())
267,809✔
1692
        {
1693
                // don't change _mem_rows or _mem_cols.  Simply update
1694
                // visible dimensions and copy buffer
1695
                _rows = rhs.rows();
267,774✔
1696
                _cols = rhs.columns();
267,774✔
1697
                copybuffer(_rows, _cols, rhs);
267,774✔
1698

1699
                _maxvalCol = rhs.maxvalueCol();                // col of max value
267,774✔
1700
                _maxvalRow = rhs.maxvalueRow();                // row of max value
267,774✔
1701
        
1702
                return *this;
267,774✔
1703
        }
1704

1705
        // Okay, rhs is larger, so allocate new memory. Call free
1706
        // memory first before changing row and column dimensions!
1707
        deallocate();        
35✔
1708
        _mem_rows = rhs.memRows();                                // change memory limits
35✔
1709
        _mem_cols = rhs.memColumns();
35✔
1710
        _rows = rhs.rows();                                                // change matrix dimensions
35✔
1711
        _cols = rhs.columns();
35✔
1712
        allocate(_mem_rows, _mem_cols);
35✔
1713
        copybuffer(_rows, _cols, rhs);
35✔
1714

1715
        _maxvalCol = rhs.maxvalueCol();                // col of max value
35✔
1716
        _maxvalRow = rhs.maxvalueRow();                // row of max value
35✔
1717
        
1718
        return *this;        
35✔
1719
}
1720

1721
// Multiplication operator
1722
matrix_2d matrix_2d::operator*(const double& rhs) const
2,226✔
1723
{
1724
        // Answer
1725
        matrix_2d m(_rows, _cols);
2,226✔
1726
        
1727
        UINT32 row, column;
1728
        for (row=0; row<_rows; row++)
8,904✔
1729
                for (column=0; column<_cols; ++column)
26,712✔
1730
                        m.put(row, column, get(row, column) * rhs);
20,034✔
1731
        return m;
2,226✔
1732
}
1733
        
1734

1735
//// Multiplication operator
1736
//matrix_2d matrix_2d::operator*(const matrix_2d& rhs) const
1737
//{
1738
//        if (_cols != rhs.rows())
1739
//                throw boost::enable_current_exception(std::runtime_error("operator*(): Matrix dimensions are incompatible."));
1740
//        
1741
//        matrix_2d m(_rows, rhs.columns());
1742
//        
1743
//        // Perform the multiplication:
1744
//        UINT32 row, column, i;
1745
//        for (row=0; row<_rows; row++) {
1746
//                for (column=0; column<rhs.columns(); ++column) {
1747
//                        m.put(row, column, 0.0);
1748
//                        for (i=0; i<_cols; ++i)
1749
//                                m.elementadd(row, column, get(row, i) * rhs.get(i, column));        
1750
//                }
1751
//        }
1752
//        return m;
1753
//}
1754
        
1755
        
1756
//// Addition operator
1757
////
1758
//matrix_2d matrix_2d::operator+(const matrix_2d& rhs) const
1759
//{
1760
//        if (_cols != rhs.rows())
1761
//                throw boost::enable_current_exception(std::runtime_error("operator+(): Matrix dimensions are incompatible."));
1762
//        
1763
//        matrix_2d m(_rows, rhs.columns());
1764
//        
1765
//        // Perform the multiplication:
1766
//        UINT32 row, column;
1767
//        for (row=0; row<_rows; row++) {
1768
//                for (column=0; column<rhs.columns(); ++column) {
1769
//                        m.put(row, column, get(row, column) + rhs.get(row, column));        
1770
//                }
1771
//        }
1772
//        return m;
1773
//}
1774
        
1775
        
1776
//// Subtraction operator
1777
////
1778
//matrix_2d matrix_2d::operator-(const matrix_2d& rhs) const
1779
//{
1780
//        if (_cols != rhs.rows())
1781
//                throw boost::enable_current_exception(std::runtime_error("operator-(): Matrix dimensions are incompatible."));
1782
//        
1783
//        matrix_2d m(_rows, rhs.columns());
1784
//        
1785
//        // Perform the multiplication:
1786
//        UINT32 row, column;
1787
//        for (row=0; row<_rows; row++) {
1788
//                for (column=0; column<rhs.columns(); ++column) {
1789
//                        m.put(row, column, get(row, column) - rhs.get(row, column));        
1790
//                }
1791
//        }
1792
//        return m;
1793
//}
1794
        
1795
        
1796
//// Multiplication-assignment operator
1797
////
1798
//// Is this needed?
1799
//matrix_2d matrix_2d::operator*=(const matrix_2d& rhs) 
1800
//{                        
1801
//        if (_cols != rhs.rows())
1802
//                throw boost::enable_current_exception(std::runtime_error("operator*=(): Matrix dimensions are incompatible."));
1803
//        
1804
//        matrix_2d m(_rows, rhs.columns());
1805
//        
1806
//        // Perform the multiplication:
1807
//        UINT32 row, column, i;
1808
//        for (row=0; row<_rows; row++) {
1809
//                for (column=0; column<rhs.columns(); ++column) {
1810
//                        m.put(row, column, 0.0);
1811
//                        for (i=0; i<_cols; ++i)
1812
//                                m.elementadd(row, column, get(row, i) * rhs.get(i, column));
1813
//                }
1814
//        }
1815
//        return (*this = m);
1816
//}
1817

1818
//// Addition-assignment operator
1819
////
1820
//matrix_2d matrix_2d::operator+=(const matrix_2d& rhs) 
1821
//{                        
1822
//        if (_cols != rhs.columns() || _rows != rhs.rows())
1823
//                throw boost::enable_current_exception(std::runtime_error("operator+=(): Matrix dimensions are incompatible."));
1824
//        
1825
//        // Perform the addition
1826
//        UINT32 row, column;
1827
//        for (row=0; row<_rows; ++row)
1828
//                for (column=0; column<_cols; ++column)
1829
//                        *getelementref(row, column) += rhs.get(row, column);
1830
//        return *this;
1831
//}
1832

1833
//// Subtraction-assignment operator
1834
////
1835
//matrix_2d matrix_2d::operator-=(const matrix_2d& rhs) 
1836
//{                        
1837
//        if (_cols != rhs.columns() || _rows != rhs.rows())
1838
//                throw boost::enable_current_exception(std::runtime_error("operator-=(): Matrix dimensions are incompatible."));
1839
//        
1840
//        // Perform the addition
1841
//        UINT32 row, column;
1842
//        for (row=0; row<_rows; ++row)
1843
//                for (column=0; column<_cols; ++column)
1844
//                        *getelementref(row, column) -= rhs.get(row, column);
1845
//        return *this;
1846
//}
1847

1848
matrix_2d matrix_2d::add(const matrix_2d& rhs)
152✔
1849
{
1850
        if (_rows != rhs.rows() || _cols != rhs.columns())
152✔
NEW
1851
                throw boost::enable_current_exception(std::runtime_error("add(): Result matrix dimensions are incompatible."));
×
1852
        
1853
        UINT32 row, column;
1854
        for (row=0; row<_rows; row++) {
22,232✔
1855
                for (column=0; column<_cols; ++column) {
44,160✔
1856
                        *getelementref(row, column) += rhs.get(row, column);        
22,080✔
1857
                }
1858
        }
1859
        return *this;
152✔
1860

1861
}
1862

1863
//matrix_2d matrix_2d::add(const matrix_2d& lhs, const matrix_2d& rhs)
1864
//{
1865
//        if (_rows != lhs.rows() || _cols != lhs.columns())
1866
//                throw boost::enable_current_exception(std::runtime_error("add(): Result matrix dimensions are incompatible."));
1867
//        
1868
//        if (_rows != rhs.rows() || _cols != rhs.columns())
1869
//                throw boost::enable_current_exception(std::runtime_error("add(): Result matrix dimensions are incompatible."));
1870
//        
1871
//        UINT32 row, column;
1872
//        for (row=0; row<_rows; row++) {
1873
//                for (column=0; column<_cols; ++column) {
1874
//                        *getelementref(row, column) = lhs.get(row, column) + rhs.get(row, column);        
1875
//                }
1876
//        }
1877
//        return *this;
1878
//
1879
//}
1880

1881
//// multiplies this matrix by rhs and stores the result in a new matrix
1882
//matrix_2d matrix_2d::multiply(const matrix_2d& rhs)
1883
//{
1884
//        if (_cols != rhs.rows())
1885
//                throw boost::enable_current_exception(std::runtime_error("multiply(): Matrix dimensions are incompatible."));
1886
//        
1887
//        matrix_2d m(_rows, rhs.columns());
1888
//        
1889
//        // Perform the multiplication
1890
//        UINT32 row, column, i;
1891
//        for (row=0; row<_rows; row++) {
1892
//                for (column=0; column<rhs.columns(); ++column) {
1893
//                        m.put(row, column, 0.0);
1894
//                        for (i=0; i<_cols; ++i)
1895
//                                m.elementadd(row, column, get(row, i) * rhs.get(i, column));
1896
//                }
1897
//        }
1898
//        return (*this = m);
1899
//}
1900
        
1901
// multiplies this matrix by rhs and stores the result in a new matrix
1902
// Uses Intel MKL dgemm
1903
matrix_2d matrix_2d::multiply_mkl(const char* lhs_trans, const matrix_2d& rhs, const char* rhs_trans)
265✔
1904
{
1905
        matrix_2d m(_rows, rhs.columns());
265✔
1906
        
1907
        const double one = 1.0;
265✔
1908
        const double zero = 0.0;
265✔
1909

1910
#if defined(_WIN64) || defined(__linux) || defined(sun) || defined(__unix__) || defined(__APPLE__)
1911
        long long lhs_rows(rows()), rhs_cols(rhs.columns());
265✔
1912
        long long lhs_cols(columns()), rhs_rows(rhs.rows());
265✔
1913
        long long new_mem_rows(memRows());
265✔
1914
        long long lhs_mem_rows(memRows());
265✔
1915
        long long rhs_mem_rows(memRows());
265✔
1916
#else // defined(_WIN32) || defined(__WIN32__)
1917
        int lhs_rows(rows()), rhs_cols(rhs.columns());
1918
        int lhs_cols(columns()), rhs_rows(rhs.rows());
1919
        int new_mem_rows(memRows());
1920
        int lhs_mem_rows(memRows());
1921
        int rhs_mem_rows(memRows());
1922
#endif        
1923

1924
        if (strcmp(lhs_trans, "T") == 0)
265✔
1925
        {
1926
                lhs_rows = columns();                // transpose
×
1927
                lhs_cols = rows();                        // transpose
×
1928
        }
1929

1930
        //if (rhs_trans == "T")
1931
        if (strcmp(rhs_trans, "T") == 0)
265✔
1932
        {
1933
                rhs_rows = rhs.columns();                // transpose
×
1934
                rhs_cols = rhs.rows();                        // transpose
×
1935
        }
1936

1937
        if (lhs_cols != rhs_rows)
265✔
NEW
1938
                throw boost::enable_current_exception(std::runtime_error("multiply_mkl(): Matrix dimensions are incompatible."));
×
1939
        else if (_rows != lhs_rows || _cols != rhs_cols)
265✔
NEW
1940
                throw boost::enable_current_exception(std::runtime_error("multiply_mkl(): Result matrix dimensions are incompatible."));
×
1941

1942
        dgemm(lhs_trans, rhs_trans,         // Type of matrices  
265✔
1943
                &lhs_rows,                      // rows of A
1944
                &rhs_cols,                                                 // columns of B
1945
                &lhs_cols,                                                // columns of A = rows of B
1946
                &one,                                                        // scalar: 1 (one)
1947
                _buffer,                                                // A matrix (this)
265✔
1948
                &lhs_mem_rows,                                        // rows of A
1949
                rhs.getbuffer(),                                // the B matrix
265✔
1950
                &rhs_mem_rows,                                        // same as rhs_rows        (columns of A = rows of B)
1951
                &zero,                                                        // scalar: 0 (zero)
1952
                m.getbuffer(),                                        // the resultant matrix
1953
                &new_mem_rows);                                        // rows of the resultant matrix
1954
        
1955
        return (*this = m);
530✔
1956
}
265✔
1957
        
1958
//// Multiplies lhs by rhs and stores the result in this.
1959
//matrix_2d matrix_2d::multiply(const matrix_2d& lhs, const matrix_2d& rhs)
1960
//{
1961
//        if (lhs.columns() != rhs.rows())
1962
//                throw boost::enable_current_exception(std::runtime_error("multiply(): Matrix dimensions are incompatible."));
1963
//        else if (_rows != lhs.rows() || _cols != rhs.columns())
1964
//                throw boost::enable_current_exception(std::runtime_error("multiply(): Result matrix dimensions are incompatible."));
1965
//        
1966
//        // Perform the multiplication
1967
//        UINT32 row, column, i;
1968
//        for (row=0; row<lhs.rows(); row++) {
1969
//                for (column=0; column<rhs.columns(); ++column) {
1970
//                        put(row, column, 0.0);
1971
//                        for (i=0; i<lhs.columns(); ++i)
1972
//                                *getelementref(row, column) += lhs.get(row, i) * rhs.get(i, column);        
1973
//                }
1974
//        }
1975
//
1976
//        return *this;
1977
//} // Multiply()
1978
        
1979

1980
// Multiplies lhs by rhs and stores the result in this.
1981
// Uses Intel MKL dgemm
1982
matrix_2d matrix_2d::multiply_mkl(const matrix_2d& lhs, const char* lhs_trans, 
20,439✔
1983
        const matrix_2d& rhs, const char* rhs_trans)
1984
{
1985
        const double one = 1.0;
20,439✔
1986
        const double zero = 0.0;
20,439✔
1987

1988
#if defined(_WIN64) || defined(__linux) || defined(sun) || defined(__unix__) || defined(__APPLE__)
1989
        long long lhs_rows(lhs.rows()), rhs_cols(rhs.columns());
20,439✔
1990
        long long lhs_cols(lhs.columns()), rhs_rows(rhs.rows());
20,439✔
1991
        long long new_mem_rows(memRows());
20,439✔
1992
        long long lhs_mem_rows(lhs.memRows());
20,439✔
1993
        long long rhs_mem_rows(rhs.memRows());
20,439✔
1994
#else // defined(_WIN32) || defined(__WIN32__)
1995
        int lhs_rows(lhs.rows()), rhs_cols(rhs.columns());
1996
        int lhs_cols(lhs.columns()), rhs_rows(rhs.rows());
1997
        int new_mem_rows(memRows());
1998
        int lhs_mem_rows(lhs.memRows());
1999
        int rhs_mem_rows(rhs.memRows());
2000
#endif        
2001

2002
        if (strncmp(lhs_trans, "T", 1) == 0)
20,439✔
2003
        {
2004
                lhs_rows = lhs.columns();                // transpose
8,894✔
2005
                lhs_cols = lhs.rows();                        // transpose
8,894✔
2006
        }
2007

2008
        if (strncmp(rhs_trans, "T", 1) == 0)
20,439✔
2009
        {
2010
                rhs_rows = rhs.columns();                // transpose
444✔
2011
                rhs_cols = rhs.rows();                        // transpose
444✔
2012
        }
2013

2014
        if (lhs_cols != rhs_rows)
20,439✔
NEW
2015
                throw boost::enable_current_exception(std::runtime_error("multiply_mkl(): Matrix dimensions are incompatible."));
×
2016
        else if (_rows != lhs_rows || _cols != rhs_cols)
20,439✔
NEW
2017
                throw boost::enable_current_exception(std::runtime_error("multiply_mkl(): Result matrix dimensions are incompatible."));
×
2018

2019
        dgemm(lhs_trans, rhs_trans,         // Type of matrices  
20,439✔
2020
                &lhs_rows,                      // rows of A
2021
                &rhs_cols,                                                 // columns of B
2022
                &lhs_cols,                                                // columns of A = rows of B
2023
                &one,                                                        // scalar: 1 (one)
2024
                lhs.getbuffer(),                                // A matrix
20,439✔
2025
                &lhs_mem_rows,                                        // rows of A
2026
                rhs.getbuffer(),                                // the B matrix
20,439✔
2027
                &rhs_mem_rows,                                        // same as rhs_rows        (columns of A = rows of B)
2028
                &zero,                                                        // scalar: 0 (zero)
2029
                _buffer,                                                // the resultant matrix (this)
2030
                &new_mem_rows);                                        // rows of the resultant matrix
2031

2032
        return *this;
20,439✔
2033
} // Multiply()
2034
        
2035

2036
//// Multiply_Square()
2037
//// Stores the multiplication of two matrices.  Assumes the result will be square, hence the upper
2038
//// triangular component is calculated first, then the lower is copied from the upper.
2039
//matrix_2d matrix_2d::multiply_square(const matrix_2d& lhs, const matrix_2d& rhs)
2040
//{
2041
//        //if (lhs.columns() != rhs.rows())
2042
//        //        throw boost::enable_current_exception(std::runtime_error("multiply_square(): Matrix dimensions are incompatible."));
2043
//        //else if (_rows != lhs.rows() || _cols != rhs.columns())
2044
//        //        throw boost::enable_current_exception(std::runtime_error("multiply_square(): Result matrix dimensions are incompatible."));
2045
//        //else if (_rows != _cols)
2046
//        //        throw boost::enable_current_exception(std::runtime_error("multiply_square(): Result matrix must be square."));
2047
//        //
2048
//        //// Perform the multiplication:
2049
//        //UINT32 row, column, i;
2050
//        //for (row=0; row<lhs.rows(); row++) {
2051
//        //        for (column=row; column<rhs.columns(); ++column) {
2052
//        //                put(row, column, 0.0);
2053
//        //                for (i=0; i<lhs.columns(); ++i)
2054
//        //                        *getelementref(row, column) += lhs.get(row, i) * rhs.get(i, column);
2055
//        //        }
2056
//        //}
2057
//
2058
//        multiply_square_triangular(lhs, rhs);
2059
//
2060
//        filllower();
2061
//        return *this;
2062
//} // Multiply()
2063
        
2064

2065
//// Multiply_Square()
2066
//// Stores the multiplication of two matrices.  Assumes the result will be square, hence the upper
2067
//// triangular component is calculated.
2068
//matrix_2d matrix_2d::multiply_square_triangular(const matrix_2d& lhs, const matrix_2d& rhs)
2069
//{
2070
//        if (lhs.columns() != rhs.rows())
2071
//                throw boost::enable_current_exception(std::runtime_error("multiply_square_triangular(): Matrix dimensions are incompatible."));
2072
//        else if (_rows != lhs.rows() || _cols != rhs.columns())
2073
//                throw boost::enable_current_exception(std::runtime_error("multiply_square_triangular(): Result matrix dimensions are incompatible."));
2074
//        else if (_rows != _cols)
2075
//                throw boost::enable_current_exception(std::runtime_error("multiply_square_triangular(): Result matrix must be square."));
2076
//        
2077
//        // Perform the multiplication:
2078
//        UINT32 row, column, i;
2079
//        for (row=0; row<lhs.rows(); row++) {
2080
//                for (column=row; column<rhs.columns(); ++column) {
2081
//                        put(row, column, 0.0);
2082
//                        for (i=0; i<lhs.columns(); ++i)
2083
//                                *getelementref(row, column) += lhs.get(row, i) * rhs.get(i, column);
2084
//                }
2085
//        }
2086
//        return *this;
2087
//} // Multiply()
2088
        
2089

2090
//// Multiply_square_t()
2091
////
2092
//// Stores the multiplication of one matrix by the transpose of the second.  Assumes the result will be square, hence the upper
2093
//// triangular component is calculated. The lower is copied from the upper.
2094
//// 
2095
//matrix_2d matrix_2d::multiply_square_t(const matrix_2d& lhs, const matrix_2d& rhs)
2096
//{
2097
//        if (lhs.columns() != rhs.rows())
2098
//                throw boost::enable_current_exception(std::runtime_error("multiply_square_t(): Matrix dimensions are incompatible."));
2099
//        else if (_rows != lhs.rows() || _cols != rhs.columns())
2100
//                throw boost::enable_current_exception(std::runtime_error("multiply_square_t(): Result matrix dimensions are incompatible."));
2101
//        else if (_rows != _cols)
2102
//                throw boost::enable_current_exception(std::runtime_error("multiply_square_t(): Result matrix must be square."));
2103
//        
2104
//        // Perform the multiplication:
2105
//        UINT32 row, column, i;
2106
//        for (row=0; row<lhs.rows(); row++) {
2107
//                for (column=row; column<rhs.columns(); ++column) {
2108
//                        put(row, column, 0.0);
2109
//                        for (i=0; i<lhs.columns(); ++i)
2110
//                                *getelementref(row, column) += lhs.get(row, i) * rhs.get(column, i);
2111
//                }
2112
//        }
2113
//        filllower();
2114
//        return *this;
2115
//} // Multiply()
2116
        
2117

2118
// Transpose()
2119
matrix_2d matrix_2d::transpose(const matrix_2d& matA)
10,441✔
2120
{
2121
        if ((matA.columns() != _rows) || (matA.rows() != _cols))
10,441✔
NEW
2122
                throw boost::enable_current_exception(std::runtime_error("transpose(): Matrix dimensions are incompatible."));
×
2123

2124
        UINT32 column, row;
2125
        for (row=0; row<_rows; row++)
41,764✔
2126
                for (column=0; column<_cols; column++)
125,292✔
2127
                        *getelementref(row, column) = matA.get(column, row);
93,969✔
2128
        return *this;
10,441✔
2129
} // Transpose()
2130

2131

2132
// Transpose()
2133
matrix_2d matrix_2d::transpose()
104✔
2134
{
2135
        matrix_2d m(_cols, _rows);
104✔
2136
        UINT32 column, row;
2137
        for (row=0; row<_rows; row++)
1,337✔
2138
                for (column=0; column<_cols; column++)
2,466✔
2139
                        m.put(column, row, get(row, column));
1,233✔
2140
        return m;
104✔
2141
} // Transpose()
2142
        
2143

2144
// computes and retains the maximum value in the matrix
2145
double matrix_2d::compute_maximum_value()
118✔
2146
{
2147
        _maxvalCol = _maxvalRow = 0;
118✔
2148
        UINT32 col, row;
118✔
2149
        for (row=0; row<_rows; ++row) {
10,267✔
2150
                for (col=0; col<_cols; col++) {
20,298✔
2151
                        if (fabs(get(row, col)) > fabs(get(_maxvalRow, _maxvalCol))) {
10,149✔
2152
                                _maxvalCol = col;
415✔
2153
                                _maxvalRow = row;
415✔
2154
                        }
2155
                }
2156
        }
2157
        return get(_maxvalRow, _maxvalCol);
118✔
2158
}
2159

2160
//// compares the first column only (i.e. use this to compare a vector of coordinates)
2161
//double matrix_2d::vectordifference(const matrix_2d& rhs)
2162
//{
2163
//        if (_rows != rhs.rows() && _cols != rhs.columns())
2164
//                throw boost::enable_current_exception(std::runtime_error("vectordifference(): Matrix dimensions are incompatible."));
2165
//
2166
//        double diffPrev(0.), diff(0.);
2167
//        for (UINT32 row=0; row<_rows; ++row)
2168
//        {
2169
//                if ((diff = fabs(get(row, 0) - rhs.get(row, 0))) > diffPrev)
2170
//                        diffPrev = diff;
2171
//        }
2172
//        return diffPrev;
2173
//}
2174

2175
//// stores the difference between two matrices (lhs - rhs)
2176
//void matrix_2d::difference(const matrix_2d* lhs, const matrix_2d* rhs)
2177
//{
2178
//        if (_rows != rhs->rows() && _cols != rhs->columns())
2179
//                throw boost::enable_current_exception(std::runtime_error("difference(): Matrix dimensions are incompatible."));
2180
//
2181
//        if (_rows != lhs->rows() && _cols != lhs->columns())
2182
//                throw boost::enable_current_exception(std::runtime_error("difference(): Matrix dimensions are incompatible."));
2183
//
2184
//        UINT32 i, j;
2185
//        for (i=0; i<_rows; ++i)
2186
//                for (j=0; j<_cols; ++j)
2187
//                        put(i, j, lhs->get(i, j) - rhs->get(i, j));
2188
//}
2189

2190
//// stores the difference between two matrices (lhs - rhs) beginning at row and col
2191
//void matrix_2d::difference(const UINT32& row_begin, const UINT32& col_begin, const matrix_2d& lhs, const matrix_2d& rhs)
2192
//{
2193
//        if (lhs.rows() != rhs.rows() && lhs.columns() != rhs.columns())
2194
//                throw boost::enable_current_exception(std::runtime_error("differenceabs(): Matrix dimensions are incompatible."));
2195
//        if (row_begin >= _rows)
2196
//                return;
2197
//        if (col_begin >= _cols)
2198
//                return;
2199
//        if (row_begin + lhs.rows() > _rows)
2200
//                return;
2201
//        if (col_begin + lhs.columns() > _cols)
2202
//                return;
2203
//        
2204
//        UINT32 i, ii(row_begin), j, jj(col_begin);
2205
//
2206
//        for (i=0; i<lhs.rows(); ++i, ++ii)
2207
//                for (j=0; j<lhs.columns(); ++j, +jj)
2208
//                        put(ii, jj, lhs.get(i, j) - rhs.get(i, j));
2209
//}
2210
        
2211

2212
//void matrix_2d::differenceabs(const matrix_2d& lhs, const matrix_2d& rhs)
2213
//{
2214
//        if (_rows != rhs.rows() && _cols != rhs.columns())
2215
//                throw boost::enable_current_exception(std::runtime_error("differenceabs(): Matrix dimensions are incompatible."));
2216
//
2217
//        if (_rows != lhs.rows() && _cols != lhs.columns())
2218
//                throw boost::enable_current_exception(std::runtime_error("differenceabs(): Matrix dimensions are incompatible."));
2219
//
2220
//        UINT32 i, j;
2221
//        for (i=0; i<_rows; ++i)
2222
//                for (j=0; j<_cols; ++j)
2223
//                        put(i, j, fabs(lhs.get(i, j) - rhs.get(i, j)));
2224
//}
2225

2226
//void matrix_2d::differenceabs(const matrix_2d& lhs, const matrix_2d* rhs)
2227
//{
2228
//        if (_rows != rhs->rows() && _cols != rhs->columns())
2229
//                throw boost::enable_current_exception(std::runtime_error("differenceabs(): Matrix dimensions are incompatible."));
2230
//
2231
//        if (_rows != lhs.rows() && _cols != lhs.columns())
2232
//                throw boost::enable_current_exception(std::runtime_error("differenceabs(): Matrix dimensions are incompatible."));
2233
//
2234
//        UINT32 i, j;
2235
//        for (i=0; i<_rows; ++i)
2236
//                for (j=0; j<_cols; ++j)
2237
//                        put(i, j, fabs(lhs.get(i, j) - rhs->get(i, j)));
2238
//}
2239

2240
#ifdef _MSDEBUG
2241
void matrix_2d::trace(const std::string& comment, const std::string& format) const
2242
{
2243
        UINT32 i, j;
2244
        if (comment.empty())
2245
                TRACE("%d %d\n", _rows, _cols);
2246
        else
2247
                TRACE("%s (%d, %d):\n", comment.c_str(), _rows, _cols);
2248
        for (i=0; i<_rows; ++i) {
2249
                for (j=0; j<_cols; ++j)
2250
                        TRACE(format.c_str(), get(i, j));
2251
                TRACE("\n");
2252
        } TRACE("\n");
2253
}
2254
#endif
2255

2256
#ifdef _MSDEBUG
2257
void matrix_2d::trace(const std::string& comment, const std::string& submat_comment, const std::string& format, 
2258
                                          const UINT32& row_begin, const UINT32& col_begin, const UINT32& rows, const UINT32& columns) const
2259
{
2260
        // comparison of unsigned expression < 0 is always false
2261
        if (row_begin >= _rows) {        
2262
                TRACE("%d %d lies outside the range of the matrix (%d %d)\n", row_begin, col_begin, _rows, _cols);
2263
                return;
2264
        }
2265
        // comparison of unsigned expression < 0 is always false
2266
        if (col_begin >= _cols) {        
2267
                TRACE("%d %d lies outside the range of the matrix (%d %d)\n", row_begin, col_begin, _rows, _cols);
2268
                return;
2269
        }
2270
        if (row_begin + rows > _rows) {        
2271
                TRACE("%d %d lies outside the range of the matrix (%d %d)\n", row_begin, col_begin, _rows, _cols);
2272
                return;
2273
        }
2274
        if (col_begin + columns > _cols) {        
2275
                TRACE("%d %d lies outside the range of the matrix (%d %d)\n", row_begin, col_begin, _rows, _cols);
2276
                return;
2277
        }
2278
        
2279
        if (comment.empty())
2280
                TRACE("%d %d, %s submatrix (%d, %d, %d*%d)\n", _rows, _cols, submat_comment.c_str(), row_begin, col_begin, rows, columns);
2281
        else
2282
                TRACE("%s (%d, %d), %s submatrix (%d, %d, %d*%d)\n", comment, _rows, _cols, submat_comment.c_str(), row_begin, col_begin, rows, columns);
2283

2284
        UINT32 i, j, row_end(row_begin+rows), col_end(col_begin+columns);
2285

2286
        for (i=row_begin; i<row_end; ++i) {
2287
                for (j=col_begin; j<col_end; ++j) 
2288
                        TRACE(format.c_str(), get(i, j));
2289
                TRACE("\n");
2290
        } TRACE("\n");
2291
}
2292
#endif
2293

2294

2295
} // namespace math 
2296
} // namespace dynadjust 
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc