@@ -442,6 +442,10 @@ struct Limits {
442442 template <typename T> Long64_t LocMax (Long64_t n, const T *a);
443443 template <typename Iterator> Iterator LocMax (Iterator first, Iterator last);
444444
445+ // Derivatives of an array
446+ template <typename T> T *Gradient (Long64_t n, T *f, double h = 1 );
447+ template <typename T> T *Laplacian (Long64_t n, T *f, double h = 1 );
448+
445449 // Hashing
446450 ULong_t Hash (const void *txt, Int_t ntxt);
447451 ULong_t Hash (const char *str);
@@ -1002,6 +1006,82 @@ Iterator TMath::LocMin(Iterator first, Iterator last) {
10021006 return std::min_element (first, last);
10031007}
10041008
1009+ // //////////////////////////////////////////////////////////////////////////////
1010+ // / \brief Calculate the one-dimensional gradient of an array with length n.
1011+ // / The first value in the returned array is a forward difference,
1012+ // / the next n-2 values are central differences, and the last is a backward difference.
1013+ // /
1014+ // / \note Function leads to undefined behavior if n does not match the length of f
1015+ // / \param n the number of points in the array
1016+ // / \param f the array of points.
1017+ // / \param h the step size. The default step size is 1.
1018+ // / \return an array of size n with the gradient. Returns nullptr if n < 2 or f empty. Ownership is transferred to the
1019+ // / caller.
1020+
1021+ template <typename T>
1022+ T *TMath::Gradient (const Long64_t n, T *f, const double h)
1023+ {
1024+ if (!f) {
1025+ ::Error (" TMath::Gradient" , " Input parameter f is empty." );
1026+ return nullptr ;
1027+ } else if (n < 2 ) {
1028+ ::Error (" TMath::Gradient" , " Input parameter n=%lld is smaller than 2." , n);
1029+ return nullptr ;
1030+ }
1031+ Long64_t i = 1 ;
1032+ T *result = new T[n];
1033+
1034+ // Forward difference
1035+ result[0 ] = (f[1 ] - f[0 ]) / h;
1036+
1037+ // Central difference
1038+ while (i < n - 1 ) {
1039+ result[i] = (f[i + 1 ] - f[i - 1 ]) / (2 * h);
1040+ i++;
1041+ }
1042+ // Backward difference
1043+ result[i] = (f[i] - f[i - 1 ]) / h;
1044+ return result;
1045+ }
1046+
1047+ // //////////////////////////////////////////////////////////////////////////////
1048+ // / \brief Calculate the Laplacian of an array with length n.
1049+ // / The first value in the returned array is a forward difference,
1050+ // / the next n-2 values are central differences, and the last is a backward difference.
1051+ // /
1052+ // / \note Function leads to undefined behavior if n does not match the length of f
1053+ // / \param n the number of points in the array
1054+ // / \param f the array of points.
1055+ // / \param h the step size. The default step size is 1.
1056+ // / \return an array of size n with the laplacian. Returns nullptr if n < 4 or f empty. Ownership is transferred to the
1057+ // / caller.
1058+
1059+ template <typename T>
1060+ T *TMath::Laplacian (const Long64_t n, T *f, const double h)
1061+ {
1062+ if (!f) {
1063+ ::Error (" TMath::Laplacian" , " Input parameter f is empty." );
1064+ return nullptr ;
1065+ } else if (n < 4 ) {
1066+ ::Error (" TMath::Laplacian" , " Input parameter n=%lld is smaller than 4." , n);
1067+ return nullptr ;
1068+ }
1069+ Long64_t i = 1 ;
1070+ T *result = new T[n];
1071+
1072+ // Forward difference
1073+ result[0 ] = (4 * f[2 ] + 2 * f[0 ] - 5 * f[1 ] - f[3 ]) / (4 * h * h);
1074+
1075+ // Central difference
1076+ while (i < n - 1 ) {
1077+ result[i] = (f[i + 1 ] + f[i - 1 ] - 2 * f[i]) / (4 * h * h);
1078+ i++;
1079+ }
1080+ // Backward difference
1081+ result[i] = (2 * f[i] - 5 * f[i - 1 ] + 4 * f[i - 2 ] - f[i - 3 ]) / (4 * h * h);
1082+ return result;
1083+ }
1084+
10051085// //////////////////////////////////////////////////////////////////////////////
10061086// / Returns index of array with the maximum element.
10071087// / If more than one element is maximum returns first found.
0 commit comments