1 // ********** DO NOT REMOVE THIS BANNER **********
2 // ORIG-DATE: 29 fev 2000
3 // -*- Mode : c++ -*-
4 //
5 // SUMMARY : array modelisation
6 // USAGE : LGPL
7 // ORG : LJLL Universite Pierre et Marie Curie, Paris, FRANCE
8 // AUTHOR : Frederic Hecht
9 // E-MAIL : frederic.hecht@ann.jussieu.fr
10 //
11
12 /*
13
14
15
16 Freefem++ is free software; you can redistribute it and/or modify
17 it under the terms of the GNU Lesser General Public License as published by
18 the Free Software Foundation; either version 2.1 of the License, or
19 (at your option) any later version.
20
21 Freefem++ is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU Lesser General Public License for more details.
25
26 You should have received a copy of the GNU Lesser General Public License
27 along with Freefem++; if not, write to the Free Software
28 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29
30
31 */
32 #ifndef KNM_H_
33 #define KNM_H_
34 // version march 2010 FH.
35 // add iterator for compatibility with gmm++
36 // ----------------------
37 // une tentative qui ne marche pas
38 // de tableau constant
39 #include <complex>
40 #include <iostream>
41 #include <iomanip>
42 #include <cmath>
43 #include <cassert>
44
45
46 using namespace std;
47 #define const_R R
48
49 #include <cstdlib>
Check_Kn(const char * str,const char * file,int line)50 inline void Check_Kn(const char * str,const char * file,int line)
51 {
52 cerr << "CHECK_KN: " << str << " in file: " << file << ", line " << line <<endl;
53 assert(0);
54 abort();
55 }
56
57 #define K_bigassert(i) if (!(i)) Check_Kn(#i,__FILE__,__LINE__);
58 #define RNM_FATAL_ERROR(i) Check_Kn(i,__FILE__,__LINE__);
59 #ifdef CHECK_KN
60
61 #define K_throwassert(i) if (!(i)) Check_Kn(#i,__FILE__,__LINE__);
62
63 #else
64 #define K_throwassert(i)
65 #endif
66 // version du 29 fev 2000
67 // correction for (... lj++,ui++ qui apelle le produit scalaire
68 // petite correction throwassert
69 // ajoute de operateur /= et *= sur des vecteurs
70 // suppression de constructeur qui pose de probleme
71 // correction oper += ... dans RNM_op.h ligne 56 change = en oper
72 // version de 25 nov 99 sans const R
73 // ajoute de '.' pour extraire une colonne, ou ligne , ...
74 // version du 22 nov 1999 cast to KN_<const R>
75 // version du 21 nov 1999 correction delete
76 // version du 13 nov 1999
77 // version du 18 mars 99
78 // F. Hecht
79 // attention les indexations les indexations peuvent changer
80 // puisque que l'on peut prendre la transposer d'une matrice
81 // tableau
82 // mais ils partent de 0
83 // version corrigee du 15/11/98
84 // version avec sous tableau --- mars 99
85 // -------
86 // remarque du 8 mars 99 FH
87 // class pour prendre des sous-tableau
88 // attention aux PB de continute dans les tableaux
89 // on a supposer que les tableaux multi indices pouvait est vue comme
90 // un tableau continue ce qui est generalement faux quand l'on en
91 // prend un sous tableau
92 // exemple: un tableau 3,5 est numerote comme:
93 // 0 3 6 9 12
94 // 1 4 7 10 13
95 // 2 5 8 11 14
96 // step
97 // indexi n 1
98 // indexj m n
99 // est le sous tableau 3,3 n'est pas numeroter consecutivement
100 //
101 // Donc la fonction IsVector1() nous dit si un tableau
102 // a un 2 ou 3 indices est ou non consecutif en memoire
103 //
104 // -- ajoute d'une classe VirtualMatrice
105 // pour modeliser le produit matrice vecteur
106 // x = A*v; via des fonctions virtuelle
107 // ----------------------------------
108 // version du 6 mars 2001 FH
109 // --- initialisation --
110 // --------------------------------
111 // version du 9 oct 2001 FH
112 // ajoute de constructeur par defaut d'une vecteur
113 // + set , pour definir le vecteur
114 // ou l'affectation (bof bof)
115 // ---------------------
116 // version sep 2002
117 // ajoute operateur >> pour KN<R> et KN_<R>
118 // --------------------
119 // version april 2003
120 // ajoute un gestion auto de
121 // la fonction InternalError pour les matriceVirtuel
122 // --------------------
123 // version jan 2004
124 // correction pour go ++
125 // des operateur #= pour les matrices et tenseurs
126 // ----------------------
127 // version feb 2004
128 // v(i(:)) = w // i(1:10)
129 // w=u(i(:)) //
130 // version mars 2004 make small correction
131 // in ITAB operator problem if non type R a defi
132 // -------------------
133 // Modif pour version avec les Complex mai 2004
134 // (u,v) donne le produit complex utiliser dans le produit matrice vecteur
135 // (u,conj(v)) donne le produit hermitiene pour le gradient conjugue
136 //
137 // -- de fonction dans le cas real
138 // modif for g++ 4.0 and xlc++ mai 2005
139 // adding some this->
140 // mars 2007
141 // correction in operator operation:b -1*c
142 // aout 2007,
143 // correct y = A*x ; when y is unset
144 // correct y += A*x ; when y is unset
145 // re-correct += sep 2007
146 // add size of the matrix in VirtualMatrix class.
147 // mars 2010 add unset KNM case ...
148 // ----------------
conj(const double & x)149 inline double conj(const double & x){return x;}
conj(const float & x)150 inline float conj(const float &x){return x;}
conj(const long & x)151 inline long conj(const long &x){return x;}
real(const double & x)152 inline double real(const double &x){return x;}
real(const float & x)153 inline float real(const float &x){return x;}
154
155 namespace RNM
156 {
Min(const T & a,const T & b)157 template<class T> inline T Min (const T &a,const T &b){return a < b ? a : b;}
Max(const T & a,const T & b)158 template<class T> inline T Max (const T &a,const T & b){return a > b ? a : b;}
Abs(const T & a)159 template<class T> inline T Abs (const T &a){return a <0 ? -a : a;}
160
Exchange(T & a,T & b)161 template<class T> inline void Exchange (T& a,T& b) {T c=a;a=b;b=c;}
Max(const T & a,const T & b,const T & c)162 template<class T> inline T Max (const T &a,const T & b,const T & c){return Max(Max(a,b),c);}
Min(const T & a,const T & b,const T & c)163 template<class T> inline T Min (const T &a,const T & b,const T & c){return Min(Min(a,b),c);}
164 // specialisation cas complex ---
165 template<class T>
Min(const complex<T> & a,complex<T> & b)166 inline complex<T> Min(const complex<T> &a,complex<T> &b)
167 { return complex<T>(min(a.real(),b.real()),min(a.imag(),b.imag()));}
168 template<class T>
Max(const complex<T> & a,const complex<T> & b)169 inline complex<T> Max(const complex<T> &a,const complex<T> &b)
170 { return complex<T>(max(a.real(),b.real()),max(a.imag(),b.imag()));}
171
172 /*inline complex<double> Min(const complex<double> &a,complex<double> &b)
173 { return complex<double>(Min(real(a),real(b)),Min(imag(a),imag(b)));}
174 inline complex<double> Max(const complex<double> &a,const complex<double> &b)
175 { return complex<double>(Max(real(a),real(b)),Max(imag(a),imag(b)));}
176 */
177 }
178 // ----
179
180 template<class R> class KNMK_ ;
181 template<class R> class KNM_ ;
182 template<class R> class KN_ ;
183 template<class R> class KN__iterator ;
184 template<class R> class KN__const_iterator ;
185 template<class R> class TKN_ ; // KN_ transpose
186 template<class R> class notKN_ ; // KN_ not
187 template<class R> class notnotKN_ ; // KN_ not not
188
189 template<class R> class KNMK ;
190 template<class R> class KNM ;
191 template<class R> class KN ;
192
193 template<class R> class conj_KN_ ;
194 template<class R> class Add_KN_;
195 template<class R> class Sub_KN_;
196 template<class R> class Mulc_KN_;
197 template<class R> class Add_Mulc_KN_;
198 template<class R> class Mul_KNM_KN_;
199 template<class R> class DotStar_KN_;
200 template<class R> class DotSlash_KN_;
201
202 template<class R> class outProduct_KN_;
203 template<class R> class if_KN_;
204 template<class R> class if_arth_KN_;
205 template<class R> class ifnot_KN_;
206 template<class R,class I> class KN_ITAB;
207
208 template<class R,typename A,typename B> class F_KN_;
209
210
211 #ifndef ffassert
212 #define ffassert assert
213 #endif
214
215 // gestion des erreur interne --
216 #ifndef InternalError
217 typedef void (* TypeofInternalErrorRoutine)(const char *) ;
InternalErrorRoutinePtr()218 static TypeofInternalErrorRoutine &InternalErrorRoutinePtr()
219 {
220 static TypeofInternalErrorRoutine routine=0;
221 return routine;
222 }
223
InternalError(const char * str)224 static void InternalError(const char * str) {
225 if (InternalErrorRoutinePtr() ) (*InternalErrorRoutinePtr())(str);
226 cerr << str;
227 exit(1);
228 }
SetInternalErrorRoutine(TypeofInternalErrorRoutine f)229 inline void SetInternalErrorRoutine(TypeofInternalErrorRoutine f)
230 {
231 InternalErrorRoutinePtr()=f;
232 }
233 #endif
234 // --
235 template<class P,class Q>
236 struct PplusQ { const P & p;const Q & q;
PplusQPplusQ237 PplusQ(const P & pp,const Q & qq) : p(pp),q(qq){}
238 };
239
240 template<class R>
241 struct VirtualMatrice { public:
242 int N,M;
VirtualMatriceVirtualMatrice243 VirtualMatrice(int nn,int mm): N(nn),M(mm) {}
VirtualMatriceVirtualMatrice244 VirtualMatrice(int nn): N(nn),M(nn) {}
245 // y += A x
246 virtual void addMatMul(const KN_<R> & x, KN_<R> & y) const =0;
addMatTransMulVirtualMatrice247 virtual void addMatTransMul(const KN_<R> & , KN_<R> & ) const
248 { InternalError("VirtualMatrice::addMatTransMul not implemented "); }
WithSolverVirtualMatrice249 virtual bool WithSolver() const {return false;} // by default no solver
SolveVirtualMatrice250 virtual void Solve( KN_<R> & ,const KN_<R> & ) const
251 { InternalError("VirtualMatrice::solve not implemented "); }
252
253 #ifdef VersionFreeFempp
254 virtual bool ChecknbLine (int n) const= 0;
255 virtual bool ChecknbColumn (int m) const =0;
256 #else
ChecknbLineVirtualMatrice257 virtual bool ChecknbLine (int n) const {return true;}
ChecknbColumnVirtualMatrice258 virtual bool ChecknbColumn (int m) const {return true;}
259 #endif
260 struct plusAx { const VirtualMatrice * A; const KN_<R> x;
plusAxVirtualMatrice::plusAx261 plusAx( const VirtualMatrice * B,const KN_<R> & y) :A(B),x(y)
262 { ffassert(B->ChecknbColumn(y.N())); }
263 };
264
operator *VirtualMatrice265 plusAx operator*(const KN_<R> & x) const {return plusAx(this,x);}
266
267 struct plusAtx { const VirtualMatrice * A; const KN_<R> x;
plusAtxVirtualMatrice::plusAtx268 plusAtx( const VirtualMatrice * B,const KN_<R> & y) :A(B),x(y)
269 {ffassert(B->ChecknbLine(y.N()));} };
270
271 struct solveAxeqb { const VirtualMatrice * A; const KN_<R> b;
solveAxeqbVirtualMatrice::solveAxeqb272 solveAxeqb( const VirtualMatrice * B,const KN_<R> & y) :A(B),b(y)
273 {ffassert(B->ChecknbColumn(y.N()));} };
274
~VirtualMatriceVirtualMatrice275 virtual ~VirtualMatrice(){}
276 };
277
278
279
280 //template <class R> class MatriceCreuseMulKN_;
281 //template <class R> class MatriceCreuseDivKN_;
282
283 class ShapeOfArray;
284
285 class FromTo{ public:
286 long from,to;
FromTo(long i,long j)287 FromTo(long i,long j):from(i),to(j) {K_throwassert(i<j);}
288 };
289
290 class SubArray{ public:
291 const long n,step,start;
292 // SubArray(char nn): n(-1),step(1),start(0) {}
SubArray(long nn,long sta=0,long s=1)293 explicit SubArray(long nn,long sta=0,long s=1): n(nn),step(s),start(sta) {}
SubArray(const FromTo & ft)294 SubArray(const FromTo& ft) : n(ft.to-ft.from+1),step(1),start(ft.from) {}
295 SubArray(const ShapeOfArray & ); // all
end() const296 long end() const { return start+ step*n;}
last() const297 long last() const { return start+ step*(n-1);}
len1() const298 long len1() const { return step*(n-1);}
299 };
300
301
302 class ShapeOfArray{ protected:
303 public:
304
305 long n; // n nb of item
306 long step; // step nb of between 2 item
307 long next; // the next array of same type in matrix for subarray
308 // by default no next ( in case of KN, and KNM -next is
309 // a counter of destruction (use in frefem++)
ShapeOfArray(const ShapeOfArray & s,long nn)310 ShapeOfArray(const ShapeOfArray & s,long nn): n(s.n),step(s.n),next(nn) {}
ShapeOfArray(long nn)311 ShapeOfArray(long nn): n(nn),step(1),next(-1) {}
312
ShapeOfArray(long nn,long s)313 ShapeOfArray(long nn,long s): n(nn),step(s),next(-1) {}
314
ShapeOfArray(long nn,long s,long nextt)315 ShapeOfArray(long nn,long s,long nextt): n(nn),step(s),next(nextt) {}
316
ShapeOfArray(const ShapeOfArray & old,const SubArray & sub)317 ShapeOfArray(const ShapeOfArray &old,const SubArray &sub)
318 : n(sub.n),step(old.step*sub.step),next(old.next)
319 { K_throwassert((sub.last())*old.step <= old.last());} // a constructor
320
ShapeOfArray(const ShapeOfArray & old,long stepo,long start)321 ShapeOfArray(const ShapeOfArray &old,long stepo,long start)
322 : n(old.n-start),step(old.step*stepo),next(old.next)
323 { K_throwassert(n>=0);}
324
end() const325 long end() const { return n*step;}
last() const326 long last() const { return (n-1)*step;}
constant() const327 long constant() const { return step==0;}
index(long k) const328 long index(long k) const { K_throwassert( (k>=0) && ( (k <n) || !step) );
329 return step*k;}
operator *(long stepp) const330 ShapeOfArray operator*(long stepp) const {return ShapeOfArray(n,step*stepp,next);}
SameShape(const ShapeOfArray & a) const331 bool SameShape(const ShapeOfArray & a) const
332 { return !step || !a.step || a.n == n ;}
N(const ShapeOfArray & a)333 long N(const ShapeOfArray & a) { return step ? n : a.n;} // size of 2 shape
334
335
336 // protected:
operator [](long k) const337 long operator[](long k) const {
338 //if( k<0 || ( k<n && !step) )
339 // cout << "k,n,step=" << k << " " << n << " " << step << endl;
340 K_throwassert( (k>=0) && ( (k <n) || !step) );
341 return step*k;}
init(long nn,long s=1,long nextt=-1)342 void init(long nn,long s=1,long nextt=-1) { n=nn; step=s; next=nextt;}
343 };
344
345 ostream & operator<<(ostream & f,const ShapeOfArray & s);
346
SameShape(const ShapeOfArray & a,const ShapeOfArray & b)347 inline bool SameShape(const ShapeOfArray & a,const ShapeOfArray & b)
348 { return !a.step || !b.step || a.n == b.n ;}
349
N(const ShapeOfArray & a,const ShapeOfArray & b)350 inline long N(const ShapeOfArray & a,const ShapeOfArray & b)
351 { K_throwassert(SameShape(a,b)); return a.step ? a.n : b.n ;}
352
SubArray(const ShapeOfArray & s)353 inline SubArray::SubArray(const ShapeOfArray & s)
354 :n(s.n),step(s.step),start(0) {}
355
356
357
358 template<class R>
359 ostream & operator<<(ostream & f,const KN_<const_R> & v) ;
360
361 template<class R> istream & operator>>(istream & f, KN_<R> & v);
362 template<class R> istream & operator>>(istream & f, KN<R> & v);
363
364 template<class R>
365 class SetArray { public:
366 R o,step;
367 long n;
SetArray(long nn,R oo=R (),R sstep=R (1))368 explicit SetArray(long nn,R oo=R(),R sstep=R(1)): o(oo),n(nn),step(sstep) {}
SetArray(SetArray<K> sa)369 template<class K> SetArray(SetArray<K> sa): o(sa.o),n(sa.n),step(sa.step) {}
370
operator [](long i) const371 R operator[](long i) const { return i <= n ? o + R(i)*step : R();}
size() const372 long size() const {return n;}
373 };
374
375 // add for gmm++ march 2010 ....
376 template<typename T> struct KN__iterator {
377 typedef T value_type;
378 typedef value_type* pointer;
379 typedef value_type& reference;
380 typedef size_t size_type;
381 typedef ptrdiff_t difference_type;
382 typedef std::bidirectional_iterator_tag iterator_category;
383 typedef KN__iterator<T> iterator;
384 private:
385 T* v;
386 long step;
387 public:
operator *KN__iterator388 reference operator *() const { return *v; }
operator ->KN__iterator389 pointer operator->() const { return &(operator*()); }
390
operator ++KN__iterator391 iterator &operator ++() { v += step; return *this; }
operator ++KN__iterator392 iterator operator ++(int) { iterator tmp = *this; ++(*this); return tmp; }
operator --KN__iterator393 iterator &operator --() { v -= step; return *this; }
operator --KN__iterator394 iterator operator --(int) { iterator tmp = *this; --(*this); return tmp; }
395
operator ==KN__iterator396 bool operator ==(const iterator &i) const { return v == i.v; }
operator !=KN__iterator397 bool operator !=(const iterator &i) const { return !(v == i.v); }
398
KN__iteratorKN__iterator399 KN__iterator(T *vv,int s) : v(vv),step(s) {K_throwassert(v);}
400 friend class KN__const_iterator<T>;
401 };
402
403 template<typename T> struct KN__const_iterator {
404 typedef T value_type;
405 typedef const value_type* pointer;
406 typedef const value_type& reference;
407 typedef size_t size_type;
408 typedef ptrdiff_t difference_type;
409 typedef std::forward_iterator_tag iterator_category;
410 typedef KN__const_iterator<T> iterator;
411
412 private:
413 const T* v;
414 long step;
415 public:
416
operator *KN__const_iterator417 reference operator *() const { return *v; }
operator ->KN__const_iterator418 pointer operator->() const { return &(operator*()); }
419
operator ++KN__const_iterator420 iterator &operator ++() { v += step; return *this; }
operator ++KN__const_iterator421 iterator operator ++(int) { iterator tmp = *this; ++(*this); return tmp; }
operator --KN__const_iterator422 iterator &operator --() { v -= step; return *this; }
operator --KN__const_iterator423 iterator operator --(int) { iterator tmp = *this; --(*this); return tmp; }
424
operator ==KN__const_iterator425 bool operator ==(const iterator &i) const { return v == i.v; }
operator !=KN__const_iterator426 bool operator !=(const iterator &i) const { return !(v == i.v); }
427
KN__const_iteratorKN__const_iterator428 KN__const_iterator(const T *vv,int s) : v(vv),step(s) {K_throwassert(v);}
KN__const_iteratorKN__const_iterator429 KN__const_iterator(const KN__const_iterator<T> & i) : v(i.v),step(i.step){}
430
431 };
432
433
434 template<class R>
435 class KN_: public ShapeOfArray {
436 protected:
437 R *v;
438 public:
439 typedef R K; // type of data
440 typedef KN__iterator<R> iterator;
441 typedef KN__const_iterator<R> const_iterator;
end()442 iterator end(){ return iterator(v+n*step,step);}
begin()443 iterator begin(){ return iterator(v,step);}
end() const444 const_iterator end() const { return const_iterator(v+n*step,step);}
begin() const445 const_iterator begin() const { return const_iterator(v,step);}
clear()446 void clear() { *this=R();}
N() const447 long N() const {return n;}
unset() const448 bool unset() const { return !v;}
set(R * vv,int nn,int st=1,int nx=-1)449 void set(R * vv,int nn,int st=1,int nx=-1) {v=vv;n=nn;step=st;next=nx;}
size() const450 long size() const{return step?n*step:n;}
operator R*() const451 operator R *() const {return v;}
KN_(const KN_<R> & u)452 KN_(const KN_<R> & u) :ShapeOfArray(u),v(u.v){}
KN_(const KN_<R> & U,const SubArray & sa)453 KN_(const KN_<R> & U,const SubArray & sa) : ShapeOfArray(U,sa),v(U.v + U.index(sa.start)) {}
454
operator ()(const SubArray & sa) const455 KN_ operator()(const SubArray & sa) const { return KN_(*this,sa);} // sub array
456
operator [](long i) const457 R & operator[](long i) const {return v[index(i)];}
operator ()(long i) const458 R & operator()(long i) const {return v[index(i)];}
operator [](int i) const459 R & operator[](int i) const {return v[index(i)];}
operator ()(int i) const460 R & operator()(int i) const {return v[index(i)];}
461
462 R operator,(const KN_<const_R> & v) const; // dot product
463
464 KN_& operator =(const SetArray<R> & u) ;
465 KN_& operator +=(const SetArray<R> & u) ;
466 KN_& operator -=(const SetArray<R> & u) ;
467 KN_& operator *=(const SetArray<R> & u) ;
468 KN_& operator /=(const SetArray<R> & u) ;
469
470 KN_& operator =(const KN_<const_R> & u) ;
471 KN_& operator +=(const KN_<const_R> & u) ;
472 KN_& operator -=(const KN_<const_R> & u) ;
473
474 KN_& operator *=(const KN_<const_R> & u) ;
475 KN_& operator /=(const KN_<const_R> & u) ;
476
477
478 KN_& operator = (const_R a) ;
479 KN_& operator +=(const_R a) ;
480 KN_& operator -=(const_R a) ;
481 KN_& operator /=(const_R a) ;
482 KN_& operator *=(const_R a) ;
483
operator =(R * a)484 KN_& operator = (R* a) { return operator =(KN_<R>(a,n));}
operator +=(R * a)485 KN_& operator += (R* a) { return operator+=(KN_<R>(a,n));}
operator -=(R * a)486 KN_& operator -= (R* a) { return operator-=(KN_<R>(a,n));}
operator *=(R * a)487 KN_& operator *= (R* a) { return operator*=(KN_<R>(a,n));}
operator /=(R * a)488 KN_& operator /= (R* a) { return operator/=(KN_<R>(a,n));}
489
490
491
492 R min() const ;
493 R max() const ;
494 R sum() const ;
495 double norm() const ;
496 double l2() const ;
497 double l1() const ;
498 double linfty() const ;
499 double lp(double p) const ;
500
501 template<class T> long last(const T &) const;
502 template<class T> long first(const T &) const;
503
504 void map(R (*f)(R )); // apply the f fonction a all element of the array
505 void map(R (*f)(const R& )); // apply the f fonction a all element of the array
506
507 template<class T>
508 void set(R (*f)(const T& ),KN_<T> & u); // apply the f fonction a all element of the array u
509
510 KN_& operator =(const DotStar_KN_<R> & u) ;
511 KN_& operator+=(const DotStar_KN_<R> & u) ;
512 KN_& operator-=(const DotStar_KN_<R> & u) ;
513 KN_& operator*=(const DotStar_KN_<R> & u) ;
514 KN_& operator/=(const DotStar_KN_<R> & u) ;
515
516 KN_& operator =(const DotSlash_KN_<R> & u) ;
517 KN_& operator+=(const DotSlash_KN_<R> & u) ;
518 KN_& operator-=(const DotSlash_KN_<R> & u) ;
519 KN_& operator*=(const DotSlash_KN_<R> & u) ;
520 KN_& operator/=(const DotSlash_KN_<R> & u) ;
521
522 KN_& operator =(const if_KN_<R> & u) ;
523 KN_& operator+=(const if_KN_<R> & u) ;
524 KN_& operator-=(const if_KN_<R> & u) ;
525 KN_& operator*=(const if_KN_<R> & u) ;
526 KN_& operator/=(const if_KN_<R> & u) ;
527
528 KN_& operator =(const ifnot_KN_<R> & u) ;
529 KN_& operator+=(const ifnot_KN_<R> & u) ;
530 KN_& operator-=(const ifnot_KN_<R> & u) ;
531 KN_& operator*=(const ifnot_KN_<R> & u) ;
532 KN_& operator/=(const ifnot_KN_<R> & u) ;
533
534 KN_& operator =(const Add_KN_<R> & u) ;
535 KN_& operator+=(const Add_KN_<R> & u) ;
536 KN_& operator-=(const Add_KN_<R> & u) ;
537 KN_& operator*=(const Add_KN_<R> & u) ;
538 KN_& operator/=(const Add_KN_<R> & u) ;
539
540 template<class I,class T> KN_& operator = (const KN_ITAB<T,I> & u);
541 template<class I,class T> KN_& operator += (const KN_ITAB<T,I> & u);
542 template<class I,class T> KN_& operator -= (const KN_ITAB<T,I> & u);
543 template<class I,class T> KN_& operator *= (const KN_ITAB<T,I> & u);
544 template<class I,class T> KN_& operator /= (const KN_ITAB<T,I> & u);
545
546
547 KN_ITAB< KN_<R>,const KN_<int> > operator()(const KN_<int> &itab) ;
548 KN_ITAB< KN_<R>,const KN_<long> > operator()(const KN_<long> &itab) ;
549 KN_ITAB<const KN_<R>,const KN_<int> > operator()(const KN_<int> &itab) const ;
550 KN_ITAB<const KN_<R>,const KN_<long> > operator()(const KN_<long> &itab) const ;
551
552
553
554
555
556 KN_& operator =(const Sub_KN_<R> & u) ;
557 KN_& operator-=(const Sub_KN_<R> & u) ;
558 KN_& operator+=(const Sub_KN_<R> & u) ;
559 KN_& operator*=(const Sub_KN_<R> & u) ;
560 KN_& operator/=(const Sub_KN_<R> & u) ;
561
562 KN_& operator =(const Mulc_KN_<R> & u) ;
563 KN_& operator+=(const Mulc_KN_<R> & u) ;
564 KN_& operator-=(const Mulc_KN_<R> & u) ;
565 KN_& operator*=(const Mulc_KN_<R> & u) ;
566 KN_& operator/=(const Mulc_KN_<R> & u) ;
567
568 KN_& operator =(const Add_Mulc_KN_<R> & u) ;
569 KN_& operator+=(const Add_Mulc_KN_<R> & u) ;
570 KN_& operator-=(const Add_Mulc_KN_<R> & u) ;
571 KN_& operator*=(const Add_Mulc_KN_<R> & u) ;
572 KN_& operator/=(const Add_Mulc_KN_<R> & u) ;
573
574 KN_& operator =(const if_arth_KN_<R> & u) ;
575 KN_& operator+=(const if_arth_KN_<R> & u) ;
576 KN_& operator-=(const if_arth_KN_<R> & u) ;
577 KN_& operator*=(const if_arth_KN_<R> & u) ;
578 KN_& operator/=(const if_arth_KN_<R> & u) ;
579
580
581 KN_& operator =(const Mul_KNM_KN_<R> & u) ;
582 KN_& operator+=(const Mul_KNM_KN_<R> & u) ;
583 KN_& operator-=(const Mul_KNM_KN_<R> & u) ;
584 KN_& operator*=(const Mul_KNM_KN_<R> & u) ;
585 KN_& operator/=(const Mul_KNM_KN_<R> & u) ;
586
587 // KN_& operator =(const MatriceCreuseMulKN_<R> & ) ;
588 // KN_& operator +=(const MatriceCreuseMulKN_<R> & ) ;
operator =(const typename VirtualMatrice<R>::plusAx & Ax)589 KN_& operator =(const typename VirtualMatrice<R>::plusAx & Ax)
590 {*this=R(); Ax.A->addMatMul(Ax.x,*this);return *this;}
operator =(const typename VirtualMatrice<R>::plusAtx & Ax)591 KN_& operator =(const typename VirtualMatrice<R>::plusAtx & Ax)
592 {*this=R(); Ax.A->addMatTransMul(Ax.x,*this);return *this;}
operator +=(const typename VirtualMatrice<R>::plusAx & Ax)593 KN_& operator +=(const typename VirtualMatrice<R>::plusAx & Ax)
594 { Ax.A->addMatMul(Ax.x,*this);return *this;}
operator +=(const typename VirtualMatrice<R>::plusAtx & Ax)595 KN_& operator +=(const typename VirtualMatrice<R>::plusAtx & Ax)
596 { Ax.A->addMatTransMul(Ax.x,*this);return *this;}
operator =(const typename VirtualMatrice<R>::solveAxeqb & Ab)597 KN_& operator =(const typename VirtualMatrice<R>::solveAxeqb & Ab)
598 {*this=R(); Ab.A->Solve(*this,Ab.b);return *this;}
599
600 template<class A,class B,class C> KN_& operator = (const F_KN_<A,B,C> & u) ;
601 template<class A,class B,class C> KN_& operator += (const F_KN_<A,B,C> & u) ;
602 template<class A,class B,class C> KN_& operator -= (const F_KN_<A,B,C> & u) ;
603 template<class A,class B,class C> KN_& operator /= (const F_KN_<A,B,C> & u) ;
604 template<class A,class B,class C> KN_& operator *= (const F_KN_<A,B,C> & u) ;
605
606
607 // KN_& operator =(const MatriceCreuseDivKN_<R> &) ;
608
609 friend ostream & operator<< <R>(ostream & f,const KN_<const_R> & v) ;
610
KN_(R * u,const ShapeOfArray & s)611 KN_(R *u,const ShapeOfArray & s):ShapeOfArray(s),v(u){}
KN_(R * u,long nn,long s)612 KN_(R *u,long nn,long s):ShapeOfArray(nn,s),v(u){}
KN_(R * u,long nn,long s,long nextt)613 KN_(R *u,long nn,long s,long nextt):ShapeOfArray(nn,s,nextt),v(u){}
KN_(R * u,long nn)614 KN_(R *u,long nn):ShapeOfArray(nn),v(u){}
615
616
617 TKN_<R> t() ; // transpose
618 const TKN_<R> t() const ; // transpose
619 notKN_<R> operator!() ; // not
620 const notKN_<R> operator!() const ; // not
621
622 // operator KN<R> &();
623 // operator const KN<R> &() const;
624
625 private:
626
operator ++()627 KN_& operator++(){K_throwassert(next>=0);v += next;return *this;} // ++U
operator --()628 KN_& operator--(){K_throwassert(next>=0);v -= next;return *this;} // --U
operator ++(int)629 KN_ operator++(int ){K_throwassert(next>=0); KN_ old=*this;v = v +next;return old;} // U++
operator --(int)630 KN_ operator--(int ){K_throwassert(next>=0); KN_ old=*this;v = v -next;return old;} // U++
631
KN_(const KN_<R> & u,long offset)632 KN_(const KN_<R> & u,long offset) :ShapeOfArray(u),v(&u[offset]){}
KN_(const KN_<R> & u,const ShapeOfArray & sh,long startv=0)633 KN_(const KN_<R> & u,const ShapeOfArray &sh,long startv=0)
634 :ShapeOfArray(sh*u.step),v(&u[startv]){}
KN_(const KN_<R> & u,long nnext,const ShapeOfArray & sh,long startv=0)635 KN_(const KN_<R> & u,long nnext,const ShapeOfArray &sh,long startv=0)
636 :ShapeOfArray(sh.n,sh.step*u.step,nnext),v(&u[startv]){ }
637 // Add for gmm++ compatibityly ...................
638 // iterator end() {return iterator(v,step)
639
640
641 // friend class KN_<R>;
642 friend class KNM_<R>;
643 friend class KNMK_<R>;
644 friend class KN<R>;
645 friend class KNM<R>;
646 friend class KNMK<R>;
647
648 };
649
650 template<class R>
651 class KNM_: public KN_<R> {
652 public:
653 ShapeOfArray shapei;
654 ShapeOfArray shapej;
655 public:
IsVector1() const656 long IsVector1() const { return (shapei.n*shapej.n) == this->n ;}
N() const657 long N() const {return shapei.n;}
M() const658 long M() const {return shapej.n;}
size() const659 long size() const { return shapei.n*shapej.n;}
660
KNM_(R * u,const ShapeOfArray & s,const ShapeOfArray & si,const ShapeOfArray & sj)661 KNM_(R* u,const ShapeOfArray & s,
662 const ShapeOfArray & si,
663 const ShapeOfArray & sj)
664 : KN_<R>(u,s),shapei(si),shapej(sj){}
KNM_(R * u,long n,long m)665 KNM_(R* u,long n,long m)
666 : KN_<R>(u,ShapeOfArray(n*m)),shapei(n,1,n),shapej(m,n,1){}
KNM_(R * u,long n,long m,long s)667 KNM_(R* u,long n,long m,long s)
668 : KN_<R>(u,ShapeOfArray(n*m,s)),shapei(n,1,n),shapej(m,n,1){}
KNM_(KN_<R> u,long n,long m)669 KNM_(KN_<R> u,long n,long m)
670 : KN_<R>(u,ShapeOfArray(m*n)),shapei(n,1,n),shapej(m,n,1){ }
671
KNM_(const KN_<R> & u,const ShapeOfArray & si,const ShapeOfArray & sj,long offset=0)672 KNM_(const KN_<R> &u,const ShapeOfArray & si,const ShapeOfArray & sj,long offset=0)
673 : KN_<R>(&u[offset],si.last()+sj.last()+1,u.step),shapei(si),shapej(sj)
674 {K_throwassert( offset>=0 && this->n+ (this->v-(R*)u) <= u.n);}
KNM_(const KN_<R> & u,const ShapeOfArray & si,const ShapeOfArray & sj,long offset,long nnext)675 KNM_(const KN_<R> &u,const ShapeOfArray & si,const ShapeOfArray & sj,long offset,long nnext)
676 : KN_<R>(&u[offset],si.last()+sj.last()+1,u.step,nnext),shapei(si),shapej(sj)
677 {K_throwassert( offset>=0 && this->n+ (this->v-(R*)u) <= u.n);}
678
KNM_(KNM_<R> U,const SubArray & si,const SubArray & sj)679 KNM_(KNM_<R> U,const SubArray & si,const SubArray & sj)
680 :KN_<R>(U,SubArray(U.ij(si.len1(),sj.len1())+1,U.ij(si.start,sj.start))),
681 shapei(U.shapei,si),shapej(U.shapej,sj){}
682
KNM_(KNM_<R> U,const SubArray & sa,const SubArray & si,const SubArray & sj)683 KNM_(KNM_<R> U,const SubArray & sa,const SubArray & si,const SubArray & sj)
684 :KN_<R>(U,SubArray(sa)),shapei(U.shapei,si),shapej(U.shapej,sj){}
685
KNM_(const KNM_<R> & u)686 KNM_(const KNM_<R> & u)
687 :KN_<R>(u),shapei(u.shapei),shapej(u.shapej) {}
688
operator ()(const SubArray & sa,const SubArray & sb) const689 KNM_ operator()(const SubArray & sa,const SubArray & sb) const
690 { return KNM_(*this,sa,sb);} // sub array
691
ij(long i,long j) const692 long ij(long i,long j) const
693 { return shapei.index(i)+shapej.index(j);}
indexij(long i,long j) const694 long indexij(long i,long j) const
695 { return this->index(shapei.index(i)+shapej.index(j));}
operator ()(long i,long j) const696 R & operator()(long i,long j) const
697 { return this->v[indexij(i,j)];}
operator ()(int i,int j) const698 R & operator()(int i,int j) const
699 { return this->v[indexij(i,j)];}
700
701
operator ()(const char,long j) const702 KN_<R> operator()(const char,long j ) const // une colonne j ('.',j)
703 { return KN_<R>(&this->v[this->index(shapej.index(j))],shapei*this->step);}
operator ()(long i,const char) const704 KN_<R> operator()(long i ,const char) const // une ligne i (i,'.')
705 { return KN_<R>(&this->v[this->index(shapei.index(i))],shapej*this->step);}
operator ()(const char,int j) const706 KN_<R> operator()(const char,int j ) const // une colonne j ('.',j)
707 { return KN_<R>(&this->v[this->index(shapej.index(j))],shapei*this->step);}
operator ()(int i,const char) const708 KN_<R> operator()(int i ,const char) const // une ligne i (i,'.')
709 { return KN_<R>(&this->v[this->index(shapei.index(i))],shapej*this->step);}
operator ()(const char,const char) const710 KN_<R> operator()(const char,const char) const // tous
711 { return *this;}
t() const712 KNM_<R> t() const
713 { return KNM_<R>(this->v,*this,shapej,shapei);} // before { return KNM_<R>(*this,shapej,shapei,v);}
714
715 KNM_& operator =(const KNM_<const_R> & u) ;
716 KNM_& operator =(const_R a) ;
717 KNM_& operator+=(const_R a) ;
718 KNM_& operator-=(const_R a) ;
719 KNM_& operator/=(const_R a) ;
720 KNM_& operator*=(const_R a) ;
721 KNM_& operator+=(const KNM_<const_R> & u) ;
722 KNM_& operator-=(const KNM_<const_R> & u) ;
723 KNM_& operator*=(const KNM_<const_R> & u) ;
724 KNM_& operator/=(const KNM_<const_R> & u) ;
725
726 KNM_ &operator =(const outProduct_KN_<R> &);
727 KNM_ &operator +=(const outProduct_KN_<R> &);
728 KNM_ &operator -=(const outProduct_KN_<R> &);
729 KNM_ &operator /=(const outProduct_KN_<R> &); // bofbof
730 KNM_ &operator *=(const outProduct_KN_<R> &); // bofbof
731
732 private:
operator ++()733 KNM_& operator++() {this->v += this->next;return *this;} // ++U
operator --()734 KNM_& operator--() {this->v -= this->next;return *this;} // ++U
operator ++(int)735 KNM_ operator++(int ){KNM_<R> old=*this;this->v = this->v +this->next;return old;} // U++
operator --(int)736 KNM_ operator--(int ){KNM_<R> old=*this;this->v = this->v -this->next;return old;} // U--
737
738
739 friend class KN_<R>;
740 // friend class KNM_<R>;
741 friend class KNMK_<R>;
742 friend class KN<R>;
743 friend class KNM<R>;
744 friend class KNMK<R>;
745 };
746
747 template<class T,class I>
748 struct KN_ITAB
749 {
KN_ITABKN_ITAB750 KN_ITAB(const T &vv,const I &iindex) : v(vv),index(iindex) {}
751 T v;
752 I index;
753 KN_ITAB & operator=(const T & t);
754 KN_ITAB & operator+=(const T & t);
755 KN_ITAB & operator-=(const T & t);
756 KN_ITAB & operator*=(const T & t);
757 KN_ITAB & operator/=(const T & t);
operator []KN_ITAB758 typename T::R & operator[](long i){ return v[index[i]];}
operator []KN_ITAB759 const typename T::R & operator[](long i) const { return v[index[i]];}
NKN_ITAB760 long N() const { return index.N();}
761 };
762
operator ()(const KN_<int> & itab) const763 template<class R> KN_ITAB<const KN_<R>,const KN_<int> > KN_<R>::operator()(const KN_<int> &itab) const { return KN_ITAB<const KN_<R>,const KN_<int> > (*this,itab);}
operator ()(const KN_<long> & itab) const764 template<class R> KN_ITAB<const KN_<R>,const KN_<long> > KN_<R>::operator()(const KN_<long> &itab) const { return KN_ITAB<const KN_<R>,const KN_<long> > (*this,itab);}
operator ()(const KN_<int> & itab)765 template<class R> KN_ITAB< KN_<R>,const KN_<int> > KN_<R>::operator()(const KN_<int> &itab) { return KN_ITAB<KN_<R>,const KN_<int> > (*this,itab);}
operator ()(const KN_<long> & itab)766 template<class R> KN_ITAB< KN_<R>,const KN_<long> > KN_<R>::operator()(const KN_<long> &itab) { return KN_ITAB<KN_<R>,const KN_<long> > (*this,itab);}
767
768
769 template<class R>
770 struct TKN_:public KN_<R> {
TKN_TKN_771 TKN_(const KN_<R> &x) : KN_<R>(x) {}
772 };
773
774 template<class R>
775 struct notKN_:public KN_<R> {
notKN_notKN_776 notKN_(const KN_<R> &x) : KN_<R>(x) {}
777 notnotKN_<R> operator!() ; // not
778 const notnotKN_<R> operator!() const ; // not
779 };
780
781 template<class R>
782 struct notnotKN_:public KN_<R> {
notnotKN_notnotKN_783 notnotKN_(const notKN_<R> &x) : KN_<R>(x) {}
784 notKN_<R> operator!() ; // notnot
785 const notKN_<R> operator!() const ; // notnot
786 };
787
788 template<class R>
t()789 TKN_<R> KN_<R>::t() { return *this;} // transpose
790
791 template<class R>
t() const792 const TKN_<R> KN_<R>::t() const { return *this;} // transpose
793
794 template<class R>
operator !()795 notKN_<R> KN_<R>::operator!() { return *this;} // not
796
797 template<class R>
operator !() const798 const notKN_<R> KN_<R>::operator!() const { return *this;} // not
799
800 template<class R>
operator !()801 notnotKN_<R> notKN_<R>::operator!() { return *this;} // not
802
803 template<class R>
operator !() const804 const notnotKN_<R> notKN_<R>::operator!() const { return *this;} // not
805
806
807 template<class R>
808 struct outProduct_KN_ {
809 const KN_<R> a,b;
810 R c;
NoutProduct_KN_811 long N() const {return a.N(); }
MoutProduct_KN_812 long M() const {return b.N(); }
outProduct_KN_outProduct_KN_813 outProduct_KN_(const KN_<R> & aa, const KN_<R> &bb,R cc=(R)1) : a(aa),b(bb),c(cc) {}
outProduct_KN_outProduct_KN_814 outProduct_KN_(const KN_<R> * aa, const KN_<R> &bb,R cc=(R)1) : a(*aa),b(bb),c(cc) {}
outProduct_KN_outProduct_KN_815 outProduct_KN_(const KN_<R> * aa, const KN_<R> *bb,R cc=(R)1) : a(*aa),b(*bb),c(cc) {}
outProduct_KN_outProduct_KN_816 outProduct_KN_(const Mulc_KN_<R> & aa,const KN_<R> & bb) : a(aa.a),b(bb),c(aa.b) {}
operator *outProduct_KN_817 outProduct_KN_ operator * (R cc) { return outProduct_KN_(a,b,c*cc);}
818 };
819
820 template<class R>
821 struct if_KN_ {
822 const KN_<R> & a,&b;
823 R c;
if_KN_if_KN_824 if_KN_(const KN_<R> & aa, const KN_<R> &bb,R cc=1.) : a(aa),b(bb),c(cc) {}
operator *if_KN_825 if_KN_ operator * (R cc) { return if_KN_(a,b,c*cc);}
826 };
827
828 template<class R>
829 struct ifnot_KN_ {
830 const KN_<R> & a,&b;
831 R c;
ifnot_KN_ifnot_KN_832 ifnot_KN_(const KN_<R> & aa, const KN_<R> &bb,R cc=1.) : a(aa),b(bb),c(cc) {}
operator *ifnot_KN_833 ifnot_KN_ operator * (R cc) { return ifnot_KN_(a,b,c*cc);}
834 };
835
836
837 template<class R>
operator *(const KN_<R> & a,const TKN_<R> & b)838 outProduct_KN_<R> operator*(const KN_<R> &a,const TKN_<R> &b)
839 { return outProduct_KN_<R>(a,b);}
840
841 template<class R>
operator *(const KN_<R> & a,const notKN_<R> & b)842 ifnot_KN_<R> operator*(const KN_<R> &a,const notKN_<R> &b)
843 { return ifnot_KN_<R>(b,a);}
844
845 template<class R>
operator *(const KN_<R> & a,const notnotKN_<R> & b)846 ifnot_KN_<R> operator*(const KN_<R> &a,const notnotKN_<R> &b)
847 { return if_KN_<R>(b,a);}
848
849 template<class R>
operator *(const notKN_<R> & b,const KN_<R> & a)850 ifnot_KN_<R> operator*(const notKN_<R> &b,const KN_<R> &a)
851 { return ifnot_KN_<R>(b,a);}
852
853 template<class R>
operator *(const notnotKN_<R> & b,const KN_<R> & a)854 ifnot_KN_<R> operator*(const notnotKN_<R> &b,const KN_<R> & a)
855 { return if_KN_<R>(b,a);}
856
857
858 template<class R>
operator *(const TKN_<R> & a,const KN_<R> & b)859 R operator*(const TKN_<R> &a,const KN_<R> &b)
860 { return (a,b);}
861
862 template<class R>
863 class KNMK_: public KN_<R> {
864 friend class KNMK<R>;
865 public:
866 ShapeOfArray shapei;
867 ShapeOfArray shapej;
868 ShapeOfArray shapek;
869 public:
IsVector1() const870 long IsVector1() const { return (shapei.n*shapej.n*shapek.n) == this->n ;}
N() const871 long N() const {return shapei.n;}
M() const872 long M() const {return shapej.n;}
K() const873 long K() const {return shapek.n;}
size() const874 long size() const { return shapei.n*shapej.n*shapek.n;}
KNMK_(const ShapeOfArray & s,const ShapeOfArray & si,const ShapeOfArray & sj,const ShapeOfArray & sk,R * u)875 KNMK_(const ShapeOfArray & s,
876 const ShapeOfArray & si,
877 const ShapeOfArray & sj,
878 const ShapeOfArray & sk,
879 R * u)
880 : KN_<R>(u,s),shapei(si),shapej(sj),shapek(sk){}
881
KNMK_(R * u,long n,long m,long k)882 KNMK_(R* u,long n,long m,long k)
883 : KN_<R>(u, ShapeOfArray(n*m*k)),shapei(n,1,n),shapej(m,n,1),shapek(k,n*m,n*m){};
884
885 // KNMK_(const KN_<R> & u,long n,long m,long k)
886 // : KN_<R>(ShapeOfArray(n*m*k)),shapei(n,1,n),shapekj(m,n,1),u),
887 // shapek(k,n*m,n*m){};
888
KNMK_(const KNMK_<R> & U,const SubArray & si,const SubArray & sj,const SubArray & sk)889 KNMK_(const KNMK_<R> &U,const SubArray & si,const SubArray & sj,const SubArray & sk) :
890 KN_<R>(U,SubArray(U.ijk(si.len1(),sj.len1(),sk.len1())+1,
891 U.ijk(si.start,sj.start,sk.start))),
892 shapei(U.shapei,si),
893 shapej(U.shapej,sj),
894 shapek(U.shapek,sk){}
895
KNMK_(const KNMK_<R> & u)896 KNMK_(const KNMK_<R> & u) :KN_<R>(u),shapei(u.shapei),shapej(u.shapej),shapek(u.shapek) {}
897
898
ijk(long i,long j,long k) const899 long ijk(long i,long j,long k) const
900 { return shapei.index(i)+shapej.index(j)+shapek.index(k);}
indexijk(long i,long j,long k) const901 long indexijk(long i,long j,long k) const
902 {return this->index(shapei.index(i)+shapej.index(j)+shapek.index(k));}
903
operator ()(long i,long j,long k) const904 R & operator()(long i,long j,long k) const {return this->v[indexijk(i,j,k)];}
operator ()(int i,int j,int k) const905 R & operator()(int i,int j,int k) const {return this->v[indexijk(i,j,k)];}
906
907 // pas de tableau suivant
operator ()(const char,long j,long k) const908 KN_<R> operator()(const char ,long j,long k) const { // le tableau (.,j,k)
909 return KN_<R>(*this,-1,shapei,shapej[j]+shapek[k]);}
operator ()(long i,const char,long k) const910 KN_<R> operator()(long i,const char ,long k) const { // le tableau (i,.,k)
911 return KN_<R>(*this,-1,shapej,shapei[i]+shapek[k]);}
operator ()(long i,long j,const char) const912 KN_<R> operator()(long i,long j,const char ) const { // le tableau (i,j,.)
913 return KN_<R>(*this,-1,shapek,shapei[i]+shapej[j]);}
914
operator ()(const char,int j,int k) const915 KN_<R> operator()(const char ,int j,int k) const { // le tableau (.,j,k)
916 return KN_<R>(*this,-1,shapei,shapej[j]+shapek[k]);}
operator ()(int i,const char,int k) const917 KN_<R> operator()(int i,const char ,int k) const { // le tableau (i,.,k)
918 return KN_<R>(*this,-1,shapej,shapei[i]+shapek[k]);}
operator ()(int i,int j,const char) const919 KN_<R> operator()(int i,int j,const char ) const { // le tableau (i,j,.)
920 return KN_<R>(*this,-1,shapek,shapei[i]+shapej[j]);}
921 //
operator ()(const char,const char,long k) const922 KNM_<R> operator()(const char ,const char ,long k) const { // le tableau (.,.,k)
923 return KNM_<R>(*this,shapei,shapej,shapek[k],shapek.next);} // step = n*m
924 //attention les suivants ne marche pas
operator ()(const char,long j,const char) const925 KNM_<R> operator()(const char ,long j,const char ) const { // le tableau (.,j,.)
926 return KNM_<R>(*this,shapei,shapek,shapej[j],-1/*shapej.next*/);} // step = n
927
operator ()(long i,const char,const char) const928 KNM_<R> operator()(long i,const char ,const char ) const { // le tableau (i,.,.)
929 return KNM_<R>(*this,shapej,shapek,shapei[i],-1/*shapei.next*/);} // step = 1
930
operator ()(const char,const char,int k) const931 KNM_<R> operator()(const char ,const char ,int k) const { // le tableau (.,.,k)
932 return KNM_<R>(*this,shapei,shapej,shapek[k],shapek.next);} // step = n*m
933 //attention les suivants ne marche pas
operator ()(const char,int j,const char) const934 KNM_<R> operator()(const char ,int j,const char ) const { // le tableau (.,j,.)
935 return KNM_<R>(*this,shapei,shapek,shapej[j],-1/*shapej.next*/);} // step = n
936
operator ()(int i,const char,const char) const937 KNM_<R> operator()(int i,const char ,const char ) const { // le tableau (i,.,.)
938 return KNM_<R>(*this,shapej,shapek,shapei[i],-1/*shapei.next*/);} // step = 1
939
940 KNMK_& operator =(const KNMK_<const_R> & u) ;
941 KNMK_& operator+=(const KNMK_<const_R> & u) ;
942 KNMK_& operator-=(const KNMK_<const_R> & u) ;
943 KNMK_& operator/=(const KNMK_<const_R> & u) ;
944 KNMK_& operator*=(const KNMK_<const_R> & u) ;
945 KNMK_& operator =(const_R a) ;
946 KNMK_& operator+=(const_R a) ;
947 KNMK_& operator-=(const_R a) ;
948 KNMK_& operator/=(const_R a) ;
949 KNMK_& operator*=(const_R a) ;
950
operator ()(SubArray si,SubArray sj,SubArray sk) const951 KNMK_ operator()(SubArray si,SubArray sj,SubArray sk) const
952 {return KNMK_(*this,si,sj,sk);}
953
954 private:
955 // KNMK_& operator++(){v += next;return *this;} // ++U
956 // KNMK_& operator--(){v -= next;return *this;} // --U
957 // KNMK_ operator++(long ){KNMK_ old=*this;v = v +next;return old;} // U++
958 // KNMK_ operator--(long ){KNMK_ old=*this;v = v -next;return old;} // U--
959
960
961 friend class KNM_<R>;
962 friend class KN_<R>;
963
964 };
965
966
967
968 template<class R>
969 class KN :public KN_<R> { public:
970
971 typedef R K;
972
973 // explicit KN(const R & u):KN_<R>(new R(uu),1,0) {}
KN()974 KN() : KN_<R>(0,0) {}
KN(long nn)975 KN(long nn) : KN_<R>(new R[nn],nn) {}
KN(long nn,R * p)976 KN(long nn, R * p) : KN_<R>(new R[nn],nn)
977 { KN_<R>::operator=(KN_<R>(p,nn));}
KN(long nn,R (* f)(long i))978 KN(long nn,R (*f)(long i) ) : KN_<R>(new R[nn],nn)
979 {for(long i=0;i<this->n;i++) this->v[i]=f(i);}
KN(long nn,const R & a)980 KN(long nn,const R & a) : KN_<R>(new R[nn],nn)
981 { KN_<R>::operator=(a);}
KN(long nn,long s,const R a)982 KN(long nn,long s,const R a) : KN_<R>(new R[nn],nn,s)
983 { KN_<R>::operator=(a);}
KN(const KN_<S> & s)984 template<class S> KN(const KN_<S> & s):KN_<R>(new R[s.n],s.n)
985 {for (long i=0;i<this->n;i++) this->v[i] = s[i];}
KN(const KN_<S> & s,R (* f)(S))986 template<class S> KN(const KN_<S> & s,R (*f)(S )):KN_<R>(new R[s.n],s.n)
987 {for (long i=0;i<this->n;i++) this->v[i] = f(s[i]);}
KN(const KN<R> & u)988 KN(const KN<R> & u):KN_<R>(new R[u.n],u.n)
989 { KN_<R>::operator=(u);}
KN(bool,KN<R> & u)990 KN(bool ,KN<R> & u):KN_<R>(u) {u.v=0;u.n=0;}// remove copy for return of local KN.
991
992 // explicit KN(const KN_<R> & u):KN_<R>(new R[u.n],u.n)
993 // { KN_<R>::operator=(u);}
994
~KN()995 ~KN(){delete [] this->v;}
996
CheckSet()997 void CheckSet() { if(!(this->n)) {cerr << "Error RNM set array\n";K_throwassert(0); exit(1);}}
operator =(R * a)998 KN& operator = (R* a) { CheckSet(); return operator =(KN_<R>(a,this->n));}
operator +=(R * a)999 KN& operator += (R* a) { CheckSet(); return operator+=(KN_<R>(a,this->n));}
operator -=(R * a)1000 KN& operator -= (R* a) { CheckSet(); return operator-=(KN_<R>(a,this->n));}
operator *=(R * a)1001 KN& operator *= (R* a) { CheckSet(); return operator*=(KN_<R>(a,this->n));}
operator /=(R * a)1002 KN& operator /= (R* a) { CheckSet(); return operator/=(KN_<R>(a,this->n));}
1003
operator =(const SetArray<R> & u)1004 KN& operator =(const SetArray<R> & u)
1005 { if(this->unset())
1006 this->set(new R[u.size()],u.size(),0,0);
1007 KN_<R>::operator= (u);
1008 return *this;}
operator +=(const SetArray<R> & u)1009 KN& operator +=(const SetArray<R> & u)
1010 { if(this->unset())
1011 this->set(new R[u.size()],u.size(),0,0);
1012 KN_<R>::operator+= (u);
1013 return *this;}
operator -=(const SetArray<R> & u)1014 KN& operator -=(const SetArray<R> & u)
1015 { if(this->unset()) this->set(new R[u.size()],u.size(),0,0); KN_<R>::operator-= (u);return *this;}
operator *=(const SetArray<R> & u)1016 KN& operator *=(const SetArray<R> & u)
1017 { if(this->unset()) this->set(new R[u.size()],u.size(),0,0); KN_<R>::operator*= (u);return *this;}
operator /=(const SetArray<R> & u)1018 KN& operator /=(const SetArray<R> & u)
1019 { if(this->unset()) this->set(new R[u.size()],u.size(),0,0); KN_<R>::operator/= (u);return *this;}
1020
operator =(const_R a)1021 KN& operator =(const_R a)
1022 { if(this->unset()) this->set(new R[1],1,0,0); KN_<R>::operator= (a);return *this;}
operator =(const KN_<R> & a)1023 KN& operator =(const KN_<R>& a)
1024 { if(this->unset()) this->set(new R[a.N()],a.N()); KN_<R>::operator= (a);return *this;}
operator =(const KN<R> & a)1025 KN& operator =(const KN<R>& a)
1026 { if(this->unset()) this->set(new R[a.N()],a.N()); KN_<R>::operator= (a);return *this;}
operator =(const Add_KN_<R> & u)1027 KN& operator =(const Add_KN_<R> & u)
1028 { if(this->unset()) this->set(new R[u.a.N()],u.a.N());KN_<R>::operator=(u);return *this;}
operator =(const DotStar_KN_<R> & u)1029 KN& operator =(const DotStar_KN_<R> & u)
1030 { if(this->unset()) this->set(new R[u.a.N()],u.a.N());KN_<R>::operator=(u);return *this;}
operator =(const if_KN_<R> & u)1031 KN& operator =(const if_KN_<R> & u)
1032 { if(this->unset()) this->set(new R[u.a.N()],u.a.N());KN_<R>::operator=(u);return *this;}
operator =(const ifnot_KN_<R> & u)1033 KN& operator =(const ifnot_KN_<R> & u)
1034 { if(this->unset()) this->set(new R[u.a.N()],u.a.N());KN_<R>::operator=(u);return *this;}
operator =(const DotSlash_KN_<R> & u)1035 KN& operator =(const DotSlash_KN_<R> & u)
1036 { if(this->unset()) this->set(new R[u.a.N()],u.a.N());KN_<R>::operator=(u);return *this;}
operator =(const Sub_KN_<R> & u)1037 KN& operator =(const Sub_KN_<R> & u)
1038 { if(this->unset()) this->set(new R[u.a.N()],u.a.N());KN_<R>::operator=(u);return *this;}
operator =(const Mulc_KN_<R> & u)1039 KN& operator =(const Mulc_KN_<R> & u)
1040 { if(this->unset()) this->set(new R[u.a.N()],u.a.N());KN_<R>::operator=(u);return *this;}
operator =(const Add_Mulc_KN_<R> & u)1041 KN& operator =(const Add_Mulc_KN_<R> & u)
1042 { if(this->unset()) this->set(new R[u.a.N()],u.a.N());KN_<R>::operator=(u);return *this;}
operator =(const if_arth_KN_<R> & u)1043 KN& operator =(const if_arth_KN_<R> & u)
1044 { if(this->unset()) this->set(new R[u.a.N()],u.a.N());KN_<R>::operator=(u);return *this;}
1045
1046
operator =(const Mul_KNM_KN_<R> & u)1047 KN& operator =(const Mul_KNM_KN_<R> & u)
1048 { if(this->unset()) this->set(new R[u.b.N()],u.b.N());KN_<R>::operator=(u);return *this;}
1049 // KN& operator =(const MatriceCreuseMulKN_<R> & Ax)
1050 // {if(this->unset()) this->set(new R[Ax.v.N()],Ax.v.N()); KN_<R>::operator=(Ax);return *this;}
1051 // KN& operator +=(const MatriceCreuseMulKN_<R> & Ax)
1052 // {if(this->unset()) this->set(new R[Ax.v.N()],Ax.v.N()); KN_<R>::operator+=(Ax);return *this;}
1053 // KN& operator =(const MatriceCreuseDivKN_<R> & A1x)
1054 // { if(this->unset()) this->set(new R[A1x.v.N()],A1x.v.N());KN_<R>::operator=(A1x);return *this;}
1055 // correcton aout 2007 FH add N,M flied in VirtualMatrice
operator =(const typename VirtualMatrice<R>::plusAx & Ax)1056 KN& operator =(const typename VirtualMatrice<R>::plusAx & Ax)
1057 { if(this->unset() && Ax.A->N ) this->set(new R[Ax.A->N],Ax.A->N);KN_<R>::operator=(Ax);return *this;}
operator =(const typename VirtualMatrice<R>::solveAxeqb & Ab)1058 KN& operator =(const typename VirtualMatrice<R>::solveAxeqb & Ab)
1059 { if(this->unset()) this->set(new R[Ab.b.N()],Ab.b.N());KN_<R>::operator=(Ab);return *this;}
operator +=(const typename VirtualMatrice<R>::plusAx & Ax)1060 KN& operator +=(const typename VirtualMatrice<R>::plusAx & Ax)
1061 { if(this->unset() && Ax.A->N) {
1062 this->set(new R[Ax.A->N],Ax.A->N);
1063 KN_<R>::operator=(R());}
1064 KN_<R>::operator+=(Ax);
1065 return *this;}
operator =(const typename VirtualMatrice<R>::plusAtx & Ax)1066 KN& operator =(const typename VirtualMatrice<R>::plusAtx & Ax)
1067 { if(this->unset()&&Ax.A->M) this->set(new R[Ax.A->M],Ax.A->M);KN_<R>::operator=(Ax);return *this;}
operator +=(const typename VirtualMatrice<R>::plusAtx & Ax)1068 KN& operator +=(const typename VirtualMatrice<R>::plusAtx & Ax)
1069 { if(this->unset()&&Ax.A->M) {
1070 this->set(new R[Ax.A->M],Ax.A->M);
1071 KN_<R>::operator=(R());}
1072 KN_<R>::operator+=(Ax);
1073 return *this;}
1074 // end correcton FH
1075 template<class P,class Q>
operator =(const PplusQ<P,Q> & PQ)1076 KN& operator =(const PplusQ<P,Q> & PQ)
1077 { *this=PQ.p; *this+=PQ.q;return *this; }
1078 template<class P,class Q>
operator +=(const PplusQ<P,Q> & PQ)1079 KN& operator +=(const PplusQ<P,Q> & PQ)
1080 { *this+=PQ.p; *this+=PQ.q;return *this; }
1081
operator -=(const_R a)1082 KN& operator -=(const_R a)
1083 { KN_<R>::operator-=(a);return *this;}
operator -=(const KN_<R> & a)1084 KN& operator -=(const KN_<R>& a)
1085 { KN_<R>::operator-= (a);return *this;}
operator -=(const Add_KN_<R> & u)1086 KN& operator -=(const Add_KN_<R> & u)
1087 { KN_<R>::operator-=(u);return *this;}
operator -=(const DotStar_KN_<R> & u)1088 KN& operator -=(const DotStar_KN_<R> & u)
1089 { KN_<R>::operator-=(u);return *this;}
operator -=(const DotSlash_KN_<R> & u)1090 KN& operator -=(const DotSlash_KN_<R> & u)
1091 { KN_<R>::operator-=(u);return *this;}
operator -=(const Sub_KN_<R> & u)1092 KN& operator -=(const Sub_KN_<R> & u)
1093 { KN_<R>::operator-=(u);return *this;}
operator -=(const Mulc_KN_<R> & u)1094 KN& operator -=(const Mulc_KN_<R> & u)
1095 { KN_<R>::operator-=(u);return *this;}
operator -=(const Add_Mulc_KN_<R> & u)1096 KN& operator -=(const Add_Mulc_KN_<R> & u)
1097 { KN_<R>::operator-=(u);return *this;}
operator -=(const if_arth_KN_<R> & u)1098 KN& operator -=(const if_arth_KN_<R> & u)
1099 { KN_<R>::operator-=(u);return *this;}
operator -=(const Mul_KNM_KN_<R> & u)1100 KN& operator -=(const Mul_KNM_KN_<R> & u)
1101 { KN_<R>::operator-=(u);return *this;}
1102
operator +=(const_R a)1103 KN& operator +=(const_R a)
1104 { KN_<R>::operator += (a);return *this;}
operator +=(const KN_<R> & a)1105 KN& operator += (const KN_<R>& a)
1106 { KN_<R>::operator+= (a);return *this;}
operator +=(const Add_KN_<R> & u)1107 KN& operator +=(const Add_KN_<R> & u)
1108 { KN_<R>::operator+=(u);return *this;}
operator +=(const DotStar_KN_<R> & u)1109 KN& operator +=(const DotStar_KN_<R> & u)
1110 { KN_<R>::operator+=(u);return *this;}
operator +=(const DotSlash_KN_<R> & u)1111 KN& operator +=(const DotSlash_KN_<R> & u)
1112 { KN_<R>::operator+=(u);return *this;}
operator +=(const Sub_KN_<R> & u)1113 KN& operator +=(const Sub_KN_<R> & u)
1114 { KN_<R>::operator+=(u);return *this;}
operator +=(const Mulc_KN_<R> & u)1115 KN& operator +=(const Mulc_KN_<R> & u)
1116 { KN_<R>::operator+=(u);return *this;}
operator +=(const Add_Mulc_KN_<R> & u)1117 KN& operator +=(const Add_Mulc_KN_<R> & u)
1118 { KN_<R>::operator+=(u);return *this;}
operator +=(const if_arth_KN_<R> & u)1119 KN& operator +=(const if_arth_KN_<R> & u)
1120 { KN_<R>::operator+=(u);return *this;}
operator +=(const Mul_KNM_KN_<R> & u)1121 KN& operator +=(const Mul_KNM_KN_<R> & u)
1122 { KN_<R>::operator+=(u);return *this;}
1123
1124
operator /=(const_R a)1125 KN& operator/=(const_R a)
1126 { KN_<R>::operator/=(a);return *this;}
operator /=(const KN_<R> & a)1127 KN& operator /= (const KN_<R>& a)
1128 { KN_<R>::operator/= (a);return *this;}
operator /=(const Add_KN_<R> & u)1129 KN& operator /=(const Add_KN_<R> & u)
1130 { KN_<R>::operator/=(u);return *this;}
operator /=(const Sub_KN_<R> & u)1131 KN& operator /=(const Sub_KN_<R> & u)
1132 { KN_<R>::operator/=(u);return *this;}
operator /=(const Mulc_KN_<R> & u)1133 KN& operator /=(const Mulc_KN_<R> & u)
1134 { KN_<R>::operator/=(u);return *this;}
operator /=(const Add_Mulc_KN_<R> & u)1135 KN& operator /=(const Add_Mulc_KN_<R> & u)
1136 { KN_<R>::operator/=(u);return *this;}
operator /=(const if_arth_KN_<R> & u)1137 KN& operator /=(const if_arth_KN_<R> & u)
1138 { KN_<R>::operator/=(u);return *this;}
1139
operator /=(const Mul_KNM_KN_<R> & u)1140 KN& operator /=(const Mul_KNM_KN_<R> & u)
1141 { KN_<R>::operator/=(u);return *this;}
1142
operator *=(const_R a)1143 KN& operator*=(const_R a)
1144 { KN_<R>::operator*=(a);return *this;}
operator *=(const KN_<const_R> & a)1145 KN& operator*=(const KN_<const_R>& a)
1146 { KN_<R>::operator*= (a);return *this;}
operator *=(const Add_KN_<R> & u)1147 KN& operator *=(const Add_KN_<R> & u)
1148 { KN_<R>::operator*=(u);return *this;}
operator *=(const Sub_KN_<R> & u)1149 KN& operator *=(const Sub_KN_<R> & u)
1150 { KN_<R>::operator*=(u);return *this;}
operator *=(const Mulc_KN_<R> & u)1151 KN& operator *=(const Mulc_KN_<R> & u)
1152 { KN_<R>::operator*=(u);return *this;}
operator *=(const Add_Mulc_KN_<R> & u)1153 KN& operator *=(const Add_Mulc_KN_<R> & u)
1154 { KN_<R>::operator*=(u);return *this;}
operator *=(const if_arth_KN_<R> & u)1155 KN& operator *=(const if_arth_KN_<R> & u)
1156 { KN_<R>::operator*=(u);return *this;}
operator *=(const Mul_KNM_KN_<R> & u)1157 KN& operator *=(const Mul_KNM_KN_<R> & u)
1158 { KN_<R>::operator*=(u);return *this;}
1159
1160
operator =(const KN_ITAB<T,I> & ui)1161 template<class I,class T> KN& operator = (const KN_ITAB<T ,I> & ui)
1162 { KN_<R>::operator =(ui); return *this;}
operator +=(const KN_ITAB<T,I> & ui)1163 template<class I,class T> KN& operator += (const KN_ITAB<T ,I> & ui)
1164 { KN_<R>::operator +=(ui); return *this;}
operator -=(const KN_ITAB<T,I> & ui)1165 template<class I,class T> KN& operator -= (const KN_ITAB<T ,I> & ui)
1166 { KN_<R>::operator -=(ui); return *this;}
operator *=(const KN_ITAB<T,I> & ui)1167 template<class I,class T> KN& operator *= (const KN_ITAB<T ,I> & ui)
1168 { KN_<R>::operator *=(ui); return *this;}
operator /=(const KN_ITAB<T,I> & ui)1169 template<class I,class T> KN& operator /= (const KN_ITAB<T ,I> & ui)
1170 { KN_<R>::operator /=(ui); return *this;}
1171
1172
1173 // two opertor to cast to an array of constant
1174 // operator KN_<const_R> & ()
1175 // { return * (KN_<const_R>*) this;}
1176 // operator KN_<const_R> const & () const
1177 // { return *(const KN_<const_R>*) this;}
1178 // operator KN<const_R> & ()
1179 // { return (KN<const_R> &) *this;}
1180 // operator KN<const_R> const & () const
1181 // { return (const KN<const_R>& ) *this;}
init(long nn)1182 void init(long nn) {this->n=nn;this->step=1;this->next=-1;this->v=new R[nn];}
init()1183 void init() {this->n=0;this->step=1;this->next=-1;this->v=0;}
init(const KN_<R> & a)1184 void init(const KN_<R> & a){init(a.N()); operator=(a);}
resize(long nn)1185 void resize(long nn) {
1186 if ( nn != this->n)
1187 {
1188 R *vo=this->v;
1189 long no=std::min(this->n,nn), so=this->step;
1190 ShapeOfArray::init(nn);
1191 this->v=new R[this->n];
1192 // copy
1193 if(this->v && vo)
1194 for(long i=0,j=0;j<no;i++,j+=so)
1195 this->v[i]=vo[j];
1196 delete [] vo;} }// mars 2010
destroy()1197 void destroy(){ if(this->next++ ==-1) {delete [] this->v; this->v=0;this->n=0;}}// mars 2010
increment()1198 void increment() { this->next--;}
1199 };
1200
1201 // Array with 2 indices
1202 // ---------------------
1203
1204 template<class R>
1205 class KNM: public KNM_<R>{ public:
1206
KNM(long nn,long mm)1207 KNM(long nn,long mm)
1208 :KNM_<R>(new R[nn*mm],nn,mm){}
KNM(const KNM<R> & u)1209 KNM(const KNM<R> & u) // PB si stepi ou stepj nulle
1210 :KNM_<R>(new R[u.size()],u.N(),u.M())
1211 { KN_<R>::operator=(u);}
KNM(const KNM_<R> & u)1212 explicit KNM(const KNM_<R> & u)
1213 :KNM_<R>(new R[u.size()],u.N(),u.M())
1214 { KNM_<R>::operator=(u);}
1215
~KNM()1216 ~KNM(){delete [] this->v;}
1217
operator =(const KNM_<const_R> & u)1218 KNM& operator=(const KNM_<const_R> & u)
1219 { if(this->unset()) this->init(u.N(),u.M()) ; KNM_<R>::operator=(u);return *this;}
operator =(const_R a)1220 KNM& operator=(const_R a)
1221 { if(this->unset()) RNM_FATAL_ERROR(" KNM operator=(double)"); KNM_<R>::operator=(a);return *this;}
operator +=(const_R a)1222 KNM& operator+=(const_R a)
1223 { if(this->unset()) RNM_FATAL_ERROR(" KNM operator+=(double)"); KNM_<R>::operator+=(a);return *this;}
operator -=(const_R a)1224 KNM& operator-=(const_R a)
1225 {if(this->unset()) RNM_FATAL_ERROR(" KNM operator-=(double)"); KNM_<R>::operator-=(a);return *this;}
operator /=(const_R a)1226 KNM& operator/=(const_R a)
1227 {if(this->unset()) RNM_FATAL_ERROR(" KNM operator/=(double)"); KNM_<R>::operator/=(a);return *this;}
operator *=(const_R a)1228 KNM& operator*=(const_R a)
1229 {if(this->unset()) RNM_FATAL_ERROR(" KNM operator*=(double)"); KNM_<R>::operator*=(a);return *this;}
operator +=(const KNM_<const_R> & u)1230 KNM& operator+=(const KNM_<const_R> & u)
1231 { if(this->unset()) this->init(u.N(),u.M()) ; KNM_<R>::operator+=(u);return *this;}
operator -=(const KNM_<const_R> & u)1232 KNM& operator-=(const KNM_<const_R> & u)
1233 { if(this->unset()) this->init(u.N(),u.M()) ;KNM_<R>::operator-=(u);return *this;}
1234
operator /=(const KNM_<const_R> & u)1235 KNM& operator/=(const KNM_<const_R> & u)
1236 { if(this->unset()) this->init(u.N(),u.M()) ;KNM_<R>::operator/=(u);return *this;}
operator *=(const KNM_<const_R> & u)1237 KNM& operator*=(const KNM_<const_R> & u)
1238 { if(this->unset()) this->init(u.N(),u.M()) ; KNM_<R>::operator*=(u);return *this;}
1239
1240
operator =(const outProduct_KN_<R> & u)1241 KNM &operator =(const outProduct_KN_<R> & u)
1242 { if(this->unset()) this->init(u.N(),u.M()) ; KNM_<R>::operator =(u);return *this;}
operator +=(const outProduct_KN_<R> & u)1243 KNM &operator +=(const outProduct_KN_<R> & u)
1244 { if(this->unset()) this->init(u.N(),u.M()) ; KNM_<R>::operator+=(u);return *this;}
operator -=(const outProduct_KN_<R> & u)1245 KNM &operator -=(const outProduct_KN_<R> & u)
1246 { if(this->unset()) this->init(u.N(),u.M()) ; KNM_<R>::operator-=(u);return *this;}
operator /=(const outProduct_KN_<R> & u)1247 KNM &operator /=(const outProduct_KN_<R> & u)
1248 { if(this->unset()) this->init(u.N(),u.M()) ;KNM_<R>::operator/=(u);return *this;}
operator *=(const outProduct_KN_<R> & u)1249 KNM &operator *=(const outProduct_KN_<R> & u)
1250 { if(this->unset()) this->init(u.N(),u.M()) ;KNM_<R>::operator*=(u);return *this;}
1251
1252
1253 // two opertors to cast to un array of constant
1254 // operator KNM_<const_R> & ()
1255 // { return * (KNM_<const_R>*) this;}
1256 // operator KNM_<const_R> const & () const
1257 // { return *(const KNM_<const_R>*) this;}
1258
1259 // operator KNM<const_R> & ()
1260 // { return * (KNM<const_R>*) this;}
1261 // operator KNM<const_R> const & () const
1262 // { return *(const KNM<const_R>*) this;}
1263
init()1264 void init() { // add mars 2010 ...
1265 this->n=0;this->step=1;this->next=-1;this->v=0;
1266 this->shapei.init(0);
1267 this->shapej.init(0);}
1268
init(long nn,long mm)1269 void init(long nn,long mm) {
1270 ShapeOfArray::init(nn*mm);
1271 this->shapei.init(nn,1,nn);
1272 this->shapej.init(mm,nn,1),
1273 this->v=new R[nn*mm];}
1274
resize(long nn,long mm)1275 void resize(long nn,long mm) {
1276 long kk=nn*mm;
1277
1278 long lso = this->size();
1279 long n = this->shapei.n;
1280 long m = this->shapej.n;
1281
1282 if( n !=nn && m != mm)
1283 {
1284 KNM_ <R> old(*this);
1285 long no=std::min(n,nn);
1286 long mo=std::min(m,mm);
1287 R *vo=this->v;
1288
1289 // new mat
1290 ShapeOfArray::init(kk);
1291 this->v=new R[this->n];
1292 this->shapei.init(nn,1,nn);
1293 this->shapej.init(mm,nn,1);
1294
1295 if(this->v && vo) // copy
1296 (*this)(SubArray(no),SubArray(mo)) = old(SubArray(no),SubArray(mo));
1297
1298 delete []vo;
1299 }
1300
1301 }
destroy()1302 void destroy(){ if(this->next++ ==-1) {delete [] this->v; this->v=0;this->n=0;}}
increment()1303 void increment() { this->next--;}
1304
1305 // void destroy(){delete [] this->v;this->n=0 ;}
1306
1307 };
1308
1309 // Array with 3 indices
1310 // ---------------------
1311 template<class R>
1312 class KNMK: public KNMK_<R>{ public:
1313
KNMK(long n,long m,long k)1314 KNMK(long n,long m,long k)
1315 :KNMK_<R>(new R[n*m*k],n,m,k){}
KNMK(const KNMK_<R> & u)1316 explicit KNMK(const KNMK_<R> & u)
1317 :KNMK_<R>(new R[u.size()],u.N(),u.M(),u.K())
1318 { KNMK_<R>::operator=(u);}
KNMK(const KNMK<R> & u)1319 KNMK(const KNMK<R> & u)
1320 :KNMK_<R>(new R[u.size()],u.N(),u.M(),u.K())
1321 { KNMK_<R>::operator=(u);}
1322
~KNMK()1323 ~KNMK(){delete [] this->v;}
1324
operator =(const KNMK_<const_R> & u)1325 KNMK& operator=(const KNMK_<const_R> & u)
1326 { KNMK_<R>::operator=(u);return *this;}
operator =(const_R a)1327 KNMK& operator=(const_R a)
1328 { KNMK_<R>::operator=(a);return *this;}
operator +=(const_R a)1329 KNMK& operator+=(const_R a)
1330 { KNMK_<R>::operator+=(a);return *this;}
operator -=(const_R a)1331 KNMK& operator-=(const_R a)
1332 { KNMK_<R>::operator-=(a);return *this;}
operator /=(const_R a)1333 KNMK& operator/=(const_R a)
1334 { KNMK_<R>::operator/=(a);return *this;}
operator *=(const_R a)1335 KNMK& operator*=(const_R a)
1336 { KNMK_<R>::operator*=(a);return *this;}
operator +=(const KNMK_<const_R> & u)1337 KNMK& operator+=(const KNMK_<const_R> & u)
1338 { KNMK_<R>::operator+=(u);return *this;}
1339 // ici jd
operator -=(const KNMK_<const_R> & u)1340 KNMK& operator-=(const KNMK_<const_R> & u)
1341 { KNMK_<R>::operator-=(u);return *this;}
operator *=(const KNMK_<const_R> & u)1342 KNMK& operator*=(const KNMK_<const_R> & u)
1343 { KNMK_<R>::operator*=(u);return *this;}
operator /=(const KNMK_<const_R> & u)1344 KNMK& operator/=(const KNMK_<const_R> & u)
1345 { KNMK_<R>::operator/=(u);return *this;}
1346
1347 // two opertor to cast to un array of constant
1348 // operator KNMK_<const_R> & ()
1349 // { return * (KNMK_<const_R>*) this;}
1350 // operator KNMK_<const_R> const & () const
1351 // { return *(const KNMK_<const_R>*) this;}
1352
1353 // operator KNMK<const_R> & ()
1354 // { return * (KNMK<const_R>*) this;}
1355 // operator KNMK<const_R> const & () const
1356 // { return *(const KNMK<const_R>*) this;}
1357 };
1358
1359 // ------------- optimization ---------------------
1360 template<class R>
1361 class conj_KN_{public:
1362 const KN_<const_R> & a;
conj_KN_(const KN_<const_R> & aa)1363 conj_KN_(const KN_<const_R> & aa) : a(aa){}
1364 };
1365
1366
conj(const KN_<long> & a)1367 inline const KN_<long> conj(const KN_<long> &a){ return a;}
conj(const KN_<double> & a)1368 inline const KN_<double> conj(const KN_<double> &a){ return a;}
conj(const KN_<float> & a)1369 inline const KN_<float> conj(const KN_<float> &a){ return a;}
1370
1371 //template<class R> conj_KN_<R> conj(const KN<R> &a){ return a;}
conj(const KN_<R> & a)1372 template<class R> conj_KN_<R> conj(const KN_<R> &a){ return a;}
1373
1374 template<class R>
1375 class DotStar_KN_{public:
1376 const KN_<const_R> a; const KN_<const_R> b;
DotStar_KN_(const KN_<const_R> & aa,const KN_<const_R> & bb)1377 DotStar_KN_(const KN_<const_R> & aa,const KN_<const_R> & bb) : a(aa),b(bb) {}
1378 };
1379
1380
1381 template<class R>
1382 class DotSlash_KN_{public:
1383 const KN_<const_R> a; const KN_<const_R> b;
DotSlash_KN_(const KN_<const_R> & aa,const KN_<const_R> & bb)1384 DotSlash_KN_(const KN_<const_R> & aa,const KN_<const_R> & bb) : a(aa),b(bb) {}
1385 };
1386
1387 template<class R>
1388 class Add_KN_{public:
1389 const KN_<const_R> a; const KN_<const_R> b;
Add_KN_(const KN_<const_R> & aa,const KN_<const_R> & bb)1390 Add_KN_(const KN_<const_R> & aa,const KN_<const_R> & bb)
1391 : a(aa),b(bb) { K_throwassert(SameShape(a,b));}
1392 };
1393
1394 template<class R>
1395 class Sub_KN_{public:
1396 const KN_<const_R> a; const KN_<const_R> b;
Sub_KN_(const KN_<const_R> & aa,const KN_<const_R> & bb)1397 Sub_KN_(const KN_<const_R> & aa,const KN_<const_R> & bb)
1398 : a(aa),b(bb) { K_throwassert(SameShape(a,b));}
1399 };
1400
1401 template<class R>
1402 class Mulc_KN_ { public:
1403 const KN_<const_R> a; const_R b;
Mulc_KN_(const KN_<const_R> & aa,const_R bb)1404 Mulc_KN_(const KN_<const_R> & aa,const_R bb) : a(aa),b(bb) {}
Mulc_KN_(const Mulc_KN_<R> & aa,const_R bb)1405 Mulc_KN_(const Mulc_KN_<R> & aa,const_R bb) : a(aa.a),b(aa.b*bb) {}
operator -() const1406 Mulc_KN_ operator-() const {return Mulc_KN_(a,-b);}
operator *(const TKN_<double> & bb)1407 outProduct_KN_<R> operator*(const TKN_<double> & bb)
1408 { return outProduct_KN_<R>(a,bb,b);}
1409
1410 };
1411
1412 template<class R>
1413 class Add_Mulc_KN_ { public:
1414 const KN_<const_R> a,b;
1415 const R ca,cb;
Add_Mulc_KN_(const Mulc_KN_<R> & aa,const Mulc_KN_<R> & bb)1416 Add_Mulc_KN_(const Mulc_KN_<R> & aa,const Mulc_KN_<R> & bb)
1417 : a(aa.a),b(bb.a),ca(aa.b),cb(bb.b) { K_throwassert(SameShape(a,b));}
Add_Mulc_KN_(const Mulc_KN_<R> & aa,const KN_<const_R> & bb,const R cbb)1418 Add_Mulc_KN_(const Mulc_KN_<R> & aa,const KN_<const_R> & bb,const R cbb)
1419 : a(aa.a),b(bb),ca(aa.b),cb(cbb) { K_throwassert(SameShape(a,b));}
Add_Mulc_KN_(const KN_<const_R> & aa,const R caa,const KN_<const_R> & bb,const R cbb)1420 Add_Mulc_KN_(const KN_<const_R> & aa,const R caa,const KN_<const_R> & bb,const R cbb)
1421 : a(aa),b(bb),ca(caa),cb(cbb) { K_throwassert(SameShape(a,b));}
1422 };
1423
1424 template<class R>
1425 class if_arth_KN_ { public:
1426 const KN_<const_R> a,b,c;
if_arth_KN_(const KN_<R> & aa,const KN_<R> & bb,const KN_<R> & cc)1427 if_arth_KN_(const KN_<R> & aa,const KN_<R> & bb,const KN_<R> & cc)
1428 : a(aa),b(bb),c(cc){ K_throwassert(SameShape(a,b)&&SameShape(a,c));}
1429 };
1430
1431
1432
1433 template<class R>
1434 class Mul_KNM_KN_ { public:
1435 const KNM_<const_R> &A;
1436 const KN_<const_R> &b;
Mul_KNM_KN_(const KNM_<const_R> & aa,const KN_<const_R> & bb)1437 Mul_KNM_KN_(const KNM_<const_R> &aa,const KN_<const_R> &bb)
1438 : A(aa),b(bb) {K_throwassert(SameShape(A.shapej,b));}
1439 };
1440
1441
1442 ostream & operator<<(ostream & f,const ShapeOfArray & s);
1443
1444 template<class R> ostream & operator<<(ostream & f,const KN_<const_R> & v);
1445 template<class R> ostream & operator<<(ostream & f,const KNM_<const_R> & v);
1446 template<class R> ostream & operator<<(ostream & f,const KNMK_<const_R> & v);
operator <<(ostream & f,const KN<const_R> & v)1447 template<class R> inline ostream & operator<<(ostream & f,const KN<const_R> & v)
1448 { return f << (const KN_<const_R> &) v;}
operator <<(ostream & f,const KNM<const_R> & v)1449 template<class R> inline ostream & operator<<(ostream & f,const KNM<const_R> & v)
1450 { return f << (const KNM_<const_R> &) v;}
operator <<(ostream & f,const KNMK<const_R> & v)1451 template<class R> inline ostream & operator<<(ostream & f,const KNMK<const_R> & v)
1452 { return f << (const KNMK_<const_R> &) v;}
1453
1454
operator +(const KN_<const_R> & a,const KN_<const_R> & b)1455 template<class R> inline Add_KN_<R> operator+(const KN_<const_R> &a,const KN_<const_R> &b)
1456 { return Add_KN_<R>(a,b);}
operator -(const KN_<const_R> & a,const KN_<const_R> & b)1457 template<class R> inline Sub_KN_<R> operator-(const KN_<const_R> &a,const KN_<const_R> &b)
1458 { return Sub_KN_<R>(a,b);}
operator *(const KN_<const_R> & a,const R & b)1459 template<class R> inline Mulc_KN_<R> operator*(const KN_<const_R> &a,const R &b)
1460 { return Mulc_KN_<R>(a,b);}
operator /(const KN_<const_R> & a,const R & b)1461 template<class R> inline Mulc_KN_<R> operator/(const KN_<const_R> &a,const R &b)
1462 { return Mulc_KN_<R>(a,1/b);}
operator *(const R & b,const KN_<const_R> & a)1463 template<class R> inline Mulc_KN_<R> operator*(const R &b,const KN_<const_R> &a)
1464 { return Mulc_KN_<R>(a,b);}
operator -(const KN_<const_R> & a)1465 template<class R> inline Mulc_KN_<R> operator-(const KN_<const_R> &a)
1466 { return Mulc_KN_<R>(a,-1);}
1467
1468
1469
operator +(const Mulc_KN_<R> & a,const Mulc_KN_<R> & b)1470 template<class R> inline Add_Mulc_KN_<R> operator+(const Mulc_KN_<R>& a,const Mulc_KN_<R> &b)
1471 { return Add_Mulc_KN_<R>(a,b);}
operator -(const Mulc_KN_<R> & a,const Mulc_KN_<R> & b)1472 template<class R> inline Add_Mulc_KN_<R> operator-(const Mulc_KN_<R>& a,const Mulc_KN_<R> &b)
1473 { return Add_Mulc_KN_<R>(a,b.a,-b.b);}
1474
operator +(const Mulc_KN_<R> & a,const KN_<const_R> & b)1475 template<class R> inline Add_Mulc_KN_<R> operator+(const Mulc_KN_<R>& a,const KN_<const_R> &b)
1476 { return Add_Mulc_KN_<R>(a,b,R(1));}
operator -(const Mulc_KN_<R> & a,const KN_<const_R> & b)1477 template<class R> inline Add_Mulc_KN_<R> operator-(const Mulc_KN_<R>& a,const KN_<const_R> &b)
1478 { return Add_Mulc_KN_<R>(a,b,R(-1));}
1479
operator +(const KN_<const_R> & b,const Mulc_KN_<R> & a)1480 template<class R> inline Add_Mulc_KN_<R> operator+(const KN_<const_R> & b,const Mulc_KN_<R>& a)
1481 { return Add_Mulc_KN_<R>(a,b,R(1));}
1482
1483 // modif FH mars 2007
operator -(const KN_<const_R> & a,const Mulc_KN_<R> & b)1484 template<class R> inline Add_Mulc_KN_<R> operator-(const KN_<const_R> & a,const Mulc_KN_<R>& b)
1485 { return Add_Mulc_KN_<R>(a,R(1),b.a,-b.b);}// modif FH mars 2007
1486
operator *(const KNM_<const_R> & A,const KN_<const_R> & b)1487 template<class R> inline Mul_KNM_KN_<R> operator*(const KNM_<const_R> & A,const KN_<const_R> & b)
1488 { return Mul_KNM_KN_<R>(A,b);}
1489
1490
SameShape(const ShapeOfArray & a,const Add_Mulc_KN_<R> & b)1491 template<class R> inline bool SameShape(const ShapeOfArray & a,const Add_Mulc_KN_<R> & b)
1492 { return SameShape(a,b.a) ;}
SameShape(const ShapeOfArray & a,const if_arth_KN_<R> & b)1493 template<class R> inline bool SameShape(const ShapeOfArray & a,const if_arth_KN_<R> & b)
1494 { return SameShape(a,b.a) ;}
SameShape(const ShapeOfArray & a,const Add_KN_<R> & b)1495 template<class R> inline bool SameShape(const ShapeOfArray & a,const Add_KN_<R> & b)
1496 { return SameShape(a,b.a) ;}
SameShape(const ShapeOfArray & a,const Sub_KN_<R> & b)1497 template<class R> inline bool SameShape(const ShapeOfArray & a,const Sub_KN_<R> & b)
1498 { return SameShape(a,b.a) ;}
SameShape(const ShapeOfArray & a,const Mulc_KN_<R> & b)1499 template<class R> inline bool SameShape(const ShapeOfArray & a,const Mulc_KN_<R> & b)
1500 { return SameShape(a,b.a) ;}
SameShape(const ShapeOfArray & a,const DotStar_KN_<R> & b)1501 template<class R> inline bool SameShape(const ShapeOfArray & a,const DotStar_KN_<R> & b)
1502 { return SameShape(a,b.a) ;}
SameShape(const ShapeOfArray & a,const DotSlash_KN_<R> & b)1503 template<class R> inline bool SameShape(const ShapeOfArray & a,const DotSlash_KN_<R> & b)
1504 { return SameShape(a,b.a) ;}
SameShape(const ShapeOfArray & a,const Mul_KNM_KN_<R> & b)1505 template<class R> inline bool SameShape(const ShapeOfArray & a,const Mul_KNM_KN_<R> & b)
1506 { return a.n==b.A.N() ;}
SameShape(const ShapeOfArray &,const VirtualMatrice<double>::plusAx &)1507 inline bool SameShape(const ShapeOfArray & ,const VirtualMatrice<double>::plusAx & )
1508 { return true ;} // pas de test car la matrice peut etre rectangulaire
SameShape(const ShapeOfArray &,const VirtualMatrice<double>::plusAtx &)1509 inline bool SameShape(const ShapeOfArray & ,const VirtualMatrice<double>::plusAtx & )
1510 { return true ;} // pas de test car la matrice peut etre rectangulaire
SameShape(const ShapeOfArray &,const VirtualMatrice<complex<double>>::plusAx &)1511 inline bool SameShape(const ShapeOfArray & ,const VirtualMatrice<complex<double> >::plusAx & )
1512 { return true ;} // pas de test car la matrice peut etre rectangulaire
SameShape(const ShapeOfArray &,const VirtualMatrice<complex<double>>::plusAtx &)1513 inline bool SameShape(const ShapeOfArray & ,const VirtualMatrice<complex<double> >::plusAtx & )
1514 { return true ;} // pas de test car la matrice peut etre rectangulaire
1515
SameShape(const ShapeOfArray &,const double)1516 inline bool SameShape(const ShapeOfArray & ,const double)
1517 { return true;}
SameShape(const ShapeOfArray &,const complex<double>)1518 inline bool SameShape(const ShapeOfArray & ,const complex<double>)
1519 { return true;}
SameShape(const ShapeOfArray &,const complex<float>)1520 inline bool SameShape(const ShapeOfArray & ,const complex<float>)
1521 { return true;}
1522
1523 template<class R>
SameShape(KNM<R> & m,const outProduct_KN_<R> & p)1524 inline bool SameShape(KNM<R>& m, const outProduct_KN_<R>& p)
1525 { return p.a.N()>=m.N() && m.M()>=p.b.N(); }
1526
SameAdress(const KN_<R> & a,const KN_<R> & b)1527 template<class R> inline long SameAdress(const KN_<R> &a, const KN_<R> &b) { return &a[0]==&b[0];}
1528 // bof -bof
1529 //template<class R> inline
1530 // KN_<R>::operator KN<R> &() { return *(KN<R> *) (void *) this;}
1531 //template<class R> inline
1532 // KN_<R>::operator const KN<R> &() const { return *(const KN<R> *) ( const void *) this;}
1533
1534 // operateur y=Ax-b ou y=Ax + b pour le GC
1535 template<class R>
operator -(const typename VirtualMatrice<R>::plusAx & A,const KN_<R> & B)1536 PplusQ< typename VirtualMatrice<R>::plusAx, Mulc_KN_<R> > operator-(const typename VirtualMatrice<R>::plusAx & A,const KN_<R> & B)
1537 { return PplusQ< typename VirtualMatrice<R>::plusAx, Mulc_KN_<R> >(A,Mulc_KN_<R>(B,R(-1.)));}
1538
1539 template<class R>
operator +(const typename VirtualMatrice<R>::plusAx & A,const KN_<R> & B)1540 PplusQ< typename VirtualMatrice<R>::plusAx, KN_<R> > operator+(const typename VirtualMatrice<R>::plusAx & A,const KN_<R> & B)
1541 { return PplusQ< typename VirtualMatrice<R>::plusAx, KN_<R> >(A,B);}
1542
1543 template<class R>
operator -(const typename VirtualMatrice<R>::plusAx & A,const KN<R> & B)1544 PplusQ< typename VirtualMatrice<R>::plusAx, Mulc_KN_<R> > operator-(const typename VirtualMatrice<R>::plusAx & A,const KN<R> & B)
1545 { return PplusQ< typename VirtualMatrice<R>::plusAx, Mulc_KN_<R> >(A,Mulc_KN_<R>(B,R(-1.)));}
1546
1547 template<class R>
operator +(const typename VirtualMatrice<R>::plusAx & A,const KN<R> & B)1548 PplusQ< typename VirtualMatrice<R>::plusAx, KN_<R> > operator+(const typename VirtualMatrice<R>::plusAx & A,const KN<R> & B)
1549 { return PplusQ< typename VirtualMatrice<R>::plusAx, KN_<R> >(A,B);}
1550
1551
1552 template<class R>
diagonal(const KNM<R> & A)1553 KN_<R> diagonal(const KNM<R> & A) {
1554 K_throwassert(A.N() == A.M());
1555 return KN_<R>(A,SubArray(A.N(),0,A.N()+1));}
1556
1557 // to def inv permutation FH mars 2006
1558 class Inv_KN_long{ public:
1559 KN_<long> t;
Inv_KN_long(const KN_<long> & v)1560 Inv_KN_long(const KN_<long> & v)
1561 : t(v) {}
Inv_KN_long(KN_<long> const * & v)1562 Inv_KN_long( KN_<long> const * & v)
1563 : t(*v) {}
operator const KN_<long>&() const1564 operator const KN_<long> & () const {return t;}
1565 };
1566
1567
1568 template<class R,typename A,typename B=R> class F_KN_
1569 {
1570 public:
1571 A (*f)(B);
1572 KN_<R> a;
N() const1573 long N() const {return a.N();}
F_KN_(A (* ff)(B),const KN_<R> & aa)1574 F_KN_( A (*ff)(B),const KN_<R> & aa): f(ff),a(aa) {}
operator [](long i) const1575 A operator[](long i) const { return f(a[i]);}
check(long n) const1576 bool check(long n) const { return n <= a.N() || a.constant(); }
constant() const1577 bool constant() const {return a.constant();}
1578 };
1579
1580 template<class R,typename A,typename B>
SameShape(const ShapeOfArray & a,const F_KN_<R,A,B> & b)1581 inline bool SameShape(const ShapeOfArray & a,const F_KN_<R,A,B> & b)
1582 { return !a.step || b.constant() || a.n == b.N() ;}
1583
1584 #include "RNM_tpl.hpp"
1585 #ifdef K_throwassert
1586 #undef K_throwassert
1587 #endif
1588 #endif
1589