JWS C Library
C language utility library
3d.c
Go to the documentation of this file.
00001 /*
00002  * This work is licensed under a Creative Commons 
00003  * Attribution-Noncommercial-Share Alike 3.0 United States License.
00004  * 
00005  *    http://creativecommons.org/licenses/by-nc-sa/3.0/us/
00006  * 
00007  * You are free:
00008  * 
00009  *    to Share - to copy, distribute, display, and perform the work
00010  *    to Remix - to make derivative works
00011  * 
00012  * Under the following conditions:
00013  * 
00014  *    Attribution. You must attribute the work in the manner specified by the
00015  *    author or licensor (but not in any way that suggests that they endorse you
00016  *    or your use of the work).
00017  * 
00018  *    Noncommercial. You may not use this work for commercial purposes.
00019  * 
00020  *    Share Alike. If you alter, transform, or build upon this work, you may
00021  *    distribute the resulting work only under the same or similar license to
00022  *    this one.
00023  * 
00024  * For any reuse or distribution, you must make clear to others the license
00025  * terms of this work. The best way to do this is by including this header.
00026  * 
00027  * Any of the above conditions can be waived if you get permission from the
00028  * copyright holder.
00029  * 
00030  * Apart from the remix rights granted under this license, nothing in this
00031  * license impairs or restricts the author's moral rights.
00032  */
00033 
00034 
00046 #include <jwsc/config.h>
00047 
00048 #include <stdlib.h>
00049 #include <inttypes.h>
00050 #include <math.h>
00051 #include <assert.h>
00052 
00053 #include "jwsc/base/error.h"
00054 #include "jwsc/prob/pdf.h"
00055 #include "jwsc/matblock/matblock.h"
00056 #include "jwsc/matblock/matblock_math.h"
00057 #include "jwsc/filter/3d.h"
00058 
00059 
00061 #define  PI  3.14159265358979323846
00062 
00063 
00088 Error* create_auto_3d_gaussian_filter_f
00089 (
00090     Matblock_f** h_out, 
00091     float        mat_sigma,
00092     float        row_sigma,
00093     float        col_sigma
00094 )
00095 {
00096     uint32_t num_mats, num_rows, num_cols;
00097 
00098     if ((num_mats = ceil(sqrt(2) * 6.0 * mat_sigma)) % 2 == 0) num_mats++;
00099     if ((num_rows = ceil(sqrt(2) * 6.0 * row_sigma)) % 2 == 0) num_rows++;
00100     if ((num_cols = ceil(sqrt(2) * 6.0 * col_sigma)) % 2 == 0) num_cols++;
00101 
00102     return create_3d_gaussian_filter_f(h_out, mat_sigma, row_sigma, col_sigma, 
00103             num_mats, num_rows, num_cols);
00104 }
00105 
00123 Error* create_auto_3d_gaussian_filter_d
00124 (
00125     Matblock_d** h_out, 
00126     double       mat_sigma,
00127     double       row_sigma,
00128     double       col_sigma
00129 )
00130 {
00131     uint32_t num_mats, num_rows, num_cols;
00132 
00133     if ((num_mats = ceil(sqrt(2) * 6.0 * mat_sigma)) % 2 == 0) num_mats++;
00134     if ((num_rows = ceil(sqrt(2) * 6.0 * row_sigma)) % 2 == 0) num_rows++;
00135     if ((num_cols = ceil(sqrt(2) * 6.0 * col_sigma)) % 2 == 0) num_cols++;
00136 
00137     return create_3d_gaussian_filter_d(h_out, mat_sigma, row_sigma, col_sigma, 
00138             num_mats, num_rows, num_cols);
00139 }
00140 
00175 Error* create_3d_gaussian_filter_f
00176 (
00177     Matblock_f** h_out, 
00178     float        mat_sigma,
00179     float        row_sigma,
00180     float        col_sigma,
00181     uint32_t     num_mats,
00182     uint32_t     num_rows,
00183     uint32_t     num_cols
00184 )
00185 {
00186     uint32_t    mat, row, col;
00187     uint32_t    m, r, c;
00188     float       x, y, z;
00189     float       x_gauss, y_gauss, z_gauss;
00190     float       gauss;
00191     Matblock_f* h;
00192 
00193     if (mat_sigma < 0.01 || row_sigma < 0.01 || col_sigma < 0.01)
00194     {
00195         return JWSC_EARG("Sigma for Gaussian is too small");
00196     }
00197 
00198     create_matblock_f(h_out, num_mats, num_rows, num_cols);
00199     h = *h_out;
00200 
00201 #if defined JWSC_HAVE_SLATEC || defined JWSC_HAVE_ERF
00202     for (mat = 0; mat < ceil(0.5*num_mats); mat++)
00203     {
00204         z       = (ceil(0.5*num_mats) - mat - 1);
00205         z_gauss = integrate_gaussian_pdf_d(0, mat_sigma, z, z+1);
00206         for (row = 0; row < ceil(0.5*num_rows); row++)
00207         {
00208             y       = (ceil(0.5*num_rows) - row - 1);
00209             y_gauss = integrate_gaussian_pdf_d(0, row_sigma, y, y+1);
00210             for (col = 0; col < ceil(0.5*num_cols); col++)
00211             {
00212                 x       = (ceil(0.5*num_cols) - col - 1);
00213                 x_gauss = integrate_gaussian_pdf_d(0, col_sigma, x, x+1);
00214                 gauss   = x_gauss*y_gauss*z_gauss;
00215 
00216                 m = mat; r = row; c = col;
00217                 h->elts[ m ][ r ][ c ] = gauss;
00218 
00219                 m = mat; r = row; c = num_cols-col-1;
00220                 h->elts[ m ][ r ][ c ] = gauss;
00221 
00222                 m = mat; r = num_rows-row-1; c = col;
00223                 h->elts[ m ][ r ][ c ] = gauss;
00224 
00225                 m = mat; r = num_rows-row-1; c = num_cols-col-1;
00226                 h->elts[ m ][ r ][ c ] = gauss;
00227 
00228                 m = num_mats-mat-1; r = row; c = col;
00229                 h->elts[ m ][ r ][ c ] = gauss;
00230 
00231                 m = num_mats-mat-1; r = row; c = num_cols-col-1;
00232                 h->elts[ m ][ r ][ c ] = gauss;
00233 
00234                 m = num_mats-mat-1; r = num_rows-row-1; c = col;
00235                 h->elts[ m ][ r ][ c ] = gauss;
00236 
00237                 m = num_mats-mat-1; r = num_rows-row-1; c = num_cols-col-1;
00238                 h->elts[ m ][ r ][ c ] = gauss;
00239             }
00240         }
00241     }
00242 #else
00243     for (mat = 0; mat < ceil(0.5*num_mats); mat++)
00244     {
00245         z       = (ceil(0.5*num_mats) - mat - 1);
00246         z_gauss = gaussian_pdf_d(0, row_sigma, z+0.5);
00247         for (row = 0; row < ceil(0.5*num_rows); row++)
00248         {
00249             y       = (ceil(0.5*num_rows) - row - 1);
00250             y_gauss = gaussian_pdf_d(0, row_sigma, y+0.5);
00251             for (col = 0; col < ceil(0.5*num_cols); col++)
00252             {
00253                 x       = (ceil(0.5*num_cols) - col - 1);
00254                 x_gauss = gaussian_pdf_d(0, col_sigma, x+0.5);
00255                 gauss   = x_gauss*y_gauss*z_gauss;
00256 
00257                 m = mat; r = row; c = col;
00258                 h->elts[ m ][ r ][ c ] = gauss;
00259 
00260                 m = mat; r = row; c = num_cols-col-1;
00261                 h->elts[ m ][ r ][ c ] = gauss;
00262 
00263                 m = mat; r = num_rows-row-1; c = col;
00264                 h->elts[ m ][ r ][ c ] = gauss;
00265 
00266                 m = mat; r = num_rows-row-1; c = num_cols-col-1;
00267                 h->elts[ m ][ r ][ c ] = gauss;
00268 
00269                 m = num_mats-mat-1; r = row; c = col;
00270                 h->elts[ m ][ r ][ c ] = gauss;
00271 
00272                 m = num_mats-mat-1; r = row; c = num_cols-col-1;
00273                 h->elts[ m ][ r ][ c ] = gauss;
00274 
00275                 m = num_mats-mat-1; r = num_rows-row-1; c = col;
00276                 h->elts[ m ][ r ][ c ] = gauss;
00277 
00278                 m = num_mats-mat-1; r = num_rows-row-1; c = num_cols-col-1;
00279                 h->elts[ m ][ r ][ c ] = gauss;
00280             }
00281         }
00282     }
00283 #endif
00284 
00285     return NULL;
00286 }
00287 
00310 Error* create_3d_gaussian_filter_d
00311 (
00312     Matblock_d** h_out, 
00313     double       mat_sigma,
00314     double       row_sigma,
00315     double       col_sigma,
00316     uint32_t     num_mats,
00317     uint32_t     num_rows,
00318     uint32_t     num_cols
00319 )
00320 {
00321     uint32_t    mat, row, col;
00322     uint32_t    m, r, c;
00323     double      x, y, z;
00324     double      x_gauss, y_gauss, z_gauss;
00325     double      gauss;
00326     Matblock_d* h;
00327 
00328     if (mat_sigma < 0.01 || row_sigma < 0.01 || col_sigma < 0.01)
00329     {
00330         return JWSC_EARG("Sigma for Gaussian is too small");
00331     }
00332 
00333     create_matblock_d(h_out, num_mats, num_rows, num_cols);
00334     h = *h_out;
00335 
00336 #if defined JWSC_HAVE_SLATEC || defined JWSC_HAVE_ERF
00337     for (mat = 0; mat < ceil(0.5*num_mats); mat++)
00338     {
00339         z       = (ceil(0.5*num_mats) - mat - 1);
00340         z_gauss = integrate_gaussian_pdf_d(0, mat_sigma, z, z+1);
00341         for (row = 0; row < ceil(0.5*num_rows); row++)
00342         {
00343             y       = (ceil(0.5*num_rows) - row - 1);
00344             y_gauss = integrate_gaussian_pdf_d(0, row_sigma, y, y+1);
00345             for (col = 0; col < ceil(0.5*num_cols); col++)
00346             {
00347                 x       = (ceil(0.5*num_cols) - col - 1);
00348                 x_gauss = integrate_gaussian_pdf_d(0, col_sigma, x, x+1);
00349                 gauss   = x_gauss*y_gauss*z_gauss;
00350 
00351                 m = mat; r = row; c = col;
00352                 h->elts[ m ][ r ][ c ] = gauss;
00353 
00354                 m = mat; r = row; c = num_cols-col-1;
00355                 h->elts[ m ][ r ][ c ] = gauss;
00356 
00357                 m = mat; r = num_rows-row-1; c = col;
00358                 h->elts[ m ][ r ][ c ] = gauss;
00359 
00360                 m = mat; r = num_rows-row-1; c = num_cols-col-1;
00361                 h->elts[ m ][ r ][ c ] = gauss;
00362 
00363                 m = num_mats-mat-1; r = row; c = col;
00364                 h->elts[ m ][ r ][ c ] = gauss;
00365 
00366                 m = num_mats-mat-1; r = row; c = num_cols-col-1;
00367                 h->elts[ m ][ r ][ c ] = gauss;
00368 
00369                 m = num_mats-mat-1; r = num_rows-row-1; c = col;
00370                 h->elts[ m ][ r ][ c ] = gauss;
00371 
00372                 m = num_mats-mat-1; r = num_rows-row-1; c = num_cols-col-1;
00373                 h->elts[ m ][ r ][ c ] = gauss;
00374             }
00375         }
00376     }
00377 #else
00378     for (mat = 0; mat < ceil(0.5*num_mats); mat++)
00379     {
00380         z       = (ceil(0.5*num_mats) - mat - 1);
00381         z_gauss = gaussian_pdf_d(0, row_sigma, z+0.5);
00382         for (row = 0; row < ceil(0.5*num_rows); row++)
00383         {
00384             y       = (ceil(0.5*num_rows) - row - 1);
00385             y_gauss = gaussian_pdf_d(0, row_sigma, y+0.5);
00386             for (col = 0; col < ceil(0.5*num_cols); col++)
00387             {
00388                 x       = (ceil(0.5*num_cols) - col - 1);
00389                 x_gauss = gaussian_pdf_d(0, col_sigma, x+0.5);
00390                 gauss   = x_gauss*y_gauss*z_gauss;
00391 
00392                 m = mat; r = row; c = col;
00393                 h->elts[ m ][ r ][ c ] = gauss;
00394 
00395                 m = mat; r = row; c = num_cols-col-1;
00396                 h->elts[ m ][ r ][ c ] = gauss;
00397 
00398                 m = mat; r = num_rows-row-1; c = col;
00399                 h->elts[ m ][ r ][ c ] = gauss;
00400 
00401                 m = mat; r = num_rows-row-1; c = num_cols-col-1;
00402                 h->elts[ m ][ r ][ c ] = gauss;
00403 
00404                 m = num_mats-mat-1; r = row; c = col;
00405                 h->elts[ m ][ r ][ c ] = gauss;
00406 
00407                 m = num_mats-mat-1; r = row; c = num_cols-col-1;
00408                 h->elts[ m ][ r ][ c ] = gauss;
00409 
00410                 m = num_mats-mat-1; r = num_rows-row-1; c = col;
00411                 h->elts[ m ][ r ][ c ] = gauss;
00412 
00413                 m = num_mats-mat-1; r = num_rows-row-1; c = num_cols-col-1;
00414                 h->elts[ m ][ r ][ c ] = gauss;
00415             }
00416         }
00417     }
00418 #endif
00419 
00420     return NULL;
00421 }
00422 
00453 Error* create_auto_3d_gaussian_dx_filter_f
00454 (
00455     Matblock_f** h_out, 
00456     float        mat_sigma,
00457     float        row_sigma,
00458     float        col_sigma
00459 )
00460 {
00461     uint32_t num_mats, num_rows, num_cols;
00462 
00463     if ((num_mats = ceil(sqrt(2) * 6.0 * mat_sigma)) % 2 == 0) num_mats++;
00464     if ((num_rows = ceil(sqrt(2) * 6.0 * row_sigma)) % 2 == 0) num_rows++;
00465     if ((num_cols = ceil(sqrt(2) * 6.0 * col_sigma)) % 2 == 0) num_cols++;
00466 
00467     return create_3d_gaussian_dx_filter_f(h_out, mat_sigma, row_sigma, 
00468             col_sigma, num_mats, num_rows, num_cols);
00469 }
00470 
00489 Error* create_auto_3d_gaussian_dx_filter_d
00490 (
00491     Matblock_d** h_out, 
00492     double       mat_sigma,
00493     double       row_sigma,
00494     double       col_sigma
00495 )
00496 {
00497     uint32_t num_mats, num_rows, num_cols;
00498 
00499     if ((num_mats = ceil(sqrt(2) * 6.0 * mat_sigma)) % 2 == 0) num_mats++;
00500     if ((num_rows = ceil(sqrt(2) * 6.0 * row_sigma)) % 2 == 0) num_rows++;
00501     if ((num_cols = ceil(sqrt(2) * 6.0 * col_sigma)) % 2 == 0) num_cols++;
00502 
00503     return create_3d_gaussian_dx_filter_d(h_out, mat_sigma, row_sigma, 
00504             col_sigma, num_mats, num_rows, num_cols);
00505 }
00506 
00538 Error* create_3d_gaussian_dx_filter_f
00539 (
00540     Matblock_f** h_out, 
00541     float        mat_sigma,
00542     float        row_sigma,
00543     float        col_sigma,
00544     uint32_t     num_mats,
00545     uint32_t     num_rows,
00546     uint32_t     num_cols
00547 )
00548 {
00549     int64_t mat, row, col;
00550     int64_t mats_center;
00551     int64_t rows_center;
00552     int64_t cols_center;
00553 
00554     float inv_mat_sigma_sqr;
00555     float inv_row_sigma_sqr;
00556     float inv_col_sigma_sqr;
00557     float gauss_val;
00558     float val;
00559 
00560     Matblock_f* h;
00561 
00562     if (mat_sigma < 0.01 || row_sigma < 0.01 || col_sigma < 0.01)
00563     {
00564         return JWSC_EARG("Sigma for Gaussian is too small");
00565     }
00566 
00567     create_matblock_f(h_out, num_mats, num_rows, num_cols);
00568     h = *h_out;
00569 
00570     mats_center       = num_mats / 2;
00571     rows_center       = num_rows / 2;
00572     cols_center       = num_cols / 2;
00573     inv_mat_sigma_sqr = 1.0 / (mat_sigma*mat_sigma);
00574     inv_row_sigma_sqr = 1.0 / (row_sigma*row_sigma);
00575     inv_col_sigma_sqr = 1.0 / (col_sigma*col_sigma);
00576 
00577     for (mat = 0; mat < num_mats; mat++)
00578     {
00579         for (row = 0; row < num_rows; row++)
00580         {
00581             for (col = 0; col < num_cols; col++)
00582             {
00583                 val = (mat-mats_center)*(mat-mats_center)*inv_mat_sigma_sqr +
00584                       (row-rows_center)*(row-rows_center)*inv_row_sigma_sqr + 
00585                       (col-cols_center)*(col-cols_center)*inv_col_sigma_sqr;
00586                 gauss_val = -1*(col - cols_center)*exp(-0.5 * val);
00587                 h->elts[ mat ][ row ][ col ] = gauss_val;
00588             }
00589         }
00590     }
00591 
00592     val = (inv_mat_sigma_sqr*inv_row_sigma_sqr*inv_col_sigma_sqr) / (2 * PI);
00593     multiply_matblock_by_scalar_f(h_out, h, val);
00594 
00595     return NULL;
00596 }
00597 
00617 Error* create_3d_gaussian_dx_filter_d
00618 (
00619     Matblock_d** h_out, 
00620     double       mat_sigma,
00621     double       row_sigma,
00622     double       col_sigma,
00623     uint32_t     num_mats,
00624     uint32_t     num_rows,
00625     uint32_t     num_cols
00626 )
00627 {
00628     int64_t mat, row, col;
00629     int64_t mats_center;
00630     int64_t rows_center;
00631     int64_t cols_center;
00632 
00633     double inv_mat_sigma_sqr;
00634     double inv_row_sigma_sqr;
00635     double inv_col_sigma_sqr;
00636     double gauss_val;
00637     double val;
00638 
00639     Matblock_d* h;
00640 
00641     if (mat_sigma < 0.01 || row_sigma < 0.01 || col_sigma < 0.01)
00642     {
00643         return JWSC_EARG("Sigma for Gaussian is too small");
00644     }
00645 
00646     create_matblock_d(h_out, num_mats, num_rows, num_cols);
00647     h = *h_out;
00648 
00649     mats_center       = num_mats / 2;
00650     rows_center       = num_rows / 2;
00651     cols_center       = num_cols / 2;
00652     inv_mat_sigma_sqr = 1.0 / (mat_sigma*mat_sigma);
00653     inv_row_sigma_sqr = 1.0 / (row_sigma*row_sigma);
00654     inv_col_sigma_sqr = 1.0 / (col_sigma*col_sigma);
00655 
00656     for (mat = 0; mat < num_mats; mat++)
00657     {
00658         for (row = 0; row < num_rows; row++)
00659         {
00660             for (col = 0; col < num_cols; col++)
00661             {
00662                 val = (mat-mats_center)*(mat-mats_center)*inv_mat_sigma_sqr +
00663                       (row-rows_center)*(row-rows_center)*inv_row_sigma_sqr + 
00664                       (col-cols_center)*(col-cols_center)*inv_col_sigma_sqr;
00665                 gauss_val = -1*(col - cols_center)*exp(-0.5 * val);
00666                 h->elts[ mat ][ row ][ col ] = gauss_val;
00667             }
00668         }
00669     }
00670 
00671     val = (inv_mat_sigma_sqr*inv_row_sigma_sqr*inv_col_sigma_sqr) / (2 * PI);
00672     multiply_matblock_by_scalar_d(h_out, h, val);
00673 
00674     return NULL;
00675 }
00676 
00707 Error* create_auto_3d_gaussian_dy_filter_f
00708 (
00709     Matblock_f** h_out, 
00710     float        mat_sigma,
00711     float        row_sigma,
00712     float        col_sigma
00713 )
00714 {
00715     uint32_t num_mats, num_rows, num_cols;
00716 
00717     if ((num_mats = ceil(sqrt(2) * 6.0 * mat_sigma)) % 2 == 0) num_mats++;
00718     if ((num_rows = ceil(sqrt(2) * 6.0 * row_sigma)) % 2 == 0) num_rows++;
00719     if ((num_cols = ceil(sqrt(2) * 6.0 * col_sigma)) % 2 == 0) num_cols++;
00720 
00721     return create_3d_gaussian_dy_filter_f(h_out, mat_sigma, row_sigma, 
00722             col_sigma, num_mats, num_rows, num_cols);
00723 }
00724 
00742 Error* create_auto_3d_gaussian_dy_filter_d
00743 (
00744     Matblock_d** h_out, 
00745     double       mat_sigma,
00746     double       row_sigma,
00747     double       col_sigma
00748 )
00749 {
00750     uint32_t num_mats, num_rows, num_cols;
00751 
00752     if ((num_mats = ceil(sqrt(2) * 6.0 * mat_sigma)) % 2 == 0) num_mats++;
00753     if ((num_rows = ceil(sqrt(2) * 6.0 * row_sigma)) % 2 == 0) num_rows++;
00754     if ((num_cols = ceil(sqrt(2) * 6.0 * col_sigma)) % 2 == 0) num_cols++;
00755 
00756     return create_3d_gaussian_dy_filter_d(h_out, mat_sigma, row_sigma, 
00757             col_sigma, num_mats, num_rows, num_cols);
00758 }
00759 
00791 Error* create_3d_gaussian_dy_filter_f
00792 (
00793     Matblock_f** h_out, 
00794     float        mat_sigma,
00795     float        row_sigma,
00796     float        col_sigma,
00797     uint32_t     num_mats,
00798     uint32_t     num_rows,
00799     uint32_t     num_cols
00800 )
00801 {
00802     int64_t mat, row, col;
00803     int64_t mats_center;
00804     int64_t rows_center;
00805     int64_t cols_center;
00806 
00807     float inv_mat_sigma_sqr;
00808     float inv_row_sigma_sqr;
00809     float inv_col_sigma_sqr;
00810     float gauss_val;
00811     float val;
00812 
00813     Matblock_f* h;
00814 
00815     if (mat_sigma < 0.01 || row_sigma < 0.01 || col_sigma < 0.01)
00816     {
00817         return JWSC_EARG("Sigma for Gaussian is too small");
00818     }
00819 
00820     create_matblock_f(h_out, num_mats, num_rows, num_cols);
00821     h = *h_out;
00822 
00823     mats_center       = num_mats / 2;
00824     rows_center       = num_rows / 2;
00825     cols_center       = num_cols / 2;
00826     inv_mat_sigma_sqr = 1.0 / (mat_sigma*mat_sigma);
00827     inv_row_sigma_sqr = 1.0 / (row_sigma*row_sigma);
00828     inv_col_sigma_sqr = 1.0 / (col_sigma*col_sigma);
00829 
00830     for (mat = 0; mat < num_mats; mat++)
00831     {
00832         for (row = 0; row < num_rows; row++)
00833         {
00834             for (col = 0; col < num_cols; col++)
00835             {
00836                 val = (mat-mats_center)*(mat-mats_center)*inv_mat_sigma_sqr +
00837                       (row-rows_center)*(row-rows_center)*inv_row_sigma_sqr + 
00838                       (col-cols_center)*(col-cols_center)*inv_col_sigma_sqr;
00839                 gauss_val = -1*(row - rows_center)*exp(-0.5 * val);
00840                 h->elts[ mat ][ row ][ col ] = gauss_val;
00841             }
00842         }
00843     }
00844 
00845     val = (inv_mat_sigma_sqr*inv_row_sigma_sqr*inv_col_sigma_sqr) / (2 * PI);
00846     multiply_matblock_by_scalar_f(h_out, h, val);
00847 
00848     return NULL;
00849 }
00850 
00870 Error* create_3d_gaussian_dy_filter_d
00871 (
00872     Matblock_d** h_out, 
00873     double       mat_sigma,
00874     double       row_sigma,
00875     double       col_sigma,
00876     uint32_t     num_mats,
00877     uint32_t     num_rows,
00878     uint32_t     num_cols
00879 )
00880 {
00881     int64_t mat, row, col;
00882     int64_t mats_center;
00883     int64_t rows_center;
00884     int64_t cols_center;
00885 
00886     double inv_mat_sigma_sqr;
00887     double inv_row_sigma_sqr;
00888     double inv_col_sigma_sqr;
00889     double gauss_val;
00890     double val;
00891 
00892     Matblock_d* h;
00893 
00894     if (mat_sigma < 0.01 || row_sigma < 0.01 || col_sigma < 0.01)
00895     {
00896         return JWSC_EARG("Sigma for Gaussian is too small");
00897     }
00898 
00899     create_matblock_d(h_out, num_mats, num_rows, num_cols);
00900     h = *h_out;
00901 
00902     mats_center       = num_mats / 2;
00903     rows_center       = num_rows / 2;
00904     cols_center       = num_cols / 2;
00905     inv_mat_sigma_sqr = 1.0 / (mat_sigma*mat_sigma);
00906     inv_row_sigma_sqr = 1.0 / (row_sigma*row_sigma);
00907     inv_col_sigma_sqr = 1.0 / (col_sigma*col_sigma);
00908 
00909     for (mat = 0; mat < num_mats; mat++)
00910     {
00911         for (row = 0; row < num_rows; row++)
00912         {
00913             for (col = 0; col < num_cols; col++)
00914             {
00915                 val = (mat-mats_center)*(mat-mats_center)*inv_mat_sigma_sqr +
00916                       (row-rows_center)*(row-rows_center)*inv_row_sigma_sqr + 
00917                       (col-cols_center)*(col-cols_center)*inv_col_sigma_sqr;
00918                 gauss_val = -1*(row - rows_center)*exp(-0.5 * val);
00919                 h->elts[ mat ][ row ][ col ] = gauss_val;
00920             }
00921         }
00922     }
00923 
00924     val = (inv_mat_sigma_sqr*inv_row_sigma_sqr*inv_col_sigma_sqr) / (2 * PI);
00925     multiply_matblock_by_scalar_d(h_out, h, val);
00926 
00927     return NULL;
00928 }
00929 
00960 Error* create_auto_3d_gaussian_dz_filter_f
00961 (
00962     Matblock_f** h_out, 
00963     float        mat_sigma,
00964     float        row_sigma,
00965     float        col_sigma
00966 )
00967 {
00968     uint32_t num_mats, num_rows, num_cols;
00969 
00970     if ((num_mats = ceil(sqrt(2) * 6.0 * mat_sigma)) % 2 == 0) num_mats++;
00971     if ((num_rows = ceil(sqrt(2) * 6.0 * row_sigma)) % 2 == 0) num_rows++;
00972     if ((num_cols = ceil(sqrt(2) * 6.0 * col_sigma)) % 2 == 0) num_cols++;
00973 
00974     return create_3d_gaussian_dz_filter_f(h_out, mat_sigma, row_sigma, 
00975             col_sigma, num_mats, num_rows, num_cols);
00976 }
00977 
00995 Error* create_auto_3d_gaussian_dz_filter_d
00996 (
00997     Matblock_d** h_out, 
00998     double       mat_sigma,
00999     double       row_sigma,
01000     double       col_sigma
01001 )
01002 {
01003     uint32_t num_mats, num_rows, num_cols;
01004 
01005     if ((num_mats = ceil(sqrt(2) * 6.0 * mat_sigma)) % 2 == 0) num_mats++;
01006     if ((num_rows = ceil(sqrt(2) * 6.0 * row_sigma)) % 2 == 0) num_rows++;
01007     if ((num_cols = ceil(sqrt(2) * 6.0 * col_sigma)) % 2 == 0) num_cols++;
01008 
01009     return create_3d_gaussian_dz_filter_d(h_out, mat_sigma, row_sigma, 
01010             col_sigma, num_mats, num_rows, num_cols);
01011 }
01012 
01044 Error* create_3d_gaussian_dz_filter_f
01045 (
01046     Matblock_f** h_out, 
01047     double       mat_sigma,
01048     double       row_sigma,
01049     double       col_sigma,
01050     uint32_t     num_mats,
01051     uint32_t     num_rows,
01052     uint32_t     num_cols
01053 )
01054 {
01055     int64_t mat, row, col;
01056     int64_t mats_center;
01057     int64_t rows_center;
01058     int64_t cols_center;
01059 
01060     float inv_mat_sigma_sqr;
01061     float inv_row_sigma_sqr;
01062     float inv_col_sigma_sqr;
01063     float gauss_val;
01064     float val;
01065 
01066     Matblock_f* h;
01067 
01068     if (mat_sigma < 0.01 || row_sigma < 0.01 || col_sigma < 0.01)
01069     {
01070         return JWSC_EARG("Sigma for Gaussian is too small");
01071     }
01072 
01073     create_matblock_f(h_out, num_mats, num_rows, num_cols);
01074     h = *h_out;
01075 
01076     mats_center       = num_mats / 2;
01077     rows_center       = num_rows / 2;
01078     cols_center       = num_cols / 2;
01079     inv_mat_sigma_sqr = 1.0 / (mat_sigma*mat_sigma);
01080     inv_row_sigma_sqr = 1.0 / (row_sigma*row_sigma);
01081     inv_col_sigma_sqr = 1.0 / (col_sigma*col_sigma);
01082 
01083     for (mat = 0; mat < num_mats; mat++)
01084     {
01085         for (row = 0; row < num_rows; row++)
01086         {
01087             for (col = 0; col < num_cols; col++)
01088             {
01089                 val = (mat-mats_center)*(mat-mats_center)*inv_mat_sigma_sqr +
01090                       (row-rows_center)*(row-rows_center)*inv_row_sigma_sqr + 
01091                       (col-cols_center)*(col-cols_center)*inv_col_sigma_sqr;
01092                 gauss_val = -1*(mat - mats_center)*exp(-0.5 * val);
01093                 h->elts[ mat ][ row ][ col ] = gauss_val;
01094             }
01095         }
01096     }
01097 
01098     val = (inv_mat_sigma_sqr*inv_row_sigma_sqr*inv_col_sigma_sqr) / (2 * PI);
01099     multiply_matblock_by_scalar_f(h_out, h, val);
01100 
01101     return NULL;
01102 }
01103 
01123 Error* create_3d_gaussian_dz_filter_d
01124 (
01125     Matblock_d** h_out, 
01126     double       mat_sigma,
01127     double       row_sigma,
01128     double       col_sigma,
01129     uint32_t     num_mats,
01130     uint32_t     num_rows,
01131     uint32_t     num_cols
01132 )
01133 {
01134     int64_t mat, row, col;
01135     int64_t mats_center;
01136     int64_t rows_center;
01137     int64_t cols_center;
01138 
01139     double inv_mat_sigma_sqr;
01140     double inv_row_sigma_sqr;
01141     double inv_col_sigma_sqr;
01142     double gauss_val;
01143     double val;
01144 
01145     Matblock_d* h;
01146 
01147     if (mat_sigma < 0.01 || row_sigma < 0.01 || col_sigma < 0.01)
01148     {
01149         return JWSC_EARG("Sigma for Gaussian is too small");
01150     }
01151 
01152     create_matblock_d(h_out, num_mats, num_rows, num_cols);
01153     h = *h_out;
01154 
01155     mats_center       = num_mats / 2;
01156     rows_center       = num_rows / 2;
01157     cols_center       = num_cols / 2;
01158     inv_mat_sigma_sqr = 1.0 / (mat_sigma*mat_sigma);
01159     inv_row_sigma_sqr = 1.0 / (row_sigma*row_sigma);
01160     inv_col_sigma_sqr = 1.0 / (col_sigma*col_sigma);
01161 
01162     for (mat = 0; mat < num_mats; mat++)
01163     {
01164         for (row = 0; row < num_rows; row++)
01165         {
01166             for (col = 0; col < num_cols; col++)
01167             {
01168                 val = (mat-mats_center)*(mat-mats_center)*inv_mat_sigma_sqr +
01169                       (row-rows_center)*(row-rows_center)*inv_row_sigma_sqr + 
01170                       (col-cols_center)*(col-cols_center)*inv_col_sigma_sqr;
01171                 gauss_val = -1*(mat - mats_center)*exp(-0.5 * val);
01172                 h->elts[ mat ][ row ][ col ] = gauss_val;
01173             }
01174         }
01175     }
01176 
01177     val = (inv_mat_sigma_sqr*inv_row_sigma_sqr*inv_col_sigma_sqr) / (2 * PI);
01178     multiply_matblock_by_scalar_d(h_out, h, val);
01179 
01180     return NULL;
01181 }
01182