@@ -45,11 +45,41 @@ class toolfunc{
4545 spin_out[2 *i+1 ] = j*spin_in[2 *i];
4646 }
4747 }
48+ #ifdef __MIX_PRECISION
49+ float x7 (float x){
50+ return pow (x,7 );
51+ }
52+ float x6 (float x){
53+ return pow (x,6 );
54+ }
55+ float expr (float x){
56+ return exp (x);
57+ }
58+ std::complex <float > expi (std::complex <float > x){
59+ const std::complex <float > j (0.0 ,1.0 );
60+ return exp (j*x);
61+ }
62+ std::complex <float > expi2 (std::complex <float > x){
63+ const std::complex <float > j (0.0 ,1.0 );
64+ const float PI = 3.14159265358979323846 ;
65+ return exp (j*PI/2.0 *x);
66+ }
67+ // Pauli matrix: [0,-i;i,0]
68+ void sigma_y (std::complex <float >* spin_in, std::complex <float >* spin_out, const int m = 1 ){
69+ const std::complex <float > j (0.0 ,1.0 );
70+ for (int i = 0 ; i < m ; ++i)
71+ {
72+ spin_out[2 *i] = -j*spin_in[2 *i+1 ];
73+ spin_out[2 *i+1 ] = j*spin_in[2 *i];
74+ }
75+ }
76+ #endif
4877};
4978class MathChebyshevTest : public testing ::Test
5079{
5180protected:
5281 ModuleBase::Chebyshev<double > *p_chetest;
82+ ModuleBase::Chebyshev<float > *p_fchetest;
5383 toolfunc fun;
5484};
5585
@@ -205,4 +235,159 @@ TEST_F(MathChebyshevTest,checkconverge)
205235
206236 delete[] v;
207237 delete p_chetest;
208- }
238+ }
239+
240+ #ifdef __MIX_PRECISION
241+ TEST_F (MathChebyshevTest,calcoef_real_float)
242+ {
243+ p_fchetest = new ModuleBase::Chebyshev<float >(10 );
244+ // x^6 = 1/32*( 10T_0 + 15T_2 + 6T_4 + T_6 )
245+ // x^7 = 1/64*( 35T_1 + 21T_3 + 7T_5 + T_7 )
246+ const float x6ref[10 ] = {10 ,0 ,15 ,0 ,6 ,0 ,1 ,0 ,0 ,0 };
247+ const float x7ref[10 ] = {0 ,35 ,0 ,21 ,0 ,7 ,0 ,1 ,0 ,0 };
248+ p_fchetest->calcoef_real (&fun,&toolfunc::x6);
249+ for (int i = 0 ;i < 10 ; ++i)
250+ {
251+ EXPECT_NEAR (p_fchetest->coef_real [i]*32.0 , x6ref[i] ,1 .e -6 );
252+ }
253+ p_fchetest->calcoef_real (&fun,&toolfunc::x7);
254+ for (int i = 0 ;i < 10 ; ++i)
255+ {
256+ EXPECT_NEAR (p_fchetest->coef_real [i]*64.0 , x7ref[i] ,1 .e -6 );
257+ }
258+ delete p_fchetest;
259+ }
260+
261+ TEST_F (MathChebyshevTest,calcoef_pair_float)
262+ {
263+ p_fchetest = new ModuleBase::Chebyshev<float >(10 );
264+ // x^6 = 1/32*( 10T_0 + 15T_2 + 6T_4 + T_6 )
265+ // x^7 = 1/64*( 35T_1 + 21T_3 + 7T_5 + T_7 )
266+ const float x6ref[10 ] = {10 ,0 ,15 ,0 ,6 ,0 ,1 ,0 ,0 ,0 };
267+ const float x7ref[10 ] = {0 ,35 ,0 ,21 ,0 ,7 ,0 ,1 ,0 ,0 };
268+ p_fchetest->calcoef_pair (&fun, &toolfunc::x6, &toolfunc::x7);
269+ for (int i = 0 ;i < 10 ; ++i)
270+ {
271+ EXPECT_NEAR (p_fchetest->coef_complex [i].real ()*32.0 , x6ref[i] ,1 .e -6 );
272+ EXPECT_NEAR (p_fchetest->coef_complex [i].imag ()*64.0 , x7ref[i] ,1 .e -6 );
273+ }
274+ delete p_fchetest;
275+ }
276+
277+ TEST_F (MathChebyshevTest,calcoef_complex_float)
278+ {
279+ const int norder = 100 ;
280+ const float PI = 3.14159265358979323846 ;
281+ p_fchetest = new ModuleBase::Chebyshev<float >(norder);
282+ float *T = new float [norder];
283+ // check exp(i\pi/4) = \sum_n C_n[exp(ix)]T_n(\pi/4) = sqrt(2)/2*(1, i)
284+ p_fchetest->calcoef_complex (&fun, &toolfunc::expi);
285+ p_fchetest->getpolyval (PI/4 , T, norder);
286+ std::complex <float > sum (0 ,0 );
287+ for (int i = 0 ; i < norder ; ++i)
288+ {
289+ sum += p_fchetest->coef_complex [i]*T[i];
290+ }
291+ EXPECT_NEAR (sum.real (), sqrt (2 )/2 ,1 .e -6 );
292+ EXPECT_NEAR (sum.imag (), sqrt (2 )/2 ,1 .e -6 );
293+ delete [] T;
294+ delete p_fchetest;
295+ }
296+
297+ TEST_F (MathChebyshevTest,calfinalvec_real_float)
298+ {
299+ const int norder = 100 ;
300+ const float E = 2.718281828459046 ;
301+ p_fchetest = new ModuleBase::Chebyshev<float >(norder);
302+ // 1 [ 1/e+e -i(e-1/e) ]
303+ // exp(\sigma_y)= - [ ], where \sigma_y = [0, -i; i, 0]
304+ // 2 [ i(e-1/e) 1/e+e ]
305+ std::complex <float > *v = new std::complex <float > [4 ];
306+ std::complex <float > *vout = new std::complex <float > [4 ];
307+ v[0 ] = 1.0 ; v[1 ] = 0.0 ; v[2 ] = 0.0 ; v[3 ] = 1.0 ; // [1 0; 0 1]
308+
309+ p_fchetest->calcoef_real (&fun,&toolfunc::expr);
310+ p_fchetest->calfinalvec_real (&fun, &toolfunc::sigma_y, v, vout, 2 ,2 ,2 );
311+ EXPECT_NEAR (vout[0 ].real (), 0.5 *(E+1 /E) ,1 .e -6 );
312+ EXPECT_NEAR (vout[0 ].imag (), 0 ,1 .e -6 );
313+ EXPECT_NEAR (vout[1 ].real (), 0 ,1 .e -6 );
314+ EXPECT_NEAR (vout[1 ].imag (), 0.5 *(E-1 /E) ,1 .e -6 );
315+ EXPECT_NEAR (vout[2 ].real (), 0 ,1 .e -6 );
316+ EXPECT_NEAR (vout[2 ].imag (),-0.5 *(E-1 /E) ,1 .e -6 );
317+ EXPECT_NEAR (vout[3 ].real (), 0.5 *(E+1 /E) ,1 .e -6 );
318+ EXPECT_NEAR (vout[3 ].imag (), 0 ,1 .e -6 );
319+
320+ delete[] v;
321+ delete[] vout;
322+ delete p_fchetest;
323+ }
324+
325+ TEST_F (MathChebyshevTest,calfinalvec_complex_float)
326+ {
327+ const int norder = 100 ;
328+ const float E = 2.718281828459046 ;
329+ p_fchetest = new ModuleBase::Chebyshev<float >(norder);
330+ // [ 0 1 ]
331+ // exp(i pi/2*\sigma_y)= [ ], where \sigma_y = [0, -i; i, 0]
332+ // [ -1 0 ]
333+ std::complex <float > *v = new std::complex <float > [4 ];
334+ std::complex <float > *vout = new std::complex <float > [4 ];
335+ v[0 ] = 1.0 ; v[1 ] = 0.0 ; v[2 ] = 0.0 ; v[3 ] = 1.0 ; // [1 0; 0 1]
336+
337+ p_fchetest->calcoef_complex (&fun,&toolfunc::expi2);
338+ p_fchetest->calfinalvec_complex (&fun, &toolfunc::sigma_y, v, vout, 2 ,2 ,2 );
339+ EXPECT_NEAR (vout[0 ].real (), 0 ,1 .e -6 );
340+ EXPECT_NEAR (vout[0 ].imag (), 0 ,1 .e -6 );
341+ EXPECT_NEAR (vout[1 ].real (),-1 ,1 .e -6 );
342+ EXPECT_NEAR (vout[1 ].imag (), 0 ,1 .e -6 );
343+ EXPECT_NEAR (vout[2 ].real (), 1 ,1 .e -6 );
344+ EXPECT_NEAR (vout[2 ].imag (), 0 ,1 .e -6 );
345+ EXPECT_NEAR (vout[3 ].real (), 0 ,1 .e -6 );
346+ EXPECT_NEAR (vout[3 ].imag (), 0 ,1 .e -6 );
347+
348+ delete[] v;
349+ delete[] vout;
350+ delete p_fchetest;
351+ }
352+
353+ TEST_F (MathChebyshevTest,tracepolyA_float)
354+ {
355+ const int norder = 100 ;
356+ p_fchetest = new ModuleBase::Chebyshev<float >(norder);
357+
358+ std::complex <float > *v = new std::complex <float > [4 ];
359+ v[0 ] = 1.0 ; v[1 ] = 0.0 ; v[2 ] = 0.0 ; v[3 ] = 1.0 ; // [1 0; 0 1]
360+
361+ p_fchetest->tracepolyA (&fun, &toolfunc::sigma_y, v, 2 ,2 ,2 );
362+ // Trace: even function: 2 ; odd function 0.
363+ for (int i = 0 ; i < norder ; ++i)
364+ {
365+ if (i%2 ==0 ) EXPECT_NEAR (p_fchetest->polytrace [i], 2 ,1 .e -6 );
366+ else EXPECT_NEAR (p_fchetest->polytrace [i], 0 ,1 .e -6 );
367+ }
368+
369+ delete[] v;
370+ delete p_fchetest;
371+ }
372+
373+ TEST_F (MathChebyshevTest,checkconverge_float)
374+ {
375+ const int norder = 100 ;
376+ p_fchetest = new ModuleBase::Chebyshev<float >(norder);
377+
378+ std::complex <float > *v = new std::complex <float > [4 ];
379+ v[0 ] = 1.0 ; v[1 ] = 0.0 ; v[2 ] = 0.0 ; v[3 ] = 1.0 ; // [1 0; 0 1]
380+ float tmin = -1.1 ;
381+ float tmax = 1.1 ;
382+ bool converge;
383+ converge = p_fchetest->checkconverge (&fun, &toolfunc::sigma_y, v, 2 , tmax, tmin, 0.2 );
384+ EXPECT_TRUE (converge);
385+ converge = p_fchetest->checkconverge (&fun, &toolfunc::sigma_y, v+2 , 2 , tmax, tmin, 0.2 );
386+ EXPECT_TRUE (converge);
387+ EXPECT_NEAR (tmin, -1.1 , 1e-6 );
388+ EXPECT_NEAR (tmax, 1.1 , 1e-6 );
389+
390+ delete[] v;
391+ delete p_fchetest;
392+ }
393+ #endif
0 commit comments