├── 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 ascl:2203.007 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 | --------------------------------------------------------------------------------