|
gimme-alpha 0.1
|
00001 /* 00002 ** density.c 00003 ** 00004 ** Made by (Johnny Q. Hacker) 00005 ** Login <solarion@borkborkbork> 00006 00007 Copyright (C) 2009 Joseph Pingenot 00008 00009 This program is free software: you can redistribute it and/or modify 00010 it under the terms of the GNU Affero General Public License as published by 00011 the Free Software Foundation, either version 3 of the License, or 00012 (at your option) any later version. 00013 00014 This program is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU Affero General Public License for more details. 00018 00019 You should have received a copy of the GNU Affero General Public License 00020 along with this program. If not, see <http://www.gnu.org/licenses/>. 00021 00022 ** Started on Tue Mar 3 15:40:58 2009 Johnny Q. Hacker 00023 ** Last update Sun May 12 01:17:25 2002 Speed Blue 00024 */ 00025 00026 #include <gsl/gsl_errno.h> 00027 #include <gsl/gsl_interp.h> 00028 #include <gsl/gsl_spline.h> 00029 #include <libcommon/density.h> 00030 #include <libcommon/gcc_hints.h> 00031 00032 double get_density_within_range2(double xmin, double xmax, double x[], double rho[], int len) { 00033 /*Use GSL to integrate using a spline interpolator*/ 00034 gsl_interp_accel *acc = gsl_interp_accel_alloc(); 00035 gsl_spline *spline = gsl_spline_alloc(gsl_interp_akima_periodic, len); 00036 gsl_spline_init(spline, x, rho, len); 00037 double density = gsl_spline_eval_integ(spline, xmin, xmax, acc); 00038 gsl_spline_free(spline); 00039 gsl_interp_accel_free(acc); 00040 return density; 00041 } 00042 00043 double get_density_within_range2_stairstep(double xmin, double xmax, double x[], double rho[], int len) { 00044 /*Use simple stair step (const interpolation) to calculate the density*/ 00045 double density=0; 00046 int prev=0; 00047 for(int i=1; i<len; i++) { 00048 if((x[i] >= xmin) && (x[i] <= xmax)) { 00049 if(unlikely((x[i-1] < xmin) && (x[i] != xmin))) { 00050 /*If we stepped over xmin, we only have a partial distance*/ 00051 density+=rho[i-1]*(xmin-x[i]); 00052 }else{ 00053 density+=rho[i-1]*(x[i]-x[i-1]); 00054 } 00055 } 00056 if(x[i] > xmax) { 00057 if(x[i-1] < xmax) { 00058 density += rho[i-1]*(xmax-x[i-1]); 00059 } 00060 /*No point in continuing the loop past this exit point.*/ 00061 break; 00062 } 00063 } 00064 return density; 00065 } 00066 00067 double get_density_within_range2_sum(double xmin, double xmax, double x[], double rho[], int len) { 00068 /*Use simple stair step (const interpolation) to calculate the density*/ 00069 double density=0; 00070 int prev=0; 00071 for(int i=1; i<len; i++) { 00072 if((x[i] >= xmin) && (x[i] <= xmax)) { 00073 if(unlikely((x[i-1] < xmin) && (x[i] != xmin))) { 00074 /*If we stepped over xmin, we only have a partial distance*/ 00075 density+=rho[i-1]; 00076 }else{ 00077 density+=rho[i-1]; 00078 } 00079 } 00080 if(x[i] > xmax) { 00081 if(x[i-1] < xmax) { 00082 density += rho[i-1]; 00083 } 00084 /*No point in continuing the loop past this exit point.*/ 00085 break; 00086 } 00087 } 00088 return density; 00089 } 00090 00091 double get_density_within_range(double xmin, double xmax, struct density_point *p, int len, short int type) { 00092 int i; 00093 double x[len]; 00094 double rho[len]; 00095 for(i=0; i<len; i++) { 00096 x[i] = p[i].x; 00097 rho[i] = p[i].rho; 00098 //fprintf(stderr, "i=%d: x=%g rho=%g -> x=%g rho=%g\n", i, p[i].x, p[i].rho, x[i], rho[i]); 00099 } 00100 switch (type) { 00101 case 1: 00102 return get_density_within_range2_stairstep(xmin, xmax, x, rho, len); 00103 break; 00104 case 2: 00105 return get_density_within_range2_sum(xmin, xmax, x, rho, len); 00106 break; 00107 default: 00108 return get_density_within_range2(xmin, xmax, x, rho, len); 00109 } 00110 }