KrisLibrary  1.0.0
fastarray.h
1 #ifndef MATH_FAST_ARRAY_H
2 #define MATH_FAST_ARRAY_H
3 
4 #include <utils.h>
5 
6 namespace Math {
7 
8 template <class T>
9 inline T* array_create(int n)
10 {
11  if(n != 0)
12  return (T*)malloc(sizeof(T)*n);
13  return NULL;
14 }
15 
16 template <class T>
17 inline void array_delete(T* v)
18 {
19  if(v)
20  free(v);
21 }
22 
23 template <class T>
24 inline void array_equal(T* a, const T* b, int n)
25 {
26  for(int i=0;i<n;i++,a++,b++)
27  *a = *b;
28 }
29 
30 template <class T>
31 inline T* array_copy(T* a, int n)
32 {
33  T* x = array_create<T>(n);
34  array_equal(x,a,n);
35  return x;
36 }
37 
38 template <class T>
39 inline void array_fill(T* a, const T& c, int n)
40 {
41  for(int i=0;i<n;i++,a++)
42  *a = c;
43 }
44 
45 template <class T>
46 inline void array_zero(T* a, int n)
47 {
48  array_fill(a,(T)0,n);
49 }
50 
51 template <class T>
52 inline void array_negate(T* x, const T* a, int n)
53 {
54  for(int i=0;i<n;i++,x++,a++)
55  *x = -*a;
56 }
57 
58 template<class T>
59 inline void array_add(T* x, const T* a, const T* b, int n)
60 {
61  for(int i=0;i<n;i++,x++,a++,b++)
62  *x = *a+*b;
63 }
64 
65 template<class T>
66 inline void array_sub(T* x, const T* a, const T* b, int n)
67 {
68  for(int i=0;i<n;i++,x++,a++,b++)
69  *x = *a-*b;
70 }
71 
72 template<class T>
73 inline void array_mul(T* x, const T* a, T s, int n)
74 {
75  for(int i=0;i<n;i++,x++,a++)
76  *x = *a*s;
77 }
78 
79 template<class T>
80 inline void array_div(T* x, const T* a, T s, int n)
81 {
82  for(int i=0;i<n;i++,x++,a++)
83  *x = *a/s;
84 }
85 
86 template<class T>
87 inline void array_acc(T* x, const T* a, int n)
88 {
89  for(int i=0;i<n;i++,x++,a++)
90  *x += *a;
91 }
92 
93 template<class T>
94 inline void array_dec(T* x, const T* a, int n)
95 {
96  for(int i=0;i<n;i++,x++,a++)
97  *x -= *a;
98 }
99 
100 template<class T>
101 inline void array_madd(T* x, const T* a, const T& s, int n)
102 {
103  for(int i=0;i<n;i++,x++,a++)
104  *x += *a*s;
105 }
106 
107 template<class T>
108 inline void array_axpby(T* z, T a, const T* x, T b, const T* y, int n)
109 {
110  for(int i=0;i<n;i++,z++,x++,y++)
111  *z = a*(*x) + b*(*y);
112 }
113 
114 template<class T>
115 inline void array_mul(T* a, const T& s, int n)
116 {
117  for(int i=0;i<n;i++,a++)
118  *a *= s;
119 }
120 
121 template<class T>
122 inline void array_div(T* a, const T& s, int n)
123 {
124  for(int i=0;i<n;i++,a++)
125  *a /= s;
126 }
127 
128 template<class T>
129 inline T array_sum_product(const T* a, const T* b, int n)
130 {
131  T sum = 0;
132  for(int i=0;i<n;i++,a++,b++)
133  sum += (*a)*(*b);
134  return sum;
135 }
136 
137 template<class T>
138 inline T array_dot(const T* a, const T* b, int n)
139 {
140  T sum = 0;
141  for(int i=0;i<n;i++,a++,b++)
142  sum += dot(*a,*b);
143  return sum;
144 }
145 
146 template<class T>
147 inline T array_norm_squared(const T* a, int n)
148 {
149  T sum = 0;
150  for(int i=0;i<n;i++,a++)
151  sum += dot(*a,*a);
152  return sum;
153 }
154 
155 //generalized arrays:
156 //x(i) = x0[i*stride]
157 template<class T>
158 inline void gen_array_fill(T* x, int xstride, T c, int n)
159 {
160  for(int i=0;i<n;i++,x+=xstride)
161  *x = c;
162 }
163 
164 template<class T>
165 inline void gen_array_mul(T* x, int xstride, T c, int n)
166 {
167  for(int i=0;i<n;i++,x+=xstride)
168  *x *= c;
169 }
170 
171 template<class T>
172 inline void gen_array_div(T* x, int xstride, T c, int n)
173 {
174  for(int i=0;i<n;i++,x+=xstride)
175  *x /= c;
176 }
177 
178 template<class T>
179 inline void gen_array_negate(T* x, int xstride, const T* a, int astride, int n)
180 {
181  for(int i=0;i<n;i++,x+=xstride,a+=astride)
182  *x = -*a;
183 }
184 
185 template<class T>
186 inline void gen_array_equal(T* x, int xstride, const T* a, int astride, int n)
187 {
188  for(int i=0;i<n;i++,x+=xstride,a+=astride)
189  *x = *a;
190 }
191 
192 template<class T>
193 inline void gen_array_swap(T* x, int xstride, T* y, int ystride, int n)
194 {
195  T tmp;
196  for(int i=0;i<n;i++,x+=xstride,y+=ystride) {
197  tmp = *x;
198  *x = *y;
199  *y = tmp;
200  }
201 }
202 
203 template<class T>
204 inline void gen_array_mul(T* x, int xstride, const T* a, int astride, T c, int n)
205 {
206  for(int i=0;i<n;i++,x+=xstride,a+=astride)
207  *x = *a*c;
208 }
209 
210 template<class T>
211 inline void gen_array_div(T* x, int xstride, const T* a, int astride, T c, int n)
212 {
213  for(int i=0;i<n;i++,x+=xstride,a+=astride)
214  *x = *a/c;
215 }
216 
217 template<class T>
218 inline void gen_array_add(T* x, int xstride, const T* a, int astride, const T* b, int bstride, int n)
219 {
220  for(int i=0;i<n;i++,x+=xstride,a+=astride,b+=bstride)
221  *x = *a+*b;
222 }
223 
224 template<class T>
225 inline void gen_array_sub(T* x, int xstride, const T* a, int astride, const T* b, int bstride, int n)
226 {
227  for(int i=0;i<n;i++,x+=xstride,a+=astride,b+=bstride)
228  *x = *a-*b;
229 }
230 
231 template<class T>
232 inline void gen_array_acc(T* x, int xstride, const T* a, int astride, int n)
233 {
234  for(int i=0;i<n;i++,x+=xstride,a+=astride)
235  *x += *a;
236 }
237 
238 template<class T>
239 inline void gen_array_dec(T* x, int xstride, const T* a, int astride, int n)
240 {
241  for(int i=0;i<n;i++,x+=xstride,a+=astride)
242  *x -= *a;
243 }
244 
245 template<class T>
246 inline void gen_array_madd(T* x, int xstride, const T* a, int astride, T s, int n)
247 {
248  for(int i=0;i<n;i++,x+=xstride,a+=astride)
249  *x += *a*s;
250 }
251 
252 template<class T>
253 inline void gen_array_axpby(T* z, int zstride, T a, const T* x, int xstride, T b, const T* y, int ystride, int n)
254 {
255  for(int i=0;i<n;i++,z+=zstride,x+=xstride,y+=ystride)
256  *z = a*(*x)+b*(*y);
257 }
258 
259 template<class T>
260 inline T gen_array_sum_product(const T* a, int astride, const T* b, int bstride, int n)
261 {
262  T sum=0;
263  for(int i=0;i<n;i++,a+=astride,b+=bstride)
264  sum += (*a)*(*b);
265  return sum;
266 }
267 
268 template<class T>
269 inline T gen_array_dot(const T* a, int astride, const T* b, int bstride, int n)
270 {
271  T sum=0;
272  for(int i=0;i<n;i++,a+=astride,b+=bstride)
273  sum += dot(*a,*b);
274  return sum;
275 }
276 
277 template<class T>
278 inline T gen_array_norm_squared(const T* a, int astride, int n)
279 {
280  T sum = 0;
281  for(int i=0;i<n;i++,a+=astride)
282  sum += (*a)*(*a);
283  return sum;
284 }
285 
286 
287 
288 // 2d arrays:
289 // Assumed to have dimensions m x n
290 // The data layout is [m pointers][big block of m*n data]
291 template <class T>
292 inline T** array2d_create(int m, int n)
293 {
294  T** array;
295  int i;
296  if(n != 0 && m != 0)
297  {
298  int ofs = m*sizeof(T*);
299  array = (T**)malloc(m*sizeof(T*) + m*n*sizeof(T));
300  unsigned char* bytes = (unsigned char*) array;
301  for(i=0; i<m; i++)
302  {
303  //array+m = offset to block
304  //i*n = offset in block
305  array[i] = (T*)((bytes + ofs) + i*n*(sizeof(T)));
306  }
307  return array;
308  }
309  return NULL;
310 }
311 
312 template <class T>
313 inline void array2d_delete(T** v)
314 {
315  if(v)
316  free(v);
317 }
318 
319 
320 //X = 0
321 template <class T>
322 inline void array2d_fill(T** X, const T& c, int m, int n)
323 {
324  array_fill(X[0], c, m*n);
325 }
326 
327 //X = I
328 template <class T>
329 inline void array2d_identity(T** X, int m, int n)
330 {
331  array_zero(X[0], m*n);
332  gen_array_fill(X[0],n+1,One,::Min(m,n));
333 }
334 
335 
336 //X = A
337 template <class T>
338 inline void array2d_equal(T** X, T** const A, int m, int n)
339 {
340  array_equal(X[0],A[0],m*n);
341 }
342 
343 //X = A
344 template <class T>
345 inline T** array2d_copy(T** A, int m, int n)
346 {
347  T** X = array2d_create<T>(m,n);
348  array2d_equal(X,A,m,n);
349  return X;
350 }
351 
352 //X = A^t. X is mxn, A is nxm
353 template <class T>
354 inline void array2d_transpose(T** X, T** const A, int m, int n)
355 {
356  int i;
357  for(i=0; i<m; i++)
358  gen_array_equal(X[i],1,&A[0][i],m,n);
359  /*
360  for(j=0; j<n; j++)
361  X[i][j] = A[j][i];
362  */
363 }
364 
365 //X = A+B
366 template <class T>
367 inline void array2d_add(T** x, T** const a, T** const b, int m, int n)
368 {
369  array_add(x[0],a[0],b[0],m*n);
370 }
371 
372 //X = A-B
373 template <class T>
374 inline void array2d_sub(T** x, T** const a, T** const b, int m, int n)
375 {
376  array_sub(x[0],a[0],b[0],m*n);
377 }
378 
379 //X = A*B. X is mxp, A is mxn, B is nxp
380 template <class T>
381 inline void array2d_mul(T** x, T** const a, T** const b, int m, int n, int p)
382 {
383  int i,j;//,k;
384  for(i=0; i<m; i++)
385  {
386  for(j=0; j<p; j++)
387  {
388  x[i][j] = gen_array_sum_product(a[i],1,&b[0][j],p,n);
389  /*
390  x[i][j] = 0;
391  for(k=0; k<n; k++)
392  x[i][j] += a[i][k]*b[k][j];
393  */
394  }
395  }
396 }
397 
398 //X = A^t*B. X is mxp, A is nxm, B is nxp
399 template <class T>
400 inline void array2d_multiply_transposeA(T** x, T** const a, T** const b, int m, int n, int p)
401 {
402  int i,j;//,k;
403  for(i=0; i<m; i++)
404  {
405  for(j=0; j<p; j++)
406  {
407  x[i][j] = gen_array_sum_product(&a[0][i],m,&b[0][j],p,n);
408  /*
409  x[i][j] = 0;
410  for(k=0; k<n; k++)
411  x[i][j] += a[k][i]*b[k][j];
412  */
413  }
414  }
415 }
416 
417 //X = A*B^t. X is mxp, A is mxn, B is pxn
418 template <class T>
419 inline void array2d_multiply_transposeB(T** x, T** const a, T** const b, int m, int n, int p)
420 {
421  int i,j;
422  for(i=0; i<m; i++)
423  {
424  for(j=0; j<p; j++)
425  {
426  /*
427  x[i][j] = 0;
428  for(int k=0; k<n; k++)
429  x[i][j] += a[i][k]*b[j][k];
430  */
431  x[i][j] = array_sum_product(a[i],b[j],n);
432  }
433  }
434 }
435 
436 //x = A*b
437 template <class T>
438 inline void array2d_vector_multiply(T* x, T** const a, const T* b, int m, int n)
439 {
440  int i;
441  for(i=0; i<m; i++)
442  x[i] = array_sum_product(a[i],b,n);
443 }
444 
445 //x = A^t*b
446 template <class T>
447 inline void array2d_vector_multiply_transpose(T* x, T** const a, const T* b, int m, int n)
448 {
449  /*
450  int i,j;
451  for(i=0; i<n; i++)
452  x[i] = 0;
453  for(i=0; i<m; i++)
454  for(j=0;j<n;j++)
455  x[j] += a[i][j]*b[i];
456  */
457  for(int i=0;i<n;i++)
458  x[i] = gen_array_sum_product(&a[0][i],n,b,1,m);
459 }
460 
461 //x += A*b
462 template <class T>
463 inline void array2d_vector_madd(T* x, T** const a, const T* b, int m, int n)
464 {
465  int i;
466  for(i=0; i<m; i++)
467  x[i] += array_sum_product(a[i],b,n);
468 }
469 
470 //x += A^t*b
471 template <class T>
472 inline void array2d_vector_madd_transpose(T* x, T** const a, const T* b, int m, int n)
473 {
474  /*
475  int i,j;
476  for(i=0; i<m; i++)
477  for(j=0;j<n;j++)
478  x[j] += a[i][j]*b[i];
479  */
480  for(int i=0;i<n;i++)
481  x[i] += gen_array_sum_product(&a[0][i],n,b,1,m);
482 }
483 
484 //returns the dot product <(row i of a),v>
485 template <class T>
486 inline T array2d_row_dot(T** const a, int i, const T* v, int m,int n)
487 {
488  return array_dot(a[i], v, n);
489 }
490 
491 //returns the dot product <(col i of a),v>
492 template <class T>
493 inline T array2d_col_dot(T** const a, int i, const T* v, int m,int n)
494 {
495  gen_array_dot(&a[0][i],n,v,1,m);
496 }
497 
498 
499 
500 template <class T>
501 inline T* gen_array2d_entry(T* X,int xis,int xjs,int i,int j)
502 {
503  return X+xis*i+xjs*j;
504 }
505 
506 //returns ptr to row i (stride is xjs)
507 template <class T>
508 inline T* gen_array2d_row(T* X,int xis,int xjs,int i)
509 {
510  return X+xis*i;
511 }
512 
513 //returns ptr to col j (stride is xis)
514 template <class T>
515 inline T* gen_array2d_col(T* X,int xis,int xjs,int j)
516 {
517  return X+xjs*j;
518 }
519 
520 //X = c
521 template <class T>
522 inline void gen_array2d_fill(T* X,int xis,int xjs,const T& c,int m, int n)
523 {
524  for(int i=0;i<m;i++,X+=xis)
525  gen_array_fill(X,xjs,c,n);
526 }
527 
528 //X = I
529 template <class T>
530 inline void gen_array2d_identity(T* X,int xis,int xjs, int m, int n)
531 {
532  gen_array2d_fill(X,xis,xjs,T(0),m,n);
533  gen_array_fill(X,xis+xjs,T(1),m);
534 }
535 
536 
537 //X = A
538 template <class T>
539 inline void gen_array2d_equal(T* X,int xis,int xjs,
540  const T* A,int ais,int ajs, int m, int n)
541 {
542  for(int i=0;i<m;i++,X+=xis,A+=ais)
543  gen_array_equal(X,xjs,A,ajs,n);
544 }
545 
546 //X = A^t. X is mxn, A is nxm
547 template <class T>
548 inline void gen_array2d_transpose(T* X,int xis,int xjs,
549  const T* A,int ais,int ajs, int m, int n)
550 {
551  gen_array2d_equal(X,xis,xjs,A,ajs,ais,m,n);
552 }
553 
554 //X = A+B
555 template <class T>
556 inline void gen_array2d_add(T* X,int xis,int xjs,
557  const T* A,int ais,int ajs,
558  const T* B,int bis,int bjs, int m, int n)
559 {
560  for(int i=0;i<m;i++,X+=xis,A+=ais,B+=bis) {
561  gen_array_add(X,xjs,A,ajs,B,bjs,n);
562  }
563 }
564 
565 //X = A-B
566 template <class T>
567 inline void gen_array2d_sub(T* X,int xis,int xjs,
568  const T* A,int ais,int ajs,
569  const T* B,int bis,int bjs, int m, int n)
570 {
571  for(int i=0;i<m;i++,X+=xis,A+=ais,B+=bis) {
572  gen_array_sub(X,xjs,A,ajs,B,bjs,n);
573  }
574 }
575 
576 //X = cA
577 template <class T>
578 inline void gen_array2d_mul(T* X,int xis,int xjs,
579  const T* A,int ais,int ajs,
580  const T& c, int m, int n)
581 {
582  for(int i=0;i<m;i++,X+=xis,A+=ais)
583  gen_array_mul(X,xjs,A,ajs,c,n);
584 }
585 
586 //X *= c
587 template <class T>
588 inline void gen_array2d_mul(T* X,int xis,int xjs,
589  const T& c, int m, int n)
590 {
591  for(int i=0;i<m;i++,X+=xis)
592  gen_array_mul(X,xjs,c,n);
593 }
594 
595 //X /= c
596 template <class T>
597 inline void gen_array2d_div(T* X,int xis,int xjs,
598  const T& c, int m, int n)
599 {
600  for(int i=0;i<m;i++,X+=xis)
601  gen_array_div(X,xjs,c,n);
602 }
603 
604 
605 //X += A
606 template <class T>
607 inline void gen_array2d_acc(T* X,int xis,int xjs,
608  const T* A,int ais,int ajs,
609  int m, int n)
610 {
611  for(int i=0;i<m;i++,X+=xis,A+=ais) {
612  gen_array_acc(X,xjs,A,ajs,n);
613  }
614 }
615 
616 //X += A
617 template <class T>
618 inline void gen_array2d_dec(T* X,int xis,int xjs,
619  const T* A,int ais,int ajs,
620  int m, int n)
621 {
622  for(int i=0;i<m;i++,X+=xis,A+=ais) {
623  gen_array_dec(X,xjs,A,ajs,n);
624  }
625 }
626 
627 //X += cA
628 template <class T>
629 inline void gen_array2d_madd(T* X,int xis,int xjs,
630  const T* A,int ais,int ajs,
631  const T& c,
632  int m, int n)
633 {
634  for(int i=0;i<m;i++,X+=xis,A+=ais) {
635  gen_array_madd(X,xjs,A,ajs,c,n);
636  }
637 }
638 
639 //X = -A
640 template <class T>
641 inline void gen_array2d_negate(T* X,int xis,int xjs,
642  const T* A,int ais,int ajs,
643  int m, int n)
644 {
645  for(int i=0;i<m;i++,X+=xis,A+=ais) {
646  gen_array_negate(X,xjs,A,ajs,n);
647  }
648 }
649 
650 //X = A*B. X is mxp, A is mxn, B is nxp
651 template <class T>
652 inline void gen_array2d_multiply(T* X,int xis,int xjs,
653  const T* A,int ais,int ajs,
654  const T* B,int bis,int bjs,
655  int m,int n,int p)
656 {
657  int i,j,k;
658  T sum;
659  for(i=0;i<m;i++, X+=xis,A+=ais)
660  {
661  T* Xi=X;
662  const T* Bj=B;
663  for(j=0;j<p;j++, Xi+=xjs,Bj+=bjs)
664  {
665  const T* Aij=A;
666  const T* Bij=Bj;
667  sum=0;
668  for(k=0;k<n;k++, Aij+=ajs,Bij+=bis)
669  sum += (*Aij)*(*Bij);
670  //sum += A[i*ais+k*ajs]*B[k*bis+j*bjs];
671  *Xi = sum;
672  //X[i*xis+j*xjs] = sum;
673  }
674  }
675 }
676 
677 //X = A^t*B. X is mxp, A is nxm, B is nxp
678 template <class T>
679 inline void gen_array2d_multiply_transposeA(T* X,int xis,int xjs,
680  const T* A,int ais,int ajs,
681  const T* B,int bis,int bjs,
682  int m,int n,int p)
683 {
684  gen_array2d_multiply(X,xis,xjs,
685  A,ajs,ais,
686  B,bis,bjs,
687  m,n,p);
688 }
689 
690 //X = A*B^t. X is mxp, A is mxn, B is pxn
691 template <class T>
692 inline void gen_array2d_multiply_transposeB(T* X,int xis,int xjs,
693  const T* A,int ais,int ajs,
694  const T* B,int bis,int bjs,
695  int m,int n,int p)
696 {
697  gen_array2d_multiply(X,xis,xjs,
698  A,ais,ajs,
699  B,bjs,bis,
700  m,n,p);
701 }
702 
703 //x = A*b
704 template <class T>
705 inline void gen_array2d_vector_multiply(T* x,int xs,
706  const T* A,int ais,int ajs,
707  const T* b,int bs,
708  int m, int n)
709 {
710  for(int i=0;i<m;i++, x+=xs,A+=ais)
711  *x = gen_array_sum_product(A,ajs, b,bs, n);
712 }
713 
714 //x = A^t*b
715 template <class T>
716 inline void gen_array2d_vector_multiply_transpose(T* x,int xs,
717  const T* A,int ais,int ajs,
718  const T* b,int bs,
719  int m, int n)
720 {
721  gen_array2d_vector_multiply(x,xs,A,ajs,ais,b,bs,n,m);
722 }
723 
724 //x += A*b
725 template <class T>
726 inline void gen_array2d_vector_madd(T* x,int xs,
727  const T* A,int ais,int ajs,
728  const T* b,int bs,
729  int m, int n)
730 {
731  for(int i=0;i<m;i++, x+=xs,A+=ais)
732  *x += gen_array_sum_product(A,ajs, b,bs, n);
733 }
734 
735 //x += A^t*b
736 template <class T>
737 inline void gen_array2d_vector_madd_transpose(T* x,int xs,
738  const T* A,int ais,int ajs,
739  const T* b,int bs,
740  int m, int n)
741 {
742  gen_array2d_vector_madd(x,xs,A,ajs,ais,b,bs,n,m);
743 }
744 
745 
746 } //namespace Math
747 
748 #endif
Utilities commonly used throughout a program.
Contains all definitions in the Math package.
Definition: WorkspaceBound.h:12