00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00026 #ifndef _ARAGELI_matrix_hpp_
00027 #define _ARAGELI_matrix_hpp_
00028
00029 #include "config.hpp"
00030
00031 #include <cstddef>
00032 #include <iostream>
00033 #include <vector>
00034 #include <utility>
00035
00036 #include "frwrddecl.hpp"
00037
00038 #include "type_opers.hpp"
00039 #include "type_traits.hpp"
00040 #include "type_pair_traits.hpp"
00041 #include "exception.hpp"
00042 #include "refcntr.hpp"
00043 #include "factory.hpp"
00044 #include "cmp.hpp"
00045 #include "io.hpp"
00046 #include "vector.hpp"
00047
00048 #include "std_import.hpp"
00049
00050
00051 namespace Arageli
00052 {
00053
00054
00056
00057 struct nonsquare_t {};
00058
00061
00062
00063
00065
00066 struct colwise_t {};
00067
00069
00070 const colwise_t colwise = colwise_t();
00071
00072
00074
00075 struct diag_t {};
00076
00078
00079 const diag_t diag = diag_t();
00080
00081
00083
00084 struct eye_t {};
00085
00087
00088 const eye_t eye = eye_t();
00089
00090
00091 struct frommat_t {};
00092 const frommat_t frommat = frommat_t();
00093
00094
00095 namespace _Internal
00096 {
00097
00098 template <typename T>
00099 struct Rep_matrix
00100 {
00101
00102 typedef std::vector<T> Mem;
00103 typedef typename Mem::size_type size_type;
00104 size_type rows, cols;
00105 Mem mem;
00106
00107 Rep_matrix () : rows(0), cols(0) {}
00108
00109 void assign (size_type rows_a, size_type cols_a, const T& val)
00110 { rows = rows_a; cols = cols_a; mem.assign(rows*cols, val); }
00111
00112 template <typename In>
00113 void assign (size_type rows_a, size_type cols_a, In b, In e)
00114 {
00115 rows = rows_a; cols = cols_a; mem.assign(b, e);
00116 ARAGELI_ASSERT_1(rows*cols == mem.size());
00117 }
00118 };
00119
00120 }
00121 }
00122
00123
00124 namespace std
00125 {
00126
00127 template <typename T>
00128 inline void swap
00129 (
00130 Arageli::_Internal::Rep_matrix<T>& a,
00131 Arageli::_Internal::Rep_matrix<T>& b
00132 )
00133 {
00134 swap(a.mem, b.mem);
00135 swap(a.rows, b.rows);
00136 swap(a.cols, b.cols);
00137 }
00138
00139 }
00140
00141
00142 namespace Arageli
00143 {
00144
00145
00147
00151 template
00152 <
00153 typename T,
00154 bool REFCNT
00155 >
00156 class matrix
00157 {
00158 template <typename T1, bool REFCNT1>
00159 friend class matrix;
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 typedef _Internal::Rep_matrix<T> Rep;
00183 typedef typename Rep::Mem Mem;
00184
00185 public:
00186
00187
00188
00190
00191
00193
00195 typedef typename Mem::value_type value_type;
00196
00198 typedef typename Mem::value_type element_type;
00199
00201 typedef typename Mem::reference reference;
00202
00204 typedef typename Mem::const_reference const_reference;
00205
00207 typedef typename Mem::pointer pointer;
00208
00210 typedef typename Mem::const_pointer const_pointer;
00211
00213
00214 typedef typename Mem::size_type size_type;
00215
00217 typedef typename Mem::difference_type difference_type;
00218
00220 typedef typename Rep::Mem::iterator iterator;
00221
00223 typedef typename Rep::Mem::const_iterator const_iterator;
00224
00225
00226
00227
00229 template <typename T1> struct other_element_type
00230 { typedef matrix<T1, REFCNT> type; };
00231
00233 template <typename T1, bool REFCNT1> struct other_element_type_refcnt
00234 { typedef matrix<T1, REFCNT1> type; };
00235
00237
00238 static const bool refcounting = REFCNT;
00239
00240
00241
00243
00244
00246
00247
00249 matrix () {}
00250
00251
00252
00253
00254
00255
00256
00257
00258
00260 matrix (std::size_t size_a, const fromsize_t& select)
00261 { assign_fromsize(size_a); }
00262
00263
00265 matrix (const char* s, const fromstr_t& select)
00266 { assign_fromstr(s); }
00267
00268
00270 template <typename Vec>
00271 matrix (const Vec& vec, const fromvec_t& select)
00272 { assign_fromvec(vec); }
00273
00274
00276 template <typename Mat>
00277 matrix (const Mat& mat, const frommat_t& select)
00278 { assign_frommat(mat); }
00279
00280
00282 template <typename X>
00283 matrix (const X& x)
00284 { assign(x); }
00285
00286
00287
00288
00289
00291
00294 template <typename Val>
00295 matrix (size_type rowscols_a, const Val& val, const fromval_t& select)
00296 { assign_fromval(rowscols_a, val); }
00297
00298
00300
00304 template <typename Seq>
00305 matrix (size_type rowscols_a, const Seq& seq, const fromseq_t& select)
00306 { assign_fromseq(rowscols_a, seq); }
00307
00308
00310
00312 matrix (size_type rows_a, size_type cols_a, const fromsize_t& select)
00313 { assign_fromsize(rows_a, cols_a); }
00314
00315
00317 template <typename Vec>
00318 matrix (size_type rows_a, const Vec& vec, const fromvec_t& select)
00319 { assign_fromvec(rows_a, vec); }
00320
00321
00323 template <typename X>
00324 matrix (size_type rowscols_a, const X& x)
00325 { assign(rowscols_a, x); }
00326
00327
00328
00329
00330
00332 template <typename Vec>
00333 matrix (const Vec& vec, const colwise_t& select)
00334 { assign_colwise(vec); }
00335
00336
00338 template <typename Vec>
00339 matrix
00340 (
00341 size_type cols_a, const Vec& vec,
00342 const colwise_t& select_1, const fromvec_t& select_2
00343 )
00344 { assign_colwise_fromvec(cols_a, vec); }
00345
00346
00348 template <typename Seq>
00349 matrix
00350 (
00351 size_type rowcols_a, const Seq& seq,
00352 const colwise_t& select_1, const fromseq_t& select_2
00353 )
00354 { assign_colwise_fromseq(rowcols_a, seq); }
00355
00356
00357 template <typename X>
00358 matrix (size_type rowcols_a, const X& x, const colwise_t& select)
00359 { assign_colwise(rowcols_a, x); }
00360
00361
00363 template <typename Seq>
00364 matrix
00365 (
00366 size_type rows_a, size_type cols_a,
00367 const Seq& seq, const colwise_t& select
00368 )
00369 { assign_colwise(rows_a, cols_a, seq); }
00370
00371
00372
00373
00374
00376
00379 template <typename Val>
00380 matrix
00381 (
00382 size_type rows_a, size_type cols_a,
00383 const Val& val,
00384 const fromval_t& select
00385 )
00386 { assign_fromval(rows_a, cols_a, val); }
00387
00388
00390
00394 template <typename Seq>
00395 matrix
00396 (
00397 size_type rows_a, size_type cols_a,
00398 const Seq& seq,
00399 const fromseq_t& select
00400 )
00401 { assign_fromseq(rows_a, cols_a, seq); }
00402
00403
00405
00416 template <typename X>
00417 matrix (size_type rows_a, size_type cols_a, const X& x)
00418 { assign(rows_a, cols_a, x); }
00419
00420
00421
00422
00423
00425
00427 template <typename Vec>
00428 matrix (const Vec& vec, const diag_t& select)
00429 { assign_diag(vec); }
00430
00431
00433
00435 template <typename Val>
00436 matrix
00437 (
00438 size_type rowscols_a, const Val& val,
00439 const diag_t& select_1,
00440 const fromval_t& select_2
00441 )
00442 { assign_diag_fromval(rowscols_a, val); }
00443
00444
00446
00448 template <typename Seq>
00449 matrix
00450 (
00451 size_type rowscols_a, const Seq& seq,
00452 const diag_t& select_1,
00453 const fromseq_t& select_2
00454 )
00455 { assign_diag_fromseq(rowscols_a, seq); }
00456
00457
00459
00461 template <typename Vec>
00462 matrix
00463 (
00464 size_type rowscols_a, const Vec& vec,
00465 const diag_t& select_1,
00466 const fromvec_t& select_2
00467 )
00468 { assign_diag_fromvec(rowscols_a, vec); }
00469
00470
00472 template <typename X>
00473 matrix
00474 (
00475 size_type rowscols_a, const X& x,
00476 const diag_t& select
00477 )
00478 { assign_diag(rowscols_a, x); }
00479
00480
00482
00485 template <typename Val>
00486 matrix
00487 (
00488 size_type rows_a, size_type cols_a,
00489 const Val& val,
00490 const diag_t& select_1,
00491 const fromval_t& select_2
00492 )
00493 { assign_diag_fromval(rows_a, cols_a, val); }
00494
00495
00497
00500 template <typename Seq>
00501 matrix
00502 (
00503 size_type rows_a, size_type cols_a, const Seq& seq,
00504 const diag_t& select_1,
00505 const fromseq_t& select_2
00506 )
00507 { assign_diag_fromseq(rows_a, cols_a, seq); }
00508
00509
00511
00514 template <typename Vec>
00515 matrix
00516 (
00517 size_type rows_a, size_type cols_a, const Vec& vec,
00518 const diag_t& select_1,
00519 const fromvec_t& select_2
00520 )
00521 { assign_diag_fromvec(rows_a, cols_a, vec); }
00522
00523
00525
00528 template <typename X>
00529 matrix
00530 (
00531 size_type rows_a, size_type cols_a,
00532 const X& x,
00533 const diag_t& select
00534 )
00535 { assign_diag(rows_a, cols_a, x); }
00536
00537
00538
00539
00540
00542
00545 matrix (size_type rowscols_a, const eye_t& select)
00546 { assign_eye(rowscols_a); }
00547
00548
00550
00553 matrix
00554 (
00555 size_type rows_a, size_type cols_a,
00556 const eye_t& select
00557 )
00558 { assign_eye(rows_a, cols_a); }
00559
00560
00561
00562
00563
00565
00566
00567
00568
00569
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00585
00586
00587
00588
00589
00590
00591
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00634
00635
00636
00637
00638
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00681
00682
00683
00685 void assign_fromsize (std::size_t size_a)
00686 { assign_fromsize(size_a, size_a); }
00687
00688
00690 void assign_fromstr (const char* s);
00691
00692
00694 template <typename Vec>
00695 void assign_fromvec (const Vec& vec)
00696 { assign_fromseq(1u, vec.size(), vec.begin()); }
00697
00698
00700 template <typename Mat>
00701 void assign_frommat (const Mat& mat)
00702 { assign_fromseq(mat.nrows(), mat.ncols(), mat.begin()); }
00703
00704
00705
00706
00707
00709
00712 template <typename Val>
00713 void assign_fromval (size_type rowscols_a, const Val& val)
00714 { assign_fromval(rowscols_a, rowscols_a, val); }
00715
00716
00718
00722 template <typename Seq>
00723 void assign_fromseq (size_type rowscols_a, const Seq& seq)
00724 { assign_fromseq(rowscols_a, rowscols_a, seq); }
00725
00726
00728
00730 void assign_fromsize (size_type rows_a, size_type cols_a)
00731 { assign_fromval(rows_a, cols_a, factory<T>::null()); }
00732
00733
00735 template <typename Vec>
00736 void assign_fromvec (size_type rows_a, const Vec& vec);
00737
00738
00739
00740
00741
00743 template <typename Vec>
00744 void assign_colwise (const Vec& vec);
00745
00746
00748 template <typename Vec>
00749 void assign_colwise_fromvec (size_type cols_a, const Vec& vec);
00750
00751
00753 template <typename Seq>
00754 void assign_colwise_fromseq (size_type rowcols_a, const Seq& seq);
00755
00756
00757 template <typename X>
00758 void assign_colwise (size_type rowcols_a, const X& x);
00759
00760
00762 template <typename Seq>
00763 void assign_colwise
00764 (size_type rows_a, size_type cols_a, const Seq& seq);
00765
00766
00767
00768
00769
00771
00774 template <typename Val>
00775 void assign_fromval
00776 (size_type rows_a, size_type cols_a, const Val& val);
00777
00778
00780
00784 template <typename Seq>
00785 void assign_fromseq
00786 (size_type rows_a, size_type cols_a, Seq seq);
00787
00788
00789
00790
00791
00793
00795 template <typename Vec>
00796 void assign_diag (const Vec& vec)
00797 { assign_diag_fromseq(vec.size(), vec.begin()); }
00798
00799
00801
00803 template <typename Val>
00804 void assign_diag_fromval (size_type rowscols_a, const Val& val)
00805 { assign_diag_fromval(rowscols_a, rowscols_a, val); }
00806
00807
00809
00811 template <typename Seq>
00812 void assign_diag_fromseq (size_type rowscols_a, const Seq& seq)
00813 { assign_diag_fromseq(rowscols_a, rowscols_a, seq); }
00814
00815
00817
00819 template <typename Vec>
00820 void assign_diag_fromvec (size_type rowscols_a, const Vec& vec)
00821 { assign_diag_fromseq(rowscols_a, vec.begin()); }
00822
00823
00825 template <typename X>
00826 void assign_diag (size_type rowscols_a, const X& x)
00827 { assign_diag(rowscols_a, rowscols_a, x); }
00828
00829
00831
00834 template <typename Val>
00835 void assign_diag_fromval
00836 (size_type rows_a, size_type cols_a, const Val& val);
00837
00838
00840
00843 template <typename Seq>
00844 void assign_diag_fromseq
00845 (size_type rows_a, size_type cols_a, Seq seq);
00846
00847
00849
00852 template <typename Vec>
00853 void assign_diag_fromvec
00854 (size_type rows_a, size_type cols_a, const Vec& vec)
00855 { assign_diag_fromseq(rows_a, cols_a, vec.begin()); }
00856
00857
00859
00862 template <typename X>
00863 void assign_diag
00864 (size_type rows_a, size_type cols_a, const X& x)
00865 { _assign_diag_val_seq_vec(rows_a, cols_a, x, type_traits<X>::category_value); }
00866
00867 private:
00868
00869 template <typename Val>
00870 void _assign_diag_val_seq_vec
00871 (size_type rows_a, size_type cols_a, const Val& val, const type_category::type&)
00872 { assign_diag_fromval(rows_a, cols_a, val); }
00873
00874 template <typename Seq>
00875 void _assign_diag_val_seq_vec
00876 (size_type rows_a, size_type cols_a, const Seq& seq, const type_category::iterator&)
00877 { assign_diag_fromseq(rows_a, cols_a, seq); }
00878
00879 template <typename Vec>
00880 void _assign_diag_val_seq_vec
00881 (size_type rows_a, size_type cols_a, const Vec& vec, const type_category::vector&)
00882 { assign_diag_fromvec(rows_a, cols_a, vec); }
00883
00884 public:
00885
00886
00887
00888
00890
00893 void assign_eye (size_type rowscols_a)
00894 { assign_eye(rowscols_a, rowscols_a); }
00895
00896
00898
00901 void assign_eye (size_type rows_a, size_type cols_a)
00902 { assign_diag_fromval(rows_a, cols_a, factory<T>::unit()); }
00903
00904
00906
00907
00908
00910
00911
00912
00913
00914
00916 void assign ()
00917 { resize(0, 0); }
00918
00919
00920
00921
00922
00924
00925
00926
00927
00929
00930
00931
00932
00934
00935
00936
00937
00938
00940
00941
00942
00943
00944
00946 template <typename X>
00947 void assign (const X& x)
00948 { _assign_size_str_vec_mat(x, type_traits<X>::category_value); }
00949
00950 private:
00951
00952 template <typename Size>
00953 void _assign_size_str_vec_mat
00954 (const Size& size_a, const type_category::integer&)
00955 { assign_fromsize(size_a); }
00956
00957 template <typename Str>
00958 void _assign_size_str_vec_mat
00959 (const Str& s, const type_category::string&)
00960 { assign_fromstr(s); }
00961
00962 template <typename Vec>
00963 void _assign_size_str_vec_mat
00964 (const Vec& vec, const type_category::vector&)
00965 { assign_fromvec(vec); }
00966
00967 template <typename Mat>
00968 void _assign_size_str_vec_mat
00969 (const Mat& mat, const type_category::matrix&)
00970 { assign_frommat(mat); }
00971
00972 public:
00973
00974
00975
00976
00979
00980
00981
00982
00983
00984
00985
00988
00989
00990
00991
00992
00993
00994
00995
00998
00999
01000
01001
01002
01004
01005
01006
01007
01008
01010 template <typename X>
01011 void assign (size_type rowscols_a, const X& x)
01012 {
01013 _assign_seq_size_vec
01014 (
01015 rowscols_a, x,
01016 type_traits<X>::category_value
01017
01018 );
01019 }
01020
01021
01022 private:
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032 template <typename Seq>
01033 void _assign_seq_size_vec
01034 (
01035 size_type rowscols_a, const Seq& seq,
01036 const type_category::iterator&
01037 )
01038 { assign_fromseq(rowscols_a, seq); }
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048 template <typename Size>
01049 void _assign_seq_size_vec
01050 (
01051 size_type rows_a, const Size& cols_a,
01052 const type_category::integer&
01053 )
01054 { assign_fromsize(rows_a, cols_a); }
01055
01056 template <typename Vec>
01057 void _assign_seq_size_vec
01058 (
01059 size_type rows_a, const Vec& vec,
01060 const type_category::vector&
01061 )
01062 { assign_fromvec(rows_a, vec); }
01063
01064 public:
01065
01066
01067
01068
01070
01071
01072
01073
01074
01076
01077
01078
01079
01080
01081
01082
01083
01084
01086
01087
01088
01089
01090
01091
01092
01093
01094
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01138
01144 template <typename X>
01145 void assign (size_type rows_a, size_type cols_a, const X& x)
01146 {
01147 _assign_val_seq
01148 (
01149 rows_a, cols_a, x,
01150 bool_type<type_pair_traits<X, T>::is_assignable>::value
01151 );
01152 }
01153
01154
01155 private:
01156
01157 template <typename Val>
01158 void _assign_val_seq
01159 (
01160 size_type rows_a, size_type cols_a, const Val& val,
01161 const true_type&
01162 )
01163 { assign_fromval(rows_a, cols_a, val); }
01164
01165 template <typename Seq>
01166 void _assign_val_seq
01167 (
01168 size_type rows_a, size_type cols_a, const Seq& seq,
01169 const false_type&
01170 )
01171 { assign_fromseq(rows_a, cols_a, seq); }
01172
01173 public:
01174
01175
01176
01177
01180
01181
01182
01183
01184
01185
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01226
01227
01228
01229
01230
01231
01232
01233
01234
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01293
01294
01297
01298
01299
01300
01301
01302
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317 template <typename X>
01318 matrix& operator= (const X& x)
01319 {
01320 _assign_from_val_str_vec_mat
01321 (
01322 x, type_traits<X>::category_value,
01323 bool_type<type_pair_traits<X, T>::is_assignable>::value
01324 );
01325
01326 return *this;
01327 }
01328
01329 private:
01330
01331 template <typename Val>
01332 void _assign_from_val_str_vec_mat
01333 (const Val& val, const type_category::type&, const true_type&)
01334 { fill_fromval(val); }
01335
01336 template <typename Str>
01337 void _assign_from_val_str_vec_mat
01338 (const Str& str, const type_category::string&, const false_type&)
01339 { assign_fromstr(str); }
01340
01341 template <typename Vec>
01342 void _assign_from_val_str_vec_mat
01343 (const Vec& vec, const type_category::vector&, const false_type&)
01344 { assign_fromvec(vec); }
01345
01346 template <typename Mat>
01347 void _assign_from_val_str_vec_mat
01348 (const Mat& mat, const type_category::matrix&, const false_type&)
01349 { assign_frommat(mat); }
01350
01351 public:
01352
01354
01355 #if 0
01356
01358
01359 template <typename T1, bool REFCNT1>
01360 matrix& operator= (const matrix<T1, REFCNT1>& x)
01361 {
01362 ARAGELI_ASSERT_1
01363 (
01364 reinterpret_cast<const void*>(this) !=
01365 reinterpret_cast<const void*>(&x)
01366 );
01367
01368 unique_clear();
01369 rep().assign(x.nrows(), x.ncols(), x.mem().begin(), x.mem().end());
01370 return *this;
01371 }
01372
01374 template <typename T1>
01375 matrix& operator= (const T1& v)
01376 {
01377 unique_clear();
01378 std::fill(mem().begin(), mem().end(), v);
01379 return *this;
01380 }
01381
01382 matrix& operator= (const char* s)
01383 { return *this = matrix(s); }
01384
01385
01387 void assign ()
01388 {
01389 unique_clear();
01390 mem().clear();
01391 rep().rows = 0;
01392 rep().cols = 0;
01393 }
01394
01395
01397
01399 void assign (size_type rowscols_a)
01400 {
01401 unique_clear();
01402 rep().assign(rowscols_a, rowscols_a, factory<T>::null());
01403 }
01404
01405
01407
01412 void assign (size_type rows_a, size_type cols_a)
01413 {
01414 unique_clear();
01415 rep().assign(rows_a, cols_a, factory<T>::null());
01416 }
01417
01418
01420
01422 void assign
01423 (
01424 size_type rows_a, size_type cols_a,
01425 const nonsquare_t& select
01426 )
01427 {
01428 unique_clear();
01429 rep().assign(rows_a, cols_a, factory<T>::null());
01430 }
01431
01432
01433
01434
01435
01437
01440 template <typename T1>
01441 void assign (size_type rowscols_a, const T1& val, const fromval_t& select)
01442 { assign_fromval(rowscols_a, val); }
01443
01444
01446
01450 template <typename In>
01451 void assign (size_type rowscols_a, const In& in, const fromseq_t& select)
01452 { assign_fromseq(rowscols_a, in); }
01453
01454
01456
01459 template <typename T1>
01460 void assign_fromval (size_type rowscols_a, const T1& val)
01461 {
01462 unique_clear();
01463 rep().assign(rowscols_a, rowscols_a, val);
01464 }
01465
01466
01468
01472 template <typename In>
01473 void assign_fromseq (size_type rowscols_a, const In& in)
01474 {
01475 unique_clear();
01476 In last = in;
01477 std::advance(last, rowscols_a*rowscols_a);
01478 rep().assign(rowscols_a, rowscols_a, in, last);
01479 }
01480
01481
01483
01494 template <typename In_or_T1>
01495 void assign (size_type rowscols_a, const In_or_T1& x)
01496 {
01497 assign_from_seq_or_val
01498 (
01499 rowscols_a, x,
01500 bool_type<type_pair_traits<In_or_T1, T>::is_convertible>::value
01501 );
01502 }
01503
01504
01505 template <typename In_or_T1>
01506 void assign_from_seq_or_val
01507 (size_type rowscols_a, const In_or_T1& x, const true_type&)
01508 { assign_fromval(rowscols_a, x); }
01509
01510
01511 template <typename In_or_T1>
01512 void assign_from_seq_or_val
01513 (size_type rowscols_a, const In_or_T1& x, const false_type&)
01514 { assign_fromseq(rowscols_a, x); }
01515
01516
01517
01518
01519
01521
01524 template <typename T1>
01525 void assign
01526 (
01527 size_type rows_a, size_type cols_a,
01528 const T1& val, const fromval_t& select
01529 )
01530 { assign_fromval(rows_a, cols_a, val); }
01531
01532
01534
01538 template <typename In>
01539 void assign
01540 (
01541 size_type rows_a, size_type cols_a,
01542 const In& in, const fromseq_t& select
01543 )
01544 { assign_fromseq(rows_a, cols_a, in); }
01545
01546
01548
01551 template <typename T1>
01552 void assign_fromval (size_type rows_a, size_type cols_a, const T1& val)
01553 {
01554 unique_clear();
01555 rep().assign(rows_a, cols_a, val);
01556 }
01557
01558
01560
01564 template <typename In>
01565 void assign_fromseq (size_type rows_a, size_type cols_a, const In& in)
01566 {
01567 unique_clear();
01568 In last = in;
01569 std::advance(last, rows_a*cols_a);
01570 rep().assign(rows_a, cols_a, in, last);
01571 }
01572
01573
01575
01586 template <typename In_or_T1>
01587 void assign (size_type rows_a, size_type cols_a, const In_or_T1& x)
01588 {
01589 assign_from_seq_or_val
01590 (
01591 rows_a, cols_a, x,
01592 bool_type<type_pair_traits<In_or_T1, T>::is_convertible>::value
01593 );
01594 }
01595
01596
01597 template <typename In_or_T1>
01598 void assign_from_seq_or_val
01599 (size_type rows_a, size_type cols_a, const In_or_T1& x, const true_type&)
01600 { assign_fromval(rows_a, cols_a, x); }
01601
01602
01603 template <typename In_or_T1>
01604 void assign_from_seq_or_val
01605 (size_type rows_a, size_type cols_a, const In_or_T1& x, const false_type&)
01606 { assign_fromseq(rows_a, cols_a, x); }
01607
01608
01609
01610
01611
01613
01617 template <typename In>
01618 void assign
01619 (
01620 size_type rowscols_a, const In& in,
01621 const colwise_t& select
01622 )
01623 { assign_colwise(rowscols_a, in); }
01624
01625
01627
01631 template <typename In>
01632 void assign
01633 (
01634 size_type rows_a, size_type cols_a,
01635 const In& in,
01636 const colwise_t& select
01637 )
01638 { assign_colwise(rows_a, cols_a, in); }
01639
01640
01642
01646 template <typename In>
01647 void assign_colwise (size_type rowscols_a, const In& in)
01648 { assign_colwise(rowscols_a, rowscols_a, in); }
01649
01650
01652
01656 template <typename In>
01657 void assign_colwise
01658 (size_type rows_a, size_type cols_a, In in);
01659
01660
01661
01662
01663
01665
01668 template <typename T1>
01669 void assign
01670 (
01671 size_type rowscols_a, const T1& val,
01672 const diag_t& select_1,
01673 const fromval_t& select_2
01674 )
01675 { assign_diag_fromval(rowscols_a, val); }
01676
01677
01679
01683 template <typename In>
01684 void assign
01685 (
01686 size_type rowscols_a, const In& in,
01687 const diag_t& select_1,
01688 const fromseq_t& select_2
01689 )
01690 { assign_diag_fromseq(rowscols_a, in); }
01691
01692
01694
01697 template <typename T1>
01698 void assign_diag_fromval (size_type rowscols_a, const T1& val)
01699 { assign_diag_fromval(rowscols_a, rowscols_a, val); }
01700
01701
01703
01707 template <typename In>
01708 void assign_diag_fromseq (size_type rowscols_a, const In& in)
01709 { assign_diag_fromseq(rowscols_a, rowscols_a, in); }
01710
01711
01713
01725 template <typename In_or_T1>
01726 void assign_diag (size_type rowscols_a, const In_or_T1& x)
01727 {
01728 assign_diag_from_seq_or_val
01729 (
01730 rowscols_a, x,
01731 bool_type<type_pair_traits<In_or_T1, T>::is_convertible>::value
01732 );
01733 }
01734
01735
01737
01738 template <typename In_or_T1>
01739 void assign
01740 (
01741 size_type rowscols_a, const In_or_T1& x,
01742 const diag_t& select_1
01743 )
01744 { assign_diag(rowscols_a, x); }
01745
01746
01747 template <typename In_or_T1>
01748 void assign_diag_from_seq_or_val
01749 (size_type rowscols_a, const In_or_T1& x, const true_type&)
01750 { assign_diag_fromval(rowscols_a, x); }
01751
01752
01753 template <typename In_or_T1>
01754 void assign_diag_from_seq_or_val
01755 (size_type rowscols_a, const In_or_T1& x, const false_type&)
01756 { assign_diag_fromseq(rowscols_a, x); }
01757
01758
01759
01760
01761
01763
01766 template <typename T1>
01767 void assign
01768 (
01769 size_type rows_a, size_type cols_a,
01770 const T1& val,
01771 const diag_t& select_1,
01772 const fromval_t& select_2
01773 )
01774 { assign_diag_fromval(rows_a, cols_a, val); }
01775
01776
01778
01782 template <typename In>
01783 void assign
01784 (
01785 size_type rows_a, size_type cols_a,
01786 const In& in,
01787 const diag_t& select_1,
01788 const fromseq_t& select_2
01789 )
01790 { assign_diag_fromseq(rows_a, cols_a, in); }
01791
01792
01794
01797 template <typename T1>
01798 void assign_diag_fromval (size_type rows_a, size_type cols_a, const T1& val);
01799
01800
01802
01806 template <typename In>
01807 void assign_diag_fromseq (size_type rows_a, size_type cols_a, In in);
01808
01809
01811
01823 template <typename In_or_T1>
01824 void assign_diag
01825 (
01826 size_type rows_a, size_type cols_a,
01827 const In_or_T1& x
01828 )
01829 {
01830 assign_diag_from_seq_or_val
01831 (
01832 rows_a, cols_a, x,
01833 bool_type<type_pair_traits<In_or_T1, T>::is_convertible>::value
01834 );
01835 }
01836
01837
01839
01840 template <typename In_or_T1>
01841 void assign
01842 (
01843 size_type rows_a, size_type cols_a,
01844 const In_or_T1& x,
01845 const diag_t& select_1
01846 )
01847 { assign_diag(rows_a, cols_a, x); }
01848
01849
01850 template <typename In_or_T1>
01851 void assign_diag_from_seq_or_val
01852 (
01853 size_type rows_a, size_type cols_a,
01854 const In_or_T1& x, const true_type&
01855 )
01856 { assign_diag_fromval(rows_a, cols_a, x); }
01857
01858
01859 template <typename In_or_T1>
01860 void assign_diag_from_seq_or_val
01861 (
01862 size_type rows_a, size_type cols_a,
01863 const In_or_T1& x, const false_type&
01864 )
01865 { assign_diag_fromseq(rows_a, cols_a, x); }
01866
01867
01868
01869
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01899
01900
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01915
01918 void assign
01919 (
01920 size_type rowscols_a,
01921 const eye_t& select
01922 )
01923 {
01924 unique_clear();
01925 assign_diag_fromval(rowscols_a, factory<T>::unit());
01926 }
01927
01929
01933 void assign
01934 (
01935 size_type rows_a, size_type cols_a,
01936 const eye_t& select
01937 )
01938 {
01939 unique_clear();
01940 assign_diag_fromval(rows_a, cols_a, factory<T>::unit());
01941 }
01942
01943 #endif
01944
01945
01946
01947
01948
01950
01951
01952
01953
01955
01956 const_reference el (size_type i, size_type j) const
01957 {
01958 ARAGELI_ASSERT_0(i < nrows() && j < ncols());
01959 return mem(i*ncols() + j);
01960 }
01961
01963
01964 reference el (size_type i, size_type j)
01965 {
01966 ARAGELI_ASSERT_0(i < nrows() && j < ncols());
01967 unique();
01968 return mem(i*ncols() + j);
01969 }
01970
01972
01973 const_reference operator() (size_type i, size_type j) const
01974 { return el(i, j); }
01975
01977
01978 reference operator() (size_type i, size_type j)
01979 { return el(i, j); }
01980
01982
01984 const_reference at (size_type i, size_type j) const
01985 {
01986 if(i > nrows() || j > ncols())throw out_of_range();
01987 return el(i, j);
01988 }
01989
01991
01993 reference at (size_type i, size_type j)
01994 {
01995 if(i > nrows() || j > ncols())throw out_of_range();
01996 return el(i, j);
01997 }
01998
01999
02000
02001
02002 void resize (size_type rows_a, size_type cols_a)
02003 {
02004 unique_clear();
02005 mem().resize(rows_a*cols_a);
02006 rep().rows = rows_a;
02007 rep().cols = cols_a;
02008 }
02009
02010
02011 bool pack ()
02012 {
02013 if(size() != capacity())
02014 {
02015 do_pack();
02016 return true;
02017 }
02018 else return false;
02019 }
02020
02021
02022
02023
02024
02025
02027 size_type nrows () const { return rep().rows; }
02028
02030 size_type ncols () const { return rep().cols; }
02031
02033 size_type size () const { return mem().size(); }
02034
02036
02039 size_type length () const { return std::max(nrows(), ncols()); }
02040
02041 size_type capacity () const { return mem().capacity(); }
02042
02044
02047 bool is_empty () const
02048 {
02049 ARAGELI_ASSERT_1(!mem().empty() || (nrows() == 0 || ncols() == 0));
02050 return mem().empty();
02051 }
02052
02054
02057 bool is_null () const;
02058
02060
02063 bool is_unit () const;
02064
02066
02069 bool is_opposite_unit () const;
02070
02072
02073 bool is_square () const { return nrows() == ncols(); }
02074
02075
02076
02077
02078
02079
02081
02083 matrix& opposite ();
02084
02086
02090 matrix& inverse ();
02091
02093
02095 matrix& each_inverse ();
02096
02097
02098 template <typename T1> matrix& add_scalar (const T1& x);
02099 template <typename T1> matrix& sub_scalar (const T1& x);
02100 template <typename T1> matrix& mul_scalar (const T1& x);
02101 template <typename T1> matrix& div_scalar (const T1& x);
02102 template <typename T1> matrix& mod_scalar (const T1& x);
02103 template <typename T1> matrix& bitand_scalar (const T1& x);
02104 template <typename T1> matrix& bitor_scalar (const T1& x);
02105 template <typename T1> matrix& bitxor_scalar (const T1& x);
02106 template <typename T1> matrix& shl_scalar (const T1& x);
02107 template <typename T1> matrix& shr_scalar (const T1& x);
02108
02109 template <typename T1> matrix& add_matrix (const T1& x) { return each_add_matrix(x); }
02110 template <typename T1> matrix& sub_matrix (const T1& x) { return each_sub_matrix(x); }
02111 template <typename T1> matrix& mul_matrix (const T1& x);
02112 template <typename T1> matrix& div_matrix (const T1& x);
02113 template <typename T1> matrix& mod_matrix (const T1& x) { return each_mod_matrix(x); }
02114 template <typename T1> matrix& bitand_matrix (const T1& x) { return each_bitand_matrix(x); }
02115 template <typename T1> matrix& bitor_matrix (const T1& x) { return each_bitor_matrix(x); }
02116 template <typename T1> matrix& bitxor_matrix (const T1& x) { return each_bitxor_matrix(x); }
02117 template <typename T1> matrix& shl_matrix (const T1& x) { return each_shl_matrix(x); }
02118 template <typename T1> matrix& shr_matrix (const T1& x) { return each_shr_matrix(x); }
02119
02120 template <typename T1> matrix& each_add_matrix (const T1& x);
02121 template <typename T1> matrix& each_sub_matrix (const T1& x);
02122 template <typename T1> matrix& each_mul_matrix (const T1& x);
02123 template <typename T1> matrix& each_div_matrix (const T1& x);
02124 template <typename T1> matrix& each_mod_matrix (const T1& x);
02125 template <typename T1> matrix& each_bitand_matrix (const T1& x);
02126 template <typename T1> matrix& each_bitor_matrix (const T1& x);
02127 template <typename T1> matrix& each_bitxor_matrix (const T1& x);
02128 template <typename T1> matrix& each_shl_matrix (const T1& x);
02129 template <typename T1> matrix& each_shr_matrix (const T1& x);
02130
02131
02138
02139 template <typename T1> matrix& operator+= (const T1& x) { return add_scalar(x); }
02140 template <typename T1> matrix& operator-= (const T1& x) { return sub_scalar(x); }
02141 template <typename T1> matrix& operator*= (const T1& x) { return mul_scalar(x); }
02142 template <typename T1> matrix& operator/= (const T1& x) { return div_scalar(x); }
02143 template <typename T1> matrix& operator%= (const T1& x) { return mod_scalar(x); }
02144 template <typename T1> matrix& operator&= (const T1& x) { return bitand_scalar(x); }
02145 template <typename T1> matrix& operator|= (const T1& x) { return bitor_scalar(x); }
02146 template <typename T1> matrix& operator^= (const T1& x) { return bitxor_scalar(x); }
02147 template <typename T1> matrix& operator<<= (const T1& x) { return shl_scalar(x); }
02148 template <typename T1> matrix& operator>>= (const T1& x) { return shr_scalar(x); }
02149
02150
02151
02152 matrix& operator+= (const T& x) { return add_scalar(x); }
02153 matrix& operator-= (const T& x) { return sub_scalar(x); }
02154 matrix& operator*= (const T& x) { return mul_scalar(x); }
02155 matrix& operator/= (const T& x) { return div_scalar(x); }
02156 matrix& operator%= (const T& x) { return mod_scalar(x); }
02157 matrix& operator&= (const T& x) { return bitand_scalar(x); }
02158 matrix& operator|= (const T& x) { return bitor_scalar(x); }
02159 matrix& operator^= (const T& x) { return bitxor_scalar(x); }
02160 matrix& operator<<= (const T& x) { return shl_scalar(x); }
02161 matrix& operator>>= (const T& x) { return shr_scalar(x); }
02162
02163
02164
02165
02166
02167
02168
02175
02176 template <typename T1, bool REFCNT1>
02177 matrix& operator+= (const matrix<T1, REFCNT1>& x) { return add_matrix(x); }
02178
02179 template <typename T1, bool REFCNT1>
02180 matrix& operator-= (const matrix<T1, REFCNT1>& x) { return sub_matrix(x); }
02181
02182 template <typename T1, bool REFCNT1>
02183 matrix& each_add (const matrix<T1, REFCNT1>& x) { return each_add_matrix(x); }
02184
02185 template <typename T1, bool REFCNT1>
02186 matrix& each_sub (const matrix<T1, REFCNT1>& x) { return each_sub_matrix(x); }
02187
02188 template <typename T1, bool REFCNT1>
02189 matrix& each_mul (const matrix<T1, REFCNT1>& x) { return each_mul_matrix(x); }
02190
02191 template <typename T1, bool REFCNT1>
02192 matrix& each_div (const matrix<T1, REFCNT1>& x) { return each_div_matrix(x); }
02193
02194 template <typename T1, bool REFCNT1>
02195 matrix& each_mod (const matrix<T1, REFCNT1>& x) { return each_mod_matrix(x); }
02196
02197 template <typename T1, bool REFCNT1>
02198 matrix& each_bitand (const matrix<T1, REFCNT1>& x) { return each_bitand_matrix(x); }
02199
02200 template <typename T1, bool REFCNT1>
02201 matrix& each_bitor (const matrix<T1, REFCNT1>& x) { return each_bitor_matrix(x); }
02202
02203 template <typename T1, bool REFCNT1>
02204 matrix& each_bitxor (const matrix<T1, REFCNT1>& x) { return each_bitxor_matrix(x); }
02205
02206 template <typename T1, bool REFCNT1>
02207 matrix& each_shl (const matrix<T1, REFCNT1>& x) { return each_shl_matrix(x); }
02208
02209 template <typename T1, bool REFCNT1>
02210 matrix& each_shr (const matrix<T1, REFCNT1>& x) { return each_shr_matrix(x); }
02211
02212
02213
02214
02216 template <typename T1, bool REFCNT1>
02217 matrix& operator*= (const matrix<T1, REFCNT1>& x) { return mul_matrix(x); }
02218
02220
02225 template <typename T1, bool REFCNT1>
02226 matrix& operator/= (const matrix<T1, REFCNT1>& x) { return div_matrix(x); }
02227
02229
02230 matrix operator- () const
02231 {
02232 matrix res(*this);
02233 return res.opposite();
02234 }
02235
02237 const matrix& operator+ () const { return *this; }
02238
02239 matrix& operator++ ()
02240 {
02241 std::for_each(begin(), end(), func::prefix_increment<T, T&>());
02242 return *this;
02243 }
02244
02245 matrix operator++ (int) { matrix t = *this; operator++(); return t; }
02246
02247 matrix& operator-- ()
02248 {
02249 std::for_each(begin(), end(), func::prefix_decrement<T, T&>());
02250 return *this;
02251 }
02252
02253 matrix operator-- (int) { matrix t = *this; operator--(); return t; }
02254
02255
02256
02257
02258
02260 void transpose ();
02261
02263 template <typename T1, bool REFCNT1>
02264 void swap (matrix<T1, REFCNT1>& x)
02265 {
02266 _Internal::swap_help_1
02267 (*this, x, store, x.store, equal_types<T, T1>::value);
02268 }
02269
02270
02271
02273
02274
02275
02276
02278
02279 iterator begin () { unique(); return mem().begin(); }
02280
02282
02283 iterator end () { unique(); return mem().end(); }
02284
02286 const_iterator begin () const { return mem().begin(); }
02287
02289 const_iterator end () const { return mem().end(); }
02290
02291
02292
02293
02294
02296
02297
02298
02299
02301
02302 void insert_row (size_type pos, const T& val);
02303
02305
02307 template <typename T1, bool REFCNT1>
02308 void insert_row (size_type pos, const vector<T1, REFCNT1>& vals);
02309
02311
02312 template <typename In>
02313 void insert_row (size_type pos, In first);
02314
02316
02317 void insert_rows (size_type pos, size_type n, const T& val);
02318
02320
02322 template <typename T1, bool REFCNT1>
02323 void insert_rows (size_type pos, size_type n, const vector<T1, REFCNT1>& vals);
02324
02326
02327 template <typename In>
02328 void insert_rows (size_type pos, size_type n, In first);
02329
02331 void erase_row (size_type pos);
02332
02334 void erase_rows (size_type pos, size_type n);
02335
02337 void swap_rows (size_type xpos, size_type ypos);
02338
02340 template <typename T1>
02341 void mult_row (size_type i, const T1& x);
02342
02344 template <typename T1>
02345 void div_row (size_type i, const T1& x);
02346
02348 template <typename T1>
02349 void mod_row (size_type i, const T1& x);
02350
02352 void add_rows (size_type dstpos, size_type srcpos);
02353
02355 void sub_rows (size_type dstpos, size_type srcpos);
02356
02358 template <typename T2>
02359 void addmult_rows (size_type dstpos, size_type srcpos, const T2& y);
02360
02362 template <typename T1, typename T2>
02363 void addmult_rows
02364 (
02365 size_type dstpos, const T1& x,
02366 size_type srcpos, const T2& y
02367 );
02368
02369
02371 template <typename T1, typename T2>
02372 void addmult_rows
02373 (
02374 size_type dstpos, const T1& x,
02375 int srcpos, const T2& y
02376 )
02377 { addmult_rows(dstpos, x, size_type(srcpos), y); }
02378
02379
02381 template <typename T1, typename V, typename T2>
02382 void addmult_rows
02383 (
02384 size_type dstpos, const T1& x,
02385 const V& srcvec, const T2& y
02386 );
02387
02389 vector<T, true> copy_row (size_type i) const
02390
02391 { return vector<T, true>(ncols(), begin() + i*ncols()); }
02392
02394
02395 template <typename V>
02396 V& copy_row (size_type i, V& res) const
02397 {
02398
02399 res.assign(ncols(), begin() + i*ncols());
02400 return res;
02401 }
02402
02403 template <typename SV>
02404 matrix<T, true> copy_rows (const SV& sv) const
02405 {
02406 matrix<T, true> res;
02407 return copy_rows(sv, res);
02408 }
02409
02410 template <typename SV, typename M>
02411 M& copy_rows (const SV& sv, M& res) const;
02412
02413 template <typename SV>
02414 void erase_rows (const SV& sv);
02415
02416 template <typename SV, typename M>
02417 M& take_rows (const SV& sv, M& res)
02418 {
02419 copy_rows(sv, res);
02420 erase_rows(sv);
02421 return res;
02422 }
02423
02424 template <typename SV>
02425 matrix<T, true> take_rows (const SV& sv)
02426 {
02427 matrix<T, true> res;
02428 return take_rows(sv, res);
02429 }
02430
02431
02432 template <typename V>
02433 V& take_row (size_type i, V& res)
02434 {
02435 copy_row(i, res);
02436 erase_row(i);
02437 return res;
02438 }
02439
02440 vector<T, true> take_row (size_type i)
02441 {
02442 vector<T, true> res;
02443 return take_row(i, res);
02444 }
02445
02446
02447 template <typename V>
02448 void assign_row (size_type i, const V& v)
02449 {
02450 ARAGELI_ASSERT_0(i < nrows());
02451 ARAGELI_ASSERT_0(v.size() >= ncols());
02452 std::copy(v.begin(), v.begin() + ncols(), begin() + ncols()*i);
02453 }
02454
02455
02456
02457
02458
02459
02461
02462
02463
02464
02466
02467 void insert_col (size_type pos, const T& val);
02468
02470
02472 template <typename T1, bool REFCNT1>
02473 void insert_col (size_type pos, const vector<T1, REFCNT1>& vals);
02474
02476
02477 template <typename In>
02478 void insert_col (size_type pos, In first);
02479
02481
02482 void insert_cols (size_type pos, size_type n, const T& val);
02483
02485
02487 template <typename T1, bool REFCNT1>
02488 void insert_cols (size_type pos, size_type n, const vector<T1, REFCNT1>& vals);
02489
02491
02492 template <typename In>
02493 void insert_cols (size_type pos, size_type n, In first);
02494
02496 void erase_col (size_type pos);
02497
02499 void erase_cols (size_type pos, size_type n);
02500
02502 void swap_cols (size_type xpos, size_type ypos);
02503
02505 template <typename T1>
02506 void mult_col (size_type i, const T1& x);
02507
02509 template <typename T1>
02510 void div_col (size_type i, const T1& x);
02511
02513 template <typename T1>
02514 void mod_col (size_type i, const T1& x);
02515
02517 void add_cols (size_type dstpos, size_type srcpos);
02518
02520 void sub_cols (size_type dstpos, size_type srcpos);
02521
02523 template <typename T2>
02524 void addmult_cols (size_type dstpos, size_type srcpos, const T2& y);
02525
02527 template <typename T1, typename T2>
02528 void addmult_cols
02529 (
02530 size_type dstpos, const T1& x,
02531 size_type srcpos, const T2& y
02532 );
02533
02535 template <typename T1, typename T2>
02536 void addmult_cols
02537 (
02538 size_type dstpos, const T1& x,
02539 int srcpos, const T2& y
02540 )
02541 { addmult_cols(dstpos, x, size_type(srcpos), y); }
02542
02544 template <typename T1, typename V, typename T2>
02545 void addmult_cols
02546 (
02547 size_type dstpos, const T1& x,
02548 const V& srcvec, const T2& y
02549 );
02550
02552 vector<T, true> copy_col (size_type i) const
02553 {
02554 vector<T, true> res;
02555 return copy_col(i, res);
02556 }
02557
02559
02560 template <typename V>
02561 V& copy_col (size_type i, V& res) const;
02562
02563 template <typename SV>
02564 matrix<T, true> copy_cols (const SV& sv) const
02565 {
02566 matrix<T, true> res;
02567 return copy_cols(sv, res);
02568 }
02569
02570 template <typename SV, typename M>
02571 M& copy_cols (const SV& sv, M& res) const;
02572
02573 template <typename SV>
02574 void erase_cols (const SV& sv);
02575
02576 template <typename SV, typename M>
02577 M& take_cols (const SV& sv, M& res)
02578 {
02579 copy_cols(sv, res);
02580 erase_cols(sv);
02581 return res;
02582 }
02583
02584 template <typename SV>
02585 matrix<T, true> take_cols (const SV& sv)
02586 {
02587 matrix<T, true> res;
02588 return take_cols(sv, res);
02589 }
02590
02591 template <typename V>
02592 V& take_col (size_type i, V& res)
02593 {
02594 copy_col(i, res);
02595 erase_col(i);
02596 return res;
02597 }
02598
02599 vector<T, true> take_col (size_type i)
02600 {
02601 vector<T, true> res;
02602 return take_col(i, res);
02603 }
02604
02605 template <typename V>
02606 void assign_col (size_type j, const V& v)
02607 {
02608 ARAGELI_ASSERT_0(j < ncols());
02609 ARAGELI_ASSERT_0(v.size() >= nrows());
02610
02611 for(size_type i = 0; i < nrows(); ++i)
02612 el(i, j) = v[i];
02613 }
02614
02615
02616
02617
02618 template <typename M>
02619 void insert_matrix_bottom (const M& m)
02620 {
02621 ARAGELI_ASSERT_0(m.ncols() == ncols());
02622
02623
02624 for(size_type i = 0; i < m.nrows(); ++i)
02625 insert_row(nrows(), m.copy_row(i));
02626 }
02627
02628
02629 template <typename RS, typename CS>
02630 matrix<T, true> copy_submatrix (const RS& rs, const CS& cs) const
02631 {
02632 matrix<T, true> res;
02633 return copy_submatrix(rs, cs, res);
02634 }
02635
02636 template <typename RS, typename CS, typename M>
02637 M& copy_submatrix (const RS& rs, const CS& cs, M& res) const;
02638
02639 template <typename RS, typename CS>
02640 void erase_submatrix (const RS& rs, const CS& cs);
02641
02642 template <typename RS, typename CS, typename M>
02643 M& take_submatrix (const RS& rs, const CS& cs, M& res)
02644 {
02645 copy_submatrix(rs, cs, res);
02646 erase_submatrix(rs, cs);
02647 return res;
02648 }
02649
02650 template <typename RS, typename CS>
02651 matrix<T, true> take_submatrix (const RS& rs, const CS& cs)
02652 {
02653 matrix<T, true> res;
02654 return take_submatrix(rs, cs, res);
02655 }
02656
02657
02659
02666 bool unique () { return store.unique(); }
02667
02669
02674 bool unique_clear () { return store.unique_clear(); }
02675
02676 private:
02677
02678 Rep& rep () { return store.value(); }
02679 const Rep& rep () const { return store.value(); }
02680
02681 Mem& mem () { return rep().mem; }
02682 const Mem& mem () const { return rep().mem; }
02683
02684 reference mem (size_type i) { return mem()[i]; }
02685 const_reference mem (size_type i) const { return mem()[i]; }
02686
02687 bool do_pack ();
02688
02689 refcntr_proxy<Rep, REFCNT> store;
02690 };
02691
02692
02693 #if 0
02694
02696 template <typename TE2, bool REFCNTE2>
02697 struct type_pair_traits<big_int, matrix<TE2, REFCNTE2> >
02698 : public type_pair_traits_for_unknown_and_vector_matrix
02699 <big_int, matrix<TE2, REFCNTE2> > {};
02700
02701 #endif
02702
02703 template <typename T, bool REFCNT>
02704 matrix<T, true> transpose (const matrix<T, REFCNT>& a)
02705 {
02706 matrix<T, true> res = a;
02707 res.transpose();
02708 return res;
02709 }
02710
02711
02713
02720 template
02721 <
02722 typename T1, bool REFCNT1,
02723 typename T2, bool REFCNT2
02724 >
02725 inline int cmp
02726 (
02727 const matrix<T1, REFCNT1>& a,
02728 const matrix<T2, REFCNT2>& b
02729 )
02730 {
02731 if(a.nrows() < b.nrows())return -1;
02732 if(a.nrows() > b.nrows())return +1;
02733 if(a.ncols() < b.ncols())return -1;
02734 if(a.ncols() > b.ncols())return +1;
02735 return _Internal::aggregate_cmp(a.begin(), a.end(), b.begin(), b.end());
02736 }
02737
02738
02739
02740 #define _ARAGELI_MATRIX_CMP(OPER) \
02741 template \
02742 < \
02743 typename T1, bool REFCNT1, \
02744 typename T2, bool REFCNT2 \
02745 > \
02746 inline bool operator OPER \
02747 (const matrix<T1, REFCNT1>& a, const matrix<T2, REFCNT2>& b) \
02748 { return cmp(a, b) OPER 0; } \
02749 \
02750 template \
02751 < \
02752 typename T1, bool REFCNT1, \
02753 typename T2 \
02754 > \
02755 inline bool operator OPER \
02756 (const matrix<T1, REFCNT1>& a, const T2& b) \
02757 { \
02758 return cmp \
02759 ( \
02760 a, \
02761 matrix<T2, false>(a.nrows(), a.ncols, b, fromsize) \
02762 ) OPER 0; \
02763 } \
02764 \
02765 template \
02766 < \
02767 typename T1, \
02768 typename T2, bool REFCNT2 \
02769 > \
02770 inline bool operator OPER \
02771 (const T1& a, const matrix<T2, REFCNT2>& b) \
02772 { \
02773 return cmp \
02774 ( \
02775 matrix<T2, false>(b.nrows(), b.ncols(), a, fromsize), \
02776 b \
02777 ) OPER 0; \
02778 }
02779
02780
02782
02783
02784 _ARAGELI_MATRIX_CMP(<=)
02785 _ARAGELI_MATRIX_CMP(>=)
02786 _ARAGELI_MATRIX_CMP(<)
02787 _ARAGELI_MATRIX_CMP(>)
02788 _ARAGELI_MATRIX_CMP(==)
02789 _ARAGELI_MATRIX_CMP(!=)
02790
02791
02792
02793 #undef _ARAGELI_MATRIX_CMP
02794
02795
02796 #define _ARAGELI_GENERIC_MATRIX_OPERATORS1(MNEM, OPERB) \
02797 template <typename T1, typename T2, typename T3> \
02798 T3& each_##MNEM##_matrix_matrix (const T1& a, const T2& b, T3& res) \
02799 { \
02800 ARAGELI_ASSERT_0(a.size() == b.size()); \
02801 ARAGELI_ASSERT_0(res.size() == a.size()); \
02802 \
02803 typename T1::const_iterator ia = a.begin(), iend = a.end(); \
02804 typename T2::const_iterator ib = b.begin(); \
02805 typename T3::iterator ic = res.begin(); \
02806 \
02807 for(; ia != iend; ++ia, ++ib, ++ic) \
02808 *ic = *ia OPERB *ib; \
02809 \
02810 return res; \
02811 } \
02812 \
02813 template <typename T1, typename T2, typename T3> \
02814 T3& MNEM##_matrix_scalar (const T1& a, const T2& b, T3& res) \
02815 { \
02816 ARAGELI_ASSERT_0(res.size() == a.size()); \
02817 \
02818 typename T1::const_iterator ia = a.begin(), iend = a.end(); \
02819 typename T3::iterator ic = res.begin(); \
02820 \
02821 for(; ia != iend; ++ia, ++ic) \
02822 *ic = *ia OPERB b; \
02823 \
02824 return res; \
02825 } \
02826 \
02827 template <typename T1, typename T2, typename T3> \
02828 T3& MNEM##_scalar_matrix (const T1& a, const T2& b, T3& res) \
02829 { \
02830 ARAGELI_ASSERT_0(res.size() == b.size()); \
02831 \
02832 typename T2::const_iterator ib = b.begin(), iend = b.end(); \
02833 typename T3::iterator ic = res.begin(); \
02834 \
02835 for(; ib != iend; ++ib, ++ic) \
02836 *ic = a OPERB *ib; \
02837 \
02838 return res; \
02839 }
02840
02841
02842 _ARAGELI_GENERIC_MATRIX_OPERATORS1(add, +)
02843 _ARAGELI_GENERIC_MATRIX_OPERATORS1(sub, -)
02844 _ARAGELI_GENERIC_MATRIX_OPERATORS1(mul, *)
02845 _ARAGELI_GENERIC_MATRIX_OPERATORS1(div, /)
02846 _ARAGELI_GENERIC_MATRIX_OPERATORS1(mod, %)
02847 _ARAGELI_GENERIC_MATRIX_OPERATORS1(bitand, &)
02848 _ARAGELI_GENERIC_MATRIX_OPERATORS1(bitor, |)
02849 _ARAGELI_GENERIC_MATRIX_OPERATORS1(bitxor, ^)
02850 _ARAGELI_GENERIC_MATRIX_OPERATORS1(shl, <<)
02851 _ARAGELI_GENERIC_MATRIX_OPERATORS1(shr, >>)
02852
02853
02854 #define _ARAGELI_GENERIC_MATRIX_OPERATORS2(MNEM) \
02855 template <typename T1, typename T2, typename T3> \
02856 T3& MNEM##_matrix_matrix (const T1& a, const T2& b, T3& res) \
02857 { return each_##MNEM##_matrix_matrix(a, b, res); }
02858
02859 template <typename T1, typename T2, typename T3>
02860 T3& mul_matrix_matrix (const T1& a, const T2& b, T3& res)
02861 { res = a; return res.mul_matrix(b); }
02862
02863 template <typename T1, typename T2, typename T3>
02864 T3& div_matrix_matrix (const T1& a, const T2& b, T3& res)
02865 { res = a; return res.div_matrix(b); }
02866
02867
02868 _ARAGELI_GENERIC_MATRIX_OPERATORS2(add)
02869 _ARAGELI_GENERIC_MATRIX_OPERATORS2(sub)
02870 _ARAGELI_GENERIC_MATRIX_OPERATORS2(mod)
02871 _ARAGELI_GENERIC_MATRIX_OPERATORS2(bitand)
02872 _ARAGELI_GENERIC_MATRIX_OPERATORS2(bitor)
02873 _ARAGELI_GENERIC_MATRIX_OPERATORS2(bitxor)
02874 _ARAGELI_GENERIC_MATRIX_OPERATORS2(shl)
02875 _ARAGELI_GENERIC_MATRIX_OPERATORS2(shr)
02876
02877
02878 #undef _ARAGELI_GENERIC_MATRIX_OPERATORS1
02879 #undef _ARAGELI_GENERIC_MATRIX_OPERATORS2
02880
02881
02882 #define _ARAGELI_MATRIX_BINARY_BY_UNARY(MNEM, OPERB) \
02883 template \
02884 < \
02885 typename T1, bool REFCNT1, \
02886 typename T2, bool REFCNT2 \
02887 > \
02888 inline matrix<T1, REFCNT1> operator OPERB \
02889 ( \
02890 const matrix<T1, REFCNT1>& a, \
02891 const matrix<T2, REFCNT2>& b \
02892 ) \
02893 { \
02894 matrix<T1, REFCNT1> t \
02895 (a.nrows(), a.ncols(), fromsize); \
02896 return MNEM##_matrix_matrix(a, b, t); \
02897 } \
02898 \
02899 template \
02900 < \
02901 typename T1, bool REFCNT1, \
02902 typename T2 \
02903 > \
02904 inline matrix<T1, REFCNT1> operator OPERB \
02905 ( \
02906 const matrix<T1, REFCNT1>& a, \
02907 const T2& b \
02908 ) \
02909 { \
02910 matrix<T1, REFCNT1> t \
02911 (a.nrows(), a.ncols(), fromsize); \
02912 return MNEM##_matrix_scalar(a, b, t); \
02913 } \
02914 \
02915 template \
02916 < \
02917 typename T1, \
02918 typename T2, bool REFCNT2 \
02919 > \
02920 inline matrix<T2, REFCNT2> operator OPERB \
02921 ( \
02922 const T1& a, \
02923 const matrix<T2, REFCNT2>& b \
02924 ) \
02925 { \
02926 matrix<T2, REFCNT2> t \
02927 (b.nrows(), b.ncols(), fromsize); \
02928 return MNEM##_scalar_matrix(a, b, t); \
02929 } \
02930 \
02931 template <typename T1, bool REFCNT1> \
02932 inline matrix<T1, REFCNT1> operator OPERB \
02933 ( \
02934 const matrix<T1, REFCNT1>& a, \
02935 const T1& b \
02936 ) \
02937 { \
02938 matrix<T1, REFCNT1> t \
02939 (a.nrows(), a.ncols(), fromsize); \
02940 return MNEM##_matrix_scalar(a, b, t); \
02941 } \
02942 \
02943 template <typename T2, bool REFCNT2> \
02944 inline matrix<T2, REFCNT2> operator OPERB \
02945 ( \
02946 const T2& a, \
02947 const matrix<T2, REFCNT2>& b \
02948 ) \
02949 { \
02950 matrix<T2, REFCNT2> t \
02951 (b.nrows(), b.ncols(), fromsize); \
02952 return MNEM##_scalar_matrix(a, b, t); \
02953 } \
02954 \
02955 \
02956 template <typename T1, bool REFCNT1> \
02957 inline matrix<rational<T1>, REFCNT1> \
02958 operator OPERB \
02959 ( \
02960 const matrix<rational<T1>, REFCNT1>& a, \
02961 const rational<T1>& b \
02962 ) \
02963 { \
02964 matrix<rational<T1>, REFCNT1> t \
02965 (a.nrows(), a.ncols(), fromsize); \
02966 return MNEM##_matrix_scalar(a, b, t); \
02967 } \
02968 \
02969 template <typename T2, bool REFCNT2> \
02970 inline matrix<rational<T2>, REFCNT2> \
02971 operator OPERB \
02972 ( \
02973 const rational<T2>& a, \
02974 const matrix<rational<T2>, REFCNT2>& b \
02975 ) \
02976 { \
02977 matrix<rational<T2>, REFCNT2> t \
02978 (b.nrows(), b.ncols(), fromsize); \
02979 return MNEM##_scalar_matrix(a, b, t); \
02980 } \
02981 \
02982 template \
02983 < \
02984 typename T1, typename D1, \
02985 bool REFCNT1, bool REFCNT2 \
02986 > \
02987 inline matrix<sparse_polynom \
02988 <T1, D1, REFCNT1>, REFCNT2> \
02989 operator OPERB \
02990 ( \
02991 const matrix<sparse_polynom \
02992 <T1, D1, REFCNT1>, REFCNT2>& a, \
02993 const sparse_polynom<T1, D1, REFCNT1>& b \
02994 ) \
02995 { \
02996 matrix<sparse_polynom \
02997 <T1, D1, REFCNT1>, REFCNT2> t \
02998 (a.nrows(), a.ncols(), fromsize); \
02999 return MNEM##_matrix_scalar(a, b, t); \
03000 } \
03001 \
03002 template \
03003 < \
03004 typename T1, typename D1, \
03005 bool REFCNT1, bool REFCNT2 \
03006 > \
03007 inline matrix<sparse_polynom \
03008 <T1, D1, REFCNT1>, REFCNT2> \
03009 operator OPERB \
03010 ( \
03011 const sparse_polynom<T1, D1, REFCNT1>& a, \
03012 const matrix<sparse_polynom \
03013 <T1, D1, REFCNT1>, REFCNT2>& b \
03014 ) \
03015 { \
03016 matrix<sparse_polynom \
03017 <T1, D1, REFCNT1>, REFCNT2> t \
03018 (b.nrows(), b.ncols(), fromsize); \
03019 return MNEM##_scalar_matrix(a, b, t); \
03020 }
03021
03022
03023
03025
03026
03027 _ARAGELI_MATRIX_BINARY_BY_UNARY(add, +)
03028 _ARAGELI_MATRIX_BINARY_BY_UNARY(sub, -)
03029 _ARAGELI_MATRIX_BINARY_BY_UNARY(mul, *)
03030 _ARAGELI_MATRIX_BINARY_BY_UNARY(div, /)
03031 _ARAGELI_MATRIX_BINARY_BY_UNARY(mod, %)
03032 _ARAGELI_MATRIX_BINARY_BY_UNARY(bitand, &)
03033 _ARAGELI_MATRIX_BINARY_BY_UNARY(bitor, |)
03034 _ARAGELI_MATRIX_BINARY_BY_UNARY(bitxor, ^)
03035 _ARAGELI_MATRIX_BINARY_BY_UNARY(shl, <<)
03036 _ARAGELI_MATRIX_BINARY_BY_UNARY(shr, >>)
03037
03038
03039
03040
03041 #undef _ARAGELI_MATRIX_BINARY_BY_UNARY
03042
03043
03044
03045
03046
03047
03048
03049
03050
03051
03052
03053
03054
03055
03056
03057
03058
03059
03060
03061
03062
03063
03064
03065
03066
03067
03068
03069
03070
03071
03072
03073
03074
03075
03076
03077
03078
03079
03080
03081
03082
03083
03084
03085
03086
03087
03088
03089
03090
03091
03092
03093
03096
03097
03098
03099
03100
03101
03102
03103
03104
03105
03106
03107
03109
03110
03111
03112
03113
03114
03115
03116
03117
03118
03119
03120
03121
03122
03123
03124
03125
03126
03127
03128
03129
03130
03131
03132
03133
03134
03135
03137
03139 template
03140 <
03141 typename T1, bool REFCNT1,
03142 typename T2, bool REFCNT2
03143 >
03144 vector<T2, REFCNT2> operator*
03145 (
03146 const matrix<T1, REFCNT1>& m,
03147 const vector<T2, REFCNT2>& x
03148 );
03149
03150
03152
03154 template
03155 <
03156 typename T2, bool REFCNT2,
03157 typename T1, bool REFCNT1
03158 >
03159 vector<T2, REFCNT2> operator*
03160 (
03161 const vector<T2, REFCNT2>& x,
03162 const matrix<T1, REFCNT1>& m
03163 );
03164
03165
03166 extern const char* matrix_output_list_first_bracket_default;
03167 extern const char* matrix_output_list_second_bracket_default;
03168 extern const char* matrix_output_list_row_separator_default;
03169 extern const char* matrix_output_list_first_row_bracket_default;
03170 extern const char* matrix_output_list_second_row_bracket_default;
03171 extern const char* matrix_output_list_col_separator_default;
03172 extern const char* matrix_input_list_first_bracket_default;
03173 extern const char* matrix_input_list_second_bracket_default;
03174 extern const char* matrix_input_list_row_separator_default;
03175 extern const char* matrix_input_list_first_row_bracket_default;
03176 extern const char* matrix_input_list_second_row_bracket_default;
03177 extern const char* matrix_input_list_col_separator_default;
03178 extern const char* matrix_output_aligned_left_col_default;
03179 extern const char* matrix_output_aligned_right_col_default;
03180 extern const char* matrix_output_aligned_inter_col_default;
03181
03182
03184
03186 template <typename T, bool REFCNT>
03187 std::ostream& output_list
03188 (
03189 std::ostream& out,
03190 const matrix<T, REFCNT>& x,
03191 const char* first_bracket = matrix_output_list_first_bracket_default,
03192 const char* second_bracket = matrix_output_list_second_bracket_default,
03193 const char* row_separator = matrix_output_list_row_separator_default,
03194 const char* first_row_bracket = matrix_output_list_first_row_bracket_default,
03195 const char* second_row_bracket = matrix_output_list_second_row_bracket_default,
03196 const char* col_separator = matrix_output_list_col_separator_default
03197 );
03198
03199
03201 template <typename T, bool REFCNT>
03202 std::istream& input_list
03203 (
03204 std::istream& out,
03205 matrix<T, REFCNT>& x,
03206 const char* first_bracket = matrix_input_list_first_bracket_default,
03207 const char* second_bracket = matrix_input_list_second_bracket_default,
03208 const char* row_separator = matrix_input_list_row_separator_default,
03209 const char* first_row_bracket = matrix_input_list_first_row_bracket_default,
03210 const char* second_row_bracket = matrix_input_list_second_row_bracket_default,
03211 const char* col_separator = matrix_input_list_col_separator_default
03212 );
03213
03214
03216 template <typename T, bool REFCNT>
03217 std::ostream& output_aligned
03218 (
03219 std::ostream& out,
03220 const matrix<T, REFCNT>& x,
03221 const char* left_col = matrix_output_aligned_left_col_default,
03222 const char* right_col = matrix_output_aligned_right_col_default,
03223 const char* inter_col = matrix_output_aligned_inter_col_default
03224 );
03225
03226
03228 template
03229 <
03230 typename T1, bool REFCNT1,
03231 typename T2, bool REFCNT2
03232 >
03233 std::ostream& output_aligned_ver_pair
03234 (
03235 std::ostream& out,
03236 const matrix<T1, REFCNT1>& m1,
03237 const matrix<T2, REFCNT2>& m2,
03238 const char* left_col = "|| ",
03239 const char* right_col = " ||",
03240 const char* inter_col = " ",
03241 const char* hsplitter = "-"
03242 );
03243
03244
03246 template
03247 <
03248 typename T1, bool REFCNT1,
03249 typename T2, bool REFCNT2
03250 >
03251 std::ostream& output_aligned_hor_pair
03252 (
03253 std::ostream& out,
03254 const matrix<T1, REFCNT1>& m1,
03255 const matrix<T2, REFCNT2>& m2,
03256 const char* left_col = "|| ",
03257 const char* right_col = " ||",
03258 const char* inter_col = " ",
03259 const char* vsplitter = " | "
03260 );
03261
03262
03264
03267 template
03268 <
03269 typename T1, bool REFCNT1,
03270 typename T2, bool REFCNT2,
03271 typename T3, bool REFCNT3
03272 >
03273 std::ostream& output_aligned_corner_triplet_br
03274 (
03275 std::ostream& out,
03276 const matrix<T1, REFCNT1>& m1,
03277 const matrix<T2, REFCNT2>& m2,
03278 const matrix<T3, REFCNT3>& m3,
03279 const char* left_col = "|| ",
03280 const char* right_col = " ||",
03281 const char* inter_col = " ",
03282 const char* vsplitter = " | ",
03283 const char* hsplitter = "-"
03284 );
03285
03286
03288 template <typename T, bool REFCNT>
03289 std::ostream& operator<< (std::ostream& out, const matrix<T, REFCNT>& x)
03290 { return output_list(out, x); }
03291
03293 template <typename T, bool REFCNT>
03294 std::istream& operator>> (std::istream& out, matrix<T, REFCNT>& x)
03295 { return input_list(out, x); }
03296
03297
03299 template <typename T, bool REFCNT>
03300 std::ofstream& operator<< (std::ofstream& out, const matrix<T, REFCNT>& x)
03301 { return static_cast<std::ofstream&>(output_list(out, x)); }
03302
03304 template <typename T, bool REFCNT>
03305 std::ifstream& operator>> (std::ifstream& out, matrix<T, REFCNT>& x)
03306 { return static_cast<std::ifstream&>(input_list(out, x)); }
03307
03308
03309
03310
03311 template <typename T, bool REFCNT>
03312 std::ostream& operator<< (std::ostringstream& out, const matrix<T, REFCNT>& x)
03313 { return output_list(out, x); }
03314
03316 template <typename T, bool REFCNT>
03317 std::istream& operator>> (std::istringstream& out, matrix<T, REFCNT>& x)
03318 { return input_list(out, x); }
03319
03320
03321
03322
03324 template <typename T, bool REFCNT>
03325 struct factory<matrix<T, REFCNT> >
03326 {
03327 private:
03328
03329 typedef matrix<T, REFCNT> TTT;
03330
03331 public:
03332
03333 static const bool is_specialized = true;
03334
03335 static const TTT& unit ()
03336 {
03337 static const TTT unit_s(1, eye);
03338 return unit_s;
03339 }
03340
03341 static TTT unit (const TTT& pat)
03342 { return TTT(pat.nrows(), Arageli::unit<T>(), diag); }
03343
03344 static const TTT& opposite_unit ()
03345 {
03346 static const TTT opposite_unit_s
03347 (1, Arageli::opposite_unit<T>(), diag);
03348 return opposite_unit_s;
03349 }
03350
03351 static TTT opposite_unit (const TTT& pat)
03352 { return TTT(pat.nrows(), Arageli::opposite_unit<T>(), diag); }
03353
03354 static const TTT& null ()
03355 {
03356 static const TTT null_s(1, Arageli::null<T>(), fromval);
03357 return null_s;
03358 }
03359
03360 static TTT null (const TTT& pat)
03361 { return TTT(pat.nrows(), Arageli::null<T>(), diag); }
03362
03363 };
03364
03365
03366 template <typename T, bool REFCNT>
03367 inline matrix<T, REFCNT> opposite
03368 (const matrix<T, REFCNT>& x)
03369 { return -x; }
03370
03371 template <typename T, bool REFCNT>
03372 inline matrix<T, REFCNT>& opposite
03373 (const matrix<T, REFCNT>& x, matrix<T, REFCNT>* y)
03374 { return (*y = x).opposite(); }
03375
03376 template <typename T, bool REFCNT>
03377 inline matrix<T, REFCNT>& opposite
03378 (matrix<T, REFCNT>* x)
03379 { return x->opposite(); }
03380
03381
03382
03383
03384
03385
03386
03387
03388
03389 template <typename T, bool REFCNT>
03390 inline matrix<T, REFCNT>& inverse
03391 (const matrix<T, REFCNT>& x, matrix<T, REFCNT>* y)
03392 { return (*y = x).inverse(); }
03393
03394 template <typename T, bool REFCNT>
03395 inline matrix<T, REFCNT>& inverse
03396 (matrix<T, REFCNT>* x)
03397 { return x->inverse(); }
03398
03399
03400 template <typename T, bool REFCNT>
03401 inline bool is_unit (const matrix<T, REFCNT>& x)
03402 { return x.is_unit(); }
03403
03404 template <typename T, bool REFCNT>
03405 inline bool is_opposite_unit (const matrix<T, REFCNT>& x)
03406 { return x.is_opposite_unit(); }
03407
03408 template <typename T, bool REFCNT>
03409 inline bool is_null (const matrix<T, REFCNT>& x)
03410 { return x.is_null(); }
03411
03412
03413 template <typename T, bool REFCNT>
03414 struct type_traits<matrix<T, REFCNT> >
03415 : public type_traits_default<matrix<T, REFCNT> >
03416 {
03417 static const bool is_specialized = type_traits<T>::is_specialized;
03418
03419 static const bool is_number = false;
03420 static const bool is_integer_number = false;
03421 static const bool is_polynom = false;
03422 static const bool is_real_number = false;
03423 static const bool is_rational_number = false;
03424 static const bool is_complex_number = false;
03425 static const bool is_ring = type_traits<T>::is_ring;
03426 static const bool is_field = false;
03427 static const bool is_finite = type_traits<T>::is_finite;
03428 static const bool is_additive_group = type_traits<T>::is_additive_group;
03429 static const bool is_multiplicative_group = false;
03430 static const bool has_zero_divisor = type_traits<T>::has_zero_divisor;
03431 static const bool is_integer_modulo_ring = false;
03432 static const bool is_matrix = true;
03433 static const bool is_vector = false;
03434
03435 static const bool has_commutative_multiplication =
03436 type_traits<T>::has_commutative_multiplication &&
03437 type_traits<T>::has_commutative_addition;
03438
03439 static const bool has_commutative_addition =
03440 type_traits<T>::has_commutative_addition;
03441
03442 static const bool has_null = type_traits<T>::has_null;
03443
03444 static const bool has_unit =
03445 type_traits<T>::has_unit &&
03446 type_traits<T>::has_null;
03447
03448 static const bool has_opposite_unit =
03449 type_traits<T>::has_opposite_unit &&
03450 type_traits<T>::has_null;
03451
03453 static const bool is_aggregate = true;
03454
03456 typedef T element_type;
03457
03458 typedef type_category::dense_matrix category_type;
03459 static const category_type category_value;
03460 };
03461
03462
03463 template <typename T, bool REFCNT>
03464 const type_category::dense_matrix
03465 type_traits<matrix<T, REFCNT> >::category_value =
03466 type_category::dense_matrix();
03467
03468
03469 template <typename T, bool REFCNT>
03470 inline std::ostream& output_polynom_first
03471 (std::ostream& out, const matrix<T, REFCNT>& x)
03472 { return output_list(out, x); }
03473
03474 template <typename T, bool REFCNT>
03475 inline std::ostream& output_polynom_internal
03476 (std::ostream& out, const matrix<T, REFCNT>& x)
03477 { return output_list(out << "+", x); }
03478
03479 template <typename T, bool REFCNT>
03480 inline std::ostream& output_pow
03481 (std::ostream& out, const matrix<T, REFCNT>& x)
03482 { return output_list(out, x); }
03483
03484 template <typename T, bool REFCNT>
03485 inline std::istream& input_polynom_first
03486 (std::istream& in, matrix<T, REFCNT>& x)
03487 { return input_list(in, x); }
03488
03489 template <typename T, bool REFCNT>
03490 std::istream& input_polynom_internal
03491 (std::istream& in, matrix<T, REFCNT>& x);
03492
03493 template <typename T, bool REFCNT>
03494 inline std::istream& input_pow
03495 (std::istream& in, matrix<T, REFCNT>& x)
03496 { return input_polynom_first(in, x); }
03497
03498
03500 template
03501 <
03502 typename T1, bool REFCNT1,
03503 typename T2, bool REFCNT2,
03504 typename T3, bool REFCNT3
03505 >
03506 void fill_submatrix_col
03507 (
03508 const matrix<T1, REFCNT1>& orig,
03509 const vector<T2, REFCNT2>& indexes,
03510 matrix<T3, REFCNT3>& res
03511 )
03512 {
03513 res.assign_fromsize(orig.nrows(), indexes.size());
03514
03515 for(typename vector<T2, REFCNT2>::size_type j = 0; j < indexes.size(); ++j)
03516 {
03517 const T2& index = indexes[j];
03518
03519 ARAGELI_ASSERT_0(index >= 0);
03520 ARAGELI_ASSERT_0(index < orig.ncols());
03521
03522 for(typename matrix<T3, REFCNT3>::size_type i = 0; i < res.nrows(); ++i)
03523 res(i, j) = orig(i, index);
03524 }
03525 }
03526
03527
03529 template
03530 <
03531 typename T1, bool REFCNT1,
03532 typename T2, bool REFCNT2,
03533 typename T3, bool REFCNT3
03534 >
03535 void fill_submatrix_row
03536 (
03537 const matrix<T1, REFCNT1>& orig,
03538 const vector<T2, REFCNT2>& indexes,
03539 matrix<T3, REFCNT3>& res
03540 )
03541 {
03542 res.assign_fromsize(indexes.size(), orig.ncols());
03543
03544 for(typename vector<T2, REFCNT2>::size_type i = 0; i < indexes.size(); ++i)
03545 {
03546 const T2& index = indexes[i];
03547
03548 ARAGELI_ASSERT_0(index >= 0);
03549 ARAGELI_ASSERT_0(index < orig.nrows());
03550
03551 for(typename matrix<T3, REFCNT3>::size_type j = 0; j < res.ncols(); ++j)
03552 res(i, j) = orig(index, j);
03553 }
03554 }
03555
03556
03557 }
03558
03559
03560 namespace std
03561 {
03562
03564 template
03565 <
03566 typename T1, bool REFCNT1,
03567 typename T2, bool REFCNT2
03568 >
03569 inline void swap
03570 (
03571 Arageli::matrix<T1, REFCNT1>& a,
03572 Arageli::matrix<T2, REFCNT2>& b
03573 )
03574 { a.swap(b); }
03575
03576
03578 template <typename T1, bool REFCNT1>
03579 inline void swap
03580 (
03581 Arageli::matrix<T1, REFCNT1>& a,
03582 Arageli::matrix<T1, REFCNT1>& b
03583 )
03584 { a.swap(b); }
03585
03586 }
03587
03588
03589 #ifdef ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE
03590 #define ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_MATRIX
03591 #include "matrix.cpp"
03592 #undef ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_MATRIX
03593 #endif
03594
03595
03596 #endif
03597