summaryrefslogtreecommitdiff
path: root/silx/math/fit/filters/src/smoothnd.c
diff options
context:
space:
mode:
Diffstat (limited to 'silx/math/fit/filters/src/smoothnd.c')
-rw-r--r--silx/math/fit/filters/src/smoothnd.c317
1 files changed, 0 insertions, 317 deletions
diff --git a/silx/math/fit/filters/src/smoothnd.c b/silx/math/fit/filters/src/smoothnd.c
deleted file mode 100644
index cb96961..0000000
--- a/silx/math/fit/filters/src/smoothnd.c
+++ /dev/null
@@ -1,317 +0,0 @@
-#/*##########################################################################
-#
-# Copyright (c) 2004-2016 European Synchrotron Radiation Facility
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-#
-#############################################################################*/
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#define MIN(x, y) (((x) < (y)) ? (x) : (y))
-#define MAX(x, y) (((x) > (y)) ? (x) : (y))
-
-#define MAX_SAVITSKY_GOLAY_WIDTH 101
-#define MIN_SAVITSKY_GOLAY_WIDTH 3
-
-/* Wrapped functions */
-void smooth1d(double *data, int size);
-void smooth2d(double *data, int size0, int size1);
-void smooth3d(double *data, int size0, int size1, int size2);
-int SavitskyGolay(double* input, long len_input, int npoints, double* output);
-
-/* Internal functions */
-long index2d(long row_idx, long col_idx, long ncols);
-long index3d(long x_idx, long y_idx, long z_idx, long ny, long nz);
-void smooth1d_rows(double *data, long nrows, long ncols);
-void smooth1d_cols(double *data, long nrows, long ncols);
-void smooth1d_x(double *data, long nx, long ny, long nz);
-void smooth1d_y(double *data, long nx, long ny, long nz);
-void smooth1d_z(double *data, long nx, long ny, long nz);
-void smooth2d_yzslice(double *data, long nx, long ny, long nz);
-void smooth2d_xzslice(double *data, long nx, long ny, long nz);
-void smooth2d_xyslice(double *data, long nx, long ny, long nz);
-
-
-/* Simple smoothing of a 1D array */
-void smooth1d(double *data, int size)
-{
- long i;
- double prev_sample;
- double next_sample;
-
- if (size < 3)
- {
- return;
- }
- prev_sample = data[0];
- for (i=0; i<(size-1); i++)
- {
- next_sample = 0.25 * (prev_sample + 2 * data[i] + data[i+1]);
- prev_sample = data[i];
- data[i] = next_sample;
- }
- data[size-1] = 0.25 * prev_sample + 0.75 * data[size-1];
- return;
-}
-
-/* Smoothing of a 2D array*/
-void smooth2d(double *data, int nrows, int ncols)
-{
- /* smooth the first dimension (rows) */
- smooth1d_rows(data, nrows, ncols);
-
- /* smooth the 2nd dimension */
- smooth1d_cols(data, nrows, ncols);
-}
-
-/* Smoothing of a 3D array */
-void smooth3d(double *data, int nx, int ny, int nz)
-{
- smooth2d_xyslice(data, nx, ny, nz);
- smooth2d_xzslice(data, nx, ny, nz);
- smooth2d_yzslice(data, nx, ny, nz);
-}
-
-/* 1D Savitsky-Golay smoothing */
-int SavitskyGolay(double* input, long len_input, int npoints, double* output)
-{
-
- //double dpoints = 5.;
- double coeff[MAX_SAVITSKY_GOLAY_WIDTH];
- int i, j, m;
- double dhelp, den;
- double *data;
-
- memcpy(output, input, len_input * sizeof(double));
-
- if (!(npoints % 2)) npoints +=1;
-
- if((npoints < MIN_SAVITSKY_GOLAY_WIDTH) || (len_input < npoints) || \
- (npoints > MAX_SAVITSKY_GOLAY_WIDTH))
- {
- /* do not smooth data */
- return 1;
- }
-
- /* calculate the coefficients */
- m = (int) (npoints/2);
- den = (double) ((2*m-1) * (2*m+1) * (2*m + 3));
- for (i=0; i<= m; i++){
- coeff[m+i] = (double) (3 * (3*m*m + 3*m - 1 - 5*i*i ));
- coeff[m-i] = coeff[m+i];
- }
-
- /* simple smoothing at the beginning */
- for (j=0; j<=(int)(npoints/3); j++)
- {
- smooth1d(output, m);
- }
-
- /* simple smoothing at the end */
- for (j=0; j<=(int)(npoints/3); j++)
- {
- smooth1d((output+len_input-m-1), m);
- }
-
- /*one does not need the whole spectrum buffer, but code is clearer */
- data = (double *) malloc(len_input * sizeof(double));
- memcpy(data, output, len_input * sizeof(double));
-
- /* the actual SG smoothing in the middle */
- for (i=m; i<(len_input-m); i++){
- dhelp = 0;
- for (j=-m;j<=m;j++) {
- dhelp += coeff[m+j] * (*(data+i+j));
- }
- if(dhelp > 0.0){
- *(output+i) = dhelp / den;
- }
- }
- free(data);
- return (0);
-}
-
-/*********************/
-/* Utility functions */
-/*********************/
-
-long index2d(long row_idx, long col_idx, long ncols)
-{
- return (row_idx*ncols+col_idx);
-}
-
-/* Apply smooth 1d on all rows in a 2D array*/
-void smooth1d_rows(double *data, long nrows, long ncols)
-{
- long row_idx;
-
- for (row_idx=0; row_idx < nrows; row_idx++)
- {
- smooth1d(&data[row_idx * ncols], ncols);
- }
-}
-
-/* Apply smooth 1d on all columns in a 2D array*/
-void smooth1d_cols(double *data, long nrows, long ncols)
-{
- long row_idx, col_idx;
- long this_idx2d, next_idx2d;
- double prev_sample;
- double next_sample;
-
- for (col_idx=0; col_idx < ncols; col_idx++)
- {
- prev_sample = data[index2d(0, col_idx, ncols)];
- for (row_idx=0; row_idx<(nrows-1); row_idx++)
- {
- this_idx2d = index2d(row_idx, col_idx, ncols);
- next_idx2d = index2d(row_idx+1, col_idx, ncols);
-
- next_sample = 0.25 * (prev_sample + \
- 2 * data[this_idx2d] + \
- data[next_idx2d]);
- prev_sample = data[this_idx2d];
- data[this_idx2d] = next_sample;
- }
-
- this_idx2d = index2d(nrows-1, col_idx, ncols);
- data[this_idx2d] = 0.25 * prev_sample + 0.75 * data[this_idx2d];
- }
-}
-
-long index3d(long x_idx, long y_idx, long z_idx, long ny, long nz)
-{
- return ((x_idx*ny + y_idx) * nz + z_idx);
-}
-
-/* Apply smooth 1d along first dimension in a 3D array*/
-void smooth1d_x(double *data, long nx, long ny, long nz)
-{
- long x_idx, y_idx, z_idx;
- long this_idx3d, next_idx3d;
- double prev_sample;
- double next_sample;
-
- for (y_idx=0; y_idx < ny; y_idx++)
- {
- for (z_idx=0; z_idx < nz; z_idx++)
- {
- prev_sample = data[index3d(0, y_idx, z_idx, ny, nz)];
- for (x_idx=0; x_idx<(nx-1); x_idx++)
- {
- this_idx3d = index3d(x_idx, y_idx, z_idx, ny, nz);
- next_idx3d = index3d(x_idx+1, y_idx, z_idx, ny, nz);
-
- next_sample = 0.25 * (prev_sample + \
- 2 * data[this_idx3d] + \
- data[next_idx3d]);
- prev_sample = data[this_idx3d];
- data[this_idx3d] = next_sample;
- }
-
- this_idx3d = index3d(nx-1, y_idx, z_idx, ny, nz);
- data[this_idx3d] = 0.25 * prev_sample + 0.75 * data[this_idx3d];
- }
- }
-}
-
-/* Apply smooth 1d along second dimension in a 3D array*/
-void smooth1d_y(double *data, long nx, long ny, long nz)
-{
- long x_idx, y_idx, z_idx;
- long this_idx3d, next_idx3d;
- double prev_sample;
- double next_sample;
-
- for (x_idx=0; x_idx < nx; x_idx++)
- {
- for (z_idx=0; z_idx < nz; z_idx++)
- {
- prev_sample = data[index3d(x_idx, 0, z_idx, ny, nz)];
- for (y_idx=0; y_idx<(ny-1); y_idx++)
- {
- this_idx3d = index3d(x_idx, y_idx, z_idx, ny, nz);
- next_idx3d = index3d(x_idx, y_idx+1, z_idx, ny, nz);
-
- next_sample = 0.25 * (prev_sample + \
- 2 * data[this_idx3d] + \
- data[next_idx3d]);
- prev_sample = data[this_idx3d];
- data[this_idx3d] = next_sample;
- }
-
- this_idx3d = index3d(x_idx, ny-1, z_idx, ny, nz);
- data[this_idx3d] = 0.25 * prev_sample + 0.75 * data[this_idx3d];
- }
- }
-}
-
-/* Apply smooth 1d along third dimension in a 3D array*/
-void smooth1d_z(double *data, long nx, long ny, long nz)
-{
- long x_idx, y_idx;
- long idx3d_first_sample;
-
- for (x_idx=0; x_idx < nx; x_idx++)
- {
- for (y_idx=0; y_idx < ny; y_idx++)
- {
- idx3d_first_sample = index3d(x_idx, y_idx, 0, ny, nz);
- /*We can use regular 1D smoothing function because z samples
- are contiguous in memory*/
- smooth1d(&data[idx3d_first_sample], nz);
- }
- }
-}
-
-/* 2D smoothing of a YZ slice in a 3D volume*/
-void smooth2d_yzslice(double *data, long nx, long ny, long nz)
-{
- long x_idx;
- long slice_size = ny * nz;
-
- /* a YZ slice is a "normal" 2D array of memory-contiguous data*/
- for (x_idx=0; x_idx < nx; x_idx++)
- {
- smooth2d(&data[x_idx*slice_size], ny, nz);
- }
-}
-
-/* 2D smoothing of a XZ slice in a 3D volume*/
-void smooth2d_xzslice(double *data, long nx, long ny, long nz)
-{
-
- /* smooth along the first dimension */
- smooth1d_x(data, nx, ny, nz);
-
- /* smooth along the third dimension */
- smooth1d_z(data, nx, ny, nz);
-}
-
-/* 2D smoothing of a XY slice in a 3D volume*/
-void smooth2d_xyslice(double *data, long nx, long ny, long nz)
-{
- /* smooth along the first dimension */
- smooth1d_x(data, nx, ny, nz);
-
- /* smooth along the second dimension */
- smooth1d_y(data, nx, ny, nz);
-}
-