├── lib
└── .keep
├── out
└── .gitignore
├── bin
└── .gitignore
├── .gitignore
├── licenses
├── licence_GAMERA.txt
├── lgpl-3.txt
└── lgpl-2.1.txt
├── python
├── gappa.i
├── setup.py
└── pkgconfig.py
├── .github
└── workflows
│ └── ci.yml
├── README.md
├── unit_tests
├── radiation_unit_test.py
└── rad_temp.dat
├── Makefile
├── src
└── 2D_interp
│ ├── bilinear.C
│ ├── interp2d_spline.C
│ ├── interp2d.C
│ └── bicubic.C
└── include
├── Utils.h
├── 2D_interp
├── interp2d_spline.h
└── interp2d.h
└── Astro.h
/lib/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/out/.gitignore:
--------------------------------------------------------------------------------
1 | # Don't ignore me!
2 | *
3 | #
4 | !.gitignore
5 |
--------------------------------------------------------------------------------
/bin/.gitignore:
--------------------------------------------------------------------------------
1 | # Please don't ignore me!
2 | *
3 | #
4 | !.gitignore
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 | *png
3 | *.pyc
4 | __pycache__
5 | .idea
6 | docu/pics/
7 |
8 | docu/doxygen/html/
9 | docu/doxygen/xml/
10 | docu/sphinx/build/
11 | python/_gamerapy.cc
12 | python/build/
13 | _gappa.cc
14 |
--------------------------------------------------------------------------------
/licenses/licence_GAMERA.txt:
--------------------------------------------------------------------------------
1 | GAMERA - Copyright (C) 2015 Joachim Hahn
2 |
3 | The GAMERA library and the GAMERA programs are free software;
4 | you can redistribute them and/or modify it under the terms of
5 | the GNU Lesser General Public License as published by the
6 | Free Software Foundation; either version 2.1 of the License,
7 | or (at your option) any later version.
8 |
9 | This software is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | Lesser General Public License for more details.
13 |
14 | You should have received a copy of the GNU Lesser General Public License
15 | along with this software. If not, see .
16 |
--------------------------------------------------------------------------------
/python/gappa.i:
--------------------------------------------------------------------------------
1 | %module gappa
2 | %{
3 | #include "../include/Radiation.h"
4 | #include "../include/Particles.h"
5 | #include "../include/Utils.h"
6 | #include "../include/Astro.h"
7 | #include "../include/2D_interp/interp2d_spline.h"
8 | #include "../include/2D_interp/interp2d.h"
9 | %}
10 |
11 | %include "typemaps.i"
12 | %include "std_vector.i"
13 | %include "std_string.i"
14 | %include "std_iostream.i"
15 | namespace std
16 | {
17 | %template(OneIVector) vector;
18 | %template(OneDVector) vector;
19 | %template(TwoDVector) vector< vector >;
20 | }
21 | %include "../include/Radiation.h"
22 | %include "../include/Particles.h"
23 | %include "../include/Utils.h"
24 | %include "../include/Astro.h"
25 | %include "../include/2D_interp/interp2d_spline.h"
26 | %include "../include/2D_interp/interp2d.h"
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | tags:
8 | - "**"
9 | pull_request:
10 |
11 | jobs:
12 | cpp:
13 | runs-on: ${{ matrix.os }}
14 |
15 | strategy:
16 | matrix:
17 | include:
18 | - os: ubuntu-latest
19 | - os: macos-12
20 | - os: macos-14
21 |
22 | steps:
23 |
24 | - uses: actions/checkout@v4
25 |
26 | - name: install dependencies (ubuntu)
27 | if : ${{ contains(matrix.os, 'ubuntu') }}
28 | run: |
29 | sudo apt update
30 | sudo apt install -y libgsl-dev swig
31 |
32 | - name: install dependencies (macos)
33 | if : ${{ contains(matrix.os, 'macos') }}
34 | run: |
35 | brew install swig gsl
36 |
37 | - uses: actions/setup-python@v5
38 | with:
39 | python-version: '3.10'
40 |
41 | - name: install python-deps
42 | run: |
43 | python -m pip install numpy matplotlib
44 |
45 | - name: build
46 | run: |
47 | make gamera gappa
48 |
49 | - name: test
50 | run: |
51 | cd unit_tests
52 | python radiation_unit_test.py
53 |
--------------------------------------------------------------------------------
/python/setup.py:
--------------------------------------------------------------------------------
1 | from distutils.core import setup, Extension
2 | import distutils.sysconfig
3 | import os
4 | import sys
5 |
6 |
7 | # Use the bundeled pkgconfig
8 | here = os.path.dirname(os.path.realpath(__file__))
9 | sys.path.insert(0, here)
10 | import pkgconfig
11 |
12 | cfg_vars = distutils.sysconfig.get_config_vars()
13 |
14 | for key,value in cfg_vars.items():
15 | if type(value) == str:
16 | cfg_vars[key] = value.replace("-Wstrict-prototypes","")
17 |
18 | extra_link_args = pkgconfig.libs('gsl').split()
19 |
20 | extra_compile_args = pkgconfig.cflags('gsl').split()
21 | extra_compile_args.append('-m64')
22 | extra_compile_args.append('-std=c++11')
23 |
24 | extension_mod = Extension(
25 | "_gappa",
26 | ["_gappa.cc",
27 | "../src/Radiation.C",
28 | "../src/Particles.C",
29 | "../src/Utils.C",
30 | "../src/Astro.C",
31 | "../src/2D_interp/interp2d.C",
32 | "../src/2D_interp/interp2d_spline.C",
33 | "../src/2D_interp/bilinear.C",
34 | "../src/2D_interp/bicubic.C"],
35 | extra_compile_args=extra_compile_args,
36 | extra_link_args=extra_link_args,
37 | include_dirs=['../include'],
38 | )
39 |
40 | setup(
41 | name="gappa",
42 | ext_modules=[extension_mod],
43 | )
44 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # GAMERA
2 |
3 | is a project launched by the [Max Planck Insitute for Nuclear Physics in Heidelberg (MPIK)](https://www.mpi-hd.mpg.de/mpi/en/),
4 | an open-source C++/python package which handles the spectral modelling of non-thermally emitting astrophysical sources in a simple and modular way. It allows the user to devise time-dependent models of leptonic and hadronic particle populations in a general astrophysical context (including SNRs, PWNs and AGNs) and to compute their subsequent photon emission.
5 |
6 | For more info and a turorial, see the [GAMERA docu!](http://libgamera.github.io/GAMERA/docs/main_page.html)
7 | (currently being updated)
8 |
9 | GAMERA is written in C++ and can be wrapped to python.
10 |
11 | The software is listed in the Astrophysics Source Code Library
12 |
13 | Quick Start
14 | ===========
15 |
16 | Dependencies
17 | ------------
18 |
19 | You need to have [GSL](http://www.gnu.org/software/gsl/) installed on your
20 | system, as well as [SWIG](http://www.swig.org/) if you want to wrap the
21 | python module. If you are a Mac user, it might be required to install
22 | [pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/).
23 |
24 | Building
25 | --------
26 |
27 | Running
28 |
29 | - $ make all
30 |
31 | will generate a shared object (lib/libgamera.so) as well as the python module
32 | (lib/_gamerapy.so , lib/gamerapy.py).
33 |
34 |
35 | Licence
36 | --------
37 |
38 |
39 | The GAMERA library and the GAMERA programs are free software;
40 | you can redistribute them and/or modify it under the terms of
41 | the GNU Lesser General Public License as published by the
42 | Free Software Foundation; either version 2.1 of the License,
43 | or (at your option) any later version.
44 |
45 | This software is distributed in the hope that it will be useful,
46 | but WITHOUT ANY WARRANTY; without even the implied warranty of
47 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
48 | Lesser General Public License for more details.
49 |
50 | A copy of the GNU Lesser General Public License version 2.1 can be found
51 | [here](https://github.com/libgamera/GAMERA/blob/master/licenses/lgpl-2.1.txt).
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/unit_tests/radiation_unit_test.py:
--------------------------------------------------------------------------------
1 | #/usr/local/bin/python
2 | import sys
3 | import os
4 | import numpy as np
5 | sys.path.append(os.path.abspath('../lib'))
6 | import gappa as gp
7 | import unittest
8 |
9 |
10 |
11 | class TestRadiationClass(unittest.TestCase):
12 |
13 | def grey_body(self,e,t,e_dens):
14 | return 15*e_dens*(gp.pi*gp.kb*t)**-4 *e**2 / (np.exp(e /(gp.kb*t))-1)
15 |
16 | def write_grey_body(self,e,t,e_dens):
17 | g = self.grey_body(e,t,e_dens)
18 | f = open("rad_temp.dat",'w')
19 | for ee,gg in list(zip(e,g)):
20 | f.write(str(ee/gp.eV_to_erg)+" "+str(gg*gp.eV_to_erg)+"\n")
21 | f.close()
22 |
23 | def test_AddThermalTargetPhotons(self):
24 | fr = gp.Radiation()
25 | t = 2.7
26 | e_dens = 0.25*gp.eV_to_erg
27 | fr.AddThermalTargetPhotons(2.7,0.25*gp.eV_to_erg)
28 | g_1 = np.array(fr.GetTargetPhotons())
29 | g_2 = self.grey_body(g_1[:,0],t,e_dens)
30 |
31 | dg = np.sqrt(np.sum((g_2-g_1[:,1])**2)) / np.sum(g_2)
32 | self.assertTrue(dg < 1e-4)
33 |
34 | def test_AddArbitraryTargetPhotons(self):
35 | fr = gp.Radiation()
36 | t = 2.7
37 | e_dens = 0.25*gp.eV_to_erg
38 | fr.AddThermalTargetPhotons(2.7,0.25*gp.eV_to_erg)
39 | g_a = np.array(fr.GetTargetPhotons(0))
40 |
41 | g_2 = self.grey_body(g_a[:,0],t,e_dens)
42 |
43 | fr.AddArbitraryTargetPhotons(list(zip(g_a[:,0],g_2)))
44 | g_b = np.array(fr.GetTargetPhotons(1))
45 |
46 | g_1 = np.interp(g_a[:,0],g_b[:,0],g_b[:,1])
47 |
48 | dg = np.sqrt(np.sum((g_2-g_1)**2)) / np.sum(g_2)
49 | self.assertTrue(dg < 1e-4)
50 |
51 |
52 | def test_ImportTargetPhotonsFromFile(self):
53 | fr = gp.Radiation()
54 | t = 2.7
55 | e_dens = 0.25*gp.eV_to_erg
56 | fr.AddThermalTargetPhotons(2.7,0.25*gp.eV_to_erg,1000)
57 | g_a = np.array(fr.GetTargetPhotons(0))
58 | self.write_grey_body(g_a[:,0],t,e_dens)
59 | fr.ImportTargetPhotonsFromFile("rad_temp.dat")
60 | g_2 = self.grey_body(g_a[:,0],t,e_dens)
61 | # print g_2
62 | g_b = np.array(fr.GetTargetPhotons(1))
63 | g_1 = np.interp(g_a[:,0],g_b[:,0],g_b[:,1])
64 | dg = np.sqrt(np.sum((g_2-g_1)**2)) / np.sum(g_2)
65 | self.assertTrue(dg < 1e-4)
66 |
67 |
68 |
69 | suite = unittest.TestLoader().loadTestsFromTestCase(TestRadiationClass)
70 | unittest.TextTestRunner(verbosity=3).run(suite)
71 | #if __name__ == '__main__':
72 | # unittest.main()
73 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 |
2 | OUTDIR = $(shell pwd)/out
3 | LIBDIR = $(shell pwd)/lib
4 |
5 |
6 | # define include path
7 | INCLUDES := -I./include
8 |
9 | # GNU scientific library stuff
10 | GSLCFLAGS := $(shell gsl-config --cflags)
11 |
12 | GSLLIBS := $(shell gsl-config --libs)
13 |
14 | # define additional switches to be passed to the compiler
15 | CXXFLAGS := $(GSLCFLAGS) -m64 -std=c++11
16 |
17 | # define additional switches to be passed to the linker
18 | LDFLAGS := $(GSLLIBS)
19 |
20 |
21 | help:
22 | @echo ''
23 | @echo 'GAMERA available make targets:'
24 | @echo ''
25 | @echo ' gamera Create the GAMERA shared object (lib/libgamera.so)'
26 | @echo ' gappa Wrap the python module (lib/gappa.py and lib/_gappa.so)'
27 | @echo ' clean remove temporary files'
28 |
29 |
30 | all: gamera gappa
31 |
32 | gamera: Radiation Particles Utils Astro bicubic bilinear interp2d interp2d_spline libgamera
33 |
34 |
35 |
36 |
37 | # create the individual .o files
38 | Radiation : src/Radiation.C
39 | $(CXX) -g -O2 -fpic -Wall -c src/Radiation.C -o $(OUTDIR)/Radiation.o $(CXXFLAGS) $(INCLUDES)
40 | Particles : src/Particles.C
41 | $(CXX) -g -O2 -fpic -Wall -c src/Particles.C -o $(OUTDIR)/Particles.o $(CXXFLAGS) $(INCLUDES)
42 | Utils : src/Utils.C
43 | $(CXX) -g -O2 -fpic -Wall -c src/Utils.C -o $(OUTDIR)/Utils.o $(CXXFLAGS) $(INCLUDES)
44 | Astro : src/Astro.C
45 | $(CXX) -g -O2 -fpic -Wall -c src/Astro.C -o $(OUTDIR)/Astro.o $(CXXFLAGS) $(INCLUDES)
46 |
47 |
48 |
49 | bicubic : src/2D_interp/bicubic.C
50 | $(CXX) -g -O2 -fpic -Wall -c src/2D_interp/bicubic.C -o $(OUTDIR)/bicubic.o $(INCLUDES) $(GSLCFLAGS)
51 | bilinear : src/2D_interp/bilinear.C
52 | $(CXX) -g -O2 -fpic -Wall -c src/2D_interp/bilinear.C -o $(OUTDIR)/bilinear.o $(INCLUDES) $(GSLCFLAGS)
53 | interp2d : src/2D_interp/interp2d.C
54 | $(CXX) -g -O2 -fpic -Wall -c src/2D_interp/interp2d.C -o $(OUTDIR)/interp2d.o $(INCLUDES) $(GSLCFLAGS)
55 | interp2d_spline : src/2D_interp/interp2d_spline.C
56 | $(CXX) -g -O2 -fpic -Wall -c src/2D_interp/interp2d_spline.C -o $(OUTDIR)/interp2d_spline.o $(INCLUDES) $(GSLCFLAGS)
57 |
58 |
59 | # create the shared library
60 | objectsSO = $(OUTDIR)/Radiation.o $(OUTDIR)/Particles.o $(OUTDIR)/Utils.o $(OUTDIR)/Astro.o $(OUTDIR)/bicubic.o $(OUTDIR)/bilinear.o $(OUTDIR)/interp2d.o $(OUTDIR)/interp2d_spline.o
61 | libgamera : $(objectsSO)
62 | @echo "Generating library $@..."
63 | $(CXX) -shared -o $(LIBDIR)/libgamera.so $(objectsSO) $(CXXFLAGS) $(LDFLAGS)
64 | @echo "-> done!"
65 |
66 |
67 | # make gappa package
68 | gappa:
69 | cd python && \
70 | swig -python -c++ -outdir ../lib -o _gappa.cc gappa.i && \
71 | python setup.py build_ext --build-lib ../lib
72 |
73 |
74 | clean-out:
75 | -rm -f out/*
76 | clean-bin:
77 | -rm -f bin/*
78 | clean-lib:
79 | -rm -f lib/*
80 | clean-python:
81 | -rm -f python/_gappa.cc python/_gappa.so python/gappa.py
82 | -rm -rf python/build/
83 |
84 | clean: clean-out clean-bin clean-lib clean-python
85 |
--------------------------------------------------------------------------------
/src/2D_interp/bilinear.C:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of interp2d, a GSL-compatible two-dimensional
3 | * interpolation library.
4 | *
5 | * Copyright 2012 David Zaslavsky
6 | * Portions based on GNU GSL interpolation code,
7 | * copyright 1996, 1997, 1998, 1999, 2000, 2004 Gerard Jungman
8 | *
9 | * This program is free software: you can redistribute it and/or modify
10 | * it under the terms of the GNU General Public License as published by
11 | * the Free Software Foundation, either version 3 of the License, or
12 | * (at your option) any later version.
13 |
14 | * This program is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | * GNU General Public License for more details.
18 |
19 | * You should have received a copy of the GNU General Public License
20 | * along with this program. If not, see .
21 | */
22 |
23 | #include
24 | #include
25 | #include "2D_interp/interp2d.h"
26 |
27 | static int bilinear_init(void* state, const double xa[], const double ya[], const double za[], size_t xsize, size_t ysize) {
28 | return GSL_SUCCESS;
29 | }
30 |
31 | static int bilinear_eval(const void* state, const double xarr[], const double yarr[], const double zarr[], size_t xsize, size_t ysize, double x, double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z) {
32 | double xmin, xmax, ymin, ymax, zminmin, zminmax, zmaxmin, zmaxmax;
33 | double dx, dy;
34 | double t, u;
35 | size_t xi, yi;
36 | if (xa != NULL) {
37 | xi = gsl_interp_accel_find(xa, xarr, xsize, x);
38 | }
39 | else {
40 | xi = gsl_interp_bsearch(xarr, x, 0, xsize - 1);
41 | }
42 | if (ya != NULL) {
43 | yi = gsl_interp_accel_find(ya, yarr, ysize, y);
44 | }
45 | else {
46 | yi = gsl_interp_bsearch(yarr, y, 0, ysize - 1);
47 | }
48 | xmin = xarr[xi];
49 | xmax = xarr[xi + 1];
50 | ymin = yarr[yi];
51 | ymax = yarr[yi + 1];
52 | zminmin = zarr[INDEX_2D(xi, yi, xsize, ysize)];
53 | zminmax = zarr[INDEX_2D(xi, yi + 1, xsize, ysize)];
54 | zmaxmin = zarr[INDEX_2D(xi + 1, yi, xsize, ysize)];
55 | zmaxmax = zarr[INDEX_2D(xi + 1, yi + 1, xsize, ysize)];
56 | dx = xmax - xmin;
57 | dy = ymax - ymin;
58 | t = (x - xmin)/dx;
59 | u = (y - ymin)/dy;
60 | *z = (1.-t)*(1.-u)*zminmin + t*(1.-u)*zmaxmin + (1.-t)*u*zminmax + t*u*zmaxmax;
61 | return GSL_SUCCESS;
62 | }
63 |
64 | static int bilinear_deriv_x(const void* state, const double xarr[], const double yarr[], const double zarr[], size_t xsize, size_t ysize, double x, double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z_p) {
65 | double xmin, xmax, ymin, ymax, zminmin, zminmax, zmaxmin, zmaxmax;
66 | double dx, dy;
67 | double dt, u;
68 | size_t xi, yi;
69 | if (xa != NULL) {
70 | xi = gsl_interp_accel_find(xa, xarr, xsize, x);
71 | }
72 | else {
73 | xi = gsl_interp_bsearch(xarr, x, 0, xsize - 1);
74 | }
75 | if (ya != NULL) {
76 | yi = gsl_interp_accel_find(ya, yarr, ysize, y);
77 | }
78 | else {
79 | yi = gsl_interp_bsearch(yarr, y, 0, ysize - 1);
80 | }
81 | xmin = xarr[xi];
82 | xmax = xarr[xi + 1];
83 | ymin = yarr[yi];
84 | ymax = yarr[yi + 1];
85 | zminmin = zarr[INDEX_2D(xi, yi, xsize, ysize)];
86 | zminmax = zarr[INDEX_2D(xi, yi + 1, xsize, ysize)];
87 | zmaxmin = zarr[INDEX_2D(xi + 1, yi, xsize, ysize)];
88 | zmaxmax = zarr[INDEX_2D(xi + 1, yi + 1, xsize, ysize)];
89 | dx = xmax - xmin;
90 | dy = ymax - ymin;
91 | dt = 1./dx; // partial t / partial x
92 | u = (y - ymin)/dy;
93 | *z_p = dt*(-(1.-u)*zminmin + (1.-u)*zmaxmin - u*zminmax + u*zmaxmax);
94 | return GSL_SUCCESS;
95 | }
96 |
97 | static int bilinear_deriv_y(const void* state, const double xarr[], const double yarr[], const double zarr[], size_t xsize, size_t ysize, double x, double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z_p) {
98 | double xmin, xmax, ymin, ymax, zminmin, zminmax, zmaxmin, zmaxmax;
99 | double dx, dy;
100 | double t, du;
101 | size_t xi, yi;
102 | if (xa != NULL) {
103 | xi = gsl_interp_accel_find(xa, xarr, xsize, x);
104 | }
105 | else {
106 | xi = gsl_interp_bsearch(xarr, x, 0, xsize - 1);
107 | }
108 | if (ya != NULL) {
109 | yi = gsl_interp_accel_find(ya, yarr, ysize, y);
110 | }
111 | else {
112 | yi = gsl_interp_bsearch(yarr, y, 0, ysize - 1);
113 | }
114 | xmin = xarr[xi];
115 | xmax = xarr[xi + 1];
116 | ymin = yarr[yi];
117 | ymax = yarr[yi + 1];
118 | zminmin = zarr[INDEX_2D(xi, yi, xsize, ysize)];
119 | zminmax = zarr[INDEX_2D(xi, yi + 1, xsize, ysize)];
120 | zmaxmin = zarr[INDEX_2D(xi + 1, yi, xsize, ysize)];
121 | zmaxmax = zarr[INDEX_2D(xi + 1, yi + 1, xsize, ysize)];
122 | dx = xmax - xmin;
123 | dy = ymax - ymin;
124 | t = (x - xmin)/dx;
125 | du = 1./dy; // partial u / partial y
126 | *z_p = du*(-(1.-t)*zminmin - t*zmaxmin + (1.-t)*zminmax + t*zmaxmax);
127 | return GSL_SUCCESS;
128 | }
129 |
130 | static int bilinear_deriv2(const void* state, const double xarr[], const double yarr[], const double zarr[], size_t xsize, size_t ysize, double x, double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z_pp) {
131 | *z_pp = 0.0;
132 | return GSL_SUCCESS;
133 | }
134 |
135 | static const interp2d_type bilinear_type = {
136 | "bilinear",
137 | 2,
138 | NULL,
139 | &bilinear_init,
140 | &bilinear_eval,
141 | &bilinear_deriv_x,
142 | &bilinear_deriv_y,
143 | &bilinear_deriv2,
144 | &bilinear_deriv2,
145 | &bilinear_deriv2,
146 | NULL
147 | };
148 |
149 | const interp2d_type* interp2d_bilinear = &bilinear_type;
150 |
--------------------------------------------------------------------------------
/python/pkgconfig.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Copyright (c) 2013 Matthias Vogelgesang
3 |
4 | # Permission is hereby granted, free of charge, to any person obtaining a copy
5 | # of this software and associated documentation files (the "Software"), to deal
6 | # in the Software without restriction, including without limitation the rights
7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | # copies of the Software, and to permit persons to whom the Software is
9 | # furnished to do so, subject to the following conditions:
10 |
11 | # The above copyright notice and this permission notice shall be included in
12 | # all copies or substantial portions of the Software.
13 |
14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | # SOFTWARE.
21 |
22 | """pkgconfig is a Python module to interface with the pkg-config command line
23 | tool."""
24 |
25 | import os
26 | import subprocess
27 | import re
28 | import collections
29 | from functools import wraps
30 |
31 |
32 | def _compare_versions(v1, v2):
33 | """
34 | Compare two version strings and return -1, 0 or 1 depending on the equality
35 | of the subset of matching version numbers.
36 |
37 | The implementation is taken from the top answer at
38 | http://stackoverflow.com/a/1714190/997768.
39 | """
40 | def normalize(v):
41 | return [int(x) for x in re.sub(r'(\.0+)*$', '', v).split(".")]
42 |
43 | n1 = normalize(v1)
44 | n2 = normalize(v2)
45 |
46 | return (n1 > n2) - (n1 < n2)
47 |
48 |
49 | def _split_version_specifier(spec):
50 | """Splits version specifiers in the form ">= 0.1.2" into ('0.1.2', '>=')"""
51 | m = re.search(r'([<>=]?=?)?\s*((\d*\.)*\d*)', spec)
52 | return m.group(2), m.group(1)
53 |
54 |
55 | def _convert_error(func):
56 | @wraps(func)
57 | def _wrapper(*args, **kwargs):
58 | try:
59 | return func(*args, **kwargs)
60 | except OSError:
61 | raise EnvironmentError("pkg-config is not installed")
62 |
63 | return _wrapper
64 |
65 |
66 | @_convert_error
67 | def _query(package, option):
68 | pkg_config_exe = os.environ.get('PKG_CONFIG', None) or 'pkg-config'
69 | cmd = '{0} {1} {2}'.format(pkg_config_exe, option, package).split()
70 | proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
71 | stderr=subprocess.PIPE)
72 | out, err = proc.communicate()
73 |
74 | return out.rstrip().decode('utf-8')
75 |
76 |
77 | @_convert_error
78 | def exists(package):
79 | """
80 | Return True if package information is available.
81 |
82 | If ``pkg-config`` not on path, raises ``EnvironmentError``.
83 | """
84 | pkg_config_exe = os.environ.get('PKG_CONFIG', None) or 'pkg-config'
85 | cmd = '{0} --exists {1}'.format(pkg_config_exe, package).split()
86 | return subprocess.call(cmd) == 0
87 |
88 |
89 | @_convert_error
90 | def requires(package):
91 | """
92 | Return a list of package names that is required by the package.
93 |
94 | If ``pkg-config`` not on path, raises ``EnvironmentError``.
95 | """
96 | return _query(package, '--print-requires').split('\n')
97 |
98 |
99 | def cflags(package):
100 | """
101 | Return the CFLAGS string returned by pkg-config.
102 |
103 | If ``pkg-config`` not on path, raises ``EnvironmentError``.
104 | """
105 | return _query(package, '--cflags')
106 |
107 |
108 | def libs(package):
109 | """Return the LDFLAGS string returned by pkg-config."""
110 | return _query(package, '--libs')
111 |
112 |
113 | def installed(package, version):
114 | """
115 | Check if the package meets the required version.
116 |
117 | The version specifier consists of an optional comparator (one of =, ==, >,
118 | <, >=, <=) and an arbitrarily long version number separated by dots. The
119 | should be as you would expect, e.g. for an installed version '0.1.2' of
120 | package 'foo':
121 |
122 | >>> installed('foo', '==0.1.2')
123 | True
124 | >>> installed('foo', '<0.1')
125 | False
126 | >>> installed('foo', '>= 0.0.4')
127 | True
128 |
129 | If ``pkg-config`` not on path, raises ``EnvironmentError``.
130 | """
131 | if not exists(package):
132 | return False
133 |
134 | number, comparator = _split_version_specifier(version)
135 | modversion = _query(package, '--modversion')
136 |
137 | try:
138 | result = _compare_versions(modversion, number)
139 | except ValueError:
140 | msg = "{0} is not a correct version specifier".format(version)
141 | raise ValueError(msg)
142 |
143 | if comparator in ('', '=', '=='):
144 | return result == 0
145 |
146 | if comparator == '>':
147 | return result > 0
148 |
149 | if comparator == '>=':
150 | return result >= 0
151 |
152 | if comparator == '<':
153 | return result < 0
154 |
155 | if comparator == '<=':
156 | return result <= 0
157 |
158 |
159 | _PARSE_MAP = {
160 | '-D': 'define_macros',
161 | '-I': 'include_dirs',
162 | '-L': 'library_dirs',
163 | '-l': 'libraries'
164 | }
165 |
166 |
167 | def parse(packages):
168 | """
169 | Parse the output from pkg-config about the passed package or packages.
170 |
171 | Builds a dictionary containing the 'libraries', the 'library_dirs',
172 | the 'include_dirs', and the 'define_macros' that are presented by
173 | pkg-config. *package* is a string with space-delimited package names.
174 |
175 | If ``pkg-config`` not on path, raises ``EnvironmentError``.
176 | """
177 | def parse_package(package):
178 | result = collections.defaultdict(set)
179 |
180 | # Execute the query to pkg-config and clean the result.
181 | out = _query(package, '--cflags --libs')
182 | out = out.replace('\\"', '')
183 |
184 | # Iterate through each token in the output.
185 | for token in out.split():
186 | key = _PARSE_MAP.get(token[:2])
187 | if key:
188 | result[key].add(token[2:].strip())
189 |
190 | # Iterate and clean define macros.
191 | macros = set()
192 | for declaration in result['define_macros']:
193 | macro = tuple(declaration.split('='))
194 | if len(macro) == 1:
195 | macro += '',
196 |
197 | macros.add(macro)
198 |
199 | result['define_macros'] = macros
200 |
201 | # Return parsed configuration.
202 | return result
203 |
204 | # Go through all package names and update the result dict accordingly.
205 | result = collections.defaultdict(set)
206 |
207 | for package in packages.split():
208 | for k, v in parse_package(package).items():
209 | result[k].update(v)
210 |
211 | return result
212 |
213 |
214 | def list_all():
215 | """Return a list of all packages found by pkg-config."""
216 | packages = [line.split()[0] for line in _query('', '--list-all').split('\n')]
217 | return packages
218 |
--------------------------------------------------------------------------------
/src/2D_interp/interp2d_spline.C:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of interp2d, a GSL-compatible two-dimensional
3 | * interpolation library.
4 | *
5 | * Copyright 2012 David Zaslavsky
6 | * Portions based on GNU GSL interpolation code,
7 | * copyright 1996, 1997, 1998, 1999, 2000, 2004 Gerard Jungman
8 | *
9 | * This program is free software: you can redistribute it and/or modify
10 | * it under the terms of the GNU General Public License as published by
11 | * the Free Software Foundation, either version 3 of the License, or
12 | * (at your option) any later version.
13 |
14 | * This program is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | * GNU General Public License for more details.
18 |
19 | * You should have received a copy of the GNU General Public License
20 | * along with this program. If not, see .
21 | */
22 |
23 | #include
24 | #include
25 | #include
26 | #include "2D_interp/interp2d_spline.h"
27 |
28 | interp2d_spline* interp2d_spline_alloc(const interp2d_type* T, size_t xsize, size_t ysize) {
29 | double* array_mem;
30 | interp2d_spline* interp;
31 | if (xsize < T->min_size || ysize < T->min_size) {
32 | GSL_ERROR_NULL("insufficient number of points for interpolation type", GSL_EINVAL);
33 | }
34 | interp = (interp2d_spline*)malloc(sizeof(interp2d_spline));
35 | if (interp == NULL) {
36 | GSL_ERROR_NULL("failed to allocate space for interp2d_spline struct", GSL_ENOMEM);
37 | }
38 | interp->interp_object.type = T;
39 | interp->interp_object.xsize = xsize;
40 | interp->interp_object.ysize = ysize;
41 | if (interp->interp_object.type->alloc == NULL) {
42 | interp->interp_object.state = NULL;
43 | }
44 | else {
45 | interp->interp_object.state = interp->interp_object.type->alloc(xsize, ysize);
46 | if (interp->interp_object.state == NULL) {
47 | free(interp);
48 | GSL_ERROR_NULL("failed to allocate space for interp2d_spline state", GSL_ENOMEM);
49 | }
50 | }
51 | // Use one contiguous block of memory for all three data arrays.
52 | // That way the code fails immediately if there isn't sufficient space for everything,
53 | // rather than allocating one or two and then having to free them.
54 | array_mem = (double*)calloc(xsize + ysize + xsize * ysize, sizeof(double));
55 | if (array_mem == NULL) {
56 | interp->interp_object.type->free(interp->interp_object.state);
57 | free(interp);
58 | GSL_ERROR_NULL("failed to allocate space for data arrays", GSL_ENOMEM);
59 | }
60 | interp->xarr = array_mem;
61 | interp->yarr = array_mem + xsize;
62 | interp->zarr = array_mem + xsize + ysize;
63 | return interp;
64 | }
65 |
66 | int interp2d_spline_init(interp2d_spline* interp, const double xarr[], const double yarr[], const double zarr[], size_t xsize, size_t ysize) {
67 | int status = interp2d_init(&(interp->interp_object), xarr, yarr, zarr, xsize, ysize);
68 | memcpy(interp->xarr, xarr, xsize * sizeof(double));
69 | memcpy(interp->yarr, yarr, ysize * sizeof(double));
70 | memcpy(interp->zarr, zarr, xsize * ysize * sizeof(double));
71 | return status;
72 | }
73 |
74 | void interp2d_spline_free(interp2d_spline* interp) {
75 | if (!interp) {
76 | return;
77 | }
78 | if (interp->interp_object.type->free) {
79 | interp->interp_object.type->free(interp->interp_object.state);
80 | }
81 | // interp->xarr points to the beginning of one contiguous block of memory
82 | // that holds interp->xarr, interp->yarr, and interp->zarr. So it all gets
83 | // freed with one call. cf. interp2d_spline_alloc() implementation
84 | free(interp->xarr);
85 | free(interp);
86 | }
87 |
88 | // All these methods just call their interp2d_eval* equivalents
89 |
90 | double interp2d_spline_eval(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya) {
91 | return interp2d_eval(&(interp->interp_object), interp->xarr, interp->yarr, interp->zarr, x, y, xa, ya);
92 | }
93 |
94 | int interp2d_spline_eval_e(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z) {
95 | return interp2d_eval_e(&(interp->interp_object), interp->xarr, interp->yarr, interp->zarr, x, y, xa, ya, z);
96 | }
97 |
98 | double interp2d_spline_eval_deriv_x(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya) {
99 | return interp2d_eval_deriv_x(&(interp->interp_object), interp->xarr, interp->yarr, interp->zarr, x, y, xa, ya);
100 | }
101 |
102 | int interp2d_spline_eval_deriv_x_e(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z) {
103 | return interp2d_eval_deriv_x_e(&(interp->interp_object), interp->xarr, interp->yarr, interp->zarr, x, y, xa, ya, z);
104 | }
105 |
106 | double interp2d_spline_eval_deriv_y(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya) {
107 | return interp2d_eval_deriv_y(&(interp->interp_object), interp->xarr, interp->yarr, interp->zarr, x, y, xa, ya);
108 | }
109 |
110 | int interp2d_spline_eval_deriv_y_e(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z) {
111 | return interp2d_eval_deriv_y_e(&(interp->interp_object), interp->xarr, interp->yarr, interp->zarr, x, y, xa, ya, z);
112 | }
113 |
114 | double interp2d_spline_eval_deriv_xx(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya) {
115 | return interp2d_eval_deriv_xx(&(interp->interp_object), interp->xarr, interp->yarr, interp->zarr, x, y, xa, ya);
116 | }
117 |
118 | int interp2d_spline_eval_deriv_xx_e(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z) {
119 | return interp2d_eval_deriv_xx_e(&(interp->interp_object), interp->xarr, interp->yarr, interp->zarr, x, y, xa, ya, z);
120 | }
121 |
122 | double interp2d_spline_eval_deriv_yy(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya) {
123 | return interp2d_eval_deriv_yy(&(interp->interp_object), interp->xarr, interp->yarr, interp->zarr, x, y, xa, ya);
124 | }
125 |
126 | int interp2d_spline_eval_deriv_yy_e(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z) {
127 | return interp2d_eval_deriv_yy_e(&(interp->interp_object), interp->xarr, interp->yarr, interp->zarr, x, y, xa, ya, z);
128 | }
129 |
130 | double interp2d_spline_eval_deriv_xy(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya) {
131 | return interp2d_eval_deriv_xy(&(interp->interp_object), interp->xarr, interp->yarr, interp->zarr, x, y, xa, ya);
132 | }
133 |
134 | int interp2d_spline_eval_deriv_xy_e(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z) {
135 | return interp2d_eval_deriv_xy_e(&(interp->interp_object), interp->xarr, interp->yarr, interp->zarr, x, y, xa, ya, z);
136 | }
137 |
138 | size_t interp2d_spline_min_size(const interp2d_spline* interp) {
139 | return interp2d_min_size(&(interp->interp_object));
140 | }
141 |
142 | const char* interp2d_spline_name(const interp2d_spline* interp) {
143 | return interp2d_name(&(interp->interp_object));
144 | }
145 |
--------------------------------------------------------------------------------
/licenses/lgpl-3.txt:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/include/Utils.h:
--------------------------------------------------------------------------------
1 | #ifndef _UTILS_
2 | #define _UTILS_
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include "2D_interp/interp2d.h"
17 | #include "2D_interp/interp2d_spline.h"
18 |
19 | /* TeV->erg */
20 | #define TeV_to_erg 1.602
21 | /* GeV->erg */
22 | #define GeV_to_erg 1.602e-3
23 | /* eV->erg */
24 | #define eV_to_erg 1.602e-12
25 | /* Thomson cross section */
26 | #define sigma_T 6.6524e-25
27 | /* classical electron radius (cm) */
28 | #define e_radius 2.8179e-13
29 | /* parsec to cm */
30 | #define pc_to_cm 3.0857e18
31 | /* kiloparsec to cm */
32 | #define kpc_to_cm 3.0857e21
33 | /* AU to cm*/
34 | #define AU_to_cm 1.496e13
35 | /* proton mass in g */
36 | #define m_p_g 1.6726e-24
37 | /* year in seconds */
38 | #define yr_to_sec 3.15576e7
39 | /* solar mass */
40 | #define mSol 1.9891e33
41 | /* Thomson cross section */
42 | #define sigma_T 6.6524e-25
43 | /* electron mass in erg */
44 | #define m_e 8.187e-7
45 | /* electron mass in g */
46 | #define m_e_g 9.1093837015e-28
47 | /* boltzmann constant (erg/K) */
48 | #define kb 1.380658e-16
49 | /* proton mass in erg */
50 | #define m_p 1.50310854e-3
51 | /* pi0 mass in erg */
52 | #define m_pi 2.1622194e-4
53 | /* parsec to cm */
54 | #define pc_to_cm 3.0857e18
55 | /* well... pi! */
56 | #define pi 3.14159265359
57 | /* year in seconds */
58 | #define yr_to_sec 3.15576e7
59 | /* solar mass */
60 | #define mSol 1.9891e33
61 | /* speed of light cm/s */
62 | #define c_speed 29979245800.
63 | /* elementary charge */
64 | #define el_charge 4.80320427e-10
65 | /* classical electron radius (cm) */
66 | #define eRadius 2.8179e-13
67 | /* planck's constant */
68 | #define hp 6.62606896e-27
69 | /* fine structure constant */
70 | #define fineStructConst 7.2974e-3
71 | /* hour in seconds */
72 | #define h_to_sec 3.6e3
73 | /* pc to lyr */
74 | #define pc_to_lyr 3.26156
75 | /* natural logarithm of 10 */
76 | #define ln10 2.302585
77 |
78 | using namespace std;
79 |
80 | /**
81 | * @file Utils.C
82 | * @author Joachim Hahn
83 | * @short Class that provides utility functions
84 | * Provides different things, mainly useful for population studies.
85 | * This includes spiral galaxy models as well as gas distributions,
86 | * B-Field distributions, coordinate transformations etc.
87 | * Also includes more technical functions that are helpful in writing
88 | * GAMERA programs.
89 | */
90 |
91 | bool sortcriterionfirstcolumn (vector i,vector j);
92 | bool sortcriterionsecondcolumn (vector i,vector j);
93 |
94 | class Utils {
95 | private:
96 | bool QUIETMODE;
97 | bool GAMERADESTROYEDTHECONSOLE;
98 | gsl_interp_type *INTERMETH;
99 | gsl_rng * r;
100 | gsl_spline *INTERNAL1DSPLINE;
101 | interp2d_spline *INTERNAL2DSPLINE;
102 |
103 | gsl_interp_accel *acc;
104 | gsl_interp_accel *xacc;
105 | gsl_interp_accel *yacc;
106 |
107 | public:
108 | /// Constructor
109 | Utils(bool DRAWLOGO = false);
110 | /// Destructor
111 | ~Utils();
112 | /// Generic parameter file reading function
113 | int ReadParameterFile(string inputname, vector parameter_names,
114 | vector files_names,
115 | vector ¶meter_values,
116 | vector &files);
117 | /// Draw the GAMERA logo
118 | void DrawGamera();
119 | /// Draw the GAPPA logo
120 | void DrawGappa();
121 | /// Write spectrum on file
122 | void WriteOut(vector > sp, string outname);
123 | /// Read a spectrum from file
124 | void ReadIn(string inname, vector< vector > &sp);
125 | /// Random number generator [0,1)
126 | double Random();
127 | /// Get n uniform random numbers in [x_min,x_max)
128 | vector UniformRandom(double x_min, double x_max,int n);
129 | /// Get linearly distributed variates
130 | vector LinearRandom(double slope, double x_min, double x_max, int n);
131 | /// Get power-law distributed variates
132 | vector PowerLawRandom(double index, double x_min, double x_max,
133 | int n);
134 | /// Get random numbers with gaussian distribution
135 | vector GaussianRandom(double width, double offset, int n);
136 | vector SignRandom(int n);
137 | vector ExponentialRandom(double ind_norm, double x_min,
138 | double x_max, int n);
139 | vector CustomFunctionRandom(vector< vector > f, int n,
140 | double xmin = 0., double xmax = 0.);
141 | vector< vector > CustomFunctionRandom2D(vector< vector > f,
142 | int n,
143 | double xmin=0., double xmax=0.,
144 | double ymin=0., double ymax=0.);
145 | double Integrate(vector< vector > f, double xmin=0., double xmax=0.);
146 | vector< vector< double> > IntegratedProfile(vector< vector > f);
147 | gsl_spline *GSLsplineFromTwoDVector(vector< vector > v);
148 | vector< vector > SortTwoDVector(vector< vector > v,
149 | int column);
150 | void TwoDVectorPushBack(double x, double y, vector< vector > &v);
151 | void TwoDVectorPushBack(double x, double y, double z, vector< vector > &v);
152 | vector< vector > ZipTwoOneDVectors(vector x,
153 | vector y);
154 | double EvalSpline(double x, gsl_spline *s, gsl_interp_accel *a,
155 | const char* t, int l);
156 | void SetInterpolationMethod(string intermeth);
157 | void Clear2DVector(vector< vector > &v);
158 | vector< vector > VectorAxisLogarithm(vector< vector > v,
159 | unsigned int column); ///< Make log10 of column
160 |
161 | vector< vector > VectorAxisPow10(vector< vector > v,
162 | int column);
163 | interp2d_spline *TwoDsplineFromTwoDVector(vector< vector > v,
164 | double &xmin, double &xmax,
165 | double &ymin, double &ymax);
166 | void SetInternal1DSpline(vector< vector > v) {
167 | gsl_interp_accel_reset(acc);
168 | if(INTERNAL1DSPLINE!=NULL) gsl_spline_free(INTERNAL1DSPLINE);
169 | INTERNAL1DSPLINE = GSLsplineFromTwoDVector(v);}
170 | void SetInternal2DSpline(vector< vector > v) {
171 | // std::cout<<" -- - --- --- " < > f, double emin=0., double emax=0.);
192 | double EnergyContentFast(vector< vector > f);
193 | vector< vector > MeshgridToTwoDVector(vector x, vector y,
194 | vector< vector > mesh);
195 | /* void TwoDVectorToMeshgrid(vector< vector > vec, vector &x,*/
196 | /* vector &y, vector< vector > &mesh);*/
197 | vector GetVectorMinMax(vector< vector > v, unsigned int axis);
198 | vector GetVectorMinMaxIndices(vector< vector > v, unsigned int axis);
199 | void ToggleQuietMode() { QUIETMODE = QUIETMODE == true ? false : true; }
200 | bool GetQuietMode() {return QUIETMODE;}
201 | vector< vector > RemoveZeroEntries(vector< vector > v);
202 | vector< vector > TwoDVectorFabs(vector< vector > v);
203 | vector RotateVector(vector v, vector p1, vector p2);
204 | double Gaussian1D(double x, double sigma, double mu=0., double norm=0.);
205 | double LogisticsFunction(double z, double h, double w);
206 | double Norm(vector v);
207 | };
208 | #endif
209 |
--------------------------------------------------------------------------------
/src/2D_interp/interp2d.C:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of interp2d, a GSL-compatible two-dimensional
3 | * interpolation library.
4 | *
5 | * Copyright 2012 David Zaslavsky
6 | * Portions based on GNU GSL interpolation code,
7 | * copyright 1996, 1997, 1998, 1999, 2000, 2004 Gerard Jungman
8 | *
9 | * This program is free software: you can redistribute it and/or modify
10 | * it under the terms of the GNU General Public License as published by
11 | * the Free Software Foundation, either version 3 of the License, or
12 | * (at your option) any later version.
13 |
14 | * This program is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | * GNU General Public License for more details.
18 |
19 | * You should have received a copy of the GNU General Public License
20 | * along with this program. If not, see .
21 | */
22 |
23 | #include
24 | #include
25 | #include "2D_interp/interp2d.h"
26 |
27 | /**
28 | * Triggers a GSL error if the argument is not equal to GSL_SUCCESS.
29 | * If the argument is GSL_SUCCESS, this does nothing.
30 | */
31 | #define DISCARD_STATUS(s) if ((s) != GSL_SUCCESS) { GSL_ERROR_VAL("interpolation error", (s), GSL_NAN); }
32 |
33 | interp2d* interp2d_alloc(const interp2d_type* T, size_t xsize, size_t ysize) {
34 | interp2d* interp;
35 | if (xsize < T->min_size || ysize < T->min_size) {
36 | GSL_ERROR_NULL("insufficient number of points for interpolation type", GSL_EINVAL);
37 | }
38 | interp = (interp2d*)malloc(sizeof(interp2d));
39 | if (interp == NULL) {
40 | GSL_ERROR_NULL("failed to allocate space for interp2d struct", GSL_ENOMEM);
41 | }
42 | interp->type = T;
43 | interp->xsize = xsize;
44 | interp->ysize = ysize;
45 | if (interp->type->alloc == NULL) {
46 | interp->state = NULL;
47 | return interp;
48 | }
49 | interp->state = interp->type->alloc(xsize, ysize);
50 | if (interp->state == NULL) {
51 | free(interp);
52 | GSL_ERROR_NULL("failed to allocate space for interp2d state", GSL_ENOMEM);
53 | }
54 | return interp;
55 | }
56 |
57 | int interp2d_init(interp2d* interp, const double xarr[], const double yarr[], const double zarr[], size_t xsize, size_t ysize) {
58 | size_t i;
59 | if (xsize != interp->xsize || ysize != interp->ysize) {
60 | GSL_ERROR("data must match size of interpolation object", GSL_EINVAL);
61 | }
62 | for (i = 1; i < xsize; i++) {
63 | if (xarr[i-1] >= xarr[i]) {
64 | GSL_ERROR("x values must be strictly increasing", GSL_EINVAL);
65 | }
66 | }
67 | for (i = 1; i < ysize; i++) {
68 | if (yarr[i-1] >= yarr[i]) {
69 | GSL_ERROR("y values must be strictly increasing", GSL_EINVAL);
70 | }
71 | }
72 | interp->xmin = xarr[0];
73 | interp->xmax = xarr[xsize - 1];
74 | interp->ymin = yarr[0];
75 | interp->ymax = yarr[ysize - 1];
76 | {
77 | int status = interp->type->init(interp->state, xarr, yarr, zarr, xsize, ysize);
78 | return status;
79 | }
80 | }
81 |
82 | void interp2d_free(interp2d* interp) {
83 | if (!interp) {
84 | return;
85 | }
86 | if (interp->type->free) {
87 | interp->type->free(interp->state);
88 | }
89 | free(interp);
90 | }
91 |
92 | /**
93 | * A wrapper function that checks boundary conditions, calls an evaluator
94 | * which implements the actual calculation of the function value or
95 | * derivative etc., and checks the return status.
96 | */
97 | static inline int interp2d_eval_impl(
98 | int (*evaluator)(const void*, const double xa[], const double ya[], const double za[], size_t xsize, size_t ysize, double x, double y, gsl_interp_accel*, gsl_interp_accel*, double* z),
99 | const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya,
100 | double* result
101 | ) {
102 | if (x < interp->xmin || x > interp->xmax) {
103 | char errmsg[80];
104 | snprintf(errmsg, 80, "x value %g not in range %g to %g", x, interp->xmin, interp->xmax);
105 | GSL_ERROR(errmsg, GSL_EDOM);
106 | }
107 | if (y < interp->ymin || y > interp->ymax) {
108 | char errmsg[80];
109 | snprintf(errmsg, 80, "y value %g not in range %g to %g", y, interp->ymin, interp->ymax);
110 | GSL_ERROR(errmsg, GSL_EDOM);
111 | }
112 | return evaluator(interp->state, xarr, yarr, zarr, interp->xsize, interp->ysize, x, y, xa, ya, result);
113 | }
114 |
115 | /**
116 | * Another wrapper function that serves as a drop-in replacement for
117 | * interp2d_eval_impl but does not check the bounds. This can be used
118 | * for extrapolation.
119 | */
120 | static inline int interp2d_eval_impl_no_boundary_check(
121 | int (*evaluator)(const void*, const double xa[], const double ya[], const double za[], size_t xsize, size_t ysize, double x, double y, gsl_interp_accel*, gsl_interp_accel*, double* z),
122 | const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya,
123 | double* result
124 | ) {
125 | return evaluator(interp->state, xarr, yarr, zarr, interp->xsize, interp->ysize, x, y, xa, ya, result);
126 | }
127 |
128 | double interp2d_eval(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya) {
129 | double z;
130 | int status = interp2d_eval_impl(interp->type->eval, interp, xarr, yarr, zarr, x, y, xa, ya, &z);
131 | DISCARD_STATUS(status)
132 | return z;
133 | }
134 |
135 | double interp2d_eval_no_boundary_check(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya) {
136 | double z;
137 | int status = interp2d_eval_impl_no_boundary_check(interp->type->eval, interp, xarr, yarr, zarr, x, y, xa, ya, &z);
138 | DISCARD_STATUS(status)
139 | return z;
140 | }
141 |
142 | int interp2d_eval_e(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z) {
143 | return interp2d_eval_impl(interp->type->eval, interp, xarr, yarr, zarr, x, y, xa, ya, z);
144 | }
145 |
146 | int interp2d_eval_e_no_boundary_check(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z) {
147 | return interp2d_eval_impl_no_boundary_check(interp->type->eval, interp, xarr, yarr, zarr, x, y, xa, ya, z);
148 | }
149 |
150 | double interp2d_eval_deriv_x(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya) {
151 | double z;
152 | int status = interp2d_eval_impl(interp->type->eval_deriv_x, interp, xarr, yarr, zarr, x, y, xa, ya, &z);
153 | DISCARD_STATUS(status)
154 | return z;
155 | }
156 |
157 | int interp2d_eval_deriv_x_e(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z) {
158 | return interp2d_eval_impl(interp->type->eval_deriv_x, interp, xarr, yarr, zarr, x, y, xa, ya, z);
159 | }
160 |
161 | double interp2d_eval_deriv_y(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya) {
162 | double z;
163 | int status = interp2d_eval_impl(interp->type->eval_deriv_y, interp, xarr, yarr, zarr, x, y, xa, ya, &z);
164 | DISCARD_STATUS(status)
165 | return z;
166 | }
167 |
168 | int interp2d_eval_deriv_y_e(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z) {
169 | return interp2d_eval_impl(interp->type->eval_deriv_y, interp, xarr, yarr, zarr, x, y, xa, ya, z);
170 | }
171 |
172 | double interp2d_eval_deriv_xx(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya) {
173 | double z;
174 | int status = interp2d_eval_impl(interp->type->eval_deriv_xx, interp, xarr, yarr, zarr, x, y, xa, ya, &z);
175 | DISCARD_STATUS(status)
176 | return z;
177 | }
178 |
179 | int interp2d_eval_deriv_xx_e(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z) {
180 | return interp2d_eval_impl(interp->type->eval_deriv_xx, interp, xarr, yarr, zarr, x, y, xa, ya, z);
181 | }
182 |
183 | double interp2d_eval_deriv_yy(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya) {
184 | double z;
185 | int status = interp2d_eval_impl(interp->type->eval_deriv_yy, interp, xarr, yarr, zarr, x, y, xa, ya, &z);
186 | DISCARD_STATUS(status)
187 | return z;
188 | }
189 |
190 | int interp2d_eval_deriv_yy_e(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z) {
191 | return interp2d_eval_impl(interp->type->eval_deriv_yy, interp, xarr, yarr, zarr, x, y, xa, ya, z);
192 | }
193 |
194 | double interp2d_eval_deriv_xy(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya) {
195 | double z;
196 | int status = interp2d_eval_impl(interp->type->eval_deriv_xy, interp, xarr, yarr, zarr, x, y, xa, ya, &z);
197 | DISCARD_STATUS(status)
198 | return z;
199 | }
200 |
201 | int interp2d_eval_deriv_xy_e(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z) {
202 | return interp2d_eval_impl(interp->type->eval_deriv_xy, interp, xarr, yarr, zarr, x, y, xa, ya, z);
203 | }
204 |
205 | size_t interp2d_type_min_size(const interp2d_type* T) {
206 | return T->min_size;
207 | }
208 |
209 | size_t interp2d_min_size(const interp2d* interp) {
210 | return interp->type->min_size;
211 | }
212 |
213 | const char* interp2d_name(const interp2d* interp) {
214 | return interp->type->name;
215 | }
216 |
--------------------------------------------------------------------------------
/include/2D_interp/interp2d_spline.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of interp2d, a GSL-compatible two-dimensional
3 | * interpolation library.
4 | *
5 | * Copyright 2013 David Zaslavsky
6 | * Portions based on GNU GSL interpolation code,
7 | * copyright 1996, 1997, 1998, 1999, 2000, 2004 Gerard Jungman
8 | *
9 | * This program is free software: you can redistribute it and/or modify
10 | * it under the terms of the GNU General Public License as published by
11 | * the Free Software Foundation, either version 3 of the License, or
12 | * (at your option) any later version.
13 |
14 | * This program is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | * GNU General Public License for more details.
18 |
19 | * You should have received a copy of the GNU General Public License
20 | * along with this program. If not, see .
21 | */
22 | /**
23 | * @file interp2d_spline.h
24 | * @brief Public interface for high-level 2D interpolation functions
25 | *
26 | * This is the public interface to the high-level functions of the
27 | * `%interp2d` library, the ones that _do_ store the data arrays.
28 | * If you're using the high-level interface, you only use the functions in
29 | * this file, unless you're creating a new interpolation type.
30 | *
31 | * The typical workflow is
32 | *
33 | * 1. create an interpolation spline object using interp2d_spline_alloc()
34 | * 2. initialize it using interp2d_spline_init()
35 | * 3. evaluate the interpolating function or its derivatives using
36 | * interp2d_spline_eval() or its counterparts, possibly many times
37 | * 4. free the memory using interp2d_spline_free()
38 | *
39 | * @see interp2d.h
40 | */
41 | #ifndef __INTERP_2D_SPLINE_H__
42 | #define __INTERP_2D_SPLINE_H__
43 |
44 | #include
45 | #include "2D_interp/interp2d.h"
46 |
47 | #ifdef __cplusplus
48 | extern "C" {
49 | #endif
50 |
51 | /**
52 | * A 2D interpolation object which stores the arrays defining the function.
53 | * In all other respects, this is just like an interp2d object.
54 | * Instances should be obtained from interp2d_spline_alloc().
55 | */
56 | typedef struct {
57 | /** The low-level interpolation object */
58 | interp2d interp_object;
59 | /** The x data array */
60 | double* xarr;
61 | /** The y data array */
62 | double* yarr;
63 | /** The z data array */
64 | double* zarr;
65 | } interp2d_spline;
66 |
67 | /**
68 | * Allocate a new interpolation spline object. When you want to do an
69 | * interpolation using the high-level interface, you start by calling
70 | * this function. Don't forget to free the memory using
71 | * interp2d_spline_free() when you're done with it.
72 | *
73 | * @param[in] T the `const struct` representing the interpolation algorithm
74 | * you want to use. This should be one of the predefined types provided
75 | * in this library, like interp2d_bilinear or interp2d_bicubic, unless you
76 | * have your own interpolation type you want to use.
77 | * @param[in] xsize the size in the x direction of the grid that will
78 | * specify the function being interpolated
79 | * @param[in] ysize the size in the y direction of the grid that will
80 | * specify the function being interpolated
81 | * @return the newly allocated interpolation object
82 | */
83 | interp2d_spline* interp2d_spline_alloc(const interp2d_type* T, size_t xsize, size_t ysize);
84 |
85 | /**
86 | * Initialize an interpolation spline object with data points that define
87 | * the function being interpolated. This method stores the sizes of the
88 | * arrays and possibly other relevant data in the interp2d_spline object,
89 | * but unlike the low-level equivalent interp2d_init(), it also stores
90 | * the data arrays `xa`, `ya`, and `za`. The content of the arrays is copied,
91 | * so if you change the array elements after calling this, it won't affect
92 | * the interpolation spline object.
93 | *
94 | * This completely resets the state of the object, so it is safe to reuse an
95 | * existing object to interpolate a new function by simply calling
96 | * interp2d_spline_init() on the object with the new arrays. The new arrays
97 | * must be the same size as the old arrays in both dimensions, otherwise this
98 | * function returns an error code.
99 | *
100 | * @param[in] interp the interpolation object, previously initialized
101 | * @param[in] xa the x coordinates of the data, of length `xsize`
102 | * @param[in] ya the y coordinates of the data, of length `ysize`
103 | * @param[in] za the z coordinates of the data, of length `xsize*ysize`
104 | * @param[in] xsize the length of the array `xa`
105 | * @param[in] ysize the length of the array `ya`
106 | * @return a status code, either `GSL_SUCCESS` or an error code indicating
107 | * what went wrong
108 | */
109 | int interp2d_spline_init(interp2d_spline* interp, const double xa[], const double ya[], const double za[], size_t xsize, size_t ysize);
110 |
111 | /**
112 | * Free the interpolation spline object.
113 | *
114 | * @param[in] interp an interpolation spline object previously allocated
115 | * with interp2d_spline_alloc()
116 | */
117 | void interp2d_spline_free(interp2d_spline* interp);
118 |
119 | /**
120 | * Evaluate the interpolating function at the point `(x,y)`.
121 | *
122 | * @param[in] interp the interpolation spline object, already initialized
123 | * using interp2d_spline_init()
124 | * @param[in] x the x coordinate at which to evaluate the interpolation
125 | * @param[in] y the y coordinate at which to evaluate the interpolation
126 | * @param[in] xa the accelerator object for the x direction (may be NULL)
127 | * @param[in] ya the accelerator object for the y direction (may be NULL)
128 | * @return the value of the interpolating function at `(x,y)`
129 | */
130 | double interp2d_spline_eval(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya);
131 |
132 | /**
133 | * Evaluate the interpolating function at the point `(x,y)`.
134 | *
135 | * @param[in] interp the interpolation spline object, already initialized
136 | * using interp2d_spline_init()
137 | * @param[in] x the x coordinate at which to evaluate the interpolation
138 | * @param[in] y the y coordinate at which to evaluate the interpolation
139 | * @param[in] xa the accelerator object for the x direction (may be NULL)
140 | * @param[in] ya the accelerator object for the y direction (may be NULL)
141 | * @param[out] z the value of the interpolating function at `(x,y)`
142 | * @return a status code, either `GSL_SUCCESS` or an error code indicating
143 | * what went wrong
144 | */
145 | int interp2d_spline_eval_e(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z);
146 |
147 | /**
148 | * Evaluate the x derivative of the interpolating function at `(x,y)`.
149 | *
150 | * @param[in] interp the interpolation spline object, already initialized
151 | * using interp2d_spline_init()
152 | * @param[in] x the x coordinate at which to evaluate the interpolation
153 | * @param[in] y the y coordinate at which to evaluate the interpolation
154 | * @param[in] xa the accelerator object for the x direction (may be NULL)
155 | * @param[in] ya the accelerator object for the y direction (may be NULL)
156 | * @return the x derivative of the interpolating function at `(x,y)`
157 | */
158 | double interp2d_spline_eval_deriv_x(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya);
159 |
160 | /**
161 | * Evaluate the x derivative of the interpolating function at `(x,y)`.
162 | *
163 | * @param[in] interp the interpolation spline object, already initialized
164 | * using interp2d_spline_init()
165 | * @param[in] x the x coordinate at which to evaluate the interpolation
166 | * @param[in] y the y coordinate at which to evaluate the interpolation
167 | * @param[in] xa the accelerator object for the x direction (may be NULL)
168 | * @param[in] ya the accelerator object for the y direction (may be NULL)
169 | * @param[out] z the x derivative of the interpolating function at `(x,y)`
170 | * @return a status code, either `GSL_SUCCESS` or an error code indicating
171 | * what went wrong
172 | */
173 | int interp2d_spline_eval_deriv_x_e(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z);
174 |
175 | /**
176 | * Evaluate the y derivative of the interpolating function at `(x,y)`.
177 | *
178 | * @param[in] interp the interpolation spline object, already initialized
179 | * using interp2d_spline_init()
180 | * @param[in] x the x coordinate at which to evaluate the interpolation
181 | * @param[in] y the y coordinate at which to evaluate the interpolation
182 | * @param[in] xa the accelerator object for the x direction (may be NULL)
183 | * @param[in] ya the accelerator object for the y direction (may be NULL)
184 | * @return the y derivative of the interpolating function at `(x,y)`
185 | */
186 | double interp2d_spline_eval_deriv_y(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya);
187 |
188 | /**
189 | * Evaluate the y derivative of the interpolating function at `(x,y)`.
190 | *
191 | * @param[in] interp the interpolation spline object, already initialized
192 | * using interp2d_spline_init()
193 | * @param[in] x the x coordinate at which to evaluate the interpolation
194 | * @param[in] y the y coordinate at which to evaluate the interpolation
195 | * @param[in] xa the accelerator object for the x direction (may be NULL)
196 | * @param[in] ya the accelerator object for the y direction (may be NULL)
197 | * @param[out] z the y derivative of the interpolating function at `(x,y)`
198 | * @return a status code, either `GSL_SUCCESS` or an error code indicating
199 | * what went wrong
200 | */
201 | int interp2d_spline_eval_deriv_y_e(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z);
202 |
203 | /**
204 | * Evaluate the second x derivative of the interpolating function at `(x,y)`.
205 | *
206 | * @param[in] interp the interpolation spline object, already initialized
207 | * using interp2d_spline_init()
208 | * @param[in] x the x coordinate at which to evaluate the interpolation
209 | * @param[in] y the y coordinate at which to evaluate the interpolation
210 | * @param[in] xa the accelerator object for the x direction (may be NULL)
211 | * @param[in] ya the accelerator object for the y direction (may be NULL)
212 | * @return the second x derivative of the interpolating function at `(x,y)`
213 | */
214 | double interp2d_spline_eval_deriv_xx(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya);
215 |
216 | /**
217 | * Evaluate the second x derivative of the interpolating function at `(x,y)`.
218 | *
219 | * @param[in] interp the interpolation spline object, already initialized
220 | * using interp2d_spline_init()
221 | * @param[in] x the x coordinate at which to evaluate the interpolation
222 | * @param[in] y the y coordinate at which to evaluate the interpolation
223 | * @param[in] xa the accelerator object for the x direction (may be NULL)
224 | * @param[in] ya the accelerator object for the y direction (may be NULL)
225 | * @param[out] z the second x derivative of the interpolating function at `(x,y)`
226 | * @return a status code, either `GSL_SUCCESS` or an error code indicating
227 | * what went wrong
228 | */
229 | int interp2d_spline_eval_deriv_xx_e(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z);
230 |
231 | /**
232 | * Evaluate the second y derivative of the interpolating function at `(x,y)`.
233 | *
234 | * @param[in] interp the interpolation spline object, already initialized
235 | * using interp2d_spline_init()
236 | * @param[in] x the x coordinate at which to evaluate the interpolation
237 | * @param[in] y the y coordinate at which to evaluate the interpolation
238 | * @param[in] xa the accelerator object for the x direction (may be NULL)
239 | * @param[in] ya the accelerator object for the y direction (may be NULL)
240 | * @return the second y derivative of the interpolating function at `(x,y)`
241 | */
242 | double interp2d_spline_eval_deriv_yy(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya);
243 |
244 | /**
245 | * Evaluate the second y derivative of the interpolating function at `(x,y)`.
246 | *
247 | * @param[in] interp the interpolation spline object, already initialized
248 | * using interp2d_spline_init()
249 | * @param[in] x the x coordinate at which to evaluate the interpolation
250 | * @param[in] y the y coordinate at which to evaluate the interpolation
251 | * @param[in] xa the accelerator object for the x direction (may be NULL)
252 | * @param[in] ya the accelerator object for the y direction (may be NULL)
253 | * @param[out] z the second y derivative of the interpolating function at `(x,y)`
254 | * @return a status code, either `GSL_SUCCESS` or an error code indicating
255 | * what went wrong
256 | */
257 | int interp2d_spline_eval_deriv_yy_e(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z);
258 |
259 | /**
260 | * Evaluate the cross derivative of the interpolating function at `(x,y)`.
261 | * This is \f$\partial_{xy}f(x,y)\f$.
262 | *
263 | * @param[in] interp the interpolation spline object, already initialized
264 | * using interp2d_spline_init()
265 | * @param[in] x the x coordinate at which to evaluate the interpolation
266 | * @param[in] y the y coordinate at which to evaluate the interpolation
267 | * @param[in] xa the accelerator object for the x direction (may be NULL)
268 | * @param[in] ya the accelerator object for the y direction (may be NULL)
269 | * @return the cross derivative of the interpolating function at `(x,y)`
270 | */
271 | double interp2d_spline_eval_deriv_xy(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya);
272 |
273 | /**
274 | * Evaluate the cross derivative of the interpolating function at `(x,y)`.
275 | * This is \f$\partial_{xy}f(x,y)\f$.
276 | *
277 | * @param[in] interp the interpolation spline object, already initialized
278 | * using interp2d_spline_init()
279 | * @param[in] x the x coordinate at which to evaluate the interpolation
280 | * @param[in] y the y coordinate at which to evaluate the interpolation
281 | * @param[in] xa the accelerator object for the x direction (may be NULL)
282 | * @param[in] ya the accelerator object for the y direction (may be NULL)
283 | * @param[out] z the cross derivative of the interpolating function at `(x,y)`
284 | * @return a status code, either `GSL_SUCCESS` or an error code indicating
285 | * what went wrong
286 | */
287 | int interp2d_spline_eval_deriv_xy_e(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z);
288 |
289 | /**
290 | * Return the minimum number of points in each dimension needed by the
291 | * type of the given interpolation object. This just accesses the type
292 | * from `interp` and calls interp2d_type_min_size() on it.
293 | */
294 | size_t interp2d_spline_min_size(const interp2d_spline* interp);
295 |
296 | /**
297 | * Return the type name of the given interpolation. This just accesses
298 | * the type object from `interp` and returns its name.
299 | */
300 | const char* interp2d_spline_name(const interp2d_spline* interp);
301 |
302 | #ifdef __cplusplus
303 | }
304 | #endif
305 |
306 | #endif
307 |
--------------------------------------------------------------------------------
/include/Astro.h:
--------------------------------------------------------------------------------
1 | #ifndef _ASTRO_
2 | #define _ASTRO_
3 |
4 | #include "Utils.h"
5 |
6 | /* TeV->erg */
7 | #define TeV_to_erg 1.602
8 | /* parsec to cm */
9 | #define pc_to_cm 3.0857e18
10 | /* kiloparsec to cm */
11 | #define kpc_to_cm 3.0857e21
12 | /* proton mass in g */
13 | #define m_p_g 1.6726e-24
14 | /* year in seconds */
15 | #define yr_to_sec 3.15576e7
16 | /* solar mass */
17 | #define mSol 1.9891e33
18 | /* Thomson cross section */
19 | #define sigma_T 6.6524e-25
20 | /* electron mass in erg */
21 | #define m_e 8.187e-7
22 | /* boltzmann constant (erg/K) */
23 | #define kb 1.380658e-16
24 | /* proton mass in erg */
25 | #define m_p 1.50310854e-3
26 | /* pi0 mass in erg */
27 | #define m_pi 2.1622194e-4
28 | /* parsec to cm */
29 | #define pc_to_cm 3.0857e18
30 | /* year in seconds */
31 | #define yr_to_sec 3.15576e7
32 | /* solar mass */
33 | #define mSol 1.9891e33
34 | /* speed of light cm/s */
35 | #define c_speed 29979245800.
36 | /* elementary charge */
37 | #define el_charge 4.80320427e-10
38 | /* classical electron radius (cm) */
39 | #define eRadius 2.8179e-13
40 | /* planck's constant */
41 | #define hp 6.62606896e-27
42 | /* fine structure constant */
43 | #define fineStructConst 7.2974e-3
44 | /* hour in seconds */
45 | #define h_to_sec 3.6e3
46 | /* pc to lyr */
47 | #define pc_to_lyr 3.26156
48 |
49 | using namespace std;
50 |
51 | /**
52 | * @file Astro.C
53 | * @author Joachim Hahn
54 | * @short Class that provides utility functions
55 | * Provides different things, mainly useful for population studies.
56 | * This includes spiral galaxy models as well as gas distributions,
57 | * B-Field distributions, coordinate transformations etc.
58 | * Also includes more technical functions that are helpful in writing
59 | * GAMERA programs.
60 | */
61 |
62 | class Astro {
63 | private:
64 | Utils *fUtils;
65 | vector xyzref;
66 | void TranslateToReferencePoint(double &x, double &y, double &z);
67 | double x_a1[7];
68 | double y_a1[7];
69 | double x_a2[7];
70 | double y_a2[7];
71 | double x_a3[7];
72 | double y_a3[7];
73 | double x_a4[7];
74 | double y_a4[7];
75 | vector TaylorCordesArms,TaylorCordesArmsInv;
76 | vector psi0V;
77 | vector theta0V;
78 | vector r0V;
79 | vector ArmsVector;
80 | double barRadius;
81 | double barAngle;
82 | double armWidth;
83 | double scaleHeight;
84 | bool QUIETMODE;
85 | double rMax;
86 | double rMinInternalBoundary;
87 | double rMaxInternalBoundary;
88 | double tMinInternalBoundary;
89 | double tMaxInternalBoundary;
90 | int SPIRALARMMODEL;
91 | int SURFACEDENSITYMODEL;
92 | int CENTRALSTRUCTUREMODEL;
93 | int MSBUBBLEMODEL;
94 | gsl_spline *TaylorCordesArm1,*TaylorCordesArm2,*TaylorCordesArm3,
95 | *TaylorCordesArm4,*TaylorCordesArm1Inv,*TaylorCordesArm2Inv,
96 | *TaylorCordesArm3Inv,*TaylorCordesArm4Inv,
97 | *thinshellvelocitylookup,*thinshellradiuslookup,
98 | *r_edreverselookup,*v_edreverselookup,*r_edforwardlookup,
99 | *v_edforwardlookup,*r_streverselookup,*v_streverselookup,
100 | *r_stforwardlookup,*v_stforwardlookup;
101 | gsl_interp_accel *accArm1,*accArm2,*accArm3,*accArm4,
102 | *accArm1Inv,*accArm2Inv,*accArm3Inv,*accArm4Inv,
103 | *atsrad,*atsvel,*aredr,*avedr,*aredf,*avedf,*arstr,
104 | *avstr,*arstf,*avstf;
105 |
106 |
107 | vector< vector > forwardshockradiusprofile;
108 | vector< vector > forwardshockvelocityprofile;
109 | vector< vector > reverseshockradiusprofile;
110 | vector< vector > reverseshockvelocityprofile;
111 | vector< vector > cdradiusprofile;
112 | vector< vector > cdvelocityprofile;
113 |
114 |
115 | vector< vector > thinshellradius;
116 | vector< vector > thinshellvelocity;
117 | double thinshellsolutiontmin;
118 | double thinshellsolutiontmax;
119 |
120 | double truelovemckeetminfed;
121 | double truelovemckeetminfst;
122 | double truelovemckeetmaxfed;
123 | double truelovemckeetmaxfst;
124 |
125 | double truelovemckeetminred;
126 | double truelovemckeetminrst;
127 | double truelovemckeetmaxred;
128 | double truelovemckeetmaxrst;
129 |
130 | vector truelovemckeeparams;
131 | vector< vector > r_edforward;
132 | vector< vector > v_edforward;
133 | vector< vector > r_edreverse;
134 | vector< vector > v_edreverse;
135 | vector< vector > r_stforward;
136 | vector< vector > v_stforward;
137 | vector< vector > r_streverse;
138 | vector< vector > v_streverse;
139 | vector TrueloveMcKeeRadiusAndSpeed(double t, bool REVERSE);
140 | int TrueloveMcKeeEjectaDominatedForwardShock(double x,
141 | double &Y,double &V);
142 | int TrueloveMcKeeEjectaDominatedReverseShock(double x,
143 | double &Y, double &V);
144 | int TrueloveMcKeeSedovTaylorPhaseForwardShock(double t,
145 | double &R, double &V);
146 | int TrueloveMcKeeSedovTaylorPhaseReverseShock(double t,
147 | double &R, double &V);
148 | void CalculateTrueLoveMcKeeParams(vector pars);
149 | vector< double > BFieldDiskComponent(vector xyz);
150 | vector BFieldRegularHaloComponent(vector xyz);
151 | vector BFieldXComponent(vector xyz);
152 | vector BFieldRandomComponent(vector xyz);
153 | double BFieldRandomRmsStrength(vector xyz);
154 | vector BFieldStriatedComponent(vector RegularDisk,
155 | vector RegularHalo,
156 | vector RegularX);
157 | vector< double > RotateBFieldComponent(vector component,
158 | vector xyz);
159 | int BFieldGetSpiralArm(vector xyz);
160 | public:
161 | Astro();
162 | ~Astro();
163 | void SetGalacticReferencePoint(vector xyz_ref);
164 | void DisableArm(int arm);///< Switch off an individual arm in Galaxy spiral model
165 | void EnableArm(int arm);///< Switch on an individual arm in Galaxy spiral model
166 | double RandomSalpeterInitialMass();///< Dice an initial star mass following the Salpeter law
167 | double MainSequenceBubbleRadius(double mDotMS, double vMSWind, double timeMS, double n, double initialMass);///< calculate the radius created by the main sequence wind of a star
168 | double CalculateMSBubbleDensity(double mDotMS, double vMSWind, double timeMS, double n, double bubbleRadius);///< Density inside the main-sequence wind blown bubble.
169 | double CalculateTimeOnMainSequence(double initialMass);///< Time on the main sequence in years as a function of initial star mass
170 | double CalculateMSMassLuminosity(double initialMass);///< Main sequence wind mass luminosity as a function of initial star mass
171 | double CalculateMSWindSpeed(double initialMass);///< Main sequence wind speed as a function of initial star mass
172 | double CalculateRGWRadius(double pBubble, double mDotRGW, double vRGWind);///< Radius of the red giant wind zone
173 | /* void CalculateBField(double x, double y, double z, double &B_tot, double &B_coh, double &B_ord, double &B_iso, vector ®FieldDirection, vector &isoFieldDirection);///< 2D-Model of the large-scale galactic magnetic field structure*/
174 | double HTotalDensity(double x, double y, double z);
175 | /* double TotalBField(double x, double y, double z);*/
176 | double HIDensity(double x, double y, double z, bool MODULATE = true);///< TODO:COMMENT
177 | double H2Density(double x, double y, double z, bool MODULATE = true);///< TODO:COMMENT
178 | double HIIDensity(double x, double y, double z, bool MODULATE = true);///< TODO:COMMENT
179 | double H_I_2_CMZ(double x, double y, double z, double H_c, double norm);
180 | double H_I_2_InnerDisk(double x, double y, double z, double H_d, double norm);
181 | double H2CMZ(double x, double y, double z);
182 | double HICMZ(double x, double y, double z);
183 | double H2InnerDisk(double x, double y, double z);
184 | double HIIThickDisk(double x, double y, double z);
185 | double HIIThinDisk(double x, double y, double z);
186 | double HIInnerDisk(double x, double y, double z);
187 | double WarmHIIDensity(double x, double y, double z);
188 | double HotHIIDensity(double x, double y, double z);
189 | double VeryHotHIIDensity(double x, double y, double z);
190 | double GravitationalPotential(double r, double z);
191 | double CalculateHINorm(double R);///< TODO:COMMENT
192 | double CalculateH2Norm(double R);///< TODO:COMMENT
193 | double GetHIColumnDensity(double R);///< TODO:COMMENT
194 | double GetH2ColumnDensity(double R);///< TODO:COMMENT
195 | double GetHIFWHM(double R);///< TODO:COMMENT
196 | double GetH2FWHM(double R);///< TODO:COMMENT
197 | double ModulateGasDensityWithSpirals(double n, double x, double y, double z);
198 | //double CalculateGasColumnDensity(vector xyzReference,vector GLGB,string gascomponent,double modulate,double range,double steps);///< calculate gas column densities
199 | /* double nRadial(double *x, double *pars);///< TODO:COMMENT*/
200 | vector GetCartesian(vector lbr, vector xyzobs);///< Galactic coordinates (GL,GB,R) ->Cartesian
201 | vector GetCartesian(double r, double l, double b, vector xyzobs);
202 | vector< vector > GetCartesianPositions(vector< vector > lbr, vector xyzobs);
203 | vector GetGalactic(vector xyz, vector xyzref);///< Cartesian coordinates -> Galactic Coordinates(GL,GB,R)
204 | void GetGalactic(double x, double y, double z, double xref, double yref, double zref, double &l, double &b);
205 | vector< vector > GetGalacticPositions(vector< vector > xyz, vector xyzref);
206 | void RotateCoordinates(double &x, double &y, double &z, double phi, double theta, double psi);///< rotate coordinate around (0,0,0) by (phi,theta,psi)
207 | void RandomTangentialShift(double r, double width, double &x, double &y);///< gaussian shift along concentric circle (retains r-distribution)
208 | void RandomGaussianShift(double r, double width, double &x, double &y);
209 | double ApparentSize(double size, vector lbr);
210 | vector GetApparentSizes(vector sizes, vector< vector > lbr);
211 | unsigned int GetRandomArm(double r);///< return a random spiral arm (identifier, i.e. an unsigned integer)
212 | void Bar(double r, double &x, double &y);///< Get xy Coordinates on a central bar inclined with an angle 'angle' clockwise
213 | void Disk(double r, double &x, double &y);///< Get random xy Coordinates on a disk
214 | double LinearSurfDens(double *x, double *par);///< radial distribution that gives a flat appearance of the galaxy
215 | void TaylorCordesSpiral(double r, int arm, double &x, double &y);/// GetRandomGalactocentricRadii(int n);/// > DiceGalacticPositions(int i);
226 | double GetRMax() {return rMax;}
227 | void SetSpiralArmModel(string centralstructuremodel);
228 | void SetCentralStructureModel(string centralstructuremodel);
229 | void SetSurfaceDensityModel(string surfacedensitymodel);
230 | void SetMainSequenceBubbleModel(string msbubblemodel);
231 | void SetScaleHeight(double SCALEHEIGHT) {scaleHeight=SCALEHEIGHT;}
232 | void SetArmWidth(double ARMWIDTH) {armWidth=ARMWIDTH;}
233 | vector< vector > CreateDensityProfile(vector pars,
234 | double rmin = 1.e-3,
235 | double rmax = 1.e3);
236 | double EvalTaylorCordesArmTheta(double r, int arm);
237 | double EvalTaylorCordesArmGalactocentricRadius(double theta, int arm);
238 | double CaseBhattacharyaProfile(double r);
239 | double IusifovKucukProfile(double r);
240 | void CalculateThinShellApproximation(vector< vector > dProfile,
241 | double E,
242 | double AdiabIndex = 1.333,
243 | double tmin = 1.e-2,
244 | double tmax = 1.e4,
245 | int steps = 200);
246 | void CalculateTrueloveMcKeeSolution(vector pars,
247 | double tmin = 1.e-2,
248 | double tmax = 1.e4,
249 | int steps = 200);
250 | void CalculateTangChevalierSolution(vector pars, double tmin=1.e-2,
251 | double tmax=1.e4, int steps=200);
252 | vector ThinShellRadiusAndSpeed(double t);
253 | vector TrueloveMcKeeRadiusAndSpeedForward(double t) {
254 | return TrueloveMcKeeRadiusAndSpeed(t,false);}
255 | vector TrueloveMcKeeRadiusAndSpeedReverse(double t) {
256 | return TrueloveMcKeeRadiusAndSpeed(t,true);}
257 | vector< vector > GetForwardShockRadiusEvolution() {
258 | return forwardshockradiusprofile;}
259 | vector< vector > GetForwardShockVelocityEvolution() {
260 | return forwardshockvelocityprofile;}
261 | vector< vector > GetReverseShockRadiusEvolution() {
262 | return reverseshockradiusprofile;}
263 | vector< vector > GetReverseShockVelocityEvolution() {
264 | return reverseshockvelocityprofile;}
265 | vector< vector > GetContactDiscontinuityRadiusEvolution() {
266 | return cdradiusprofile;}
267 | vector< vector > GetContactDiscontinuityVelocityEvolution() {
268 | return cdvelocityprofile;}
269 | void CalculateForwardShockInRGWind(vector pars,
270 | double tmin = 1.e-2,
271 | double tmax = 1.e4,
272 | int steps = 200);
273 | vector ForwardShockInRGWind(double t, vector pars,
274 | vector< vector > profile);
275 |
276 | void SetInterpolationMethod(string intermeth)
277 | {fUtils->SetInterpolationMethod(intermeth);}
278 | void ToggleQuietMode() { QUIETMODE = QUIETMODE == true ? false : true; }
279 | bool GetQuietMode() {return QUIETMODE;}
280 | vector CalculateBField(vector xyz, int component = -1);
281 | vector< vector > CalculateBFieldPositions(vector< vector > pos, int component=-1);
282 | vector< vector > CalculateBFieldComponents(vector xyz, int component = -1);
283 | vector CalculateBFieldStrengthComposition(vector xyz);
284 | double CalculateBFieldStrength(vector xyz);
285 | vector< vector > LineOfSight(double gl, double gb, vector obs, double r_max=50, int steps=200);
286 | vector< vector > LineOfSight(double gl, double gb, vector obs, vector rvals);
287 |
288 | };
289 | #endif
290 |
--------------------------------------------------------------------------------
/licenses/lgpl-2.1.txt:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 2.1, February 1999
3 |
4 | Copyright (C) 1991, 1999 Free Software Foundation, Inc.
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | [This is the first released version of the Lesser GPL. It also counts
10 | as the successor of the GNU Library Public License, version 2, hence
11 | the version number 2.1.]
12 |
13 | Preamble
14 |
15 | The licenses for most software are designed to take away your
16 | freedom to share and change it. By contrast, the GNU General Public
17 | Licenses are intended to guarantee your freedom to share and change
18 | free software--to make sure the software is free for all its users.
19 |
20 | This license, the Lesser General Public License, applies to some
21 | specially designated software packages--typically libraries--of the
22 | Free Software Foundation and other authors who decide to use it. You
23 | can use it too, but we suggest you first think carefully about whether
24 | this license or the ordinary General Public License is the better
25 | strategy to use in any particular case, based on the explanations below.
26 |
27 | When we speak of free software, we are referring to freedom of use,
28 | not price. Our General Public Licenses are designed to make sure that
29 | you have the freedom to distribute copies of free software (and charge
30 | for this service if you wish); that you receive source code or can get
31 | it if you want it; that you can change the software and use pieces of
32 | it in new free programs; and that you are informed that you can do
33 | these things.
34 |
35 | To protect your rights, we need to make restrictions that forbid
36 | distributors to deny you these rights or to ask you to surrender these
37 | rights. These restrictions translate to certain responsibilities for
38 | you if you distribute copies of the library or if you modify it.
39 |
40 | For example, if you distribute copies of the library, whether gratis
41 | or for a fee, you must give the recipients all the rights that we gave
42 | you. You must make sure that they, too, receive or can get the source
43 | code. If you link other code with the library, you must provide
44 | complete object files to the recipients, so that they can relink them
45 | with the library after making changes to the library and recompiling
46 | it. And you must show them these terms so they know their rights.
47 |
48 | We protect your rights with a two-step method: (1) we copyright the
49 | library, and (2) we offer you this license, which gives you legal
50 | permission to copy, distribute and/or modify the library.
51 |
52 | To protect each distributor, we want to make it very clear that
53 | there is no warranty for the free library. Also, if the library is
54 | modified by someone else and passed on, the recipients should know
55 | that what they have is not the original version, so that the original
56 | author's reputation will not be affected by problems that might be
57 | introduced by others.
58 |
59 | Finally, software patents pose a constant threat to the existence of
60 | any free program. We wish to make sure that a company cannot
61 | effectively restrict the users of a free program by obtaining a
62 | restrictive license from a patent holder. Therefore, we insist that
63 | any patent license obtained for a version of the library must be
64 | consistent with the full freedom of use specified in this license.
65 |
66 | Most GNU software, including some libraries, is covered by the
67 | ordinary GNU General Public License. This license, the GNU Lesser
68 | General Public License, applies to certain designated libraries, and
69 | is quite different from the ordinary General Public License. We use
70 | this license for certain libraries in order to permit linking those
71 | libraries into non-free programs.
72 |
73 | When a program is linked with a library, whether statically or using
74 | a shared library, the combination of the two is legally speaking a
75 | combined work, a derivative of the original library. The ordinary
76 | General Public License therefore permits such linking only if the
77 | entire combination fits its criteria of freedom. The Lesser General
78 | Public License permits more lax criteria for linking other code with
79 | the library.
80 |
81 | We call this license the "Lesser" General Public License because it
82 | does Less to protect the user's freedom than the ordinary General
83 | Public License. It also provides other free software developers Less
84 | of an advantage over competing non-free programs. These disadvantages
85 | are the reason we use the ordinary General Public License for many
86 | libraries. However, the Lesser license provides advantages in certain
87 | special circumstances.
88 |
89 | For example, on rare occasions, there may be a special need to
90 | encourage the widest possible use of a certain library, so that it becomes
91 | a de-facto standard. To achieve this, non-free programs must be
92 | allowed to use the library. A more frequent case is that a free
93 | library does the same job as widely used non-free libraries. In this
94 | case, there is little to gain by limiting the free library to free
95 | software only, so we use the Lesser General Public License.
96 |
97 | In other cases, permission to use a particular library in non-free
98 | programs enables a greater number of people to use a large body of
99 | free software. For example, permission to use the GNU C Library in
100 | non-free programs enables many more people to use the whole GNU
101 | operating system, as well as its variant, the GNU/Linux operating
102 | system.
103 |
104 | Although the Lesser General Public License is Less protective of the
105 | users' freedom, it does ensure that the user of a program that is
106 | linked with the Library has the freedom and the wherewithal to run
107 | that program using a modified version of the Library.
108 |
109 | The precise terms and conditions for copying, distribution and
110 | modification follow. Pay close attention to the difference between a
111 | "work based on the library" and a "work that uses the library". The
112 | former contains code derived from the library, whereas the latter must
113 | be combined with the library in order to run.
114 |
115 | GNU LESSER GENERAL PUBLIC LICENSE
116 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
117 |
118 | 0. This License Agreement applies to any software library or other
119 | program which contains a notice placed by the copyright holder or
120 | other authorized party saying it may be distributed under the terms of
121 | this Lesser General Public License (also called "this License").
122 | Each licensee is addressed as "you".
123 |
124 | A "library" means a collection of software functions and/or data
125 | prepared so as to be conveniently linked with application programs
126 | (which use some of those functions and data) to form executables.
127 |
128 | The "Library", below, refers to any such software library or work
129 | which has been distributed under these terms. A "work based on the
130 | Library" means either the Library or any derivative work under
131 | copyright law: that is to say, a work containing the Library or a
132 | portion of it, either verbatim or with modifications and/or translated
133 | straightforwardly into another language. (Hereinafter, translation is
134 | included without limitation in the term "modification".)
135 |
136 | "Source code" for a work means the preferred form of the work for
137 | making modifications to it. For a library, complete source code means
138 | all the source code for all modules it contains, plus any associated
139 | interface definition files, plus the scripts used to control compilation
140 | and installation of the library.
141 |
142 | Activities other than copying, distribution and modification are not
143 | covered by this License; they are outside its scope. The act of
144 | running a program using the Library is not restricted, and output from
145 | such a program is covered only if its contents constitute a work based
146 | on the Library (independent of the use of the Library in a tool for
147 | writing it). Whether that is true depends on what the Library does
148 | and what the program that uses the Library does.
149 |
150 | 1. You may copy and distribute verbatim copies of the Library's
151 | complete source code as you receive it, in any medium, provided that
152 | you conspicuously and appropriately publish on each copy an
153 | appropriate copyright notice and disclaimer of warranty; keep intact
154 | all the notices that refer to this License and to the absence of any
155 | warranty; and distribute a copy of this License along with the
156 | Library.
157 |
158 | You may charge a fee for the physical act of transferring a copy,
159 | and you may at your option offer warranty protection in exchange for a
160 | fee.
161 |
162 | 2. You may modify your copy or copies of the Library or any portion
163 | of it, thus forming a work based on the Library, and copy and
164 | distribute such modifications or work under the terms of Section 1
165 | above, provided that you also meet all of these conditions:
166 |
167 | a) The modified work must itself be a software library.
168 |
169 | b) You must cause the files modified to carry prominent notices
170 | stating that you changed the files and the date of any change.
171 |
172 | c) You must cause the whole of the work to be licensed at no
173 | charge to all third parties under the terms of this License.
174 |
175 | d) If a facility in the modified Library refers to a function or a
176 | table of data to be supplied by an application program that uses
177 | the facility, other than as an argument passed when the facility
178 | is invoked, then you must make a good faith effort to ensure that,
179 | in the event an application does not supply such function or
180 | table, the facility still operates, and performs whatever part of
181 | its purpose remains meaningful.
182 |
183 | (For example, a function in a library to compute square roots has
184 | a purpose that is entirely well-defined independent of the
185 | application. Therefore, Subsection 2d requires that any
186 | application-supplied function or table used by this function must
187 | be optional: if the application does not supply it, the square
188 | root function must still compute square roots.)
189 |
190 | These requirements apply to the modified work as a whole. If
191 | identifiable sections of that work are not derived from the Library,
192 | and can be reasonably considered independent and separate works in
193 | themselves, then this License, and its terms, do not apply to those
194 | sections when you distribute them as separate works. But when you
195 | distribute the same sections as part of a whole which is a work based
196 | on the Library, the distribution of the whole must be on the terms of
197 | this License, whose permissions for other licensees extend to the
198 | entire whole, and thus to each and every part regardless of who wrote
199 | it.
200 |
201 | Thus, it is not the intent of this section to claim rights or contest
202 | your rights to work written entirely by you; rather, the intent is to
203 | exercise the right to control the distribution of derivative or
204 | collective works based on the Library.
205 |
206 | In addition, mere aggregation of another work not based on the Library
207 | with the Library (or with a work based on the Library) on a volume of
208 | a storage or distribution medium does not bring the other work under
209 | the scope of this License.
210 |
211 | 3. You may opt to apply the terms of the ordinary GNU General Public
212 | License instead of this License to a given copy of the Library. To do
213 | this, you must alter all the notices that refer to this License, so
214 | that they refer to the ordinary GNU General Public License, version 2,
215 | instead of to this License. (If a newer version than version 2 of the
216 | ordinary GNU General Public License has appeared, then you can specify
217 | that version instead if you wish.) Do not make any other change in
218 | these notices.
219 |
220 | Once this change is made in a given copy, it is irreversible for
221 | that copy, so the ordinary GNU General Public License applies to all
222 | subsequent copies and derivative works made from that copy.
223 |
224 | This option is useful when you wish to copy part of the code of
225 | the Library into a program that is not a library.
226 |
227 | 4. You may copy and distribute the Library (or a portion or
228 | derivative of it, under Section 2) in object code or executable form
229 | under the terms of Sections 1 and 2 above provided that you accompany
230 | it with the complete corresponding machine-readable source code, which
231 | must be distributed under the terms of Sections 1 and 2 above on a
232 | medium customarily used for software interchange.
233 |
234 | If distribution of object code is made by offering access to copy
235 | from a designated place, then offering equivalent access to copy the
236 | source code from the same place satisfies the requirement to
237 | distribute the source code, even though third parties are not
238 | compelled to copy the source along with the object code.
239 |
240 | 5. A program that contains no derivative of any portion of the
241 | Library, but is designed to work with the Library by being compiled or
242 | linked with it, is called a "work that uses the Library". Such a
243 | work, in isolation, is not a derivative work of the Library, and
244 | therefore falls outside the scope of this License.
245 |
246 | However, linking a "work that uses the Library" with the Library
247 | creates an executable that is a derivative of the Library (because it
248 | contains portions of the Library), rather than a "work that uses the
249 | library". The executable is therefore covered by this License.
250 | Section 6 states terms for distribution of such executables.
251 |
252 | When a "work that uses the Library" uses material from a header file
253 | that is part of the Library, the object code for the work may be a
254 | derivative work of the Library even though the source code is not.
255 | Whether this is true is especially significant if the work can be
256 | linked without the Library, or if the work is itself a library. The
257 | threshold for this to be true is not precisely defined by law.
258 |
259 | If such an object file uses only numerical parameters, data
260 | structure layouts and accessors, and small macros and small inline
261 | functions (ten lines or less in length), then the use of the object
262 | file is unrestricted, regardless of whether it is legally a derivative
263 | work. (Executables containing this object code plus portions of the
264 | Library will still fall under Section 6.)
265 |
266 | Otherwise, if the work is a derivative of the Library, you may
267 | distribute the object code for the work under the terms of Section 6.
268 | Any executables containing that work also fall under Section 6,
269 | whether or not they are linked directly with the Library itself.
270 |
271 | 6. As an exception to the Sections above, you may also combine or
272 | link a "work that uses the Library" with the Library to produce a
273 | work containing portions of the Library, and distribute that work
274 | under terms of your choice, provided that the terms permit
275 | modification of the work for the customer's own use and reverse
276 | engineering for debugging such modifications.
277 |
278 | You must give prominent notice with each copy of the work that the
279 | Library is used in it and that the Library and its use are covered by
280 | this License. You must supply a copy of this License. If the work
281 | during execution displays copyright notices, you must include the
282 | copyright notice for the Library among them, as well as a reference
283 | directing the user to the copy of this License. Also, you must do one
284 | of these things:
285 |
286 | a) Accompany the work with the complete corresponding
287 | machine-readable source code for the Library including whatever
288 | changes were used in the work (which must be distributed under
289 | Sections 1 and 2 above); and, if the work is an executable linked
290 | with the Library, with the complete machine-readable "work that
291 | uses the Library", as object code and/or source code, so that the
292 | user can modify the Library and then relink to produce a modified
293 | executable containing the modified Library. (It is understood
294 | that the user who changes the contents of definitions files in the
295 | Library will not necessarily be able to recompile the application
296 | to use the modified definitions.)
297 |
298 | b) Use a suitable shared library mechanism for linking with the
299 | Library. A suitable mechanism is one that (1) uses at run time a
300 | copy of the library already present on the user's computer system,
301 | rather than copying library functions into the executable, and (2)
302 | will operate properly with a modified version of the library, if
303 | the user installs one, as long as the modified version is
304 | interface-compatible with the version that the work was made with.
305 |
306 | c) Accompany the work with a written offer, valid for at
307 | least three years, to give the same user the materials
308 | specified in Subsection 6a, above, for a charge no more
309 | than the cost of performing this distribution.
310 |
311 | d) If distribution of the work is made by offering access to copy
312 | from a designated place, offer equivalent access to copy the above
313 | specified materials from the same place.
314 |
315 | e) Verify that the user has already received a copy of these
316 | materials or that you have already sent this user a copy.
317 |
318 | For an executable, the required form of the "work that uses the
319 | Library" must include any data and utility programs needed for
320 | reproducing the executable from it. However, as a special exception,
321 | the materials to be distributed need not include anything that is
322 | normally distributed (in either source or binary form) with the major
323 | components (compiler, kernel, and so on) of the operating system on
324 | which the executable runs, unless that component itself accompanies
325 | the executable.
326 |
327 | It may happen that this requirement contradicts the license
328 | restrictions of other proprietary libraries that do not normally
329 | accompany the operating system. Such a contradiction means you cannot
330 | use both them and the Library together in an executable that you
331 | distribute.
332 |
333 | 7. You may place library facilities that are a work based on the
334 | Library side-by-side in a single library together with other library
335 | facilities not covered by this License, and distribute such a combined
336 | library, provided that the separate distribution of the work based on
337 | the Library and of the other library facilities is otherwise
338 | permitted, and provided that you do these two things:
339 |
340 | a) Accompany the combined library with a copy of the same work
341 | based on the Library, uncombined with any other library
342 | facilities. This must be distributed under the terms of the
343 | Sections above.
344 |
345 | b) Give prominent notice with the combined library of the fact
346 | that part of it is a work based on the Library, and explaining
347 | where to find the accompanying uncombined form of the same work.
348 |
349 | 8. You may not copy, modify, sublicense, link with, or distribute
350 | the Library except as expressly provided under this License. Any
351 | attempt otherwise to copy, modify, sublicense, link with, or
352 | distribute the Library is void, and will automatically terminate your
353 | rights under this License. However, parties who have received copies,
354 | or rights, from you under this License will not have their licenses
355 | terminated so long as such parties remain in full compliance.
356 |
357 | 9. You are not required to accept this License, since you have not
358 | signed it. However, nothing else grants you permission to modify or
359 | distribute the Library or its derivative works. These actions are
360 | prohibited by law if you do not accept this License. Therefore, by
361 | modifying or distributing the Library (or any work based on the
362 | Library), you indicate your acceptance of this License to do so, and
363 | all its terms and conditions for copying, distributing or modifying
364 | the Library or works based on it.
365 |
366 | 10. Each time you redistribute the Library (or any work based on the
367 | Library), the recipient automatically receives a license from the
368 | original licensor to copy, distribute, link with or modify the Library
369 | subject to these terms and conditions. You may not impose any further
370 | restrictions on the recipients' exercise of the rights granted herein.
371 | You are not responsible for enforcing compliance by third parties with
372 | this License.
373 |
374 | 11. If, as a consequence of a court judgment or allegation of patent
375 | infringement or for any other reason (not limited to patent issues),
376 | conditions are imposed on you (whether by court order, agreement or
377 | otherwise) that contradict the conditions of this License, they do not
378 | excuse you from the conditions of this License. If you cannot
379 | distribute so as to satisfy simultaneously your obligations under this
380 | License and any other pertinent obligations, then as a consequence you
381 | may not distribute the Library at all. For example, if a patent
382 | license would not permit royalty-free redistribution of the Library by
383 | all those who receive copies directly or indirectly through you, then
384 | the only way you could satisfy both it and this License would be to
385 | refrain entirely from distribution of the Library.
386 |
387 | If any portion of this section is held invalid or unenforceable under any
388 | particular circumstance, the balance of the section is intended to apply,
389 | and the section as a whole is intended to apply in other circumstances.
390 |
391 | It is not the purpose of this section to induce you to infringe any
392 | patents or other property right claims or to contest validity of any
393 | such claims; this section has the sole purpose of protecting the
394 | integrity of the free software distribution system which is
395 | implemented by public license practices. Many people have made
396 | generous contributions to the wide range of software distributed
397 | through that system in reliance on consistent application of that
398 | system; it is up to the author/donor to decide if he or she is willing
399 | to distribute software through any other system and a licensee cannot
400 | impose that choice.
401 |
402 | This section is intended to make thoroughly clear what is believed to
403 | be a consequence of the rest of this License.
404 |
405 | 12. If the distribution and/or use of the Library is restricted in
406 | certain countries either by patents or by copyrighted interfaces, the
407 | original copyright holder who places the Library under this License may add
408 | an explicit geographical distribution limitation excluding those countries,
409 | so that distribution is permitted only in or among countries not thus
410 | excluded. In such case, this License incorporates the limitation as if
411 | written in the body of this License.
412 |
413 | 13. The Free Software Foundation may publish revised and/or new
414 | versions of the Lesser General Public License from time to time.
415 | Such new versions will be similar in spirit to the present version,
416 | but may differ in detail to address new problems or concerns.
417 |
418 | Each version is given a distinguishing version number. If the Library
419 | specifies a version number of this License which applies to it and
420 | "any later version", you have the option of following the terms and
421 | conditions either of that version or of any later version published by
422 | the Free Software Foundation. If the Library does not specify a
423 | license version number, you may choose any version ever published by
424 | the Free Software Foundation.
425 |
426 | 14. If you wish to incorporate parts of the Library into other free
427 | programs whose distribution conditions are incompatible with these,
428 | write to the author to ask for permission. For software which is
429 | copyrighted by the Free Software Foundation, write to the Free
430 | Software Foundation; we sometimes make exceptions for this. Our
431 | decision will be guided by the two goals of preserving the free status
432 | of all derivatives of our free software and of promoting the sharing
433 | and reuse of software generally.
434 |
435 | NO WARRANTY
436 |
437 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
438 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
439 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
440 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
441 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
442 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
443 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
444 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
445 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
446 |
447 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
448 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
449 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
450 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
451 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
452 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
453 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
454 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
455 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
456 | DAMAGES.
457 |
458 | END OF TERMS AND CONDITIONS
459 |
460 | How to Apply These Terms to Your New Libraries
461 |
462 | If you develop a new library, and you want it to be of the greatest
463 | possible use to the public, we recommend making it free software that
464 | everyone can redistribute and change. You can do so by permitting
465 | redistribution under these terms (or, alternatively, under the terms of the
466 | ordinary General Public License).
467 |
468 | To apply these terms, attach the following notices to the library. It is
469 | safest to attach them to the start of each source file to most effectively
470 | convey the exclusion of warranty; and each file should have at least the
471 | "copyright" line and a pointer to where the full notice is found.
472 |
473 |
474 | Copyright (C)
475 |
476 | This library is free software; you can redistribute it and/or
477 | modify it under the terms of the GNU Lesser General Public
478 | License as published by the Free Software Foundation; either
479 | version 2.1 of the License, or (at your option) any later version.
480 |
481 | This library is distributed in the hope that it will be useful,
482 | but WITHOUT ANY WARRANTY; without even the implied warranty of
483 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
484 | Lesser General Public License for more details.
485 |
486 | You should have received a copy of the GNU Lesser General Public
487 | License along with this library; if not, write to the Free Software
488 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
489 |
490 | Also add information on how to contact you by electronic and paper mail.
491 |
492 | You should also get your employer (if you work as a programmer) or your
493 | school, if any, to sign a "copyright disclaimer" for the library, if
494 | necessary. Here is a sample; alter the names:
495 |
496 | Yoyodyne, Inc., hereby disclaims all copyright interest in the
497 | library `Frob' (a library for tweaking knobs) written by James Random Hacker.
498 |
499 | , 1 April 1990
500 | Ty Coon, President of Vice
501 |
502 | That's all there is to it!
503 |
504 |
505 |
--------------------------------------------------------------------------------
/include/2D_interp/interp2d.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of interp2d, a GSL-compatible two-dimensional
3 | * interpolation library.
4 | *
5 | * Copyright 2012 David Zaslavsky
6 | * Portions based on GNU GSL interpolation code,
7 | * copyright 1996, 1997, 1998, 1999, 2000, 2004 Gerard Jungman
8 | *
9 | * This program is free software: you can redistribute it and/or modify
10 | * it under the terms of the GNU General Public License as published by
11 | * the Free Software Foundation, either version 3 of the License, or
12 | * (at your option) any later version.
13 |
14 | * This program is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | * GNU General Public License for more details.
18 |
19 | * You should have received a copy of the GNU General Public License
20 | * along with this program. If not, see .
21 | */
22 | /**
23 | * @file interp2d.h
24 | * @brief Public interface for low-level 2D interpolation functions
25 | *
26 | * This is the public interface to the low-level functions of the
27 | * `%interp2d` library, i.e. the functions that don't store the data arrays.
28 | * If you're using the low-level interface, you only use the functions in
29 | * this file, unless you're creating a new interpolation type.
30 | *
31 | * The typical workflow is
32 | *
33 | * 1. create an interpolation object using interp2d_alloc()
34 | * 2. initialize it using interp2d_init()
35 | * 3. evaluate the interpolating function or its derivatives using
36 | * interp2d_eval() or its counterparts, possibly many times
37 | * 4. free the memory using interp2d_free()
38 | *
39 | * @see interp2d_spline.h
40 | */
41 |
42 | #ifndef __INTERP_2D_H__
43 | #define __INTERP_2D_H__
44 |
45 | #include
46 |
47 | #ifdef __cplusplus
48 | extern "C" {
49 | #endif
50 |
51 | /**
52 | * An algorithm for 2D interpolation.
53 | *
54 | * There will be one instance of this `struct` representing each type
55 | * of interpolation that the library supports: bilinear, bicubic, etc.
56 | * You can use a custom interpolation type by declaring an instance of
57 | * this and populating it with pointers to the functions that implement
58 | * your interpolation, along with the other fields.
59 | *
60 | * @see interp2d_bilinear
61 | * interp2d_bicubic
62 | */
63 | typedef struct {
64 | /** The name of the algorithm. Use interp2d_name() to access this field. */
65 | const char* name;
66 | /** The minimum number of points in each dimension required by the algorithm. Use interp2d_min_size() to access this field. */
67 | unsigned int min_size;
68 | /** The method that allocates memory for an interpolation object of this type. */
69 | void* (*alloc)(size_t xsize, size_t ysize);
70 | /** The method that initializes the interpolation type. */
71 | int (*init)(void*, const double xa[], const double ya[], const double za[], size_t xsize, size_t ysize);
72 | /** The method that evaluates the interpolation at the given point. */
73 | int (*eval)(const void*, const double xa[], const double ya[], const double za[], size_t xsize, size_t ysize, double x, double y, gsl_interp_accel*, gsl_interp_accel*, double* z);
74 | /** The method that evaluates the x derivative of the interpolation at the given point. */
75 | int (*eval_deriv_x) (const void*, const double xa[], const double ya[], const double za[], size_t xsize, size_t ysize, double x, double y, gsl_interp_accel*, gsl_interp_accel*, double* z_p);
76 | /** The method that evaluates the y derivative of the interpolation at the given point. */
77 | int (*eval_deriv_y) (const void*, const double xa[], const double ya[], const double za[], size_t xsize, size_t ysize, double x, double y, gsl_interp_accel*, gsl_interp_accel*, double* z_p);
78 | /** The method that evaluates the second x derivative of the interpolation at the given point. */
79 | int (*eval_deriv_xx) (const void*, const double xa[], const double ya[], const double za[], size_t xsize, size_t ysize, double x, double y, gsl_interp_accel*, gsl_interp_accel*, double* z_pp);
80 | /** The method that evaluates the second y derivative of the interpolation at the given point. */
81 | int (*eval_deriv_xy) (const void*, const double xa[], const double ya[], const double za[], size_t xsize, size_t ysize, double x, double y, gsl_interp_accel*, gsl_interp_accel*, double* z_pp);
82 | /** The method that evaluates the cross derivative of the interpolation at the given point. */
83 | int (*eval_deriv_yy) (const void*, const double xa[], const double ya[], const double za[], size_t xsize, size_t ysize, double x, double y, gsl_interp_accel*, gsl_interp_accel*, double* z_pp);
84 | /** The method that frees the memory. */
85 | void (*free)(void*);
86 | } interp2d_type;
87 |
88 | /**
89 | * Represents a 2D interpolation object. This is the thing you create
90 | * to actually do an interpolation. Instances of this should be obtained
91 | * from interp2d_alloc(). (Even if you are using a custom interpolation
92 | * type.)
93 | */
94 | typedef struct {
95 | /** The type object for the interpolation. */
96 | const interp2d_type* type;
97 | /** The minimum value of x for which data have been provided. */
98 | double xmin;
99 | /** The maximum value of x for which data have been provided. */
100 | double xmax;
101 | /** The minimum value of y for which data have been provided. */
102 | double ymin;
103 | /** The maximum value of y for which data have been provided. */
104 | double ymax;
105 | /** The number of x values provided. */
106 | size_t xsize;
107 | /** The number of y values provided. */
108 | size_t ysize;
109 | /** A state object. This is specific to the interpolation type. */
110 | void* state;
111 | } interp2d;
112 |
113 | /** The interpolation type for bilinear interpolation. */
114 | extern const interp2d_type* interp2d_bilinear;
115 | /** The interpolation type for bicubic interpolation. */
116 | extern const interp2d_type* interp2d_bicubic;
117 | // To be added:
118 | // GSL_VAR const interp2d_type* interp2d_bipoly;
119 |
120 | /**
121 | * Return the minimum number of points in each dimension needed by
122 | * an interpolation type. For example bilinear interpolation needs
123 | * at least a 2 by 2 grid, so `interp2d_type_min_size(interp2d_bilinear)`
124 | * returns 2.
125 | */
126 | size_t interp2d_type_min_size(const interp2d_type* T);
127 | /**
128 | * Return the minimum number of points in each dimension needed by the
129 | * type of the given interpolation object. This just accesses the type
130 | * from `interp` and calls interp2d_type_min_size() on it.
131 | */
132 | size_t interp2d_min_size(const interp2d* interp);
133 | /**
134 | * Return the type name of the given interpolation. This just accesses
135 | * the type object from `interp` and returns its name.
136 | */
137 | const char* interp2d_name(const interp2d* interp);
138 |
139 | /**
140 | * Allocate a new interpolation object. When you want to do an interpolation,
141 | * you start by calling this function. Don't forget to free the memory using
142 | * interp2d_free() when you're done with it.
143 | *
144 | * Implementation note: this just performs some checks and calls the allocator
145 | * method specified in the interp2d_type instance. So you can use it with
146 | * custom interpolation types.
147 | *
148 | * @param[in] T the `const struct` representing the interpolation algorithm
149 | * you want to use. This should be one of the predefined types provided
150 | * in this library, like interp2d_bilinear or interp2d_bicubic, unless you
151 | * have your own interpolation type you want to use.
152 | * @param[in] xsize the size in the x direction of the grid that will
153 | * specify the function being interpolated
154 | * @param[in] ysize the size in the y direction of the grid that will
155 | * specify the function being interpolated
156 | * @return the newly allocated interpolation object
157 | */
158 | interp2d* interp2d_alloc(const interp2d_type* T, size_t xsize, size_t ysize);
159 |
160 | /**
161 | * Initialize an interpolation object with data points that define the
162 | * function being interpolated. This method stores the sizes of the arrays
163 | * and possibly other relevant data in the interp2d object, but it does not
164 | * actually store the arrays `xa`, `ya`, and `za`. So you need to pass the
165 | * same arrays to interp2d_eval() or whatever evaluation function you use.
166 | *
167 | * This completely resets the state of the interpolation object, so it is safe
168 | * to reuse an existing interpolation object to interpolate a new function by
169 | * simply calling interp2d_init() on the interpolation object with the arrays
170 | * defining the new function.
171 | *
172 | * @param[in] interp the interpolation object, previously initialized
173 | * @param[in] xa the x coordinates of the data, of length `xsize`
174 | * @param[in] ya the y coordinates of the data, of length `ysize`
175 | * @param[in] za the z coordinates of the data, of length `xsize*ysize`
176 | * @param[in] xsize the length of the array `xa`
177 | * @param[in] ysize the length of the array `ya`
178 | * @return a status code, either `GSL_SUCCESS` or an error code indicating
179 | * what went wrong
180 | */
181 | int interp2d_init(interp2d* interp, const double xa[], const double ya[], const double za[], size_t xsize, size_t ysize);
182 |
183 | /**
184 | * Free the interpolation object.
185 | *
186 | * @param[in] interp an interpolation object previously allocated with
187 | * interp2d_alloc()
188 | */
189 | void interp2d_free(interp2d* interp);
190 |
191 | /**
192 | * Evaluate the interpolating function at the point `(x,y)`.
193 | *
194 | * @param[in] interp the interpolation object, which should have already
195 | * been initialized using the arrays `xarr`, `yarr`, and `zarr`. This
196 | * object stores the sizes of the arrays (among other values).
197 | * @param[in] xarr the x coordinates of the points defining the function.
198 | * This should be the same x array that was passed to interp2d_init()
199 | * when initializing `interp`.
200 | * @param[in] yarr the y coordinates of the points defining the function
201 | * This should be the same y array that was passed to interp2d_init()
202 | * when initializing `interp`.
203 | * @param[in] zarr the z coordinates of the points defining the function
204 | * This should be the same z array that was passed to interp2d_init()
205 | * when initializing `interp`.
206 | * @param[in] x the x coordinate at which to evaluate the interpolation
207 | * @param[in] y the y coordinate at which to evaluate the interpolation
208 | * @param[in] xa the accelerator object for the x direction (may be NULL)
209 | * @param[in] ya the accelerator object for the y direction (may be NULL)
210 | * @return the value of the interpolating function at `(x,y)`
211 | */
212 | double interp2d_eval(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya);
213 |
214 | /**
215 | * Evaluate the interpolating function at the point `(x,y)`, without checking
216 | * whether `(x,y)` is within the bounds of the interpolation. This function
217 | * can be used for extrapolation - but do so at your own risk! Extrapolation
218 | * quickly loses its predictive value as you move away from the region in which
219 | * function values are known.
220 | *
221 | * @param[in] interp the interpolation object, which should have already
222 | * been initialized using the arrays `xarr`, `yarr`, and `zarr`. This
223 | * object stores the sizes of the arrays (among other values).
224 | * @param[in] xarr the x coordinates of the points defining the function.
225 | * This should be the same x array that was passed to interp2d_init()
226 | * when initializing `interp`.
227 | * @param[in] yarr the y coordinates of the points defining the function
228 | * This should be the same y array that was passed to interp2d_init()
229 | * when initializing `interp`.
230 | * @param[in] zarr the z coordinates of the points defining the function
231 | * This should be the same z array that was passed to interp2d_init()
232 | * when initializing `interp`.
233 | * @param[in] x the x coordinate at which to evaluate the interpolation
234 | * @param[in] y the y coordinate at which to evaluate the interpolation
235 | * @param[in] xa the accelerator object for the x direction (may be NULL)
236 | * @param[in] ya the accelerator object for the y direction (may be NULL)
237 | * @return the value of the interpolating function at `(x,y)`
238 | */
239 | double interp2d_eval_no_boundary_check(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya);
240 |
241 | /**
242 | * Evaluate the interpolating function at the point `(x,y)`.
243 | *
244 | * @param[in] interp the interpolation object, which should have already
245 | * been initialized using the arrays `xarr`, `yarr`, and `zarr`. This
246 | * object stores the sizes of the arrays (among other values).
247 | * @param[in] xarr the x coordinates of the points defining the function.
248 | * This should be the same x array that was passed to interp2d_init()
249 | * when initializing `interp`.
250 | * @param[in] yarr the y coordinates of the points defining the function
251 | * This should be the same y array that was passed to interp2d_init()
252 | * when initializing `interp`.
253 | * @param[in] zarr the z coordinates of the points defining the function
254 | * This should be the same z array that was passed to interp2d_init()
255 | * when initializing `interp`.
256 | * @param[in] x the x coordinate at which to evaluate the interpolation
257 | * @param[in] y the y coordinate at which to evaluate the interpolation
258 | * @param[in] xa the accelerator object for the x direction (may be NULL)
259 | * @param[in] ya the accelerator object for the y direction (may be NULL)
260 | * @param[out] z the value of the interpolating function at `(x,y)`
261 | * @return a status code, either `GSL_SUCCESS` or an error code indicating
262 | * what went wrong
263 | */
264 | int interp2d_eval_e(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z);
265 |
266 | /**
267 | * Evaluate the interpolating function at the point `(x,y)`, without checking
268 | * whether `(x,y)` is within the bounds of the interpolation. This function
269 | * can be used for extrapolation - but do so at your own risk! Extrapolation
270 | * quickly loses its predictive value as you move away from the region in which
271 | * function values are known.
272 | *
273 | * @param[in] interp the interpolation object, which should have already
274 | * been initialized using the arrays `xarr`, `yarr`, and `zarr`. This
275 | * object stores the sizes of the arrays (among other values).
276 | * @param[in] xarr the x coordinates of the points defining the function.
277 | * This should be the same x array that was passed to interp2d_init()
278 | * when initializing `interp`.
279 | * @param[in] yarr the y coordinates of the points defining the function
280 | * This should be the same y array that was passed to interp2d_init()
281 | * when initializing `interp`.
282 | * @param[in] zarr the z coordinates of the points defining the function
283 | * This should be the same z array that was passed to interp2d_init()
284 | * when initializing `interp`.
285 | * @param[in] x the x coordinate at which to evaluate the interpolation
286 | * @param[in] y the y coordinate at which to evaluate the interpolation
287 | * @param[in] xa the accelerator object for the x direction (may be NULL)
288 | * @param[in] ya the accelerator object for the y direction (may be NULL)
289 | * @param[out] z the value of the interpolating function at `(x,y)`
290 | * @return a status code, either `GSL_SUCCESS` or an error code indicating
291 | * what went wrong
292 | */
293 | int interp2d_eval_e_no_boundary_check(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z);
294 |
295 | /**
296 | * Evaluate the x derivative of the interpolating function at `(x,y)`.
297 | *
298 | * @param[in] interp the interpolation object, which should have already
299 | * been initialized using the arrays `xarr`, `yarr`, and `zarr`. This
300 | * object stores the sizes of the arrays (among other values).
301 | * @param[in] xarr the x coordinates of the points defining the function.
302 | * This should be the same x array that was passed to interp2d_init()
303 | * when initializing `interp`.
304 | * @param[in] yarr the y coordinates of the points defining the function
305 | * This should be the same y array that was passed to interp2d_init()
306 | * when initializing `interp`.
307 | * @param[in] zarr the z coordinates of the points defining the function
308 | * This should be the same z array that was passed to interp2d_init()
309 | * when initializing `interp`.
310 | * @param[in] x the x coordinate at which to evaluate the interpolation
311 | * @param[in] y the y coordinate at which to evaluate the interpolation
312 | * @param[in] xa the accelerator object for the x direction (may be NULL)
313 | * @param[in] ya the accelerator object for the y direction (may be NULL)
314 | * @return the x derivative of the interpolating function at `(x,y)`
315 | */
316 | double interp2d_eval_deriv_x(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya);
317 |
318 | /**
319 | * Evaluate the x derivative of the interpolating function at `(x,y)`.
320 | *
321 | * @param[in] interp the interpolation object, which should have already
322 | * been initialized using the arrays `xarr`, `yarr`, and `zarr`. This
323 | * object stores the sizes of the arrays (among other values).
324 | * @param[in] xarr the x coordinates of the points defining the function.
325 | * This should be the same x array that was passed to interp2d_init()
326 | * when initializing `interp`.
327 | * @param[in] yarr the y coordinates of the points defining the function
328 | * This should be the same y array that was passed to interp2d_init()
329 | * when initializing `interp`.
330 | * @param[in] zarr the z coordinates of the points defining the function
331 | * This should be the same z array that was passed to interp2d_init()
332 | * when initializing `interp`.
333 | * @param[in] x the x coordinate at which to evaluate the interpolation
334 | * @param[in] y the y coordinate at which to evaluate the interpolation
335 | * @param[in] xa the accelerator object for the x direction (may be NULL)
336 | * @param[in] ya the accelerator object for the y direction (may be NULL)
337 | * @param[out] z the x derivative of the interpolating function at `(x,y)`
338 | * @return a status code, either `GSL_SUCCESS` or an error code indicating
339 | * what went wrong
340 | */
341 | int interp2d_eval_deriv_x_e(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z);
342 |
343 | /**
344 | * Evaluate the y derivative of the interpolating function at `(x,y)`.
345 | *
346 | * @param[in] interp the interpolation object, which should have already
347 | * been initialized using the arrays `xarr`, `yarr`, and `zarr`. This
348 | * object stores the sizes of the arrays (among other values).
349 | * @param[in] xarr the x coordinates of the points defining the function.
350 | * This should be the same x array that was passed to interp2d_init()
351 | * when initializing `interp`.
352 | * @param[in] yarr the y coordinates of the points defining the function
353 | * This should be the same y array that was passed to interp2d_init()
354 | * when initializing `interp`.
355 | * @param[in] zarr the z coordinates of the points defining the function
356 | * This should be the same z array that was passed to interp2d_init()
357 | * when initializing `interp`.
358 | * @param[in] x the x coordinate at which to evaluate the interpolation
359 | * @param[in] y the y coordinate at which to evaluate the interpolation
360 | * @param[in] xa the accelerator object for the x direction (may be NULL)
361 | * @param[in] ya the accelerator object for the y direction (may be NULL)
362 | * @return the y derivative of the interpolating function at `(x,y)`
363 | */
364 | double interp2d_eval_deriv_y(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya);
365 |
366 | /**
367 | * Evaluate the y derivative of the interpolating function at `(x,y)`.
368 | *
369 | * @param[in] interp the interpolation object, which should have already
370 | * been initialized using the arrays `xarr`, `yarr`, and `zarr`. This
371 | * object stores the sizes of the arrays (among other values).
372 | * @param[in] xarr the x coordinates of the points defining the function.
373 | * This should be the same x array that was passed to interp2d_init()
374 | * when initializing `interp`.
375 | * @param[in] yarr the y coordinates of the points defining the function
376 | * This should be the same y array that was passed to interp2d_init()
377 | * when initializing `interp`.
378 | * @param[in] zarr the z coordinates of the points defining the function
379 | * This should be the same z array that was passed to interp2d_init()
380 | * when initializing `interp`.
381 | * @param[in] x the x coordinate at which to evaluate the interpolation
382 | * @param[in] y the y coordinate at which to evaluate the interpolation
383 | * @param[in] xa the accelerator object for the x direction (may be NULL)
384 | * @param[in] ya the accelerator object for the y direction (may be NULL)
385 | * @param[out] z the y derivative of the interpolating function at `(x,y)`
386 | * @return a status code, either `GSL_SUCCESS` or an error code indicating
387 | * what went wrong
388 | */
389 | int interp2d_eval_deriv_y_e(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z);
390 |
391 | /**
392 | * Evaluate the second x derivative of the interpolating function at `(x,y)`.
393 | *
394 | * @param[in] interp the interpolation object, which should have already
395 | * been initialized using the arrays `xarr`, `yarr`, and `zarr`. This
396 | * object stores the sizes of the arrays (among other values).
397 | * @param[in] xarr the x coordinates of the points defining the function.
398 | * This should be the same x array that was passed to interp2d_init()
399 | * when initializing `interp`.
400 | * @param[in] yarr the y coordinates of the points defining the function
401 | * This should be the same y array that was passed to interp2d_init()
402 | * when initializing `interp`.
403 | * @param[in] zarr the z coordinates of the points defining the function
404 | * This should be the same z array that was passed to interp2d_init()
405 | * when initializing `interp`.
406 | * @param[in] x the x coordinate at which to evaluate the interpolation
407 | * @param[in] y the y coordinate at which to evaluate the interpolation
408 | * @param[in] xa the accelerator object for the x direction (may be NULL)
409 | * @param[in] ya the accelerator object for the y direction (may be NULL)
410 | * @return the second x derivative of the interpolating function at `(x,y)`
411 | */
412 | double interp2d_eval_deriv_xx(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya);
413 |
414 | /**
415 | * Evaluate the second x derivative of the interpolating function at `(x,y)`.
416 | *
417 | * @param[in] interp the interpolation object, which should have already
418 | * been initialized using the arrays `xarr`, `yarr`, and `zarr`. This
419 | * object stores the sizes of the arrays (among other values).
420 | * @param[in] xarr the x coordinates of the points defining the function.
421 | * This should be the same x array that was passed to interp2d_init()
422 | * when initializing `interp`.
423 | * @param[in] yarr the y coordinates of the points defining the function
424 | * This should be the same y array that was passed to interp2d_init()
425 | * when initializing `interp`.
426 | * @param[in] zarr the z coordinates of the points defining the function
427 | * This should be the same z array that was passed to interp2d_init()
428 | * when initializing `interp`.
429 | * @param[in] x the x coordinate at which to evaluate the interpolation
430 | * @param[in] y the y coordinate at which to evaluate the interpolation
431 | * @param[in] xa the accelerator object for the x direction (may be NULL)
432 | * @param[in] ya the accelerator object for the y direction (may be NULL)
433 | * @param[out] z the second x derivative of the interpolating function at `(x,y)`
434 | * @return a status code, either `GSL_SUCCESS` or an error code indicating
435 | * what went wrong
436 | */
437 | int interp2d_eval_deriv_xx_e(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z);
438 |
439 | /**
440 | * Evaluate the second y derivative of the interpolating function at `(x,y)`.
441 | *
442 | * @param[in] interp the interpolation object, which should have already
443 | * been initialized using the arrays `xarr`, `yarr`, and `zarr`. This
444 | * object stores the sizes of the arrays (among other values).
445 | * @param[in] xarr the x coordinates of the points defining the function.
446 | * This should be the same x array that was passed to interp2d_init()
447 | * when initializing `interp`.
448 | * @param[in] yarr the y coordinates of the points defining the function
449 | * This should be the same y array that was passed to interp2d_init()
450 | * when initializing `interp`.
451 | * @param[in] zarr the z coordinates of the points defining the function
452 | * This should be the same z array that was passed to interp2d_init()
453 | * when initializing `interp`.
454 | * @param[in] x the x coordinate at which to evaluate the interpolation
455 | * @param[in] y the y coordinate at which to evaluate the interpolation
456 | * @param[in] xa the accelerator object for the x direction (may be NULL)
457 | * @param[in] ya the accelerator object for the y direction (may be NULL)
458 | * @return the second y derivative of the interpolating function at `(x,y)`
459 | */
460 | double interp2d_eval_deriv_yy(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya);
461 |
462 | /**
463 | * Evaluate the second y derivative of the interpolating function at `(x,y)`.
464 | *
465 | * @param[in] interp the interpolation object, which should have already
466 | * been initialized using the arrays `xarr`, `yarr`, and `zarr`. This
467 | * object stores the sizes of the arrays (among other values).
468 | * @param[in] xarr the x coordinates of the points defining the function.
469 | * This should be the same x array that was passed to interp2d_init()
470 | * when initializing `interp`.
471 | * @param[in] yarr the y coordinates of the points defining the function
472 | * This should be the same y array that was passed to interp2d_init()
473 | * when initializing `interp`.
474 | * @param[in] zarr the z coordinates of the points defining the function
475 | * This should be the same z array that was passed to interp2d_init()
476 | * when initializing `interp`.
477 | * @param[in] x the x coordinate at which to evaluate the interpolation
478 | * @param[in] y the y coordinate at which to evaluate the interpolation
479 | * @param[in] xa the accelerator object for the x direction (may be NULL)
480 | * @param[in] ya the accelerator object for the y direction (may be NULL)
481 | * @param[out] z the second y derivative of the interpolating function at `(x,y)`
482 | * @return a status code, either `GSL_SUCCESS` or an error code indicating
483 | * what went wrong
484 | */
485 | int interp2d_eval_deriv_yy_e(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z);
486 |
487 | /**
488 | * Evaluate the cross derivative of the interpolating function at `(x,y)`.
489 | * This is \f$\partial_{xy}f(x,y)\f$.
490 | *
491 | * @param[in] interp the interpolation object, which should have already
492 | * been initialized using the arrays `xarr`, `yarr`, and `zarr`. This
493 | * object stores the sizes of the arrays (among other values).
494 | * @param[in] xarr the x coordinates of the points defining the function.
495 | * This should be the same x array that was passed to interp2d_init()
496 | * when initializing `interp`.
497 | * @param[in] yarr the y coordinates of the points defining the function
498 | * This should be the same y array that was passed to interp2d_init()
499 | * when initializing `interp`.
500 | * @param[in] zarr the z coordinates of the points defining the function
501 | * This should be the same z array that was passed to interp2d_init()
502 | * when initializing `interp`.
503 | * @param[in] x the x coordinate at which to evaluate the interpolation
504 | * @param[in] y the y coordinate at which to evaluate the interpolation
505 | * @param[in] xa the accelerator object for the x direction (may be NULL)
506 | * @param[in] ya the accelerator object for the y direction (may be NULL)
507 | * @return the cross derivative of the interpolating function at `(x,y)`
508 | */
509 | double interp2d_eval_deriv_xy(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya);
510 |
511 | /**
512 | * Evaluate the cross derivative of the interpolating function at `(x,y)`.
513 | * This is \f$\partial_{xy}f(x,y)\f$.
514 | *
515 | * @param[in] interp the interpolation object, which should have already
516 | * been initialized using the arrays `xarr`, `yarr`, and `zarr`. This
517 | * object stores the sizes of the arrays (among other values).
518 | * @param[in] xarr the x coordinates of the points defining the function.
519 | * This should be the same x array that was passed to interp2d_init()
520 | * when initializing `interp`.
521 | * @param[in] yarr the y coordinates of the points defining the function
522 | * This should be the same y array that was passed to interp2d_init()
523 | * when initializing `interp`.
524 | * @param[in] zarr the z coordinates of the points defining the function
525 | * This should be the same z array that was passed to interp2d_init()
526 | * when initializing `interp`.
527 | * @param[in] x the x coordinate at which to evaluate the interpolation
528 | * @param[in] y the y coordinate at which to evaluate the interpolation
529 | * @param[in] xa the accelerator object for the x direction (may be NULL)
530 | * @param[in] ya the accelerator object for the y direction (may be NULL)
531 | * @param[out] z the cross derivative of the interpolating function at `(x,y)`
532 | * @return a status code, either `GSL_SUCCESS` or an error code indicating
533 | * what went wrong
534 | */
535 | int interp2d_eval_deriv_xy_e(const interp2d* interp, const double xarr[], const double yarr[], const double zarr[], const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z);
536 |
537 | /**
538 | * Compute the index into a 1D array for a given pair of `x,y` indices.
539 | * This implements row-major ordering.
540 | *
541 | * In _theory_, if you are working with column-major arrays, you should
542 | * be able to redefine this macro as
543 | *
544 | * #define INDEX_2D(xi, yi, xsize, ysize) ((xi) * (ysize) + (yi))
545 | *
546 | * and all `%interp2d` functions would then use column-major ordering.
547 | * But this is not guaranteed to work properly. It's probably better to
548 | * just transpose your arrays.
549 | *
550 | * @param[in] xi the index of the desired grid position along the x dimension
551 | * @param[in] yi the index of the desired grid position along the y dimension
552 | * @param[in] xsize the size of the grid in the x dimension
553 | * @param[in] ysize the size of the grid in the y dimension
554 | */
555 | #define INDEX_2D(xi, yi, xsize, ysize) ((yi) * (xsize) + (xi))
556 |
557 | #ifdef __cplusplus
558 | }
559 | #endif
560 |
561 | #endif
562 |
--------------------------------------------------------------------------------
/src/2D_interp/bicubic.C:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of interp2d, a GSL-compatible two-dimensional
3 | * interpolation library.
4 | *
5 | * Copyright 2012 Thomas Beutlich, David Zaslavsky
6 | * Portions based on alglib 3.6 interpolation code,
7 | * copyright Sergey Bochkanov
8 | * Portions based on GNU GSL interpolation code,
9 | * copyright 1996, 1997, 1998, 1999, 2000, 2004 Gerard Jungman
10 | *
11 | * This program is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 |
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 |
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see .
23 | */
24 |
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include "2D_interp/interp2d.h"
31 |
32 | typedef struct
33 | {
34 | double * zx;
35 | double * zy;
36 | double * zxy;
37 | } bicubic_state_t;
38 |
39 | static void* bicubic_alloc(size_t xsize, size_t ysize) {
40 | bicubic_state_t *state = (bicubic_state_t*) malloc(sizeof (bicubic_state_t));
41 | if (state == NULL)
42 | {
43 | GSL_ERROR_NULL("failed to allocate space for state", GSL_ENOMEM);
44 | }
45 |
46 | state->zx = (double *) malloc (xsize * ysize * sizeof (double));
47 | if (state->zx == NULL)
48 | {
49 | free (state);
50 | GSL_ERROR_NULL("failed to allocate space for zx", GSL_ENOMEM);
51 | }
52 |
53 | state->zy = (double *) malloc (xsize * ysize * sizeof (double));
54 | if (state->zy == NULL)
55 | {
56 | free (state->zx);
57 | free (state);
58 | GSL_ERROR_NULL("failed to allocate space for zy", GSL_ENOMEM);
59 | }
60 |
61 | state->zxy = (double *) malloc (xsize * ysize * sizeof (double));
62 | if (state->zxy == NULL)
63 | {
64 | free (state->zx);
65 | free (state->zy);
66 | free (state);
67 | GSL_ERROR_NULL("failed to allocate space for zxy", GSL_ENOMEM);
68 | }
69 |
70 | return state;
71 | }
72 |
73 | static int bicubic_init(void* vstate, const double xa[], const double ya[], const double za[], size_t xsize, size_t ysize) {
74 | bicubic_state_t *state = (bicubic_state_t *) vstate;
75 |
76 | gsl_interp_accel *acc = gsl_interp_accel_alloc();
77 | gsl_spline *spline;
78 | gsl_vector *x;
79 | gsl_vector *y;
80 | size_t i, j;
81 |
82 | x = gsl_vector_alloc(xsize);
83 | y = gsl_vector_alloc(xsize);
84 | spline = gsl_spline_alloc(gsl_interp_cspline, xsize);
85 | for (j = 0; j <= ysize - 1; j++)
86 | {
87 | for (i = 0; i <= xsize - 1; i++)
88 | {
89 | gsl_vector_set(x, i, xa[i]);
90 | gsl_vector_set(y, i, za[INDEX_2D(i, j, xsize, ysize)]);
91 | }
92 | gsl_spline_init(spline, x->data, y->data, xsize);
93 | for (i = 0; i <= xsize - 1; i++)
94 | {
95 | state->zx[INDEX_2D(i, j, xsize, ysize)] = gsl_spline_eval_deriv(spline, xa[i], acc);
96 | }
97 | }
98 | gsl_vector_free(x);
99 | gsl_vector_free(y);
100 | gsl_spline_free(spline);
101 | gsl_interp_accel_reset(acc);
102 |
103 | x = gsl_vector_alloc(ysize);
104 | y = gsl_vector_alloc(ysize);
105 | spline = gsl_spline_alloc(gsl_interp_cspline, ysize);
106 | for (i = 0; i <= xsize - 1; i++)
107 | {
108 | for (j = 0; j <= ysize - 1; j++)
109 | {
110 | gsl_vector_set(x, j, ya[j]);
111 | gsl_vector_set(y, j, za[INDEX_2D(i, j, xsize, ysize)]);
112 | }
113 | gsl_spline_init(spline, x->data, y->data, ysize);
114 | for (j = 0; j <= ysize - 1; j++)
115 | {
116 | state->zy[INDEX_2D(i, j, xsize, ysize)] = gsl_spline_eval_deriv(spline, ya[j], acc);
117 | }
118 | }
119 | gsl_vector_free(x);
120 | gsl_vector_free(y);
121 | gsl_spline_free(spline);
122 | gsl_interp_accel_reset(acc);
123 |
124 | x = gsl_vector_alloc(xsize);
125 | y = gsl_vector_alloc(xsize);
126 | spline = gsl_spline_alloc(gsl_interp_cspline, xsize);
127 | for (j = 0; j <= ysize - 1; j++)
128 | {
129 | for (i = 0; i <= xsize - 1; i++)
130 | {
131 | gsl_vector_set(x, i, xa[i]);
132 | gsl_vector_set(y, i, state->zy[INDEX_2D(i, j, xsize, ysize)]);
133 | }
134 | gsl_spline_init(spline, x->data, y->data, xsize);
135 | for (i = 0; i <= xsize - 1; i++)
136 | {
137 | state->zxy[INDEX_2D(i, j, xsize, ysize)] = gsl_spline_eval_deriv(spline, xa[i], acc);
138 | }
139 | }
140 | gsl_vector_free(x);
141 | gsl_vector_free(y);
142 | gsl_spline_free(spline);
143 | gsl_interp_accel_free(acc);
144 | return GSL_SUCCESS;
145 | }
146 |
147 | static void bicubic_free (void * vstate) {
148 | bicubic_state_t *state = (bicubic_state_t *) vstate;
149 |
150 | free (state->zx);
151 | free (state->zy);
152 | free (state->zxy);
153 | free (state);
154 | }
155 |
156 | static int bicubic_eval(const void* vstate, const double xarr[], const double yarr[], const double zarr[], size_t xsize, size_t ysize, double x, double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z) {
157 | bicubic_state_t *state = (bicubic_state_t *) vstate;
158 |
159 | double xmin, xmax, ymin, ymax;
160 | double zminmin, zminmax, zmaxmin, zmaxmax;
161 | double zxminmin, zxminmax, zxmaxmin, zxmaxmax;
162 | double zyminmin, zyminmax, zymaxmin, zymaxmax;
163 | double zxyminmin, zxyminmax, zxymaxmin, zxymaxmax;
164 | // dx and dy are the size of the grid cell
165 | double dx, dy;
166 | double dt, du;
167 | // t and u are the positions within the grid cell at which we are computing
168 | // the interpolation, in units of grid cell size
169 | double t, u;
170 | double t0, t1, t2, t3, u0, u1, u2, u3;
171 | double v;
172 | size_t xi, yi;
173 | // First compute the indices into the data arrays where we are interpolating
174 | if (xa != NULL) {
175 | xi = gsl_interp_accel_find(xa, xarr, xsize, x);
176 | }
177 | else {
178 | xi = gsl_interp_bsearch(xarr, x, 0, xsize - 1);
179 | }
180 | if (ya != NULL) {
181 | yi = gsl_interp_accel_find(ya, yarr, ysize, y);
182 | }
183 | else {
184 | yi = gsl_interp_bsearch(yarr, y, 0, ysize - 1);
185 | }
186 | // Find the minimum and maximum values on the grid cell in each dimension
187 | xmin = xarr[xi];
188 | xmax = xarr[xi + 1];
189 | ymin = yarr[yi];
190 | ymax = yarr[yi + 1];
191 | zminmin = zarr[INDEX_2D(xi, yi, xsize, ysize)];
192 | zminmax = zarr[INDEX_2D(xi, yi + 1, xsize, ysize)];
193 | zmaxmin = zarr[INDEX_2D(xi + 1, yi, xsize, ysize)];
194 | zmaxmax = zarr[INDEX_2D(xi + 1, yi + 1, xsize, ysize)];
195 | // Get the width and height of the grid cell
196 | dx = xmax - xmin;
197 | dy = ymax - ymin;
198 | t = (x - xmin)/dx;
199 | u = (y - ymin)/dy;
200 | dt = 1./dx; // partial t / partial x
201 | du = 1./dy; // partial u / partial y
202 | zxminmin = state->zx[INDEX_2D(xi, yi, xsize, ysize)]/dt;
203 | zxminmax = state->zx[INDEX_2D(xi, yi + 1, xsize, ysize)]/dt;
204 | zxmaxmin = state->zx[INDEX_2D(xi + 1, yi, xsize, ysize)]/dt;
205 | zxmaxmax = state->zx[INDEX_2D(xi + 1, yi + 1, xsize, ysize)]/dt;
206 | zyminmin = state->zy[INDEX_2D(xi, yi, xsize, ysize)]/du;
207 | zyminmax = state->zy[INDEX_2D(xi, yi + 1, xsize, ysize)]/du;
208 | zymaxmin = state->zy[INDEX_2D(xi + 1, yi, xsize, ysize)]/du;
209 | zymaxmax = state->zy[INDEX_2D(xi + 1, yi + 1, xsize, ysize)]/du;
210 | zxyminmin = state->zxy[INDEX_2D(xi, yi, xsize, ysize)]/(dt*du);
211 | zxyminmax = state->zxy[INDEX_2D(xi, yi + 1, xsize, ysize)]/(dt*du);
212 | zxymaxmin = state->zxy[INDEX_2D(xi + 1, yi, xsize, ysize)]/(dt*du);
213 | zxymaxmax = state->zxy[INDEX_2D(xi + 1, yi + 1, xsize, ysize)]/(dt*du);
214 | t0 = 1;
215 | t1 = t;
216 | t2 = t*t;
217 | t3 = t*t2;
218 | u0 = 1;
219 | u1 = u;
220 | u2 = u*u;
221 | u3 = u*u2;
222 |
223 | *z = 0;
224 | v = zminmin;
225 | *z += v*t0*u0;
226 | v = zyminmin;
227 | *z += v*t0*u1;
228 | v = -3*zminmin + 3*zminmax - 2*zyminmin - zyminmax;
229 | *z += v*t0*u2;
230 | v = 2*zminmin - 2*zminmax + zyminmin + zyminmax;
231 | *z += v*t0*u3;
232 | v = zxminmin;
233 | *z += v*t1*u0;
234 | v = zxyminmin;
235 | *z += v*t1*u1;
236 | v = -3*zxminmin + 3*zxminmax - 2*zxyminmin - zxyminmax;
237 | *z += v*t1*u2;
238 | v = 2*zxminmin - 2*zxminmax + zxyminmin + zxyminmax;
239 | *z += v*t1*u3;
240 | v = -3*zminmin + 3*zmaxmin - 2*zxminmin - zxmaxmin;
241 | *z += v*t2*u0;
242 | v = -3*zyminmin + 3*zymaxmin - 2*zxyminmin - zxymaxmin;
243 | *z += v*t2*u1;
244 | v = 9*zminmin - 9*zmaxmin + 9*zmaxmax - 9*zminmax + 6*zxminmin + 3*zxmaxmin - 3*zxmaxmax - 6*zxminmax + 6*zyminmin - 6*zymaxmin - 3*zymaxmax + 3*zyminmax + 4*zxyminmin + 2*zxymaxmin + zxymaxmax + 2*zxyminmax;
245 | *z += v*t2*u2;
246 | v = -6*zminmin + 6*zmaxmin - 6*zmaxmax + 6*zminmax - 4*zxminmin - 2*zxmaxmin + 2*zxmaxmax + 4*zxminmax - 3*zyminmin + 3*zymaxmin + 3*zymaxmax - 3*zyminmax - 2*zxyminmin - zxymaxmin - zxymaxmax - 2*zxyminmax;
247 | *z += v*t2*u3;
248 | v = 2*zminmin - 2*zmaxmin + zxminmin + zxmaxmin;
249 | *z += v*t3*u0;
250 | v = 2*zyminmin - 2*zymaxmin + zxyminmin + zxymaxmin;
251 | *z += v*t3*u1;
252 | v = -6*zminmin + 6*zmaxmin - 6*zmaxmax + 6*zminmax - 3*zxminmin - 3*zxmaxmin + 3*zxmaxmax + 3*zxminmax - 4*zyminmin + 4*zymaxmin + 2*zymaxmax - 2*zyminmax - 2*zxyminmin - 2*zxymaxmin - zxymaxmax - zxyminmax;
253 | *z += v*t3*u2;
254 | v = 4*zminmin - 4*zmaxmin + 4*zmaxmax - 4*zminmax + 2*zxminmin + 2*zxmaxmin - 2*zxmaxmax - 2*zxminmax + 2*zyminmin - 2*zymaxmin - 2*zymaxmax + 2*zyminmax + zxyminmin + zxymaxmin + zxymaxmax + zxyminmax;
255 | *z += v*t3*u3;
256 | return GSL_SUCCESS;
257 | }
258 |
259 | static int bicubic_deriv_x(const void* vstate, const double xarr[], const double yarr[], const double zarr[], size_t xsize, size_t ysize, double x, double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z_p) {
260 | bicubic_state_t *state = (bicubic_state_t *) vstate;
261 |
262 | double xmin, xmax, ymin, ymax;
263 | double zminmin, zminmax, zmaxmin, zmaxmax;
264 | double zxminmin, zxminmax, zxmaxmin, zxmaxmax;
265 | double zyminmin, zyminmax, zymaxmin, zymaxmax;
266 | double zxyminmin, zxyminmax, zxymaxmin, zxymaxmax;
267 | // dx and dy are the size of the grid cell
268 | double dx, dy;
269 | double dt, du;
270 | // t and u are the positions within the grid cell at which we are computing
271 | // the interpolation, in units of grid cell size
272 | double t, u;
273 | double t0, t1, t2, u0, u1, u2, u3;
274 | double v;
275 | size_t xi, yi;
276 | // First compute the indices into the data arrays where we are interpolating
277 | if (xa != NULL) {
278 | xi = gsl_interp_accel_find(xa, xarr, xsize, x);
279 | }
280 | else {
281 | xi = gsl_interp_bsearch(xarr, x, 0, xsize - 1);
282 | }
283 | if (ya != NULL) {
284 | yi = gsl_interp_accel_find(ya, yarr, ysize, y);
285 | }
286 | else {
287 | yi = gsl_interp_bsearch(yarr, y, 0, ysize - 1);
288 | }
289 | // Find the minimum and maximum values on the grid cell in each dimension
290 | xmin = xarr[xi];
291 | xmax = xarr[xi + 1];
292 | ymin = yarr[yi];
293 | ymax = yarr[yi + 1];
294 | zminmin = zarr[INDEX_2D(xi, yi, xsize, ysize)];
295 | zminmax = zarr[INDEX_2D(xi, yi + 1, xsize, ysize)];
296 | zmaxmin = zarr[INDEX_2D(xi + 1, yi, xsize, ysize)];
297 | zmaxmax = zarr[INDEX_2D(xi + 1, yi + 1, xsize, ysize)];
298 | // Get the width and height of the grid cell
299 | dx = xmax - xmin;
300 | dy = ymax - ymin;
301 | t = (x - xmin)/dx;
302 | u = (y - ymin)/dy;
303 | dt = 1./dx; // partial t / partial x
304 | du = 1./dy; // partial u / partial y
305 | zxminmin = state->zx[INDEX_2D(xi, yi, xsize, ysize)]/dt;
306 | zxminmax = state->zx[INDEX_2D(xi, yi + 1, xsize, ysize)]/dt;
307 | zxmaxmin = state->zx[INDEX_2D(xi + 1, yi, xsize, ysize)]/dt;
308 | zxmaxmax = state->zx[INDEX_2D(xi + 1, yi + 1, xsize, ysize)]/dt;
309 | zyminmin = state->zy[INDEX_2D(xi, yi, xsize, ysize)]/du;
310 | zyminmax = state->zy[INDEX_2D(xi, yi + 1, xsize, ysize)]/du;
311 | zymaxmin = state->zy[INDEX_2D(xi + 1, yi, xsize, ysize)]/du;
312 | zymaxmax = state->zy[INDEX_2D(xi + 1, yi + 1, xsize, ysize)]/du;
313 | zxyminmin = state->zxy[INDEX_2D(xi, yi, xsize, ysize)]/(dt*du);
314 | zxyminmax = state->zxy[INDEX_2D(xi, yi + 1, xsize, ysize)]/(dt*du);
315 | zxymaxmin = state->zxy[INDEX_2D(xi + 1, yi, xsize, ysize)]/(dt*du);
316 | zxymaxmax = state->zxy[INDEX_2D(xi + 1, yi + 1, xsize, ysize)]/(dt*du);
317 | t0 = 1;
318 | t1 = t;
319 | t2 = t*t;
320 | u0 = 1;
321 | u1 = u;
322 | u2 = u*u;
323 | u3 = u*u2;
324 |
325 | *z_p = 0;
326 | v = zxminmin;
327 | *z_p += v*t0*u0;
328 | v = zxyminmin;
329 | *z_p += v*t0*u1;
330 | v = -3*zxminmin + 3*zxminmax - 2*zxyminmin - zxyminmax;
331 | *z_p += v*t0*u2;
332 | v = 2*zxminmin - 2*zxminmax + zxyminmin + zxyminmax;
333 | *z_p += v*t0*u3;
334 | v = -3*zminmin + 3*zmaxmin - 2*zxminmin - zxmaxmin;
335 | *z_p += 2*v*t1*u0;
336 | v = -3*zyminmin + 3*zymaxmin - 2*zxyminmin - zxymaxmin;
337 | *z_p += 2*v*t1*u1;
338 | v = 9*zminmin - 9*zmaxmin + 9*zmaxmax - 9*zminmax + 6*zxminmin + 3*zxmaxmin - 3*zxmaxmax - 6*zxminmax + 6*zyminmin - 6*zymaxmin - 3*zymaxmax + 3*zyminmax + 4*zxyminmin + 2*zxymaxmin + zxymaxmax + 2*zxyminmax;
339 | *z_p += 2*v*t1*u2;
340 | v = -6*zminmin + 6*zmaxmin - 6*zmaxmax + 6*zminmax - 4*zxminmin - 2*zxmaxmin + 2*zxmaxmax + 4*zxminmax - 3*zyminmin + 3*zymaxmin + 3*zymaxmax - 3*zyminmax - 2*zxyminmin - zxymaxmin - zxymaxmax - 2*zxyminmax;
341 | *z_p += 2*v*t1*u3;
342 | v = 2*zminmin - 2*zmaxmin + zxminmin + zxmaxmin;
343 | *z_p += 3*v*t2*u0;
344 | v = 2*zyminmin - 2*zymaxmin + zxyminmin + zxymaxmin;
345 | *z_p += 3*v*t2*u1;
346 | v = -6*zminmin + 6*zmaxmin - 6*zmaxmax + 6*zminmax - 3*zxminmin - 3*zxmaxmin + 3*zxmaxmax + 3*zxminmax - 4*zyminmin + 4*zymaxmin + 2*zymaxmax - 2*zyminmax - 2*zxyminmin - 2*zxymaxmin - zxymaxmax - zxyminmax;
347 | *z_p += 3*v*t2*u2;
348 | v = 4*zminmin - 4*zmaxmin + 4*zmaxmax - 4*zminmax + 2*zxminmin + 2*zxmaxmin - 2*zxmaxmax - 2*zxminmax + 2*zyminmin - 2*zymaxmin - 2*zymaxmax + 2*zyminmax + zxyminmin + zxymaxmin + zxymaxmax + zxyminmax;
349 | *z_p += 3*v*t2*u3;
350 | *z_p *= dt;
351 | return GSL_SUCCESS;
352 | }
353 |
354 | static int bicubic_deriv_y(const void* vstate, const double xarr[], const double yarr[], const double zarr[], size_t xsize, size_t ysize, double x, double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z_p) {
355 | bicubic_state_t *state = (bicubic_state_t *) vstate;
356 |
357 | double xmin, xmax, ymin, ymax;
358 | double zminmin, zminmax, zmaxmin, zmaxmax;
359 | double zxminmin, zxminmax, zxmaxmin, zxmaxmax;
360 | double zyminmin, zyminmax, zymaxmin, zymaxmax;
361 | double zxyminmin, zxyminmax, zxymaxmin, zxymaxmax;
362 | // dx and dy are the size of the grid cell
363 | double dx, dy;
364 | double dt, du;
365 | // t and u are the positions within the grid cell at which we are computing
366 | // the interpolation, in units of grid cell size
367 | double t, u;
368 | double t0, t1, t2, t3, u0, u1, u2;
369 | double v;
370 | size_t xi, yi;
371 | // First compute the indices into the data arrays where we are interpolating
372 | if (xa != NULL) {
373 | xi = gsl_interp_accel_find(xa, xarr, xsize, x);
374 | }
375 | else {
376 | xi = gsl_interp_bsearch(xarr, x, 0, xsize - 1);
377 | }
378 | if (ya != NULL) {
379 | yi = gsl_interp_accel_find(ya, yarr, ysize, y);
380 | }
381 | else {
382 | yi = gsl_interp_bsearch(yarr, y, 0, ysize - 1);
383 | }
384 | // Find the minimum and maximum values on the grid cell in each dimension
385 | xmin = xarr[xi];
386 | xmax = xarr[xi + 1];
387 | ymin = yarr[yi];
388 | ymax = yarr[yi + 1];
389 | zminmin = zarr[INDEX_2D(xi, yi, xsize, ysize)];
390 | zminmax = zarr[INDEX_2D(xi, yi + 1, xsize, ysize)];
391 | zmaxmin = zarr[INDEX_2D(xi + 1, yi, xsize, ysize)];
392 | zmaxmax = zarr[INDEX_2D(xi + 1, yi + 1, xsize, ysize)];
393 | // Get the width and height of the grid cell
394 | dx = xmax - xmin;
395 | dy = ymax - ymin;
396 | t = (x - xmin)/dx;
397 | u = (y - ymin)/dy;
398 | dt = 1./dx; // partial t / partial x
399 | du = 1./dy; // partial u / partial y
400 | zxminmin = state->zx[INDEX_2D(xi, yi, xsize, ysize)]/dt;
401 | zxminmax = state->zx[INDEX_2D(xi, yi + 1, xsize, ysize)]/dt;
402 | zxmaxmin = state->zx[INDEX_2D(xi + 1, yi, xsize, ysize)]/dt;
403 | zxmaxmax = state->zx[INDEX_2D(xi + 1, yi + 1, xsize, ysize)]/dt;
404 | zyminmin = state->zy[INDEX_2D(xi, yi, xsize, ysize)]/du;
405 | zyminmax = state->zy[INDEX_2D(xi, yi + 1, xsize, ysize)]/du;
406 | zymaxmin = state->zy[INDEX_2D(xi + 1, yi, xsize, ysize)]/du;
407 | zymaxmax = state->zy[INDEX_2D(xi + 1, yi + 1, xsize, ysize)]/du;
408 | zxyminmin = state->zxy[INDEX_2D(xi, yi, xsize, ysize)]/(dt*du);
409 | zxyminmax = state->zxy[INDEX_2D(xi, yi + 1, xsize, ysize)]/(dt*du);
410 | zxymaxmin = state->zxy[INDEX_2D(xi + 1, yi, xsize, ysize)]/(dt*du);
411 | zxymaxmax = state->zxy[INDEX_2D(xi + 1, yi + 1, xsize, ysize)]/(dt*du);
412 | t0 = 1;
413 | t1 = t;
414 | t2 = t*t;
415 | t3 = t*t2;
416 | u0 = 1;
417 | u1 = u;
418 | u2 = u*u;
419 |
420 | *z_p = 0;
421 | v = zyminmin;
422 | *z_p += v*t0*u0;
423 | v = -3*zminmin + 3*zminmax - 2*zyminmin - zyminmax;
424 | *z_p += 2*v*t0*u1;
425 | v = 2*zminmin-2*zminmax + zyminmin + zyminmax;
426 | *z_p += 3*v*t0*u2;
427 | v = zxyminmin;
428 | *z_p += v*t1*u0;
429 | v = -3*zxminmin + 3*zxminmax - 2*zxyminmin - zxyminmax;
430 | *z_p += 2*v*t1*u1;
431 | v = 2*zxminmin - 2*zxminmax + zxyminmin + zxyminmax;
432 | *z_p += 3*v*t1*u2;
433 | v = -3*zyminmin + 3*zymaxmin - 2*zxyminmin - zxymaxmin;
434 | *z_p += v*t2*u0;
435 | v = 9*zminmin - 9*zmaxmin + 9*zmaxmax - 9*zminmax + 6*zxminmin + 3*zxmaxmin - 3*zxmaxmax - 6*zxminmax + 6*zyminmin - 6*zymaxmin - 3*zymaxmax + 3*zyminmax + 4*zxyminmin + 2*zxymaxmin + zxymaxmax + 2*zxyminmax;
436 | *z_p += 2*v*t2*u1;
437 | v = -6*zminmin + 6*zmaxmin - 6*zmaxmax + 6*zminmax - 4*zxminmin - 2*zxmaxmin + 2*zxmaxmax + 4*zxminmax - 3*zyminmin + 3*zymaxmin + 3*zymaxmax - 3*zyminmax - 2*zxyminmin - zxymaxmin - zxymaxmax - 2*zxyminmax;
438 | *z_p += 3*v*t2*u2;
439 | v = 2*zyminmin - 2*zymaxmin + zxyminmin + zxymaxmin;
440 | *z_p += v*t3*u0;
441 | v = -6*zminmin + 6*zmaxmin - 6*zmaxmax + 6*zminmax - 3*zxminmin - 3*zxmaxmin + 3*zxmaxmax + 3*zxminmax - 4*zyminmin + 4*zymaxmin + 2*zymaxmax - 2*zyminmax - 2*zxyminmin - 2*zxymaxmin - zxymaxmax - zxyminmax;
442 | *z_p += 2*v*t3*u1;
443 | v = 4*zminmin - 4*zmaxmin + 4*zmaxmax - 4*zminmax + 2*zxminmin + 2*zxmaxmin - 2*zxmaxmax - 2*zxminmax + 2*zyminmin - 2*zymaxmin - 2*zymaxmax + 2*zyminmax + zxyminmin + zxymaxmin + zxymaxmax + zxyminmax;
444 | *z_p += 3*v*t3*u2;
445 | *z_p *= du;
446 | return GSL_SUCCESS;
447 | }
448 |
449 | static int bicubic_deriv_xx(const void* vstate, const double xarr[], const double yarr[], const double zarr[], size_t xsize, size_t ysize, double x, double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z_pp) {
450 | bicubic_state_t *state = (bicubic_state_t *) vstate;
451 |
452 | double xmin, xmax, ymin, ymax;
453 | double zminmin, zminmax, zmaxmin, zmaxmax;
454 | double zxminmin, zxminmax, zxmaxmin, zxmaxmax;
455 | double zyminmin, zyminmax, zymaxmin, zymaxmax;
456 | double zxyminmin, zxyminmax, zxymaxmin, zxymaxmax;
457 | // dx and dy are the size of the grid cell
458 | double dx, dy;
459 | double dt, du;
460 | // t and u are the positions within the grid cell at which we are computing
461 | // the interpolation, in units of grid cell size
462 | double t, u;
463 | double t0, t1, u0, u1, u2, u3;
464 | double v;
465 | size_t xi, yi;
466 | // First compute the indices into the data arrays where we are interpolating
467 | if (xa != NULL) {
468 | xi = gsl_interp_accel_find(xa, xarr, xsize, x);
469 | }
470 | else {
471 | xi = gsl_interp_bsearch(xarr, x, 0, xsize - 1);
472 | }
473 | if (ya != NULL) {
474 | yi = gsl_interp_accel_find(ya, yarr, ysize, y);
475 | }
476 | else {
477 | yi = gsl_interp_bsearch(yarr, y, 0, ysize - 1);
478 | }
479 | // Find the minimum and maximum values on the grid cell in each dimension
480 | xmin = xarr[xi];
481 | xmax = xarr[xi + 1];
482 | ymin = yarr[yi];
483 | ymax = yarr[yi + 1];
484 | zminmin = zarr[INDEX_2D(xi, yi, xsize, ysize)];
485 | zminmax = zarr[INDEX_2D(xi, yi + 1, xsize, ysize)];
486 | zmaxmin = zarr[INDEX_2D(xi + 1, yi, xsize, ysize)];
487 | zmaxmax = zarr[INDEX_2D(xi + 1, yi + 1, xsize, ysize)];
488 | // Get the width and height of the grid cell
489 | dx = xmax - xmin;
490 | dy = ymax - ymin;
491 | t = (x - xmin)/dx;
492 | u = (y - ymin)/dy;
493 | dt = 1./dx; // partial t / partial x
494 | du = 1./dy; // partial u / partial y
495 | zxminmin = state->zx[INDEX_2D(xi, yi, xsize, ysize)]/dt;
496 | zxminmax = state->zx[INDEX_2D(xi, yi + 1, xsize, ysize)]/dt;
497 | zxmaxmin = state->zx[INDEX_2D(xi + 1, yi, xsize, ysize)]/dt;
498 | zxmaxmax = state->zx[INDEX_2D(xi + 1, yi + 1, xsize, ysize)]/dt;
499 | zyminmin = state->zy[INDEX_2D(xi, yi, xsize, ysize)]/du;
500 | zyminmax = state->zy[INDEX_2D(xi, yi + 1, xsize, ysize)]/du;
501 | zymaxmin = state->zy[INDEX_2D(xi + 1, yi, xsize, ysize)]/du;
502 | zymaxmax = state->zy[INDEX_2D(xi + 1, yi + 1, xsize, ysize)]/du;
503 | zxyminmin = state->zxy[INDEX_2D(xi, yi, xsize, ysize)]/(dt*du);
504 | zxyminmax = state->zxy[INDEX_2D(xi, yi + 1, xsize, ysize)]/(dt*du);
505 | zxymaxmin = state->zxy[INDEX_2D(xi + 1, yi, xsize, ysize)]/(dt*du);
506 | zxymaxmax = state->zxy[INDEX_2D(xi + 1, yi + 1, xsize, ysize)]/(dt*du);
507 | t0 = 1;
508 | t1 = t;
509 | u0 = 1;
510 | u1 = u;
511 | u2 = u*u;
512 | u3 = u*u2;
513 |
514 | *z_pp = 0;
515 | v = -3*zminmin + 3*zmaxmin - 2*zxminmin - zxmaxmin;
516 | *z_pp += 2*v*t0*u0;
517 | v = -3*zyminmin + 3*zymaxmin - 2*zxyminmin - zxymaxmin;
518 | *z_pp += 2*v*t0*u1;
519 | v = 9*zminmin - 9*zmaxmin + 9*zmaxmax - 9*zminmax + 6*zxminmin + 3*zxmaxmin - 3*zxmaxmax - 6*zxminmax + 6*zyminmin - 6*zymaxmin - 3*zymaxmax + 3*zyminmax + 4*zxyminmin + 2*zxymaxmin + zxymaxmax + 2*zxyminmax;
520 | *z_pp += 2*v*t0*u2;
521 | v = -6*zminmin + 6*zmaxmin - 6*zmaxmax + 6*zminmax - 4*zxminmin - 2*zxmaxmin + 2*zxmaxmax + 4*zxminmax - 3*zyminmin + 3*zymaxmin + 3*zymaxmax - 3*zyminmax - 2*zxyminmin - zxymaxmin - zxymaxmax - 2*zxyminmax;
522 | *z_pp += 2*v*t0*u3;
523 | v = 2*zminmin - 2*zmaxmin + zxminmin + zxmaxmin;
524 | *z_pp += 6*v*t1*u0;
525 | v = 2*zyminmin - 2*zymaxmin + zxyminmin + zxymaxmin;
526 | *z_pp += 6*v*t1*u1;
527 | v = -6*zminmin + 6*zmaxmin - 6*zmaxmax + 6*zminmax - 3*zxminmin - 3*zxmaxmin + 3*zxmaxmax + 3*zxminmax - 4*zyminmin + 4*zymaxmin + 2*zymaxmax - 2*zyminmax - 2*zxyminmin - 2*zxymaxmin - zxymaxmax - zxyminmax;
528 | *z_pp += 6*v*t1*u2;
529 | v = 4*zminmin - 4*zmaxmin + 4*zmaxmax - 4*zminmax + 2*zxminmin + 2*zxmaxmin - 2*zxmaxmax - 2*zxminmax + 2*zyminmin - 2*zymaxmin - 2*zymaxmax + 2*zyminmax + zxyminmin + zxymaxmin + zxymaxmax + zxyminmax;
530 | *z_pp += 6*v*t1*u3;
531 | *z_pp *= dt*dt;
532 | return GSL_SUCCESS;
533 | }
534 |
535 | static int bicubic_deriv_xy(const void* vstate, const double xarr[], const double yarr[], const double zarr[], size_t xsize, size_t ysize, double x, double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z_pp) {
536 | bicubic_state_t *state = (bicubic_state_t *) vstate;
537 |
538 | double xmin, xmax, ymin, ymax;
539 | double zminmin, zminmax, zmaxmin, zmaxmax;
540 | double zxminmin, zxminmax, zxmaxmin, zxmaxmax;
541 | double zyminmin, zyminmax, zymaxmin, zymaxmax;
542 | double zxyminmin, zxyminmax, zxymaxmin, zxymaxmax;
543 | // dx and dy are the size of the grid cell
544 | double dx, dy;
545 | double dt, du;
546 | // t and u are the positions within the grid cell at which we are computing
547 | // the interpolation, in units of grid cell size
548 | double t, u;
549 | double t0, t1, t2, u0, u1, u2;
550 | double v;
551 | size_t xi, yi;
552 | // First compute the indices into the data arrays where we are interpolating
553 | if (xa != NULL) {
554 | xi = gsl_interp_accel_find(xa, xarr, xsize, x);
555 | }
556 | else {
557 | xi = gsl_interp_bsearch(xarr, x, 0, xsize - 1);
558 | }
559 | if (ya != NULL) {
560 | yi = gsl_interp_accel_find(ya, yarr, ysize, y);
561 | }
562 | else {
563 | yi = gsl_interp_bsearch(yarr, y, 0, ysize - 1);
564 | }
565 | // Find the minimum and maximum values on the grid cell in each dimension
566 | xmin = xarr[xi];
567 | xmax = xarr[xi + 1];
568 | ymin = yarr[yi];
569 | ymax = yarr[yi + 1];
570 | zminmin = zarr[INDEX_2D(xi, yi, xsize, ysize)];
571 | zminmax = zarr[INDEX_2D(xi, yi + 1, xsize, ysize)];
572 | zmaxmin = zarr[INDEX_2D(xi + 1, yi, xsize, ysize)];
573 | zmaxmax = zarr[INDEX_2D(xi + 1, yi + 1, xsize, ysize)];
574 | // Get the width and height of the grid cell
575 | dx = xmax - xmin;
576 | dy = ymax - ymin;
577 | t = (x - xmin)/dx;
578 | u = (y - ymin)/dy;
579 | dt = 1./dx; // partial t / partial x
580 | du = 1./dy; // partial u / partial y
581 | zxminmin = state->zx[INDEX_2D(xi, yi, xsize, ysize)]/dt;
582 | zxminmax = state->zx[INDEX_2D(xi, yi + 1, xsize, ysize)]/dt;
583 | zxmaxmin = state->zx[INDEX_2D(xi + 1, yi, xsize, ysize)]/dt;
584 | zxmaxmax = state->zx[INDEX_2D(xi + 1, yi + 1, xsize, ysize)]/dt;
585 | zyminmin = state->zy[INDEX_2D(xi, yi, xsize, ysize)]/du;
586 | zyminmax = state->zy[INDEX_2D(xi, yi + 1, xsize, ysize)]/du;
587 | zymaxmin = state->zy[INDEX_2D(xi + 1, yi, xsize, ysize)]/du;
588 | zymaxmax = state->zy[INDEX_2D(xi + 1, yi + 1, xsize, ysize)]/du;
589 | zxyminmin = state->zxy[INDEX_2D(xi, yi, xsize, ysize)]/(dt*du);
590 | zxyminmax = state->zxy[INDEX_2D(xi, yi + 1, xsize, ysize)]/(dt*du);
591 | zxymaxmin = state->zxy[INDEX_2D(xi + 1, yi, xsize, ysize)]/(dt*du);
592 | zxymaxmax = state->zxy[INDEX_2D(xi + 1, yi + 1, xsize, ysize)]/(dt*du);
593 | t0 = 1;
594 | t1 = t;
595 | t2 = t*t;
596 | u0 = 1;
597 | u1 = u;
598 | u2 = u*u;
599 |
600 | *z_pp = 0;
601 | v = zxyminmin;
602 | *z_pp += v*t0*u0;
603 | v = -3*zxminmin + 3*zxminmax - 2*zxyminmin - zxyminmax;
604 | *z_pp += 2*v*t0*u1;
605 | v = 2*zxminmin - 2*zxminmax + zxyminmin + zxyminmax;
606 | *z_pp += 3*v*t0*u2;
607 | v = -3*zyminmin + 3*zymaxmin - 2*zxyminmin - zxymaxmin;
608 | *z_pp += 2*v*t1*u0;
609 | v = 9*zminmin - 9*zmaxmin + 9*zmaxmax - 9*zminmax + 6*zxminmin + 3*zxmaxmin - 3*zxmaxmax - 6*zxminmax + 6*zyminmin - 6*zymaxmin - 3*zymaxmax + 3*zyminmax + 4*zxyminmin + 2*zxymaxmin + zxymaxmax + 2*zxyminmax;
610 | *z_pp += 4*v*t1*u1;
611 | v = -6*zminmin + 6*zmaxmin - 6*zmaxmax + 6*zminmax - 4*zxminmin - 2*zxmaxmin + 2*zxmaxmax + 4*zxminmax - 3*zyminmin + 3*zymaxmin + 3*zymaxmax - 3*zyminmax - 2*zxyminmin - zxymaxmin - zxymaxmax - 2*zxyminmax;
612 | *z_pp += 6*v*t1*u2;
613 | v = 2*zyminmin - 2*zymaxmin + zxyminmin + zxymaxmin;
614 | *z_pp += 3*v*t2*u0;
615 | v = -6*zminmin + 6*zmaxmin - 6*zmaxmax + 6*zminmax - 3*zxminmin - 3*zxmaxmin + 3*zxmaxmax + 3*zxminmax - 4*zyminmin + 4*zymaxmin + 2*zymaxmax - 2*zyminmax - 2*zxyminmin - 2*zxymaxmin - zxymaxmax - zxyminmax;
616 | *z_pp += 6*v*t2*u1;
617 | v = 4*zminmin - 4*zmaxmin + 4*zmaxmax - 4*zminmax + 2*zxminmin + 2*zxmaxmin - 2*zxmaxmax - 2*zxminmax + 2*zyminmin - 2*zymaxmin - 2*zymaxmax + 2*zyminmax + zxyminmin + zxymaxmin + zxymaxmax + zxyminmax;
618 | *z_pp += 9*v*t2*u2;
619 | *z_pp *= dt*du;
620 | return GSL_SUCCESS;
621 | }
622 |
623 | static int bicubic_deriv_yy(const void* vstate, const double xarr[], const double yarr[], const double zarr[], size_t xsize, size_t ysize, double x, double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z_pp) {
624 | bicubic_state_t *state = (bicubic_state_t *) vstate;
625 |
626 | double xmin, xmax, ymin, ymax;
627 | double zminmin, zminmax, zmaxmin, zmaxmax;
628 | double zxminmin, zxminmax, zxmaxmin, zxmaxmax;
629 | double zyminmin, zyminmax, zymaxmin, zymaxmax;
630 | double zxyminmin, zxyminmax, zxymaxmin, zxymaxmax;
631 | // dx and dy are the size of the grid cell
632 | double dx, dy;
633 | double dt, du;
634 | // t and u are the positions within the grid cell at which we are computing
635 | // the interpolation, in units of grid cell size
636 | double t, u;
637 | double t0, t1, t2, t3, u0, u1;
638 | double v;
639 | size_t xi, yi;
640 | // First compute the indices into the data arrays where we are interpolating
641 | if (xa != NULL) {
642 | xi = gsl_interp_accel_find(xa, xarr, xsize, x);
643 | }
644 | else {
645 | xi = gsl_interp_bsearch(xarr, x, 0, xsize - 1);
646 | }
647 | if (ya != NULL) {
648 | yi = gsl_interp_accel_find(ya, yarr, ysize, y);
649 | }
650 | else {
651 | yi = gsl_interp_bsearch(yarr, y, 0, ysize - 1);
652 | }
653 | // Find the minimum and maximum values on the grid cell in each dimension
654 | xmin = xarr[xi];
655 | xmax = xarr[xi + 1];
656 | ymin = yarr[yi];
657 | ymax = yarr[yi + 1];
658 | zminmin = zarr[INDEX_2D(xi, yi, xsize, ysize)];
659 | zminmax = zarr[INDEX_2D(xi, yi + 1, xsize, ysize)];
660 | zmaxmin = zarr[INDEX_2D(xi + 1, yi, xsize, ysize)];
661 | zmaxmax = zarr[INDEX_2D(xi + 1, yi + 1, xsize, ysize)];
662 | // Get the width and height of the grid cell
663 | dx = xmax - xmin;
664 | dy = ymax - ymin;
665 | t = (x - xmin)/dx;
666 | u = (y - ymin)/dy;
667 | dt = 1./dx; // partial t / partial x
668 | du = 1./dy; // partial u / partial y
669 | zxminmin = state->zx[INDEX_2D(xi, yi, xsize, ysize)]/dt;
670 | zxminmax = state->zx[INDEX_2D(xi, yi + 1, xsize, ysize)]/dt;
671 | zxmaxmin = state->zx[INDEX_2D(xi + 1, yi, xsize, ysize)]/dt;
672 | zxmaxmax = state->zx[INDEX_2D(xi + 1, yi + 1, xsize, ysize)]/dt;
673 | zyminmin = state->zy[INDEX_2D(xi, yi, xsize, ysize)]/du;
674 | zyminmax = state->zy[INDEX_2D(xi, yi + 1, xsize, ysize)]/du;
675 | zymaxmin = state->zy[INDEX_2D(xi + 1, yi, xsize, ysize)]/du;
676 | zymaxmax = state->zy[INDEX_2D(xi + 1, yi + 1, xsize, ysize)]/du;
677 | zxyminmin = state->zxy[INDEX_2D(xi, yi, xsize, ysize)]/(dt*du);
678 | zxyminmax = state->zxy[INDEX_2D(xi, yi + 1, xsize, ysize)]/(dt*du);
679 | zxymaxmin = state->zxy[INDEX_2D(xi + 1, yi, xsize, ysize)]/(dt*du);
680 | zxymaxmax = state->zxy[INDEX_2D(xi + 1, yi + 1, xsize, ysize)]/(dt*du);
681 | t0 = 1;
682 | t1 = t;
683 | t2 = t*t;
684 | t3 = t*t2;
685 | u0 = 1;
686 | u1 = u;
687 |
688 | *z_pp = 0;
689 | v = -3*zminmin + 3*zminmax - 2*zyminmin - zyminmax;
690 | *z_pp += 2*v*t0*u0;
691 | v = 2*zminmin-2*zminmax + zyminmin + zyminmax;
692 | *z_pp += 6*v*t0*u1;
693 | v = -3*zxminmin + 3*zxminmax - 2*zxyminmin - zxyminmax;
694 | *z_pp += 2*v*t1*u0;
695 | v = 2*zxminmin - 2*zxminmax + zxyminmin + zxyminmax;
696 | *z_pp += 6*v*t1*u1;
697 | v = 9*zminmin - 9*zmaxmin + 9*zmaxmax - 9*zminmax + 6*zxminmin + 3*zxmaxmin - 3*zxmaxmax - 6*zxminmax + 6*zyminmin - 6*zymaxmin - 3*zymaxmax + 3*zyminmax + 4*zxyminmin + 2*zxymaxmin + zxymaxmax + 2*zxyminmax;
698 | *z_pp += 2*v*t2*u0;
699 | v = -6*zminmin + 6*zmaxmin - 6*zmaxmax + 6*zminmax - 4*zxminmin - 2*zxmaxmin + 2*zxmaxmax + 4*zxminmax - 3*zyminmin + 3*zymaxmin + 3*zymaxmax - 3*zyminmax - 2*zxyminmin - zxymaxmin - zxymaxmax - 2*zxyminmax;
700 | *z_pp += 6*v*t2*u1;
701 | v = -6*zminmin + 6*zmaxmin - 6*zmaxmax + 6*zminmax - 3*zxminmin - 3*zxmaxmin + 3*zxmaxmax + 3*zxminmax - 4*zyminmin + 4*zymaxmin + 2*zymaxmax - 2*zyminmax - 2*zxyminmin - 2*zxymaxmin - zxymaxmax - zxyminmax;
702 | *z_pp += 2*v*t3*u0;
703 | v = 4*zminmin - 4*zmaxmin + 4*zmaxmax - 4*zminmax + 2*zxminmin + 2*zxmaxmin - 2*zxmaxmax - 2*zxminmax + 2*zyminmin - 2*zymaxmin - 2*zymaxmax + 2*zyminmax + zxyminmin + zxymaxmin + zxymaxmax + zxyminmax;
704 | *z_pp += 6*v*t3*u1;
705 | *z_pp *= du*du;
706 | return GSL_SUCCESS;
707 | }
708 |
709 | static const interp2d_type bicubic_type = {
710 | "bicubic",
711 | 4,
712 | bicubic_alloc,
713 | bicubic_init,
714 | bicubic_eval,
715 | bicubic_deriv_x,
716 | bicubic_deriv_y,
717 | bicubic_deriv_xx,
718 | bicubic_deriv_xy,
719 | bicubic_deriv_yy,
720 | bicubic_free
721 | };
722 |
723 | const interp2d_type* interp2d_bicubic = &bicubic_type;
724 |
--------------------------------------------------------------------------------
/unit_tests/rad_temp.dat:
--------------------------------------------------------------------------------
1 | 2.326951685393255e-16 7.109162435471483e-07
2 | 2.4252939175834895e-16 7.410162928609844e-07
3 | 2.5277923145505283e-16 7.723931558997815e-07
4 | 2.634622525201939e-16 8.0499628524853e-07
5 | 2.745967621764717e-16 8.389375672891391e-07
6 | 2.862018413511522e-16 8.744914527716493e-07
7 | 2.982973773745703e-16 9.11463747435305e-07
8 | 3.1090409806054374e-16 9.499811080280741e-07
9 | 3.24043607227103e-16 9.900176870411924e-07
10 | 3.377384217184074e-16 1.0318689426812553e-06
11 | 3.520120099912906e-16 1.0755204195819993e-06
12 | 3.6688883233256067e-16 1.1209637267562482e-06
13 | 3.823943827759747e-16 1.1683546487943605e-06
14 | 3.985552327907187e-16 1.2176976939813713e-06
15 | 4.153990768162614e-16 1.2691620933879577e-06
16 | 4.3295477972161404e-16 1.3229242386357333e-06
17 | 4.512524262703256e-16 1.3786943616887773e-06
18 | 4.703233726759805e-16 1.4369798137573022e-06
19 | 4.90200300336547e-16 1.4978224389409934e-06
20 | 5.109172718396627e-16 1.5611146464163893e-06
21 | 5.325097893348275e-16 1.6270733842167683e-06
22 | 5.550148553725386e-16 1.6957669002175802e-06
23 | 5.784710363146243e-16 1.7674308663361086e-06
24 | 6.029185284244418e-16 1.8421530444581047e-06
25 | 6.283992267501959e-16 1.9200315801500528e-06
26 | 6.549567969194224e-16 2.0011754364274995e-06
27 | 6.826367499676682e-16 2.085704854433108e-06
28 | 7.114865203296007e-16 2.173909696648435e-06
29 | 7.415555471261973e-16 2.265776339030005e-06
30 | 7.72895358887315e-16 2.361461795214141e-06
31 | 8.055596618548282e-16 2.461294251532835e-06
32 | 8.396044320176542e-16 2.565300032166346e-06
33 | 8.75088011036389e-16 2.6736777835377265e-06
34 | 9.120712062219335e-16 2.7867990840194456e-06
35 | 9.50617394739443e-16 2.9045776172839823e-06
36 | 9.907926322161686e-16 3.0272591660552876e-06
37 | 1.0326657659393163e-15 3.155264446026319e-06
38 | 1.0763085528378967e-15 3.2885583411402493e-06
39 | 1.1217957824507589e-15 3.427597879561189e-06
40 | 1.1692054050915287e-15 3.572385791619747e-06
41 | 1.2186186654300885e-15 3.723418551399869e-06
42 | 1.27012024171951e-15 3.880740003629406e-06
43 | 1.3237983909070327e-15 4.044731602810799e-06
44 | 1.379745099877759e-15 4.21563972616148e-06
45 | 1.4380562430902514e-15 4.393892375187676e-06
46 | 1.4988317468741627e-15 4.579468707310218e-06
47 | 1.5621757606714595e-15 4.773163027987243e-06
48 | 1.628196835514681e-15 4.9748493281752575e-06
49 | 1.6970081100480963e-15 5.185061110070577e-06
50 | 1.768727504410535e-15 5.404203224197937e-06
51 | 1.8434779223121416e-15 5.632553105649326e-06
52 | 1.9213874616513536e-15 5.870577799711122e-06
53 | 2.002589634033024e-15 6.1187774332223906e-06
54 | 2.0872235935638805e-15 6.3773708762398636e-06
55 | 2.1754343753173938e-15 6.64677080529594e-06
56 | 2.2673731438767092e-15 6.927743089245605e-06
57 | 2.3631974523815682e-15 7.220619033838347e-06
58 | 2.463071512523131e-15 7.525770628352428e-06
59 | 2.567166475949398e-15 7.84377014311091e-06
60 | 2.675660727563451e-15 8.175234050333948e-06
61 | 2.788740191217148e-15 8.52082489033e-06
62 | 2.906598648324119e-15 8.880779610579215e-06
63 | 3.029438069938068e-15 9.256174551378692e-06
64 | 3.157468962865454e-15 9.647348868794733e-06
65 | 3.2909107304056744e-15 1.0055011820691147e-05
66 | 3.429992048336946e-15 1.0480087195431805e-05
67 | 3.5749512567921926e-15 1.0922926364132165e-05
68 | 3.726036768696499e-15 1.1384573726736527e-05
69 | 3.883507495466047e-15 1.1865664230134199e-05
70 | 4.0476332906980576e-15 1.2367215424628133e-05
71 | 4.2186954126120665e-15 1.288984094561178e-05
72 | 4.396987006035011e-15 1.3434542803656197e-05
73 | 4.582813604756102e-15 1.4002398714923278e-05
74 | 4.776493655112335e-15 1.4594091696284768e-05
75 | 4.9783590617019225e-15 1.5210860611493621e-05
76 | 5.1887557561607965e-15 1.5853714303311147e-05
77 | 5.408044289976892e-15 1.6523750953934054e-05
78 | 5.636600452358105e-15 1.7222161860640632e-05
79 | 5.8748159142127415e-15 1.7949919632689306e-05
80 | 6.123098899346037e-15 1.8708571637855186e-05
81 | 6.381874884022956e-15 1.949929706436183e-05
82 | 6.651587326096089e-15 2.0323384981770518e-05
83 | 6.932698424948153e-15 2.1182238986081763e-05
84 | 7.225689913551364e-15 2.207738204016839e-05
85 | 7.53106388400104e-15 2.301046151661715e-05
86 | 7.849343647938101e-15 2.3982938719960388e-05
87 | 8.181074633334995e-15 2.4996567972065853e-05
88 | 8.526825319181785e-15 2.605292871745753e-05
89 | 8.887188209674213e-15 2.7154062952634257e-05
90 | 9.262780849573134e-15 2.8301534215973594e-05
91 | 9.654246882475328e-15 2.9497697007483403e-05
92 | 1.0062257153809252e-14 3.0744282707838824e-05
93 | 1.0487510860445847e-14 3.204366955483304e-05
94 | 1.0930736748894522e-14 3.3397942752150284e-05
95 | 1.139269436413759e-14 3.480937570690097e-05
96 | 1.187417535124328e-14 3.62804379846466e-05
97 | 1.237600481198783e-14 3.7813803598433035e-05
98 | 1.2899042718811527e-14 3.941188604275336e-05
99 | 1.344418538853169e-14 4.107747877508758e-05
100 | 1.4012367018338108e-14 4.2813606733148205e-05
101 | 1.4604561286703117e-14 4.462290464103415e-05
102 | 1.5221783021949734e-14 4.650873229014416e-05
103 | 1.5865089941337258e-14 4.847439581962926e-05
104 | 1.6535584463644564e-14 5.0523000924914365e-05
105 | 1.723441559835725e-14 5.265825374686648e-05
106 | 1.7962780914696085e-14 5.488368355887739e-05
107 | 1.8721928593861073e-14 5.720312891530978e-05
108 | 1.9513159568007966e-14 5.962075072193997e-05
109 | 2.033782974962277e-14 6.214041438338943e-05
110 | 2.1197352355114617e-14 6.476665121644146e-05
111 | 2.209320032660896e-14 6.750388390380394e-05
112 | 2.3026908856091187e-14 7.035659978755266e-05
113 | 2.400007801622627e-14 7.333015629164016e-05
114 | 2.5014375502362765e-14 7.642921898629936e-05
115 | 2.60715394904201e-14 7.96591998743025e-05
116 | 2.7173381615556633e-14 8.302580198537202e-05
117 | 2.8321790076722983e-14 8.653472260984309e-05
118 | 2.951873287242072e-14 9.019183094059295e-05
119 | 3.076626117321158e-14 9.400350442012847e-05
120 | 3.2066512836756557e-14 9.797633448204654e-05
121 | 3.3421716071408375e-14 0.0001021171489389365
122 | 3.483419325463577e-14 0.0001064327195773688
123 | 3.6306364912822966e-14 0.0001109308915619742
124 | 3.78407538692644e-14 0.00011561903009174842
125 | 3.943998956746318e-14 0.0001205054676410446
126 | 4.110681257714178e-14 0.0001255982685418468
127 | 4.284407929068702e-14 0.0001309062048981222
128 | 4.4654766818077377e-14 0.0001364386286282261
129 | 4.654197808868095e-14 0.00014220487116491538
130 | 4.8508947168666956e-14 0.00014821474955631518
131 | 5.055904480314303e-14 0.0001544786003329796
132 | 5.269578419251581e-14 0.0001610073148061363
133 | 5.492282701297345e-14 0.0001678119022506369
134 | 5.724398969140744e-14 0.00017490400185688794
135 | 5.966324994552671e-14 0.0001822957648275404
136 | 6.218475360037177e-14 0.00019000005390106732
137 | 6.481282169291008e-14 0.00019802985528990415
138 | 6.75519578768877e-14 0.00020639895540704628
139 | 7.040685614062674e-14 0.00021512183015877926
140 | 7.338240885099415e-14 0.00022421337836175012
141 | 7.648371513732709e-14 0.0002336891308448168
142 | 7.97160896296817e-14 0.00024356546171597096
143 | 8.308507156638007e-14 0.000253859012540524
144 | 8.659643428646262e-14 0.00026458769756248075
145 | 9.025619512331319e-14 0.0002757698169480134
146 | 9.407062571641074e-14 0.0002874244355369392
147 | 9.804626275887922e-14 0.00029957160638828875
148 | 1.0218991919925299e-13 0.0003122322813631156
149 | 1.0650869591665432e-13 0.0003254279088620357
150 | 1.1100999388939006e-13 0.00033918113966193857
151 | 1.1570152687782075e-13 0.00035351574654957497
152 | 1.2059133464323652e-13 0.00036845607362322646
153 | 1.2568779672539237e-13 0.00038402790983043614
154 | 1.3099964680231334e-13 0.0004002577873725839
155 | 1.3653598765697726e-13 0.00041717354677100457
156 | 1.4230630677652365e-13 0.0004348042743218453
157 | 1.4832049261072004e-13 0.0004531800857104155
158 | 1.5458885151754807e-13 0.0004723325453009039
159 | 1.6112212542494813e-13 0.0004922943004567478
160 | 1.6793151023898925e-13 0.0005130998255062569
161 | 1.7502867503001e-13 0.0005347845917708824
162 | 1.824257820296086e-13 0.000557385821239809
163 | 1.9013550747275159e-13 0.0005809421403249629
164 | 1.9817106332071638e-13 0.0006054940283443645
165 | 2.0654621990209503e-13 0.0006310836401389479
166 | 2.1527532951065753e-13 0.0006577546345366954
167 | 2.2437335100051428e-13 0.0006855527982566774
168 | 2.338558754207256e-13 0.0007145258868193283
169 | 2.4373915273328777e-13 0.0007447233142079175
170 | 2.540401196602814e-13 0.0007761971123832096
171 | 2.647764287079031e-13 0.0008090008456910111
172 | 2.759664784171187e-13 0.0008431910586717516
173 | 2.876294448927767e-13 0.000878826205776083
174 | 2.997853146652139e-13 0.0009159674836529253
175 | 3.1245491894066595e-13 0.0009546782511019053
176 | 3.2565996929917864e-13 0.0009950251944318574
177 | 3.3942309490119207e-13 0.0010370771340012987
178 | 3.537678812665608e-13 0.0010809063662742071
179 | 3.687189106924612e-13 0.0011265879635917696
180 | 3.843018043794525e-13 0.001174200031597265
181 | 4.005432663378786e-13 0.0012238244511477583
182 | 4.1747112914985505e-13 0.001275546052873427
183 | 4.3511440166526004e-13 0.0013294533822467455
184 | 4.5350331871346606e-13 0.0013856391612312058
185 | 4.726693929160012e-13 0.0014441993419461233
186 | 4.92645468688931e-13 0.0015052345417496166
187 | 5.134657785275024e-13 0.0015688491242309228
188 | 5.351660016695043e-13 0.001635152189168362
189 | 5.577833252378736e-13 0.001704257472553505
190 | 5.813565079673266e-13 0.0017762832624058766
191 | 6.05925946624221e-13 0.0018513529625220826
192 | 6.315337452334715e-13 0.001929595357640064
193 | 6.582237872311514e-13 0.002011144422874247
194 | 6.860418106664259e-13 0.002096139941130359
195 | 7.150354865816886e-13 0.002184727508465087
196 | 7.452545007052198e-13 0.0022770590332954286
197 | 7.76750638596361e-13 0.002373292625229132
198 | 8.095778743891173e-13 0.0024735932952302643
199 | 8.43792463286263e-13 0.0025781330472268212
200 | 8.794530379624594e-13 0.002687090677867345
201 | 9.16620709041584e-13 0.0028006531798657843
202 | 9.553591698204592e-13 0.0029190151189964295
203 | 9.957348054184432e-13 0.0030423793010876995
204 | 1.037816806539927e-12 0.0031709571514662734
205 | 1.081677288044694e-12 0.0033049689659120692
206 | 1.127391412529327e-12 0.0034446445079731568
207 | 1.1750375191314492e-12 0.0035902228488506986
208 | 1.2246972577775195e-12 0.003741953819240035
209 | 1.276455729104244e-12 0.003900097285674088
210 | 1.3304016302933824e-12 0.004064924199563145
211 | 1.3866274070698635e-12 0.004236717052420919
212 | 1.445229412123682e-12 0.004415770212476062
213 | 1.5063080702270636e-12 0.004602390617935556
214 | 1.5699680503298557e-12 0.004796898039283363
215 | 1.6363184449280552e-12 0.004999625859631381
216 | 1.705472957012857e-12 0.005210921269917008
217 | 1.777550094920591e-12 0.0054311466174656806
218 | 1.852673375417457e-12 0.005660679068314165
219 | 1.930971535367081e-12 0.005899912216411724
220 | 2.0125787523436167e-12 0.006149255853056164
221 | 2.0976348745684575e-12 0.006409137214127114
222 | 2.1862856605645923e-12 0.006680001813094682
223 | 2.2786830289392977e-12 0.00696231386231312
224 | 2.3749853187232056e-12 0.007256556916691769
225 | 2.4753575607118927e-12 0.0075632353739462374
226 | 2.5799717602749748e-12 0.007882874781972232
227 | 2.689007192117355e-12 0.008216022850733503
228 | 2.8026507074977456e-12 0.008563250540273978
229 | 2.9210970544309384e-12 0.008925152912332975
230 | 3.044549211422547e-12 0.009302349906785799
231 | 3.173218735308132e-12 0.009695488309357755
232 | 3.307326123792795e-12 0.010105241441132918
233 | 3.4471011933125085e-12 0.010532311783335958
234 | 3.5927834728647293e-12 0.010977431015923885
235 | 3.744622614483171e-12 0.011441362052317123
236 | 3.902878821060176e-12 0.01192489991718547
237 | 4.067823292249822e-12 0.012428873050460506
238 | 4.239738689215904e-12 0.01295414535798231
239 | 4.418919619021211e-12 0.013501616803479149
240 | 4.605673139488192e-12 0.014072225546466506
241 | 4.800319285396171e-12 0.014666949579053441
242 | 5.003191616916843e-12 0.015286808025035624
243 | 5.214637791227899e-12 0.015932863054233276
244 | 5.435020158284324e-12 0.016606221786583237
245 | 5.6647163817683416e-12 0.017308038192224103
246 | 5.904120086282103e-12 0.018039514994076963
247 | 6.153641531892201e-12 0.018801905579699147
248 | 6.413708317181959e-12 0.01959651656095138
249 | 6.684766112016298e-12 0.020424709568018326
250 | 6.967279421274893e-12 0.02128790386414745
251 | 7.261732380862432e-12 0.02218757868402007
252 | 7.56862958736005e-12 0.023125275935566847
253 | 7.88849696273972e-12 0.02410260232670099
254 | 8.221882655623411e-12 0.02512123266258498
255 | 8.569357980631514e-12 0.026182912586308258
256 | 8.931518397430234e-12 0.027289461562158297
257 | 9.308984531155733e-12 0.028442775795999405
258 | 9.702403235963736e-12 0.029644831734921696
259 | 1.0112448703527096e-11 0.03089768921008271
260 | 1.0539823618381e-11 0.032203495339433896
261 | 1.0985260362095673e-11 0.03356448778160849
262 | 1.1449522268340113e-11 0.03498299877440291
263 | 1.1933404930987692e-11 0.03646145918164917
264 | 1.2437737567505215e-11 0.03800240272004569
265 | 1.2963384439961907e-11 0.039608470064485674
266 | 1.3511246336093434e-11 0.04128241332037133
267 | 1.4082262112959035e-11 0.0430271013520307
268 | 1.4677410305837096e-11 0.04484552377323459
269 | 1.5297710805116275e-11 0.04674079677404452
270 | 1.5944226604055847e-11 0.048716168275645726
271 | 1.6618065620410314e-11 0.050775023378682775
272 | 1.732038259504004e-11 0.05292089043991183
273 | 1.80523810707614e-11 0.055157446691967774
274 | 1.8815315454827644e-11 0.05748852484779116
275 | 1.9610493168574828e-11 0.05991811960622873
276 | 2.0439276887916667e-11 0.06245039455492659
277 | 2.1303086878527747e-11 0.06508968917823944
278 | 2.220340342971684e-11 0.06784052615247961
279 | 2.3141769391161217e-11 0.07070761990120752
280 | 2.4119792816849065e-11 0.07369588343761506
281 | 2.5139149720760906e-11 0.07681043762628652
282 | 2.6201586949012305e-11 0.08005662005154977
283 | 2.7308925173379823e-11 0.08343999336462603
284 | 2.846306201134016e-11 0.08696635566683196
285 | 2.9665975277969155e-11 0.09064174996199378
286 | 3.091972637527341e-11 0.09447247460655672
287 | 3.2226463824762727e-11 0.09846509447714441
288 | 3.3588426949316983e-11 0.10262645147173884
289 | 3.5007949710657084e-11 0.10696367659320564
290 | 3.648746470899606e-11 0.11148420270813518
291 | 3.802950735172444e-11 0.11619577644419235
292 | 3.96367201982737e-11 0.1211064719534052
293 | 4.131185748860348e-11 0.12622470453459236
294 | 4.3057789863072833e-11 0.13155924495169713
295 | 4.487750928178392e-11 0.13711923512893132
296 | 4.6774134151828315e-11 0.14291420306407604
297 | 4.875091467122225e-11 0.14895407938166866
298 | 5.0811238398688635e-11 0.15524921431908448
299 | 5.2958636058830725e-11 0.16181039599318517
300 | 5.5196787592645435e-11 0.16864886779815813
301 | 5.752952846374505e-11 0.17577634894463506
302 | 5.99608562310941e-11 0.1832050533121857
303 | 6.249493739952496e-11 0.19094771142009023
304 | 6.513611455977165e-11 0.19901759179926906
305 | 6.788891383025767e-11 0.20742852326096262
306 | 7.075805261339045e-11 0.21619491971878235
307 | 7.374844767965452e-11 0.22533180369862932
308 | 7.68652235933565e-11 0.2348548330414698
309 | 8.011372149446123e-11 0.24478032678260825
310 | 8.349950825156812e-11 0.2551252942461455
311 | 8.702838600171288e-11 0.2659074631880072
312 | 9.070640209334279e-11 0.27714531071843257
313 | 9.453985944950475e-11 0.28885809489787806
314 | 9.853532736900478e-11 0.30106588774633514
315 | 1.0269965278404913e-10 0.3137896089898257
316 | 1.0703997199365856e-10 0.32705106334574097
317 | 1.1156372289296333e-10 0.34087297641808195
318 | 1.1627865771933578e-10 0.35527903454034904
319 | 1.2119285633720317e-10 0.37029392475282874
320 | 1.2631474008430668e-10 0.38594337789503896
321 | 1.3165308620313495e-10 0.4022542118009503
322 | 1.3721704288226193e-10 0.4192543780633577
323 | 1.4301614493336626e-10 0.4369730092096652
324 | 1.490603301307965e-10 0.455440469294895
325 | 1.5535995624168345e-10 0.47468840539925644
326 | 1.6192581877578336e-10 0.4947498022609075
327 | 1.6876916948546975e-10 0.5156590383353595
328 | 1.7590173564757644e-10 0.5374519453696831
329 | 1.8333574016013494e-10 0.5601658691675282
330 | 1.9108392248844548e-10 0.5838397338077116
331 | 1.9915956049637585e-10 0.6085141087463675
332 | 2.075764932003007e-10 0.6342312774525927
333 | 2.1634914448467346e-10 0.6610353106575045
334 | 2.2549254781987187e-10 0.6889721419391569
335 | 2.350223720246755e-10 0.7180896455864161
336 | 2.4495494811752386e-10 0.7484377193796247
337 | 2.5530729730256897e-10 0.7800683698854534
338 | 2.6609716013848224e-10 0.8130358016641047
339 | 2.7734302694000027e-10 0.8473965099049681
340 | 2.890641694643095e-10 0.8832093774405724
341 | 3.0128067393656805e-10 0.9205357758391749
342 | 3.1401347547116157e-10 0.9594396699746167
343 | 3.272843939476784e-10 0.9999877281704613
344 | 3.411161714030849e-10 1.0422494363996755
345 | 3.5553251100417826e-10 1.086297217247169
346 | 3.705581176671035e-10 1.1322065537275643
347 | 3.862187403935422e-10 1.180056119330778
348 | 4.0254121639612513e-10 1.2299279122128575
349 | 4.1955351708868415e-10 1.2819073960464442
350 | 4.3728479602015525e-10 1.3360836461180452
351 | 4.5576543883427786e-10 1.392549502279156
352 | 4.750271153407025e-10 1.4514017284850702
353 | 4.951028337867421e-10 1.5127411772564903
354 | 5.160269974227697e-10 1.576672964210478
355 | 5.378354634581971e-10 1.643306646622591
356 | 5.60565604509067e-10 1.7127564121630101
357 | 5.842563726425588e-10 1.7851412745034028
358 | 6.089483661281597e-10 1.8605852766230733
359 | 6.346838990098915e-10 1.9392177040920937
360 | 6.615070736188157e-10 2.021173306376204
361 | 6.894638561500824e-10 2.1065925272385733
362 | 7.186021554340346e-10 2.1956217464506738
363 | 7.489719050363575e-10 2.2884135295325647
364 | 7.806251488279662e-10 2.3851268900133222
365 | 8.136161301712689e-10 2.485927561476718
366 | 8.480013848756444e-10 2.5909882817469096
367 | 8.838398380814258e-10 2.7004890886088937
368 | 9.211929052384232e-10 2.81461762902548
369 | 9.601245973520234e-10 2.933569479750882
370 | 1.00070163067723e-09 3.057548482968923
371 | 1.0429935410486197e-09 3.1867670957365597
372 | 1.0870728030421421e-09 3.3214467539563652
373 | 1.1330149541729644e-09 3.461818251494355
374 | 1.1808987243421999e-09 3.608122135901621
375 | 1.2308061707543435e-09 3.7606091208323686
376 | 1.2828228185366293e-09 3.919540515150417
377 | 1.3370378073012709e-09 4.085188671301759
378 | 1.393544043901762e-09 4.257837451330648
379 | 1.4524383616449962e-09 4.437782714033244
380 | 1.513821686232054e-09 4.625332821443013
381 | 1.5777992087120211e-09 4.820809167174897
382 | 1.6444805657452259e-09 5.024546727492261
383 | 1.713980027484808e-09 5.236894634931991
384 | 1.7864166933985864e-09 5.458216776928835
385 | 1.8619146963668018e-09 5.688892418963765
386 | 1.9406034154054907e-09 5.929316854847204
387 | 2.022617697380028e-09 6.179902083838912
388 | 2.108098088088788e-09 6.441077516136907
389 | 2.1971910731129184e-09 6.713290709944685
390 | 2.2900493288449722e-09 6.997008137113512
391 | 2.386831984126576e-09 7.292715982672283
392 | 2.4877048929434962e-09 7.600920978774673
393 | 2.5928409186454155e-09 7.92215127149887
394 | 2.702420230177479e-09 8.256957327265132
395 | 2.8166306108312504e-09 8.605912875184849
396 | 2.9356677800441885e-09 8.969615890153111
397 | 3.059735728799087e-09 9.348689617686555
398 | 3.1890470691982587e-09 9.743783641650763
399 | 3.323823398811514e-09 10.155574997590758
400 | 3.4642956804223e-09 10.584769332164706
401 | 3.6107046378227795e-09 11.032102112499734
402 | 3.763301168336095e-09 11.498339886615028
403 | 3.92234677277276e-09 11.984281596548389
404 | 4.0881140035579775e-09 12.490759946636443
405 | 4.260886931797827e-09 13.018642831483374
406 | 4.440961634084729e-09 13.568834821878804
407 | 4.628646699876404e-09 14.142278714709837
408 | 4.824263760317811e-09 14.739957149023128
409 | 5.028148039412299e-09 15.36289428872297
410 | 5.240648928486489e-09 16.01215757751941
411 | 5.462130584933353e-09 16.688859567879643
412 | 5.692972556259507e-09 17.39415982677958
413 | 5.933570430506168e-09 18.129266922264815
414 | 6.184336514158365e-09 18.895440494632393
415 | 6.4457005387041175e-09 19.693993413175857
416 | 6.718110397054412e-09 20.526294026523814
417 | 7.002032911085939e-09 21.39376850607479
418 | 7.297954631621921e-09 22.29790328930299
419 | 7.60638267222194e-09 23.240247626102693
420 | 7.927845578209611e-09 24.222416232798142
421 | 8.262894232427308e-09 25.246092058498874
422 | 8.612102799270148e-09 26.313029167128835
423 | 8.976069708616981e-09 27.42505574280483
424 | 9.355418681344517e-09 28.58407722129037
425 | 9.750799798181996e-09 29.792079553212176
426 | 1.0162890613738075e-08 31.05113260675937
427 | 1.0592397317609012e-08 32.363393712059064
428 | 1.1040055944557888e-08 33.73111135670384
429 | 1.1506633635838746e-08 35.156629036579005
430 | 1.1992929953827133e-08 36.64238927014641
431 | 1.2499778252209898e-08 38.190937781111
432 | 1.3028047104082308e-08 39.80492785876671
433 | 1.3578641790399762e-08 41.487124901504664
434 | 1.4152505851334844e-08 43.2404111530717
435 | 1.475062270319823e-08 45.06779063835265
436 | 1.537401732369432e-08 46.97239430755771
437 | 1.602375800839956e-08 48.95748539730602
438 | 1.6700958201473545e-08 51.02646501942195
439 | 1.7406778403740074e-08 53.182877983196185
440 | 1.8142428161408016e-08 55.430418866198906
441 | 1.8909168138840037e-08 57.77293833899996
442 | 1.970831227892119e-08 60.214449758555695
443 | 2.054123005472957e-08 62.75913603915107
444 | 2.1409348816367646e-08 65.41135681311012
445 | 2.2314156236976006e-08 68.17565589401019
446 | 2.325720286212112e-08 71.05676905538564
447 | 2.424010476692606e-08 74.05963213646204
448 | 2.526454632549747e-08 77.18938949138014
449 | 2.6332283097394867e-08 80.45140279354543
450 | 2.744514483608857e-08 83.85126021175341
451 | 2.8605038624561917e-08 87.39478597507109
452 | 2.9813952143431076e-08 91.0880503383148
453 | 3.1073957077182986e-08 94.93737997003329
454 | 3.238721266436861e-08 98.9493687786176
455 | 3.375596939783536e-08 103.13088919319209
456 | 3.518257288133972e-08 107.48910392240661
457 | 3.6669467849148997e-08 112.03147820720415
458 | 3.821920235552054e-08 116.76579259197625
459 | 3.9834432141237784e-08 121.70015623240369
460 | 4.151792518468604e-08 126.84302076502819
461 | 4.327256644526689e-08 132.20319476205947
462 | 4.5101362807280134e-08 137.78985879425446
463 | 4.7007448232745234e-08 143.6125811286965
464 | 4.899408913199269e-08 149.68133408891416
465 | 5.106468996122871e-08 156.00651110326953
466 | 5.3222799056665636e-08 162.59894447166005
467 | 5.547211471521581e-08 169.46992388037086
468 | 5.7816491532169414e-08 176.63121569765528
469 | 6.025994700671675e-08 184.0950830797872
470 | 6.280666842663495e-08 191.8743069254998
471 | 6.546102004393694e-08 199.98220771112628
472 | 6.822755055377967e-08 208.43266824480278
473 | 7.111100088944781e-08 217.2401573789018
474 | 7.411631234677107e-08 226.4197547185989
475 | 7.724863505189774e-08 235.98717637060406
476 | 8.05133367869355e-08 245.95880177511347
477 | 8.391601218858364e-08 256.351701663989
478 | 8.74624923355204e-08 267.18366719587607
479 | 9.115885474097476e-08 278.47324031514
480 | 9.501143376760708e-08 290.23974538527864
481 | 9.902683148254587e-08 302.5033221525162
482 | 1.0321192897118319e-07 315.2849600924804
483 | 1.0757389812911639e-07 328.6065341989267
484 | 1.1212021395244398e-07 342.4908422745375
485 | 1.1685866734747721e-07 356.96164378635916
486 | 1.2179737848181893e-07 372.04370035025016
487 | 1.2694481069968924e-07 387.7628179132758
488 | 1.323097850253441e-07 404.14589070447784
489 | 1.3790149527944136e-07 421.22094702555336
490 | 1.437295238342583e-07 439.01719696129163
491 | 1.4980385803476046e-07 457.5650820858931
492 | 1.5613490731366183e-07 476.89632725078866
493 | 1.6273352102980602e-07 497.043994537541
494 | 1.6961100706043797e-07 518.0425394677706
495 | 1.767791511792266e-07 539.9278695615775
496 | 1.8425023725324706e-07 562.7374053430652
497 | 1.920370682935324e-07 586.5101438920908
498 | 2.0015298839526963e-07 611.2867250488932
499 | 2.0861190560523753e-07 637.1095003796777
500 | 2.174283157556745e-07 664.022605017161
501 | 2.2661732730541898e-07 692.0720324942074
502 | 2.361946872308931e-07 721.30571269324
503 | 2.461768080112971e-07 751.7735930383334
504 | 2.565807957542597e-07 783.5277230645564
505 | 2.6742447951014146e-07 816.6223424997347
506 | 2.787264418252268e-07 851.1139730049879
507 | 2.9050605058616325e-07 887.061513720439
508 | 3.0278349221021836e-07 924.5263407722455
509 | 3.155798062382318e-07 963.572410900939
510 | 3.2891692138954374e-07 1004.2663693791436
511 | 3.4281769314068597e-07 1046.6776623913368
512 | 3.5730594289223344e-07 1090.8786540546637
513 | 3.724064987909349e-07 1136.9447482698397
514 | 3.881452382770798e-07 1184.9545155954418
515 | 4.045491324300121e-07 1234.9898253464032
516 | 4.216462921877861e-07 1287.1359831255118
517 | 4.394660165201694e-07 1341.4818740057822
518 | 4.580388426375453e-07 1398.1201115882084
519 | 4.773965983217571e-07 1457.1471931674894
520 | 4.97572456468572e-07 1518.6636612473606
521 | 5.186009919352325e-07 1582.7742716571213
522 | 5.405182407905139e-07 1649.5881685274828
523 | 5.633617620688228e-07 1719.219066395852
524 | 5.871707021341634e-07 1791.7854397177507
525 | 6.119858617642707e-07 1867.4107200755655
526 | 6.378497660698692e-07 1946.2235013787083
527 | 6.648067373688794e-07 2028.3577533667865
528 | 6.929029711404515e-07 2113.9530437349563
529 | 7.221866151889875e-07 2203.1547692083004
530 | 7.52707852153816e-07 2296.1143959091514
531 | 7.845189855059093e-07 2392.989709367498
532 | 8.176745291790176e-07 2493.94507453853
533 | 8.522313009888172e-07 2599.1517062020816
534 | 8.882485200001623e-07 2708.7879501294087
535 | 9.257879080092971e-07 2823.039575418252
536 | 9.649137953149354e-07 2942.1000784038683
537 | 1.0056932309594638e-06 3066.170998570127
538 | 1.048196097629189e-06 3195.462246895453
539 | 1.0924952314105277e-06 3330.1924470793742
540 | 1.1386665466073624e-06 3470.5892901088982
541 | 1.1867891658334633e-06 3616.889902637245
542 | 1.2369455556029072e-06 3769.3412296554666
543 | 1.289221667650855e-06 3928.2004319532916
544 | 1.343707086226864e-06 4093.7352988762946
545 | 1.4004951816131474e-06 4266.22467689537
546 | 1.4596832701308633e-06 4445.958914517268
547 | 1.5213727809086301e-06 4633.240324076825
548 | 1.5856694296990553e-06 4828.38366095768
549 | 1.6526834000411457e-06 5031.71662080116
550 | 1.722529532079046e-06 5243.580355267626
551 | 1.7953275193606876e-06 5464.330006926096
552 | 1.8712021139535904e-06 5694.33526385138
553 | 1.9502833402293226e-06 5933.9809345130525
554 | 2.032706717682974e-06 6183.6675435464185
555 | 2.1186134931694808e-06 6443.811948996292
556 | 2.208150882954789e-06 6714.847981622787
557 | 2.3014723249966383e-06 6997.227106862342
558 | 2.3987377418873064e-06 7291.419110023595
559 | 2.500113814908905e-06 7597.91280530267
560 | 2.605774269670875e-06 7917.216769179981
561 | 2.715900173819161e-06 8249.860098759535
562 | 2.830680247327255e-06 8596.393195586998
563 | 2.9503111859008337e-06 8957.388575463818
564 | 3.0749979980502103e-06 9333.44170475367
565 | 3.2049543564082278e-06 9725.171863640067
566 | 3.3404029638956387e-06 10133.223036766289
567 | 3.481575935361462e-06 10558.264831638884
568 | 3.628715195352322e-06 11000.993425135634
569 | 3.782072892692419e-06 11462.13253839559
570 | 3.941911832584586e-06 11942.434440309886
571 | 4.1085059269729065e-06 12442.680979758214
572 | 4.28214066393868e-06 12963.684646648346
573 | 4.46311359693412e-06 13506.289661731063
574 | 4.6517348546921685e-06 14071.373095049637
575 | 4.848327672686252e-06 14659.846012767855
576 | 5.05322894705073e-06 15272.654651990462
577 | 5.26678981191127e-06 15910.781623035917
578 | 5.489376241114506e-06 16575.247138464663
579 | 5.721369675388156e-06 17267.11026797447
580 | 5.963167676006332e-06 17987.470218079405
581 | 6.21518460608024e-06 18737.467635257053
582 | 6.47785234064174e-06 19518.28593100549
583 | 6.751621006736661e-06 20331.152626972005
584 | 7.0369597547961195e-06 21177.340718018968
585 | 7.334357562607734e-06 22058.170050752695
586 | 7.644324073264474e-06 22975.008714680287
587 | 7.967390468527134e-06 23929.27444275484
588 | 8.30411037909706e-06 24922.436017631007
589 | 8.65506083335906e-06 25956.01467946796
590 | 9.020843246220354e-06 27031.585530590815
591 | 9.402084449740048e-06 28150.77893174588
592 | 9.799437767315383e-06 29315.28188405102
593 | 1.0213584133265484e-05 30526.839390062574
594 | 1.0645233259731269e-05 31787.255786625865
595 | 1.1095124852891172e-05 33098.396041366796
596 | 1.1564029880576894e-05 34462.18700379533
597 | 1.2052751893461447e-05 35880.61860102963
598 | 1.2562128402083609e-05 37355.74496710946
599 | 1.3093032312068512e-05 38889.68549373151
600 | 1.3646373420003924e-05 40484.625789021826
601 | 1.4223099972535617e-05 42142.81852962834
602 | 1.4824200291353634e-05 43866.58418998974
603 | 1.5450704466854147e-05 45658.31163108815
604 | 1.6103686123379288e-05 47520.458529327945
605 | 1.6784264259059995e-05 49455.551624383705
606 | 1.749360516341477e-05 51466.186762931095
607 | 1.8232924415990517e-05 53555.02871309395
608 | 1.9003488969470403e-05 55724.810722211165
609 | 1.980661932081862e-05 57978.33378814014
610 | 2.0643691774182577e-05 60318.46561174596
611 | 2.1516140799430473e-05 62748.139195499316
612 | 2.2425461490365988e-05 65270.35105017615
613 | 2.337321212683269e-05 67888.15896854742
614 | 2.436101684509873e-05 70604.67932163035
615 | 2.5390568421098052e-05 73423.08382956285
616 | 2.6463631171297638e-05 76346.59575543526
617 | 2.7582043976161977e-05 79378.48546647625
618 | 2.874772343139594e-05 82522.06530283744
619 | 2.996266713236633e-05 85780.68368985405
620 | 3.1228957097330467e-05 89157.71842507673
621 | 3.254876333533816e-05 92656.56906658018
622 | 3.392434756492127e-05 96280.64834406678
623 | 3.53580670899435e-05 100033.37250911053
624 | 3.685237883925231e-05 103918.15053554162
625 | 3.840984357705573e-05 107938.37207548696
626 | 4.003313029123906e-05 112097.39407097864
627 | 4.172502076714191e-05 116398.52591537088
628 | 4.348841435463324e-05 120845.01305309717
629 | 4.532633293665385e-05 125440.01890063247
630 | 4.724192610774066e-05 130186.60496595406
631 | 4.92384765714071e-05 135087.7090384152
632 | 5.131940576562902e-05 140146.12131585623
633 | 5.3488279726076293e-05 145364.4583311007
634 | 5.574881519713787e-05 150745.13453585783
635 | 5.810488600121253e-05 156290.33139664927
636 | 6.056052967718024e-05 162001.9638548891
637 | 6.311995439943024e-05 167881.64400189227
638 | 6.578754618930305e-05 173930.64181963593
639 | 6.856787643130411e-05 180149.8428398399
640 | 7.146570970696965e-05 186539.70257771507
641 | 7.448601195980948e-05 193100.19760293615
642 | 7.763395900531859e-05 199830.77311947444
643 | 8.091494540064113e-05 206730.28693836872
644 | 8.433459368908644e-05 213796.9497438943
645 | 8.789876403533906e-05 221028.26157452338
646 | 9.161356426787462e-05 228420.94446627572
647 | 9.548536034579088e-05 235970.87123830715
648 | 9.95207872679906e-05 243672.99043973137
649 | 0.00010372676044341114 251521.2475236831
650 | 0.00010811048754178568 259508.50237050562
651 | 0.00011267948084524436 267626.4433478295
652 | 0.00011744157012192195 275865.49817236356
653 | 0.00012240491604363318 284214.74192772654
654 | 0.0001275780241706095 292661.8026959239
655 | 0.00013296975952726216 301192.765378472
656 | 0.00013858936179395026 309792.0744180852
657 | 0.0001444464611407868 318442.43628459575
658 | 0.00015055109473061752 327124.7227606831
659 | 0.00015691372391945268 335817.8762551708
660 | 0.00016354525218382799 344498.81858506525
661 | 0.00017045704380581615 353142.36490278493
662 | 0.00017766094334770955 361721.1447023655
663 | 0.00018516929594974637 370205.532117457
664 | 0.00019299496848566527 378563.588023534
665 | 0.00020115137161234067 386761.01677482633
666 | 0.00020965248275128627 394761.1407397677
667 | 0.00021851287004140814 402524.89614247414
668 | 0.0002277477173040555 410010.85406531073
669 | 0.00023737285006315104 417175.270810263
670 | 0.00024740476266499047 423972.1721432846
671 | 0.00025786064654418603 430353.4762418237
672 | 0.00026875841968419285 436269.16041373747
673 | 0.0002801167573229034 441667.47683442803
674 | 0.00029195512395592993 446495.2226328567
675 | 0.00030429380669241764 450698.0696163265
676 | 0.0003171539500205497 454220.9587243879
677 | 0.00033055759204232205 457008.56390543154
678 | 0.00034452770223967956 459005.8294731601
679 | 0.0003590882208367369 460158.5840789264
680 | 0.00037426409982553355 460414.23318300676
681 | 0.0003900813457256311 459722.5302770222
682 | 0.0004065670641508273 458036.42505800875
683 | 0.00042374950625936013 455312.9842465167
684 | 0.00044165811716720215 451514.377753045
685 | 0.00046032358640741037 446608.9194235801
686 | 0.0004797779005220021 440572.14765536616
687 | 0.0005000543978764814 433387.9268202051
688 | 0.0005211878257909531 425049.54575730185
689 | 0.0005432144000857241 415560.7847424373
690 | 0.0005661718671434386 404936.91750252806
691 | 0.000590099568594098 393205.61028283014
692 | 0.0006150385087338158 380407.6760091476
693 | 0.0006410314247928419 366597.6385993951
694 | 0.000668122860173272 351844.0608965507
695 | 0.0006963592407819475 336229.58997710433
696 | 0.0007257889545893573 319850.6761958397
697 | 0.0007564624345508767 302816.9276820427
698 | 0.0007884322450324465 285250.0704409811
699 | 0.0008217531718887963 267282.4959324828
700 | 0.0008564823163485757 249055.39298822999
701 | 0.0008926791928672845 230716.47892372444
702 | 0.0009304058311156885 212417.36512541425
703 | 0.0009697268822784948 194310.61433912985
704 | 0.001010709729845451 176546.5691109727
705 | 0.0010534246050847244 159270.05180178146
706 | 0.0010979447073964491 142617.05456878766
707 | 0.0011443463297526831 126711.5508619796
708 | 0.0011927089894387443 111662.56658764741
709 | 0.0012431155643199676 97561.64770410325
710 | 0.0012956524348674058 84480.85068079695
711 | 0.0013504096321858533 72471.36269104283
712 | 0.0014074809922978728 61562.83014746592
713 | 0.001466964316948211 51763.438623034854
714 | 0.0015289615412041708 43060.74655563361
715 | 0.0015935789081391563 35423.232326376536
716 | 0.001660927150898737 28802.472693433072
717 | 0.0017311216824612361 23135.83363885265
718 | 0.0018042827934180287 18349.525684395318
719 | 0.0018805358581124823 14361.85727698627
720 | 0.001960011549490795 11086.51362366868
721 | 0.002042846063032914 8435.694900121065
722 | 0.002129181350147282 6322.966346244985
723 | 0.0022191653614293694 4665.701486191864
724 | 0.0023129523002008677 3387.0356740341877
725 | 0.0024107028867640123 2417.2868246149887
726 | 0.0025125846338239 1694.8397604995794
727 | 0.0026187721335507647 1166.5265145842463
728 | 0.0027294473567741643 787.5642104388153
729 | 0.0028447999648217796 521.1327632487223
730 | 0.0029650276345372308 337.68567573940953
731 | 0.0030903363970338797 214.08884953049358
732 | 0.0032209409907651312 132.6757973106397
733 | 0.0033570652295162834 80.29487276125576
734 | 0.0034989423859485445 47.40748855277075
735 | 0.003646815591352485 27.278174640228748
736 | 0.003800938252295977 15.279878983932047
737 | 0.0039615744848806094 8.322768732601554
738 | 0.004128999567350767 4.402965324632357
739 | 0.004303500411830982 2.2595228747314517
740 | 0.004485376055999987 1.1233734158755935
741 | 0.004674938175544004 0.5403631973241597
742 | 0.004872511618267478 0.2511281041606369
743 | 0.00507843496077654 0.11259546526881412
744 | 0.005293061088689155 0.048629957957276225
745 | 0.005516757801366279 0.020200301533692514
746 | 0.005749908442200301 0.008056887788636068
747 | 0.005992912555540922 0.0030802543977988843
748 | 0.006246186571384173 0.001126778248942098
749 | 0.006510164518997974 0.00039365236332040363
750 | 0.006785298770707082 0.00013108877902051651
751 | 0.007072060817112104 4.152565069822938e-05
752 | 0.007370942075070994 1.2486723164460074e-05
753 | 0.00768245472982768 3.5563598910231048e-06
754 | 0.00800713261273095 9.571759593071973e-07
755 | 0.008345532116047712 2.428668764527232e-07
756 | 0.008698233146438344 5.794992797243039e-08
757 | 0.009065840118728045 1.2969330635169637e-08
758 | 0.009448982991677218 2.7151044293844543e-09
759 | 0.009848318347525852 5.30193508041162e-10
760 | 0.010264530517161875 9.629061316211079e-11
761 | 0.010698332752841676 1.6214515926976147e-11
762 | 0.011150468450472432 2.5235218108110405e-12
763 | 0.011621712423550852 3.617821133595702e-13
764 | 0.012112872230941442 4.761204910350327e-14
765 | 0.0126247895607697 5.731199264940708e-15
766 | 0.013158341672801728 6.286308787263234e-16
767 | 0.013714442901782085 6.258366516170282e-17
768 | 0.014294046224306089 5.632001421660443e-18
769 | 0.014898144891911679 4.561915376504525e-19
770 | 0.015527774133189426 3.31117614759734e-20
771 | 0.01618401292782755 2.1436514119568276e-21
772 | 0.016867985855632105 1.2318674644096007e-22
773 | 0.017580865023690898 6.25207480041393e-24
774 | 0.018323872074983753 2.7877554389134077e-25
775 | 0.019098280281881118 1.0861232523488131e-26
776 | 0.019905416728118727 3.676382240385687e-28
777 | 0.020746664582987358 1.0747261472506746e-29
778 | 0.02162346547163505 2.6966214029629613e-31
779 | 0.0225373219455436 5.770093279059776e-33
780 | 0.02348980005741301 1.0458359277420447e-34
781 | 0.02448253204486632 1.5944679456608886e-36
782 | 0.025517219127573928 2.0298523165158363e-38
783 | 0.026595634422590615 2.1414119264069606e-40
784 | 0.027719625982901407 1.8572654294474638e-42
785 |
--------------------------------------------------------------------------------