Xmipp  v3.23.11-Nereus
multidim_array.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Carlos Oscar S. Sorzano (coss@cnb.csic.es)
4  *
5  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20  * 02111-1307 USA
21  *
22  * All comments concerning this program package may be sent to the
23  * e-mail address 'xmipp@cnb.csic.es'
24  ***************************************************************************/
25 
26 #include <fstream>
27 #include <algorithm>
28 #include "bilib/kernel.h"
29 #include "matrix2d.h"
30 #include "multidim_array.h"
31 #include "multidim_array_base.h"
32 #include "numerical_recipes.h"
33 #include "xmipp_funcs.h"
34 #include "xmipp_filename.h"
35 #include "utils/half.hpp"
36 
37 template<typename T>
39 {
40 // there's wrong bracket somewhere, and I don't want to think about it now
41 // m.resizeNoCopy(YSIZE(*this),XSIZE(*this));
42 // memcpy(&MAT_ELEM(m,0,0),&A3D_ELEM(*this,k,0,0),YSIZE(*this),XSIZE(*this)*sizeof(double));
43  REPORT_ERROR(ERR_NOT_IMPLEMENTED,"Please contact developers");
44 }
45 
46 template<typename T>
48 {
49  resizeNoCopy(MAT_YSIZE(op1), MAT_XSIZE(op1));
50  memcpy(data,MATRIX2D_ARRAY(op1), MAT_SIZE(op1)*sizeof(T));
51 
52  return *this;
53 }
54 
55 template<typename T>
57 {
58  op1.resizeNoCopy(YSIZE(*this), XSIZE(*this));
59  memcpy(MATRIX2D_ARRAY(op1), MULTIDIM_ARRAY(*this), MULTIDIM_SIZE(*this)*sizeof(T));
60 }
61 
62 
63 
64 // Window in 2D -----------------------------------------------------------
65 template<typename T>
66 void window2D(const MultidimArray<T> &Ibig, MultidimArray<T> &Ismall,
67  size_t y0, size_t x0, size_t yF, size_t xF)
68 {
69  Ismall.resizeNoCopy(yF - y0 + 1, xF - x0 + 1);
70  STARTINGY(Ismall) = y0;
71  STARTINGX(Ismall) = x0;
72  /*
73  FOR_ALL_ELEMENTS_IN_ARRAY2D(Ismall)
74  A2D_ELEM(Ismall, i, j) = A2D_ELEM(Ibig, i, j);
75  */
76  size_t sizeToCopy=XSIZE(Ismall)*sizeof(T);
77  for (int y=y0; y<=yF; y++)
78  memcpy( &A2D_ELEM(Ismall,y,STARTINGX(Ismall)), &A2D_ELEM(Ibig,y,STARTINGX(Ismall)), sizeToCopy);
79 }
80 
81 template void window2D(const MultidimArray<double> &Ibig, MultidimArray<double> &Ismall, size_t y0, size_t x0, size_t yF, size_t xF);
82 template void window2D(const MultidimArray<float> &Ibig, MultidimArray<float> &Ismall, size_t y0, size_t x0, size_t yF, size_t xF);
83 
84 // Show a complex array ---------------------------------------------------
85 template<>
86 std::ostream& operator<<(std::ostream& ostrm,
87  const MultidimArray< std::complex<double> >& v)
88 {
89  if (v.xdim == 0)
90  ostrm << "NULL MultidimArray\n";
91  else
92  ostrm << std::endl;
93 
94  for (size_t l = 0; l < NSIZE(v); l++)
95  {
96  if (NSIZE(v)>1)
97  ostrm << "Image No. " << l << std::endl;
98  for (int k = STARTINGZ(v); k <= FINISHINGZ(v); k++)
99  {
100  if (ZSIZE(v)>1)
101  ostrm << "Slice No. " << k << std::endl;
102  for (int i = STARTINGY(v); i <= FINISHINGY(v); i++)
103  {
104  for (int j = STARTINGX(v); j <= FINISHINGX(v); j++)
105  ostrm << A3D_ELEM(v, k, i, j) << ' ';
106  ostrm << std::endl;
107  }
108  }
109  }
110 
111  return ostrm;
112 }
113 
114 template<>
115 void MultidimArray< std::complex< double > >::computeDoubleMinMax(double& minval, double& maxval) const
116 {
117  REPORT_ERROR(ERR_NOT_IMPLEMENTED,"MultidimArray::computeDoubleMinMax not implemented for complex.");
118 }
119 template<>
120 void MultidimArray< std::complex< double > >::computeDoubleMinMaxRange(double& minval, double& maxval, size_t pos, size_t size) const
121 {
122  REPORT_ERROR(ERR_NOT_IMPLEMENTED,"MultidimArray::computeDoubleMinMax not implemented for complex.");
123 }
124 template<>
125 void MultidimArray< std::complex< double > >::rangeAdjust(std::complex< double > minF, std::complex< double > maxF)
126 {
127  REPORT_ERROR(ERR_NOT_IMPLEMENTED,"MultidimArray::rangeAdjust not implemented for complex.");
128 }
129 
130 template<>
131 double MultidimArray< std::complex< double > >::computeAvg() const
132 {
133  REPORT_ERROR(ERR_NOT_IMPLEMENTED,"MultidimArray::computeAvg not implemented for complex.");
134 }
135 
136 template<>
137 void MultidimArray< std::complex< double > >::maxIndex(size_t &lmax, int& kmax, int& imax, int& jmax) const
138 {
139  REPORT_ERROR(ERR_NOT_IMPLEMENTED,"MultidimArray::maxIndex not implemented for complex.");
140 }
141 
142 // void MultidimArray<double>::selfNormalizeInterval(double minPerc, double maxPerc, int Npix)
143 // {
144 // std::vector<double> randValues; // Vector with random chosen values
145 
146 // for(int i=0, i<Npix, i++)
147 // {
148 // size_t indx = (size_t)rnd_unif(0, MULTIDIM_SIZE(*this));
149 // randValues.push_back(DIRECT_MULTIDIM_ELEM(*this,indx))
150 // }
151 // std::sort(randValues.begin(),randValues.end());
152 
153 // double m = randValues[(size_t)(minPerc*Npix)];
154 // double M = randValues[(size_t)(minPerc*Npix)];
155 
156 // FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY_ptr(*this,n,ptr)
157 // *ptr = 2/(M-m)*(*ptr-m)-1;
158 
159 // }
160 
161 template<>
162 bool operator==(const MultidimArray< std::complex< double > >& op1, const MultidimArray< std::complex< double > >& op2)
163 {
164  double accuracy = XMIPP_EQUAL_ACCURACY;
165  if (! op1.sameShape(op2) || op1.data==NULL || op2.data == NULL)
166  return false;
168  if ( fabs(DIRECT_MULTIDIM_ELEM(op1,n).real() -
169  DIRECT_MULTIDIM_ELEM(op2,n).real() > accuracy)
170  ||
171  fabs(DIRECT_MULTIDIM_ELEM(op1,n).imag() -
172  DIRECT_MULTIDIM_ELEM(op2,n).imag() > accuracy)
173  )
174  return false;
175  return true;
176 }
177 
178 template<>
179 void MultidimArray< std::complex< double > >::getReal(MultidimArray<double> & realImg) const
180 {
181  if (NZYXSIZE(*this) == 0)
182  {
183  realImg.clear();
184  return;
185  }
186 
187  realImg.resizeNoCopy(*this);
188  double * ptr1 = (double*) MULTIDIM_ARRAY(*this);
189 
190  // Unroll the loop
191  const size_t unroll=4;
192  size_t nmax=(NZYXSIZE(*this)/unroll)*unroll;
193  for (size_t n=0; n<nmax; n+=unroll)
194  {
195  DIRECT_MULTIDIM_ELEM(realImg, n) = static_cast<double>(*ptr1++);
196  ptr1++;
197  DIRECT_MULTIDIM_ELEM(realImg, n+1) = static_cast<double>(*(ptr1++));
198  ptr1++;
199  DIRECT_MULTIDIM_ELEM(realImg, n+2) = static_cast<double>(*(ptr1++));
200  ptr1++;
201  DIRECT_MULTIDIM_ELEM(realImg, n+3) = static_cast<double>(*(ptr1++));
202  ptr1++;
203  }
204  // Do the remaining elements
205  for (size_t n=nmax; n<NZYXSIZE(*this); ++n)
206  {
207  DIRECT_MULTIDIM_ELEM(realImg, n) = static_cast<double>(*ptr1++);
208  ptr1++;
209  }
210 
211 }
212 
213 template<>
214 void MultidimArray< std::complex< double > >::getImag(MultidimArray<double> & imagImg) const
215 {
216  if (NZYXSIZE(*this) == 0)
217  {
218  imagImg.clear();
219  return;
220  }
221 
222  imagImg.resizeNoCopy(*this);
223  double * ptr1 = (double*) MULTIDIM_ARRAY(*this);
224 
225  // Unroll the loop
226  const size_t unroll=4;
227  size_t nmax=(NZYXSIZE(*this)/unroll)*unroll;
228  for (size_t n=0; n<nmax; n+=unroll)
229  {
230  DIRECT_MULTIDIM_ELEM(imagImg, n) = static_cast<double>(*(++ptr1));
231  ptr1++;
232  DIRECT_MULTIDIM_ELEM(imagImg, n+1) = static_cast<double>(*(++ptr1));
233  ptr1++;
234  DIRECT_MULTIDIM_ELEM(imagImg, n+2) = static_cast<double>(*(++ptr1));
235  ptr1++;
236  DIRECT_MULTIDIM_ELEM(imagImg, n+3) = static_cast<double>(*(++ptr1));
237  ptr1++;
238  }
239  // Do the remaining elements
240  for (size_t n=nmax; n<NZYXSIZE(*this); ++n)
241  {
242  DIRECT_MULTIDIM_ELEM(imagImg, n) = static_cast<double>(*(++ptr1));
243  ptr1++;
244  }
245 
246 }
247 
248 
249 template<>
250 double MultidimArray<double>::interpolatedElement2D(double x, double y, double outside_value) const
251 {
252  double dx0 = floor(x);
253  int x0=(int)dx0;
254  double fx = x - dx0;
255  int x1 = x0 + 1;
256  double dy0 = floor(y);
257  int y0=(int)dy0;
258  double fy = y - dy0;
259  int y1 = y0 + 1;
260 
261  int i0=STARTINGY(*this);
262  int j0=STARTINGX(*this);
263  int iF=FINISHINGY(*this);
264  int jF=FINISHINGX(*this);
265 
266  /* Next code avoids checking two times some variables that are doubles.
267  * The code before was:
268  ASSIGNVAL2D(d00,y0,x0);
269  ASSIGNVAL2D(d01,y0,x1);
270  ASSIGNVAL2D(d10,y1,x0);
271  ASSIGNVAL2D(d11,y1,x1);
272  */
273  double d00, d10, d11, d01, *ref;
274  if ((x0 >= j0) && (x1 <= jF) && (y0 >= i0) && (y1 <= iF))
275  {
276  ref = &A2D_ELEM(*this, y0, x0);
277  d00 = (*ref++);
278  d01 = (*ref);
279  ref = &A2D_ELEM(*this, y1, x0);
280  d10 = (*ref++);
281  d11 = (*ref);
282  }
283  else
284  {
285  bool outX0,outX1,outY0,outY1;
286  outX0 = (x0 < j0) || (x0 > jF);
287  outX1 = (x1 < j0) || (x1 > jF);
288  outY0 = (y0 < i0) || (y0 > iF);
289  outY1 = (y1 < i0) || (y1 > iF);
290 
291  if (outY0)
292  {
293  d00 = outside_value;
294  d01 = outside_value;
295  d10 = outside_value;
296  d11 = outside_value;
297  }
298  else if(outY1)
299  {
300  d10 = outside_value;
301  d11 = outside_value;
302 
303  if (outX0)
304  {
305  d00 = outside_value;
306  d01 = outside_value;
307  }
308  else
309  {
310  d00 = A2D_ELEM(*this, y0, x0);
311  if (outX1)
312  {
313  d01 = outside_value;
314  }
315  else
316  {
317  d01 = A2D_ELEM(*this, y0, x1);
318  }
319  }
320  }
321  else
322  {
323  if (outX0)
324  {
325  d00 = outside_value;
326  d10 = outside_value;
327  d01 = outside_value;
328  d11 = outside_value;
329  }
330  else
331  {
332  if (outX1)
333  {
334  d01 = outside_value;
335  d11 = outside_value;
336  }
337  else
338  {
339  d01 = A2D_ELEM(*this, y0, x1);
340  d11 = A2D_ELEM(*this, y1, x1);
341  }
342 
343  d00 = A2D_ELEM(*this, y0, x0);
344  d10 = A2D_ELEM(*this, y1, x0);
345  }
346  }
347  }
348 
349  double d0 = LIN_INTERP(fx, d00, d01);
350  double d1 = LIN_INTERP(fx, d10, d11);
351  return LIN_INTERP(fy, d0, d1);
352 }
353 
355 {
356  s.resizeNoCopy(x);
357  c.resizeNoCopy(x);
358  double *ptr=NULL;
359  double *ptrS=MULTIDIM_ARRAY(s);
360  double *ptrC=MULTIDIM_ARRAY(c);
361  size_t n;
363  sincos(*ptr, ptrS++,ptrC++);
364 }
365 
366 
368  double &p0, double &p1, double &p2)
369 {
371  REPORT_ERROR(ERR_MULTIDIM_SIZE,"Not all vectors are of the same size");
372  if (MULTIDIM_SIZE(z) < 10)
373  REPORT_ERROR(ERR_MULTIDIM_SIZE, "Not enough elements to compute Least Squares plane fit");
374 
375  double m11=0, m12=0, m13=0, m21=0, m22=0, m23=0, m31=0, m32=0, m33=0;
376  double b1=0, b2=0, b3=0;
377 
379  {
380  double X=DIRECT_MULTIDIM_ELEM(x,n);
381  double Y=DIRECT_MULTIDIM_ELEM(y,n);
382  double Z=DIRECT_MULTIDIM_ELEM(z,n);
383  m11+=X*X;
384  m12+=X*Y;
385  m13+=X;
386 
387  m22+=Y*Y;
388  m23+=Y;
389 
390  b1+=X*Z;
391  b2+=Y*Z;
392  b3+=Z;
393  }
394  m21=m12;
395  m31=m13;
396  m32=m23;
397  m33=MULTIDIM_SIZE(z);
398 
399  Matrix2D<double> A(3, 3);
400  Matrix1D<double> b(3);
401  Matrix1D<double> c(3);
402 
403  A(0,0)=m11;
404  A(0,1)=m12;
405  A(0,2)=m13;
406  A(1,0)=m21;
407  A(1,1)=m22;
408  A(1,2)=m23;
409  A(2,0)=m31;
410  A(2,1)=m32;
411  A(2,2)=m33;
412 
413  b(0)=b1;
414  b(1)=b2;
415  b(2)=b3;
416 
417  c = A.inv() * b;
418  p0 = c(2);
419  p2 = c(1);
420  p1 = c(0);
421 }
422 
423 template<typename T>
425  int SplineDegree) const
426 {
427  int SplineDegree_1 = SplineDegree - 1;
428 
429  // Logical to physical
430  z -= STARTINGZ(*this);
431  y -= STARTINGY(*this);
432  x -= STARTINGX(*this);
433 
434  int l1 = (int)ceil(x - SplineDegree_1);
435  int l2 = l1 + SplineDegree;
436 
437  int m1 = (int)ceil(y - SplineDegree_1);
438  int m2 = m1 + SplineDegree;
439 
440  int n1 = (int)ceil(z - SplineDegree_1);
441  int n2 = n1 + SplineDegree;
442 
443  double zyxsum = 0.0;
444  double aux;
445  int Xdim=(int)XSIZE(*this);
446  int Ydim=(int)YSIZE(*this);
447  int Zdim=(int)ZSIZE(*this);
448  for (int nn = n1; nn <= n2; nn++)
449  {
450  int equivalent_nn=nn;
451  if (nn<0)
452  equivalent_nn=-nn-1;
453  else if (nn>=Zdim)
454  equivalent_nn=2*Zdim-nn-1;
455  double yxsum = 0.0;
456  for (int m = m1; m <= m2; m++)
457  {
458  int equivalent_m=m;
459  if (m<0)
460  equivalent_m=-m-1;
461  else if (m>=Ydim)
462  equivalent_m=2*Ydim-m-1;
463  double xsum = 0.0;
464  for (int l = l1; l <= l2; l++)
465  {
466  double xminusl = x - (double) l;
467  int equivalent_l=l;
468  if (l<0)
469  equivalent_l=-l-1;
470  else if (l>=Xdim)
471  equivalent_l=2*Xdim-l-1;
472  double Coeff = (double) DIRECT_A3D_ELEM(*this,
473  equivalent_nn,equivalent_m,equivalent_l);
474  switch (SplineDegree)
475  {
476  case 2:
477  xsum += Coeff * Bspline02(xminusl);
478  break;
479  case 3:
480  BSPLINE03(aux,xminusl);
481  xsum += Coeff * aux;
482  break;
483  case 4:
484  xsum += Coeff * Bspline04(xminusl);
485  break;
486  case 5:
487  xsum += Coeff * Bspline05(xminusl);
488  break;
489  case 6:
490  xsum += Coeff * Bspline06(xminusl);
491  break;
492  case 7:
493  xsum += Coeff * Bspline07(xminusl);
494  break;
495  case 8:
496  xsum += Coeff * Bspline08(xminusl);
497  break;
498  case 9:
499  xsum += Coeff * Bspline09(xminusl);
500  break;
501  }
502  }
503 
504  double yminusm = y - (double) m;
505  switch (SplineDegree)
506  {
507  case 2:
508  yxsum += xsum * Bspline02(yminusm);
509  break;
510  case 3:
511  BSPLINE03(aux,yminusm);
512  yxsum += xsum * aux;
513  break;
514  case 4:
515  yxsum += xsum * Bspline04(yminusm);
516  break;
517  case 5:
518  yxsum += xsum * Bspline05(yminusm);
519  break;
520  case 6:
521  yxsum += xsum * Bspline06(yminusm);
522  break;
523  case 7:
524  yxsum += xsum * Bspline07(yminusm);
525  break;
526  case 8:
527  yxsum += xsum * Bspline08(yminusm);
528  break;
529  case 9:
530  yxsum += xsum * Bspline09(yminusm);
531  break;
532  }
533  }
534 
535  double zminusn = z - (double) nn;
536  switch (SplineDegree)
537  {
538  case 2:
539  zyxsum += yxsum * Bspline02(zminusn);
540  break;
541  case 3:
542  BSPLINE03(aux,zminusn);
543  zyxsum += yxsum * aux;
544  break;
545  case 4:
546  zyxsum += yxsum * Bspline04(zminusn);
547  break;
548  case 5:
549  zyxsum += yxsum * Bspline05(zminusn);
550  break;
551  case 6:
552  zyxsum += yxsum * Bspline06(zminusn);
553  break;
554  case 7:
555  zyxsum += yxsum * Bspline07(zminusn);
556  break;
557  case 8:
558  zyxsum += yxsum * Bspline08(zminusn);
559  break;
560  case 9:
561  zyxsum += yxsum * Bspline09(zminusn);
562  break;
563  }
564  }
565 
566  return (T) zyxsum;
567 }
568 
569 template<typename T>
570 T MultidimArray<T>::interpolatedElementBSpline2D(double x, double y, int SplineDegree) const
571 {
572  int SplineDegree_1 = SplineDegree - 1;
573 
574  // Logical to physical
575  y -= STARTINGY(*this);
576  x -= STARTINGX(*this);
577 
578  int l1 = (int)ceil(x - SplineDegree_1);
579  int l2 = l1 + SplineDegree;
580  int m1 = (int)ceil(y - SplineDegree_1);
581  int m2 = m1 + SplineDegree;
582 
583  double columns = 0.0;
584  double aux;
585  int Ydim=(int)YSIZE(*this);
586  int Xdim=(int)XSIZE(*this);
587  for (int m = m1; m <= m2; m++)
588  {
589  int equivalent_m=m;
590  if (m<0)
591  equivalent_m=-m-1;
592  else if (m>=Ydim)
593  equivalent_m=2*Ydim-m-1;
594  double rows = 0.0;
595  for (int l = l1; l <= l2; l++)
596  {
597  double xminusl = x - (double) l;
598  int equivalent_l=l;
599  if (l<0)
600  equivalent_l=-l-1;
601  else if (l>=Xdim)
602  equivalent_l=2*Xdim-l-1;
603  double Coeff = DIRECT_A2D_ELEM(*this, equivalent_m,equivalent_l);
604  switch (SplineDegree)
605  {
606  case 2:
607  rows += Coeff * Bspline02(xminusl);
608  break;
609 
610  case 3:
611  BSPLINE03(aux,xminusl);
612  rows += Coeff * aux;
613  break;
614 
615  case 4:
616  rows += Coeff * Bspline04(xminusl);
617  break;
618 
619  case 5:
620  rows += Coeff * Bspline05(xminusl);
621  break;
622 
623  case 6:
624  rows += Coeff * Bspline06(xminusl);
625  break;
626 
627  case 7:
628  rows += Coeff * Bspline07(xminusl);
629  break;
630 
631  case 8:
632  rows += Coeff * Bspline08(xminusl);
633  break;
634 
635  case 9:
636  rows += Coeff * Bspline09(xminusl);
637  break;
638  }
639  }
640 
641  double yminusm = y - (double) m;
642  switch (SplineDegree)
643  {
644  case 2:
645  columns += rows * Bspline02(yminusm);
646  break;
647 
648  case 3:
649  BSPLINE03(aux,yminusm);
650  columns += rows * aux;
651  break;
652 
653  case 4:
654  columns += rows * Bspline04(yminusm);
655  break;
656 
657  case 5:
658  columns += rows * Bspline05(yminusm);
659  break;
660 
661  case 6:
662  columns += rows * Bspline06(yminusm);
663  break;
664 
665  case 7:
666  columns += rows * Bspline07(yminusm);
667  break;
668 
669  case 8:
670  columns += rows * Bspline08(yminusm);
671  break;
672 
673  case 9:
674  columns += rows * Bspline09(yminusm);
675  break;
676  }
677  }
678  return (T) columns;
679 }
680 
681 template<typename T>
683 {
684  bool firstTime=true; // Inner loop first time execution flag.
685  double *ref;
686 
687  // Logical to physical
688  y -= STARTINGY(*this);
689  x -= STARTINGX(*this);
690 
691  int l1 = (int)ceil(x - 2);
692  int l2 = l1 + 3;
693  int m1 = (int)ceil(y - 2);
694  int m2 = m1 + 3;
695 
696  double columns = 0.0;
697  double aux;
698  int Ydim=(int)YSIZE(*this);
699  int Xdim=(int)XSIZE(*this);
700 
701  int equivalent_l_Array[LOOKUP_TABLE_LEN]; // = new int [l2 - l1 + 1];
702  double aux_Array[LOOKUP_TABLE_LEN];// = new double [l2 - l1 + 1];
703 
704  for (int m = m1; m <= m2; m++)
705  {
706  int equivalent_m=m;
707  if (m<0)
708  equivalent_m=-m-1;
709  else if (m>=Ydim)
710  equivalent_m=2*Ydim-m-1;
711  double rows = 0.0;
712  int index=0;
713  ref = &DIRECT_A2D_ELEM(*this, equivalent_m,0);
714  for (int l = l1; l <= l2; l++)
715  {
716  int equivalent_l;
717  // Check if it is first time executing inner loop.
718  if (firstTime)
719  {
720  double xminusl = x - (double) l;
721  equivalent_l=l;
722  if (l<0)
723  {
724  equivalent_l=-l-1;
725  }
726  else if (l>=Xdim)
727  {
728  equivalent_l=2*Xdim-l-1;
729  }
730 
731  equivalent_l_Array[index] = equivalent_l;
732  BSPLINE03(aux,xminusl);
733  aux_Array[index] = aux;
734  index++;
735  }
736  else
737  {
738  equivalent_l = equivalent_l_Array[index];
739  aux = aux_Array[index];
740  index++;
741  }
742 
743  //double Coeff = DIRECT_A2D_ELEM(*this, equivalent_m,equivalent_l);
744  double Coeff = ref[equivalent_l];
745  rows += Coeff * aux;
746  }
747 
748  // Set first time inner flag is executed to false.
749  firstTime = false;
750 
751  double yminusm = y - (double) m;
752  BSPLINE03(aux,yminusm);
753  columns += rows * aux;
754  }
755 
756  return (T) columns;
757 }
758 
759 template<typename T>
760 T MultidimArray<T>::interpolatedElementBSpline1D(double x, int SplineDegree) const
761 {
762  int SplineDegree_1 = SplineDegree - 1;
763 
764  // Logical to physical
765  x -= STARTINGX(*this);
766 
767  int l1 = (int)ceil(x - SplineDegree_1);
768  int l2 = l1 + SplineDegree;
769  int Xdim=(int)XSIZE(*this);
770  double sum = 0.0;
771  for (int l = l1; l <= l2; l++)
772  {
773  double xminusl = x - (double) l;
774  int equivalent_l=l;
775  if (l<0)
776  equivalent_l=-l-1;
777  else if (l>=Xdim)
778  equivalent_l=2*Xdim-l-1;
779  double Coeff = (double) DIRECT_A1D_ELEM(*this, equivalent_l);
780  double aux;
781  switch (SplineDegree)
782  {
783  case 2:
784  sum += Coeff * Bspline02(xminusl);
785  break;
786 
787  case 3:
788  BSPLINE03(aux,xminusl);
789  sum += Coeff * aux;
790  break;
791 
792  case 4:
793  sum += Coeff * Bspline04(xminusl);
794  break;
795 
796  case 5:
797  sum += Coeff * Bspline05(xminusl);
798  break;
799 
800  case 6:
801  sum += Coeff * Bspline06(xminusl);
802  break;
803 
804  case 7:
805  sum += Coeff * Bspline07(xminusl);
806  break;
807 
808  case 8:
809  sum += Coeff * Bspline08(xminusl);
810  break;
811 
812  case 9:
813  sum += Coeff * Bspline09(xminusl);
814  break;
815  }
816  }
817  return (T) sum;
818 }
819 
820 template<typename T>
821 void MultidimArray<T>::initRandom(double op1, double op2, RandomMode mode)
822 {
823  T* ptr=NULL;
824  size_t n;
825  if (mode == RND_UNIFORM)
827  *ptr = static_cast< T >(rnd_unif(op1, op2));
828  else if (mode == RND_GAUSSIAN)
830  *ptr = static_cast< T >(rnd_gaus(op1, op2));
831  else
833  formatString("InitRandom: Mode not supported"));
834 }
835 
836 template<typename T>
838  double op2,
839  const String& mode,
840  double df) const
841 {
842  T* ptr=NULL;
843  size_t n;
844  if (mode == "uniform")
846  *ptr += static_cast< T >(rnd_unif(op1, op2));
847  else if (mode == "gaussian")
849  *ptr += static_cast< T >(rnd_gaus(op1, op2));
850  else if (mode == "student")
852  *ptr += static_cast< T >(rnd_student_t(df, op1, op2));
853  else
855  formatString("AddNoise: Mode not supported (%s)", mode.c_str()));
856 }
857 
858 template<typename T>
859 FILE* MultidimArray<T>::mmapFile(T* &_data, size_t nzyxDim) const
860 {
861 #ifdef XMIPP_MMAP
862  FILE* fMap = tmpfile();
863  int Fd = fileno(fMap);
864 
865  if ((lseek(Fd, nzyxDim*sizeof(T)-1, SEEK_SET) == -1) || (::write(Fd,"",1) == -1))
866  {
867  fclose(fMap);
868  REPORT_ERROR(ERR_IO_NOWRITE,"MultidimArray::resize: Error 'stretching' the map file.");
869  }
870  if ( (_data = (T*) mmap(0,nzyxDim*sizeof(T), PROT_READ | PROT_WRITE, MAP_SHARED, Fd, 0)) == (void*) MAP_FAILED )
871  REPORT_ERROR(ERR_MMAP_NOTADDR,formatString("MultidimArray::resize: mmap failed. Error %s", strerror(errno)));
872 
873  return fMap;
874 #else
875 
876  REPORT_ERROR(ERR_MMAP,"Mapping not supported in Windows");
877 #endif
878 
879 }
880 
881 template<typename T>
883 {
884  checkDimension(1);
885 
887  indx.clear();
888 
889  if (xdim == 0)
890  return;
891 
892  if (xdim == 1)
893  {
894  indx.resizeNoCopy(1);
895  DIRECT_A1D_ELEM(indx,0) = 1;
896  return;
897  }
898 
899  // Initialise data
900  indx.resizeNoCopy(xdim);
901  typeCast(*this, temp);
902 
903  // Sort indexes
904  double* temp_array = temp.adaptForNumericalRecipes1D();
905  int* indx_array = indx.adaptForNumericalRecipes1D();
906  indexx(XSIZE(*this), temp_array, indx_array);
907 }
908 
909 template<typename T>
910 void MultidimArray<T>::selfNormalizeInterval(double minPerc, double maxPerc, int Npix)
911 {
912  std::vector<double> randValues; // Vector with random chosen values
913 
914  for(int i=0; i<Npix; i++)
915  {
916  size_t indx = (size_t)rnd_unif(0, MULTIDIM_SIZE(*this));
917  randValues.push_back(DIRECT_MULTIDIM_ELEM(*this,indx));
918  }
919  std::sort(randValues.begin(),randValues.end());
920 
921  double m = randValues[(size_t)(minPerc*Npix)];
922  double M = randValues[(size_t)(maxPerc*Npix)];
923 
924  T* ptr=NULL;
925  size_t n;
927  *ptr = 2/(M-m)*(*ptr-m)-1;
928 }
929 
930 template<typename T>
931 void MultidimArray<T>::showWithGnuPlot(const String& xlabel, const String& title)
932 {
933  checkDimension(1);
934 
935  FileName fn_tmp;
936  fn_tmp.initRandom(10);
937  const char * fnStr = fn_tmp.c_str();
938  MultidimArray<T>::write(formatString("PPP%s.txt", fnStr));
939 
940  std::ofstream fh_gplot;
941  fh_gplot.open(formatString("PPP%s.gpl", fnStr).c_str());
942  if (!fh_gplot)
944  formatString("vector::showWithGnuPlot: Cannot open PPP%s.gpl for output", fnStr));
945  fh_gplot << "set xlabel \"" + xlabel + "\"\n";
946  fh_gplot << "plot \"PPP" + fn_tmp + ".txt\" title \"" + title +
947  "\" w l\n";
948  fh_gplot << "pause 300 \"\"\n";
949  fh_gplot.close();
950  if (0 != system(formatString("(gnuplot PPP%s.gpl; rm PPP%s.txt PPP%s.gpl) &", fnStr, fnStr, fnStr).c_str()) ) {
951  REPORT_ERROR(ERR_IO, "Cannot open gnuplot");
952  }
953 }
954 
955 template<typename T>
957 {
958  FileName nam;
959  nam.initRandom(15);
960 
961  nam = formatString("PPP%s.txt", nam.c_str());
962  write(nam);
963 
964  if (0 != system(formatString("xmipp_edit -i %s -remove &", nam.c_str()).c_str())) {
965  REPORT_ERROR(ERR_IO, "Cannot open xmipp_edit");
966  }
967 }
968 
969 template<typename T>
970 void MultidimArray<T>::write(const FileName& fn) const
971 {
972  std::ofstream out;
973  out.open(fn.c_str(), std::ios::out);
974  if (!out)
976  formatString("MultidimArray::write: File %s cannot be opened for output", fn.c_str()));
977 
978  out << *this;
979  out.close();
980 }
981 
982 template<typename T>
983 void MultidimArray<T>::resize(size_t Ndim, size_t Zdim, size_t Ydim, size_t Xdim, bool copy)
984 {
985  if (Ndim*Zdim*Ydim*Xdim == nzyxdimAlloc && data != NULL)
986  {
987  ndim = Ndim;
988  xdim = Xdim;
989  ydim = Ydim;
990  zdim = Zdim;
991  yxdim = Ydim * Xdim;
992  zyxdim = Zdim * yxdim;
993  nzyxdim = Ndim * zyxdim;
994  return;
995  }
996  else if (!destroyData)
997  REPORT_ERROR(ERR_MULTIDIM_SIZE, "Cannot resize array when accessing through alias.");
998 
999  if (Xdim <= 0 || Ydim <= 0 || Zdim <= 0 || Ndim <= 0)
1000  {
1001  clear();
1002  return;
1003  }
1004 
1005  // data can be NULL while xdim etc are set to non-zero values
1006  // (This can happen for reading of images...)
1007  // In that case, initialize data to zeros.
1008  if (NZYXSIZE(*this) > 0 && data == NULL)
1009  {
1010  ndim = Ndim;
1011  xdim = Xdim;
1012  ydim = Ydim;
1013  zdim = Zdim;
1014  yxdim = Ydim * Xdim;
1015  zyxdim = Zdim * yxdim;
1016  nzyxdim = Ndim * zyxdim;
1017 
1018  coreAllocate();
1019  return;
1020  }
1021 
1022  // Ask for memory
1023  size_t YXdim=(size_t)Ydim*Xdim;
1024  size_t ZYXdim=YXdim*Zdim;
1025  size_t NZYXdim=ZYXdim*Ndim;
1026  FILE* new_mFd=NULL;
1027 
1028  T * new_data=NULL;
1029 
1030  try
1031  {
1032  if (mmapOn)
1033  new_mFd = mmapFile(new_data, NZYXdim);
1034  else
1035  new_data = new T [NZYXdim];
1036 
1037  memset(new_data,0,NZYXdim*sizeof(T));
1038  }
1039  catch (std::bad_alloc &)
1040  {
1041  if (!mmapOn)
1042  {
1043  setMmap(true);
1044  resize(Ndim, Zdim, Ydim, Xdim, copy);
1045  return;
1046  }
1047  else
1048  {
1049  std::ostringstream sstream;
1050  sstream << "Allocate: No space left to allocate ";
1051  sstream << (NZYXdim * sizeof(T)/1024/1024/1024) ;
1052  sstream << "Gb." ;
1053  REPORT_ERROR(ERR_MEM_NOTENOUGH, sstream.str());
1054  }
1055  }
1056  // Copy needed elements, fill with 0 if necessary
1057  if (copy)
1058  {
1059  const auto nCopy = std::min(Ndim, NSIZE(*this));
1060  const auto zCopy = std::min(Zdim, ZSIZE(*this));
1061  const auto yCopy = std::min(Ydim, YSIZE(*this));
1062  const auto xCopy = std::min(Xdim, XSIZE(*this));
1063  const auto xCopyBytes = xCopy*sizeof(T);
1064 
1065  for (size_t l = 0; l < nCopy; ++l)
1066  for (size_t k = 0; k < zCopy; ++k)
1067  for (size_t i = 0; i < yCopy; ++i)
1068  memcpy(
1069  new_data + l*ZYXdim + k*YXdim + i*Xdim,
1070  data + l*zyxdim + k*yxdim + i*xdim,
1071  xCopyBytes
1072  );
1073  }
1074 
1075  // deallocate old array
1076  coreDeallocate();
1077 
1078  // assign *this vector to the newly created
1079  data = new_data;
1080  ndim = Ndim;
1081  xdim = Xdim;
1082  ydim = Ydim;
1083  zdim = Zdim;
1084  yxdim = Ydim * Xdim;
1085  zyxdim = Zdim * yxdim;
1086  nzyxdim = Ndim * zyxdim;
1087  mFd = new_mFd;
1089 }
1090 
1091 template<typename T>
1093 {
1094  result = *this;
1095  std::sort(result.data, result.data + result.nzyxdim);
1096 }
1097 
1098 template<typename T>
1100 {
1101  std::vector<double> bgI;
1102 
1104  {
1105  if (DIRECT_MULTIDIM_ELEM(mask, n) != 0)
1106  {
1107  double aux = DIRECT_MULTIDIM_ELEM(*this, n);
1108  bgI.push_back(aux);
1109  }
1110  }
1111 
1112  std::sort(bgI.begin(), bgI.end());
1113  if (bgI.size() % 2 != 0)
1114  median = bgI[bgI.size() / 2];
1115  else
1116  median = (bgI[(bgI.size() - 1) / 2] + bgI[bgI.size() / 2]) / 2.0;
1117 }
1118 
1119 template<typename T>
1121  T avgv,
1122  T sigv,
1123  double accuracy,
1124  MultidimArray<int> * mask)
1125 {
1126  T* ptr=NULL;
1127  size_t n;
1129  if (mask == NULL || DIRECT_MULTIDIM_ELEM(*mask,n) > 0 )
1130  if (ABS(*ptr - oldv) <= accuracy)
1131  *ptr = rnd_gaus(avgv, sigv);
1132 }
1133 
1134 // explicit instantiation
1135 template class MultidimArray<double>;
1136 
1137 // mmapFile
1138 template FILE* MultidimArray<bool>::mmapFile(bool*&, unsigned long) const;
1139 template FILE* MultidimArray<float>::mmapFile(float*&, unsigned long) const;
1140 template FILE* MultidimArray<char>::mmapFile(char*&, unsigned long) const;
1141 template FILE* MultidimArray<int>::mmapFile(int*&, unsigned long) const;
1142 template FILE* MultidimArray<long>::mmapFile(long*&, unsigned long) const;
1143 template FILE* MultidimArray<short>::mmapFile(short*&, unsigned long) const;
1144 template FILE* MultidimArray<unsigned char>::mmapFile(unsigned char*&, unsigned long) const;
1145 template FILE* MultidimArray<unsigned int>::mmapFile(unsigned int*&, unsigned long) const;
1146 template FILE* MultidimArray<unsigned long>::mmapFile(unsigned long*&, unsigned long) const;
1147 template FILE* MultidimArray<unsigned short>::mmapFile(unsigned short*&, unsigned long) const;
1148 template FILE* MultidimArray<std::complex<double>>::mmapFile(std::complex<double>*&, unsigned long) const;
1149 template FILE* MultidimArray<half_float::half>::mmapFile(half_float::half*&, unsigned long) const;
1150 
1151 // resize
1152 template void MultidimArray<bool>::resize(unsigned long, unsigned long, unsigned long, unsigned long, bool);
1153 template void MultidimArray<float>::resize(unsigned long, unsigned long, unsigned long, unsigned long, bool);
1154 template void MultidimArray<char>::resize(unsigned long, unsigned long, unsigned long, unsigned long, bool);
1155 template void MultidimArray<long>::resize(unsigned long, unsigned long, unsigned long, unsigned long, bool);
1156 template void MultidimArray<int>::resize(unsigned long, unsigned long, unsigned long, unsigned long, bool);
1157 template void MultidimArray<short>::resize(unsigned long, unsigned long, unsigned long, unsigned long, bool);
1158 template void MultidimArray<unsigned char>::resize(unsigned long, unsigned long, unsigned long, unsigned long, bool);
1159 template void MultidimArray<unsigned int>::resize(unsigned long, unsigned long, unsigned long, unsigned long, bool);
1160 template void MultidimArray<unsigned long>::resize(unsigned long, unsigned long, unsigned long, unsigned long, bool);
1161 template void MultidimArray<unsigned short>::resize(unsigned long, unsigned long, unsigned long, unsigned long, bool);
1162 template void MultidimArray<std::complex<double>>::resize(unsigned long, unsigned long, unsigned long, unsigned long, bool);
1163 template void MultidimArray<half_float::half>::resize(unsigned long, unsigned long, unsigned long, unsigned long, bool);
1164 
1165 // index sort
1168 
1169 // init random
1170 template void MultidimArray<float>::initRandom(double, double, RandomMode);
1171 template void MultidimArray<char>::initRandom(double, double, RandomMode);
1172 template void MultidimArray<long>::initRandom(double, double, RandomMode);
1173 template void MultidimArray<int>::initRandom(double, double, RandomMode);
1174 template void MultidimArray<short>::initRandom(double, double, RandomMode);
1175 template void MultidimArray<unsigned char>::initRandom(double, double, RandomMode);
1176 template void MultidimArray<unsigned int>::initRandom(double, double, RandomMode);
1177 template void MultidimArray<unsigned long>::initRandom(double, double, RandomMode);
1178 template void MultidimArray<unsigned short>::initRandom(double, double, RandomMode);
1179 template void MultidimArray<half_float::half>::initRandom(double, double, RandomMode);
1180 
1181 // write
1182 template void MultidimArray<bool>::write(FileName const&) const;
#define NSIZE(v)
void planeFit(const MultidimArray< double > &z, const MultidimArray< double > &x, const MultidimArray< double > &y, double &p0, double &p1, double &p2)
#define MAT_YSIZE(m)
Definition: matrix2d.h:124
T interpolatedElementBSpline1D(double x, int SplineDegree=3) const
int * nmax
#define YSIZE(v)
void min(Image< double > &op1, const Image< double > &op2)
#define A2D_ELEM(v, i, j)
double Bspline05(double Argument)
void coreDeallocate() noexcept
void resize(size_t Ndim, size_t Zdim, size_t Ydim, size_t Xdim, bool copy=true)
Case or algorithm not implemented yet.
Definition: xmipp_error.h:177
#define MAT_SIZE(m)
Definition: matrix2d.h:128
__host__ __device__ float2 floor(const float2 v)
double rnd_student_t(double nu)
#define FINISHINGX(v)
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
T interpolatedElementBSpline2D_Degree3(double x, double y) const
void sort(MultidimArray< T > &result) const
#define LOOKUP_TABLE_LEN
void initRandom(double op1, double op2, RandomMode mode=RND_UNIFORM)
doublereal * c
#define MULTIDIM_SIZE(v)
Global mmap error.
Definition: xmipp_error.h:170
void resizeNoCopy(const MultidimArray< T1 > &v)
FILE * mmapFile(T *&_data, size_t nzyxDim) const
static double * y
Couldn&#39;t write to file.
Definition: xmipp_error.h:140
There is not enough memory for allocation.
Definition: xmipp_error.h:166
T interpolatedElementBSpline3D(double x, double y, double z, int SplineDegree=3) const
#define DIRECT_A2D_ELEM(v, i, j)
#define MULTIDIM_ARRAY(v)
void inv(Matrix2D< T > &result) const
Definition: matrix2d.cpp:663
RandomMode
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY_ptr(v, n, ptr)
Input/Output general error.
Definition: xmipp_error.h:134
Incorrect MultidimArray size.
Definition: xmipp_error.h:174
#define FINISHINGZ(v)
#define STARTINGX(v)
bool operator==(const MultidimArray< std::complex< double > > &op1, const MultidimArray< std::complex< double > > &op2)
doublereal * x
#define i
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
void median(MultidimArray< T > &x, MultidimArray< T > &y, T &m)
Definition: filters.h:1055
double Bspline04(double Argument)
void resizeNoCopy(int Ydim, int Xdim)
Definition: matrix2d.h:534
T interpolatedElement2D(double x, double y, T outside_value=(T) 0) const
#define STARTINGY(v)
double rnd_unif()
#define A3D_ELEM(V, k, i, j)
Definition: mask.h:36
Map addressing of file has failed.
Definition: xmipp_error.h:171
#define DIRECT_A1D_ELEM(v, i)
#define checkDimension(dim)
doublereal * b
void addNoise(double op1, double op2, const String &mode="uniform", double df=3.) const
void computeMedian_within_binary_mask(const MultidimArray< int > &mask, double &median) const
#define y0
#define x0
std::ostream & operator<<(std::ostream &ostrm, const MultidimArray< std::complex< double > > &v)
void getSliceAsMatrix(size_t k, Matrix2D< T > &m) const
viol index
void setMmap(bool mmap)
#define XMIPP_EQUAL_ACCURACY
Definition: xmipp_macros.h:119
void indexx(int n, double arrin[], int indx[])
#define XSIZE(v)
void write(const FileName &fn) const
T * adaptForNumericalRecipes1D() const
MultidimArray< T > & operator=(const MultidimArray< T > &op1)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
void sincos(const MultidimArray< double > &x, MultidimArray< double > &s, MultidimArray< double > &c)
double Bspline07(double Argument)
#define ABS(x)
Definition: xmipp_macros.h:142
void showWithGnuPlot(const String &xlabel, const String &title)
#define ZSIZE(v)
double z
#define DIRECT_MULTIDIM_ELEM(v, n)
double Bspline08(double Argument)
#define NZYXSIZE(v)
void randomSubstitute(T oldv, T avgv, T sigv, double accuracy=XMIPP_EQUAL_ACCURACY, MultidimArray< int > *mask=NULL)
void window2D(const MultidimArray< T > &Ibig, MultidimArray< T > &Ismall, size_t y0, size_t x0, size_t yF, size_t xF)
void mode
#define xF
void sort(struct DCEL_T *dcel)
Definition: sorting.cpp:18
#define DIRECT_A3D_ELEM(v, k, i, j)
T interpolatedElementBSpline2D(double x, double y, int SplineDegree=3) const
double * d0
#define j
int m
File cannot be open.
Definition: xmipp_error.h:137
#define FINISHINGY(v)
double Bspline02(double Argument)
void typeCast(const Matrix1D< T1 > &v1, Matrix1D< T2 > &v2)
Definition: matrix1d.h:1227
#define MAT_XSIZE(m)
Definition: matrix2d.h:120
std::string String
Definition: xmipp_strings.h:34
double rnd_gaus()
String formatString(const char *format,...)
void selfNormalizeInterval(double minPerc=0.25, double maxPerc=0.75, int Npix=1000)
double Bspline09(double Argument)
void copy(Matrix2D< T > &op1) const
#define LIN_INTERP(a, l, h)
Definition: xmipp_macros.h:381
double Bspline06(double Argument)
Incorrect value received.
Definition: xmipp_error.h:195
#define MATRIX2D_ARRAY(m)
Definition: matrix2d.h:89
#define yF
#define STARTINGZ(v)
int * n
double sum() const
void indexSort(MultidimArray< int > &indx) const
#define BSPLINE03(y, x)
Definition: kernel.h:83
void initRandom(int length)