1 #ifndef FUNCTIONS_ARRAY_H
2 #define FUNCTIONS_ARRAY_H
6 #include "functions_type.h"
28 #include "functions_numeric.h"
29 #include "functions_string.h"
36 namespace functions_array {
42 template<
typename T,
size_t D> requires (functions_type::isArithmeticType<T>)
43 inline void reset(std::array<T,D>& a) {
44 memset(a.data(),0,
sizeof(T)*D);
48 template<
typename T> requires (functions_type::isArithmeticType<T>)
49 inline void reset(std::valarray<T>& a) {
50 if (a.size()>0) memset(&a[0],0,
sizeof(T)*a.size());
61 template<
typename T,
size_t D,
size_t L> requires ((L==D) && functions_type::isArithmeticType<T>)
62 inline T levelMixedProduct(
const T* A,
const T* B,
const T* C) {
63 return (*C)*(A[1-D]*B[-1]-A[-1]*B[1-D]);
67 template<
typename T,
size_t D,
size_t L> requires ((L>1) && (L<D) && functions_type::isArithmeticType<T>)
68 inline T levelMixedProduct(
const T* A,
const T* B,
const T* C) {
69 return (*C)*(A[1]*B[-1]-A[-1]*B[1])+levelMixedProduct<T,D,L+1>(A+1,B+1,C+1);
73 template<
typename T,
size_t D,
size_t L> requires ((L==1) && functions_type::isArithmeticType<T>)
74 inline T levelMixedProduct(
const T* A,
const T* B,
const T* C) {
75 return (*C)*(A[1]*B[D-1]-A[D-1]*B[1])+levelMixedProduct<T,D,2>(A+1,B+1,C+1);
83 template<
typename T,
size_t D> requires (functions_type::isArithmeticType<T>)
84 inline T mixedProduct(
const T* A,
const T* B,
const T* C) {
85 return levelMixedProduct<T,D,1>(A,B,C);
89 template<
typename T,
size_t D> requires (functions_type::isArithmeticType<T>)
90 inline T mixedProduct(
const std::array<T,D>& A,
const std::array<T,D>& B,
const std::array<T,D>& C) {
91 return levelMixedProduct<T,D,1>(A.data(),B.data(),C.data());
99 template<
typename T,
size_t D,
size_t L> requires ((L==D) && functions_type::isArithmeticType<T>)
100 inline void levelVectorProduct(
const T* A,
const T* B,T* R) {
101 (*R)+=(A[1-D]*B[-1]-A[-1]*B[1-D]);
105 template<
typename T,
size_t D,
size_t L> requires ((L>1) && (L<D) && functions_type::isArithmeticType<T>)
106 inline void levelVectorProduct(
const T* A,
const T* B,T* R) {
107 (*R)+=(A[1]*B[-1]-A[-1]*B[1]);
108 levelVectorProduct<T,D,L+1>(A+1,B+1,R+1);
112 template<
typename T,
size_t D,
size_t L> requires ((L==1) && functions_type::isArithmeticType<T>)
113 inline void levelVectorProduct(
const T* A,
const T* B,T* R) {
114 (*R)+=(A[1]*B[D-1]-A[D-1]*B[1]);
115 levelVectorProduct<T,D,2>(A+1,B+1,R+1);
122 template<
typename T,
size_t D> requires (functions_type::isArithmeticType<T>)
123 inline void vectorProduct(
const T* A,
const T* B, T* R) {
124 ASSERT_IN((R!=A) && (R!=B));
125 levelVectorProduct<T,D,1>(A,B,R);
129 template<
typename T,
size_t D> requires (functions_type::isArithmeticType<T>)
130 inline void vectorProduct(
const T* A,
const T* B,
const tBoolean& alpha,T* R) {
131 if (alpha==0) memset(R,0,
sizeof(T)*D);
132 vectorProduct<T,D,1>(A,B,R);
137 template<
typename T,
size_t D> requires (functions_type::isArithmeticType<T>)
138 inline void vectorProduct(
const std::array<T,D>& A,
const std::array<T,D>& B,
const tBoolean& alpha, std::array<T,D>& R) {
139 vectorProduct<T,D,1>(A.data(),B.data(),alpha,R.data());
148 template<
typename T,
typename Q,
size_t L,
size_t D> requires ( (L==D) && functions_type::isArithmeticType<T>&& functions_type::isArithmeticType<Q>)
149 inline T levelScalarProduct(
const T * M,
const Q *H) {
156 template<
typename T,
typename Q,
size_t L,
size_t D> requires ( (L<D) && functions_type::isArithmeticType<T> && functions_type::isArithmeticType<Q>)
157 inline T levelScalarProduct(
const T * M,
const Q *H) {
158 return (*M)*(*H)+levelScalarProduct<T,Q,L+1,D>(M+1,H+1);
166 template<
typename T,
typename Q,
size_t D> requires (functions_type::isArithmeticType<T> && functions_type::isArithmeticType<Q>)
167 inline T scalarProduct(
const T* M,
const Q* H) {
168 return levelScalarProduct<T,Q,1,D>(M,H);
173 template<
typename T,
size_t D> requires functions_type::isArithmeticType<T>
174 inline T scalarProduct(
const T* M,
const T* H) {
175 return levelScalarProduct<T,T,1,D>(M,H);
181 template<
typename T,
typename Q,
size_t D> requires (functions_type::isArithmeticType<T> && functions_type::isArithmeticType<Q>)
182 inline T scalarProduct(
const std::array<T,D>& M,
const std::array<Q,D>& H) {
183 return levelScalarProduct<T,Q,1,D>(M.data(),H.data());
188 template<
typename T,
size_t D> requires functions_type::isArithmeticType<T>
189 inline T scalarProduct(
const std::array<T,D>& M,
const std::array<T,D>& H) {
190 return levelScalarProduct<T,T,1,D>(M.data(),H.data());
199 template<
typename T,
size_t D> requires functions_type::isArithmeticType<T>
200 inline T norm2(
const std::array<T,D>& M) {
201 return levelScalarProduct<T,T,1,D>(M.data(),M.data());
206 template<
typename T,
size_t D> requires functions_type::isArithmeticType<T>
207 inline tReal norm(
const std::array<T,D>& M) {
208 return sqrt(norm2(M));
214 template<
typename T,
size_t D> requires functions_type::isArithmeticType<T>
215 inline tReal norm2(
const T* M) {
216 return levelScalarProduct<T,T,1,D>(M,M);
221 template<
typename T,
size_t D> requires functions_type::isArithmeticType<T>
222 inline tReal norm(
const T* M) {
223 return sqrt(norm2(M));
231 template<
typename T,
size_t L,
size_t D> requires ( (L==D) && functions_type::isArithmeticType<T>)
232 inline T levelL2Distance2(
const T * M,
const T *H) {
233 return ((*M)-(*H))*((*M)-(*H));
239 template<
typename T,
size_t L,
size_t D> requires ( (L<D) && functions_type::isArithmeticType<T>)
240 inline T levelL2Distance2(
const T * M,
const T *H) {
241 return ((*M)-(*H))*((*M)-(*H))+levelL2Distance2<T,L+1,D>(M+1,H+1);
248 template<
typename T,
size_t D>
249 inline T L2Distance2(
const std::array<T,D>& M,
const std::array<T,D>& H) {
250 return levelL2Distance2<T,1,D>(M.data(),H.data());
257 template<
typename T,
size_t D>
258 inline T L2Distance2(
const T* M,
const T* H) {
259 return levelL2Distance2<T,1,D>(M,H);
267 template<
typename T,
size_t D>
268 inline T L2Distance(
const std::array<T,D>& M,
const std::array<T,D>& H) {
269 return sqrt(L2Distance2(M,H));
276 template<
typename T,
size_t D>
277 inline T L2Distance(
const T* M,
const T* H) {
278 return sqrt(L2Distance2<T,D>(M,H));
286 template<
typename S,
typename T,
size_t L,
size_t D> requires ((L==D) && functions_type::isArithmeticType<T> && functions_type::isArithmeticType<S>)
287 inline S levelProduct(
const T* a) {
294 template<
typename S,
typename T,
size_t L,
size_t D> requires ((L<D) && functions_type::isArithmeticType<T> && functions_type::isArithmeticType<S>)
295 inline S levelProduct(
const T* a) {
296 return ((S)(*a))*levelProduct<S,T,L+1,D>(a+1);
301 template<
typename S,
typename T,
size_t D> requires (functions_type::isArithmeticType<T> && functions_type::isArithmeticType<S>)
302 inline S product(
const std::array<T,D>& a) {
303 return levelProduct<S,T,1,D>(a.data());
308 template<
typename T,
size_t D> requires (functions_type::isArithmeticType<T>)
309 inline T product(
const std::array<T,D>& a) {
310 return levelProduct<T,T,1,D>(a.data());
315 template<
typename T> requires (functions_type::isArithmeticType<T>)
316 inline T product(
const std::vector<T>& as) {
318 for(
const auto& a:as) {
328 template<
typename S,
typename T,
size_t D> requires (functions_type::isArithmeticType<T> && functions_type::isArithmeticType<S>)
329 inline S product(
const T*a) {
330 return levelProduct<S,T,1,D>(a);
340 template<
typename T,
size_t L,
size_t D> requires ((L==D) && functions_type::isArithmeticType<T>)
341 inline const T& levelMin(
const T* a) {
348 template<
typename T,
size_t L,
size_t D> requires ((L<D) && functions_type::isArithmeticType<T>)
349 inline const T& levelMin(
const T* a) {
350 return functions_numeric::min(levelMin<T,L+1,D>(a+1),*a);
357 template<
typename T,
size_t D> requires functions_type::isArithmeticType<T>
358 inline const T& min(
const std::array<T,D>& a) {
359 return levelMin<T,1,D>(a.data());
365 template<
typename T,
size_t D> requires functions_type::isArithmeticType<T>
366 inline const T& min(
const T* a) {
367 return levelMin<T,1,D>(a);
376 template<
typename T,
size_t L,
size_t D> requires ((L==D) && functions_type::isArithmeticType<T>)
377 inline const T& levelMax(
const T* a) {
385 template<
typename T,
size_t L,
size_t D> requires ((L<D) && functions_type::isArithmeticType<T>)
386 inline const T& levelMax(
const T* a) {
387 return functions_numeric::max(levelMax<T,L+1,D>(a+1),*a);
394 template<
typename T,
size_t D> requires functions_type::isArithmeticType<T>
395 inline const T& max(
const std::array<T,D>& a) {
396 return levelMax<T,1,D>(a.data());
402 template<
typename T,
size_t D> requires functions_type::isArithmeticType<T>
403 inline const T& max(
const T* a) {
404 return levelMax<T,1,D>(a);
415 template<
typename T,
size_t L,
size_t D> requires ((L==D) && functions_type::isArithmeticType<T>)
416 inline void levelMaxArray(
const T* al,
const T* bl,T* rl) {
417 (*rl)=std::max(*al,*bl);
424 template<
typename T,
size_t L,
size_t D> requires ((L<D) && functions_type::isArithmeticType<T>)
425 inline void levelMaxArray(
const T* al,
const T* bl,T* rl) {
426 (*rl)=std::max(*al,*bl);
427 levelMaxArray<T,L+1,D>(al+1,bl+1,rl+1);
434 template<
typename T,
size_t D>
435 inline std::array<T,D>& max(std::array<T,D>& a,
const std::array<T,D>& b) {
436 levelMaxArray<T,1,D>(a.data(),b.data(),a.data());
445 inline std::valarray<T>& max(std::valarray<T>& a,
const std::valarray<T>& b) {
446 const auto *ib=&b[0];
448 ak=(ak>(*ib))?ak:(*ib);
461 template<
typename T,
size_t L,
size_t D> requires ((L==D) && functions_type::isArithmeticType<T>)
462 inline void levelMinArray(
const T* al,
const T* bl,T* rl) {
463 (*rl)=std::min(*al,*bl);
471 template<
typename T,
size_t L,
size_t D> requires ((L<D) && functions_type::isArithmeticType<T>)
472 inline void levelMinArray(
const T* al,
const T* bl,T* rl) {
473 (*rl)=std::min(*al,*bl);
474 levelMinArray<T,L+1,D>(al+1,bl+1,rl+1);
482 template<
typename T,
size_t D>
483 inline std::array<T,D>& min(std::array<T,D>& a,
const std::array<T,D>& b) {
484 levelMinArray<T,1,D>(a.data(),b.data(),a.data());
493 inline std::valarray<T>& min(std::valarray<T>& a,
const std::valarray<T>& b) {
494 const auto *ib=&b[0];
496 ak=(ak<(*ib))?ak:(*ib);
508 template<
typename T,
typename Q,
size_t L,
size_t D> requires (L==D)
509 inline void levelCopy(T* al,
const Q* bl) {
517 template<
typename T,
typename Q,
size_t L,
size_t D> requires (L<D)
518 inline void levelCopy(T* al,
const Q* bl) {
520 levelCopy<T,Q,L+1,D>(al+1,bl+1);
528 template<
typename T,
typename Q,
size_t D>
529 inline std::array<T,D>& copy(std::array<T,D>& a,
const std::array<Q,D>& b) {
530 levelCopy<T,Q,1,D>(a.data(),b.data());
541 template<
typename T,
typename Q,
size_t L,
size_t D> requires ((L==D) && functions_type::isArithmeticType<T> && functions_type::isArithmeticType<Q>)
542 inline void levelAdd(T* al,
const Q* bl) {
551 template<
typename T,
typename Q,
size_t L,
size_t D> requires ((L<D) && functions_type::isArithmeticType<T> && functions_type::isArithmeticType<Q>)
552 inline void levelAdd(T* al,
const Q* bl) {
554 levelAdd<T,Q,L+1,D>(al+1,bl+1);
562 template<
typename T,
typename Q,
size_t D> requires ( functions_type::isArithmeticType<T> && functions_type::isArithmeticType<Q>)
563 inline std::array<T,D>& add(std::array<T,D>& a,
const std::array<Q,D>& b) {
564 levelAdd<T,Q,1,D>(a.data(),b.data());
575 template<
typename T,
typename Q,
size_t L,
size_t D> requires ((L==D) && functions_type::isArithmeticType<T> && functions_type::isArithmeticType<Q>)
576 inline void levelSub(T* al,
const Q* bl) {
585 template<
typename T,
typename Q,
size_t L,
size_t D> requires ((L<D) && functions_type::isArithmeticType<T> && functions_type::isArithmeticType<Q>)
586 inline void levelSub(T* al,
const Q* bl) {
588 levelSub<T,Q,L+1,D>(al+1,bl+1);
595 template<
typename T,
typename Q,
size_t D> requires ( functions_type::isArithmeticType<Q> && functions_type::isArithmeticType<T>)
596 inline std::array<T,D>& sub(std::array<T,D>& a,
const std::array<Q,D>& b) {
597 levelSub<T,Q,1,D>(a.data(),b.data());
605 template<
typename T,
typename Q> requires ( functions_type::isArithmeticType<Q> && functions_type::isArithmeticType<T>)
606 inline std::valarray<T>& sub(std::valarray<T>& a,
const std::valarray<Q>& b) {
623 template<
typename T,
typename Q,
typename R,
size_t L,
size_t D> requires ((L==D) && functions_type::isArithmeticType<T>)
624 inline void levelAXPY(
const R& a,
const Q* xl,T* yl) {
625 (*yl)+=(T) (((Q)a)*(*xl));
634 template<
typename T,
typename Q,
typename R,
size_t L,
size_t D> requires ((L<D) && functions_type::isArithmeticType<T>)
635 inline void levelAXPY(
const R& a,
const Q* xl,T* yl) {
636 (*yl)+=(T) (((Q)a)*(*xl));
637 levelAXPY<T,Q,R,L+1,D>(a,xl+1,yl+1);
646 template<
typename T,
typename Q,
typename R,
size_t D>
647 inline std::array<T,D>& axpy(
const R& alpha,
const std::array<Q,D>& x,std::array<T,D>& y) {
648 levelAXPY<T,Q,R,1,D>(alpha,x.data(),y.data());
659 template<
typename T,
typename Q,
typename R,
size_t L,
size_t D> requires (L==D)
660 inline void levelAXPY(
const R* al,
const Q* xl,T* yl) {
661 (*yl)+=(T) (((R)(*al))*(*xl));
670 template<
typename T,
typename Q,
typename R,
size_t L,
size_t D> requires (L<D)
671 inline void levelAXPY(
const R* al,
const Q* xl,T* yl) {
672 (*yl)+=(T) (((R)(*al))*(*xl));
673 levelAXPY<T,Q,R,L+1,D>(al+1,xl+1,yl+1);
682 template<
typename T,
typename Q,
typename R,
size_t D> requires ( functions_type::isArithmeticType<Q> && functions_type::isArithmeticType<T>)
683 inline std::array<T,D>& axpy(
const std::array<R,D>& alpha,
const std::array<Q,D>& x,std::array<T,D>& y) {
684 levelAXPY<T,Q,R,1,D>(alpha.data(),x.data(),y.data());
695 template<
typename Q,
typename T,
size_t D>
696 inline tString toString(
const std::array<T,D>& a) {
697 std::stringstream ss;
699 for(
const auto & ai : a) {
700 ss<<std::setprecision(12)<<((Q)ai)<<
",";
702 if (a.size()>0)ss.seekp(-1, std::ios_base::end);
710 template<
typename T,
size_t D>
711 inline tString toString(
const std::array<T,D>& a) {
712 std::stringstream ss;
714 for(
const auto & ai : a) {
715 ss<<std::setprecision(12)<<ai<<
",";
717 if (a.size()>0)ss.seekp(-1, std::ios_base::end);
724 template<
typename Q,
typename T>
725 inline tString toString(
const size_t& asize,
const T* a,
const tIndex& nPrintedValues) {
726 std::stringstream ss;
728 const T* ea=a;ea+=asize;
732 if (nPrintedValues>=asize) {
734 ss<<std::setprecision(12)<<((Q)(*ia))<<
",";
740 for (tInteger k=0;k<=nPrintedValues;k++) {
741 index=((asize-1)*k)/nPrintedValues;
742 ss<<index<<
":"<<std::setprecision(12)<<((Q)a[index])<<
",";
745 if (asize>0)ss.seekp(-1, std::ios_base::end);
751 template<
typename Q,
typename T>
752 inline tString toString(
const size_t& asize,
const T* a) {
753 return toString<Q,T>(asize,a,asize);
758 inline tString toString(
const size_t& asize,
const T* a) {
759 return toString<T,T>(asize,a,asize);
762 template<
typename S,
typename T>
763 inline tString toString(
const std::valarray<T>& a,
const tIndex& nPrintedValues) {
764 return toString<S,T>(a.size(),&a[0],nPrintedValues);
767 inline tString toString(
const std::valarray<T>& a,
const tIndex& nPrintedValues) {
768 return toString<T,T>(a.size(),&a[0],nPrintedValues);
774 inline tString toString(
const std::valarray<T>& a) {
775 return toString<T,T>(a.size(),&a[0],a.size());
780 inline tString toString(
const std::vector<T>& a) {
781 std::stringstream ss;
783 for(
const auto & ai : a) {
786 if (a.size()>0)ss.seekp(-1, std::ios_base::end);
792 template<
typename Kd,
typename Vd,
typename K,
typename V>
793 inline tString toString(
const std::map<K,V>& a) {
794 std::stringstream ss;
796 for(
const auto & ai : a) {
797 ss<<((Kd)ai.first)<<
"->"<<((Vd)ai.second)<<
",";
799 if (a.size()>0) ss.seekp(-1, std::ios_base::end);
804 template<
typename K,
typename V>
805 inline tString toString(
const std::map<K,V>& a) {
806 std::stringstream ss;
808 for(
const auto & ai : a) {
809 ss<<ai.first<<
"->"<<ai.second<<
",";
811 if (a.size()>0) ss.seekp(-1, std::ios_base::end);
817 template<
typename T> requires (functions_type::isArithmeticType<T>)
818 inline tBoolean parse(
const tString& s,std::vector<T>& vs) {
822 std::array<tChar,3> beginArrayDelim={
'{',
'[',
'('};
823 std::array<tChar,3> endArrayDelim={
'}',
']',
')'};
826 functions_string::trim(sexpr);
830 for(
const auto& b:beginArrayDelim) {
831 if (sexpr[0]==b)
break;
834 if (c>=beginArrayDelim.size())
return false;
836 tIndex i=sexpr.find_last_of(endArrayDelim[c]);
837 if (i>=sexpr.length())
return false;
842 sexpr=sexpr.substr(1,i-1);
843 while (sexpr.length()>0) {
844 i=sexpr.find_first_of(
',');
845 if (i<sexpr.length()) {
847 token=sexpr.substr(0,i);
849 sexpr=sexpr.substr(i+1);
857 functions_numeric::parse(token,v);