KADATH
mult_sin_1d.cpp
1 /*
2  Copyright 2017 Philippe Grandclement
3 
4  This file is part of Kadath.
5 
6  Kadath is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  Kadath is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with Kadath. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "base_spectral.hpp"
21 #include "headcpp.hpp"
22 #include "array.hpp"
23 namespace Kadath {
24 int mult_sin_1d_pasprevu (Array<double>&) {
25  cout << "mult_sin_1d not implemented." << endl ;
26  abort() ;
27 }
28 
29 int mult_sin_1d_cossin (Array<double>& tab) {
30  assert (tab.get_ndim()==1) ;
31  int nr = tab.get_size(0) ;
32  assert (nr%2==0) ;
33  Array<double> res (nr) ;
34 
35  res.set(0) = 0.5*tab(3) ;
36  res.set(1) = 0 ;
37  res.set(2) = 0.5*tab(5) ;
38  res.set(3) = tab(0) - 0.5*tab(4) ;
39  for (int k=4; k<nr-2; k+=2) {
40  // Cosines :
41  res.set(k) = 0.5*(tab(3+k) - tab(k-1)) ;
42  // Sines
43  res.set(k+1) = 0.5*(tab(k-2) - tab(k+2)) ;
44  }
45 
46  res.set(nr-2) = -0.5*tab(nr-3) ;
47  res.set(nr-1) = 0. ;
48 
49  tab = res ;
50  return COSSIN ;
51 }
52 
53 int mult_sin_1d_cos (Array<double>& tab) {
54  assert (tab.get_ndim()==1) ;
55  int nr = tab.get_size(0) ;
56 
57  Array<double> res (nr) ;
58 
59  res.set(0) = 0. ;
60  res.set(1) = tab(0) - 0.5*tab(2) ;
61  for (int k=2; k<nr-1; k++)
62  // Sines
63  res.set(k) = 0.5*(tab(k-1) - tab(k+1)) ;
64  //res.set(nr-1) = 0.5*tab(nr-2) ;
65  res.set(nr-1) = 0 ;
66 
67  tab = res ;
68  return SIN ;
69 }
70 
71 int mult_sin_1d_sin (Array<double>& tab) {
72  assert (tab.get_ndim()==1) ;
73  int nr = tab.get_size(0) ;
74 
75  Array<double> res (nr) ;
76 
77  res.set(0) = 0.5*tab(1) ;
78  res.set(1) = 0.5*tab(2) ;
79  for (int k=2; k<nr-1; k++)
80  // Sines
81  res.set(k) = 0.5*(-tab(k-1) + tab(k+1)) ;
82  //res.set(nr-1) = -0.5*tab(nr-2) ;
83  res.set(nr-1) = 0 ;
84 
85  tab = res ;
86  return COS ;
87 }
88 
89 int mult_sin_1d_cos_even (Array<double>& tab) {
90  assert (tab.get_ndim()==1) ;
91  int nr = tab.get_size(0) ;
92 
93  Array<double> res (nr) ;
94 
95  res.set(0) = tab(0) - 0.5*tab(1) ;
96  for (int k=1; k<nr-1; k++)
97  // Sines
98  res.set(k) = 0.5*(tab(k) - tab(k+1)) ;
99  //res.set(nr-1) = 0.5*tab(nr-1) ;
100  res.set(nr-1) = 0 ;
101 
102  tab = res ;
103  return SIN_ODD ;
104 }
105 
106 int mult_sin_1d_cos_odd (Array<double>& tab) {
107  assert (tab.get_ndim()==1) ;
108  int nr = tab.get_size(0) ;
109 
110  Array<double> res (nr) ;
111 
112  res.set(0) = 0. ;
113  for (int k=1; k<nr; k++)
114  // Sines
115  res.set(k) = 0.5*(tab(k-1) - tab(k)) ;
116 
117  tab = res ;
118  return SIN_EVEN ;
119 }
120 
121 int mult_sin_1d_sin_even (Array<double>& tab) {
122  assert (tab.get_ndim()==1) ;
123  int nr = tab.get_size(0) ;
124 
125  Array<double> res (nr) ;
126 
127  res.set(0) = 0.5*tab(1) ;
128  for (int k=1; k<nr-1; k++)
129  // Sines
130  res.set(k) = 0.5*(-tab(k) + tab(k+1)) ;
131  //res.set(nr-1) = -0.5*tab(nr-1) ;
132  res.set(nr-1) = 0 ;
133 
134  tab = res ;
135  return COS_ODD ;
136 }
137 
138 int mult_sin_1d_sin_odd (Array<double>& tab) {
139  assert (tab.get_ndim()==1) ;
140  int nr = tab.get_size(0) ;
141 
142  Array<double> res (nr) ;
143 
144  res.set(0) = 0.5*tab(0) ;
145  for (int k=1; k<nr ; k++)
146  // Sines
147  res.set(k) = 0.5*(-tab(k-1) + tab(k)) ;
148 
149  tab = res ;
150  return COS_EVEN ;
151 }
152 
153 int mult_sin_1d (int base, Array<double>& tab) {
154  static int (*mult_sin_1d[NBR_MAX_BASE])(Array<double>&) ;
155  static bool premier_appel = true ;
156 
157  // Premier appel
158  if (premier_appel) {
159  premier_appel = false ;
160 
161  for (int i=0; i<NBR_MAX_BASE; i++)
162  mult_sin_1d[i] = mult_sin_1d_pasprevu ;
163 
164  mult_sin_1d[COSSIN] = mult_sin_1d_cossin ;
165  mult_sin_1d[COS_EVEN] = mult_sin_1d_cos_even ;
166  mult_sin_1d[COS_ODD] = mult_sin_1d_cos_odd ;
167  mult_sin_1d[SIN_EVEN] = mult_sin_1d_sin_even ;
168  mult_sin_1d[SIN_ODD] = mult_sin_1d_sin_odd ;
169  mult_sin_1d[COS] = mult_sin_1d_cos ;
170  mult_sin_1d[SIN] = mult_sin_1d_sin ;
171  }
172 
173  return mult_sin_1d[base](tab) ;
174 }}