1 //////////////////////////////////////////////////////////////////////// 2 // 3 // Copyright (C) 1996-2021 The Octave Project Developers 4 // 5 // See the file COPYRIGHT.md in the top-level directory of this 6 // distribution or <https://octave.org/copyright/>. 7 // 8 // This file is part of Octave. 9 // 10 // Octave is free software: you can redistribute it and/or modify it 11 // under the terms of the GNU General Public License as published by 12 // the Free Software Foundation, either version 3 of the License, or 13 // (at your option) any later version. 14 // 15 // Octave is distributed in the hope that it will be useful, but 16 // WITHOUT ANY WARRANTY; without even the implied warranty of 17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 // GNU General Public License for more details. 19 // 20 // You should have received a copy of the GNU General Public License 21 // along with Octave; see the file COPYING. If not, see 22 // <https://www.gnu.org/licenses/>. 23 // 24 //////////////////////////////////////////////////////////////////////// 25 26 #if ! defined (octave_lo_specfun_h) 27 #define octave_lo_specfun_h 1 28 29 #include "octave-config.h" 30 31 #include "Array.h" 32 #include "oct-cmplx.h" 33 34 class ComplexColumnVector; 35 class ComplexMatrix; 36 class ComplexNDArray; 37 class FloatComplexColumnVector; 38 class FloatComplexMatrix; 39 class FloatComplexNDArray; 40 class FloatMatrix; 41 class FloatNDArray; 42 class FloatRowVector; 43 class Matrix; 44 class NDArray; 45 class RowVector; 46 47 namespace octave 48 { 49 namespace math 50 { acosh(double x)51 inline double acosh (double x) { return std::acosh (x); } acosh(float x)52 inline float acosh (float x) { return std::acoshf (x); } acosh(const Complex & x)53 inline Complex acosh (const Complex& x) { return std::acosh (x); } acosh(const FloatComplex & x)54 inline FloatComplex acosh (const FloatComplex& x) { return std::acosh (x); } 55 56 extern OCTAVE_API Complex airy (const Complex& z, bool deriv, bool scaled, 57 octave_idx_type& ierr); 58 extern OCTAVE_API ComplexMatrix airy (const ComplexMatrix& z, bool deriv, 59 bool scaled, Array<octave_idx_type>& ierr); 60 extern OCTAVE_API ComplexNDArray airy (const ComplexNDArray& z, bool deriv, 61 bool scaled, Array<octave_idx_type>& ierr); 62 extern OCTAVE_API FloatComplex airy (const FloatComplex& z, bool deriv, 63 bool scaled, octave_idx_type& ierr); 64 extern OCTAVE_API FloatComplexMatrix airy (const FloatComplexMatrix& z, 65 bool deriv, bool scaled, Array<octave_idx_type>& ierr); 66 extern OCTAVE_API FloatComplexNDArray airy (const FloatComplexNDArray& z, 67 bool deriv, bool scaled, Array<octave_idx_type>& ierr); 68 asinh(double x)69 inline double asinh (double x) { return std::asinh (x); } asinh(float x)70 inline float asinh (float x) { return std::asinhf (x); } asinh(const Complex & x)71 inline Complex asinh (const Complex& x) { return std::asinh (x); } asinh(const FloatComplex & x)72 inline FloatComplex asinh (const FloatComplex& x) { return std::asinh (x); } 73 atanh(double x)74 inline double atanh (double x) { return std::atanh (x); } atanh(float x)75 inline float atanh (float x) { return std::atanhf (x); } atanh(const Complex & x)76 inline Complex atanh (const Complex& x) { return std::atanh (x); } atanh(const FloatComplex & x)77 inline FloatComplex atanh (const FloatComplex& x) { return std::atanh (x); } 78 79 extern OCTAVE_API Complex besselj (double alpha, const Complex& x, bool scaled, 80 octave_idx_type& ierr); 81 extern OCTAVE_API Complex bessely (double alpha, const Complex& x, bool scaled, 82 octave_idx_type& ierr); 83 extern OCTAVE_API Complex besseli (double alpha, const Complex& x, bool scaled, 84 octave_idx_type& ierr); 85 extern OCTAVE_API Complex besselk (double alpha, const Complex& x, bool scaled, 86 octave_idx_type& ierr); 87 extern OCTAVE_API Complex besselh1 (double alpha, const Complex& x, bool scaled, 88 octave_idx_type& ierr); 89 extern OCTAVE_API Complex besselh2 (double alpha, const Complex& x, bool scaled, 90 octave_idx_type& ierr); 91 92 extern OCTAVE_API ComplexMatrix besselj (double alpha, const ComplexMatrix& x, 93 bool scaled, Array<octave_idx_type>& ierr); 94 extern OCTAVE_API ComplexMatrix bessely (double alpha, const ComplexMatrix& x, 95 bool scaled, Array<octave_idx_type>& ierr); 96 extern OCTAVE_API ComplexMatrix besseli (double alpha, const ComplexMatrix& x, 97 bool scaled, Array<octave_idx_type>& ierr); 98 extern OCTAVE_API ComplexMatrix besselk (double alpha, const ComplexMatrix& x, 99 bool scaled, Array<octave_idx_type>& ierr); 100 extern OCTAVE_API ComplexMatrix besselh1 (double alpha, const ComplexMatrix& x, 101 bool scaled, Array<octave_idx_type>& ierr); 102 extern OCTAVE_API ComplexMatrix besselh2 (double alpha, const ComplexMatrix& x, 103 bool scaled, Array<octave_idx_type>& ierr); 104 105 extern OCTAVE_API ComplexMatrix besselj (const Matrix& alpha, const Complex& x, 106 bool scaled, Array<octave_idx_type>& ierr); 107 extern OCTAVE_API ComplexMatrix bessely (const Matrix& alpha, const Complex& x, 108 bool scaled, Array<octave_idx_type>& ierr); 109 extern OCTAVE_API ComplexMatrix besseli (const Matrix& alpha, const Complex& x, 110 bool scaled, Array<octave_idx_type>& ierr); 111 extern OCTAVE_API ComplexMatrix besselk (const Matrix& alpha, const Complex& x, 112 bool scaled, Array<octave_idx_type>& ierr); 113 extern OCTAVE_API ComplexMatrix besselh1 (const Matrix& alpha, const Complex& x, 114 bool scaled, Array<octave_idx_type>& ierr); 115 extern OCTAVE_API ComplexMatrix besselh2 (const Matrix& alpha, const Complex& x, 116 bool scaled, Array<octave_idx_type>& ierr); 117 118 extern OCTAVE_API ComplexMatrix besselj (const Matrix& alpha, 119 const ComplexMatrix& x, bool scaled, Array<octave_idx_type>& ierr); 120 extern OCTAVE_API ComplexMatrix bessely (const Matrix& alpha, 121 const ComplexMatrix& x, bool scaled, Array<octave_idx_type>& ierr); 122 extern OCTAVE_API ComplexMatrix besseli (const Matrix& alpha, 123 const ComplexMatrix& x, bool scaled, Array<octave_idx_type>& ierr); 124 extern OCTAVE_API ComplexMatrix besselk (const Matrix& alpha, 125 const ComplexMatrix& x, bool scaled, Array<octave_idx_type>& ierr); 126 extern OCTAVE_API ComplexMatrix besselh1 (const Matrix& alpha, 127 const ComplexMatrix& x, bool scaled, Array<octave_idx_type>& ierr); 128 extern OCTAVE_API ComplexMatrix besselh2 (const Matrix& alpha, 129 const ComplexMatrix& x, bool scaled, Array<octave_idx_type>& ierr); 130 131 extern OCTAVE_API ComplexNDArray besselj (double alpha, const ComplexNDArray& x, 132 bool scaled, Array<octave_idx_type>& ierr); 133 extern OCTAVE_API ComplexNDArray bessely (double alpha, const ComplexNDArray& x, 134 bool scaled, Array<octave_idx_type>& ierr); 135 extern OCTAVE_API ComplexNDArray besseli (double alpha, const ComplexNDArray& x, 136 bool scaled, Array<octave_idx_type>& ierr); 137 extern OCTAVE_API ComplexNDArray besselk (double alpha, const ComplexNDArray& x, 138 bool scaled, Array<octave_idx_type>& ierr); 139 extern OCTAVE_API ComplexNDArray besselh1 (double alpha, 140 const ComplexNDArray& x, bool scaled, Array<octave_idx_type>& ierr); 141 extern OCTAVE_API ComplexNDArray besselh2 (double alpha, 142 const ComplexNDArray& x, bool scaled, Array<octave_idx_type>& ierr); 143 144 extern OCTAVE_API ComplexNDArray besselj (const NDArray& alpha, 145 const Complex& x, bool scaled, Array<octave_idx_type>& ierr); 146 extern OCTAVE_API ComplexNDArray bessely (const NDArray& alpha, 147 const Complex& x, bool scaled, Array<octave_idx_type>& ierr); 148 extern OCTAVE_API ComplexNDArray besseli (const NDArray& alpha, 149 const Complex& x, bool scaled, Array<octave_idx_type>& ierr); 150 extern OCTAVE_API ComplexNDArray besselk (const NDArray& alpha, 151 const Complex& x, bool scaled, Array<octave_idx_type>& ierr); 152 extern OCTAVE_API ComplexNDArray besselh1 (const NDArray& alpha, 153 const Complex& x, bool scaled, Array<octave_idx_type>& ierr); 154 extern OCTAVE_API ComplexNDArray besselh2 (const NDArray& alpha, 155 const Complex& x, bool scaled, Array<octave_idx_type>& ierr); 156 157 extern OCTAVE_API ComplexNDArray besselj (const NDArray& alpha, 158 const ComplexNDArray& x, bool scaled, Array<octave_idx_type>& ierr); 159 extern OCTAVE_API ComplexNDArray bessely (const NDArray& alpha, 160 const ComplexNDArray& x, bool scaled, Array<octave_idx_type>& ierr); 161 extern OCTAVE_API ComplexNDArray besseli (const NDArray& alpha, 162 const ComplexNDArray& x, bool scaled, Array<octave_idx_type>& ierr); 163 extern OCTAVE_API ComplexNDArray besselk (const NDArray& alpha, 164 const ComplexNDArray& x, bool scaled, Array<octave_idx_type>& ierr); 165 extern OCTAVE_API ComplexNDArray besselh1 (const NDArray& alpha, 166 const ComplexNDArray& x, bool scaled, Array<octave_idx_type>& ierr); 167 extern OCTAVE_API ComplexNDArray besselh2 (const NDArray& alpha, 168 const ComplexNDArray& x, bool scaled, Array<octave_idx_type>& ierr); 169 170 extern OCTAVE_API ComplexMatrix besselj (const RowVector& alpha, 171 const ComplexColumnVector& x, bool scaled, Array<octave_idx_type>& ierr); 172 extern OCTAVE_API ComplexMatrix bessely (const RowVector& alpha, 173 const ComplexColumnVector& x, bool scaled, Array<octave_idx_type>& ierr); 174 extern OCTAVE_API ComplexMatrix besseli (const RowVector& alpha, 175 const ComplexColumnVector& x, bool scaled, Array<octave_idx_type>& ierr); 176 extern OCTAVE_API ComplexMatrix besselk (const RowVector& alpha, 177 const ComplexColumnVector& x, bool scaled, Array<octave_idx_type>& ierr); 178 extern OCTAVE_API ComplexMatrix besselh1 (const RowVector& alpha, 179 const ComplexColumnVector& x, bool scaled, Array<octave_idx_type>& ierr); 180 extern OCTAVE_API ComplexMatrix besselh2 (const RowVector& alpha, 181 const ComplexColumnVector& x, bool scaled, Array<octave_idx_type>& ierr); 182 183 extern OCTAVE_API FloatComplex besselj (float alpha, const FloatComplex& x, 184 bool scaled, octave_idx_type& ierr); 185 extern OCTAVE_API FloatComplex bessely (float alpha, const FloatComplex& x, 186 bool scaled, octave_idx_type& ierr); 187 extern OCTAVE_API FloatComplex besseli (float alpha, const FloatComplex& x, 188 bool scaled, octave_idx_type& ierr); 189 extern OCTAVE_API FloatComplex besselk (float alpha, const FloatComplex& x, 190 bool scaled, octave_idx_type& ierr); 191 extern OCTAVE_API FloatComplex besselh1 (float alpha, const FloatComplex& x, 192 bool scaled, octave_idx_type& ierr); 193 extern OCTAVE_API FloatComplex besselh2 (float alpha, const FloatComplex& x, 194 bool scaled, octave_idx_type& ierr); 195 196 extern OCTAVE_API FloatComplexMatrix besselj (float alpha, 197 const FloatComplexMatrix& x, bool scaled, Array<octave_idx_type>& ierr); 198 extern OCTAVE_API FloatComplexMatrix bessely (float alpha, 199 const FloatComplexMatrix& x, bool scaled, Array<octave_idx_type>& ierr); 200 extern OCTAVE_API FloatComplexMatrix besseli (float alpha, 201 const FloatComplexMatrix& x, bool scaled, Array<octave_idx_type>& ierr); 202 extern OCTAVE_API FloatComplexMatrix besselk (float alpha, 203 const FloatComplexMatrix& x, bool scaled, Array<octave_idx_type>& ierr); 204 extern OCTAVE_API FloatComplexMatrix besselh1 (float alpha, 205 const FloatComplexMatrix& x, bool scaled, Array<octave_idx_type>& ierr); 206 extern OCTAVE_API FloatComplexMatrix besselh2 (float alpha, 207 const FloatComplexMatrix& x, bool scaled, Array<octave_idx_type>& ierr); 208 209 extern OCTAVE_API FloatComplexMatrix besselj (const FloatMatrix& alpha, 210 const FloatComplex& x, bool scaled, Array<octave_idx_type>& ierr); 211 extern OCTAVE_API FloatComplexMatrix bessely (const FloatMatrix& alpha, 212 const FloatComplex& x, bool scaled, Array<octave_idx_type>& ierr); 213 extern OCTAVE_API FloatComplexMatrix besseli (const FloatMatrix& alpha, 214 const FloatComplex& x, bool scaled, Array<octave_idx_type>& ierr); 215 extern OCTAVE_API FloatComplexMatrix besselk (const FloatMatrix& alpha, 216 const FloatComplex& x, bool scaled, Array<octave_idx_type>& ierr); 217 extern OCTAVE_API FloatComplexMatrix besselh1 (const FloatMatrix& alpha, 218 const FloatComplex& x, bool scaled, Array<octave_idx_type>& ierr); 219 extern OCTAVE_API FloatComplexMatrix besselh2 (const FloatMatrix& alpha, 220 const FloatComplex& x, bool scaled, Array<octave_idx_type>& ierr); 221 222 extern OCTAVE_API FloatComplexMatrix besselj (const FloatMatrix& alpha, 223 const FloatComplexMatrix& x, bool scaled, Array<octave_idx_type>& ierr); 224 extern OCTAVE_API FloatComplexMatrix bessely (const FloatMatrix& alpha, 225 const FloatComplexMatrix& x, bool scaled, Array<octave_idx_type>& ierr); 226 extern OCTAVE_API FloatComplexMatrix besseli (const FloatMatrix& alpha, 227 const FloatComplexMatrix& x, bool scaled, Array<octave_idx_type>& ierr); 228 extern OCTAVE_API FloatComplexMatrix besselk (const FloatMatrix& alpha, 229 const FloatComplexMatrix& x, bool scaled, Array<octave_idx_type>& ierr); 230 extern OCTAVE_API FloatComplexMatrix besselh1 (const FloatMatrix& alpha, 231 const FloatComplexMatrix& x, bool scaled, Array<octave_idx_type>& ierr); 232 extern OCTAVE_API FloatComplexMatrix besselh2 (const FloatMatrix& alpha, 233 const FloatComplexMatrix& x, bool scaled, Array<octave_idx_type>& ierr); 234 235 extern OCTAVE_API FloatComplexNDArray besselj (float alpha, 236 const FloatComplexNDArray& x, bool scaled, Array<octave_idx_type>& ierr); 237 extern OCTAVE_API FloatComplexNDArray bessely (float alpha, 238 const FloatComplexNDArray& x, bool scaled, Array<octave_idx_type>& ierr); 239 extern OCTAVE_API FloatComplexNDArray besseli (float alpha, 240 const FloatComplexNDArray& x, bool scaled, Array<octave_idx_type>& ierr); 241 extern OCTAVE_API FloatComplexNDArray besselk (float alpha, 242 const FloatComplexNDArray& x, bool scaled, Array<octave_idx_type>& ierr); 243 extern OCTAVE_API FloatComplexNDArray besselh1 (float alpha, 244 const FloatComplexNDArray& x, bool scaled, Array<octave_idx_type>& ierr); 245 extern OCTAVE_API FloatComplexNDArray besselh2 (float alpha, 246 const FloatComplexNDArray& x, bool scaled, Array<octave_idx_type>& ierr); 247 248 extern OCTAVE_API FloatComplexNDArray besselj (const FloatNDArray& alpha, 249 const FloatComplex& x, bool scaled, Array<octave_idx_type>& ierr); 250 extern OCTAVE_API FloatComplexNDArray bessely (const FloatNDArray& alpha, 251 const FloatComplex& x, bool scaled, Array<octave_idx_type>& ierr); 252 extern OCTAVE_API FloatComplexNDArray besseli (const FloatNDArray& alpha, 253 const FloatComplex& x, bool scaled, Array<octave_idx_type>& ierr); 254 extern OCTAVE_API FloatComplexNDArray besselk (const FloatNDArray& alpha, 255 const FloatComplex& x, bool scaled, Array<octave_idx_type>& ierr); 256 extern OCTAVE_API FloatComplexNDArray besselh1 (const FloatNDArray& alpha, 257 const FloatComplex& x, bool scaled, Array<octave_idx_type>& ierr); 258 extern OCTAVE_API FloatComplexNDArray besselh2 (const FloatNDArray& alpha, 259 const FloatComplex& x, bool scaled, Array<octave_idx_type>& ierr); 260 261 extern OCTAVE_API FloatComplexNDArray besselj (const FloatNDArray& alpha, 262 const FloatComplexNDArray& x, bool scaled, Array<octave_idx_type>& ierr); 263 extern OCTAVE_API FloatComplexNDArray bessely (const FloatNDArray& alpha, 264 const FloatComplexNDArray& x, bool scaled, Array<octave_idx_type>& ierr); 265 extern OCTAVE_API FloatComplexNDArray besseli (const FloatNDArray& alpha, 266 const FloatComplexNDArray& x, bool scaled, Array<octave_idx_type>& ierr); 267 extern OCTAVE_API FloatComplexNDArray besselk (const FloatNDArray& alpha, 268 const FloatComplexNDArray& x, bool scaled, Array<octave_idx_type>& ierr); 269 extern OCTAVE_API FloatComplexNDArray besselh1 (const FloatNDArray& alpha, 270 const FloatComplexNDArray& x, bool scaled, Array<octave_idx_type>& ierr); 271 extern OCTAVE_API FloatComplexNDArray besselh2 (const FloatNDArray& alpha, 272 const FloatComplexNDArray& x, bool scaled, Array<octave_idx_type>& ierr); 273 274 extern OCTAVE_API FloatComplexMatrix besselj (const FloatRowVector& alpha, 275 const FloatComplexColumnVector& x, bool scaled, Array<octave_idx_type>& ierr); 276 extern OCTAVE_API FloatComplexMatrix bessely (const FloatRowVector& alpha, 277 const FloatComplexColumnVector& x, bool scaled, Array<octave_idx_type>& ierr); 278 extern OCTAVE_API FloatComplexMatrix besseli (const FloatRowVector& alpha, 279 const FloatComplexColumnVector& x, bool scaled, Array<octave_idx_type>& ierr); 280 extern OCTAVE_API FloatComplexMatrix besselk (const FloatRowVector& alpha, 281 const FloatComplexColumnVector& x, bool scaled, Array<octave_idx_type>& ierr); 282 extern OCTAVE_API FloatComplexMatrix besselh1 (const FloatRowVector& alpha, 283 const FloatComplexColumnVector& x, bool scaled, Array<octave_idx_type>& ierr); 284 extern OCTAVE_API FloatComplexMatrix besselh2 (const FloatRowVector& alpha, 285 const FloatComplexColumnVector& x, bool scaled, Array<octave_idx_type>& ierr); 286 287 extern OCTAVE_API Complex biry (const Complex& z, bool deriv, bool scaled, 288 octave_idx_type& ierr); 289 extern OCTAVE_API ComplexMatrix biry (const ComplexMatrix& z, bool deriv, 290 bool scaled, Array<octave_idx_type>& ierr); 291 extern OCTAVE_API ComplexNDArray biry (const ComplexNDArray& z, bool deriv, 292 bool scaled, Array<octave_idx_type>& ierr); 293 extern OCTAVE_API FloatComplex biry (const FloatComplex& z, bool deriv, 294 bool scaled, octave_idx_type& ierr); 295 extern OCTAVE_API FloatComplexMatrix biry (const FloatComplexMatrix& z, 296 bool deriv, bool scaled, Array<octave_idx_type>& ierr); 297 extern OCTAVE_API FloatComplexNDArray biry (const FloatComplexNDArray& z, 298 bool deriv, bool scaled, Array<octave_idx_type>& ierr); 299 cbrt(double x)300 inline double cbrt (double x) { return std::cbrt (x); } cbrt(float x)301 inline float cbrt (float x) { return std::cbrtf (x); } 302 303 extern OCTAVE_API double dawson (double x); 304 extern OCTAVE_API float dawson (float x); 305 extern OCTAVE_API Complex dawson (const Complex& x); 306 extern OCTAVE_API FloatComplex dawson (const FloatComplex& x); 307 308 extern OCTAVE_API void ellipj (double u, double m, double& sn, double& cn, 309 double& dn, double& err); 310 extern OCTAVE_API void ellipj (const Complex& u, double m, Complex& sn, 311 Complex& cn, Complex& dn, double& err); 312 erf(double x)313 inline double erf (double x) { return std::erf (x); } erf(float x)314 inline float erf (float x) { return std::erff (x); } 315 extern OCTAVE_API Complex erf (const Complex& x); 316 extern OCTAVE_API FloatComplex erf (const FloatComplex& x); 317 erfc(double x)318 inline double erfc (double x) { return std::erfc (x); } erfc(float x)319 inline float erfc (float x) { return std::erfcf (x); } 320 extern OCTAVE_API Complex erfc (const Complex& x); 321 extern OCTAVE_API FloatComplex erfc (const FloatComplex& x); 322 323 extern OCTAVE_API double erfcinv (double x); 324 extern OCTAVE_API float erfcinv (float x); 325 326 extern OCTAVE_API double erfcx (double x); 327 extern OCTAVE_API float erfcx (float x); 328 extern OCTAVE_API Complex erfcx (const Complex& x); 329 extern OCTAVE_API FloatComplex erfcx (const FloatComplex& x); 330 331 extern OCTAVE_API double erfi (double x); 332 extern OCTAVE_API float erfi (float x); 333 extern OCTAVE_API Complex erfi (const Complex& x); 334 extern OCTAVE_API FloatComplex erfi (const FloatComplex& x); 335 336 extern OCTAVE_API double erfinv (double x); 337 extern OCTAVE_API float erfinv (float x); 338 expm1(double x)339 inline double expm1 (double x) { return std::expm1 (x); } expm1(float x)340 inline float expm1 (float x) { return std::expm1f (x); } 341 extern OCTAVE_API Complex expm1 (const Complex& x); 342 extern OCTAVE_API FloatComplex expm1 (const FloatComplex& x); 343 344 extern OCTAVE_API double gamma (double x); 345 extern OCTAVE_API float gamma (float x); 346 lgamma(double x)347 inline double lgamma (double x) { return std::lgamma (x); } lgamma(float x)348 inline float lgamma (float x) { return std::lgammaf (x); } 349 log1p(double x)350 inline double log1p (double x) { return std::log1p (x); } log1p(float x)351 inline float log1p (float x) { return std::log1pf (x); } 352 extern OCTAVE_API Complex log1p (const Complex& x); 353 extern OCTAVE_API FloatComplex log1p (const FloatComplex& x); 354 355 extern OCTAVE_API double psi (double x); 356 extern OCTAVE_API float psi (float x); 357 extern OCTAVE_API Complex psi (const Complex& x); 358 extern OCTAVE_API FloatComplex psi (const FloatComplex& x); 359 extern OCTAVE_API double psi (octave_idx_type n, double z); 360 extern OCTAVE_API float psi (octave_idx_type n, float z); 361 362 extern OCTAVE_API Complex rc_lgamma (double x); 363 extern OCTAVE_API FloatComplex rc_lgamma (float x); 364 365 extern OCTAVE_API Complex rc_log1p (double x); 366 extern OCTAVE_API FloatComplex rc_log1p (float x); 367 } 368 } 369 370 #endif 371