/* Fesslix - Stochastic Analysis
 * Copyright (C) 2010-2016 Wolfgang Betz
 *
 * Fesslix is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Fesslix is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Fesslix.  If not, see <http://www.gnu.org/licenses/>. 
 */

#ifndef fesslix_flxfem_GegenbauerPolyH_hard_H
#define fesslix_flxfem_GegenbauerPolyH_hard_H

#if defined(_MSC_VER)
  #include "flxfem_export.h"
#else
  #define FLXFEM_EXPORT
#endif


#include "flxmath.h"


class flxVec;

const tuint MAXHGEGENBAUER = 45;	// maximal polynomial order of hierarchic Gegenbauer polynomials

FLXFEM_EXPORT void hGBP_check_order(const tuint req_order);

const tdouble hGBP0(const tdouble &x);
const tdouble hGBP1(const tdouble &x);
const tdouble hGBP2(const tdouble &x);
const tdouble hGBP3(const tdouble &x);
const tdouble hGBP4(const tdouble &x);
const tdouble hGBP5(const tdouble &x);
const tdouble hGBP6(const tdouble &x);
const tdouble hGBP7(const tdouble &x);
const tdouble hGBP8(const tdouble &x);
const tdouble hGBP9(const tdouble &x);
const tdouble hGBP10(const tdouble &x);
const tdouble hGBP11(const tdouble &x);
const tdouble hGBP12(const tdouble &x);
const tdouble hGBP13(const tdouble &x);
const tdouble hGBP14(const tdouble &x);
const tdouble hGBP15(const tdouble &x);
const tdouble hGBP16(const tdouble &x);
const tdouble hGBP17(const tdouble &x);
const tdouble hGBP18(const tdouble &x);
const tdouble hGBP19(const tdouble &x);
const tdouble hGBP20(const tdouble &x);
const tdouble hGBP21(const tdouble &x);
const tdouble hGBP22(const tdouble &x);
const tdouble hGBP23(const tdouble &x);
const tdouble hGBP24(const tdouble &x);
const tdouble hGBP25(const tdouble &x);
const tdouble hGBP26(const tdouble &x);
const tdouble hGBP27(const tdouble &x);
const tdouble hGBP28(const tdouble &x);
const tdouble hGBP29(const tdouble &x);
const tdouble hGBP30(const tdouble &x);
const tdouble hGBP31(const tdouble &x);
const tdouble hGBP32(const tdouble &x);
const tdouble hGBP33(const tdouble &x);
const tdouble hGBP34(const tdouble &x);
const tdouble hGBP35(const tdouble &x);
const tdouble hGBP36(const tdouble &x);
const tdouble hGBP37(const tdouble &x);
const tdouble hGBP38(const tdouble &x);
const tdouble hGBP39(const tdouble &x);
const tdouble hGBP40(const tdouble &x);
const tdouble hGBP41(const tdouble &x);
const tdouble hGBP42(const tdouble &x);
const tdouble hGBP43(const tdouble &x);
const tdouble hGBP44(const tdouble &x);
const tdouble hGBP45(const tdouble &x);

typedef const tdouble (*hGBPptr)(const tdouble&);

#ifdef fesslix_flxfem_GegenbauerPolyH_hard_CPP
  FLXFEM_EXPORT hGBPptr hGBP[] = {hGBP0,hGBP1,hGBP2,hGBP3,hGBP4,hGBP5,hGBP6,hGBP7,hGBP8,hGBP9,hGBP10,hGBP11,hGBP12,hGBP13,hGBP14,hGBP15,hGBP16,hGBP17,hGBP18,hGBP19,hGBP20,hGBP21,hGBP22,hGBP23,hGBP24,hGBP25,hGBP26,hGBP27,hGBP28,hGBP29,hGBP30,hGBP31,hGBP32,hGBP33,hGBP34,hGBP35,hGBP36,hGBP37,hGBP38,hGBP39,hGBP40,hGBP41,hGBP42,hGBP43,hGBP44,hGBP45};
#else
  FLXFEM_EXPORT extern hGBPptr hGBP[];
#endif

/**
* @brief evaluates hGBP[i] at 'x' and multiplies it with 'f' -> stores result in r[i] (add to r[i])
*/
void hGBP_const(flxVec& r, const tdouble& x, const tdouble& f);
/**
* @brief evaluates hGBP[i] at 'x' -> stores result in r[i] (overwrites r[i])
*/
void hGBP_vec(flxVec& r, const tdouble& x);
/**
* @brief evaluates a point in the space spanned by hGBP
* @param N up to polynomial order 'N'
* @param x evaluate polynomials at 'x'
* @param c0 coordinate of GBP_0
* @param c1 coordinate of GBP_1
* @param coordH vector of coordinates of higher order polynomials
*/
const tdouble hGBP_rlz(const tuint N, const tdouble& x, const tdouble& c0, const tdouble& c1, const tdouble* coordH);


#endif // fesslix_flxfem_GegenbauerPolyH_hard_H
