Program Listing for File Utils.cc¶
↰ Return to documentation for file (Utils.cc)
/*--------------------------------------------------------------------------*\
| |
| Copyright (C) 2017 |
| |
| , __ , __ |
| /|/ \ /|/ \ |
| | __/ _ ,_ | __/ _ ,_ |
| | \|/ / | | | | \|/ / | | | |
| |(__/|__/ |_/ \_/|/|(__/|__/ |_/ \_/|/ |
| /| /| |
| \| \| |
| |
| Enrico Bertolazzi |
| Dipartimento di Ingegneria Industriale |
| Universita` degli Studi di Trento |
| email: enrico.bertolazzi@unitn.it |
| |
\*--------------------------------------------------------------------------*/
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#include "Utils.hh"
namespace Utils {
using std::string;
using std::lower_bound;
/*\
:|: _
:|: | |__ __ _ ___ ___ _ _ __ _ _ __ ___
:|: | '_ \/ _` (_-</ -_) ' \/ _` | ' \/ -_)
:|: |_.__/\__,_/__/\___|_||_\__,_|_|_|_\___|
:|:
\*/
#ifdef UTILS_OS_WINDOWS
string
basename( char const * const path ) {
static char drive[100];
static char dir[1024];
static char fname[256];
static char ext[128];
errno_t e = _splitpath_s(
path,
drive, 100,
dir, 1024,
fname, 256,
ext, 128
);
UTILS_ASSERT0( e == 0, "lapack_wrapper, basename failed!\n" );
return fname;
}
#else
string
basename( char const * const path ) {
if ( path[0] == '\0' ) return string("");
string filename(path);
size_t len = filename.length();
size_t index = filename.find_last_of("/\\");
if ( index == string::npos ) return filename;
if ( index + 1 >= len ) {
--len;
index = filename.substr(0, len).find_last_of("/\\");
if ( len == 0 ) return filename;
if ( index == 0 ) return filename.substr(1, len - 1);
if ( index == string::npos ) return filename.substr(0, len);
return filename.substr(index + 1, len - index - 1);
}
return filename.substr(index + 1, len - index);
}
#endif
/*\
| _ ___ _ _
| ___ ___ __ _ _ __ ___| |__ |_ _|_ __ | |_ ___ _ ____ ____ _| |
| / __|/ _ \/ _` | '__/ __| '_ \ | || '_ \| __/ _ \ '__\ \ / / _` | |
| \__ \ __/ (_| | | | (__| | | || || | | | || __/ | \ V / (_| | |
| |___/\___|\__,_|_| \___|_| |_|___|_| |_|\__\___|_| \_/ \__,_|_|
\*/
template <typename T_int, typename T_real>
void
searchInterval(
T_int npts,
T_real const * const X,
T_real & x,
T_int & lastInterval,
bool closed,
bool can_extend
) {
// check points
T_int n = npts-1;
UTILS_ASSERT(
npts > 1 && lastInterval >= 0 && lastInterval < n,
"In searchInterval( npts={}, X, x={}, lastInterval={}, closed={}, can_extend={})\n"
"npts musrt be >= 2 and lastInterval must be in [0,npts-2]\n",
npts, lastInterval, closed, can_extend
);
// checl range
T_real xl = X[0];
T_real xr = X[n];
if ( closed ) { // put x in range (change also its value)
T_real L = xr-xl;
x -= xl;
x = fmod( x, L );
if ( x < 0 ) x += L;
x += xl;
} else {
UTILS_ASSERT(
can_extend || (x >= xl && x <= xr),
"In searchInterval( npts={}, X, x={}, lastInterval={}, closed={}, can_extend={})\n"
"out of range: [{},{}]\n",
npts, lastInterval, closed, can_extend, xl, xr
);
}
// find the interval of the support of the B-spline
T_real const * XL = X+lastInterval;
if ( XL[1] < x ) { // x on the right
if ( x >= X[n-1] ) {
lastInterval = n-1; // last interval
} else if ( x < XL[2] ) { // x in (XL[1],XL[2])
++lastInterval;
} else { // x >= XL[2] search the right interval
T_real const * XE = X+n;
lastInterval += T_int(lower_bound( XL, XE, x )-XL);
T_real const * XX = X+lastInterval;
if ( x < XX[0] || Utils::isZero(XX[0]-XX[1]) ) --lastInterval;
}
} else if ( x < XL[0] ) { // on the left
if ( x <= X[1] ) { // x in [X[0],X[1]]
lastInterval = 0; // first interval
} else if ( XL[-1] <= x ) { // x in [XL[-1],XL[0])
--lastInterval;
} else {
lastInterval = T_int(lower_bound( X+1, XL, x )-X);
T_real const * XX = X+lastInterval;
if ( x < XX[0] || Utils::isZero(XX[0]-XX[1]) ) --lastInterval;
}
} else {
// x in the interval [ XL[0], XL[1] ] nothing to do
}
// check computed interval
UTILS_ASSERT(
lastInterval >= 0 && lastInterval < n,
"In searchInterval( npts={}, X, x={}, lastInterval={}, closed={}, can_extend={})\n"
"computed lastInterval of range: [{},{}]\n",
npts, lastInterval, closed, can_extend, xl, xr
);
}
extern template void searchInterval(
int32_t npts,
float const * const X,
float & x,
int32_t & lastInterval,
bool closed,
bool can_extend
);
template void searchInterval(
int32_t npts,
double const * const X,
double & x,
int32_t & lastInterval,
bool closed,
bool can_extend
);
template void searchInterval(
int64_t npts,
float const * const X,
float & x,
int64_t & lastInterval,
bool closed,
bool can_extend
);
template void searchInterval(
int64_t npts,
double const * const X,
double & x,
int64_t & lastInterval,
bool closed,
bool can_extend
);
}
#endif