Skip to content

Commit d7881c2

Browse files
authored
Merge pull request #35 from FastNFT/release-0.2
Release 0.2.1
2 parents becba5d + 1671cc8 commit d7881c2

File tree

7 files changed

+76
-19
lines changed

7 files changed

+76
-19
lines changed

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
# Changelog
22

3-
## [0.2.0] -- 2018-09
3+
## [0.2.1] -- 2018-09-28
4+
5+
### Fixed
6+
7+
- Computation of norming constants from residues in fnft_nsev_inverse was incorrect when continuous spectrum was present.
8+
9+
## [0.2.0] -- 2018-09-21
410

511
### Added
612

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ project(fnft C)
2121

2222
set(FNFT_VERSION_MAJOR 0)
2323
set(FNFT_VERSION_MINOR 2)
24-
set(FNFT_VERSION_PATCH 0)
24+
set(FNFT_VERSION_PATCH 1)
2525
set(FNFT_VERSION_SUFFIX "") # should not be longer than FNFT_SUFFIX_MAXLEN
2626
set(FNFT_VERSION ${FNFT_VERSION_MAJOR}.${FNFT_VERSION_MINOR}.${FNFT_VERSION_PATCH}${FNFT_VERSION_SUFFIX})
2727

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ FNFT is a software library for the fast numerical computation of (inverse) nonli
99
### Forward Transforms
1010

1111
* Nonlinear Schroedinger equation
12+
1213
* Vanishing boundary conditions
1314
* Reflection coefficient and/or scattering coefficients (a and b)
1415
* Bound states (eigenvalues)
1516
* Norming constants and/or residues
17+
1618
* Periodic boundary conditions
1719
* Main spectrum
1820
* Auxiliary spectrum
@@ -23,6 +25,7 @@ FNFT is a software library for the fast numerical computation of (inverse) nonli
2325
### Inverse Transforms
2426

2527
* Nonlinear Schroedinger equation
28+
2629
* Vanishing boundary conditions
2730
* Inversion of reflection coefficients, b-scattering coefficients or the inverse Fourier transform of the b-coefficient
2831
* Bound states (eigenvalues) can be added with arbitrary norming constants/residuals

src/fnft_nsev_inverse.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#include "fnft__fft_wrapper.h"
3030
#include "fnft__poly_specfact.h"
3131
#include "fnft__misc.h"
32+
#include "fnft__nse_scatter.h"
33+
3234

