jacobwilliams / bspline-fortran Goto Github PK
View Code? Open in Web Editor NEWMultidimensional B-Spline Interpolation of Data on a Regular Grid
License: Other
Multidimensional B-Spline Interpolation of Data on a Regular Grid
License: Other
This reshape call for the 3d ink
routine:
temp(1:nx*ny*nz) = reshape( fcn, [nx*ny*nz] )
Is crashing for large data sets. Replace with loops. Note there is also another one for the 5D routine.
The bspline_defc_module
module doesn't support the user-defined integer type (ip
, specified by a compiler directive).
This also makes the unit tests not compile if using anything other than int32
.
I received an email that maybe extrapolation to the right (when xval is to the right of the rightmost point in the grid) isn't working for the 3D case. Need to look into this.
Hi,
Thanks for making bspline-fortran available.
I'm trying to use it in a project that I compile with ifort.
Unfortunately I have not managed to find the configuration file where the compiler is defined (using cmake).
Could you please help me find it?
Thanks
Gianni
In the call to subroutine check(s,n,k,x,t,ierrs,error), array temporaries are created, which means that actual arguments are copied into temporary storage before routine calls. This may be specific to the Intel Fortran Compiler, and can be seen by building and running with the flag '-check arg_temp_created'. Since this happens for every call to db*val, I was concerned about an adverse performance impact, and started a thread on comp.lang.fortran:
https://groups.google.com/forum/#!topic/comp.lang.fortran/jPRslnUD-Pk
The upshot of that discussion is that:
integer,dimension(4),intent(in)
to
integer,dimension(:),intent(in)
This resolves the issue.
The code can't be used in a parallelized environment, because there are variables with the SAVE attribute in the subroutines db[X]val. This makes them effectively global, so that different parallel threads -each calling db[X]val independently- will overwrite the value, resulting in run-time errors. I think this behaviour will also occur for the object-oriented version (not tested), but it may be easier to remedy there.
In my opinion, modern Fortran code should be written so that it can be used in parallel applications. For example, in my case, an outer loop is parallelized with OpenMP, and within the loop each thread uses bspline-fortran for interpolation. I think this is a common setting, and that bspline-fortran should be a prime candidate for such high-performance applications.
For parallelization with OpenMP, I have implemented an easy solution (easy to implement, though it took me a complete day to figure out what was going wrong...). For example for subroutine db2val, replace the lines
integer,save :: inbvx = 1
integer,save :: iloy = 1
by
integer,save :: inbvx
integer,save :: iloy
!$OMP THREADPRIVATE(inbvx, iloy)
inbvx = 1
iloy = 1
This creates separate SAVEd variables inbvx, iloy for each thread, which are then 'global' within the thread. In my own application, this resolved the problems. Compiling and running with the Intel Fortran Compiler with maximum debug flags didn't report any warnings or errors. However, I am not a programmer by training, so I can't say how good or reliable or general the solution is.
For the object-oriented version, one could make use of the private type components that correspond to inbvx, iloy to avoid the need for the SAVE attribute. This would have the advantage of being more portable, since it wouldn't be limited to OpenMP. But it would require a little bit larger modifications of db[X]val and maybe the routines called by it, I believe. This object-oriented solution and the OpenMP-based one are not mutually exclusive.
PGI Fortran compiler gives the following error when compiling the sub_module:
bspline-fortran/src> pgfortran -c -Ktrap=fp bspline_kinds_module.F90 bspline_sub_module.f90
bspline_kinds_module.F90:
bspline_sub_module.f90:
PGF90-W-0155-Integer overflow occurred when evaluating ** (bspline_sub_module.f90: 3615)
PGF90-S-0098-Divide by zero (bspline_sub_module.f90: 3615)
0 inform, 1 warnings, 1 severes, 0 fatal for dbint4
This error caused by line 3615 in bspline_sub_module.f90
real(wp),parameter :: wdtol = radix(1.0_wp)**(1-digits(1.0_wp)) !! d1mach(4)
The types of radix
and digits
are integer, so the right-hand side of this expression is (integer)^(integer)
form.
Therefore, when the result of radix(1.0_wp)**(1-digits(1.0_wp)) is too small for the integer type, the overflow causes.
(Perhaps other compilers do type conversion automatically, but the PGI compiler does not.)
Possible alternatives are:
real(wp),parameter :: wdtol = real(radix(1.0_wp), kind=wp)**(1-digits(1.0_wp)) !! d1mach(4)
or
real(wp),parameter :: wdtol = epsilon(1.0_wp) !! d1mach(4)
Need more graceful error handling, and returning of flags that indicate specifically what error occurred (rather than just printing messages to the console).
Allow option for user-specified knots for the object-oriented interface.
it would be great to have also bsplines for 1D interpolation with the same call syntax, i.e.,
db1ink(x,nx,fcn,kx,tx,bcoef,iflag)
db1val(...)
Or is there something that I am missing?
In dbspvn
, I think these two should be intent(inout)
:
real(wp),dimension(*),intent(out) :: work !! a work vector of length `2*k`
integer(ip),intent(out) :: iwork !! a work parameter. both `work` and `iwork` contain
For the case where there routine is called again with index = 2
.
The size_of
functions in the object oriented classes only return a default integer. So, it can overflow for very large data sets. Should give the user some ability to specify the integer kind to use.
Should have a speed test for both the subroutine and object-oriented interfaces. Possibly with and without OpenMP.
Here is an example, adapted from Rouson, Xia, Xu (2014).
module template_class
type :: t_template
!...
end type t_template
interface t_template
module procedure constructor
end interface
contains
elemental function constructor( ) result (new_instance)
type(t_template) :: new_instance
!...
end function constructor
end module template_class
which allows initialization statements such as
dti = t_template
which can be useful in cases such as outlined in issue #12 .
Consider including DEFC a least-squares B-Spline fit from SLATEC.
Hello,
Is there any function to export control points of a b-spline?
Many thanks!
I would like to be able to get definite integrals of B-Splines.
There seems to be something in the CMLIB library: BSQAD
, which only depends on INTRV
and BVALU
, both of which exist already in bspline-fortran
.
Dear all,
I got the following error when I used cmake.
My system: CentOS 7.5, gcc-gfortran 4.8.5 20150623
Scanning dependencies of target bspline-fortran
[ 25%] Building Fortran object CMakeFiles/bspline-fortran.dir/src/bspline_kinds_module.f90.o
[ 50%] Building Fortran object CMakeFiles/bspline-fortran.dir/src/bspline_sub_module.f90.o
[ 75%] Building Fortran object CMakeFiles/bspline-fortran.dir/src/bspline_oo_module.f90.o
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:21.54:
integer,parameter :: int_size = storage_size(1) !! size of a defa
1
Error: Invalid character in name at (1)
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:22.54:
integer,parameter :: logical_size = storage_size(.true.) !! size of a defa
1
Error: Invalid character in name at (1)
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:23.54:
integer,parameter :: real_size = storage_size(1.0_wp) !! size of a `rea
1
Error: Invalid character in name at (1)
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:63.52:
type,extends(bspline_class),public :: bspline_1d
1
Error: Finalization at (1) is not yet implemented
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:86.52:
type,extends(bspline_class),public :: bspline_2d
1
Error: Finalization at (1) is not yet implemented
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:109.52:
type,extends(bspline_class),public :: bspline_3d
1
Error: Finalization at (1) is not yet implemented
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:137.52:
type,extends(bspline_class),public :: bspline_4d
1
Error: Finalization at (1) is not yet implemented
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:170.52:
type,extends(bspline_class),public :: bspline_5d
1
Error: Finalization at (1) is not yet implemented
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:208.52:
type,extends(bspline_class),public :: bspline_6d
1
Error: Finalization at (1) is not yet implemented
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:491.18:
s = 2int_size + logical_size + 22int_size
1
Error: Symbol 'int_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:491.33:
s = 2int_size + logical_size + 22int_size
1
Error: Symbol 'logical_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:493.46:
if (allocated(me%bcoef)) s = s + real_sizesize(me%bcoef,1)&
1
Error: Symbol 'real_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:464.18:
s = 2int_size + logical_size + 18int_size
1
Error: Symbol 'int_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:464.33:
s = 2int_size + logical_size + 18int_size
1
Error: Symbol 'logical_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:466.46:
if (allocated(me%bcoef)) s = s + real_sizesize(me%bcoef,1)&
1
Error: Symbol 'real_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:439.18:
s = 2int_size + logical_size + 14int_size
1
Error: Symbol 'int_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:439.33:
s = 2int_size + logical_size + 14int_size
1
Error: Symbol 'logical_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:441.46:
if (allocated(me%bcoef)) s = s + real_sizesize(me%bcoef,1)&
1
Error: Symbol 'real_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:416.18:
s = 2int_size + logical_size + 10int_size
1
Error: Symbol 'int_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:416.33:
s = 2int_size + logical_size + 10int_size
1
Error: Symbol 'logical_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:418.46:
if (allocated(me%bcoef)) s = s + real_sizesize(me%bcoef,1)&
1
Error: Symbol 'real_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:395.18:
s = 2int_size + logical_size + 6int_size
1
Error: Symbol 'int_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:395.33:
s = 2int_size + logical_size + 6int_size
1
Error: Symbol 'logical_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:397.46:
if (allocated(me%bcoef)) s = s + real_sizesize(me%bcoef,1)&
1
Error: Symbol 'real_size' at (1) has no IMPLICIT type
/home/lyzhao/soft/exc/tmp/bspline-fortran-5.4.2/src/bspline_oo_module.f90:376.18:
s = 2int_size + logical_size + 2int_size
1
Error: Symbol 'int_size' at (1) has no IMPLICIT type
Fatal Error: Error count reached limit of 25.
make[3]: *** [CMakeFiles/bspline-fortran.dir/src/bspline_oo_module.f90.o] Error 1
make[2]: *** [CMakeFiles/bspline-fortran.dir/src/bspline_oo_module.f90.o.provides] Error 2
make[1]: *** [CMakeFiles/bspline-fortran.dir/all] Error 2
make: *** [all] Error 2
Any help will be appreciated.
Youzhao Lan
Intel Fortran 14 gives the following error when compiling the oo module:
bspline-fortran/src> ifort -c bspline_sub_module.f90 bspline_oo_module.f90
bspline_oo_module.f90(50): error #8259: The type bound procedure definition statement must contains only one binding name. [INITIALIZE_1D_SPECIFY_KNOTS]
procedure :: initialize_1d_auto_knots,initialize_1d_specify_knots
----------------------------------------------^
bspline_oo_module.f90(70): error #8259: The type bound procedure definition statement must contains only one binding name. [INITIALIZE_2D_SPECIFY_KNOTS]
procedure :: initialize_2d_auto_knots,initialize_2d_specify_knots
----------------------------------------------^
bspline_oo_module.f90(95): error #8259: The type bound procedure definition statement must contains only one binding name. [INITIALIZE_3D_SPECIFY_KNOTS]
procedure :: initialize_3d_auto_knots,initialize_3d_specify_knots
----------------------------------------------^
bspline_oo_module.f90(126): error #8259: The type bound procedure definition statement must contains only one binding name. [INITIALIZE_4D_SPECIFY_KNOTS]
procedure :: initialize_4d_auto_knots,initialize_4d_specify_knots
----------------------------------------------^
bspline_oo_module.f90(161): error #8259: The type bound procedure definition statement must contains only one binding name. [INITIALIZE_5D_SPECIFY_KNOTS]
procedure :: initialize_5d_auto_knots,initialize_5d_specify_knots
----------------------------------------------^
bspline_oo_module.f90(201): error #8259: The type bound procedure definition statement must contains only one binding name. [INITIALIZE_6D_SPECIFY_KNOTS]
procedure :: initialize_6d_auto_knots,initialize_6d_specify_knots
----------------------------------------------^
bspline_oo_module.f90(200): error #8423: In GENERIC type bound procedure definition each binding name must be the name of a specific binding of the type. [INITIALIZE_6D_SPECIFY_KNOTS]
generic,public :: initialize => initialize_6d_auto_knots,initialize_6d_specify_knots
-----------------------------------------------------------------^
bspline_oo_module.f90(160): error #8423: In GENERIC type bound procedure definition each binding name must be the name of a specific binding of the type. [INITIALIZE_5D_SPECIFY_KNOTS]
generic,public :: initialize => initialize_5d_auto_knots,initialize_5d_specify_knots
-----------------------------------------------------------------^
bspline_oo_module.f90(125): error #8423: In GENERIC type bound procedure definition each binding name must be the name of a specific binding of the type. [INITIALIZE_4D_SPECIFY_KNOTS]
generic,public :: initialize => initialize_4d_auto_knots,initialize_4d_specify_knots
-----------------------------------------------------------------^
bspline_oo_module.f90(94): error #8423: In GENERIC type bound procedure definition each binding name must be the name of a specific binding of the type. [INITIALIZE_3D_SPECIFY_KNOTS]
generic,public :: initialize => initialize_3d_auto_knots,initialize_3d_specify_knots
-----------------------------------------------------------------^
bspline_oo_module.f90(69): error #8423: In GENERIC type bound procedure definition each binding name must be the name of a specific binding of the type. [INITIALIZE_2D_SPECIFY_KNOTS]
generic,public :: initialize => initialize_2d_auto_knots,initialize_2d_specify_knots
-----------------------------------------------------------------^
bspline_oo_module.f90(49): error #8423: In GENERIC type bound procedure definition each binding name must be the name of a specific binding of the type. [INITIALIZE_1D_SPECIFY_KNOTS]
generic,public :: initialize => initialize_1d_auto_knots,initialize_1d_specify_knots
-----------------------------------------------------------------^
compilation aborted for bspline_oo_module.f90 (code 1)
I'm considering redefining the iflag
return values from the initialization routines so that a 0
value means no errors. This would match the evaluation routines. Also, for specifying the knots, there should be a logical input specify_knots
, rather than the current dual-use iflag
variable (which is an artifact from the original code). This would break backward compatibility, so it would be in the 5.0 release.
Hi,
Just want to ask how should the variables inbvx,inbvy,inbvz,iloy,iloz,w1_3d,w2_3d,w3_3d on a 3D splines be set for an open mp code?
Should they be shared or private?
Thank you.
volcompt
In bspline_sub_module.f90, 'many' array temporaries are created.
When compiling with GCC 7.3.0 and the warning flag -Warray-temporaries, most of them intervene in the calls to dintrv, dbvalu, dbknot and dbtpcf
With just runtime checks, -fcheck=all, they arise for the "fcn" argument of dbtpcf.
I have no idea how harmelss those runtime array temporaries are but since I am incorporating bspline-fortran within a large 3D code I would like to avoid memory fragmentation as much as possible and not exhaust my stack.
I managed to eliminate most of the array temporaries by changing explicit-shape dummy arguments to assumed-shape dummy arguments in most of the routines and getting rid of some assumed-size dummy arrays. But problem remains for "fcn" and "bcoef" in dbtpcf.
I assume it would be tricky to change everything and it would require some copying to adapt the routines for 1D and 3D as the library was originally written in 2D, but I thought assumed-size arrays should not be used in modern Fortran.
Consider splpak and see if that is something that could be merged into this library.
Hi,
We used your library to develop our project and we would like to pusblish it on github with a GPL license.
Is that compatible with you?
Best regards,
Benjamin
Currently, we only have 1D integration. For completeness we should have 1D-6D. Note: this project may be useful: https://github.com/jacobwilliams/quadrature-fortran
See also #33
Consider adding an extrapolation option, where if a point is requested outside the bounds, it just does an extrapolation of the endpoints or something like that.
Hi Jacob,
Thanks for this excellent library.
I noticed that the documentation on jacobwilliams.github.io is broken for this package, perhaps something went wrong on github pages? Could you take a look?
Thanks,
Daan
Hello, I have never used cmake, so I have (I think) a very dumb question.
I'm trying to compile with cmake, so I followed the readme and started the compilation with make
. The problem is that after few instant the compilation stops with an error since it cannot find the .mod files (that are inside the lib directory).
Is there something that is not written in the readme that I should do ? It seems that the makefile doesn't know where to look for .mod files.
Thanks in advance !
I want to get rid of the pyplot-fortran
submodule, and use FPM to pull that in. I don't know how to do that with CMake, so I may end up removing CMake support for tests, unless somebody else wants to maintain that. Also probably will remove FoBiS support.
Hello! When compiling with gfortran with -Wall, every type definition gives this warning:
mpif90 -Ofast -march=native -mtune=native -pipe -g -fopenmp -Wall -c src/bspline_oo_module.f90 src/bspline_oo_module.f90:62:52:
type,extends(bspline_class),public :: bspline_1d
1
Warning: Only array FINAL procedures declared for derived type ‘bspline_1d’ defined at (1), suggest also scalar one [-Wsurprising]
Can it be safely ignored? Thank you!
Dear Williams,
Could you upload your open source codes into open source software journal like:
The Journal of Open Source Software, ArXiv, ...
for easy citation?:)
Best Regards,
Young-Myung Choi
There appear to be problems related to the thread safety of this library.
Below code works fine when running without OpenMP:
program main
use bspline_module
use bspline_kinds_module
implicit none
type(bspline_1d) :: s
real(kind=wp), dimension(:), allocatable :: x, fcn
real(kind=wp) :: q, f
integer :: i, iflag
integer, parameter :: size = 30
print *, '*** START'
print *, '*** INIT'
allocate(x(size), fcn(size))
do i = 1, size
x(i) = real(i, wp)
fcn(i) = x(i)**2
print *, i, x(i), fcn(i)
end do
call s%initialize(x, fcn, 4, iflag)
print *, iflag
print *, '*** EVAL'
!$omp parallel do default(shared) private(i, q, f, iflag)
do i = 1, 50000
call random_number(q)
q = 1.0_wp + q * real(size-1, wp)
call s%evaluate(q, 0, f, iflag)
if (iflag /= 0) print *, q, iflag, s%status_message(iflag)
end do
!$omp end parallel do
print *, '*** END'
end program main
Enabling bounds checks and enabling OpenMP then gives out-of-bounds errors when evaluating the spline in parallel. Both gfortran
(with -fcheck=bounds
) and ifort
(with -check bounds
) throw these errors and I doubt that they are false positives.
ifort
output:
forrtl: severe (408): fort: (3): Subscript #1 of the array A has value 0 which is less than the lower bound of 1
gfortran
output:
At line 3056 of file [...]/bspline_sub_module.f90
Fortran runtime error: Index '0' of dimension 1 of array 'a' below lower bound of 1
Have you come across this before @jacobwilliams or I am making some mistake here?
I think db[X]ink
doesn't check whether the abscissae x
(, y
,…) and the function values fcn
have the same length. Should it? If so, should it return an appropriate flag (or issue a warning)?
Hi Jacob,
I think there is a typo in the dimension check for the 3D splines, line 1708 in the current sub module.
It says
if (size(z)/=size(f3,2)) then; iflag = 702; return; end if
but should say
if (size(z)/=size(f3,3)) then; iflag = 702; return; end if
Thanks for all your work on this, so useful!
Moritz
Add a C/Python interface.
Add support for compiling with the Fortran Package Manager.
This is similar to issue #4 but now I tried the OO module. When compiled with -openmp, my code builds but crashes with SIGSEGV at runtime. This does not happen without -openmp.
When I add the SAVE attribute to the spline instance, e.g.,
type(bspline_2d) ,save:: v_spline
the program runs without crashing. Each thread gets its own copy by
!$OMP PARALLEL PRIVATE(v_spline)
I am not quite sure why this is happening. Could it be that the default initialization in the derived type declaration, e.g.,
integer :: inbvy = 1
integer :: iloy = 1
puts the variables on stack, thereby making them global (like the problem in #4 )? Or maybe my workaround with SAVE is erroneous? I could also imagine that this is a compiler bug, I tested with Intel composer_xe_2015.1.133 and composer_xe_2015.0.090, fairly recent compilers. Strangely enough, the problem also disappears if the compiler option -ftrapuv (which I use for debugging) is specified.
I have put substantial effort in moving my code to the OO version and in investigating this issue, and would be very grateful for any help.
Add logo to the ford-produced documentation.
Hello! Any advice on how to debug what seems to be a thread safety issue with OpenMP at evaluation? Did anyone else run into this problem? I'll put together a minimal example.
Would switching to the non-OO subroutines help?
Thank you!
I'm afraid that many routines currently use a wrong type of array in Fortran. This leads to a much lower data size limit than could otherwise be achieved.
All large local variables should allocatable, because they use heap memory by default. Currently many large local arrays are of automatic size, so they get allocated on the stack. This commit shows how to correct the db3ink
procedure. The fix is straightforward, but a little tedious to implement everywhere.
I see two solutions:
The 'right' approach: do what I did for db3ink
in all procedures, and then merge the branch.
A hack: use a compiler option to force all arrays onto the heap. This commit shows how I did this with the intel compiler. I don't know how to do the equivalent for the GNU compiler.
For reference, these were the limits for the data sizes for
type(bspline_3d) :: spline
...
call spline%initialize( &
x=xi, y=yi, z=zi, &
fcn=data, &
kx=4, ky=4, kz=4, &
iflag=iflag, &
extrap=.true. &
)
on my computer cluster:
original maximum: size(xi) * size(yi) * size(zi) = 9 * 9 * 9
;
after fixing db3ink
: 9 * 9 * 20
(approximate);
after compiling everything with -heap-arrays
: 264 * 240 * 240
still works. Did not test larger array.
Would it be a good and feasible idea to make the procedures pure
? Since the save
variables are gone, that's one less obstacle. The other obstacle are the error messages. Since an error flag is already present, one could move the messages to a separate (non-pure) type-bound subroutine which takes flag as input and prints the corresponding message.
In my case, the spline evaluation appears in a bottleneck part of the code that could benefit from optimization which the compiler can do for pure
procedures, and bspline is the only element preventing this.
Maybe add pyplot-fortran (used for the test programs) as a git submodule.
Add a preprocessor option to be able to select the real and integer kinds.
See also: #31
For the test programs.
Are their any opportunities to speed up the low-level routines perhaps by using OpenMP, or maybe do concurrent
loops? Look into this.
Update the CMake config file to enable more control of the build.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.