SLIP  1.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
derivatives.hpp
Go to the documentation of this file.
1 /*
2  * Copyright(c):
3  * Signal Image and Communications (SIC) Department
4  * http://www.sic.sp2mi.univ-poitiers.fr/
5  * - University of Poitiers, France http://www.univ-poitiers.fr
6  * - XLIM Institute UMR CNRS 7252 http://www.xlim.fr/
7  *
8  * and
9  *
10  * D2 Fluid, Thermic and Combustion
11  * - University of Poitiers, France http://www.univ-poitiers.fr
12  * - PPRIME Institute - UPR CNRS 3346 http://www.pprime.fr
13  * - ISAE-ENSMA http://www.ensma.fr
14  *
15  * Contributor(s):
16  * The SLIP team,
17  * Benoit Tremblais <tremblais_AT_sic.univ-poitiers.fr>,
18  * Laurent David <laurent.david_AT_lea.univ-poitiers.fr>,
19  * Ludovic Chatellier <ludovic.chatellier_AT_univ-poitiers.fr>,
20  * Lionel Thomas <lionel.thomas_AT_univ-poitiers.fr>,
21  * Denis Arrivault <arrivault_AT_sic.univ-poitiers.fr>,
22  * Julien Dombre <julien.dombre_AT_univ-poitiers.fr>.
23  *
24  * Description:
25  * The Simple Library of Image Processing (SLIP) is a new image processing
26  * library. It is written in the C++ language following as much as possible
27  * the ISO/ANSI C++ standard. It is consequently compatible with any system
28  * satisfying the ANSI C++ complience. It works on different Unix , Linux ,
29  * Mircrosoft Windows and Mac OS X plateforms. SLIP is a research library that
30  * was created by the Signal, Image and Communications (SIC) departement of
31  * the XLIM, UMR 7252 CNRS Institute in collaboration with the Fluids, Thermic
32  * and Combustion departement of the P', UPR 3346 CNRS Institute of the
33  * University of Poitiers.
34  *
35  * The SLIP Library source code has been registered to the APP (French Agency
36  * for the Protection of Programs) by the University of Poitiers and CNRS,
37  * under registration number IDDN.FR.001.300034.000.S.P.2010.000.21000.
38 
39  * http://www.sic.sp2mi.univ-poitiers.fr/slip/
40  *
41  * This software is governed by the CeCILL-C license under French law and
42  * abiding by the rules of distribution of free software. You can use,
43  * modify and/ or redistribute the software under the terms of the CeCILL-C
44  * license as circulated by CEA, CNRS and INRIA at the following URL
45  * http://www.cecill.info.
46  * As a counterpart to the access to the source code and rights to copy,
47  * modify and redistribute granted by the license, users are provided only
48  * with a limited warranty and the software's author, the holder of the
49  * economic rights, and the successive licensors have only limited
50  * liability.
51  *
52  * In this respect, the user's attention is drawn to the risks associated
53  * with loading, using, modifying and/or developing or reproducing the
54  * software by the user in light of its specific status of free software,
55  * that may mean that it is complicated to manipulate, and that also
56  * therefore means that it is reserved for developers and experienced
57  * professionals having in-depth computer knowledge. Users are therefore
58  * encouraged to load and test the software's suitability as regards their
59  * requirements in conditions enabling the security of their systems and/or
60  * data to be ensured and, more generally, to use and operate it in the
61  * same conditions as regards security.
62  *
63  * The fact that you are presently reading this means that you have had
64  * knowledge of the CeCILL-C license and that you accept its terms.
65  */
66 
67 
68 
77 #ifndef SLIP_DERIVATIVES_HPP
78 #define SLIP_DERIVATIVES_HPP
79 #include <iostream>
80 #include <cassert>
81 #include <vector>
82 #include "linear_algebra.hpp"
84 #include "convolution.hpp"
85 #include "Vector.hpp"
86 #include "Matrix.hpp"
87 #include "Point2d.hpp"
88 #include "Point3d.hpp"
89 #include "Point4d.hpp"
90 #include "neighbors.hpp"
91 
92 namespace slip
93 {
94 
121 {
125 };
126 
128  /* @{ */
129 
154  template<class Container2D>
155  inline
156  void finite_diff_coef(const std::size_t sch_ord,
157  const std::size_t sch_shift,
158  Container2D& Dinv)
159  {
160  //Precondition
161  assert(sch_ord >= sch_shift);
162  // Internal Variables
164  Container2D D(sch_ord+1,sch_ord+1,0.0);
165 
166  for(std::size_t i = 0; i <= sch_ord; ++i)
167  {
168  D[i][0] = 1.0;
169  tmp[i] = typename Container2D::value_type(int(i) - int(sch_shift));
170  }
171  for(std::size_t i = 0; i <= sch_ord; ++i)
172  {
173  for(std::size_t j = 1; j <= sch_ord; ++j)
174  {
175  D[i][j] = D[i][j-1] * tmp[i] / typename Container2D::value_type(j);
176  }
177  }
178  // Result container
179  Dinv.resize(sch_ord+1,sch_ord+1); //finite differences coefficient matrix
180  //matrix inversion
181  slip::inverse(D,Dinv);
182 }
183 
211  template<class Container2D>
212  inline
213  void finite_diff_coef(const std::size_t sch_ord,
214  const std::size_t sch_shift,
215  const typename Container2D::value_type& h,
216  Container2D& Dinv)
217  {
218  //Precondition
219  assert(sch_ord >= sch_shift);
220  assert(h != typename Container2D::value_type(0));
221  typedef typename Container2D::value_type value_type;
222  // Internal Variables
223  slip::Vector<value_type> tmp(sch_ord+1);
224  Container2D D(sch_ord+1,sch_ord+1,0.0);
225 
226  for(std::size_t i = 0; i <= sch_ord; ++i)
227  {
228  D[i][0] = 1.0;
229  tmp[i] = value_type(int(i) - int(sch_shift));
230  }
231  for(std::size_t i = 0; i <= sch_ord; ++i)
232  {
233  for(std::size_t j = 1; j <= sch_ord; ++j)
234  {
235  D[i][j] = D[i][j-1] * tmp[i] / value_type(j);
236  }
237  }
238  // Result container
239  Dinv.resize(sch_ord+1,sch_ord+1); //finite differences coefficient matrix
240  //matrix inversion
241  slip::inverse(D,Dinv);
242  value_type inv_h = value_type(1)/h;
243  for(std::size_t i = 1; i <= sch_ord; ++i)
244  {
245  for(std::size_t j = 0; j <= sch_ord; ++j)
246  {
247  Dinv[i][j] *= inv_h;
248  }
249  inv_h*=inv_h;
250  }
251 
252 }
253 
281  template<typename KernelsIterator>
282  inline
283  void finite_diff_kernels(const std::size_t der_ord,
284  const std::size_t sch_ord,
285  const std::size_t sch_shift,
286  std::vector<KernelsIterator>& kernels_first)
287  {
288  //central kernel
290  slip::finite_diff_coef(sch_ord,sch_shift,Dinv);
291  std::copy(Dinv.row_rbegin(der_ord),Dinv.row_rend(der_ord),kernels_first[0]);
292  //first border kernels
293  for (std::size_t bord_shift = 0; bord_shift < sch_shift; ++bord_shift)
294  {
295  //generate finite differences coefficients
296  slip::finite_diff_coef(sch_ord,bord_shift,Dinv);
297  //extract derivation kernel
298  std::copy(Dinv.row_rbegin(der_ord),Dinv.row_rend(der_ord),kernels_first[bord_shift + 1]);
299 
300  }
301  //last border kernels
302  for (std::size_t bord_shift = sch_shift + 1; bord_shift <= sch_ord; ++bord_shift)
303  {
304  //generate finite differences coefficients
305  slip::finite_diff_coef(sch_ord,bord_shift,Dinv);
306  //extract derivation kernel
307  std::copy(Dinv.row_rbegin(der_ord),Dinv.row_rend(der_ord),kernels_first[bord_shift]);
308  }
309  }
310 
339  template<typename KernelsIterator>
340  inline
341  void finite_diff_kernels(const std::size_t der_ord,
342  const std::size_t sch_ord,
343  const std::size_t sch_shift,
344  const typename std::iterator_traits<KernelsIterator>::value_type& h,
345  std::vector<KernelsIterator>& kernels_first)
346  {
347  //central kernel
349  slip::finite_diff_coef(sch_ord,sch_shift,h,Dinv);
350  std::copy(Dinv.row_rbegin(der_ord),Dinv.row_rend(der_ord),kernels_first[0]);
351  //first border kernels
352  for (std::size_t bord_shift = 0; bord_shift < sch_shift; ++bord_shift)
353  {
354  //generate finite differences coefficients
355  slip::finite_diff_coef(sch_ord,bord_shift,h,Dinv);
356  //extract derivation kernel
357  std::copy(Dinv.row_rbegin(der_ord),Dinv.row_rend(der_ord),kernels_first[bord_shift + 1]);
358 
359  }
360  //last border kernels
361  for (std::size_t bord_shift = sch_shift + 1; bord_shift <= sch_ord; ++bord_shift)
362  {
363  //generate finite differences coefficients
364  slip::finite_diff_coef(sch_ord,bord_shift,h,Dinv);
365  //extract derivation kernel
366  std::copy(Dinv.row_rbegin(der_ord),Dinv.row_rend(der_ord),kernels_first[bord_shift]);
367  }
368  }
369 
415  template<typename SrcIter, typename Container2D, typename ResIter>
416  inline
417  void derivative(SrcIter first, SrcIter last,
418  const std::size_t der_ord,
419  const std::size_t sch_ord,
420  const std::size_t sch_shift,
421  const Container2D& M,
422  ResIter result)
423  {
424  assert(sch_ord >= der_ord);
425  assert(sch_shift <= sch_ord);
426  //- derivation kernel
427  slip::Vector<double> K(sch_ord+1);
428  //extract derivation kernel (reversed for convolution algorithm)
429  for(std::size_t i=0; i<=sch_ord; ++i)
430  K[sch_ord-i]=M[der_ord][i];
431 
432  slip::same_convolution(first,last,
433  K.begin(),K.end(),sch_ord-sch_shift,sch_shift,
434  result,
437  // Border Treatment //
438  // A variable derivation kernel is applied : //
439  // -scheme shift varies from 0 to sch_shift //
440  // on the first elements //
441  // -scheme shift varies from sch_shift+1 to sch_ord //
442  // on the last elements //
444 
445  // Internal Variables
446  //- derivation kernel
447  slip::Matrix<double> Dinv(sch_ord+1,sch_ord+1);
449  // beginning of block : shift from 0 to sch_shift-1
451  for (std::size_t bord_shift = 0; bord_shift < sch_shift; ++bord_shift)
452  {
453  //generate finite differences coefficients
454  slip::finite_diff_coef(sch_ord,bord_shift,Dinv);
455  //extract derivation kernel (reversed for convolution algorithm)
456  for(std::size_t i = 0; i <= sch_ord; ++i)
457  K[sch_ord - i] = Dinv[der_ord][i];
458  //compute the convolution on the left border
459  slip::valid_convolution(first,first+(sch_ord + 1),
460  K.begin(),K.end(),(sch_ord - bord_shift),
461  bord_shift,
462  result + bord_shift);
463  }
464 
466  // end of block : shift from sch_shift+1 to sch_ord
468  for (std::size_t bord_shift = sch_shift + 1; bord_shift <= sch_ord; ++bord_shift)
469  {
470  //generate finite differences coefficients
471  slip::finite_diff_coef(sch_ord,bord_shift,Dinv);
472  //extract derivation kernel (reversed for convolution algorithm)
473  for(std::size_t i = 0; i <= sch_ord; ++i)
474  K[sch_ord - i] = Dinv[der_ord][i];
475 
476  //compute the convolution at the end of block
477  slip::valid_convolution(last - (1 + sch_ord),
478  last,
479  K.begin(),K.end(),(sch_ord - bord_shift),bord_shift,
480  (result + (last-first))-(1 + sch_ord) + bord_shift);
481  }
482  }
483 
510  template<typename SrcIter, typename KernelsIterator, typename ResIter>
511  inline
512  void derivative(SrcIter first, SrcIter last,
513  const std::size_t der_ord,
514  const std::size_t sch_ord,
515  const std::size_t sch_shift,
516  const std::vector<KernelsIterator>& kernels_first,
517  ResIter result)
518  {
519  assert(sch_ord >= der_ord);
520  assert(sch_shift <= sch_ord);
521 
522  std::size_t sch_ord_plus_one = sch_ord + 1;
523  slip::same_convolution(first,last,
524  kernels_first[0],kernels_first[0] + sch_ord_plus_one,
525  sch_ord-sch_shift,
526  sch_shift,
527  result,
530  // Border Treatment //
531  // A variable derivation kernel is applied : //
532  // -scheme shift varies from 0 to sch_shift //
533  // on the first elements //
534  // -scheme shift varies from sch_shift+1 to sch_ord //
535  // on the last elements //
537 
539  // beginning of block : shift from 0 to sch_shift-1
541  for (std::size_t bord_shift = 0; bord_shift < sch_shift; ++bord_shift)
542  {
543  //compute the convolution on the left border
544  slip::valid_convolution(first,first + sch_ord_plus_one,
545  kernels_first[bord_shift+1],
546  kernels_first[bord_shift+1]+ sch_ord_plus_one,
547  (sch_ord - bord_shift),
548  bord_shift,
549  result + bord_shift);
550  }
551 
553  // end of block : shift from sch_shift+1 to sch_ord
555  for (std::size_t bord_shift = sch_shift + 1; bord_shift <= sch_ord; ++bord_shift)
556  {
557  //compute the convolution at the end of block
558  slip::valid_convolution(last - sch_ord_plus_one,
559  last,
560  kernels_first[bord_shift],
561  kernels_first[bord_shift]+ sch_ord_plus_one,
562  (sch_ord - bord_shift),
563  bord_shift,
564  (result + (last-first))-sch_ord_plus_one + bord_shift);
565  }
566  }
567 
568 
590  template<typename Iterator2d1, typename Iterator2d2, typename T>
591  inline
592  void derivative_2d(Iterator2d1 I_up,
593  Iterator2d1 I_bot,
594  const slip::Point2d<T>& grid_step,
595  slip::SPATIAL_DIRECTION der_dir,
596  const std::size_t der_order,
597  const std::size_t sch_order,
598  Iterator2d2 R_up,
599  Iterator2d2 R_bot)
600  {
601  assert(sch_order >= der_order);
602  assert( ((der_dir == X_DIRECTION) && (int((I_bot-I_up)[0]) > int(sch_order)))
603  ||((der_dir == Y_DIRECTION) && (int((I_bot-I_up)[1]) > int(sch_order))) );
604  assert((sch_order / 2) <= sch_order);
605  assert((R_bot - R_up) == (I_bot-I_up));
606  typedef typename Iterator2d1::value_type value_type;
607  typedef typename Iterator2d1::size_type size_type;
608  size_type sch_shift = sch_order / 2;
609 
610 
611  //computes all kernels
612  slip::Matrix<T> kernels(sch_order + 1, sch_order + 1);
613  std::vector<typename slip::Matrix<T>::iterator> kernels_iterators(sch_order + 1);
614  for(size_type i = 0; i < (sch_order + 1); ++i)
615  {
616  kernels_iterators[i] = kernels.row_begin(i);
617  }
618 
619  if(der_dir == X_DIRECTION)
620  {
621  slip::finite_diff_kernels(der_order,sch_order,sch_shift,
622  grid_step[0],
623  kernels_iterators);
624  size_type rows = size_type((I_bot-I_up)[0]);
625  for(size_type i = 0; i < rows; ++i)
626  {
627  slip::derivative(I_up.row_begin(i),
628  I_up.row_end(i),
629  der_order,
630  sch_order,
631  sch_shift,
632  kernels_iterators,
633  R_up.row_begin(i));
634  }
635  }
636 
637  if(der_dir == Y_DIRECTION)
638  {
639  slip::finite_diff_kernels(der_order,sch_order,sch_shift,
640  grid_step[1],
641  kernels_iterators);
642  size_type cols = size_type((I_bot-I_up)[1]);
643  for(size_type j = 0; j < cols; ++j)
644  {
645  slip::derivative(I_up.col_rbegin(j),
646  I_up.col_rend(j),
647  der_order,
648  sch_order,
649  sch_shift,
650  kernels_iterators,
651  R_up.col_rbegin(j));
652 
653  }
654  }
655  }
656 
692  template<typename RandomAccessIterator3d1,
693  typename RandomAccessIterator3d2,
694  typename T>
695  inline
696  void derivative_3d(RandomAccessIterator3d1 I_fup,
697  RandomAccessIterator3d1 I_back_bot,
698  const slip::Point3d<T>& grid_step,
699  slip::SPATIAL_DIRECTION der_dir,
700  const std::size_t der_order,
701  const std::size_t sch_order,
702  RandomAccessIterator3d2 R_fup,
703  RandomAccessIterator3d2 R_back_bot)
704  {
705  assert(sch_order >= der_order);
706  assert( ((der_dir == X_DIRECTION) && (int((I_back_bot-I_fup)[2]) > int(sch_order)))
707  ||((der_dir == Y_DIRECTION) && (int((I_back_bot-I_fup)[1]) > int(sch_order)))
708  ||((der_dir == Z_DIRECTION) && (int((I_back_bot-I_fup)[0]) > int(sch_order))));
709  assert((sch_order / 2) <= sch_order);
710  assert((R_back_bot - R_fup) == (I_back_bot-I_fup));
711  typedef typename RandomAccessIterator3d1::value_type value_type;
712  typedef typename RandomAccessIterator3d1::size_type size_type;
713  size_type sch_shift = sch_order / 2;
714 
715 
716  //computes all kernels
717  slip::Matrix<T> kernels(sch_order + 1, sch_order + 1);
718  std::vector<typename slip::Matrix<T>::iterator> kernels_iterators(sch_order + 1);
719  std::vector<typename slip::Matrix<T>::reverse_iterator> rkernels_iterators(sch_order + 1);
720  for(size_type i = 0; i < (sch_order + 1); ++i)
721  {
722  kernels_iterators[i] = kernels.row_begin(i);
723  rkernels_iterators[i] = kernels.row_rbegin(i);
724  }
725 
726  if(der_dir == X_DIRECTION)
727  {
728  slip::finite_diff_kernels(der_order,sch_order,sch_shift,
729  grid_step[0],
730  kernels_iterators);
731  const size_type rows = static_cast<std::size_t>((I_back_bot-I_fup)[1]);
732  const size_type slices = static_cast<std::size_t>((I_back_bot-I_fup)[0]);
733  for(size_type k = 0; k < slices; ++k)
734  {
735  for(size_type i = 0; i < rows; ++i)
736  {
737  slip::derivative(I_fup.row_begin(k,i),
738  I_fup.row_end(k,i),
739  der_order,
740  sch_order,
741  sch_shift,
742  kernels_iterators,
743  R_fup.row_begin(k,i));
744  }
745  }
746  }
747 
748  if(der_dir == Y_DIRECTION)
749  {
750  slip::finite_diff_kernels(der_order,sch_order,sch_shift,
751  grid_step[1],
752  kernels_iterators);
753  const size_type cols = static_cast<std::size_t>((I_back_bot-I_fup)[2]);
754  const size_type slices = static_cast<std::size_t>((I_back_bot-I_fup)[0]);
755 
756  for(size_type k = 0; k < slices; ++k)
757  {
758  for(size_type j = 0; j < cols; ++j)
759  {
760  slip::derivative(I_fup.col_begin(k,j),
761  I_fup.col_end(k,j),
762  der_order,
763  sch_order,
764  sch_shift,
765  rkernels_iterators,
766  R_fup.col_begin(k,j));
767  }
768  }
769  }
770  if(der_dir == Z_DIRECTION)
771  {
772  slip::finite_diff_kernels(der_order,sch_order,sch_shift,
773  grid_step[2],
774  kernels_iterators);
775  const size_type rows = static_cast<std::size_t>((I_back_bot-I_fup)[1]);
776  const size_type cols = static_cast<std::size_t>((I_back_bot-I_fup)[2]);
777 
778  for(size_type i = 0; i < rows; ++i)
779  {
780  for(size_type j = 0; j < cols; ++j)
781  {
782  slip::derivative(I_fup.slice_begin(i,j),
783  I_fup.slice_end(i,j),
784  der_order,
785  sch_order,
786  sch_shift,
787  rkernels_iterators,
788  R_fup.slice_begin(i,j));
789  }
790  }
791  }
792  }
793 
794 
825 {
830 };
831 
833 /* @{ */
834 
876 template<typename RandomAccessIterator4d1,
877 typename RandomAccessIterator4d2,
878 typename T>
879 inline
880 void derivative_4d(RandomAccessIterator4d1 I_ffup,
881  RandomAccessIterator4d1 I_last_back_bot,
882  const slip::Point4d<T>& grid_step,
883  slip::FOUR_DIM_DIRECTION der_dir,
884  const std::size_t der_order,
885  const std::size_t sch_order,
886  RandomAccessIterator4d2 R_ffup,
887  RandomAccessIterator4d2 R_last_back_bot)
888 {
889  assert(sch_order >= der_order);
890  assert( ((der_dir == T_DIRECTION) && (int((I_last_back_bot-I_ffup)[0]) > int(sch_order)))
891  ||((der_dir == S_DIRECTION) && (int((I_last_back_bot-I_ffup)[3]) > int(sch_order)))
892  ||((der_dir == R_DIRECTION) && (int((I_last_back_bot-I_ffup)[2]) > int(sch_order)))
893  ||((der_dir == C_DIRECTION) && (int((I_last_back_bot-I_ffup)[1]) > int(sch_order))));
894  assert((sch_order / 2) <= sch_order);
895  assert((R_last_back_bot - R_ffup) == (I_last_back_bot-I_ffup));
896  typedef typename RandomAccessIterator4d1::value_type value_type;
897  typedef typename RandomAccessIterator4d1::size_type size_type;
898  size_type sch_shift = sch_order / 2;
899 
900 
901  //computes all kernels
902  slip::Matrix<T> kernels(sch_order + 1, sch_order + 1);
903  std::vector<typename slip::Matrix<T>::iterator> kernels_iterators(sch_order + 1);
904  std::vector<typename slip::Matrix<T>::reverse_iterator> rkernels_iterators(sch_order + 1);
905  for(size_type i = 0; i < (sch_order + 1); ++i)
906  {
907  kernels_iterators[i] = kernels.row_begin(i);
908  rkernels_iterators[i] = kernels.row_rbegin(i);
909  }
910 
911  if(der_dir == T_DIRECTION)
912  {
913  slip::finite_diff_kernels(der_order,sch_order,sch_shift,
914  grid_step[0],
915  kernels_iterators);
916  const size_type rows = static_cast<std::size_t>((I_last_back_bot-I_ffup)[2]);
917  const size_type cols = static_cast<std::size_t>((I_last_back_bot-I_ffup)[3]);
918  const size_type slices = static_cast<std::size_t>((I_last_back_bot-I_ffup)[1]);
919  for(size_type k = 0; k < slices; ++k)
920  {
921  for(size_type i = 0; i < rows; ++i)
922  {
923  for(size_type j = 0; j < cols; ++j)
924  {
925  slip::derivative(I_ffup.slab_begin(k,i,j),
926  I_ffup.slab_end(k,i,j),
927  der_order,
928  sch_order,
929  sch_shift,
930  kernels_iterators,
931  R_ffup.slab_begin(k,i,j));
932  }
933  }
934  }
935  }
936 
937  if(der_dir == S_DIRECTION)
938  {
939  slip::finite_diff_kernels(der_order,sch_order,sch_shift,
940  grid_step[1],
941  kernels_iterators);
942  const size_type rows = static_cast<std::size_t>((I_last_back_bot-I_ffup)[2]);
943  const size_type slices = static_cast<std::size_t>((I_last_back_bot-I_ffup)[1]);
944  const size_type slabs = static_cast<std::size_t>((I_last_back_bot-I_ffup)[0]);
945  for(size_type t = 0; t < slabs; ++t)
946  {
947  for(size_type k = 0; k < slices; ++k)
948  {
949  for(size_type i = 0; i < rows; ++i)
950  {
951  slip::derivative(I_ffup.row_begin(t,k,i),
952  I_ffup.row_end(t,k,i),
953  der_order,
954  sch_order,
955  sch_shift,
956  kernels_iterators,
957  R_ffup.row_begin(t,k,i));
958  }
959  }
960  }
961  }
962 
963  if(der_dir == R_DIRECTION)
964  {
965  slip::finite_diff_kernels(der_order,sch_order,sch_shift,
966  grid_step[2],
967  kernels_iterators);
968  const size_type cols = static_cast<std::size_t>((I_last_back_bot-I_ffup)[3]);
969  const size_type slices = static_cast<std::size_t>((I_last_back_bot-I_ffup)[1]);
970  const size_type slabs = static_cast<std::size_t>((I_last_back_bot-I_ffup)[0]);
971  for(size_type t = 0; t < slabs; ++t)
972  {
973  for(size_type k = 0; k < slices; ++k)
974  {
975  for(size_type j = 0; j < cols; ++j)
976  {
977  slip::derivative(I_ffup.col_begin(t,k,j),
978  I_ffup.col_end(t,k,j),
979  der_order,
980  sch_order,
981  sch_shift,
982  rkernels_iterators,
983  R_ffup.col_begin(t,k,j));
984  }
985  }
986  }
987  }
988  if(der_dir == C_DIRECTION)
989  {
990  slip::finite_diff_kernels(der_order,sch_order,sch_shift,
991  grid_step[3],
992  kernels_iterators);
993  const size_type rows = static_cast<std::size_t>((I_last_back_bot-I_ffup)[2]);
994  const size_type cols = static_cast<std::size_t>((I_last_back_bot-I_ffup)[3]);
995  const size_type slabs = static_cast<std::size_t>((I_last_back_bot-I_ffup)[0]);
996  for(size_type t = 0; t < slabs; ++t)
997  {
998  for(size_type i = 0; i < rows; ++i)
999  {
1000  for(size_type j = 0; j < cols; ++j)
1001  {
1002  slip::derivative(I_ffup.slice_begin(t,i,j),
1003  I_ffup.slice_end(t,i,j),
1004  der_order,
1005  sch_order,
1006  sch_shift,
1007  rkernels_iterators,
1008  R_ffup.slice_begin(t,i,j));
1009  }
1010  }
1011  }
1012  }
1013 }
1014 
1015 
1016 
1017 
1018 /* @} */
1019 
1020 
1021  //----------------------------------------------------------
1022  // local derivatives
1023  //----------------------------------------------------------
1024 
1025 template<typename Real>
1026 inline
1027 Real minmod(const Real gplus, const Real gminus)
1028 {
1029  Real m = Real();
1030 
1031  if (gplus*gminus > Real())
1032  {
1033  Real absgplus = std::abs(gplus);
1034  Real absgminus = std::abs(gminus);
1035  m = std::min(absgplus,absgminus);
1036  m = m * m;
1037  }
1038  else
1039  {
1040  m = Real();
1041  }
1042  return m;
1043 }
1044 
1045 template<typename Real>
1046 inline
1047 Real max_brockett_maragos_plus(const Real gplus, const Real gminus)
1048 {
1049 
1050 Real max = std::max(gplus,-gminus);
1051 max = std::max(max,Real(0.0));
1052 return max * max;
1053 }
1054 
1055 template<typename Real>
1056 inline
1057 Real max_brockett_maragos_minus(const Real gplus, const Real gminus)
1058 {
1059 
1060  Real max = std::max(Real(0.0),gminus);
1061  max = std::max(max,gplus);
1062  return max * max;
1063 }
1064 
1065 
1066 template<typename Real>
1067 inline
1068 Real osher_sethian_plus(const Real gplus, const Real gminus)
1069 {
1070  Real max = std::max(gplus,Real(0.0));
1071  Real min = std::min(gminus,Real(0.0));
1072 
1073  max = max * max;
1074  min = min * min;
1075 
1076  return min + max;
1077 }
1078 
1079 template<typename Real>
1080 inline
1081 Real osher_sethian_minus(const Real gplus, const Real gminus)
1082 {
1083 
1084 
1085  Real max = std::max(gminus,Real(0.0));
1086  Real min = std::min(gplus,Real(0.0));
1087 
1088  max = max * max;
1089  min = min * min;
1090 
1091  return min + max;
1092 }
1093 
1094 //
1095 // dx local derivatives
1096 //
1097 template<typename Real,typename>
1098 struct __dx
1099 {
1100  template <typename _II>
1101  static Real
1102  dx(_II it)
1103  {
1104  Real left = *(it - 1);
1105  Real right = *(it + 1);
1106 
1107  return Real(0.5) * (right - left);
1108  }
1109 };
1110 
1111 template<typename Real>
1112 struct __dx<Real,std::random_access_iterator_tag>
1113 {
1114  template <typename _II>
1115  static Real
1116  dx(_II it)
1117  {
1118  Real left = *(it - 1);
1119  Real right = *(it + 1);
1120 
1121  return Real(0.5) * (right - left);
1122  }
1123 };
1124 
1125 template<typename Real>
1126 struct __dx<Real, std::random_access_iterator2d_tag>
1127 {
1128  template <typename _II>
1129  static Real
1130  dx(_II it)
1131  {
1132  Real left = it[slip::n_8c[4]];
1133  Real right = it[slip::n_8c[0]];
1134 
1135  return Real(0.5) * (right - left);
1136  }
1137 };
1138 
1139 template<typename Real>
1140 struct __dx<Real, std::random_access_iterator3d_tag>
1141 {
1142  template <typename _II>
1143  static Real
1144  dx(_II it)
1145  {
1146  Real left = it[slip::n_6c[3]];
1147  Real right = it[slip::n_6c[1]];
1148 
1149  return Real(0.5) * (right - left);
1150  }
1151 };
1152 
1159 template<typename Real>
1160 struct __dx<Real,std::random_access_iterator4d_tag>
1161 {
1162  template <typename _II>
1163  static Real
1164  dx(_II it)
1165  {
1166  Real left = it[slip::n_4d_8c[4]];
1167  Real right = it[slip::n_4d_8c[2]];
1168 
1169  return Real(0.5) * (right - left);
1170  }
1171 };
1172 
1173 
1174 template<typename Real> struct Dx
1175 {
1176 
1177  Dx(){}
1178  template<typename Iterator>
1179  Real operator() (Iterator& it) const
1180  {
1181  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
1182  return __dx<Real,_Category>::dx(it);
1183  }
1184 };
1185 
1186 
1187 
1188 //
1189 // dy local derivatives
1190 //
1191 template<typename Real,typename>
1192 struct __dy
1193 {
1194  template <typename _II>
1195  static Real
1196  dy(_II it)
1197  {
1198  Real left = *(it - 1);
1199  Real right = *(it + 1);
1200 
1201  return Real(0.5) * (right - left);
1202  }
1203 };
1204 
1205 template<typename Real>
1206 struct __dy<Real,std::random_access_iterator_tag>
1207 {
1208  template <typename _II>
1209  static Real
1210  dy(_II it)
1211  {
1212  return __dx<Real,std::random_access_iterator_tag>::dx(it);
1213  }
1214 };
1215 
1216 template<typename Real>
1217 struct __dy<Real, std::random_access_iterator2d_tag>
1218 {
1219  template <typename _II>
1220  static Real
1221  dy(_II it)
1222  {
1223  Real top = it[slip::n_8c[2]];
1224  Real bottom = it[slip::n_8c[6]];
1225 
1226  return Real(0.5) * (top - bottom);
1227  }
1228 };
1229 
1230 template<typename Real>
1231 struct __dy<Real, std::random_access_iterator3d_tag>
1232 {
1233  template <typename _II>
1234  static Real
1235  dy(_II it)
1236  {
1237  Real top = it[slip::n_6c[2]];
1238  Real bottom = it[slip::n_6c[4]];
1239 
1240  return Real(0.5) * (top - bottom);
1241  }
1242 };
1243 
1252 template<typename Real>
1253 struct __dy<Real, std::random_access_iterator4d_tag>
1254 {
1255  template <typename _II>
1256  static Real
1257  dy(_II it)
1258  {
1259  Real top = it[slip::n_4d_8c[3]];
1260  Real bottom = it[slip::n_4d_8c[5]];
1261 
1262  return Real(0.5) * (top - bottom);
1263  }
1264 };
1265 
1266 template<typename Real> struct Dy
1267 {
1268 
1269  Dy(){}
1270  template<typename Iterator>
1271  Real operator() (Iterator& it) const
1272  {
1273  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
1274  return __dy<Real,_Category>::dy(it);
1275  }
1276 };
1277 
1278 
1279 //
1280 // dz local derivatives
1281 //
1282 template<typename Real,typename>
1283 struct __dz
1284 {
1285  template <typename _II>
1286  static Real
1287  dz(_II it)
1288  {
1289  Real left = *(it - 1);
1290  Real right = *(it + 1);
1291 
1292  return Real(0.5) * (right - left);
1293  }
1294 };
1295 
1296 template<typename Real>
1297 struct __dz<Real,std::random_access_iterator_tag>
1298 {
1299  template <typename _II>
1300  static Real
1301  dz(_II it)
1302  {
1303  return __dx<Real,std::random_access_iterator_tag>::dx(it);
1304  }
1305 };
1306 
1307 template<typename Real>
1308 struct __dz<Real, std::random_access_iterator2d_tag>
1309 {
1310  template <typename _II>
1311  static Real
1312  dz(_II it)
1313  {
1314  Real top = it[slip::n_8c[5]];
1315  Real bottom = it[slip::n_8c[0]];
1316 
1317  return Real(0.5) * (top - bottom);
1318  }
1319 };
1320 
1321 template<typename Real>
1322 struct __dz<Real, std::random_access_iterator3d_tag>
1323 {
1324  template <typename _II>
1325  static Real
1326  dz(_II it)
1327  {
1328  Real top = it[slip::n_6c[0]];
1329  Real bottom = it[slip::n_6c[5]];
1330 
1331  return Real(0.5) * (top - bottom);
1332  }
1333 };
1334 
1344 template<typename Real>
1345 struct __dz<Real, std::random_access_iterator4d_tag>
1346 {
1347  template <typename _II>
1348  static Real
1349  dz(_II it)
1350  {
1351  Real top = it[slip::n_4d_8c[1]];
1352  Real bottom = it[slip::n_4d_8c[6]];
1353 
1354  return Real(0.5) * (top - bottom);
1355  }
1356 };
1357 
1358 
1359 template<typename Real> struct Dz
1360 {
1361 
1362  Dz(){}
1363  template<typename Iterator>
1364  Real operator() (Iterator& it) const
1365  {
1366  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
1367  return __dz<Real,_Category>::dz(it);
1368  }
1369 };
1370 
1371 
1378 template<typename Real,typename>
1379 struct __dt
1380 {
1381  template <typename _II>
1382  static Real
1383  dt(_II it)
1384  {
1385  Real prev = *(it - 1);
1386  Real next = *(it + 1);
1387 
1388  return Real(0.5) * (next - prev);
1389  }
1390 };
1391 
1392 template<typename Real>
1393 struct __dt<Real,std::random_access_iterator_tag>
1394 {
1395  template <typename _II>
1396  static Real
1397  dt(_II it)
1398  {
1399  return __dx<Real,std::random_access_iterator_tag>::dx(it);
1400  }
1401 };
1402 
1403 template<typename Real>
1404 struct __dt<Real, std::random_access_iterator2d_tag>
1405 {
1406  template <typename _II>
1407  static Real
1408  dt(_II it)
1409  {
1410  Real prev = it[slip::n_8c[5]];
1411  Real next = it[slip::n_8c[0]];
1412 
1413  return Real(next - prev);
1414  }
1415 };
1416 
1417 template<typename Real>
1418 struct __dt<Real, std::random_access_iterator3d_tag>
1419 {
1420  template <typename _II>
1421  static Real
1422  dt(_II it)
1423  {
1424  Real prev = it[slip::n_26c[5]];
1425  Real next = it[slip::n_26c[19]];
1426 
1427  return Real(next - prev);
1428  }
1429 };
1430 
1431 template<typename Real>
1432 struct __dt<Real, std::random_access_iterator4d_tag>
1433 {
1434  template <typename _II>
1435  static Real
1436  dt(_II it)
1437  {
1438  Real prev = it[slip::n_4d_8c[0]];
1439  Real next = it[slip::n_4d_8c[7]];
1440 
1441  return Real(0.5) * (next - prev);
1442  }
1443 };
1444 
1445 template<typename Real> struct Dt
1446 {
1447 
1448  Dt(){}
1449  template<typename Iterator>
1450  Real operator() (Iterator& it) const
1451  {
1452  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
1453  return __dt<Real,_Category>::dt(it);
1454  }
1455 };
1456 
1457 
1458 
1459 //
1460 // forward dx
1461 //
1462 template<typename Real,typename>
1463 struct __dx_fwd
1464 {
1465  template <typename _II>
1466  static Real
1467  dx_fwd(_II it)
1468  {
1469  Real center = *it;
1470  Real right = *(it + 1);
1471 
1472  return (right - center);
1473  }
1474 };
1475 
1476 template<typename Real>
1477 struct __dx_fwd<Real,std::random_access_iterator_tag>
1478 {
1479  template <typename _II>
1480  static Real
1481  dx_fwd(_II it)
1482  {
1483  Real center = *it;
1484  Real right = *(it + 1);
1485 
1486  return (right - center);
1487 
1488  }
1489 };
1490 
1491 template<typename Real>
1492 struct __dx_fwd<Real, std::random_access_iterator2d_tag>
1493 {
1494  template <typename _II>
1495  static Real
1496  dx_fwd(_II it)
1497  {
1498  Real center = *it;
1499  Real right = it[slip::n_8c[0]];
1500 
1501  return (right - center);
1502  }
1503 };
1504 
1505 template<typename Real>
1506 struct __dx_fwd<Real, std::random_access_iterator3d_tag>
1507 {
1508  template <typename _II>
1509  static Real
1510  dx_fwd(_II it)
1511  {
1512  Real center = *it;
1513  Real right = it[slip::n_6c[1]];
1514 
1515  return (right - center);
1516  }
1517 };
1518 
1526 template<typename Real>
1527 struct __dx_fwd<Real, std::random_access_iterator4d_tag>
1528 {
1529  template <typename _II>
1530  static Real
1531  dx_fwd(_II it)
1532  {
1533  Real center = *it;
1534  Real right = it[slip::n_4d_8c[2]];
1535 
1536  return (right - center);
1537  }
1538 };
1539 
1540 
1541 template<typename Real> struct DxFwd
1542 {
1543 
1544  DxFwd(){}
1545  template<typename Iterator>
1546  Real operator() (Iterator& it) const
1547  {
1548  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
1549  return __dx_fwd<Real,_Category>::dx_fwd(it);
1550  }
1551 };
1552 
1553 //
1554 // forward dy
1555 //
1556 template<typename Real,typename>
1557 struct __dy_fwd
1558 {
1559  template <typename _II>
1560  static Real
1561  dy_fwd(_II it)
1562  {
1563  Real center = *it;
1564  Real right = *(it + 1);
1565 
1566  return (right - center);
1567  }
1568 };
1569 
1570 template<typename Real>
1571 struct __dy_fwd<Real,std::random_access_iterator_tag>
1572 {
1573  template <typename _II>
1574  static Real
1575  dy_fwd(_II it)
1576  {
1577  return __dx_fwd<Real,std::random_access_iterator_tag>::dx_fwd(it);
1578  }
1579 };
1580 
1581 template<typename Real>
1582 struct __dy_fwd<Real, std::random_access_iterator2d_tag>
1583 {
1584  template <typename _II>
1585  static Real
1586  dy_fwd(_II it)
1587  {
1588  Real top = it[slip::n_8c[2]];
1589  Real center = *it;
1590 
1591  return (top - center);
1592  }
1593 };
1594 
1595 template<typename Real>
1596 struct __dy_fwd<Real, std::random_access_iterator3d_tag>
1597 {
1598  template <typename _II>
1599  static Real
1600  dy_fwd(_II it)
1601  {
1602  Real top = it[slip::n_6c[2]];
1603  Real center = *it;
1604 
1605  return (top - center);
1606  }
1607 };
1608 
1616 template<typename Real>
1617 struct __dy_fwd<Real, std::random_access_iterator4d_tag>
1618 {
1619  template <typename _II>
1620  static Real
1621  dy_fwd(_II it)
1622  {
1623  Real top = it[slip::n_4d_8c[3]];
1624  Real center = *it;
1625 
1626  return (top - center);
1627  }
1628 };
1629 
1630 
1631 template<typename Real> struct DyFwd
1632 {
1633 
1634  DyFwd(){}
1635  template<typename Iterator>
1636  Real operator() (Iterator& it) const
1637  {
1638  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
1639  return __dy_fwd<Real,_Category>::dy_fwd(it);
1640  }
1641 };
1642 
1643 //
1644 // dz forward
1645 //
1646 template<typename Real,typename>
1647 struct __dz_fwd
1648 {
1649  template <typename _II>
1650  static Real
1651  dz_fwd(_II it)
1652  {
1653  Real center = *it;
1654  Real right = *(it + 1);
1655 
1656  return (right - center);
1657  }
1658 };
1659 
1660 template<typename Real>
1661 struct __dz_fwd<Real,std::random_access_iterator_tag>
1662 {
1663  template <typename _II>
1664  static Real
1665  dz_fwd(_II it)
1666  {
1667  return __dx_fwd<Real,std::random_access_iterator_tag>::dx_fwd(it);
1668  }
1669 };
1670 
1671 template<typename Real>
1672 struct __dz_fwd<Real, std::random_access_iterator2d_tag>
1673 {
1674  template <typename _II>
1675  static Real
1676  dz_fwd(_II it)
1677  {
1678  Real top = it[slip::n_8c[5]];
1679  Real center = *it;
1680 
1681  return (top - center);
1682  }
1683 };
1684 
1685 template<typename Real>
1686 struct __dz_fwd<Real, std::random_access_iterator3d_tag>
1687 {
1688  template <typename _II>
1689  static Real
1690  dz_fwd(_II it)
1691  {
1692  Real top = it[slip::n_6c[0]];
1693  Real center = *it;
1694 
1695  return (top - center);
1696  }
1697 };
1698 
1706 template<typename Real>
1707 struct __dz_fwd<Real, std::random_access_iterator4d_tag>
1708 {
1709  template <typename _II>
1710  static Real
1711  dz_fwd(_II it)
1712  {
1713  Real top = it[slip::n_4d_8c[1]];
1714  Real center = *it;
1715 
1716  return (top - center);
1717  }
1718 };
1719 
1720 template<typename Real> struct DzFwd
1721 {
1722 
1723  DzFwd(){}
1724  template<typename Iterator>
1725  Real operator() (Iterator& it) const
1726  {
1727  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
1728  return __dz_fwd<Real,_Category>::dz_fwd(it);
1729  }
1730 };
1731 
1732 
1740 template<typename Real,typename>
1741 struct __dt_fwd
1742 {
1743  template <typename _II>
1744  static Real
1745  dt_fwd(_II it)
1746  {
1747  Real center = *it;
1748  Real next = *(it + 1);
1749 
1750  return (next - center);
1751  }
1752 };
1753 
1754 template<typename Real>
1755 struct __dt_fwd<Real,std::random_access_iterator_tag>
1756 {
1757  template <typename _II>
1758  static Real
1759  dt_fwd(_II it)
1760  {
1761  return __dx_fwd<Real,std::random_access_iterator_tag>::dx_fwd(it);
1762  }
1763 };
1764 
1765 template<typename Real>
1766 struct __dt_fwd<Real, std::random_access_iterator2d_tag>
1767 {
1768  template <typename _II>
1769  static Real
1770  dt_fwd(_II it)
1771  {
1772  Real center = *it;
1773  Real next = it[slip::n_8c[0]];
1774 
1775  return Real (next - center);
1776  }
1777 };
1778 
1779 template<typename Real>
1780 struct __dt_fwd<Real, std::random_access_iterator3d_tag>
1781 {
1782  template <typename _II>
1783  static Real
1784  dt_fwd(_II it)
1785  {
1786  Real center = *it;
1787  Real next = it[slip::n_26c[19]];
1788 
1789  return Real (next - center);
1790  }
1791 };
1792 
1793 template<typename Real>
1794 struct __dt_fwd<Real, std::random_access_iterator4d_tag>
1795 {
1796  template <typename _II>
1797  static Real
1798  dt_fwd(_II it)
1799  {
1800  Real next = it[slip::n_4d_8c[7]];
1801  Real center = *it;
1802 
1803  return (next - center);
1804  }
1805 };
1806 
1807 template<typename Real> struct DtFwd
1808 {
1809 
1810  DtFwd(){}
1811  template<typename Iterator>
1812  Real operator() (Iterator& it) const
1813  {
1814  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
1815  return __dt_fwd<Real,_Category>::dt_fwd(it);
1816  }
1817 };
1818 
1819 //
1820 // backward dx
1821 //
1822 template<typename Real,typename>
1823 struct __dx_bck
1824 {
1825  template <typename _II>
1826  static Real
1827  dx_bck(_II it)
1828  {
1829  Real left = *(it - 1);
1830  Real center = *it;
1831 
1832  return (center - left);
1833  }
1834 };
1835 
1836 template<typename Real>
1837 struct __dx_bck<Real,std::random_access_iterator_tag>
1838 {
1839  template <typename _II>
1840  static Real
1841  dx_bck(_II it)
1842  {
1843  Real left = *(it - 1);
1844  Real center = *it;
1845 
1846  return (center - left);
1847  }
1848 };
1849 
1850 template<typename Real>
1851 struct __dx_bck<Real, std::random_access_iterator2d_tag>
1852 {
1853  template <typename _II>
1854  static Real
1855  dx_bck(_II it)
1856  {
1857  Real left = it[slip::n_8c[4]];
1858  Real center = *it;
1859 
1860  return (center - left);
1861  }
1862 };
1863 
1864 template<typename Real>
1865 struct __dx_bck<Real, std::random_access_iterator3d_tag>
1866 {
1867  template <typename _II>
1868  static Real
1869  dx_bck(_II it)
1870  {
1871  Real left = it[slip::n_6c[3]];
1872  Real center = *it;
1873 
1874  return (center - left);
1875  }
1876 };
1877 
1878 
1886 template<typename Real>
1887 struct __dx_bck<Real, std::random_access_iterator4d_tag>
1888 {
1889  template <typename _II>
1890  static Real
1891  dx_bck(_II it)
1892  {
1893  Real left = it[slip::n_4d_8c[4]];
1894  Real center = *it;
1895 
1896  return (center - left);
1897  }
1898 };
1899 
1900 
1901 template<typename Real> struct DxBck
1902 {
1903 
1904  DxBck(){}
1905  template<typename Iterator>
1906  Real operator() (Iterator& it) const
1907  {
1908  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
1909  return __dx_bck<Real,_Category>::dx_bck(it);
1910  }
1911 };
1912 
1913 //
1914 // Backward dy
1915 //
1916 template<typename Real,typename>
1917 struct __dy_bck
1918 {
1919  template <typename _II>
1920  static Real
1921  dy_bck(_II it)
1922  {
1923  Real left = *(it - 1);
1924  Real center = *it;
1925 
1926  return (center - left);
1927  }
1928 };
1929 
1930 template<typename Real>
1931 struct __dy_bck<Real,std::random_access_iterator_tag>
1932 {
1933  template <typename _II>
1934  static Real
1935  dy_bck(_II it)
1936  {
1937  return __dx_bck<Real,std::random_access_iterator_tag>::dx_bck(it);
1938  }
1939 };
1940 
1941 template<typename Real>
1942 struct __dy_bck<Real, std::random_access_iterator2d_tag>
1943 {
1944  template <typename _II>
1945  static Real
1946  dy_bck(_II it)
1947  {
1948  Real center = *it;
1949  Real bottom = it[slip::n_8c[6]];
1950 
1951  return (center - bottom);
1952  }
1953 };
1954 
1955 template<typename Real>
1956 struct __dy_bck<Real, std::random_access_iterator3d_tag>
1957 {
1958  template <typename _II>
1959  static Real
1960  dy_bck(_II it)
1961  {
1962  Real center = *it;
1963  Real bottom = it[slip::n_6c[4]];
1964 
1965  return Real(0.5) * (center - bottom);
1966  }
1967 };
1968 
1977 template<typename Real>
1978 struct __dy_bck<Real, std::random_access_iterator4d_tag>
1979 {
1980  template <typename _II>
1981  static Real
1982  dy_bck(_II it)
1983  {
1984  Real center = *it;
1985  Real bottom = it[slip::n_4d_8c[5]];
1986 
1987  return (center - bottom);
1988  }
1989 };
1990 
1991 
1992 template<typename Real> struct DyBck
1993 {
1994 
1995  DyBck(){}
1996  template<typename Iterator>
1997  Real operator() (Iterator& it) const
1998  {
1999  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
2000  return __dy_bck<Real,_Category>::dy_bck(it);
2001  }
2002 };
2003 
2004 //
2005 // Backward dz
2006 //
2007 
2008 template<typename Real,typename>
2009 struct __dz_bck
2010 {
2011  template <typename _II>
2012  static Real
2013  dz_bck(_II it)
2014  {
2015  Real left = *(it - 1);
2016  Real center = *it;
2017 
2018  return (left - center);
2019  }
2020 };
2021 
2022 template<typename Real>
2023 struct __dz_bck<Real,std::random_access_iterator_tag>
2024 {
2025  template <typename _II>
2026  static Real
2027  dz_bck(_II it)
2028  {
2029  return __dx_bck<Real,std::random_access_iterator_tag>::dx_bck(it);
2030  }
2031 };
2032 
2033 template<typename Real>
2034 struct __dz_bck<Real, std::random_access_iterator2d_tag>
2035 {
2036  template <typename _II>
2037  static Real
2038  dz_bck(_II it)
2039  {
2040  Real center = *it;
2041  Real bottom = it[slip::n_8c[0]];
2042 
2043  return (center - bottom);
2044  }
2045 };
2046 
2047 template<typename Real>
2048 struct __dz_bck<Real, std::random_access_iterator3d_tag>
2049 {
2050  template <typename _II>
2051  static Real
2052  dz_bck(_II it)
2053  {
2054  Real center = *it;
2055  Real bottom = it[slip::n_6c[5]];
2056 
2057  return (center - bottom);
2058  }
2059 };
2060 
2061 
2070 template<typename Real>
2071 struct __dz_bck<Real, std::random_access_iterator4d_tag>
2072 {
2073  template <typename _II>
2074  static Real
2075  dz_bck(_II it)
2076  {
2077  Real center = *it;
2078  Real bottom = it[slip::n_4d_8c[6]];
2079 
2080  return (center - bottom);
2081  }
2082 };
2083 
2084 template<typename Real> struct DzBck
2085 {
2086 
2087  DzBck(){}
2088  template<typename Iterator>
2089  Real operator() (Iterator& it) const
2090  {
2091  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
2092  return __dz_bck<Real,_Category>::dz_bck(it);
2093  }
2094 };
2095 
2096 
2105 template<typename Real,typename>
2106 struct __dt_bck
2107 {
2108  template <typename _II>
2109  static Real
2110  dt_bck(_II it)
2111  {
2112  Real prev = *(it - 1);
2113  Real center = *it;
2114 
2115  return (center - prev);
2116  }
2117 };
2118 
2119 template<typename Real>
2120 struct __dt_bck<Real,std::random_access_iterator_tag>
2121 {
2122  template <typename _II>
2123  static Real
2124  dt_bck(_II it)
2125  {
2126  return __dx_bck<Real,std::random_access_iterator_tag>::dx_bck(it);
2127  }
2128 };
2129 
2130 template<typename Real>
2131 struct __dt_bck<Real, std::random_access_iterator2d_tag>
2132 {
2133  template <typename _II>
2134  static Real
2135  dt_bck(_II it)
2136  {
2137  Real center = *it;
2138  Real prev = it[slip::n_8c[5]];
2139 
2140  return (center - prev);
2141  }
2142 };
2143 
2144 template<typename Real>
2145 struct __dt_bck<Real, std::random_access_iterator3d_tag>
2146 {
2147  template <typename _II>
2148  static Real
2149  dt_bck(_II it)
2150  {
2151  Real center = *it;
2152  Real prev = it[slip::n_26c[5]];
2153 
2154  return (center - prev);
2155  }
2156 };
2157 
2158 template<typename Real>
2159 struct __dt_bck<Real, std::random_access_iterator4d_tag>
2160 {
2161  template <typename _II>
2162  static Real
2163  dt_bck(_II it)
2164  {
2165  Real center = *it;
2166  Real prev = it[slip::n_4d_8c[0]];
2167 
2168  return (center - prev);
2169  }
2170 };
2171 
2172 template<typename Real> struct DtBck
2173 {
2174 
2175  DtBck(){}
2176  template<typename Iterator>
2177  Real operator() (Iterator& it) const
2178  {
2179  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
2180  return __dt_bck<Real,_Category>::dt_bck(it);
2181  }
2182 };
2183 
2184 
2185 //
2186 // Prewittx
2187 //
2188 template<typename Real,typename>
2189 struct __prewittx
2190 {
2191  template <typename _II>
2192  static Real
2193  prewittx(_II it)
2194  {
2195  return __dx<Real,std::random_access_iterator_tag>::dx(it);
2196  }
2197 };
2198 
2199 template<typename Real>
2200 struct __prewittx<Real,std::random_access_iterator_tag>
2201 {
2202  template <typename _II>
2203  static Real
2204  prewittx(_II it)
2205  {
2206  return __dx<Real,std::random_access_iterator_tag>::dx(it);
2207  }
2208 };
2209 
2210 template<typename Real>
2211 struct __prewittx<Real, std::random_access_iterator2d_tag>
2212 {
2213  template <typename _II>
2214  static Real
2215  prewittx(_II it)
2216  {
2217 
2218  Real NE = it[slip::n_8c[1]];
2219  Real E = it[slip::n_8c[0]];
2220  Real NW = it[slip::n_8c[3]];
2221  Real W = it[slip::n_8c[4]];
2222  Real SE = it[slip::n_8c[7]];
2223  Real SW = it[slip::n_8c[5]];
2224 
2225  return Real(0.5) * (((NE - NW) + (E - W)) + (SE - SW));
2226  }
2227 };
2228 
2229 template<typename Real>
2230 struct __prewittx<Real, std::random_access_iterator3d_tag>
2231 {
2232  template <typename _II>
2233  static Real
2234  prewittx(_II it)
2235  {
2236  //right
2237  Real RE = it[slip::n_26c[1]];
2238  Real RNE = it[slip::n_26c[2]];
2239  Real RN = it[slip::n_26c[10]];
2240  Real RNW = it[slip::n_26c[19]];
2241  Real RW = it[slip::n_26c[18]];
2242  Real RSW = it[slip::n_26c[17]];
2243  Real RS = it[slip::n_26c[25]];
2244  Real RSE = it[slip::n_26c[8]];
2245  Real S_RC = it[slip::n_26c[9]];
2246 
2247  //left
2248  Real LE = it[slip::n_26c[5]];
2249  Real LNE = it[slip::n_26c[4]];
2250  Real LN = it[slip::n_26c[12]];
2251  Real LNW = it[slip::n_26c[21]];
2252  Real LW = it[slip::n_26c[14]];
2253  Real LSW = it[slip::n_26c[15]];
2254  Real LS = it[slip::n_26c[23]];
2255  Real LSE = it[slip::n_26c[6]];
2256  Real LC = it[slip::n_26c[22]];
2257 
2258  return Real(0.5) * ((RE - LE) + (RNE - LNE) + (RN - LN)
2259  + (RNW - LNW)+ (RW - LW) + (RSW - LSW)
2260  + (RS - LS) + (RSE - LSE) + (S_RC - LC));
2261  }
2262 };
2263 
2264 template<typename Real> struct Prewittx
2265 {
2266 
2268  template<typename Iterator>
2269  Real operator() (Iterator& it) const
2270  {
2271  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
2272  return __prewittx<Real,_Category>::prewittx(it);
2273  }
2274 };
2275 
2276 //
2277 // Prewitty
2278 //
2279 template<typename Real,typename>
2280 struct __prewitty
2281 {
2282  template <typename _II>
2283  static Real
2284  prewitty(_II it)
2285  {
2286  return __dx<Real,std::random_access_iterator_tag>::dx(it);
2287  }
2288 };
2289 
2290 template<typename Real>
2291 struct __prewitty<Real,std::random_access_iterator_tag>
2292 {
2293  template <typename _II>
2294  static Real
2295  prewitty(_II it)
2296  {
2297  return __dx<Real,std::random_access_iterator_tag>::dx(it);
2298  }
2299 };
2300 
2301 template<typename Real>
2302 struct __prewitty<Real, std::random_access_iterator2d_tag>
2303 {
2304  template <typename _II>
2305  static Real
2306  prewitty(_II it)
2307  {
2308 
2309  Real NE = it[slip::n_8c[1]];
2310  Real N = it[slip::n_8c[2]];
2311  Real NW = it[slip::n_8c[3]];
2312  Real S = it[slip::n_8c[6]];
2313  Real SE = it[slip::n_8c[7]];
2314  Real SW = it[slip::n_8c[5]];
2315 
2316  return Real(0.5) * (((NE - SE) + (N - S)) + (NW - SW));
2317  }
2318 };
2319 
2320 template<typename Real>
2321 struct __prewitty<Real, std::random_access_iterator3d_tag>
2322 {
2323  template <typename _II>
2324  static Real
2325  prewitty(_II it)
2326  {
2327  //top
2328  Real TE = it[slip::n_26c[10]];
2329  Real TNE = it[slip::n_26c[2]];
2330  Real TN = it[slip::n_26c[3]];
2331  Real TNW = it[slip::n_26c[4]];
2332  Real TW = it[slip::n_26c[12]];
2333  Real TSW = it[slip::n_26c[21]];
2334  Real TS = it[slip::n_26c[20]];
2335  Real TSE = it[slip::n_26c[19]];
2336  Real TC = it[slip::n_26c[11]];
2337 
2338  //bottom
2339  Real BE = it[slip::n_26c[25]];
2340  Real BNE = it[slip::n_26c[8]];
2341  Real BN = it[slip::n_26c[7]];
2342  Real BNW = it[slip::n_26c[6]];
2343  Real BW = it[slip::n_26c[23]];
2344  Real BSW = it[slip::n_26c[15]];
2345  Real BS = it[slip::n_26c[16]];
2346  Real BSE = it[slip::n_26c[17]];
2347  Real S_BC = it[slip::n_26c[24]];
2348 
2349  return Real(0.5) * ((TE - BE) + (TNE - BNE) + (TN - BN)
2350  + (TNW - BNW)+ (TW - BW) + (TSW - BSW)
2351  + (TS - BS) + (TSE - BSE) + (TC - S_BC));
2352  }
2353 };
2354 
2355 template<typename Real> struct Prewitty
2356 {
2357 
2359  template<typename Iterator>
2360  Real operator() (Iterator& it) const
2361  {
2362  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
2363  return __prewitty<Real,_Category>::prewitty(it);
2364  }
2365 };
2366 
2367 //
2368 // Prewittz
2369 //
2370 template<typename Real,typename>
2371 struct __prewittz
2372 {
2373  template <typename _II>
2374  static Real
2375  prewittz(_II it)
2376  {
2377  return __dx<Real,std::random_access_iterator_tag>::dx(it);
2378  }
2379 };
2380 
2381 template<typename Real>
2382 struct __prewittz<Real,std::random_access_iterator_tag>
2383 {
2384  template <typename _II>
2385  static Real
2386  prewittz(_II it)
2387  {
2388  return __dx<Real,std::random_access_iterator_tag>::dx(it);
2389  }
2390 };
2391 
2392 
2393 template<typename Real>
2394 struct __prewittz<Real, std::random_access_iterator3d_tag>
2395 {
2396  template <typename _II>
2397  static Real
2398  prewittz(_II it)
2399  {
2400  //front
2401  Real FE = it[slip::n_26c[5]];
2402  Real FNE = it[slip::n_26c[4]];
2403  Real FN = it[slip::n_26c[3]];
2404  Real FNW = it[slip::n_26c[2]];
2405  Real FW = it[slip::n_26c[1]];
2406  Real FSW = it[slip::n_26c[8]];
2407  Real FS = it[slip::n_26c[7]];
2408  Real FSE = it[slip::n_26c[6]];
2409  Real FC = it[slip::n_26c[0]];
2410 
2411  //back
2412  Real BE = it[slip::n_26c[14]];
2413  Real BNE = it[slip::n_26c[21]];
2414  Real BN = it[slip::n_26c[20]];
2415  Real BNW = it[slip::n_26c[19]];
2416  Real BW = it[slip::n_26c[18]];
2417  Real BSW = it[slip::n_26c[17]];
2418  Real BS = it[slip::n_26c[16]];
2419  Real BSE = it[slip::n_26c[15]];
2420  Real S_BC = it[slip::n_26c[13]];
2421 
2422  return Real(0.5) * ((FE - BE) + (FNE - BNE) + (FN - BN)
2423  + (FNW - BNW)+ (FW - BW) + (FSW - BSW)
2424  + (FS - BS) + (FSE - BSE) + (FC - S_BC));
2425  }
2426 };
2427 
2428 template<typename Real> struct Prewittz
2429 {
2430 
2432  template<typename Iterator>
2433  Real operator() (Iterator& it) const
2434  {
2435  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
2436  return __prewittz<Real,_Category>::prewittz(it);
2437  }
2438 };
2439 
2440 //
2441 // Sobelx
2442 //
2443 template<typename Real,typename>
2444 struct __sobelx
2445 {
2446  template <typename _II>
2447  static Real
2448  sobelx(_II it)
2449  {
2450  return __dx<Real,std::random_access_iterator_tag>::dx(it);
2451  }
2452 };
2453 
2454 template<typename Real>
2455 struct __sobelx<Real,std::random_access_iterator_tag>
2456 {
2457  template <typename _II>
2458  static Real
2459  sobelx(_II it)
2460  {
2461  return __dx<Real,std::random_access_iterator_tag>::dx(it);
2462  }
2463 };
2464 
2465 template<typename Real>
2466 struct __sobelx<Real, std::random_access_iterator2d_tag>
2467 {
2468  template <typename _II>
2469  static Real
2470  sobelx(_II it)
2471  {
2472 
2473  Real NE = it[slip::n_8c[1]];
2474  Real E = it[slip::n_8c[0]];
2475  Real NW = it[slip::n_8c[3]];
2476  Real W = it[slip::n_8c[4]];
2477  Real SE = it[slip::n_8c[7]];
2478  Real SW = it[slip::n_8c[5]];
2479 
2480  return Real(0.5) * (((NE - NW) + Real(2.0) * (E - W)) + (SE - SW));
2481  }
2482 };
2483 
2484 template<typename Real>
2485 struct __sobelx<Real, std::random_access_iterator3d_tag>
2486 {
2487  template <typename _II>
2488  static Real
2489  sobelx(_II it)
2490  {
2491  //right
2492  Real RE = it[slip::n_26c[1]];
2493  Real RNE = it[slip::n_26c[2]];
2494  Real RN = it[slip::n_26c[10]];
2495  Real RNW = it[slip::n_26c[19]];
2496  Real RW = it[slip::n_26c[18]];
2497  Real RSW = it[slip::n_26c[17]];
2498  Real RS = it[slip::n_26c[25]];
2499  Real RSE = it[slip::n_26c[8]];
2500  Real S_RC = it[slip::n_26c[9]];
2501 
2502  //left
2503  Real LE = it[slip::n_26c[5]];
2504  Real LNE = it[slip::n_26c[4]];
2505  Real LN = it[slip::n_26c[12]];
2506  Real LNW = it[slip::n_26c[21]];
2507  Real LW = it[slip::n_26c[14]];
2508  Real LSW = it[slip::n_26c[15]];
2509  Real LS = it[slip::n_26c[23]];
2510  Real LSE = it[slip::n_26c[6]];
2511  Real LC = it[slip::n_26c[22]];
2512 
2513  return (Real(2.0) * (RE - LE) + (RNE - LNE) + Real(2.0) * (RN - LN)
2514  + (RNW - LNW) + Real(2.0) * (RW - LW) + (RSW - LSW) + Real(2.0) * (RS - LS) + (RSE - LSE)+ Real(4.0) * (S_RC - LC));
2515  }
2516 };
2517 
2518 template<typename Real> struct Sobelx
2519 {
2520 
2522  template<typename Iterator>
2523  Real operator() (Iterator& it) const
2524  {
2525  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
2526  return __sobelx<Real,_Category>::sobelx(it);
2527  }
2528 };
2529 
2530 
2531 //
2532 // Sobely
2533 //
2534 template<typename Real,typename>
2535 struct __sobely
2536 {
2537  template <typename _II>
2538  static Real
2539  sobely(_II it)
2540  {
2541  return __dx<Real,std::random_access_iterator_tag>::dx(it);
2542  }
2543 };
2544 
2545 template<typename Real>
2546 struct __sobely<Real,std::random_access_iterator_tag>
2547 {
2548  template <typename _II>
2549  static Real
2550  sobely(_II it)
2551  {
2552  return __dx<Real,std::random_access_iterator_tag>::dx(it);
2553  }
2554 };
2555 
2556 template<typename Real>
2557 struct __sobely<Real, std::random_access_iterator2d_tag>
2558 {
2559  template <typename _II>
2560  static Real
2561  sobely(_II it)
2562  {
2563 
2564  Real NE = it[slip::n_8c[1]];
2565  Real N = it[slip::n_8c[2]];
2566  Real NW = it[slip::n_8c[3]];
2567  Real S = it[slip::n_8c[6]];
2568  Real SE = it[slip::n_8c[7]];
2569  Real SW = it[slip::n_8c[5]];
2570 
2571  return Real(0.5) * (((NE - SE) + Real(2.0) * (N - S)) + (NW - SW));
2572  }
2573 };
2574 
2575 template<typename Real>
2576 struct __sobely<Real, std::random_access_iterator3d_tag>
2577 {
2578  template <typename _II>
2579  static Real
2580  sobely(_II it)
2581  {
2582  //top
2583  Real TE = it[slip::n_26c[10]];
2584  Real TNE = it[slip::n_26c[2]];
2585  Real TN = it[slip::n_26c[3]];
2586  Real TNW = it[slip::n_26c[4]];
2587  Real TW = it[slip::n_26c[12]];
2588  Real TSW = it[slip::n_26c[21]];
2589  Real TS = it[slip::n_26c[20]];
2590  Real TSE = it[slip::n_26c[19]];
2591  Real TC = it[slip::n_26c[11]];
2592 
2593  //bottom
2594  Real BE = it[slip::n_26c[25]];
2595  Real BNE = it[slip::n_26c[8]];
2596  Real BN = it[slip::n_26c[7]];
2597  Real BNW = it[slip::n_26c[6]];
2598  Real BW = it[slip::n_26c[23]];
2599  Real BSW = it[slip::n_26c[15]];
2600  Real BS = it[slip::n_26c[16]];
2601  Real BSE = it[slip::n_26c[17]];
2602  Real S_BC = it[slip::n_26c[24]];
2603 
2604  return (Real(2.0) * (TE - BE) + (TNE - BNE) + Real(2.0) * (TN - BN)
2605  + (TNW - BNW) + Real(2.0) * (TW - BW) + (TSW - BSW) + Real(2.0) * (TS - BS) + (TSE - BSE)+ Real(4.0) * (TC - S_BC));
2606  }
2607 };
2608 
2609 template<typename Real> struct Sobely
2610 {
2611 
2613  template<typename Iterator>
2614  Real operator() (Iterator& it) const
2615  {
2616  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
2617  return __sobely<Real,_Category>::sobely(it);
2618  }
2619 };
2620 
2621 //
2622 // Sobelz
2623 //
2624 template<typename Real,typename>
2625 struct __sobelz
2626 {
2627  template <typename _II>
2628  static Real
2629  sobelz(_II it)
2630  {
2631  return __dx<Real,std::random_access_iterator_tag>::dx(it);
2632  }
2633 };
2634 
2635 template<typename Real>
2636 struct __sobelz<Real,std::random_access_iterator_tag>
2637 {
2638  template <typename _II>
2639  static Real
2640  sobelz(_II it)
2641  {
2642  return __dx<Real,std::random_access_iterator_tag>::dx(it);
2643  }
2644 };
2645 
2646 
2647 
2648 template<typename Real>
2649 struct __sobelz<Real, std::random_access_iterator3d_tag>
2650 {
2651  template <typename _II>
2652  static Real
2653  sobelz(_II it)
2654  {
2655 
2656  //front
2657  Real FE = it[slip::n_26c[5]];
2658  Real FNE = it[slip::n_26c[4]];
2659  Real FN = it[slip::n_26c[3]];
2660  Real FNW = it[slip::n_26c[2]];
2661  Real FW = it[slip::n_26c[1]];
2662  Real FSW = it[slip::n_26c[8]];
2663  Real FS = it[slip::n_26c[7]];
2664  Real FSE = it[slip::n_26c[6]];
2665  Real FC = it[slip::n_26c[0]];
2666 
2667  //back
2668  Real BE = it[slip::n_26c[14]];
2669  Real BNE = it[slip::n_26c[21]];
2670  Real BN = it[slip::n_26c[20]];
2671  Real BNW = it[slip::n_26c[19]];
2672  Real BW = it[slip::n_26c[18]];
2673  Real BSW = it[slip::n_26c[17]];
2674  Real BS = it[slip::n_26c[16]];
2675  Real BSE = it[slip::n_26c[15]];
2676  Real S_BC = it[slip::n_26c[13]];
2677 
2678  return (Real(2.0) * (FE - BE) + (FNE - BNE) + Real(2.0) * (FN - BN)
2679  + (FNW - BNW) + Real(2.0) * (FW - BW) + (FSW - BSW) + Real(2.0) * (FS - BS) + (FSE - BSE)+ Real(4.0) * (FC - S_BC));
2680  }
2681 };
2682 
2683 template<typename Real> struct Sobelz
2684 {
2685 
2687  template<typename Iterator>
2688  Real operator() (Iterator& it) const
2689  {
2690  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
2691  return __sobelz<Real,_Category>::sobelz(it);
2692  }
2693 };
2694 
2695 //
2696 //dv first derivative in the direction of v
2697 //
2698 template<typename Real,typename>
2699 struct __dv
2700 {
2701  template <typename _II, typename Block>
2702  static Real
2703  dv(_II it, Block v)
2704  {
2705  assert(Block::SIZE == 1);
2706  Real dx = __dx<Real,std::random_access_iterator_tag>::dx(it);
2707  if(v[0] < Real(0))
2708  {
2709  dx = -dx;
2710  }
2711  return dx;
2712  }
2713 };
2714 
2715 template<typename Real>
2716 struct __dv<Real,std::random_access_iterator_tag>
2717 {
2718  template <typename _II, typename Block>
2719  static Real
2720  dv(_II it, Block v)
2721  {
2722  assert(Block::SIZE == 1);
2723  return __dv<Real,std::random_access_iterator_tag>::dv(it,v);
2724  }
2725 };
2726 
2727 template<typename Real>
2728 struct __dv<Real, std::random_access_iterator2d_tag>
2729 {
2730  template <typename _II, typename Block>
2731  static Real
2732  dv(_II it, Block v)
2733  {
2734  assert(Block::SIZE == 2);
2735  Real result = Real(0);
2736  Real norm = slip::Euclidean_norm<Real>(v.begin(),v.end());
2737 
2738  if(norm != Real(0))
2739  {
2740  Block grad;
2741  grad[0] = __dx<Real,std::random_access_iterator2d_tag>::dx(it);
2742  grad[1] = __dy<Real,std::random_access_iterator2d_tag>::dy(it);
2743  result = std::inner_product(grad.begin(),grad.end(),v.begin(),Real()) / norm;
2744  }
2745  return result;
2746  }
2747 };
2748 
2749 template<typename Real>
2750 struct __dv<Real, std::random_access_iterator3d_tag>
2751 {
2752  template <typename _II, typename Block>
2753  static Real
2754  dv(_II it, Block v)
2755  {
2756  assert(Block::SIZE == 3);
2757  Real result = Real(0);
2758  Real norm = slip::Euclidean_norm<Real>(v.begin(),v.end());
2759  if(norm != Real(0))
2760  {
2761  Block grad;
2762  grad[0] = __dx<Real,std::random_access_iterator3d_tag>::dx(it);
2763  grad[1] = __dy<Real,std::random_access_iterator3d_tag>::dy(it);
2764  grad[2] = __dz<Real,std::random_access_iterator3d_tag>::dz(it);
2765  result = std::inner_product(grad.begin(),grad.end(),v.begin(),Real()) / norm;
2766  }
2767  return result;
2768  }
2769 };
2770 
2771 
2779 template<typename Real>
2780 struct __dv<Real, std::random_access_iterator4d_tag>
2781 {
2782  template <typename _II, typename Block>
2783  static Real
2784  dv(_II it, Block v)
2785  {
2786  assert(Block::SIZE == 4);
2787  Real result = Real(0);
2788  Real norm = slip::Euclidean_norm<Real>(v.begin(),v.end());
2789  if(norm != Real(0))
2790  {
2791  Block grad;
2792  grad[0] = __dt<Real,std::random_access_iterator4d_tag>::dt(it);
2793  grad[1] = __dx<Real,std::random_access_iterator4d_tag>::dx(it);
2794  grad[2] = __dy<Real,std::random_access_iterator4d_tag>::dy(it);
2795  grad[3] = __dz<Real,std::random_access_iterator4d_tag>::dz(it);
2796  result = std::inner_product(grad.begin(),grad.end(),v.begin(),Real()) / norm;
2797  }
2798  return result;
2799  }
2800 };
2801 
2802 
2803 template<typename Real, typename Block> struct Dv
2804 {
2805  Dv(Block v)
2806  :v_(v)
2807  {}
2808  template<typename Iterator>
2809  Real operator() (Iterator& it) const
2810  {
2811  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
2812  return __dv<Real,_Category>::dv(it,v_);
2813  }
2814  Block v_;
2815 };
2816 
2817 
2818 //
2819 // gradient norm
2820 //
2821 template<typename Real,typename>
2822 struct __grad
2823 {
2824  template <typename _II>
2825  static Real
2826  grad(_II it)
2827  {
2828  Real dx = __dx<Real,std::random_access_iterator_tag>::dx(it);
2829 
2830  return std::abs(dx);
2831  }
2832 };
2833 
2834 template<typename Real>
2835 struct __grad<Real, std::random_access_iterator2d_tag>
2836 {
2837  template <typename _II>
2838  static Real
2839  grad(_II it)
2840  {
2841  Real dx = __dx<Real,std::random_access_iterator2d_tag>::dx(it);
2842  Real dy = __dy<Real,std::random_access_iterator2d_tag>::dy(it);
2843 
2844  return std::sqrt((dx * dx) + (dy * dy));
2845 
2846  }
2847 };
2848 
2849 template<typename Real>
2850 struct __grad<Real, std::random_access_iterator3d_tag>
2851 {
2852  template <typename _II>
2853  static Real
2854  grad(_II it)
2855  {
2856  Real dx = __dx<Real,std::random_access_iterator3d_tag>::dx(it);
2857  Real dy = __dy<Real,std::random_access_iterator3d_tag>::dy(it);
2858  Real dz = __dz<Real,std::random_access_iterator3d_tag>::dz(it);
2859 
2860  return std::sqrt((dx * dx) + (dy * dy) + (dz * dz));
2861 
2862  }
2863 };
2864 
2865 
2866 
2875 template<typename Real>
2876 struct __grad<Real, std::random_access_iterator4d_tag>
2877 {
2878  template <typename _II>
2879  static Real
2880  grad(_II it)
2881  {
2882  Real dt = __dt<Real,std::random_access_iterator4d_tag>::dt(it);
2883  Real dx = __dx<Real,std::random_access_iterator4d_tag>::dx(it);
2884  Real dy = __dy<Real,std::random_access_iterator4d_tag>::dy(it);
2885  Real dz = __dz<Real,std::random_access_iterator4d_tag>::dz(it);
2886 
2887  return std::sqrt((dt * dt) + (dx * dx) + (dy * dy) + (dz * dz));
2888 
2889  }
2890 };
2891 
2892 
2893 template<typename Real> struct Grad
2894 {
2895  Grad(){}
2896  template<typename Iterator>
2897  Real operator() (Iterator it) const
2898  {
2899  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
2900  return __grad<Real,_Category>::grad(it);
2901  }
2902 };
2903 
2904 
2905 
2906 
2907 //
2908 // dxx local derivatives
2909 //
2910 
2911 template<typename Real,typename>
2912 struct __dxx
2913 {
2914  template <typename _II>
2915  static Real
2916  dxx(_II it)
2917  {
2918  Real left = *(it - 1);
2919  Real center = *it;
2920  Real right = *(it + 1);
2921 
2922  return ((right + left) - Real(2) * center);
2923  }
2924 };
2925 
2926 template<typename Real>
2927 struct __dxx<Real,std::random_access_iterator_tag>
2928 {
2929  template <typename _II>
2930  static Real
2931  dxx(_II it)
2932  {
2933  Real left = *(it - 1);
2934  Real center = *it;
2935  Real right = *(it + 1);
2936 
2937  return ((right + left) - Real(2) * center);
2938  }
2939 };
2940 
2941 template<typename Real>
2942 struct __dxx<Real, std::random_access_iterator2d_tag>
2943 {
2944  template <typename _II>
2945  static Real
2946  dxx(_II it)
2947  {
2948  Real left = it[slip::n_8c[4]];
2949  Real center = *it;
2950  Real right = it[slip::n_8c[0]];
2951 
2952  return ((right + left) - Real(2) * center);
2953  }
2954 };
2955 
2956 template<typename Real>
2957 struct __dxx<Real, std::random_access_iterator3d_tag>
2958 {
2959  template <typename _II>
2960  static Real
2961  dxx(_II it)
2962  {
2963  Real left = it[slip::n_6c[3]];
2964  Real center = *it;
2965  Real right = it[slip::n_6c[1]];
2966 
2967  return ((right + left) - Real(2) * center);
2968  }
2969 };
2970 
2979 template<typename Real>
2980 struct __dxx<Real, std::random_access_iterator4d_tag>
2981 {
2982  template <typename _II>
2983  static Real
2984  dxx(_II it)
2985  {
2986  Real left = it[slip::n_4d_8c[4]];
2987  Real center = *it;
2988  Real right = it[slip::n_4d_8c[2]];
2989 
2990  return ((right + left) - Real(2) * center);
2991  }
2992 };
2993 
2994 
2995 template<typename Real> struct Dxx
2996 {
2997 
2998  Dxx(){}
2999  template<typename Iterator>
3000  Real operator() (Iterator& it) const
3001  {
3002  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
3003  return __dxx<Real,_Category>::dxx(it);
3004  }
3005 };
3006 
3007 
3008 //
3009 // dyy local derivatives
3010 //
3011 template<typename Real,typename>
3012 struct __dyy
3013 {
3014  template <typename _II>
3015  static Real
3016  dyy(_II it)
3017  {
3018  Real left = *(it - 1);
3019  Real center = *it;
3020  Real right = *(it + 1);
3021 
3022  return ((right + left) - Real(2) * center);
3023  }
3024 };
3025 
3026 template<typename Real>
3027 struct __dyy<Real,std::random_access_iterator_tag>
3028 {
3029  template <typename _II>
3030  static Real
3031  dyy(_II it)
3032  {
3033  return __dxx<Real,std::random_access_iterator_tag>::dxx(it);
3034  }
3035 };
3036 
3037 template<typename Real>
3038 struct __dyy<Real, std::random_access_iterator2d_tag>
3039 {
3040  template <typename _II>
3041  static Real
3042  dyy(_II it)
3043  {
3044  Real top = it[slip::n_8c[2]];
3045  Real center = *it;
3046  Real bottom = it[slip::n_8c[6]];
3047 
3048  return ((top + bottom) - Real(2) * center);
3049  }
3050 };
3051 
3052 template<typename Real>
3053 struct __dyy<Real, std::random_access_iterator3d_tag>
3054 {
3055  template <typename _II>
3056  static Real
3057  dyy(_II it)
3058  {
3059  Real top = it[slip::n_6c[2]];
3060  Real center = *it;
3061  Real bottom = it[slip::n_6c[4]];
3062 
3063  return ((top + bottom) - Real(2) * center);
3064  }
3065 };
3066 
3074 template<typename Real>
3075 struct __dyy<Real, std::random_access_iterator4d_tag>
3076 {
3077  template <typename _II>
3078  static Real
3079  dyy(_II it)
3080  {
3081  Real top = it[slip::n_4d_8c[3]];
3082  Real center = *it;
3083  Real bottom = it[slip::n_4d_8c[5]];
3084 
3085  return ((top + bottom) - Real(2) * center);
3086  }
3087 };
3088 
3089 template<typename Real> struct Dyy
3090 {
3091 
3092  Dyy(){}
3093  template<typename Iterator>
3094  Real operator() (Iterator& it) const
3095  {
3096  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
3097  return __dyy<Real,_Category>::dyy(it);
3098  }
3099 };
3100 
3101 //
3102 // dzz local derivatives
3103 //
3104 template<typename Real,typename>
3105 struct __dzz
3106 {
3107  template <typename _II>
3108  static Real
3109  dzz(_II it)
3110  {
3111  Real left = *(it - 1);
3112  Real center = *it;
3113  Real right = *(it + 1);
3114 
3115  return ((right + left) - Real(2) * center);
3116  }
3117 };
3118 
3119 template<typename Real>
3120 struct __dzz<Real,std::random_access_iterator_tag>
3121 {
3122  template <typename _II>
3123  static Real
3124  dzz(_II it)
3125  {
3126  return __dxx<Real,std::random_access_iterator_tag>::dxx(it);
3127  }
3128 };
3129 
3130 template<typename Real>
3131 struct __dzz<Real, std::random_access_iterator2d_tag>
3132 {
3133  template <typename _II>
3134  static Real
3135  dzz(_II it)
3136  {
3137  Real top = it[slip::n_8c[5]];
3138  Real center = *it;
3139  Real bottom = it[slip::n_8c[0]];
3140 
3141  return ((top + bottom) - Real(2) * center);
3142  }
3143 };
3144 
3145 template<typename Real>
3146 struct __dzz<Real, std::random_access_iterator3d_tag>
3147 {
3148  template <typename _II>
3149  static Real
3150  dzz(_II it)
3151  {
3152  Real top = it[slip::n_6c[5]];
3153  Real center = *it;
3154  Real bottom = it[slip::n_6c[0]];
3155 
3156  return ((top + bottom) - Real(2) * center);
3157  }
3158 };
3159 
3160 
3168 template<typename Real>
3169 struct __dzz<Real, std::random_access_iterator4d_tag>
3170 {
3171  template <typename _II>
3172  static Real
3173  dzz(_II it)
3174  {
3175  Real top = it[slip::n_4d_8c[6]];
3176  Real center = *it;
3177  Real bottom = it[slip::n_4d_8c[1]];
3178 
3179  return ((top + bottom) - Real(2) * center);
3180  }
3181 };
3182 
3183 template<typename Real> struct Dzz
3184 {
3185 
3186  Dzz(){}
3187  template<typename Iterator>
3188  Real operator() (Iterator& it) const
3189  {
3190  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
3191  return __dzz<Real,_Category>::dzz(it);
3192  }
3193 };
3194 
3202 template<typename Real,typename>
3203 struct __dtt
3204 {
3205  template <typename _II>
3206  static Real
3207  dtt(_II it)
3208  {
3209  Real prev = *(it - 1);
3210  Real center = *it;
3211  Real next = *(it + 1);
3212 
3213  return ((next + prev) - Real(2) * center);
3214  }
3215 };
3216 
3217 template<typename Real>
3218 struct __dtt<Real,std::random_access_iterator_tag>
3219 {
3220  template <typename _II>
3221  static Real
3222  dtt(_II it)
3223  {
3224  return __dxx<Real,std::random_access_iterator_tag>::dxx(it);
3225  }
3226 };
3227 
3228 template<typename Real>
3229 struct __dtt<Real, std::random_access_iterator2d_tag>
3230 {
3231  template <typename _II>
3232  static Real
3233  dtt(_II it)
3234  {
3235  Real prev = it[slip::n_8c[5]];
3236  Real center = *it;
3237  Real next = it[slip::n_8c[0]];
3238 
3239  return ((next + prev) - Real(2) * center);
3240  }
3241 };
3242 
3243 template<typename Real>
3244 struct __dtt<Real, std::random_access_iterator3d_tag>
3245 {
3246  template <typename _II>
3247  static Real
3248  dtt(_II it)
3249  {
3250  Real prev = it[slip::n_26c[5]];
3251  Real center = *it;
3252  Real next = it[slip::n_26c[19]];
3253 
3254  return ((next + prev) - Real(2) * center);
3255  }
3256 };
3257 
3258 template<typename Real>
3259 struct __dtt<Real, std::random_access_iterator4d_tag>
3260 {
3261  template <typename _II>
3262  static Real
3263  dtt(_II it)
3264  {
3265  Real prev = it[slip::n_4d_8c[0]];
3266  Real center = *it;
3267  Real next = it[slip::n_4d_8c[7]];
3268 
3269  return ((next + prev) - Real(2) * center);
3270  }
3271 };
3272 
3273 template<typename Real> struct Dtt
3274 {
3275 
3276  Dtt(){}
3277  template<typename Iterator>
3278  Real operator() (Iterator& it) const
3279  {
3280  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
3281  return __dtt<Real,_Category>::dtt(it);
3282  }
3283 };
3284 
3285 template<typename Real,typename>
3286 struct __dxy
3287 {
3288  template <typename _II>
3289  static Real
3290  dxy(_II it)
3291  {
3292  Real left = *(it - 1);
3293  Real center = *it;
3294  Real right = *(it + 1);
3295 
3296  return ((right + left) - Real(2) * center);
3297  }
3298 };
3299 
3300 template<typename Real>
3301 struct __dxy<Real,std::random_access_iterator_tag>
3302 {
3303  template <typename _II>
3304  static Real
3305  dxy(_II it)
3306  {
3307  Real left = *(it - 1);
3308  Real center = *it;
3309  Real right = *(it + 1);
3310 
3311  return ((right + left) - Real(2) * center);
3312  }
3313 };
3314 
3315 template<typename Real>
3316 struct __dxy<Real, std::random_access_iterator2d_tag>
3317 {
3318  template <typename _II>
3319  static Real
3320  dxy(_II it)
3321  {
3322 
3323  Real NE = it[slip::n_8c[1]];
3324  Real NW = it[slip::n_8c[3]];
3325  Real SE = it[slip::n_8c[7]];
3326  Real SW = it[slip::n_8c[5]];
3327 
3328  return ((SW + NE) - (SE + NW)) * Real(0.25);
3329  }
3330 };
3331 
3332 template<typename Real>
3333 struct __dxy<Real, std::random_access_iterator3d_tag>
3334 {
3335  template <typename _II>
3336  static Real
3337  dxy(_II it)
3338  {
3339  Real NE = it[slip::n_26c[10]];
3340  Real NW = it[slip::n_26c[12]];
3341  Real SE = it[slip::n_26c[25]];
3342  Real SW = it[slip::n_26c[23]];
3343 
3344  return ((SW + NE) - (SE + NW)) * Real(0.25);
3345  }
3346 };
3347 
3348 template<typename Real> struct Dxy
3349 {
3350 
3351  Dxy(){}
3352  template<typename Iterator>
3353  Real operator() (Iterator& it) const
3354  {
3355  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
3356  return __dxy<Real,_Category>::dxy(it);
3357  }
3358 };
3359 
3360 //
3361 //dxz
3362 template<typename Real,typename>
3363 struct __dxz
3364 {
3365  template <typename _II>
3366  static Real
3367  dxz(_II it)
3368  {
3369  return __dxx<Real,std::random_access_iterator_tag>::dxx(it);
3370  }
3371 };
3372 
3373 template<typename Real>
3374 struct __dxz<Real,std::random_access_iterator_tag>
3375 {
3376  template <typename _II>
3377  static Real
3378  dxz(_II it)
3379  {
3380  return __dxx<Real,std::random_access_iterator_tag>::dxx(it);
3381  }
3382 };
3383 
3384 
3385 template<typename Real>
3386 struct __dxz<Real, std::random_access_iterator3d_tag>
3387 {
3388  template <typename _II>
3389  static Real
3390  dxz(_II it)
3391  {
3392  Real NE = it[slip::n_26c[1]];
3393  Real NW = it[slip::n_26c[5]];
3394  Real SE = it[slip::n_26c[18]];
3395  Real SW = it[slip::n_26c[14]];
3396 
3397  return ((SW + NE) - (SE + NW)) * Real(0.25);
3398  }
3399 };
3400 
3401 template<typename Real> struct Dxz
3402 {
3403 
3404  Dxz(){}
3405  template<typename Iterator>
3406  Real operator() (Iterator& it) const
3407  {
3408  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
3409  return __dxz<Real,_Category>::dxz(it);
3410  }
3411 };
3412 
3413 //
3414 //dyz
3415 template<typename Real,typename>
3416 struct __dyz
3417 {
3418  template <typename _II>
3419  static Real
3420  dyz(_II it)
3421  {
3422  return __dxx<Real,std::random_access_iterator_tag>::dxx(it);
3423  }
3424 };
3425 
3426 template<typename Real>
3427 struct __dyz<Real,std::random_access_iterator_tag>
3428 {
3429  template <typename _II>
3430  static Real
3431  dyz(_II it)
3432  {
3433  return __dxx<Real,std::random_access_iterator_tag>::dxx(it);
3434  }
3435 };
3436 
3437 
3438 
3439 template<typename Real>
3440 struct __dyz<Real, std::random_access_iterator3d_tag>
3441 {
3442  template <typename _II>
3443  static Real
3444  dyz(_II it)
3445  {
3446  Real NE = it[slip::n_26c[3]];
3447  Real NW = it[slip::n_26c[20]];
3448  Real SE = it[slip::n_26c[18]];
3449  Real SW = it[slip::n_26c[7]];
3450 
3451  return ((SW + NE) - (SE + NW)) * Real(0.25);
3452  }
3453 };
3454 
3455 template<typename Real> struct Dyz
3456 {
3457 
3458  Dyz(){}
3459  template<typename Iterator>
3460  Real operator() (Iterator& it) const
3461  {
3462  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
3463  return __dyz<Real,_Category>::dyz(it);
3464  }
3465 };
3466 
3467 
3468 
3469 //
3470 //dxy Weickert
3471 //
3472 
3473 template<typename Real,typename>
3474 struct __dxy_w
3475 {
3476  template <typename _II>
3477  static Real
3478  dxy_w(_II it)
3479  {
3480  Real left = *(it - 1);
3481  Real center = *it;
3482  Real right = *(it + 1);
3483 
3484  return ((right + left) - Real(2) * center);
3485  }
3486 };
3487 
3488 template<typename Real>
3489 struct __dxy_w<Real,std::random_access_iterator_tag>
3490 {
3491  template <typename _II>
3492  static Real
3493  dxy_w(_II it)
3494  {
3495  Real left = *(it - 1);
3496  Real center = *it;
3497  Real right = *(it + 1);
3498 
3499  return ((right + left) - Real(2) * center);
3500  }
3501 };
3502 
3503 template<typename Real>
3504 struct __dxy_w<Real, std::random_access_iterator2d_tag>
3505 {
3506  template <typename _II>
3507  static Real
3508  dxy_w(_II it)
3509  {
3510  Real gx = __dx<Real,std::random_access_iterator2d_tag>::dx(it);
3511  Real gy = __dy<Real,std::random_access_iterator2d_tag>::dy(it);
3512  Real gxgy = gx * gy;
3513 
3514  Real dxy = Real(0);
3515 
3516  Real center = *it;
3517  Real E = it[slip::n_8c[0]];
3518  Real NE = it[slip::n_8c[1]];
3519  Real N = it[slip::n_8c[2]];
3520  Real NW = it[slip::n_8c[3]];
3521  Real W = it[slip::n_8c[4]];
3522  Real SW = it[slip::n_8c[5]];
3523  Real S = it[slip::n_8c[6]];
3524  Real SE = it[slip::n_8c[7]];
3525  if(gxgy > 0)
3526  {
3527  dxy = (SW + NE + Real(2) * center - E - S - N - W) * Real(0.5);
3528  }
3529  else
3530  {
3531  dxy = (E + S + N + W - NW - SE - Real(2) * center) * Real(0.5);
3532  }
3533 
3534  return dxy;
3535  }
3536 };
3537 
3538 template<typename Real>
3539 struct __dxy_w<Real, std::random_access_iterator3d_tag>
3540 {
3541  template <typename _II>
3542  static Real
3543  dxy_w(_II it)
3544  {
3545  Real gx = __dx<Real,std::random_access_iterator2d_tag>::dx(it);
3546  Real gy = __dy<Real,std::random_access_iterator2d_tag>::dy(it);
3547  Real gxgy = gx * gy;
3548 
3549  Real dxy = Real(0);
3550 
3551  Real center = *it;
3552  Real E = it[slip::n_26c[9]];
3553  Real NE = it[slip::n_26c[10]];
3554  Real N = it[slip::n_26c[11]];
3555  Real NW = it[slip::n_26c[12]];
3556  Real W = it[slip::n_26c[22]];
3557  Real SW = it[slip::n_26c[23]];
3558  Real S = it[slip::n_26c[24]];
3559  Real SE = it[slip::n_26c[25]];
3560 
3561  if(gxgy > 0)
3562  {
3563  dxy = (SW + NE + Real(2) * center - E - S - N - W) * Real(0.5);
3564  }
3565  else
3566  {
3567  dxy = (E + S + N + W - NW - SE - Real(2) * center) * Real(0.5);
3568  }
3569 
3570  return dxy;
3571 
3572  }
3573 };
3574 
3575 template<typename Real> struct Dxy_W
3576 {
3577 
3578  Dxy_W(){}
3579  template<typename Iterator>
3580  Real operator() (Iterator& it) const
3581  {
3582  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
3583  return __dxy_w<Real,_Category>::dxy_w(it);
3584  }
3585 };
3586 
3587 //
3588 // divergence local derivatives
3589 //
3590 template<typename Real,typename>
3591 struct __div
3592 {
3593  template <typename _II>
3594  static Real
3595  div(_II it)
3596  {
3597  return __dx<Real,std::random_access_iterator_tag>::dx(it);
3598  }
3599 };
3600 
3601 template<typename Real>
3602 struct __div<Real,std::random_access_iterator_tag>
3603 {
3604  template <typename _II>
3605  static Real
3606  div(_II it)
3607  {
3608  return __dx<Real,std::random_access_iterator_tag>::dx(it);
3609  }
3610 };
3611 
3612 template<typename Real>
3613 struct __div<Real,std::random_access_iterator2d_tag>
3614 {
3615  template <typename _II>
3616  static Real
3617  div(_II it)
3618  {
3619  return __dx<Real,std::random_access_iterator2d_tag>::dx(it)
3620  +__dy<Real,std::random_access_iterator2d_tag>::dy(it);
3621  }
3622 };
3623 
3624 template<typename Real>
3625 struct __div<Real,std::random_access_iterator3d_tag>
3626 {
3627  template <typename _II>
3628  static Real
3629  div(_II it)
3630  {
3631  return __dx<Real,std::random_access_iterator3d_tag>::dx(it)
3632  +__dy<Real,std::random_access_iterator3d_tag>::dy(it)
3633  +__dz<Real,std::random_access_iterator3d_tag>::dz(it);
3634  }
3635 };
3636 
3644 template<typename Real>
3645 struct __div<Real,std::random_access_iterator4d_tag>
3646 {
3647  template <typename _II>
3648  static Real
3649  div(_II it)
3650  {
3651  return __dt<Real,std::random_access_iterator4d_tag>::dt(it)
3652  +__dx<Real,std::random_access_iterator4d_tag>::dx(it)
3653  +__dy<Real,std::random_access_iterator4d_tag>::dy(it)
3654  +__dz<Real,std::random_access_iterator4d_tag>::dz(it);
3655  }
3656 };
3657 
3658 
3659 template<typename Real> struct Div
3660 {
3661 
3662  Div(){}
3663  template<typename Iterator>
3664  Real operator() (Iterator& it) const
3665  {
3666  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
3667  return __div<Real,_Category>::div(it);
3668  }
3669 };
3670 
3671 
3672 
3673 
3674 //
3675 // local laplacian
3676 //
3677 template<typename Real,typename>
3678 struct __lap
3679 {
3680  template <typename _II>
3681  static Real
3682  lap(_II it)
3683  {
3684  return __dxx<Real,std::random_access_iterator_tag>::dxx(it);
3685  }
3686 };
3687 
3688 template<typename Real>
3689 struct __lap<Real,std::random_access_iterator_tag>
3690 {
3691  template <typename _II>
3692  static Real
3693  lap(_II it)
3694  {
3695  return __dxx<Real,std::random_access_iterator_tag>::dxx(it);
3696  }
3697 };
3698 
3699 template<typename Real>
3700 struct __lap<Real,std::random_access_iterator2d_tag>
3701 {
3702  template <typename _II>
3703  static Real
3704  lap(_II it)
3705  {
3706  return __dxx<Real,std::random_access_iterator2d_tag>::dxx(it)
3707  +__dyy<Real,std::random_access_iterator2d_tag>::dyy(it);
3708  }
3709 };
3710 
3711 template<typename Real>
3712 struct __lap<Real,std::random_access_iterator3d_tag>
3713 {
3714  template <typename _II>
3715  static Real
3716  lap(_II it)
3717  {
3718  return __dxx<Real,std::random_access_iterator3d_tag>::dxx(it)
3719  +__dyy<Real,std::random_access_iterator3d_tag>::dyy(it)
3720  +__dzz<Real,std::random_access_iterator3d_tag>::dzz(it);
3721  }
3722 };
3723 
3731 template<typename Real>
3732 struct __lap<Real,std::random_access_iterator4d_tag>
3733 {
3734  template <typename _II>
3735  static Real
3736  lap(_II it)
3737  {
3738  return __dtt<Real,std::random_access_iterator4d_tag>::dtt(it)
3739  +__dxx<Real,std::random_access_iterator4d_tag>::dxx(it)
3740  +__dyy<Real,std::random_access_iterator4d_tag>::dyy(it)
3741  +__dzz<Real,std::random_access_iterator4d_tag>::dzz(it);
3742  }
3743 };
3744 
3745 
3746 template<typename Real> struct Lap
3747 {
3748 
3749  Lap(){}
3750  template<typename Iterator>
3751  Real operator() (Iterator& it) const
3752  {
3753  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
3754  return __lap<Real,_Category>::lap(it);
3755  }
3756 };
3757 
3758 template<typename Real,typename>
3759 struct __lap_8c
3760 {
3761  template <typename _II>
3762  static Real
3763  lap(_II it)
3764  {
3765  return __dxx<Real,std::random_access_iterator_tag>::dxx(it);
3766  }
3767 };
3768 template<typename Real>
3769 struct __lap_8c<Real, std::random_access_iterator2d_tag>
3770 {
3771  template <typename _II>
3772  static Real
3773  lap(_II it)
3774  {
3775 
3776  const Real gamma = Real(2) / Real(3);
3777  Real gamma2 = Real(1) - gamma;
3778  Real inv_2h2 = Real(0.5);
3779 
3780  Real Ixx = __dxx<Real,std::random_access_iterator2d_tag>::dxx(it);
3781  Real Iyy = __dyy<Real,std::random_access_iterator2d_tag>::dyy(it);
3782  Real NE = it[slip::n_8c[1]];
3783  Real NW = it[slip::n_8c[3]];
3784  Real SE = it[slip::n_8c[7]];
3785  Real SW = it[slip::n_8c[5]];
3786  Real diag = (((SE + NW) + (SW + NE)) - ((Real(4) * *it))) * inv_2h2;
3787 
3788  return ((gamma2 * Ixx) + (gamma2 * Iyy)) + (gamma * diag);
3789  }
3790 };
3791 template<typename Real> struct Lap8
3792 {
3793 
3794  Lap8(){}
3795  template<typename Iterator>
3796  Real operator() (Iterator& it) const
3797  {
3798  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
3799  return __lap_8c<Real,_Category>::lap(it);
3800  }
3801 };
3802 
3803 
3804 template<typename Real> struct LapLindeberg
3805 {
3806 
3808  template<typename Iterator>
3809  Real operator() (Iterator& it) const
3810  {
3811  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
3812  return slip::constants<Real>::half()*__lap_8c<Real,_Category>::lap(it);
3813  }
3814 };
3815 //
3816 // local second derivative in the direction of the gradient
3817 //
3818 template<typename Real,typename>
3819 struct __iee_sapiro
3820 {
3821  template <typename _II>
3822  static Real
3823  iee_sapiro(_II it)
3824  {
3825  return __dxx<Real,std::random_access_iterator_tag>::dxx(it);
3826  }
3827 };
3828 
3829 template<typename Real>
3830 struct __iee_sapiro<Real, std::random_access_iterator2d_tag>
3831 {
3832  template <typename _II>
3833  static Real
3834  iee_sapiro(_II it)
3835  {
3836 
3837  Real gx = __dx<Real,std::random_access_iterator2d_tag>::dx(it);
3838  Real gy = __dy<Real,std::random_access_iterator2d_tag>::dy(it);
3839  Real gx2 = gx * gx;
3840  Real gy2 = gy * gy;
3841  Real g2 = gx2 + gy2;
3842 
3843  Real iee = Real(0);
3844 
3845  if(g2 != 0)
3846  {
3847  Real lambda1 = gx2;
3848  Real lambda2 = gy2;
3849  Real lambda3 = Real(0.5) * (gx * gy);
3850  Real lambda4 = - lambda3;
3851  Real lambda0 = Real(-2.0) * (lambda1 + lambda2);
3852  Real center = *it;
3853  Real E = it[slip::n_8c[0]];
3854  Real NE = it[slip::n_8c[1]];
3855  Real N = it[slip::n_8c[2]];
3856  Real NW = it[slip::n_8c[3]];
3857  Real W = it[slip::n_8c[4]];
3858  Real SW = it[slip::n_8c[5]];
3859  Real S = it[slip::n_8c[6]];
3860  Real SE = it[slip::n_8c[7]];
3861 
3862 
3863  iee = ( lambda4 * (NW + SE)
3864  + lambda3 * (NE + SW)
3865  + lambda2 * (S + N)
3866  + lambda1 * (W + E)
3867  + lambda0 * center) / g2 ;
3868  }
3869 
3870 
3871  return(iee);
3872 
3873  }
3874 };
3875 
3876 template<typename Real>
3877 struct __iee_sapiro<Real, std::random_access_iterator3d_tag>
3878 {
3879  template <typename _II>
3880  static Real
3881  iee_sapiro(_II it)
3882  {
3883 
3884  Real dx = __dx<Real,std::random_access_iterator3d_tag>::dx(it);
3885  Real dy = __dy<Real,std::random_access_iterator3d_tag>::dy(it);
3886  Real dz = __dz<Real,std::random_access_iterator3d_tag>::dz(it);
3887 
3888  Real dx2 = dx * dx;
3889  Real dy2 = dy * dy;
3890  Real dz2 = dz + dz;
3891 
3892  Real g2 = (dx2 + dy2) + dz2;
3893 
3894  Real iee = Real(0);
3895 
3896  if(g2 != 0)
3897  {
3898 
3899  Real dxx = __dxx<Real,std::random_access_iterator3d_tag>::dxx(it);
3900  Real dyy = __dyy<Real,std::random_access_iterator3d_tag>::dyy(it);
3901  Real dzz = __dzz<Real,std::random_access_iterator3d_tag>::dzz(it);
3902 
3903  Real dxy = __dxy<Real,std::random_access_iterator3d_tag>::dxy(it);
3904  Real dxz = __dxz<Real,std::random_access_iterator3d_tag>::dxz(it);
3905  Real dyz = __dyz<Real,std::random_access_iterator3d_tag>::dyz(it);
3906 
3907  Real dxdy = dx * dy;
3908  Real dxdz = dx * dz;
3909  Real dydz = dy * dz;
3910 
3911  Real a = (dy2 + dz2) * dxx;
3912  Real b = (dx2 + dz2) * dyy;
3913  Real c = (dx2 + dy2) * dzz;
3914  Real d = Real(2.0) * (dxdy * dxy);
3915  Real e = Real(2.0) * (dxdz * dxz);
3916  Real f = Real(2.0) * (dydz * dyz);
3917 
3918  iee = ((a + b) + (c + d) + (e + f)) / g2;
3919  }
3920 
3921  return(iee);
3922 
3923  }
3924 };
3925 
3926 template<typename Real> struct Iee_Sapiro
3927 {
3928 
3930  template<typename Iterator>
3931  Real operator() (Iterator& it) const
3932  {
3933  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
3934  return __iee_sapiro<Real,_Category>::iee_sapiro(it);
3935  }
3936 };
3937 
3938 template<typename Real,typename>
3939 struct __iee_lucido
3940 {
3941  template <typename _II>
3942  static Real
3943  iee_lucido(_II it)
3944  {
3945  return __dxx<Real,std::random_access_iterator_tag>::dxx(it);
3946  }
3947 };
3948 
3949 template<typename Real>
3950 struct __iee_lucido<Real, std::random_access_iterator2d_tag>
3951 {
3952  template <typename _II>
3953  static Real
3954  iee_lucido(_II it)
3955  {
3956 
3957  Real gx = __dx<Real,std::random_access_iterator2d_tag>::dx(it);
3958  Real gy = __dy<Real,std::random_access_iterator2d_tag>::dy(it);
3959  Real gx2 = gx * gx;
3960  Real gy2 = gy * gy;
3961  Real g2 = gx2 + gy2;
3962  Real gxgy = gx * gy;
3963  Real iee = Real(0);
3964 
3965  if(g2 != 0)
3966  {
3967  if(gxgy >= 0)
3968  {
3969 
3970 
3971  Real lambda1 = gx2 - gxgy;
3972  Real lambda2 = gy2 - gxgy;
3973  Real lambda3 = gxgy;
3974  // Real lambda4 = - lambda3;
3975  Real lambda0 = Real(-2.0) * ((lambda1 + lambda2) + lambda3);
3976  Real center = *it;
3977  Real E = it[slip::n_8c[0]];
3978  Real NE = it[slip::n_8c[1]];
3979  Real N = it[slip::n_8c[2]];
3980  Real W = it[slip::n_8c[4]];
3981  Real SW = it[slip::n_8c[5]];
3982  Real S = it[slip::n_8c[6]];
3983 
3984  iee = ( lambda3 * (NE + SW)
3985  + lambda2 * (S + N)
3986  + lambda1 * (W + E)
3987  + lambda0 * center)/ g2;
3988  }
3989  else
3990  {
3991  Real lambda1 = gx2 + gxgy;
3992  Real lambda2 = gy2 + gxgy;
3993  Real lambda4 = - gxgy;
3994  Real lambda0 = Real(-2.0) * ((lambda1 + lambda2) + lambda4);
3995  Real center = *it;
3996  Real E = it[slip::n_8c[0]];
3997  Real N = it[slip::n_8c[2]];
3998  Real NW = it[slip::n_8c[3]];
3999  Real W = it[slip::n_8c[4]];
4000  Real S = it[slip::n_8c[6]];
4001  Real SE = it[slip::n_8c[7]];
4002  iee = ( lambda4 * (NW + SE)
4003  + lambda2 * (S + N)
4004  + lambda1 * (W + E)
4005  + lambda0 * center)/ g2;
4006  }
4007 
4008  }
4009 
4010 
4011  return(iee);
4012 
4013  }
4014 };
4015 template<typename Real> struct Iee_Lucido
4016 {
4017 
4019  template<typename Iterator>
4020  Real operator() (Iterator& it)
4021  {
4022  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
4023  return __iee_lucido<Real,_Category>::iee_lucido(it);
4024  }
4025 };
4026 template<typename Real,typename>
4027 struct __iee_augereau
4028 {
4029  template <typename _II>
4030  static Real
4031  iee_augereau(_II it)
4032  {
4033  return __dxx<Real,std::random_access_iterator_tag>::dxx(it);
4034  }
4035 };
4036 
4037 template<typename Real>
4038 struct __iee_augereau<Real, std::random_access_iterator2d_tag>
4039 {
4040  template <typename _II>
4041  static Real
4042  iee_augereau(_II it)
4043  {
4044 
4045  Real gx = __dx<Real,std::random_access_iterator2d_tag>::dx(it);
4046  Real gy = __dy<Real,std::random_access_iterator2d_tag>::dy(it);
4047  Real gx2 = gx * gx;
4048  Real gy2 = gy * gy;
4049  Real g2 = gx2 + gy2;
4050  Real gxgy = gx * gy;
4051  Real absgx = std::abs(gx);
4052  Real absgy = std::abs(gy);
4053  Real iee = Real(0);
4054 
4055  if(g2 != 0)
4056  {
4057  if(absgx >= absgy)
4058  {
4059  Real lambda0 = Real(-2.0) * gx2;
4060  Real lambda1 = gx2 - gy2;
4061  Real lambda3 = Real(0.5) * (gy2 + gxgy);
4062  Real lambda4 = Real(0.5) * (gy2 - gxgy);
4063 
4064  Real center = *it;
4065  Real E = it[slip::n_8c[0]];
4066  Real NE = it[slip::n_8c[1]];
4067  Real NW = it[slip::n_8c[3]];
4068  Real W = it[slip::n_8c[4]];
4069  Real SW = it[slip::n_8c[5]];
4070  Real SE = it[slip::n_8c[7]];
4071 
4072  iee = ( lambda4 * (NW + SE)
4073  + lambda3 * (NE + SW)
4074  + lambda1 * (W + E)
4075  + lambda0 * center)/ g2;
4076  }
4077  else
4078  {
4079  Real lambda0 = Real(-2.0) * gy2;
4080  Real lambda2 = gy2 - gx2;
4081  Real lambda3 = Real(0.5) * (gx2 + gxgy);
4082  Real lambda4 = Real(0.5) * (gx2 - gxgy);
4083 
4084  Real center = *it;
4085  Real NE = it[slip::n_8c[1]];
4086  Real N = it[slip::n_8c[2]];
4087  Real NW = it[slip::n_8c[3]];
4088  Real SW = it[slip::n_8c[5]];
4089  Real S = it[slip::n_8c[6]];
4090  Real SE = it[slip::n_8c[7]];
4091  iee = ( lambda4 * (NW + SE)
4092  + lambda3 * (NE + SW)
4093  + lambda2 * (S + N)
4094  + lambda0 * center)/ g2;
4095  }
4096 
4097  }
4098 
4099 
4100  return(iee);
4101 
4102  }
4103 };
4104 template<typename Real> struct Iee_Augereau
4105 {
4106 
4108  template<typename Iterator>
4109  Real operator() (Iterator& it) const
4110  {
4111  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
4112  return __iee_augereau<Real,_Category>::iee_augereau(it);
4113  }
4114 };
4115 
4116 
4117 
4118 
4119 //
4120 template<typename Real,typename>
4121 struct __iee_alvarez
4122 {
4123  template <typename _II>
4124  static Real
4125  iee_alvarez(_II it)
4126  {
4127  return __dxx<Real,std::random_access_iterator_tag>::dxx(it);
4128  }
4129 };
4130 
4131 template<typename Real>
4132 struct __iee_alvarez<Real, std::random_access_iterator2d_tag>
4133 {
4134  template <typename _II>
4135  static Real
4136  iee_alvarez(_II it)
4137  {
4138 
4139  Real gx = __dx<Real,std::random_access_iterator2d_tag>::dx(it);
4140  Real gy = __dy<Real,std::random_access_iterator2d_tag>::dy(it);
4141  Real gx2 = gx * gx;
4142  Real gy2 = gy * gy;
4143  Real g2 = gx2 + gy2;
4144  Real gxgy = gx * gy;
4145 
4146  Real iee = Real(0);
4147 
4148  if(g2 != 0)
4149  {
4150 
4151  Real lambda0 = Real(0.25);
4152  Real lambda1 = Real(2.0) * lambda0 - gy2 / g2;
4153  Real lambda2 = Real(2.0) * lambda0 - gx2 / g2;
4154  Real lambda3 = -lambda0 + Real(0.5) * ( Real(1) + gxgy / g2);
4155  Real lambda4 = -lambda0 + Real(0.5) * ( Real(1) - gxgy / g2);
4156  lambda0 = Real(-1.0);//-4.0*0.25
4157  Real center = *it;
4158  Real E = it[slip::n_8c[0]];
4159  Real NE = it[slip::n_8c[1]];
4160  Real N = it[slip::n_8c[2]];
4161  Real NW = it[slip::n_8c[3]];
4162  Real W = it[slip::n_8c[4]];
4163  Real SW = it[slip::n_8c[5]];
4164  Real S = it[slip::n_8c[6]];
4165  Real SE = it[slip::n_8c[7]];
4166 
4167  iee = ( lambda4 * (NW + SE)
4168  + lambda3 * (NE + SW)
4169  + lambda2 * (N + S)
4170  + lambda1 * (W + E)
4171  + lambda0 * center);
4172  }
4173 
4174  return(iee);
4175 
4176  }
4177 };
4178 template<typename Real> struct Iee_Alvarez
4179 {
4180 
4182  template<typename Iterator>
4183  Real operator() (Iterator& it) const
4184  {
4185  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
4186  return __iee_alvarez<Real,_Category>::iee_alvarez(it);
4187  }
4188 };
4189 
4190 //
4191 template<typename Real,typename>
4192 struct __iee_alvarez2
4193 {
4194  template <typename _II>
4195  static Real
4196  iee_alvarez2(_II it)
4197  {
4198  return __dxx<Real,std::random_access_iterator_tag>::dxx(it);
4199  }
4200 };
4201 
4202 template<typename Real>
4203 struct __iee_alvarez2<Real, std::random_access_iterator2d_tag>
4204 {
4205  template <typename _II>
4206  static Real
4207  iee_alvarez2(_II it)
4208  {
4209 
4210  Real gx = __dx<Real,std::random_access_iterator2d_tag>::dx(it);
4211  Real gy = __dy<Real,std::random_access_iterator2d_tag>::dy(it);
4212  Real gx2 = gx * gx;
4213  Real gy2 = gy * gy;
4214  Real g2 = gx2 + gy2;
4215  Real gxgy = gx * gy;
4216 
4217  Real iee = Real(0);
4218 
4219  if(g2 != 0)
4220  {
4221  Real absgx = std::abs(gx);
4222  Real absgy = std::abs(gy);
4223  Real lambda0 = Real(0);
4224  if ( (absgx > absgy) && (gxgy>=0) )
4225  {
4226  lambda0 = ( Real(2.0) * gx2 + gy2 - gxgy ) / Real(4.0);
4227 
4228  }
4229  else if ( (absgx <= absgy) && (gxgy >= 0) )
4230  {
4231  lambda0 = ( Real(2.0) * gy2 + gx2 - gxgy ) / Real(4.0);
4232 
4233  }
4234  else if ( (absgx > absgy) && (gxgy <= 0) )
4235  {
4236 
4237  lambda0 = ( Real(2.0) * gx2 + gy2 + gxgy ) / Real(4.0);
4238 
4239  }
4240  else
4241  {
4242  lambda0 = ( gy2 + Real(2.0) * gx2 - gxgy ) / Real(4.0);
4243 
4244  }
4245 
4246  Real lambda1 = Real(2.0) * lambda0 - gy2;
4247  Real lambda2 = Real(2.0) *lambda0 - gx2;
4248  Real lambda3 = -lambda0 + Real(0.5) * ( gx2 + gxgy + gy2 );
4249  Real lambda4 = -lambda0 + Real(0.5) * ( gx2 - gxgy + gy2 );
4250  lambda0 = -4.0*lambda0;
4251 
4252  Real center = *it;
4253  Real E = it[slip::n_8c[0]];
4254  Real NE = it[slip::n_8c[1]];
4255  Real N = it[slip::n_8c[2]];
4256  Real NW = it[slip::n_8c[3]];
4257  Real W = it[slip::n_8c[4]];
4258  Real SW = it[slip::n_8c[5]];
4259  Real S = it[slip::n_8c[6]];
4260  Real SE = it[slip::n_8c[7]];
4261 
4262  iee = ( lambda4 * (NW + SE)
4263  + lambda3 * (NE + SW)
4264  + lambda2 * (N + S)
4265  + lambda1 * (W + E)
4266  + lambda0 * center)/ g2;
4267  }
4268 
4269  return(iee);
4270 
4271  }
4272 };
4273 template<typename Real> struct Iee_Alvarez2
4274 {
4276  template<typename Iterator>
4277  Real operator() (Iterator& it) const
4278  {
4279  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
4280  return __iee_alvarez2<Real,_Category>::iee_alvarez2(it);
4281  }
4282 };
4283 //
4284 template<typename Real,typename>
4285 struct __iee_cohignac
4286 {
4287  template <typename _II>
4288  static Real
4289  iee_cohignac(_II it)
4290  {
4291  return __dxx<Real,std::random_access_iterator_tag>::dxx(it);
4292  }
4293 };
4294 
4295 template<typename Real>
4296 struct __iee_cohignac<Real, std::random_access_iterator2d_tag>
4297 {
4298  template <typename _II>
4299  static Real
4300  iee_cohignac(_II it)
4301  {
4302 
4303  Real gx = __dx<Real,std::random_access_iterator2d_tag>::dx(it);
4304  Real gy = __dy<Real,std::random_access_iterator2d_tag>::dy(it);
4305  Real gx2 = gx * gx;
4306  Real gy2 = gy * gy;
4307  Real g2 = gx2 + gy2;
4308  Real gxgy = gx * gy;
4309 
4310  Real iee = Real(0);
4311 
4312  if(g2 != 0)
4313  {
4314  Real lambda0 = Real(0.5) - gx2/g2 + (gx2 / g2) * (gy2 / g2);
4315  Real lambda1 = Real(2.0) * lambda0 - gy2 /g2;
4316  Real lambda2 = Real(2.0) * lambda0 - gx2 / g2;
4317  Real lambda3 = -lambda0 + Real(0.5) * (Real(1.0) + gxgy / g2);
4318  Real lambda4 = -lambda0 + Real(0.5) * (Real(1.0) - gxgy / g2);
4319  lambda0 = Real(-4.0) * lambda0;
4320  Real center = *it;
4321  Real E = it[slip::n_8c[0]];
4322  Real NE = it[slip::n_8c[1]];
4323  Real N = it[slip::n_8c[2]];
4324  Real NW = it[slip::n_8c[3]];
4325  Real W = it[slip::n_8c[4]];
4326  Real SW = it[slip::n_8c[5]];
4327  Real S = it[slip::n_8c[6]];
4328  Real SE = it[slip::n_8c[7]];
4329 
4330  iee = ( lambda4 * (NW + SE)
4331  + lambda3 * (NE + SW)
4332  + lambda2 * (N + S)
4333  + lambda1 * (W + E)
4334  + lambda0 * center);
4335  }
4336 
4337  return(iee);
4338 
4339  }
4340 };
4341 template<typename Real> struct Iee_Cohignac
4342 {
4344  template<typename Iterator>
4345  Real operator() (Iterator& it) const
4346  {
4347  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
4348  return __iee_cohignac<Real,_Category>::iee_cohignac(it);
4349  }
4350 };
4351 
4352 
4353 //
4354 // local second derivative in the direction
4355 // perpendicular to the gradient
4356 //
4357 template<typename Real,typename>
4358 struct __inn_sapiro
4359 {
4360  template <typename _II>
4361  static Real
4362  inn_sapiro(_II it)
4363  {
4364  return __dxx<Real,std::random_access_iterator_tag>::dxx(it);
4365  }
4366 };
4367 
4368 template<typename Real>
4369 struct __inn_sapiro<Real, std::random_access_iterator2d_tag>
4370 {
4371  template <typename _II>
4372  static Real
4373  inn_sapiro(_II it)
4374  {
4375 
4376  Real gx = __dx<Real,std::random_access_iterator2d_tag>::dx(it);
4377  Real gy = __dy<Real,std::random_access_iterator2d_tag>::dy(it);
4378  Real gx2 = gx * gx;
4379  Real gy2 = gy * gy;
4380  Real g2 = gx2 + gy2;
4381  Real gxgy = gx * gy;
4382  Real inn = Real(0);
4383 
4384  if(g2 != 0)
4385  {
4386  Real lambda1 = gy2;
4387  Real lambda2 = gx2;
4388  Real lambda4 = Real(0.5) * gxgy;
4389  Real lambda3 = - lambda4;
4390  Real lambda0 = Real(-2.0) * (lambda1 + lambda2);
4391  Real center = *it;
4392  Real E = it[slip::n_8c[0]];
4393  Real NE = it[slip::n_8c[1]];
4394  Real N = it[slip::n_8c[2]];
4395  Real NW = it[slip::n_8c[3]];
4396  Real W = it[slip::n_8c[4]];
4397  Real SW = it[slip::n_8c[5]];
4398  Real S = it[slip::n_8c[6]];
4399  Real SE = it[slip::n_8c[7]];
4400 
4401 
4402  inn = ( lambda4 * (NW + SE)
4403  + lambda3 * (NE + SW)
4404  + lambda2 * (S + N)
4405  + lambda1 * (W + E)
4406  + lambda0 * center) / g2 ;
4407  }
4408 
4409 
4410  return(inn);
4411 
4412  }
4413 };
4414 
4415 template<typename Real>
4416 struct __inn_sapiro<Real, std::random_access_iterator3d_tag>
4417 {
4418  template <typename _II>
4419  static Real
4420  inn_sapiro(_II it)
4421  {
4422 
4423  Real dx = __dx<Real,std::random_access_iterator3d_tag>::dx(it);
4424  Real dy = __dy<Real,std::random_access_iterator3d_tag>::dy(it);
4425  Real dz = __dz<Real,std::random_access_iterator3d_tag>::dz(it);
4426 
4427  Real dx2 = dx * dx;
4428  Real dy2 = dy * dy;
4429  Real dz2 = dz + dz;
4430 
4431  Real g2 = (dx2 + dy2) + dz2;
4432 
4433  Real inn = Real(0);
4434 
4435  if(g2 != 0)
4436  {
4437 
4438  Real dxx = __dxx<Real,std::random_access_iterator3d_tag>::dxx(it);
4439  Real dyy = __dyy<Real,std::random_access_iterator3d_tag>::dyy(it);
4440  Real dzz = __dzz<Real,std::random_access_iterator3d_tag>::dzz(it);
4441 
4442  Real dxy = __dxy<Real,std::random_access_iterator3d_tag>::dxy(it);
4443  Real dxz = __dxz<Real,std::random_access_iterator3d_tag>::dxz(it);
4444  Real dyz = __dyz<Real,std::random_access_iterator3d_tag>::dyz(it);
4445 
4446  Real dxdy = dx * dy;
4447  Real dxdz = dx * dz;
4448  Real dydz = dy * dz;
4449 
4450  Real a = (dy2 + dz2) * dxx;
4451  Real b = (dx2 + dz2) * dyy;
4452  Real c = (dx2 + dy2) * dzz;
4453  Real d = - Real(2.0) * (dxdy * dxy);
4454  Real e = - Real(2.0) * (dxdz * dxz);
4455  Real f = - Real(2.0) * (dydz * dyz);
4456 
4457  inn = ((a + b) + (c + d) + (e + f)) / g2;
4458  }
4459  return(inn);
4460 
4461  }
4462 };
4463 
4464 template<typename Real> struct Inn_Sapiro
4465 {
4467  template<typename Iterator>
4468  Real operator() (Iterator& it) const
4469  {
4470  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
4471  return __inn_sapiro<Real,_Category>::inn_sapiro(it);
4472  }
4473 };
4474 
4475 template<typename Real,typename>
4476 struct __inn_lucido
4477 {
4478  template <typename _II>
4479  static Real
4480  inn_lucido(_II it)
4481  {
4482  return __dxx<Real,std::random_access_iterator_tag>::dxx(it);
4483  }
4484 };
4485 
4486 template<typename Real>
4487 struct __inn_lucido<Real, std::random_access_iterator2d_tag>
4488 {
4489  template <typename _II>
4490  static Real
4491  inn_lucido(_II it)
4492  {
4493 
4494  Real gx = __dx<Real,std::random_access_iterator2d_tag>::dx(it);
4495  Real gy = __dy<Real,std::random_access_iterator2d_tag>::dy(it);
4496  Real gx2 = gx * gx;
4497  Real gy2 = gy * gy;
4498  Real g2 = gx2 + gy2;
4499  Real gxgy = gx * gy;
4500  Real inn = Real(0);
4501 
4502  if(g2 != 0)
4503  {
4504  if(gxgy >= 0)
4505  {
4506 
4507 
4508  Real lambda1 = gy2 - gxgy;
4509  Real lambda2 = gx2 - gxgy;
4510  Real lambda4 = gxgy;
4511  Real lambda0 = Real(-2.0) * ((lambda1 + lambda2) + lambda4);
4512  Real center = *it;
4513  Real E = it[slip::n_8c[0]];
4514  Real N = it[slip::n_8c[2]];
4515  Real NW = it[slip::n_8c[3]];
4516  Real W = it[slip::n_8c[4]];
4517  Real S = it[slip::n_8c[6]];
4518  Real SE = it[slip::n_8c[7]];
4519 
4520  inn = ( lambda4 * (NW + SE)
4521  + lambda2 * (S + N)
4522  + lambda1 * (W + E)
4523  + lambda0 * center)/ g2;
4524  }
4525  else
4526  {
4527  Real lambda1 = gy2 + gxgy;
4528  Real lambda2 = gx2 + gxgy;
4529  Real lambda3 = - gxgy;
4530  Real lambda0 = Real(-2.0) * ((lambda1 + lambda2) + lambda3);
4531  Real center = *it;
4532  Real E = it[slip::n_8c[0]];
4533  Real N = it[slip::n_8c[2]];
4534  Real SW = it[slip::n_8c[5]];
4535  Real W = it[slip::n_8c[4]];
4536  Real S = it[slip::n_8c[6]];
4537  Real NE = it[slip::n_8c[1]];
4538  inn = ( lambda3 * (SW + NE)
4539  + lambda2 * (S + N)
4540  + lambda1 * (W + E)
4541  + lambda0 * center)/ g2;
4542  }
4543 
4544  }
4545 
4546 
4547  return(inn);
4548 
4549  }
4550 };
4551 
4552 template<typename Real> struct Inn_Lucido
4553 {
4555  template<typename Iterator>
4556  Real operator() (Iterator& it) const
4557  {
4558  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
4559  return __inn_lucido<Real,_Category>::inn_lucido(it);
4560  }
4561 };
4562 
4563 //
4564 template<typename Real,typename>
4565 struct __inn_augereau
4566 {
4567  template <typename _II>
4568  static Real
4569  inn_augereau(_II it)
4570  {
4571  return __dxx<Real,std::random_access_iterator_tag>::dxx(it);
4572  }
4573 };
4574 
4575 template<typename Real>
4576 struct __inn_augereau<Real, std::random_access_iterator2d_tag>
4577 {
4578  template <typename _II>
4579  static Real
4580  inn_augereau(_II it)
4581  {
4582 
4583  Real gx = __dx<Real,std::random_access_iterator2d_tag>::dx(it);
4584  Real gy = __dy<Real,std::random_access_iterator2d_tag>::dy(it);
4585  Real gx2 = gx * gx;
4586  Real gy2 = gy * gy;
4587  Real g2 = gx2 + gy2;
4588  Real gxgy = gx * gy;
4589  Real absgx = std::abs(gx);
4590  Real absgy = std::abs(gy);
4591  Real inn = Real(0);
4592 
4593  if(g2 != 0)
4594  {
4595  if(absgx >= absgy)
4596  {
4597  Real lambda0 = Real(-2.0) * gx2;
4598  Real lambda2 = gx2 - gy2;
4599  Real lambda3 = Real(0.5) * (gy2 - gxgy);
4600  Real lambda4 = Real(0.5) * (gy2 + gxgy);
4601 
4602  Real center = *it;
4603 
4604  Real NE = it[slip::n_8c[1]];
4605  Real N = it[slip::n_8c[2]];
4606  Real NW = it[slip::n_8c[3]];
4607  Real SW = it[slip::n_8c[5]];
4608  Real S = it[slip::n_8c[6]];
4609  Real SE = it[slip::n_8c[7]];
4610 
4611 
4612  inn = ( lambda4 * (NW + SE)
4613  + lambda3 * (NE + SW)
4614  + lambda2 * (S + N)
4615  + lambda0 * center)/ g2;
4616  }
4617  else
4618  {
4619  Real lambda0 = Real(-2.0) * gy2;
4620  Real lambda1 = gy2 - gx2;
4621  Real lambda3 = Real(0.5) * (gx2 - gxgy);
4622  Real lambda4 = Real(0.5) * (gx2 + gxgy);
4623 
4624  Real center = *it;
4625  Real E = it[slip::n_8c[0]];
4626  Real NE = it[slip::n_8c[1]];
4627 
4628  Real NW = it[slip::n_8c[3]];
4629  Real W = it[slip::n_8c[4]];
4630  Real SW = it[slip::n_8c[5]];
4631  // Real S = it[slip::n_8c[6]];
4632  Real SE = it[slip::n_8c[7]];
4633  inn = ( lambda4 * (NW + SE)
4634  + lambda3 * (NE + SW)
4635  + lambda1 * (E + W)
4636  + lambda0 * center)/ g2;
4637  }
4638 
4639  }
4640 
4641 
4642  return(inn);
4643 
4644  }
4645 };
4646 template<typename Real> struct Inn_Augereau
4647 {
4649  template<typename Iterator>
4650  Real operator() (Iterator& it) const
4651  {
4652  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
4653  return __inn_augereau<Real,_Category>::inn_augereau(it);
4654  }
4655 };
4656 
4657 //
4658 template<typename Real,typename>
4659 struct __inn_alvarez
4660 {
4661  template <typename _II>
4662  static Real
4663  inn_alvarez(_II it)
4664  {
4665  return __dxx<Real,std::random_access_iterator_tag>::dxx(it);
4666  }
4667 };
4668 
4669 template<typename Real>
4670 struct __inn_alvarez<Real, std::random_access_iterator2d_tag>
4671 {
4672  template <typename _II>
4673  static Real
4674  inn_alvarez(_II it)
4675  {
4676 
4677  Real gx = __dx<Real,std::random_access_iterator2d_tag>::dx(it);
4678  Real gy = __dy<Real,std::random_access_iterator2d_tag>::dy(it);
4679  Real gx2 = gx * gx;
4680  Real gy2 = gy * gy;
4681  Real g2 = gx2 + gy2;
4682  Real gxgy = gx * gy;
4683 
4684  Real inn = Real(0);
4685 
4686  if(g2 != 0)
4687  {
4688 
4689  Real lambda0 = Real(0.25);
4690  Real lambda1 = Real(2.0) * lambda0 - gx2 / g2;
4691  Real lambda2 = Real(2.0) * lambda0 - gy2 / g2;
4692  Real lambda3 = -lambda0 + Real(0.5) * ( Real(1) - gxgy / g2);
4693  Real lambda4 = -lambda0 + Real(0.5) * ( Real(1) + gxgy / g2);
4694  lambda0 = Real(-1.0);//-4.0*0.25
4695  Real center = *it;
4696  Real E = it[slip::n_8c[0]];
4697  Real NE = it[slip::n_8c[1]];
4698  Real N = it[slip::n_8c[2]];
4699  Real NW = it[slip::n_8c[3]];
4700  Real W = it[slip::n_8c[4]];
4701  Real SW = it[slip::n_8c[5]];
4702  Real S = it[slip::n_8c[6]];
4703  Real SE = it[slip::n_8c[7]];
4704 
4705  inn = ( lambda4 * (NW + SE)
4706  + lambda3 * (NE + SW)
4707  + lambda2 * (N + S)
4708  + lambda1 * (W + E)
4709  + lambda0 * center)/ g2;
4710  }
4711 
4712  return(inn);
4713 
4714  }
4715 };
4716 template<typename Real> struct Inn_Alvarez
4717 {
4719  template<typename Iterator>
4720  Real operator() (Iterator& it) const
4721  {
4722  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
4723  return __inn_alvarez<Real,_Category>::inn_alvarez(it);
4724  }
4725 };
4726 //
4727 template<typename Real,typename>
4728 struct __inn_alvarez2
4729 {
4730  template <typename _II>
4731  static Real
4732  inn_alvarez2(_II it)
4733  {
4734  return __dxx<Real,std::random_access_iterator_tag>::dxx(it);
4735  }
4736 };
4737 
4738 template<typename Real>
4739 struct __inn_alvarez2<Real, std::random_access_iterator2d_tag>
4740 {
4741  template <typename _II>
4742  static Real
4743  inn_alvarez2(_II it)
4744  {
4745 
4746  Real gx = __dx<Real,std::random_access_iterator2d_tag>::dx(it);
4747  Real gy = __dy<Real,std::random_access_iterator2d_tag>::dy(it);
4748  Real gx2 = gx * gx;
4749  Real gy2 = gy * gy;
4750  Real g2 = gx2 + gy2;
4751  Real gxgy = gx * gy;
4752 
4753  Real inn = Real(0);
4754 
4755  if(g2 != 0)
4756  {
4757  Real absgx = std::abs(gx);
4758  Real absgy = std::abs(gy);
4759  Real lambda0 = Real(0);
4760  if ( (absgx > absgy) && (gxgy>=0) )
4761  {
4762  lambda0 = ( Real(2.0) * gy2 + gx2 + gxgy ) / Real(4.0);
4763 
4764  }
4765  else if ( (absgx <= absgy) && (gxgy >= 0) )
4766  {
4767  lambda0 = ( Real(2.0) * gx2 + gy2 + gxgy ) / Real(4.0);
4768 
4769  }
4770  else if ( (absgx > absgy) && (gxgy <= 0) )
4771  {
4772 
4773  lambda0 = ( Real(2.0) * gy2 + gx2 + gxgy ) / Real(4.0);
4774 
4775  }
4776  else
4777  {
4778  lambda0 = ( gx2 + Real(2.0) * gy2 + gxgy ) / Real(4.0);
4779 
4780  }
4781 
4782  Real lambda1 = Real(2.0) * lambda0 - gx2;
4783  Real lambda2 = Real(2.0) *lambda0 - gy2;
4784  Real lambda3 = -lambda0 + Real(0.5) * ( gx2 - gxgy + gy2 );
4785  Real lambda4 = -lambda0 + Real(0.5) * ( gx2 + gxgy + gy2 );
4786  lambda0 = -4.0*lambda0;
4787 
4788  Real center = *it;
4789  Real E = it[slip::n_8c[0]];
4790  Real NE = it[slip::n_8c[1]];
4791  Real N = it[slip::n_8c[2]];
4792  Real NW = it[slip::n_8c[3]];
4793  Real W = it[slip::n_8c[4]];
4794  Real SW = it[slip::n_8c[5]];
4795  Real S = it[slip::n_8c[6]];
4796  Real SE = it[slip::n_8c[7]];
4797 
4798  inn = ( lambda4 * (NW + SE)
4799  + lambda3 * (NE + SW)
4800  + lambda2 * (N + S)
4801  + lambda1 * (W + E)
4802  + lambda0 * center)/ g2;
4803  }
4804 
4805  return(inn);
4806 
4807  }
4808 };
4809 template<typename Real> struct Inn_Alvarez2
4810 {
4812  template<typename Iterator>
4813  Real operator() (Iterator& it) const
4814  {
4815  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
4816  return __inn_alvarez2<Real,_Category>::inn_alvarez2(it);
4817  }
4818 };
4819 //
4820 template<typename Real,typename>
4821 struct __inn_cohignac
4822 {
4823  template <typename _II>
4824  static Real
4825  inn_cohignac(_II it)
4826  {
4827  return __dxx<Real,std::random_access_iterator_tag>::dxx(it);
4828  }
4829 };
4830 
4831 template<typename Real>
4832 struct __inn_cohignac<Real, std::random_access_iterator2d_tag>
4833 {
4834  template <typename _II>
4835  static Real
4836  inn_cohignac(_II it)
4837  {
4838 
4839  Real gx = __dx<Real,std::random_access_iterator2d_tag>::dx(it);
4840  Real gy = __dy<Real,std::random_access_iterator2d_tag>::dy(it);
4841  Real gx2 = gx * gx;
4842  Real gy2 = gy * gy;
4843  Real g2 = gx2 + gy2;
4844  Real gxgy = gx * gy;
4845 
4846  Real inn = Real(0);
4847 
4848  if(g2 != 0)
4849  {
4850  Real lambda0 = Real(0.5) - gx2/g2 + (gx2 / g2) * (gx2 / g2);
4851  Real lambda1 = Real(2.0) * lambda0 - gx2 /g2;
4852  Real lambda2 = Real(2.0) * lambda0 - gy2 / g2;
4853  Real lambda3 = -lambda0 + Real(0.5) * (Real(1.0) - gxgy / g2);
4854  Real lambda4 = -lambda0 + Real(0.5) * (Real(1.0) + gxgy / g2);
4855  lambda0 = Real(-4.0) * lambda0;
4856 
4857  Real center = *it;
4858  Real E = it[slip::n_8c[0]];
4859  Real NE = it[slip::n_8c[1]];
4860  Real N = it[slip::n_8c[2]];
4861  Real NW = it[slip::n_8c[3]];
4862  Real W = it[slip::n_8c[4]];
4863  Real SW = it[slip::n_8c[5]];
4864  Real S = it[slip::n_8c[6]];
4865  Real SE = it[slip::n_8c[7]];
4866 
4867  inn = ( lambda4 * (NW + SE)
4868  + lambda3 * (NE + SW)
4869  + lambda2 * (N + S)
4870  + lambda1 * (W + E)
4871  + lambda0 * center);
4872  }
4873 
4874  return(inn);
4875 
4876  }
4877 };
4878 template<typename Real> struct Inn_Cohignac
4879 {
4881  template<typename Iterator>
4882  Real operator() (Iterator it) const
4883  {
4884  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
4885  return __inn_cohignac<Real,_Category>::inn_cohignac(it);
4886  }
4887 };
4888 
4889 //
4890 //dvv second derivative in the direction of v
4891 //
4892 template<typename Real,typename>
4893 struct __dvv
4894 {
4895  template <typename _II, typename Block>
4896  static Real
4897  dvv(_II it, Block v)
4898  {
4899  assert(Block::SIZE == 1);
4900  Real dxx = __dxx<Real,std::random_access_iterator_tag>::dxx(it);
4901  if(v[0] < Real(0))
4902  {
4903  dxx = -dxx;
4904  }
4905  return dxx;
4906  }
4907 };
4908 
4909 template<typename Real>
4910 struct __dvv<Real,std::random_access_iterator_tag>
4911 {
4912  template <typename _II, typename Block>
4913  static Real
4914  dvv(_II it, Block v)
4915  {
4916  assert(Block::SIZE == 1);
4917  return __dvv<Real,std::random_access_iterator_tag>::dvv(it,v);
4918  }
4919 };
4920 
4921 template<typename Real>
4922 struct __dvv<Real, std::random_access_iterator2d_tag>
4923 {
4924  template <typename _II, typename Block>
4925  static Real
4926  dvv(_II it, Block v)
4927  {
4928  assert(Block::SIZE == 2);
4929  Real result = Real(0);
4930  Real a2 = v[0] * v[0];
4931  Real b2 = v[1] * v[1];
4932  Real norm2 = a2 + b2;
4933 
4934  if(norm2 != Real(0))
4935  {
4936 
4937  Real dxx = __dxx<Real,std::random_access_iterator2d_tag>::dxx(it);
4938  Real dyy = __dyy<Real,std::random_access_iterator2d_tag>::dyy(it);
4939  Real dxy = __dxy<Real,std::random_access_iterator2d_tag>::dxy(it);
4940 
4941  result = (a2 * dxx + 2.0 * v[0] * v[1] * dxy + b2 * dyy) / norm2 ;
4942  }
4943  return result;
4944  }
4945 };
4946 
4947 template<typename Real>
4948 struct __dvv<Real, std::random_access_iterator3d_tag>
4949 {
4950  template <typename _II, typename Block>
4951  static Real
4952  dvv(_II it, Block v)
4953  {
4954  assert(Block::SIZE == 3);
4955  Real result = Real(0);
4956  Real a2 = v[0] * v[0];
4957  Real b2 = v[1] * v[1];
4958  Real c2 = v[2] * v[2];
4959  Real norm2 = a2 + b2 + c2;
4960 
4961  if(norm2 != Real(0))
4962  {
4963  Real dxx = __dxx<Real,std::random_access_iterator3d_tag>::dxx(it);
4964  Real dyy = __dyy<Real,std::random_access_iterator3d_tag>::dyy(it);
4965  Real dzz = __dzz<Real,std::random_access_iterator3d_tag>::dzz(it);
4966 
4967  Real dxy = __dxy<Real,std::random_access_iterator3d_tag>::dxy(it);
4968  Real dxz = __dxz<Real,std::random_access_iterator3d_tag>::dxz(it);
4969  Real dyz = __dyz<Real,std::random_access_iterator3d_tag>::dyz(it);
4970 
4971  Real ab = v[0] * v[1];
4972  Real ac = v[0] * v[2];
4973  Real bc = v[1] * v[2];
4974 
4975  Real a1 = a2 * dxx;
4976  Real a2 = b2 * dyy;
4977  Real a3 = c2 * dzz;
4978  Real a4 = 2.0 * (ab * dxy);
4979  Real a5 = 2.0 * (ac * dxz);
4980  Real a6 = 2.0 * (bc * dyz);
4981 
4982 
4983  result = ((a1 + a2) + (a3 + a4) + (a5 + a6)) / norm2;
4984 
4985  }
4986  return result;
4987  }
4988 };
4989 
4990 
4991 
4992 template<typename Real, typename Block> struct Dvv
4993 {
4994  Dvv(Block v)
4995  :v_(v)
4996  {}
4997  template<typename Iterator>
4998  Real operator() (Iterator& it) const
4999  {
5000  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
5001  return __dvv<Real,_Category>::dvv(it,v_);
5002  }
5003  Block v_;
5004 };
5005 
5006 
5007 //
5008 template<typename Real,typename>
5009 struct __minmodx
5010 {
5011  template <typename _II>
5012  static Real
5013  minmodx(_II it)
5014  {
5015  Real dxp = __dx_fwd<Real,std::random_access_iterator_tag>::dx_fwd(it);
5016  Real dxm = __dx_bck<Real,std::random_access_iterator_tag>::dx_bck(it);
5017 
5018  return minmod<Real>(dxp,dxm);
5019  }
5020 };
5021 
5022 template<typename Real>
5023 struct __minmodx<Real, std::random_access_iterator2d_tag>
5024 {
5025  template <typename _II>
5026  static Real
5027  minmodx(_II it)
5028  {
5029 
5030  Real dxp = __dx_fwd<Real,std::random_access_iterator2d_tag>::dx_fwd(it);
5031  Real dxm = __dx_bck<Real,std::random_access_iterator2d_tag>::dx_bck(it);
5032  return minmod<Real>(dxp,dxm);
5033 
5034  }
5035 };
5036 
5037 template<typename Real>
5038 struct __minmodx<Real, std::random_access_iterator3d_tag>
5039 {
5040  template <typename _II>
5041  static Real
5042  minmodx(_II it)
5043  {
5044 
5045  Real dxp = __dx_fwd<Real,std::random_access_iterator3d_tag>::dx_fwd(it);
5046  Real dxm = __dx_bck<Real,std::random_access_iterator3d_tag>::dx_bck(it);
5047  return minmod<Real>(dxp,dxm);
5048 
5049  }
5050 };
5051 template<typename Real> struct Minmodx
5052 {
5054  template<typename Iterator>
5055  Real operator() (Iterator it) const
5056  {
5057  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
5058  return __minmodx<Real,_Category>::minmodx(it);
5059  }
5060 };
5061 
5062 //
5063 template<typename Real,typename>
5064 struct __minmody
5065 {
5066  template <typename _II>
5067  static Real
5068  minmody(_II it)
5069  {
5070  Real dyp = __dy_fwd<Real,std::random_access_iterator_tag>::dy_fwd(it);
5071  Real dym = __dy_bck<Real,std::random_access_iterator_tag>::dy_bck(it);
5072 
5073  return minmod<Real>(dyp,dym);
5074  }
5075 };
5076 
5077 template<typename Real>
5078 struct __minmody<Real, std::random_access_iterator2d_tag>
5079 {
5080  template <typename _II>
5081  static Real
5082  minmody(_II it)
5083  {
5084 
5085  Real dyp = __dy_fwd<Real,std::random_access_iterator2d_tag>::dy_fwd(it);
5086  Real dym = __dy_bck<Real,std::random_access_iterator2d_tag>::dy_bck(it);
5087  return minmod<Real>(dyp,dym);
5088 
5089  }
5090 };
5091 
5092 template<typename Real>
5093 struct __minmody<Real, std::random_access_iterator3d_tag>
5094 {
5095  template <typename _II>
5096  static Real
5097  minmody(_II it)
5098  {
5099 
5100  Real dyp = __dy_fwd<Real,std::random_access_iterator3d_tag>::dy_fwd(it);
5101  Real dym = __dy_bck<Real,std::random_access_iterator3d_tag>::dy_bck(it);
5102  return minmod<Real>(dyp,dym);
5103 
5104  }
5105 };
5106 template<typename Real> struct Minmody
5107 {
5109  template<typename Iterator>
5110  Real operator() (Iterator it) const
5111  {
5112  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
5113  return __minmody<Real,_Category>::minmody(it);
5114  }
5115 };
5116 
5117 
5118 //
5119 template<typename Real,typename>
5120 struct __minmodz
5121 {
5122  template <typename _II>
5123  static Real
5124  minmodz(_II it)
5125  {
5126  Real dzp = __dz_fwd<Real,std::random_access_iterator_tag>::dz_fwd(it);
5127  Real dzm = __dz_bck<Real,std::random_access_iterator_tag>::dz_bck(it);
5128 
5129  return minmod<Real>(dzp,dzm);
5130  }
5131 };
5132 
5133 template<typename Real>
5134 struct __minmodz<Real, std::random_access_iterator2d_tag>
5135 {
5136  template <typename _II>
5137  static Real
5138  minmodz(_II it)
5139  {
5140 
5141  Real dzp = __dz_fwd<Real,std::random_access_iterator2d_tag>::dz_fwd(it);
5142  Real dzm = __dz_bck<Real,std::random_access_iterator2d_tag>::dz_bck(it);
5143  return minmod<Real>(dzp,dzm);
5144 
5145  }
5146 };
5147 
5148 template<typename Real>
5149 struct __minmodz<Real, std::random_access_iterator3d_tag>
5150 {
5151  template <typename _II>
5152  static Real
5153  minmodz(_II it)
5154  {
5155 
5156  Real dzp = __dz_fwd<Real,std::random_access_iterator3d_tag>::dz_fwd(it);
5157  Real dzm = __dz_bck<Real,std::random_access_iterator3d_tag>::dz_bck(it);
5158  return minmod<Real>(dzp,dzm);
5159 
5160  }
5161 };
5162 template<typename Real> struct Minmodz
5163 {
5165  template<typename Iterator>
5166  Real operator() (Iterator it) const
5167  {
5168  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
5169  return __minmodz<Real,_Category>::minmodz(it);
5170  }
5171 };
5172 
5173 //
5174 // grad minus Osher Sethian
5175 //
5176 template<typename Real,typename>
5177 struct __gradminus_OS
5178 {
5179  template <typename _II>
5180  static Real
5181  gradminus_OS(_II it)
5182  {
5183  Real dxp = __dx_fwd<Real,std::random_access_iterator_tag>::dx_fwd(it);
5184  Real dxm = __dx_bck<Real,std::random_access_iterator_tag>::dx_bck(it);
5185  Real max_x = osher_sethian_minus<Real>(dxp,dxm);
5186  return std::sqrt(max_x);
5187  }
5188 };
5189 
5190 template<typename Real>
5191 struct __gradminus_OS<Real, std::random_access_iterator2d_tag>
5192 {
5193  template <typename _II>
5194  static Real
5195  gradminus_OS(_II it)
5196  {
5197  Real dxp = __dx_fwd<Real,std::random_access_iterator2d_tag>::dx_fwd(it);
5198  Real dxm = __dx_bck<Real,std::random_access_iterator2d_tag>::dx_bck(it);
5199  Real dyp = __dy_fwd<Real,std::random_access_iterator2d_tag>::dy_fwd(it);
5200  Real dym = __dy_bck<Real,std::random_access_iterator2d_tag>::dy_bck(it);
5201  Real max_x = osher_sethian_minus<Real>(dxp,dxm);
5202  Real max_y = osher_sethian_minus<Real>(dyp,dym);
5203  return std::sqrt(max_x + max_y);
5204 
5205  }
5206 };
5207 
5208 template<typename Real>
5209 struct __gradminus_OS<Real, std::random_access_iterator3d_tag>
5210 {
5211  template <typename _II>
5212  static Real
5213  gradminus_OS(_II it)
5214  {
5215  Real dxp = __dx_fwd<Real,std::random_access_iterator3d_tag>::dx_fwd(it);
5216  Real dxm = __dx_bck<Real,std::random_access_iterator3d_tag>::dx_bck(it);
5217  Real dyp = __dy_fwd<Real,std::random_access_iterator3d_tag>::dy_fwd(it);
5218  Real dym = __dy_bck<Real,std::random_access_iterator3d_tag>::dy_bck(it);
5219  Real dzp = __dz_fwd<Real,std::random_access_iterator3d_tag>::dz_fwd(it);
5220  Real dzm = __dz_bck<Real,std::random_access_iterator3d_tag>::dz_bck(it);
5221 
5222  Real max_x = osher_sethian_minus<Real>(dxp,dxm);
5223  Real max_y = osher_sethian_minus<Real>(dyp,dym);
5224  Real max_z = osher_sethian_minus<Real>(dzp,dzm);
5225 
5226  return std::sqrt(max_x + max_y + max_z);
5227 
5228  }
5229 };
5230 template<typename Real> struct Gradminus_OS
5231 {
5233  template<typename Iterator>
5234  Real operator() (Iterator it) const
5235  {
5236  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
5237  return __gradminus_OS<Real,_Category>::gradminus_OS(it);
5238  }
5239 };
5240 
5241 
5242 //
5243 // grad plus Osher Sethian
5244 //
5245 template<typename Real,typename>
5246 struct __gradplus_OS
5247 {
5248  template <typename _II>
5249  static Real
5250  gradplus_OS(_II it)
5251  {
5252  Real dxp = __dx_fwd<Real,std::random_access_iterator_tag>::dx_fwd(it);
5253  Real dxm = __dx_bck<Real,std::random_access_iterator_tag>::dx_bck(it);
5254  Real max_x = osher_sethian_plus<Real>(dxp,dxm);
5255  return std::sqrt(max_x);
5256  }
5257 };
5258 
5259 template<typename Real>
5260 struct __gradplus_OS<Real, std::random_access_iterator2d_tag>
5261 {
5262  template <typename _II>
5263  static Real
5264  gradplus_OS(_II it)
5265  {
5266  Real dxp = __dx_fwd<Real,std::random_access_iterator2d_tag>::dx_fwd(it);
5267  Real dxm = __dx_bck<Real,std::random_access_iterator2d_tag>::dx_bck(it);
5268  Real dyp = __dy_fwd<Real,std::random_access_iterator2d_tag>::dy_fwd(it);
5269  Real dym = __dy_bck<Real,std::random_access_iterator2d_tag>::dy_bck(it);
5270  Real max_x = osher_sethian_plus<Real>(dxp,dxm);
5271  Real max_y = osher_sethian_plus<Real>(dyp,dym);
5272  return std::sqrt(max_x + max_y);
5273 
5274  }
5275 };
5276 
5277 template<typename Real>
5278 struct __gradplus_OS<Real, std::random_access_iterator3d_tag>
5279 {
5280  template <typename _II>
5281  static Real
5282  gradplus_OS(_II it)
5283  {
5284  Real dxp = __dx_fwd<Real,std::random_access_iterator3d_tag>::dx_fwd(it);
5285  Real dxm = __dx_bck<Real,std::random_access_iterator3d_tag>::dx_bck(it);
5286  Real dyp = __dy_fwd<Real,std::random_access_iterator3d_tag>::dy_fwd(it);
5287  Real dym = __dy_bck<Real,std::random_access_iterator3d_tag>::dy_bck(it);
5288  Real dzp = __dz_fwd<Real,std::random_access_iterator3d_tag>::dz_fwd(it);
5289  Real dzm = __dz_bck<Real,std::random_access_iterator3d_tag>::dz_bck(it);
5290 
5291  Real max_x = osher_sethian_plus<Real>(dxp,dxm);
5292  Real max_y = osher_sethian_plus<Real>(dyp,dym);
5293  Real max_z = osher_sethian_plus<Real>(dzp,dzm);
5294 
5295  return std::sqrt(max_x + max_y + max_z);
5296 
5297  }
5298 };
5299 template<typename Real> struct Gradplus_OS
5300 {
5302  template<typename Iterator>
5303  Real operator() (Iterator it) const
5304  {
5305  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
5306  return __gradplus_OS<Real,_Category>::gradplus_OS(it);
5307  }
5308 };
5309 
5310 
5311 //
5312 // grad minus Brockett Maragos
5313 //
5314 template<typename Real,typename>
5315 struct __gradminus_BM
5316 {
5317  template <typename _II>
5318  static Real
5319  gradminus_BM(_II it)
5320  {
5321  Real dxp = __dx_fwd<Real,std::random_access_iterator_tag>::dx_fwd(it);
5322  Real dxm = __dx_bck<Real,std::random_access_iterator_tag>::dx_bck(it);
5323  Real max_x = max_brockett_maragos_minus<Real>(dxp,dxm);
5324  return std::sqrt(max_x);
5325  }
5326 };
5327 
5328 template<typename Real>
5329 struct __gradminus_BM<Real, std::random_access_iterator2d_tag>
5330 {
5331  template <typename _II>
5332  static Real
5333  gradminus_BM(_II it)
5334  {
5335  Real dxp = __dx_fwd<Real,std::random_access_iterator2d_tag>::dx_fwd(it);
5336  Real dxm = __dx_bck<Real,std::random_access_iterator2d_tag>::dx_bck(it);
5337  Real dyp = __dy_fwd<Real,std::random_access_iterator2d_tag>::dy_fwd(it);
5338  Real dym = __dy_bck<Real,std::random_access_iterator2d_tag>::dy_bck(it);
5339  Real max_x = max_brockett_maragos_minus<Real>(dxp,dxm);
5340  Real max_y = max_brockett_maragos_minus<Real>(dyp,dym);
5341  return std::sqrt(max_x + max_y);
5342 
5343  }
5344 };
5345 
5346 template<typename Real>
5347 struct __gradminus_BM<Real, std::random_access_iterator3d_tag>
5348 {
5349  template <typename _II>
5350  static Real
5351  gradminus_BM(_II it)
5352  {
5353  Real dxp = __dx_fwd<Real,std::random_access_iterator3d_tag>::dx_fwd(it);
5354  Real dxm = __dx_bck<Real,std::random_access_iterator3d_tag>::dx_bck(it);
5355  Real dyp = __dy_fwd<Real,std::random_access_iterator3d_tag>::dy_fwd(it);
5356  Real dym = __dy_bck<Real,std::random_access_iterator3d_tag>::dy_bck(it);
5357  Real dzp = __dz_fwd<Real,std::random_access_iterator3d_tag>::dz_fwd(it);
5358  Real dzm = __dz_bck<Real,std::random_access_iterator3d_tag>::dz_bck(it);
5359 
5360  Real max_x = max_brockett_maragos_minus<Real>(dxp,dxm);
5361  Real max_y = max_brockett_maragos_minus<Real>(dyp,dym);
5362  Real max_z = max_brockett_maragos_minus<Real>(dzp,dzm);
5363 
5364  return std::sqrt(max_x + max_y + max_z);
5365 
5366  }
5367 };
5368 template<typename Real> struct Gradminus_BM
5369 {
5371  template<typename Iterator>
5372  Real operator() (Iterator it) const
5373  {
5374  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
5375  return __gradminus_BM<Real,_Category>::gradminus_BM(it);
5376  }
5377 };
5378 
5379 //
5380 // grad plus Brockett Maragos
5381 //
5382 template<typename Real,typename>
5383 struct __gradplus_BM
5384 {
5385  template <typename _II>
5386  static Real
5387  gradplus_BM(_II it)
5388  {
5389  Real dxp = __dx_fwd<Real,std::random_access_iterator_tag>::dx_fwd(it);
5390  Real dxm = __dx_bck<Real,std::random_access_iterator_tag>::dx_bck(it);
5391  Real max_x = max_brockett_maragos_plus<Real>(dxp,dxm);
5392  return std::sqrt(max_x);
5393  }
5394 };
5395 
5396 template<typename Real>
5397 struct __gradplus_BM<Real, std::random_access_iterator2d_tag>
5398 {
5399  template <typename _II>
5400  static Real
5401  gradplus_BM(_II it)
5402  {
5403  Real dxp = __dx_fwd<Real,std::random_access_iterator2d_tag>::dx_fwd(it);
5404  Real dxm = __dx_bck<Real,std::random_access_iterator2d_tag>::dx_bck(it);
5405  Real dyp = __dy_fwd<Real,std::random_access_iterator2d_tag>::dy_fwd(it);
5406  Real dym = __dy_bck<Real,std::random_access_iterator2d_tag>::dy_bck(it);
5407  Real max_x = max_brockett_maragos_plus<Real>(dxp,dxm);
5408  Real max_y = max_brockett_maragos_plus<Real>(dyp,dym);
5409  return std::sqrt(max_x + max_y);
5410 
5411  }
5412 };
5413 
5414 template<typename Real>
5415 struct __gradplus_BM<Real, std::random_access_iterator3d_tag>
5416 {
5417  template <typename _II>
5418  static Real
5419  gradplus_BM(_II it)
5420  {
5421  Real dxp = __dx_fwd<Real,std::random_access_iterator3d_tag>::dx_fwd(it);
5422  Real dxm = __dx_bck<Real,std::random_access_iterator3d_tag>::dx_bck(it);
5423  Real dyp = __dy_fwd<Real,std::random_access_iterator3d_tag>::dy_fwd(it);
5424  Real dym = __dy_bck<Real,std::random_access_iterator3d_tag>::dy_bck(it);
5425  Real dzp = __dz_fwd<Real,std::random_access_iterator3d_tag>::dz_fwd(it);
5426  Real dzm = __dz_bck<Real,std::random_access_iterator3d_tag>::dz_bck(it);
5427 
5428  Real max_x = max_brockett_maragos_plus<Real>(dxp,dxm);
5429  Real max_y = max_brockett_maragos_plus<Real>(dyp,dym);
5430  Real max_z = max_brockett_maragos_plus<Real>(dzp,dzm);
5431 
5432  return std::sqrt(max_x + max_y + max_z);
5433 
5434  }
5435 };
5436 template<typename Real> struct Gradplus_BM
5437 {
5439  template<typename Iterator>
5440  Real operator() (Iterator it) const
5441  {
5442  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
5443  return __gradplus_BM<Real,_Category>::gradplus_BM(it);
5444  }
5445 };
5446 
5447 //
5448 // grad minus minmod
5449 //
5450 template<typename Real,typename>
5451 struct __gradminus_minmod
5452 {
5453  template <typename _II>
5454  static Real
5455  gradminus_minmod(_II it)
5456  {
5457  Real dx = __minmodx<Real,std::random_access_iterator_tag>::minmodx(it);
5458  return std::sqrt(dx);
5459  }
5460 };
5461 
5462 template<typename Real>
5463 struct __gradminus_minmod<Real, std::random_access_iterator2d_tag>
5464 {
5465  template <typename _II>
5466  static Real
5467  gradminus_minmod(_II it)
5468  {
5469  Real dx = __minmodx<Real,std::random_access_iterator2d_tag>::minmodx(it);
5470  Real dy = __minmody<Real,std::random_access_iterator2d_tag>::minmody(it);
5471 
5472  return std::sqrt(dx + dy);
5473  }
5474 };
5475 
5476 template<typename Real>
5477 struct __gradminus_minmod<Real, std::random_access_iterator3d_tag>
5478 {
5479  template <typename _II>
5480  static Real
5481  gradminus_minmod(_II it)
5482  {
5483 
5484  Real dx = __minmodx<Real,std::random_access_iterator3d_tag>::minmodx(it);
5485  Real dy = __minmody<Real,std::random_access_iterator3d_tag>::minmody(it);
5486  Real dz = __minmodz<Real,std::random_access_iterator3d_tag>::minmodz(it);
5487 
5488  return std::sqrt(dx + dy + dz);
5489 
5490  }
5491 };
5492 template<typename Real> struct Gradminus_minmod
5493 {
5495  template<typename Iterator>
5496  Real operator() (Iterator it) const
5497  {
5498  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
5499  return __gradminus_minmod<Real,_Category>::gradminus_minmod(it);
5500  }
5501 };
5502 
5503 template<typename Real> struct Gradplus_minmod
5504 {
5506  template<typename Iterator>
5507  Real operator() (Iterator it) const
5508  {
5509  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
5510  return __gradminus_minmod<Real,_Category>::gradminus_minmod(it);
5511  }
5512 };
5513 
5514 
5516 // Curvatures
5518 //
5519 // cmin : minimal principal curvature
5520 //
5521 template<typename Real,typename>
5522 struct __min_curv
5523 {
5524  template <typename _II>
5525  static Real
5526  min_curv(_II it)
5527  {
5528  Real p = __dx<Real,std::random_access_iterator_tag>::dx(it);
5529  Real r = __dxx<Real,std::random_access_iterator_tag>::dxx(it);
5530  Real p2 = p * p;
5531  return -r / Real(std::sqrt(1.0 + double(p2)));
5532  }
5533 };
5534 
5535 template<typename Real>
5536 struct __min_curv<Real,std::random_access_iterator_tag>
5537 {
5538  template <typename _II>
5539  static Real
5540  min_curv(_II it)
5541  {
5542  Real p = __dx<Real,std::random_access_iterator_tag>::dx(it);
5543  Real r = __dxx<Real,std::random_access_iterator_tag>::dxx(it);
5544  Real p2 = p * p;
5545  return -r / Real(std::sqrt(1.0 + double(p2)));
5546  }
5547 };
5548 
5549 template<typename Real>
5550 struct __min_curv<Real, std::random_access_iterator2d_tag>
5551 {
5552  template <typename _II>
5553  static Real
5554  min_curv(_II it)
5555  {
5556  Real p = __dx<Real,std::random_access_iterator2d_tag>::dx(it);
5557  Real q = __dy<Real,std::random_access_iterator2d_tag>::dy(it);
5558  Real s = __dxy<Real,std::random_access_iterator2d_tag>::dxy(it);
5559  Real r = __dxx<Real,std::random_access_iterator2d_tag>::dxx(it);
5560  Real t = __dyy<Real,std::random_access_iterator2d_tag>::dyy(it);
5561  Real p2 = p * p;
5562  Real q2 = q * q;
5563  Real H = 1 + p2 + q2;
5564  Real n = Real(std::sqrt(H));
5565  Real n3= H * n;
5566 
5567  Real n4 = H * H;
5568  Real ctot = (r * t - s * s) / n4;
5569  Real rau = ( (Real(1) + p2) * t - Real(2) * p * q * s + (Real(1) + q2) * r) / n3;
5570 
5571  return( rau - Real(std::sqrt(rau * rau - ctot)) );
5572  }
5573 };
5574 
5575 
5576 
5577 
5578 template<typename Real> struct Min_Curv
5579 {
5580 
5582  template<typename Iterator>
5583  Real operator() (Iterator& it) const
5584  {
5585  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
5586  return __min_curv<Real,_Category>::min_curv(it);
5587  }
5588 };
5589 
5590 //
5591 // max_curv : maximal principal curvature
5592 //
5593 template<typename Real,typename>
5594 struct __max_curv
5595 {
5596  template <typename _II>
5597  static Real
5598  max_curv(_II it)
5599  {
5600  Real p = __dx<Real,std::random_access_iterator_tag>::dx(it);
5601  Real r = __dxx<Real,std::random_access_iterator_tag>::dxx(it);
5602  Real p2 = p * p;
5603  return -r / Real(std::sqrt(1.0 + double(p2)));
5604 
5605  }
5606 };
5607 
5608 template<typename Real>
5609 struct __max_curv<Real,std::random_access_iterator_tag>
5610 {
5611  template <typename _II>
5612  static Real
5613  max_curv(_II it)
5614  {
5615  Real p = __dx<Real,std::random_access_iterator_tag>::dx(it);
5616  Real r = __dxx<Real,std::random_access_iterator_tag>::dxx(it);
5617  Real p2 = p * p;
5618  return -r / Real(std::sqrt(1.0 + double(p2)));
5619  }
5620 };
5621 
5622 template<typename Real>
5623 struct __max_curv<Real, std::random_access_iterator2d_tag>
5624 {
5625  template <typename _II>
5626  static Real
5627  max_curv(_II it)
5628  {
5629  Real p = __dx<Real,std::random_access_iterator2d_tag>::dx(it);
5630  Real q = __dy<Real,std::random_access_iterator2d_tag>::dy(it);
5631  Real s = __dxy<Real,std::random_access_iterator2d_tag>::dxy(it);
5632  Real r = __dxx<Real,std::random_access_iterator2d_tag>::dxx(it);
5633  Real t = __dyy<Real,std::random_access_iterator2d_tag>::dyy(it);
5634  Real p2 = p * p;
5635  Real q2 = q * q;
5636  Real H = 1 + p2 + q2;
5637  Real n = Real(std::sqrt(H));
5638  Real n3= H * n;
5639 
5640  Real n4 = H * H;
5641  Real ctot = (r * t - s * s) / n4;
5642  Real rau = ( (Real(1) + p2) * t - Real(2) * p * q * s + (Real(1) + q2) * r) / n3;
5643 
5644  return( rau + Real(std::sqrt(rau * rau - ctot)) );
5645  }
5646 };
5647 
5648 
5649 
5650 
5651 
5652 template<typename Real> struct Max_Curv
5653 {
5654 
5656  template<typename Iterator>
5657  Real operator() (Iterator& it) const
5658  {
5659  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
5660  return __max_curv<Real,_Category>::max_curv(it);
5661  }
5662 };
5663 
5664 
5665 //
5666 // mean_curv : mean principal curvature
5667 //
5668 template<typename Real,typename>
5669 struct __mean_curv
5670 {
5671  template <typename _II>
5672  static Real
5673  mean_curv(_II it)
5674  {
5675  Real p = __dx<Real,std::random_access_iterator_tag>::dx(it);
5676  Real r = __dxx<Real,std::random_access_iterator_tag>::dxx(it);
5677  Real p2 = p * p;
5678  return -r / Real(std::sqrt(1.0 + double(p2)));
5679 
5680  }
5681 };
5682 
5683 template<typename Real>
5684 struct __mean_curv<Real,std::random_access_iterator_tag>
5685 {
5686  template <typename _II>
5687  static Real
5688  mean_curv(_II it)
5689  {
5690  Real p = __dx<Real,std::random_access_iterator_tag>::dx(it);
5691  Real r = __dxx<Real,std::random_access_iterator_tag>::dxx(it);
5692  Real p2 = p * p;
5693  return -r / Real(std::sqrt(1.0 + double(p2)));
5694  }
5695 };
5696 
5697 template<typename Real>
5698 struct __mean_curv<Real, std::random_access_iterator2d_tag>
5699 {
5700  template <typename _II>
5701  static Real
5702  mean_curv(_II it)
5703  {
5704  Real p = __dx<Real,std::random_access_iterator2d_tag>::dx(it);
5705  Real q = __dy<Real,std::random_access_iterator2d_tag>::dy(it);
5706  Real s = __dxy<Real,std::random_access_iterator2d_tag>::dxy(it);
5707  Real r = __dxx<Real,std::random_access_iterator2d_tag>::dxx(it);
5708  Real t = __dyy<Real,std::random_access_iterator2d_tag>::dyy(it);
5709  Real p2 = p * p;
5710  Real q2 = q * q;
5711  Real H = 1 + p2 + q2;
5712  Real n = Real(std::sqrt(H));
5713  Real n3= H * n;
5714 
5715  return ( ( (Real(1) + p2) * t - Real(2) * p * q * s + (Real(1) + q2) * r) /(Real(2.0) * n3) );
5716  }
5717 };
5718 
5719 template<typename Real>
5720 struct __mean_curv<Real, std::random_access_iterator3d_tag>
5721 {
5722  template <typename _II>
5723  static Real
5724  mean_curv(_II it)
5725  {
5726 
5727  Real Ix = __dx<Real,std::random_access_iterator3d_tag>::dx(it);
5728  Real Iy = __dy<Real,std::random_access_iterator3d_tag>::dy(it);
5729  Real Iz = __dz<Real,std::random_access_iterator3d_tag>::dz(it);
5730  Real Ixy = __dxy<Real,std::random_access_iterator3d_tag>::dxy(it);
5731  Real Ixz = __dxz<Real,std::random_access_iterator3d_tag>::dxz(it);
5732  Real Iyz = __dyz<Real,std::random_access_iterator3d_tag>::dyz(it);
5733  Real Ixx = __dxx<Real,std::random_access_iterator3d_tag>::dxx(it);
5734  Real Iyy = __dyy<Real,std::random_access_iterator3d_tag>::dyy(it);
5735  Real Izz = __dzz<Real,std::random_access_iterator3d_tag>::dzz(it);
5736 
5737  Real Ix2 = Ix * Ix;
5738  Real Iy2 = Iy * Iy;
5739  Real Iz2 = Iz * Iz;
5740 
5741  Real IxIy = Ix * Iy;
5742  Real IxIz = Ix * Iz;
5743  Real IyIz = Iy * Iz;
5744 
5745  Real a = (Real(1.0) + (Ix2 + Iz2));
5746  Real b = (Real(1.0) + (Iy2 + Iz2));
5747  Real c = (Real(1.0) + (Ix2 + Iy2));
5748 
5749  Real g = (Real(1.0) + Ix2) + (Iy2 + Iz2);
5750 
5751  Real den = Real(std::pow(double(g),double(3.0/2.0)));
5752 
5753  Real H = (
5754  (a * Iyy) + (b * Ixx) + (c * Izz)
5755  - Real(2.0) * IxIy * Ixy
5756  - Real(2.0) * IxIz * Ixz
5757  - Real(2.0) * IyIz * Iyz ) / den ;
5758 
5759  return (H / Real(3.0));
5760  }
5761 };
5762 
5763 
5764 
5765 template<typename Real> struct Mean_Curv
5766 {
5767 
5769  template<typename Iterator>
5770  Real operator() (Iterator& it) const
5771  {
5772  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
5773  return __mean_curv<Real,_Category>::mean_curv(it);
5774  }
5775 };
5776 
5777 //
5778 // total_curv : total principal curvature
5779 //
5780 template<typename Real,typename>
5781 struct __total_curv
5782 {
5783  template <typename _II>
5784  static Real
5785  total_curv(_II it)
5786  {
5787  Real p = __dx<Real,std::random_access_iterator_tag>::dx(it);
5788  Real r = __dxx<Real,std::random_access_iterator_tag>::dxx(it);
5789  Real p2 = p * p;
5790  return -r / Real(std::sqrt(1.0 + double(p2)));
5791  }
5792 };
5793 
5794 template<typename Real>
5795 struct __total_curv<Real,std::random_access_iterator_tag>
5796 {
5797  template <typename _II>
5798  static Real
5799  total_curv(_II it)
5800  {
5801  Real p = __dx<Real,std::random_access_iterator_tag>::dx(it);
5802  Real r = __dxx<Real,std::random_access_iterator_tag>::dxx(it);
5803  Real p2 = p * p;
5804  return -r / Real(std::sqrt(1.0 + double(p2)));
5805  }
5806 };
5807 
5808 template<typename Real>
5809 struct __total_curv<Real, std::random_access_iterator2d_tag>
5810 {
5811  template <typename _II>
5812  static Real
5813  total_curv(_II it)
5814  {
5815  Real p = __dx<Real,std::random_access_iterator2d_tag>::dx(it);
5816  Real q = __dy<Real,std::random_access_iterator2d_tag>::dy(it);
5817  Real s = __dxy<Real,std::random_access_iterator2d_tag>::dxy(it);
5818  Real r = __dxx<Real,std::random_access_iterator2d_tag>::dxx(it);
5819  Real t = __dyy<Real,std::random_access_iterator2d_tag>::dyy(it);
5820  Real p2 = p * p;
5821  Real q2 = q * q;
5822 
5823  Real n = (Real(1) + p2 + q2) * (Real(1) + p2 + q2);
5824 
5825  return (( r * t - s * s) / n);
5826  }
5827 };
5828 
5829 template<typename Real>
5830 struct __total_curv<Real, std::random_access_iterator3d_tag>
5831 {
5832  template <typename _II>
5833  static Real
5834  total_curv(_II it)
5835  {
5836 
5837  Real Ix = __dx<Real,std::random_access_iterator3d_tag>::dx(it);
5838  Real Iy = __dy<Real,std::random_access_iterator3d_tag>::dy(it);
5839  Real Iz = __dz<Real,std::random_access_iterator3d_tag>::dz(it);
5840  Real Ixy = __dxy<Real,std::random_access_iterator3d_tag>::dxy(it);
5841  Real Ixz = __dxz<Real,std::random_access_iterator3d_tag>::dxz(it);
5842  Real Iyz = __dyz<Real,std::random_access_iterator3d_tag>::dyz(it);
5843  Real Ixx = __dxx<Real,std::random_access_iterator3d_tag>::dxx(it);
5844  Real Iyy = __dyy<Real,std::random_access_iterator3d_tag>::dyy(it);
5845  Real Izz = __dzz<Real,std::random_access_iterator3d_tag>::dzz(it);
5846 
5847  Real Ix2 = Ix * Ix;
5848  Real Iy2 = Iy * Iy;
5849  Real Iz2 = Iz * Iz;
5850 
5851  Real Ixy2 = Ixy * Ixy;
5852  Real Ixz2 = Ixz * Ixz;
5853  Real Iyz2 = Iyz * Iyz;
5854 
5855 
5856  Real g = (Real(1.0) + Ix2) + (Iy2 + Iz2);
5857 
5858  Real den = Real(std::pow(double(g),double(2.0/5.0)));
5859 
5860  Real K = ( (Ixx * Iyy) * Izz
5861  + (Real(2.0) * Ixy) * (Ixz * Iyz)
5862  - (Ixx * Iyz2) - (Iyy * Ixz2) - (Izz * Ixy2)) / den;
5863 
5864  return K;
5865 
5866  }
5867 };
5868 
5869 
5870 
5871 template<typename Real> struct Total_Curv
5872 {
5873 
5875  template<typename Iterator>
5876  Real operator() (Iterator& it) const
5877  {
5878  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
5879  return __total_curv<Real,_Category>::total_curv(it);
5880  }
5881 };
5882 
5883 
5884 //
5885 // lambda1 : first eigen value of the hessian matrix
5886 //
5887 template<typename Real,typename>
5888 struct __lambda1_curv
5889 {
5890  template <typename _II>
5891  static Real
5892  lambda1_curv(_II it)
5893  {
5894  return __dxx<Real,std::random_access_iterator_tag>::dxx(it);
5895  }
5896 };
5897 
5898 template<typename Real>
5899 struct __lambda1_curv<Real,std::random_access_iterator_tag>
5900 {
5901  template <typename _II>
5902  static Real
5903  lambda1_curv(_II it)
5904  {
5905  return __dxx<Real,std::random_access_iterator_tag>::dxx(it);
5906  }
5907 };
5908 
5909 template<typename Real>
5910 struct __lambda1_curv<Real, std::random_access_iterator2d_tag>
5911 {
5912  template <typename _II>
5913  static Real
5914  lambda1_curv(_II it)
5915  {
5916  Real s = __dxy<Real,std::random_access_iterator2d_tag>::dxy(it);
5917  Real r = __dxx<Real,std::random_access_iterator2d_tag>::dxx(it);
5918  Real t = __dyy<Real,std::random_access_iterator2d_tag>::dyy(it);
5919  Real s2 = s * s;
5920 
5921  return (((r + t) + Real(std::sqrt(double( (r - t) * (r - t) + 4.0 * s2) ) ) )/ Real(2.0) );
5922  }
5923 };
5924 
5925 
5926 
5927 template<typename Real> struct Lambda1_Curv
5928 {
5929 
5931  template<typename Iterator>
5932  Real operator() (Iterator& it) const
5933  {
5934  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
5935  return __lambda1_curv<Real,_Category>::lambda1_curv(it);
5936  }
5937 };
5938 
5939 
5940 //
5941 // lambda2 : first eigen value of the hessian matrix
5942 //
5943 template<typename Real,typename>
5944 struct __lambda2_curv
5945 {
5946  template <typename _II>
5947  static Real
5948  lambda2_curv(_II it)
5949  {
5950  return __dxx<Real,std::random_access_iterator_tag>::dxx(it);
5951  }
5952 };
5953 
5954 template<typename Real>
5955 struct __lambda2_curv<Real,std::random_access_iterator_tag>
5956 {
5957  template <typename _II>
5958  static Real
5959  lambda2_curv(_II it)
5960  {
5961  return __dxx<Real,std::random_access_iterator_tag>::dxx(it);
5962  }
5963 };
5964 
5965 template<typename Real>
5966 struct __lambda2_curv<Real, std::random_access_iterator2d_tag>
5967 {
5968  template <typename _II>
5969  static Real
5970  lambda2_curv(_II it)
5971  {
5972  Real s = __dxy<Real,std::random_access_iterator2d_tag>::dxy(it);
5973  Real r = __dxx<Real,std::random_access_iterator2d_tag>::dxx(it);
5974  Real t = __dyy<Real,std::random_access_iterator2d_tag>::dyy(it);
5975  Real s2 = s * s;
5976 
5977  return (((r + t) - Real(std::sqrt(double( (r - t) * (r - t) + 4.0 * s2) ) ) )/ Real(2.0) );
5978  }
5979 };
5980 
5981 
5982 
5983 
5984 template<typename Real> struct Lambda2_Curv
5985 {
5986 
5988  template<typename Iterator>
5989  Real operator() (Iterator& it) const
5990  {
5991  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
5992  return __lambda2_curv<Real,_Category>::lambda2_curv(it);
5993  }
5994 };
5995 
5996 
5997 //
5998 // k_iso: isophote curvature
5999 //
6000 template<typename Real,typename>
6001 struct __iso_curv
6002 {
6003  template <typename _II>
6004  static Real
6005  iso_curv(_II it)
6006  {
6007  return __min_curv<Real,std::random_access_iterator_tag>::min_curv(it);
6008  }
6009 };
6010 
6011 template<typename Real>
6012 struct __iso_curv<Real,std::random_access_iterator_tag>
6013 {
6014  template <typename _II>
6015  static Real
6016  iso_curv(_II it)
6017  {
6018  return __min_curv<Real,std::random_access_iterator_tag>::min_curv(it);
6019  }
6020 };
6021 
6022 template<typename Real>
6023 struct __iso_curv<Real, std::random_access_iterator2d_tag>
6024 {
6025  template <typename _II>
6026  static Real
6027  iso_curv(_II it)
6028  {
6029  Real p = __dx<Real,std::random_access_iterator2d_tag>::dx(it);
6030  Real q = __dy<Real,std::random_access_iterator2d_tag>::dy(it);
6031  Real s = __dxy<Real,std::random_access_iterator2d_tag>::dxy(it);
6032  Real r = __dxx<Real,std::random_access_iterator2d_tag>::dxx(it);
6033  Real t = __dyy<Real,std::random_access_iterator2d_tag>::dyy(it);
6034  Real p2 = p * p;
6035  Real q2 = q * q;
6036  Real H = p2 + q2;
6037  Real n = Real(std::sqrt(H));
6038  Real n3= H * n;
6039 
6040  Real result = Real(0.0);
6041 
6042  if(n3 != Real(0.0))
6043  {
6044  result = (Real(2.0) * p * q * s - q2 * r - p2 * t ) / n3;
6045  }
6046  else
6047  {
6048  result = std::numeric_limits<Real>::max();
6049  }
6050  return result;
6051  }
6052 };
6053 
6054 
6055 template<typename Real> struct Iso_Curv
6056 {
6057 
6059  template<typename Iterator>
6060  Real operator() (Iterator& it) const
6061  {
6062  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
6063  return __iso_curv<Real,_Category>::iso_curv(it);
6064  }
6065 };
6066 
6067 //
6068 // courant line curvature
6069 //
6070 template<typename Real,typename>
6071 struct __courant_line_curv
6072 {
6073  template <typename _II>
6074  static Real
6075  courant_line_curv(_II it)
6076  {
6077  return __min_curv<Real,std::random_access_iterator_tag>::min_curv(it);
6078  }
6079 };
6080 
6081 template<typename Real>
6082 struct __courant_line_curv<Real,std::random_access_iterator_tag>
6083 {
6084  template <typename _II>
6085  static Real
6086  courant_line_curv(_II it)
6087  {
6088  return __min_curv<Real,std::random_access_iterator_tag>::min_curv(it);
6089  }
6090 };
6091 
6092 template<typename Real>
6093 struct __courant_line_curv<Real, std::random_access_iterator2d_tag>
6094 {
6095  template <typename _II>
6096  static Real
6097  courant_line_curv(_II it)
6098  {
6099  Real p = __dx<Real,std::random_access_iterator2d_tag>::dx(it);
6100  Real q = __dy<Real,std::random_access_iterator2d_tag>::dy(it);
6101  Real s = __dxy<Real,std::random_access_iterator2d_tag>::dxy(it);
6102  Real r = __dxx<Real,std::random_access_iterator2d_tag>::dxx(it);
6103  Real t = __dyy<Real,std::random_access_iterator2d_tag>::dyy(it);
6104  Real p2 = p * p;
6105  Real q2 = q * q;
6106  Real H = p2 + q2;
6107  Real n = Real(std::sqrt(H));
6108  Real n3= H * n;
6109 
6110  Real result = Real(0.0);
6111 
6112  if(n3 != Real(0.0))
6113  {
6114  result = (p * q * (t - r) + s * (p2 - q2) ) / n3;
6115  }
6116  else
6117  {
6118  result = std::numeric_limits<Real>::max();
6119  }
6120  return result;
6121  }
6122 };
6123 
6124 
6125 template<typename Real> struct Courant_Line_Curv
6126 {
6127 
6129  template<typename Iterator>
6130  Real operator() (Iterator& it) const
6131  {
6132  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
6133  return __courant_line_curv<Real,_Category>::courant_line_curv(it);
6134  }
6135 };
6136 
6137 
6138 //
6139 // computes the relative variation of the gradient along courant lines
6140 //
6141 template<typename Real,typename>
6142 struct __delta_g_curv
6143 {
6144  template <typename _II>
6145  static Real
6146  delta_g_curv(_II it)
6147  {
6148  return __min_curv<Real,std::random_access_iterator_tag>::min_curv(it);
6149  }
6150 };
6151 
6152 template<typename Real>
6153 struct __delta_g_curv<Real,std::random_access_iterator_tag>
6154 {
6155  template <typename _II>
6156  static Real
6157  delta_g_curv(_II it)
6158  {
6159  return __min_curv<Real,std::random_access_iterator_tag>::min_curv(it);
6160  }
6161 };
6162 
6163 template<typename Real>
6164 struct __delta_g_curv<Real, std::random_access_iterator2d_tag>
6165 {
6166  template <typename _II>
6167  static Real
6168  delta_g_curv(_II it)
6169  {
6170  Real p = __dx<Real,std::random_access_iterator2d_tag>::dx(it);
6171  Real q = __dy<Real,std::random_access_iterator2d_tag>::dy(it);
6172  Real s = __dxy<Real,std::random_access_iterator2d_tag>::dxy(it);
6173  Real r = __dxx<Real,std::random_access_iterator2d_tag>::dxx(it);
6174  Real t = __dyy<Real,std::random_access_iterator2d_tag>::dyy(it);
6175  Real p2 = p * p;
6176  Real q2 = q * q;
6177  Real H = p2 + q2;
6178  Real n = Real(std::sqrt(H));
6179  Real n3= H * n;
6180 
6181  Real result = Real(0.0);
6182 
6183  if(n3 != Real(0.0))
6184  {
6185  result = - (((2.0 * p) * (q * s) + (q2 * r) + (p2 * t) ) / n3);
6186  }
6187  else
6188  {
6189  result = std::numeric_limits<Real>::max();
6190  }
6191  return result;
6192  }
6193 };
6194 
6195 
6196 template<typename Real> struct Delta_G_Curv
6197 {
6198 
6200  template<typename Iterator>
6201  Real operator() (Iterator& it) const
6202  {
6203  typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
6204  return __delta_g_curv<Real,_Category>::delta_g_curv(it);
6205  }
6206 };
6207 
6208 
6209 
6211 /* @{ */
6252 template <typename RandomAccessIteratorNd1,
6253  typename RandomAccessIteratorNd2,
6254  typename Operator>
6255 void differential_operator(RandomAccessIteratorNd1 in_first,
6256  RandomAccessIteratorNd1 in_last,
6257  RandomAccessIteratorNd2 out_first,
6258  Operator& op)
6259 {
6260  for(; in_first != in_last; ++in_first, ++out_first)
6261  {
6262  *out_first = op(in_first);
6263  }
6264 }
6319 template <typename RandomAccessIteratorNd1,
6320  typename RandomAccessIteratorNd2,
6321  typename RandomAccessIteratorNd3,
6322  typename Operator1,
6323  typename Operator2>
6324 void differential_operator_2(RandomAccessIteratorNd1 in_first,
6325  RandomAccessIteratorNd1 in_last,
6326  RandomAccessIteratorNd2 out_first1,
6327  RandomAccessIteratorNd3 out_first2,
6328 
6329  Operator1& op1,
6330  Operator2& op2)
6331 {
6332  for(; in_first != in_last; ++in_first, ++out_first1, ++out_first2)
6333  {
6334  *out_first1 = op1(in_first);
6335  *out_first2 = op2(in_first);
6336  }
6337 }
6338 
6399 template <typename RandomAccessIteratorNd1,
6400  typename RandomAccessIteratorNd2,
6401  typename RandomAccessIteratorNd3,
6402  typename RandomAccessIteratorNd4,
6403  typename Operator1,
6404  typename Operator2,
6405  typename Operator3>
6406 void differential_operator_3(RandomAccessIteratorNd1 in_first,
6407  RandomAccessIteratorNd1 in_last,
6408  RandomAccessIteratorNd2 out_first1,
6409  RandomAccessIteratorNd3 out_first2,
6410  RandomAccessIteratorNd4 out_first3,
6411  Operator1& op1,
6412  Operator2& op2,
6413  Operator3& op3)
6414 {
6415  for(; in_first != in_last; ++in_first, ++out_first1, ++out_first2,
6416 ++out_first3)
6417  {
6418  *out_first1 = op1(in_first);
6419  *out_first2 = op2(in_first);
6420  *out_first3 = op3(in_first);
6421  }
6422 }
6423 
6424 /* @} */
6425 
6426 }//slip::
6427 
6428 #endif //SLIP_DERIVATIVES_HPP
Real operator()(Iterator &it) const
Real operator()(Iterator &it) const
Real operator()(Iterator it) const
Dvv(Block v)
Real operator()(Iterator &it) const
Provides a class to modelize 3d points.
Real operator()(Iterator it) const
Real operator()(Iterator &it) const
Real operator()(Iterator &it) const
Real operator()(Iterator &it) const
Real operator()(Iterator &it) const
void center(RandomAccessIterator first, RandomAccessIterator last, RandomAccessIterator2 out_first)
Substracts its mean to a range.
Real operator()(Iterator it) const
Real operator()(Iterator &it) const
reverse_row_iterator row_rbegin(const size_type row)
Returns a read/write reverse iterator that points to the last element of the row row in the Matrix...
Real operator()(Iterator &it) const
Real operator()(Iterator &it) const
Real operator()(Iterator &it) const
Real operator()(Iterator &it)
Real operator()(Iterator &it) const
Real operator()(Iterator it) const
Real operator()(Iterator &it) const
Real operator()(Iterator &it) const
iterator end()
Returns a read/write iterator that points one past the last element in the Vector. Iteration is done in ordinary element order.
Definition: Vector.hpp:1481
Dv(Block v)
T & min(const GrayscaleImage< T > &M1)
Returns the min element of a GrayscaleImage.
Real operator()(Iterator &it) const
Real operator()(Iterator &it) const
Real operator()(Iterator &it) const
Real operator()(Iterator &it) const
Real operator()(Iterator &it) const
Real operator()(Iterator it) const
Real minmod(const Real gplus, const Real gminus)
Real operator()(Iterator &it) const
Provides a class to modelize 4d points.
void differential_operator_2(RandomAccessIteratorNd1 in_first, RandomAccessIteratorNd1 in_last, RandomAccessIteratorNd2 out_first1, RandomAccessIteratorNd3 out_first2, Operator1 &op1, Operator2 &op2)
Applies 2 differential operators on a range.
Real operator()(Iterator &it) const
Real operator()(Iterator &it) const
void derivative_3d(RandomAccessIterator3d1 I_fup, RandomAccessIterator3d1 I_back_bot, const slip::Point3d< T > &grid_step, slip::SPATIAL_DIRECTION der_dir, const std::size_t der_order, const std::size_t sch_order, RandomAccessIterator3d2 R_fup, RandomAccessIterator3d2 R_back_bot)
Computes finite differences derivatives of a 3d range.
Real operator()(Iterator it) const
Real osher_sethian_minus(const Real gplus, const Real gminus)
Real operator()(Iterator &it) const
Real operator()(Iterator &it) const
Provides common linear algebra algorithms.
Real operator()(Iterator &it) const
Real operator()(Iterator &it) const
Real operator()(Iterator &it) const
HyperVolume< T > abs(const HyperVolume< T > &M)
void differential_operator_3(RandomAccessIteratorNd1 in_first, RandomAccessIteratorNd1 in_last, RandomAccessIteratorNd2 out_first1, RandomAccessIteratorNd3 out_first2, RandomAccessIteratorNd4 out_first3, Operator1 &op1, Operator2 &op2, Operator3 &op3)
Applies 3 differential operators on a range.
Real operator()(Iterator &it) const
Real operator()(Iterator &it) const
This is a point2d class, a specialized version of Point<CoordType,DIM> with DIM = 2...
Definition: Array2d.hpp:132
Real operator()(Iterator &it) const
Real max_brockett_maragos_minus(const Real gplus, const Real gminus)
Real operator()(Iterator &it) const
Real operator()(Iterator it) const
reverse_row_iterator row_rend(const size_type row)
Returns a read/write reverse iterator that points one past the first element of the row row in the Ma...
Real operator()(Iterator &it) const
void derivative_2d(Iterator2d1 I_up, Iterator2d1 I_bot, const slip::Point2d< T > &grid_step, slip::SPATIAL_DIRECTION der_dir, const std::size_t der_order, const std::size_t sch_order, Iterator2d2 R_up, Iterator2d2 R_bot)
Computes finite differences derivatives of a 2d range.
Provides a class to manipulate neighbourhood configurations.
Real operator()(Iterator &it) const
Real operator()(Iterator &it) const
This is a point4d class, a specialized version of Point<CoordType,DIM> with DIM = 4...
Real operator()(Iterator &it) const
void finite_diff_coef(const std::size_t sch_ord, const std::size_t sch_shift, Container2D &Dinv)
return finite differences coefficients for derivation based on Taylor series (sch_ord-sch_shift steps...
Real operator()(Iterator &it) const
Real operator()(Iterator &it) const
static _Tp half()
Constant .
Definition: macros.hpp:426
void derivative_4d(RandomAccessIterator4d1 I_ffup, RandomAccessIterator4d1 I_last_back_bot, const slip::Point4d< T > &grid_step, slip::FOUR_DIM_DIRECTION der_dir, const std::size_t der_order, const std::size_t sch_order, RandomAccessIterator4d2 R_ffup, RandomAccessIterator4d2 R_last_back_bot)
Computes finite differences derivatives of a 4d range.
void copy(_II first, _II last, _OI output_first)
Copy algorithm optimized for slip iterators.
Definition: copy_ext.hpp:177
Numerical Vector class. This container statisfies the RandomAccessContainer concepts of the Standard ...
Definition: Vector.hpp:104
Real operator()(Iterator &it) const
HyperVolume< T > sqrt(const HyperVolume< T > &M)
Real operator()(Iterator it) const
Real max_brockett_maragos_plus(const Real gplus, const Real gminus)
Real operator()(Iterator &it) const
Real operator()(Iterator &it) const
Numerical matrix class. This container statisfies the BidirectionnalContainer concepts of the STL...
Real operator()(Iterator &it) const
void same_convolution(SrcIter first, SrcIter last, KernelIter kernel_first, KernelIter kernel_last, std::size_t ksize_left, std::size_t ksize_right, ResIter result, slip::BORDER_TREATMENT bt=slip::BORDER_TREATMENT_ZERO_PADDED)
Computes the same convolution of signal by a 1d-kernel.
void valid_convolution(SrcIter first, SrcIter last, KernelIter kernel_first, KernelIter kernel_last, std::size_t ksize_left, std::size_t ksize_right, ResIter result)
Computes the valid convolution of signal by a 1d-kernel.
void inverse(const Matrix1 &M, const std::size_t nr1, const std::size_t nc1, Matrix2 &IM, const std::size_t nr2, const std::size_t nc2)
Computes the inverse of a matrix using gaussian elimination.
Real operator()(Iterator &it) const
Real operator()(Iterator &it) const
Real operator()(Iterator it) const
Real operator()(Iterator &it) const
Real operator()(Iterator &it) const
std::iterator_traits< RandomAccessIterator1 >::value_type inner_product(RandomAccessIterator1 first1, RandomAccessIterator1 last1, RandomAccessIterator2 first2, typename std::iterator_traits< RandomAccessIterator1 >::value_type init=typename std::iterator_traits< RandomAccessIterator1 >::value_type())
Computes the inner_product of two ranges X and Y: .
Real osher_sethian_plus(const Real gplus, const Real gminus)
Provides some convolution algorithms.
FOUR_DIM_DIRECTION
Choose between different directions in a 4D space.
SPATIAL_DIRECTION
Choose between different spatial directions.
Provides a class to manipulate Numerical Matrix.
Provides a class to modelize 2d points.
Real operator()(Iterator &it) const
void differential_operator(RandomAccessIteratorNd1 in_first, RandomAccessIteratorNd1 in_last, RandomAccessIteratorNd2 out_first, Operator &op)
Applies a differential operator on a range.
Real operator()(Iterator &it) const
Real operator()(Iterator &it) const
void derivative(SrcIter first, SrcIter last, const std::size_t der_ord, const std::size_t sch_ord, const std::size_t sch_shift, const Container2D &M, ResIter result)
Computes 1d finite differences derivatives of an iterator range.
Real operator()(Iterator &it) const
void finite_diff_kernels(const std::size_t der_ord, const std::size_t sch_ord, const std::size_t sch_shift, std::vector< KernelsIterator > &kernels_first)
Computes finite differences kernels for derivation based on Taylor series (sch_ord-sch_shift steps up...
Real operator()(Iterator it) const
row_iterator row_begin(const size_type row)
Returns a read/write iterator that points to the first element of the row row in the Matrix...
Real operator()(Iterator &it) const
Real operator()(Iterator it) const
Provides a class to manipulate numerical vectors.
T & max(const GrayscaleImage< T > &M1)
Returns the max element of a GrayscaleImage.
Real operator()(Iterator &it) const
iterator begin()
Returns a read/write iterator that points to the first element in the Vector. Iteration is done in or...
Definition: Vector.hpp:1474
This is a point3d class, a specialized version of Point<CoordType,DIM> with DIM = 3...