3335
static fnft_nsev_inverse_opts_t default_opts = {
3436
.discretization = nse_discretization_2SPLIT2A,
@@ -704,6 +706,7 @@ static INT add_discrete_spectrum(
704706
COMPLEX * bnd_states_conj = NULL;
705707
COMPLEX * bnd_states_diff = NULL;
706708
COMPLEX tmp;
709+
COMPLEX * acoeff_cs = NULL;
707710
COMPLEX * phi = NULL;
708711
COMPLEX * psi = NULL;
709712
UINT i,j;
@@ -716,9 +719,10 @@ static INT add_discrete_spectrum(
716719
norm_consts = malloc(K * sizeof(COMPLEX));
717720
bnd_states_conj = malloc(K * sizeof(COMPLEX));
718721
bnd_states_diff = malloc(K * sizeof(COMPLEX));
722+
acoeff_cs = malloc(3*K * sizeof(COMPLEX));
719723
if (t == NULL || bnd_states == NULL ||
720724
bnd_states_conj == NULL || bnd_states_diff == NULL ||
721-
norm_consts == NULL) {
725+
norm_consts == NULL || acoeff_cs == NULL) {
722726
ret_code = E_NOMEM;
723727
goto leave_fun;
724728
}
@@ -768,16 +772,29 @@ static INT add_discrete_spectrum(
768772
//CDT works with norming constants so residues need to be converted to
769773
// norming constants
770774
if (opts_ptr->discspec_type == fnft_nsev_inverse_dstype_RESIDUES){
775+
if (contspec_flag != 0){
776+
//When continuous spectrum exists, the non-solitonic component
777+
// of the potential contributes to the residues and needs to be
778+
// removed.
779+
UINT trunc_index;
780+
trunc_index = D;
781+
ret_code = nse_scatter_bound_states(D, q, T, &trunc_index, K,
782+
bnd_states, acoeff_cs, acoeff_cs+K, acoeff_cs+2*K, nse_discretization_BO);
783+
CHECK_RETCODE(ret_code, leave_fun);
784+
}
785+
else {
786+
for (i = 0; i < K; i++)
787+
acoeff_cs[i] = 1;
788+
}
771789
for (i = 0; i < K; i++){
772-
tmp = 1;
790+
tmp = acoeff_cs[i];
773791
for (j = 0; j < K; j++){
774792
if (j != i){
775793
tmp = tmp*(bnd_states[i]-bnd_states[j])/(bnd_states[i]-CONJ(bnd_states[j]));
776794
}
777795
}
778796
norm_consts[i]=(norm_consts[i]/bnd_states_diff[i])*tmp;
779-
}
780-
797+
}
781798
}
782799

783800
// In absence of contspec some tricks can be used to
@@ -896,6 +913,7 @@ static INT add_discrete_spectrum(
896913
free(bnd_states_conj);
897914
free(bnd_states_diff);
898915
free(norm_consts);
916+
free(acoeff_cs);
899917
return ret_code;
900918
}
901919

test/fnft_nsev_inverse/fnft_nsev_inverse_test_against_forward/fnft_nsev_inverse_test_against_forward_w_discrete.inc

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
#include <stdio.h>
3131

3232
static INT fnft_nsev_inverse_test(const UINT D, const UINT M,
33-
const REAL error_bound, fnft_nsev_inverse_opts_t * opts_ptr)
33+
const REAL error_bound, fnft_nsev_inverse_opts_t * opts_inv_ptr)
3434
{
3535
if (M < D)
3636
return E_INVALID_ARGUMENT(M);
@@ -70,9 +70,13 @@ static INT fnft_nsev_inverse_test(const UINT D, const UINT M,
7070
//Setting up forward transform options
7171
fnft_nsev_opts_t opts_fwd = fnft_nsev_default_opts();
7272
opts_fwd.discretization = nse_discretization_2SPLIT4B;
73+
if (opts_inv_ptr->discspec_type == fnft_nsev_inverse_dstype_RESIDUES)
74+
opts_fwd.discspec_type = nsev_dstype_RESIDUES;
75+
else if (opts_inv_ptr->discspec_type == fnft_nsev_inverse_dstype_NORMING_CONSTANTS)
76+
opts_fwd.discspec_type = nsev_dstype_NORMING_CONSTANTS;
7377

7478
//Obtain XI grid
75-
ret_code = fnft_nsev_inverse_XI(D, T, M, XI, opts_ptr->discretization);
79+
ret_code = fnft_nsev_inverse_XI(D, T, M, XI, opts_inv_ptr->discretization);
7680
CHECK_RETCODE(ret_code, leave_fun);
7781

7882
//Perform full forward NFT
@@ -82,7 +86,7 @@ static INT fnft_nsev_inverse_test(const UINT D, const UINT M,
8286

8387
//Perform full inverse NFT
8488
ret_code = fnft_nsev_inverse(M, contspec, XI, *K_ptr, bound_states, normconsts_or_residues, D, q, T,
85-
kappa, opts_ptr);
89+
kappa, opts_inv_ptr);
8690
CHECK_RETCODE(ret_code, leave_fun);
8791

8892
REAL error = misc_rel_err(D, q, q_exact);

test/fnft_nsev_inverse/fnft_nsev_inverse_test_against_forward/fnft_nsev_inverse_test_against_forward_w_discrete_2split2A.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,34 @@ int main()
2727
REAL error_bound;
2828
INT ret_code = SUCCESS;
2929

30-
fnft_nsev_inverse_opts_t opts = fnft_nsev_inverse_default_opts();
31-
opts.discretization = nse_discretization_2SPLIT2A;
32-
opts.discspec_type = fnft_nsev_inverse_dstype_NORMING_CONSTANTS;
30+
fnft_nsev_inverse_opts_t opts_inv = fnft_nsev_inverse_default_opts();
31+
opts_inv.discretization = nse_discretization_2SPLIT2A;
32+
opts_inv.discspec_type = fnft_nsev_inverse_dstype_NORMING_CONSTANTS;
3333

34+
D = 512;
35+
M = 2*D;
36+
error_bound = 0.014;
37+
ret_code = fnft_nsev_inverse_test(D, M, error_bound, &opts_inv);
38+
CHECK_RETCODE(ret_code, leave_fun);
39+
40+
D = D*2;
41+
M = 2*D;
42+
error_bound = error_bound/4;
43+
ret_code = fnft_nsev_inverse_test(D, M, error_bound, &opts_inv);
44+
CHECK_RETCODE(ret_code, leave_fun);
45+
46+
opts_inv.discspec_type = fnft_nsev_inverse_dstype_RESIDUES;
3447

3548
D = 512;
3649
M = 2*D;
3750
error_bound = 0.014;
38-
ret_code = fnft_nsev_inverse_test(D, M, error_bound, &opts);
51+
ret_code = fnft_nsev_inverse_test(D, M, error_bound, &opts_inv);
3952
CHECK_RETCODE(ret_code, leave_fun);
4053

4154
D = D*2;
4255
M = 2*D;
4356
error_bound = error_bound/4;
44-
ret_code = fnft_nsev_inverse_test(D, M, error_bound, &opts);
57+
ret_code = fnft_nsev_inverse_test(D, M, error_bound, &opts_inv);
4558
CHECK_RETCODE(ret_code, leave_fun);
4659

4760

test/fnft_nsev_inverse/fnft_nsev_inverse_test_against_forward/fnft_nsev_inverse_test_against_forward_w_discrete_2split2_modal.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,34 @@ int main()
2727
REAL error_bound;
2828
INT ret_code = SUCCESS;
2929

30-
fnft_nsev_inverse_opts_t opts = fnft_nsev_inverse_default_opts();
31-
opts.discretization = nse_discretization_2SPLIT2_MODAL;
32-
opts.discspec_type = fnft_nsev_inverse_dstype_NORMING_CONSTANTS;
30+
fnft_nsev_inverse_opts_t opts_inv = fnft_nsev_inverse_default_opts();
31+
opts_inv.discretization = nse_discretization_2SPLIT2_MODAL;
32+
opts_inv.discspec_type = fnft_nsev_inverse_dstype_NORMING_CONSTANTS;
3333

34+
D = 512;
35+
M = 2*D;
36+
error_bound = 0.014;
37+
ret_code = fnft_nsev_inverse_test(D, M, error_bound, &opts_inv);
38+
CHECK_RETCODE(ret_code, leave_fun);
39+
40+
D = D*2;
41+
M = 2*D;
42+
error_bound = error_bound/4;
43+
ret_code = fnft_nsev_inverse_test(D, M, error_bound, &opts_inv);
44+
CHECK_RETCODE(ret_code, leave_fun);
45+
46+
opts_inv.discspec_type = fnft_nsev_inverse_dstype_RESIDUES;
3447

3548
D = 512;
3649
M = 2*D;
3750
error_bound = 0.014;
38-
ret_code = fnft_nsev_inverse_test(D, M, error_bound, &opts);
51+
ret_code = fnft_nsev_inverse_test(D, M, error_bound, &opts_inv);
3952
CHECK_RETCODE(ret_code, leave_fun);
4053

4154
D = D*2;
4255
M = 2*D;
4356
error_bound = error_bound/4;
44-
ret_code = fnft_nsev_inverse_test(D, M, error_bound, &opts);
57+
ret_code = fnft_nsev_inverse_test(D, M, error_bound, &opts_inv);
4558
CHECK_RETCODE(ret_code, leave_fun);
4659

4760

0 commit comments

Comments
 (0)