libftsh
A Fast Transform for Spherical Harmonics
 All Data Structures Files Functions Variables Defines
libftsh.h
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2000, 2012 Martin J. Mohlenkamp
00003  *
00004  * This program is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017  *
00018  */
00019 
00020 
00027 /* make sure we haven't already included this library **/
00028 #ifndef LIBFTSH_PRESENT
00029 #define LIBFTSH_PRESENT
00030 
00031 
00032 #include <math.h>
00033 #include <stdlib.h>
00034 #include <stdio.h>
00035 #include <assert.h>
00036 #include <string.h>
00037 #include <time.h>
00038 
00039 
00040 #ifndef PI
00041 #define PI 3.14159265358979323846264338328
00042 #endif
00043  
00048 #ifndef USE_double
00049 #define USE_double 1
00050 #endif
00051 
00053 #if USE_double
00054 #define REAL double
00055 #else
00056 #define REAL float
00057 #endif
00058 
00059 /* Deal with possible ways fftw was compiled */
00060 #if 0
00061 
00062 #if USE_double
00063   /* double precision header */
00064 #include "dfftw.h"
00065 #include "drfftw.h"
00066 #else
00067   /* single precision header */
00068 #include "sfftw.h"
00069 #include "srfftw.h"
00070 #endif
00071 #else /*fftw in only one precision. pray it is the right precision */
00072 /*  Make sure it is compiled with fftw_real == REAL */
00073 #include "fftw.h"
00074 #include "rfftw.h"
00075 #endif
00076 
00077 /*************************************************************************/
00078 /**** data structures ****************************************************/
00079 /*************************************************************************/
00080 
00081 
00095 typedef struct{
00097   int numpts;
00099   fftw_complex *complex_work;
00101   fftw_plan w_plan;
00103   rfftw_plan rw_plan_forward;
00105   rfftw_plan rw_plan_reverse;
00107   REAL *trig_save; 
00108 }Ftrigtw_Plan; 
00109 
00112 typedef struct 
00113 {
00119   int max_size;
00121   int n_row;
00123   int n_col;
00127   REAL *matrix;
00128 } Dense_Matrix;
00129 
00135 typedef struct 
00136 {
00142   int max_size;
00146   int n_row;
00148   REAL *vector;
00149 } Dense_Vector;
00150 
00162 typedef struct 
00163 {
00169   int max_size;
00173   int max_rows;
00177   int max_bands;
00179   int n_row;
00181   int n_col;
00183   int non_zero;
00193   int *band_p;
00204   int *band_list;
00206   REAL *matrix;
00207 } Banded_Matrix;
00208 
00224 typedef struct{
00226   unsigned int max_size; 
00228   int *int_work;
00230   REAL *real_work;
00231 } Bdmat_Op_Workspace;
00232 
00241 typedef struct{
00245   int best_level; 
00247   int num_levels;
00256   unsigned short int **branching;
00258   unsigned int **cost_full;
00263   unsigned int **cost_asym;
00267   unsigned int *order_level;
00272   unsigned int *order_within;
00273 }Dyadic_Gsearch_Save;
00274 
00286 typedef struct{
00288   int bell_length;
00302   int *bell_offsets;
00304   REAL *bell_handle;
00305 }Fast1_Save;
00306 
00317 typedef struct{
00321   int numpts;
00323   int left_extra;
00325   int right_extra;
00330   int fcn_offset;
00336   int coef_offset;
00340   REAL *bell;
00346   REAL *dualbell;
00355   int which_transform;
00359   Ftrigtw_Plan transform_plan;
00360 }Local_Trig_Interval;
00361 
00367 typedef struct{
00373   int max_intervals;
00375   int n_interval[2];
00378   Banded_Matrix matrix[2];
00382   Local_Trig_Interval *ilist[2];
00383 }Pm_1D;
00384 
00391 typedef struct{
00396   Banded_Matrix matrix[2];
00397 }Pm_Direct_bd;
00398 
00403 typedef struct{
00407   Dense_Matrix matrix[2];
00408 }Pm_Direct_d;
00409 
00422 typedef struct{
00425   int numpts;
00428   int band_limit;
00431   Dense_Vector dvect_coef[2];
00433   Dense_Vector dvect_fcn[2];
00435   REAL *eval_fcn[2];
00437   REAL *over_rootsin;
00439   REAL *mod_weight;
00440 }Pm_1D_Workspace;
00441 
00442 
00445 typedef struct{
00450   int numpts;
00454   REAL **sofar;
00458   int *size;
00461   REAL *ex;
00464   REAL *why;
00465 }Pmncos_Recurrence_Save;
00466 
00467 /*************************************************************************/
00468 /******* END Data Structures *********************************************/
00469 /*************************************************************************/
00470 
00471 
00472 /*************************************************************************/
00473 /******* BEGIN function prototypes ***************************************/
00474 /*************************************************************************/
00475 
00476 /* dvect.c */
00477 Dense_Vector init_dvect_memory(unsigned  int n
00478                                );
00479 void give_dvect_memory(Dense_Vector *current,
00480                        Dense_Vector *previous
00481                        );
00482 /* dmat.c */
00483 Dense_Matrix init_dmat_memory(unsigned  int n
00484                                );
00485 void give_dmat_memory(Dense_Matrix *current,
00486                        Dense_Matrix *previous
00487                        );
00488 void free_dmat_memory(Dense_Matrix *in
00489                       );
00490 void dump_bin_dmat(Dense_Matrix *x,
00491                    FILE *out
00492                    );
00493 void load_bin_dmat(Dense_Matrix *x,
00494                    FILE *in
00495                    );
00496 /* dmat_ops.c */
00497 void dmat_dvect_multiply(Dense_Vector *out,
00498                          Dense_Matrix *inmat,
00499                          Dense_Vector *invect
00500                          );
00501 void dmat_t_dvect_multiply(Dense_Vector *out,
00502                            Dense_Matrix *inmat,
00503                            Dense_Vector *invect
00504                            );
00505 /* bdmat.c */
00506 Banded_Matrix init_bdmat_memory(int max_size,
00507                                 int max_rows,
00508                                 int max_bands
00509                                 );
00510 void give_bdmat_memory(Banded_Matrix *current,
00511                        Banded_Matrix *previous
00512                        );
00513 void free_bdmat_memory(Banded_Matrix *in
00514                        );
00515 void bdmat_copy(Banded_Matrix *out,
00516                 Banded_Matrix *in
00517                 );
00518 void dump_bin_bdmat(Banded_Matrix *x,
00519                     FILE *out
00520                     );
00521 void load_bin_bdmat(Banded_Matrix *x,
00522                     FILE *in
00523                     );
00524 /* bdmat_ops.c */
00525 void bdmat_dvect_multiply(Dense_Vector *out,
00526                           Banded_Matrix *inmat,
00527                           Dense_Vector *invect
00528                           );
00529 void bdmat_t_dvect_multiply(Dense_Vector *out,
00530                             Banded_Matrix *inmat,
00531                             Dense_Vector *invect
00532                             );
00533 void dmat_to_bdmat(Banded_Matrix *out,
00534                    Dense_Matrix *in,
00535                    REAL cutoff,
00536                    int min_gap
00537                    );
00538 /* dyadic_gsearch.c */
00539 int dyadic_gsearch(Dyadic_Gsearch_Save *dy_gs_save
00540                    );
00541 void dyadic_gsearch_init(Dyadic_Gsearch_Save *dy_gs_save,
00542                          int num_levels
00543                          );
00544 void dyadic_gsearch_free(Dyadic_Gsearch_Save *dy_gs_save
00545                          );
00546 /* fast1_fromfile.c*/
00547 void fast1_fromfile(int *numpts_ptr,
00548                     int *band_limit_ptr,
00549                     REAL **node_ptr,
00550                     REAL **weight_ptr,
00551                     Pm_1D **pmn_matrix_ptr,
00552                     Pm_1D_Workspace *pmnwork,
00553                     FILE *fp
00554                     );
00555 void load_fast1(int *numpts_ptr,
00556                 int *band_limit_ptr,
00557                 int *num_levels_ptr,
00558                 REAL **node_ptr,
00559                 REAL **weight_ptr,
00560                 Fast1_Save *saves_fordump,
00561                 Pm_1D **pmn_matrix_ptr,
00562                 FILE *fp
00563                 );
00564 /* direct1_fromfile.c*/
00565 void direct1_fromfile(int *numpts_ptr,
00566                       int *band_limit_ptr,
00567                       REAL **node_ptr,
00568                       REAL **weight_ptr,
00569                       Pm_Direct_d **pmn_matrix_ptr,
00570                       Pm_1D_Workspace *pmnwork,
00571                       FILE *fp
00572                       );
00573 void load_direct1(int *numpts_ptr,
00574                   int *band_limit_ptr,
00575                   REAL **node_ptr,
00576                   REAL **weight_ptr,
00577                   Pm_Direct_d **pmn_matrix_ptr,
00578                   FILE *fp
00579                   );
00580 /* dctw.c */
00581 void dctw(REAL *fcn,
00582           Ftrigtw_Plan *main_plan,
00583           int dir
00584           );
00585 void dctw_init(Ftrigtw_Plan *main_plan,
00586                int flags,
00587                int numpts
00588                );
00589 void rfftw_to_NR_format(REAL *data_nr,
00590                         REAL *data_rfftw,
00591                         int numpts,
00592                         int dir
00593                         );
00594 /* lctw.c */
00595 void lctw(REAL *fcn,
00596           Ftrigtw_Plan *main_plan
00597           );
00598 void lctw_init(Ftrigtw_Plan *main_plan,
00599                int flags,
00600                int numpts
00601                );
00602 /* bell_utils.c */
00603 REAL dualabell(REAL (*origbell) (int,int),
00604                  int laplength,
00605                  int t
00606                  );
00607 void bell_1size_init(REAL *bellout,
00608                      REAL (*whichbell) (int,int),
00609                      int lapleft,
00610                      int center,
00611                      int lapright,
00612                      int dual_flag
00613                      );
00614 void fold_e_e_1s(REAL *coef,
00615                  REAL *fcn,
00616                  int numpts,
00617                  REAL *left,
00618                  int n_left,
00619                  REAL *right,
00620                  int n_right,
00621                  REAL *bell,
00622                  int dir
00623                  );
00624 void fold_e_o_1s(REAL *coef,
00625                  REAL *fcn,
00626                  int numpts,
00627                  REAL *left,
00628                  int n_left,
00629                  REAL *right,
00630                  int n_right,
00631                  REAL *bell,
00632                  int dir
00633                  );
00634 /* Pmn_construct.c */
00635 REAL Pmncos(int order,
00636             int index,
00637             REAL phi
00638             );
00639 void Pmncos_resave_init(Pmncos_Recurrence_Save *pmn_save,
00640                         REAL *node,
00641                         int numpts
00642                         );
00643 void next_rtsinPmncos(REAL *outfcn,
00644                       Pmncos_Recurrence_Save *pmn_save,
00645                       int halfpts,
00646                       int order,
00647                       int index
00648                       );
00649 void Pmncos_resave_destroy(Pmncos_Recurrence_Save *pmn_save
00650                            );
00651 /* direct1_tofile.c */
00652 void direct1_tofile(int  numpts,
00653                     int band_limit,
00654                     REAL *node,
00655                     REAL *weight,
00656                     FILE *fp
00657                     );
00658 void init_direct1(Pm_Direct_d **out,
00659                   int halfpts,
00660                   int band_limit,
00661                   REAL *node
00662                   );
00663 void dump_direct1(int numpts,
00664                   int band_limit,
00665                   REAL *node,
00666                   REAL *weight,
00667                   Pm_Direct_d *pmn_matrix,
00668                   FILE *fp
00669                   );
00670 /* fast1_tofile.c */
00671 REAL fast1_tofile(int  numpts,
00672                   int band_limit,
00673                   REAL *node,
00674                   REAL *weight,
00675                   REAL epsilon,
00676                   FILE *fp
00677                   );
00678 void init_fast1(Pm_1D **out,
00679                 Fast1_Save *saves_fordump,
00680                 int halfpts,
00681                 int band_limit,
00682                 REAL *node,
00683                 int *numlevels,
00684                 REAL epsilon,
00685                 REAL (*bell_choice) (int,int)
00686                 );
00687 void dump_fast1(int numpts,
00688                 int band_limit,
00689                 int num_levels,
00690                 REAL *node,
00691                 REAL *weight,
00692                 Fast1_Save *saves_fordump,
00693                 Pm_1D *pmn_matrix,
00694                 FILE *fp
00695                 );
00696 /* direct1_transform.c */
00697 void Pm_direct1_analyse(REAL *outcoef,
00698                         Pm_Direct_d *inmat,
00699                         REAL *infcn,
00700                         Pm_1D_Workspace *pmnwork
00701                         );
00702 void Pm_direct1_synthesize(REAL *outfcn,
00703                            Pm_Direct_d *inmat,
00704                            REAL *incoef,
00705                            Pm_1D_Workspace *pmnwork
00706                            );
00707 /* matbells.c  */
00708 REAL bellmat1(int laplength,
00709                 int t
00710                 );
00711 REAL bellmat2(int laplength,
00712                 int t
00713                 );
00714 REAL bellmat3(int laplength,
00715                 int t
00716                 );
00717 REAL bellmat4(int laplength,
00718                 int t
00719                 );
00720 REAL bellmat5(int laplength,
00721                 int t
00722                 );
00723 REAL bellmat6(int laplength,
00724                 int t
00725                 );
00726 REAL bellmat7(int laplength,
00727                 int t
00728                 );
00729 REAL bellmat8(int laplength,
00730                 int t
00731                 );
00732 REAL bellmat9(int laplength,
00733                 int t
00734                 );
00735 REAL bellmat10(int laplength,
00736                 int t
00737                 );
00738 REAL bellmat11(int laplength,
00739                 int t
00740                 );
00741 REAL bellmat12(int laplength,
00742                 int t
00743                 );
00744 REAL bellmat13(int laplength,
00745                 int t
00746                 );
00747 REAL bellmat14(int laplength,
00748                 int t
00749                 );
00750 REAL bellmat15(int laplength,
00751                 int t
00752                 );
00753 REAL bellmat16(int laplength,
00754                 int t
00755                 );
00756 REAL bellmat17(int laplength,
00757                 int t
00758                 );
00759 REAL bellmat18(int laplength,
00760                 int t
00761                 );
00762 REAL bellmat19(int laplength,
00763                 int t
00764                 );
00765 REAL bellmat20(int laplength,
00766                 int t
00767                 );
00768 /* fast1_transform.c */
00769 void Pm_1d_analyse(REAL *outcoef,
00770                    Pm_1D *inmat,
00771                    REAL *infcn,
00772                    Pm_1D_Workspace *pmnwork
00773                    );
00774 void Pm_1d_synthesize(REAL *outfcn,
00775                       Pm_1D *inmat,
00776                       REAL *incoef,
00777                       Pm_1D_Workspace *pmnwork
00778                       );
00779 /* mk_gnode_gweight.c */
00780 void mk_gnode_gweight(REAL *gnode,
00781                       REAL *gweight,
00782                       REAL epsilon,
00783                       int numpts
00784                       );
00785 void mk_cosi_gnode(REAL *gnode,
00786                    REAL epsilon,
00787                    int numpts
00788                    );
00789 void cosi_gnode_to_gweight(REAL *gweight,
00790                            REAL *gnode,
00791                            int numpts
00792                            );
00793 /* second.c */
00794 double second();
00795 /* getoption.c */
00796 char* getoption(const char* flag,
00797                 int argc,
00798                 char **argv
00799                 );
00800 /* pointwise_ops.c */
00801 void pointwise_multiply(REAL *out,
00802                         REAL *in_1,
00803                         REAL *in_2,
00804                         int numpts
00805                         );
00806 void reflect_evenodd(REAL *even,
00807                      REAL *odd,
00808                      REAL *whole,
00809                      int numpts,
00810                      int dir
00811                      );
00812 void remove_rootsin(REAL *out,
00813                     REAL *in,
00814                     REAL *node,
00815                     int numpts
00816                     );
00817 /* dyadic_trig_gsearch.c */
00818 void dyadic_g_ilist_init(Local_Trig_Interval *ilist[2],
00819                          int *ints_used,
00820                          int *coefs_used,
00821                          REAL **bell_handle,
00822                          int *bell_length,
00823                          int **bell_offsets,
00824                          int halfpts,
00825                          int num_levels,
00826                          REAL (*bell_choice) (int,int),
00827                          int flags
00828                          );
00829 void ltrigint_init(Local_Trig_Interval *out,
00830                    int numpts,
00831                    int left_extra,
00832                    int right_extra,
00833                    int fcn_offset,
00834                    int coef_offset,
00835                    REAL (*bell_choice)(int,int),
00836                    int which_transform,
00837                    int fftw_flags
00838                    );
00839 void gsearch_to_ilist(Local_Trig_Interval *ilist_out,
00840                       int *intervals_kept,
00841                       int max_intervals,
00842                       Local_Trig_Interval *ilist_in,
00843                       Dyadic_Gsearch_Save *dy_gs_save,
00844                       int halfpts
00845                       );
00846 /* trig_int_ops.c */
00847 void evaluate_intlist(REAL *outfcn,
00848                       REAL *incoef,
00849                       Local_Trig_Interval *interval_list,
00850                       int num_intervals
00851                       );
00852 void expand_d_intlist(REAL *outcoef,
00853                       REAL *infcn,
00854                       Local_Trig_Interval *interval_list,
00855                       int num_intervals
00856                       );
00857 void expand_intlist(REAL *outcoef,
00858                    REAL *infcn,
00859                    Local_Trig_Interval *interval_list,
00860                    int num_intervals
00861                    );
00862 /* count_thresh.c */
00863 int count_thresh(REAL *lambda,
00864                  int howmany,
00865                  REAL thresh
00866                  );
00867 /* init_Pm_1d_workspace */
00868 void init_Pm_1d_workspace(Pm_1D_Workspace *out,
00869                           int numpts,
00870                           int band_limit,
00871                           REAL *node,
00872                           REAL *weight
00873                           );
00874 
00875 /* */
00876 void ftgaqd(int *nlat,
00877             REAL *theta,
00878             REAL *wts,
00879             REAL *work,
00880             int *lwork,
00881             int *ierror
00882             );
00883 void gnode_to_Pmninit(REAL ***sofar,
00884                       REAL **ex,
00885                       REAL **why,
00886                       int **size,
00887                       REAL *gnode,
00888                       int hemipts
00889                       );
00890 
00891 /*************************************************************************/
00892 /******* END function prototypes *****************************************/
00893 /*************************************************************************/
00894 
00895 #endif /* LIBFTSH_PRESENT */