KADATH
div_cos_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 div_cos_1d_pasprevu (Array<double>&) {
25  cout << "div_cos_1d not implemented." << endl ;
26  abort() ;
27 }
28 
29 int div_cos_1d_cos_even (Array<double>& tab) {
30  assert (tab.get_ndim()==1) ;
31  int nr = tab.get_size(0) ;
32 
33  Array<double> res (nr) ;
34 
35  double somme = 0 ;
36  res.set(nr-1) = 0. ;
37  int signe = 1 ;
38  for (int k=nr-2; k>=0; k--) {
39  somme -= 2*signe*tab(k+1) ;
40  signe *= -1 ;
41  res.set(k) = (k%2==0) ? somme : -somme;
42  }
43  tab = res ;
44  return COS_ODD ;
45 }
46 
47 int div_cos_1d_sin_odd (Array<double>& tab) {
48  assert (tab.get_ndim()==1) ;
49  int nr = tab.get_size(0) ;
50 
51  Array<double> res (nr) ;
52 
53  double somme = 0 ;
54  res.set(nr-1) = 0. ;
55  int signe = -1 ;
56  for (int k=nr-2; k>0; k--) {
57  somme -= 2*signe*tab(k) ;
58  signe *= -1 ;
59  res.set(k) = (k%2==0) ? -somme : +somme ;
60  }
61 
62  tab = res ;
63  return SIN_EVEN ;
64 }
65 
66 int div_cos_1d_cos_odd (Array<double>& tab) {
67  assert (tab.get_ndim()==1) ;
68  int nr = tab.get_size(0) ;
69 
70  Array<double> res (nr) ;
71 
72  double somme = 0 ;
73  res.set(nr-1) = 0. ;
74  int signe = -1 ;
75  for (int k=nr-2; k>=0; k--) {
76  somme += 2*tab(k)*signe ;
77  res.set(k) = (k%2==0) ? somme : -somme;
78  signe *= -1 ;
79  }
80  res.set(0) *= 0.5 ;
81  tab = res ;
82  return COS_EVEN ;
83 }
84 
85 int div_cos_1d_sin_even (Array<double>& tab) {
86  assert (tab.get_ndim()==1) ;
87  int nr = tab.get_size(0) ;
88 
89  Array<double> res (nr) ;
90 
91  double somme = 0 ;
92  int signe = -1 ;
93  res.set(nr-1) = 0. ;
94  for (int k=nr-2; k>=0; k--) {
95  somme -= 2*tab(k+1)*signe ;
96  signe *= -1 ;
97  res.set(k) = (k%2==0) ? -somme : somme;
98  }
99  tab = res ;
100  return SIN_ODD ;
101 }
102 
103 int div_cos_1d (int base, Array<double>& tab) {
104  static int (*div_cos_1d[NBR_MAX_BASE])(Array<double>&) ;
105  static bool premier_appel = true ;
106 
107  // Premier appel
108  if (premier_appel) {
109  premier_appel = false ;
110 
111  for (int i=0; i<NBR_MAX_BASE; i++)
112  div_cos_1d[i] = div_cos_1d_pasprevu ;
113 
114  div_cos_1d[COS_EVEN] = div_cos_1d_cos_even ;
115  div_cos_1d[SIN_ODD] = div_cos_1d_sin_odd ;
116  div_cos_1d[COS_ODD] = div_cos_1d_cos_odd ;
117  div_cos_1d[SIN_EVEN] = div_cos_1d_sin_even ;
118  }
119 
120  return div_cos_1d[base](tab) ;
121 }}