S2kit  1.1
Toolkit for working with functions defined on the sphere
seminaive.c
Go to the documentation of this file.
1 
10 #include "s2kit/seminaive.h"
11 
12 #include <math.h>
13 #include <stdio.h>
14 #include <string.h>
15 
16 #include <fftw3.h>
17 
18 #include "s2kit/cospml.h"
19 
56 void InvDLTSemi(double* coeffs, const int bw, const int m, double* result, double* trans_cos_pml_table,
57  double* sin_values, double* workspace, fftw_plan* plan) {
58  int size = 2 * bw;
59 
60  // for paranoia, zero out arrays
61  memset(workspace, 0, sizeof(double) * size);
62  memset(result, 0, sizeof(double) * size);
63 
64  double* fcos = workspace;
65  double* trans_tableptr = trans_cos_pml_table;
66 
67  double coeff = 0.5 / sqrt(bw);
68  /*
69  main loop - compute each value of fcos
70 
71  Note that all zeroes have been stripped out of the
72  `trans_cos_pml_table`, so indexing is somewhat complicated.
73  */
74  for (int i = 0; i < bw; ++i) {
75  if (i == (bw - 1) && m % 2) {
76  fcos[bw - 1] = 0.0;
77  break;
78  }
79 
80  double* assoc_offset;
81  if (i > m)
82  assoc_offset = coeffs + (i - m) + (m % 2);
83  else
84  assoc_offset = coeffs + (i % 2);
85 
86  int rowsize = Transpose_RowSize(i, m, bw);
87 
88  double value = 0.;
89  for (int j = 0; j < rowsize; ++j)
90  value += assoc_offset[2 * j] * trans_tableptr[j];
91 
92  fcos[i] = value * coeff; // scale coefficients prior to taking inverse DCT
93 
94  trans_tableptr += rowsize;
95  }
96 
97  // special coeff for the first one
98  fcos[0] /= (sqrt(size) * coeff);
99 
100  /*
101  now we have the cosine series for the result,
102  so now evaluate the cosine series at `2*bw` Chebyshev nodes
103  */
104 
105  // take the inverse dct
106  // Note that I am using the guru interface
107  fftw_execute_r2r(*plan, fcos, result);
108 
109  if (!(m % 2))
110  return;
111 
112  // if m is odd, then need to multiply by sin(x) at Chebyshev nodes
113  for (int i = 0; i < size; ++i)
114  result[i] *= sin_values[i];
115 }
116 
153 void DLTSemi(double* data, const int bw, const int m, double* result, double* workspace, double* cos_pml_table,
154  double* weights, fftw_plan* plan) {
155  // TODO add check 0 <= `m` < `bw` (and to any other func)
156  int size = 2 * bw;
157 
158  double* weighted_data = workspace;
159  double* cos_data = weighted_data + size;
160 
161  // apply quadrature weights to the data and compute the cosine transform
162  if (m % 2)
163  for (int i = 0; i < size; ++i)
164  weighted_data[i] = data[i] * weights[2 * bw + i];
165  else
166  for (int i = 0; i < size; ++i)
167  weighted_data[i] = data[i] * weights[i];
168 
169  // smooth the weighted signal
170  fftw_execute_r2r(*plan, weighted_data, cos_data);
171 
172  // normalize
173  cos_data[0] *= M_SQRT1_2;
174  double coeff = 1. / sqrt(2. * size);
175  for (int i = 0; i < size; ++i)
176  cos_data[i] *= coeff;
177 
178  /*
179  Do the projections.
180  Note that the `cos_pml_table` has had all the zeroes
181  stripped out so the indexing is complicated somewhat
182  */
183  int toggle = 0;
184  for (int i = m; i < bw; ++i) {
185  double* pml_ptr = cos_pml_table + TableOffset(m, i);
186 
187  double value = 0.;
188  for (int j = 0; j < (i / 2); ++j)
189  value += cos_data[(2 * j) + toggle] * pml_ptr[j];
190 
191  if (!((i - m) % 2) || !(m % 2))
192  value += cos_data[(2 * (i / 2)) + toggle] * pml_ptr[(i / 2)];
193 
194  result[i - m] = value;
195 
196  toggle = (toggle + 1) % 2;
197  }
198 }
DLTSemi
void DLTSemi(double *data, const int bw, const int m, double *result, double *workspace, double *cos_pml_table, double *weights, fftw_plan *plan)
Computes the Legendre transform of data using the seminaive algorithm.
Definition: seminaive.c:153
Transpose_RowSize
int Transpose_RowSize(const int, const int, const int)
Definition: cospml.c:270
cospml.h
TableOffset
int TableOffset(int, int)
Definition: cospml.c:123
InvDLTSemi
void InvDLTSemi(double *coeffs, const int bw, const int m, double *result, double *trans_cos_pml_table, double *sin_values, double *workspace, fftw_plan *plan)
Computes the inverse Legendre transform using the transposed seminaive algorithm.
Definition: seminaive.c:56
seminaive.h