Skip to content

Commit 7468328

Browse files
rootroot
authored andcommitted
UT and annotations for math_bspline
1 parent eeb8cc7 commit 7468328

File tree

5 files changed

+115
-58
lines changed

5 files changed

+115
-58
lines changed

source/module_base/math_bspline.cpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,12 @@ namespace ModuleBase
3232
}
3333
}
3434

35-
void Bspline::cleanp()
36-
{
37-
delete[] bezier;
38-
bezier = NULL;
39-
}
40-
4135
double Bspline::bezier_ele(int n)
4236
{
4337
return this->bezier[n];
4438
}
4539

46-
void Bspline::getbslpine(double x)
40+
void Bspline::getbspline(double x)
4741
{
4842
bezier[0] = 1.0;
4943
for(int k = 1 ; k <= norder ; ++k)

source/module_base/math_bspline.h

Lines changed: 43 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4,57 +4,54 @@
44
namespace ModuleBase
55
{
66

7-
8-
//
9-
//DESCRIPTION:
10-
// A class to treat Cardinal B-spline interpolation.
11-
// qianrui created 2021-09-14
12-
//MATH:
13-
// Only uniform nodes are considered: xm-x[m-1]=Dx(>= 0) for control node: X={x0,x1,...,xm};
14-
// Any function p(x) can be written by
15-
// p(x)=\sum_i{ci*M_ik(x)} (k->infinity),
16-
// where M_ik is the i-th k-order Cardinal B-spline base function
17-
// and ci is undetermined coefficient.
18-
// M_i0 = H(x-xi)-H(x-x[i+1]), H(x): step function
19-
// x-xi x[i+k+1]-x
20-
// M_ik(x)= ---------*M_i(k-1)(x)+ ----------------*M_[i+1][k-1](x) ( xi <= x <= x[i+1] )
21-
// x[i+k]-xi x[i+k+1]-x[i+1]
22-
// For uniform nodes: M_[i+1]k(x+Dx)=M_ik(x)
23-
// If we define Bk[n] stores M_ik(x+n*Dx) for x in (xi,xi+Dx):
24-
// x+n*Dx-xi xi+(k-n+1)*Dx-x
25-
// Bk[n] = -----------*B(k-1)[n] + -----------------*B(k-1)[n-1]
26-
// k*Dx k*Dx
27-
//USAGE:
28-
// ModuleBase::Bspline bp;
29-
// bp.init(10,0.7,2); //Dx = 0.7, xi = 2
30-
// bp.getbslpine(0.5); //x = 0.5
31-
// cout<<bp.bspline_ele(3)<<endl; //print M_ik[xi+3*Dx+x]: M_i[10](4.6)
32-
//
7+
/**
8+
* @brief A class to treat Cardinal B-spline interpolation.
9+
*
10+
* @author qianrui created 2021-09-14
11+
* @details see: J. Chem. Phys. 103, 8577 (1995).
12+
* Math:
13+
* Only uniform nodes are considered: xm-x[m-1]=Dx(>= 0) for control node: X={x0,x1,...,xm};
14+
* Any function p(x) can be written by
15+
* p(x)=\sum_i{ci*M_ik(x)} (k->infinity),
16+
* where M_ik is the i-th k-order Cardinal B-spline base function
17+
* and ci is undetermined coefficient.
18+
* M_i0 = H(x-xi)-H(x-x[i+1]), H(x): step function
19+
* x-xi x[i+k+1]-x
20+
* M_ik(x)= ---------*M_i(k-1)(x)+ ----------------*M_[i+1][k-1](x) ( xi <= x <= x[i+1] )
21+
* x[i+k]-xi x[i+k+1]-x[i+1]
22+
* For uniform nodes: M_[i+1]k(x+Dx)=M_ik(x)
23+
* If we define Bk[n] stores M_ik(x+n*Dx) for x in (xi,xi+Dx):
24+
* x+n*Dx-xi xi+(k-n+1)*Dx-x
25+
* Bk[n] = -----------*B(k-1)[n] + -----------------*B(k-1)[n-1]
26+
* k*Dx k*Dx
27+
* USAGE:
28+
* ModuleBase::Bspline bp;
29+
* bp.init(10,0.7,2); //Dx = 0.7, xi = 2
30+
* bp.getbslpine(0.5); //x = 0.5
31+
* cout<<bp.bezier_ele(3)<<endl; //print M_ik[xi+3*Dx+x]: M_i[10](4.6)
32+
*
33+
*/
3334
class Bspline
3435
{
35-
private:
36-
int norder; // the order of bezier base; norder >= 0
37-
double Dx; //Dx: the interval of control node
38-
double xi; // xi: the starting point
39-
double *bezier; //bezier[n] = Bk[n]
36+
private:
37+
int norder; // the order of bezier base; norder >= 0
38+
double Dx; // Dx: the interval of control node
39+
double xi; // xi: the starting point
40+
double *bezier; // bezier[n] = Bk[n]
4041

41-
public:
42-
Bspline();
43-
~Bspline();
42+
public:
43+
Bspline();
44+
~Bspline();
4445

45-
//Init norder, Dx, xi
46-
void init(int norderin, double Dxin, double xiin);
46+
void init(int norderin, double Dxin, double xiin);
4747

48-
//delete[] bezier
49-
void cleanp();
48+
// Get the result of i-th bezier base functions for different input x+xi+n*Dx.
49+
// x should be in [0,Dx]
50+
// n-th result is stored in bezier[n];
51+
void getbspline(double x);
5052

51-
//Get the result of i-th bezier base functions for different input x+xi+n*Dx.
52-
//x should be in [0,Dx]
53-
//n-th result is stored in bezier[n];
54-
void getbslpine(double x);
55-
56-
//get the element of bezier
57-
double bezier_ele(int n);
53+
// get the element of bezier
54+
double bezier_ele(int n);
5855
};
59-
}
56+
} // namespace ModuleBase
6057
#endif

