/* 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_legendrePolyH_hard_H
#define fesslix_flxfem_legendrePolyH_hard_H

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

#include "flxmath.h"


class flxVec;

const tuint MAXHLEGENDRE = 45;	// maximal polynomial order of hierarchic legendre polynomials

FLXFEM_EXPORT void hLP_check_order(const tuint req_order);

const tdouble hLP0(const tdouble &x);
const tdouble hLP1(const tdouble &x);
const tdouble hLP2(const tdouble &x);
const tdouble hLP3(const tdouble &x);
const tdouble hLP4(const tdouble &x);
const tdouble hLP5(const tdouble &x);
const tdouble hLP6(const tdouble &x);
const tdouble hLP7(const tdouble &x);
const tdouble hLP8(const tdouble &x);
const tdouble hLP9(const tdouble &x);
const tdouble hLP10(const tdouble &x);
const tdouble hLP11(const tdouble &x);
const tdouble hLP12(const tdouble &x);
const tdouble hLP13(const tdouble &x);
const tdouble hLP14(const tdouble &x);
const tdouble hLP15(const tdouble &x);
const tdouble hLP16(const tdouble &x);
const tdouble hLP17(const tdouble &x);
const tdouble hLP18(const tdouble &x);
const tdouble hLP19(const tdouble &x);
const tdouble hLP20(const tdouble &x);
const tdouble hLP21(const tdouble &x);
const tdouble hLP22(const tdouble &x);
const tdouble hLP23(const tdouble &x);
const tdouble hLP24(const tdouble &x);
const tdouble hLP25(const tdouble &x);
const tdouble hLP26(const tdouble &x);
const tdouble hLP27(const tdouble &x);
const tdouble hLP28(const tdouble &x);
const tdouble hLP29(const tdouble &x);
const tdouble hLP30(const tdouble &x);
const tdouble hLP31(const tdouble &x);
const tdouble hLP32(const tdouble &x);
const tdouble hLP33(const tdouble &x);
const tdouble hLP34(const tdouble &x);
const tdouble hLP35(const tdouble &x);
const tdouble hLP36(const tdouble &x);
const tdouble hLP37(const tdouble &x);
const tdouble hLP38(const tdouble &x);
const tdouble hLP39(const tdouble &x);
const tdouble hLP40(const tdouble &x);
const tdouble hLP41(const tdouble &x);
const tdouble hLP42(const tdouble &x);
const tdouble hLP43(const tdouble &x);
const tdouble hLP44(const tdouble &x);
const tdouble hLP45(const tdouble &x);

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

#ifdef fesslix_flxfem_legendrePolyH_hard_CPP
  FLXFEM_EXPORT LPptr hLP[] = {hLP0,hLP1,hLP2,hLP3,hLP4,hLP5,hLP6,hLP7,hLP8,hLP9,hLP10,hLP11,hLP12,hLP13,hLP14,hLP15,hLP16,hLP17,hLP18,hLP19,hLP20,hLP21,hLP22,hLP23,hLP24,hLP25,hLP26,hLP27,hLP28,hLP29,hLP30,hLP31,hLP32,hLP33,hLP34,hLP35,hLP36,hLP37,hLP38,hLP39,hLP40,hLP41,hLP42,hLP43,hLP44,hLP45};
#else
  FLXFEM_EXPORT extern LPptr hLP[];
#endif

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

const tdouble dhLP0(const tdouble &x);
const tdouble dhLP1(const tdouble &x);
const tdouble dhLP2(const tdouble &x);
const tdouble dhLP3(const tdouble &x);
const tdouble dhLP4(const tdouble &x);
const tdouble dhLP5(const tdouble &x);
const tdouble dhLP6(const tdouble &x);
const tdouble dhLP7(const tdouble &x);
const tdouble dhLP8(const tdouble &x);
const tdouble dhLP9(const tdouble &x);
const tdouble dhLP10(const tdouble &x);
const tdouble dhLP11(const tdouble &x);
const tdouble dhLP12(const tdouble &x);
const tdouble dhLP13(const tdouble &x);
const tdouble dhLP14(const tdouble &x);
const tdouble dhLP15(const tdouble &x);
const tdouble dhLP16(const tdouble &x);
const tdouble dhLP17(const tdouble &x);
const tdouble dhLP18(const tdouble &x);
const tdouble dhLP19(const tdouble &x);
const tdouble dhLP20(const tdouble &x);
const tdouble dhLP21(const tdouble &x);
const tdouble dhLP22(const tdouble &x);
const tdouble dhLP23(const tdouble &x);
const tdouble dhLP24(const tdouble &x);
const tdouble dhLP25(const tdouble &x);
const tdouble dhLP26(const tdouble &x);
const tdouble dhLP27(const tdouble &x);
const tdouble dhLP28(const tdouble &x);
const tdouble dhLP29(const tdouble &x);
const tdouble dhLP30(const tdouble &x);
const tdouble dhLP31(const tdouble &x);
const tdouble dhLP32(const tdouble &x);
const tdouble dhLP33(const tdouble &x);
const tdouble dhLP34(const tdouble &x);
const tdouble dhLP35(const tdouble &x);
const tdouble dhLP36(const tdouble &x);
const tdouble dhLP37(const tdouble &x);
const tdouble dhLP38(const tdouble &x);
const tdouble dhLP39(const tdouble &x);
const tdouble dhLP40(const tdouble &x);
const tdouble dhLP41(const tdouble &x);
const tdouble dhLP42(const tdouble &x);
const tdouble dhLP43(const tdouble &x);
const tdouble dhLP44(const tdouble &x);
const tdouble dhLP45(const tdouble &x);

#ifdef fesslix_flxfem_legendrePolyH_hard_CPP
  LPptr dhLP[] = {dhLP0,dhLP1,dhLP2,dhLP3,dhLP4,dhLP5,dhLP6,dhLP7,dhLP8,dhLP9,dhLP10,dhLP11,dhLP12,dhLP13,dhLP14,dhLP15,dhLP16,dhLP17,dhLP18,dhLP19,dhLP20,dhLP21,dhLP22,dhLP23,dhLP24,dhLP25,dhLP26,dhLP27,dhLP28,dhLP29,dhLP30,dhLP31,dhLP32,dhLP33,dhLP34,dhLP35,dhLP36,dhLP37,dhLP38,dhLP39,dhLP40,dhLP41,dhLP42,dhLP43,dhLP44,dhLP45};
#else
  extern LPptr dhLP[];
#endif

/**
* @brief evaluates dhLP[i] at 'x' -> stores result in r[i] (overwrites r[i])
*/
void dhLP_vec(flxVec& r, const tdouble& x);

#endif // fesslix_flxfem_legendrePolyH_hard_H