AppendTo[$Path, NotebookDirectory[]];
<<PrintVector`

P=64;(* Working precision. *)

GenerateFilename[prefix_][NN_,M_]:=Module[{d=Length[NN], (* Dimension. *)},Return[FileNameJoin[{prefix,"nfft_"<>ToString[d]<>"d_"<>StringJoin[Map[Function[x,ToString[x]<>"_"],NN]<>ToString[M]<>".txt"]}]]]
GenerateFilenameAdjoint[prefix_][NN_,M_]:=Module[{d=Length[NN], (* Dimension. *)},Return[FileNameJoin[{prefix,"nfft_adjoint_"<>ToString[d]<>"d_"<>StringJoin[Map[Function[x,ToString[x]<>"_"],NN]<>ToString[M]<>".txt"]}]]]
Generate[NN_,M_,FilenameGenerator_]:=Module[
{
d=Length[NN], (* Dimension. *)
file
},
SeedRandom[1];
II=Table[Table[k,{k,Ceiling[-NN[[i]]/2],Floor[(NN[[i]]-1)/2]}],{i,1,d}];
II[[0]]=Sequence;
II=Flatten[Outer[List,II],d-1];(* Index set. *)
x =Transpose[ Table[RandomReal[{-1/2,1/2},M,WorkingPrecision->P],{i,1,d}]] ;(* Random nodes. *)
fhat = (*Table[If[i==1,1,0],{i,1,Length[II]}]*) RandomComplex[{-1-I,1+I},Length[II],WorkingPrecision->P]; (* Random Fourier coefficients. *)
f=Table[Sum[fhat[[k]]*Exp[-2*π*I*Dot[II[[k]],x[[j]]]],{k,1,Length[II]}],{j,1,M}];(* Function values. *)
filename=FilenameGenerator[NN,M];
file = OpenWrite[filename];
WriteString[file, FormatIntegerRaw[d] <>"\n"];
WriteString[file, FormatIntegerVectorRaw[NN]<>"\n"];
WriteString[file, FormatIntegerRaw[M]<>"\n"];
WriteString[file, FormatVectorRaw[Flatten[x]]<>"\n"];
WriteString[file, FormatVectorRaw[fhat]<>"\n"];
WriteString[file, FormatVectorRaw[f]<>"\n"];
Close[file];
(*Print[filename];*)
Return[{FileBaseName[FileNameTake[filename,-1]], FileNameTake[filename,-2]}]
]
GenerateAdjoint[NN_,M_,FilenameGenerator_]:=Module[
{
d=Length[NN], (* Dimension. *)
file
},
SeedRandom[1];
II=Table[Table[k,{k,Ceiling[-NN[[i]]/2],Floor[(NN[[i]]-1)/2]}],{i,1,d}];
II[[0]]=Sequence;
II=Flatten[Outer[List,II],d-1];(* Index set. *)
x=Transpose[Table[RandomReal[{-1/2,1/2},M,WorkingPrecision->P],{i,1,d}]] ;(* Random nodes. *)
f=RandomComplex[{-1-I,1+I},M,WorkingPrecision->P];(* Random function values. *)
fhat=Table[Sum[f[[j]]*Exp[2*π*I*Dot[II[[k]],x[[j]]]],{j,1,M}],{k,1,Length[II]}];(* Pseudo Fourier coefficients. *)
filename=FilenameGenerator[NN,M];
file = OpenWrite[filename];
WriteString[file, FormatIntegerRaw[d] <>"\n"];
WriteString[file, FormatIntegerVectorRaw[NN]<>"\n"];
WriteString[file, FormatIntegerRaw[M]<>"\n"];
WriteString[file, FormatVectorRaw[Flatten[x]]<>"\n"];
WriteString[file, FormatVectorRaw[fhat]<>"\n"];
WriteString[file, FormatVectorRaw[f]<>"\n"];
Close[file];
(*Print[filename];*)
Return[{FileBaseName[FileNameTake[filename,-1]], FileNameTake[filename,-2]}]
]
MakeTestcase[NN_,M_]:=Generate[NN,M,GenerateFilename[FileNameJoin[{NotebookDirectory[],"data"}]]]
MakeTestcaseAdjoint[NN_,M_]:=GenerateAdjoint[NN,M,GenerateFilenameAdjoint[FileNameJoin[{NotebookDirectory[],"data"}]]]
Formatter[x_]:="&"<>x;

(* 1D Testcases Trafo. *)
d=1;
NN={1,2,4,10,20,50};
NN=Table[NN,{j,1,d}];
NN[[0]]=Sequence;
NN=Flatten[Outer[List,NN],d-1];
M={1,10,20,50};
x = Flatten[Table[Table[MakeTestcase[NN[[i]],M[[j]]],{j,1,Length[M]}],{i,1,Length[NN]}],1];
StringJoin[Map[Function[y,"static const testcase_delegate_file_t " <>y[[1]]<>" = {X(setup_file),X(destroy_file),ABSPATH(\""<> y[[2]]<>"\")};\n"],x]]
FormatVector[x[[All,1]], "*testcases_1d_file", "testcase_delegate_file_t", Formatter]

(* 1D Testcases Adjoint. *)
d=1;
NN={1,2,4,10,20,50};
NN=Table[NN,{j,1,d}];
NN[[0]]=Sequence;
NN=Flatten[Outer[List,NN],d-1];
M={1,10,20,50};
x = Flatten[Table[Table[MakeTestcaseAdjoint[NN[[i]],M[[j]]],{j,1,Length[M]}],{i,1,Length[NN]}],1];
StringJoin[Map[Function[y,"static const testcase_delegate_file_t " <>y[[1]]<>" = {X(setup_file),X(destroy_file),ABSPATH(\""<> y[[2]]<>"\")};\n"],x]]
FormatVector[x[[All,1]], "*testcases_adjoint_1d_file", "testcase_delegate_file_t", Formatter]

(* 2D Testcases Trafo. *)
d=2;
NN={10,20};
NN=Table[NN,{j,1,d}];
NN[[0]]=Sequence;
NN=Flatten[Outer[List,NN],d-1];
M={20,50};
x = Flatten[Table[Table[MakeTestcase[NN[[i]],M[[j]]],{j,1,Length[M]}],{i,1,Length[NN]}],1];
StringJoin[Map[Function[y,"static const testcase_delegate_file_t " <>y[[1]]<>" = {X(setup_file),X(destroy_file),ABSPATH(\""<> y[[2]]<>"\")};\n"],x]]
FormatVector[x[[All,1]], "*testcases_2d_file", "testcase_delegate_file_t", Formatter]

(* 2D Testcases Adjoint. *)
d=2;
NN={10,20};
NN=Table[NN,{j,1,d}];
NN[[0]]=Sequence;
NN=Flatten[Outer[List,NN],d-1];
M={20,50};
x = Flatten[Table[Table[MakeTestcaseAdjoint[NN[[i]],M[[j]]],{j,1,Length[M]}],{i,1,Length[NN]}],1];
StringJoin[Map[Function[y,"static const testcase_delegate_file_t " <>y[[1]]<>" = {X(setup_file),X(destroy_file),ABSPATH(\""<> y[[2]]<>"\")};\n"],x]]
FormatVector[x[[All,1]], "*testcases_adjoint_2d_file", "testcase_delegate_file_t", Formatter]

(* 3D Testcases Trafo. *)
d=3;
NN={10};
NN=Table[NN,{j,1,d}];
NN[[0]]=Sequence;
NN=Flatten[Outer[List,NN],d-1];
M={10};
x = Flatten[Table[Table[MakeTestcase[NN[[i]],M[[j]]],{j,1,Length[M]}],{i,1,Length[NN]}],1];
StringJoin[Map[Function[y,"static const testcase_delegate_file_t " <>y[[1]]<>" = {X(setup_file),X(destroy_file),ABSPATH(\""<> y[[2]]<>"\")};\n"],x]]
FormatVector[x[[All,1]], "*testcases_3d_file", "testcase_delegate_file_t", Formatter]

(* 3D Testcases Adjoint. *)
d=3;
NN={10};
NN=Table[NN,{j,1,d}];
NN[[0]]=Sequence;
NN=Flatten[Outer[List,NN],d-1];
M={10};
x = Flatten[Table[Table[MakeTestcaseAdjoint[NN[[i]],M[[j]]],{j,1,Length[M]}],{i,1,Length[NN]}],1];
StringJoin[Map[Function[y,"static const testcase_delegate_file_t " <>y[[1]]<>" = {X(setup_file),X(destroy_file),ABSPATH(\""<> y[[2]]<>"\")};\n"],x]]
FormatVector[x[[All,1]], "*testcases_adjoint_3d_file", "testcase_delegate_file_t", Formatter]

(* 4D Testcases *)
d=4;
NN={10};
NN=Table[NN,{j,1,d}];
NN[[0]]=Sequence;
NN=Flatten[Outer[List,NN],d-1];
M={10};
x = Flatten[Table[Table[MakeTestcase[NN[[i]],M[[j]]],{j,1,Length[M]}],{i,1,Length[NN]}],1];
StringJoin[Map[Function[y,"static const testcase_delegate_file_t " <>y[[1]]<>" = {X(setup_file),X(destroy_file),ABSPATH(\""<> y[[2]]<>"\")};\n"],x]]
FormatVector[x[[All,1]], "*testcases_3d_file", "testcase_delegate_file_t", Formatter]
(*FormatVector[Flatten[Table[Table[MakeTestcase[NN[[i]],M[[j]]],{j,1,Length[M]}],{i,1,Length[NN]}]],"filenames"]*)