source/module_base/test/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,7 @@ AddTest(
8282
LIBS ${math_libs}
8383
SOURCES math_ylmreal_test.cpp ../math_ylmreal.cpp ../realarray.cpp ../timer.cpp ../matrix.cpp
8484
)
85+
AddTest(
86+
TARGET base_math_bspline
87+
SOURCES math_bspline_test.cpp ../math_bspline.cpp
88+
)
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#include "../math_bspline.h"
2+
#include "gtest/gtest.h"
3+
4+
/************************************************
5+
* unit test of class Bspline
6+
***********************************************/
7+
8+
/**
9+
* - Tested Functions:
10+
* - Init
11+
* - norder must be even
12+
* - norder mush be positive
13+
* - Properties
14+
* - \sum_i M_n(u+i) = 1 (i=0,1,2,...n)
15+
*
16+
*/
17+
18+
class MathBsplineTest : public testing::Test
19+
{
20+
protected:
21+
ModuleBase::Bspline bp;
22+
int norder;
23+
};
24+
25+
TEST_F(MathBsplineTest,Init)
26+
{
27+
EXPECT_DEATH(
28+
{
29+
norder = 3; // norder must be even
30+
bp.init(norder,0.05,0);
31+
},""
32+
);
33+
EXPECT_DEATH(
34+
{
35+
norder = 0; // norder must be positive
36+
bp.init(norder,0.05,0);
37+
},""
38+
);
39+
}
40+
41+
// summation over n is unity
42+
TEST_F(MathBsplineTest,Properties)
43+
{
44+
int by = 2;
45+
for (norder=2;norder<=20;norder=norder+by)
46+
{
47+
bp.init(norder,1.0,0);
48+
bp.getbspline(0.2);
49+
double sum=0.0;
50+
//std::cout << "\n" << "norder : "<< norder<<std::endl;
51+
for (int i=0;i<=norder;i++)
52+
{
53+
//std::cout << i << " " << bp.bezier_ele(i) << std::endl;
54+
sum += bp.bezier_ele(i);
55+
}
56+
//std::cout<<"sum "<< sum<< std::endl;
57+
EXPECT_NEAR(sum,1.0,1.e-15);
58+
bp.getbspline(0.0); // must be set to 0.0 to test M_n(0)
59+
EXPECT_NEAR(bp.bezier_ele(0),0,1.e-16);
60+
EXPECT_NEAR(bp.bezier_ele(norder+1),0,1.e-16);
61+
}
62+
}

source/src_pw/bspline_sf.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ void PW_Basis::bspline_sf(const int norder)
4646
bsx.init(norder, 1, 0);
4747
bsy.init(norder, 1, 0);
4848
bsz.init(norder, 1, 0);
49-
bsx.getbslpine(dx);
50-
bsy.getbslpine(dy);
51-
bsz.getbslpine(dz);
49+
bsx.getbspline(dx);
50+
bsy.getbspline(dy);
51+
bsz.getbspline(dz);
5252

5353
for(int iz = 0 ; iz <= norder ; ++iz)
5454
{
@@ -109,7 +109,7 @@ void PW_Basis:: bsplinecoef(complex<double> *b1, complex<double> *b2, complex<do
109109
const std::complex<double> ci_tpi = ModuleBase::NEG_IMAG_UNIT * ModuleBase::TWO_PI;
110110
ModuleBase::Bspline bsp;
111111
bsp.init(norder, 1, 0);
112-
bsp.getbslpine(1.0);
112+
bsp.getbspline(1.0);
113113
for(int ix = 0 ; ix < this->nx ; ++ix)
114114
{
115115
complex<double> fracx=0;
@@ -137,4 +137,4 @@ void PW_Basis:: bsplinecoef(complex<double> *b1, complex<double> *b2, complex<do
137137
}
138138
b3[iz] = exp(ci_tpi*double(norder*iz)/double(nz))/fracz;
139139
}
140-
}
140+
}

0 commit comments

Comments
 (0)