```// @(#)root/hist:\$Id: TSpline.h 27193 2009-01-20 11:18:46Z brun \$
// Author: Federico Carminati   28/02/2000

/*************************************************************************
*                                                                       *
* For the licensing terms see \$ROOTSYS/LICENSE.                         *
* For the list of contributors see \$ROOTSYS/README/CREDITS.             *
*************************************************************************/

#ifndef ROOT_TSpline
#define ROOT_TSpline

#ifndef ROOT_TGraph
#include "TGraph.h"
#endif

class TH1;
class TF1;

class TSpline : public TNamed, public TAttLine,
public TAttFill, public TAttMarker
{
protected:
Double_t  fDelta;     // Distance between equidistant knots
Double_t  fXmin;      // Minimum value of abscissa
Double_t  fXmax;      // Maximum value of abscissa
Int_t     fNp;        // Number of knots
Bool_t    fKstep;     // True of equidistant knots
TH1F     *fHistogram; // Temporary histogram
TGraph   *fGraph;     // Graph for drawing the knots
Int_t     fNpx;       // Number of points used for graphical representation

TSpline(const TSpline&);
TSpline& operator=(const TSpline&);
virtual void     BuildCoeff()=0;

public:
TSpline() : fDelta(-1), fXmin(0), fXmax(0),
fNp(0), fKstep(kFALSE), fHistogram(0), fGraph(0), fNpx(100) {}
TSpline(const char *title, Double_t delta, Double_t xmin,
Double_t xmax, Int_t np, Bool_t step) :
TNamed("Spline",title), TAttFill(0,1),
fDelta(delta), fXmin(xmin),
fXmax(xmax), fNp(np), fKstep(step),
fHistogram(0), fGraph(0), fNpx(100) {}
virtual ~TSpline();

virtual void     GetKnot(Int_t i, Double_t &x, Double_t &y) const =0;
virtual Int_t    DistancetoPrimitive(Int_t px, Int_t py);
virtual void     Draw(Option_t *option="");
virtual void     ExecuteEvent(Int_t event, Int_t px, Int_t py);
virtual Double_t GetDelta() const {return fDelta;}
virtual Int_t    GetNp()    const {return fNp;}
virtual Int_t    GetNpx()   const {return fNpx;}
virtual Double_t GetXmin()  const {return fXmin;}
virtual Double_t GetXmax()  const {return fXmax;}
virtual void     Paint(Option_t *option="");
virtual Double_t Eval(Double_t x) const=0;
virtual void     SaveAs(const char * /*filename*/,Option_t * /*option*/) const {;}
void             SetNpx(Int_t n) {fNpx=n;}

ClassDef (TSpline,2) // Spline base class
};

//______________________________________________________________________________
class TSplinePoly : public TObject
{
protected:
Double_t fX;     // abscissa
Double_t fY;     // constant term

public:
TSplinePoly() :
fX(0), fY(0) {}
TSplinePoly(Double_t x, Double_t y) :
fX(x), fY(y) {}
TSplinePoly(TSplinePoly const &other);
TSplinePoly &operator=(TSplinePoly const &other);

Double_t &X() {return fX;}
Double_t &Y() {return fY;}
void GetKnot(Double_t &x, Double_t &y) const {x=fX; y=fY;}

virtual Double_t Eval(Double_t) const {return fY;}

private:
void CopyPoly(TSplinePoly const &other);

ClassDef(TSplinePoly,2) // Spline polynomial terms
};

inline TSplinePoly::TSplinePoly(TSplinePoly const &other)
:
TObject(other), fX(0), fY(0)
{
CopyPoly(other);
}

//______________________________________________________________________________
class TSplinePoly3 : public TSplinePoly
{
private:
Double_t fB; // first order expansion coefficient :  fB*1! is the first derivative at x
Double_t fC; // second order expansion coefficient : fC*2! is the second derivative at x
Double_t fD; // third order expansion coefficient :  fD*3! is the third derivative at x

public:
TSplinePoly3() :
fB(0), fC(0), fD(0) {}
TSplinePoly3(Double_t x, Double_t y, Double_t b, Double_t c, Double_t d) :
TSplinePoly(x,y), fB(b), fC(c), fD(d) {}
TSplinePoly3(TSplinePoly3 const &other);
TSplinePoly3 &operator=(TSplinePoly3 const &other);

Double_t &B() {return fB;}
Double_t &C() {return fC;}
Double_t &D() {return fD;}
Double_t Eval(Double_t x) const {
Double_t dx=x-fX;
return (fY+dx*(fB+dx*(fC+dx*fD)));
}
Double_t Derivative(Double_t x) const {
Double_t dx=x-fX;
return (fB+2*fC*dx+3*fD*dx*dx);
}

private:
void CopyPoly(TSplinePoly3 const &other);

ClassDef(TSplinePoly3,1)  // Third spline polynomial terms
};

inline TSplinePoly3::TSplinePoly3(TSplinePoly3 const &other)
:
TSplinePoly(other), fB(0), fC(0), fD(0)
{
CopyPoly(other);
}

//______________________________________________________________________________
class TSplinePoly5 : public TSplinePoly
{
private:
Double_t fB; // first order expansion coefficient :  fB*1! is the first derivative at x
Double_t fC; // second order expansion coefficient : fC*2! is the second derivative at x
Double_t fD; // third order expansion coefficient :  fD*3! is the third derivative at x
Double_t fE; // fourth order expansion coefficient : fE*4! is the fourth derivative at x
Double_t fF; // fifth order expansion coefficient :  fF*5! is the fifth derivative at x

public:
TSplinePoly5() :
fB(0), fC(0), fD(0), fE(0), fF(0) {}
TSplinePoly5(Double_t x, Double_t y, Double_t b, Double_t c,
Double_t d, Double_t e, Double_t f) :
TSplinePoly(x,y), fB(b), fC(c), fD(d), fE(e), fF(f) {}
TSplinePoly5(TSplinePoly5 const &other);
TSplinePoly5 &operator=(TSplinePoly5 const &other);

Double_t &B() {return fB;}
Double_t &C() {return fC;}
Double_t &D() {return fD;}
Double_t &E() {return fE;}
Double_t &F() {return fF;}
Double_t Eval(Double_t x) const {
Double_t dx=x-fX;
return (fY+dx*(fB+dx*(fC+dx*(fD+dx*(fE+dx*fF)))));
}
Double_t Derivative(Double_t x) const{
Double_t dx=x-fX;
return (fB+2*fC*dx+3*fD*dx*dx+4*fE*dx*dx*dx+5*fF*dx*dx*dx*dx);
}

private:
void CopyPoly(TSplinePoly5 const &other);

ClassDef(TSplinePoly5,1)  // Quintic spline polynomial terms
};

inline TSplinePoly5::TSplinePoly5(TSplinePoly5 const &other)
:
TSplinePoly(other), fB(0), fC(0), fD(0), fE(0), fF(0)
{
CopyPoly(other);
}

//______________________________________________________________________________
class TSpline3 : public TSpline
{
protected:
TSplinePoly3  *fPoly;       //[fNp] Array of polynomial terms
Double_t       fValBeg;     // Initial value of first or second derivative
Double_t       fValEnd;     // End value of first or second derivative
Int_t          fBegCond;    // 0=no beg cond, 1=first derivative, 2=second derivative
Int_t          fEndCond;    // 0=no end cond, 1=first derivative, 2=second derivative

void   BuildCoeff();
void   SetCond(const char *opt);

public:
TSpline3() : TSpline() , fPoly(0), fValBeg(0), fValEnd(0),
fBegCond(-1), fEndCond(-1) {}
TSpline3(const char *title,
Double_t x[], Double_t y[], Int_t n, const char *opt=0,
Double_t valbeg=0, Double_t valend=0);
TSpline3(const char *title,
Double_t xmin, Double_t xmax,
Double_t y[], Int_t n, const char *opt=0,
Double_t valbeg=0, Double_t valend=0);
TSpline3(const char *title,
Double_t x[], const TF1 *func, Int_t n, const char *opt=0,
Double_t valbeg=0, Double_t valend=0);
TSpline3(const char *title,
Double_t xmin, Double_t xmax,
const TF1 *func, Int_t n, const char *opt=0,
Double_t valbeg=0, Double_t valend=0);
TSpline3(const char *title,
const TGraph *g, const char *opt=0,
Double_t valbeg=0, Double_t valend=0);
TSpline3(const TH1 *h, const char *opt=0,
Double_t valbeg=0, Double_t valend=0);
TSpline3(const TSpline3&);
TSpline3& operator=(const TSpline3&);
Int_t    FindX(Double_t x) const;
Double_t Eval(Double_t x) const;
Double_t Derivative(Double_t x) const;
virtual ~TSpline3() {if (fPoly) delete [] fPoly;}
void GetCoeff(Int_t i, Double_t &x, Double_t &y, Double_t &b,
Double_t &c, Double_t &d) {x=fPoly[i].X();y=fPoly[i].Y();
b=fPoly[i].B();c=fPoly[i].C();d=fPoly[i].D();}
void GetKnot(Int_t i, Double_t &x, Double_t &y) const
{x=fPoly[i].X(); y=fPoly[i].Y();}
virtual  void     SaveAs(const char *filename,Option_t *option="") const;
virtual  void     SavePrimitive(ostream &out, Option_t *option = "");
virtual  void     SetPoint(Int_t i, Double_t x, Double_t y);
virtual  void     SetPointCoeff(Int_t i, Double_t b, Double_t c, Double_t d);
static void Test();

ClassDef (TSpline3,2)  // Class to create third natural splines
};

//______________________________________________________________________________
class TSpline5 : public TSpline
{
protected:
TSplinePoly5  *fPoly;     //[fNp] Array of polynomial terms

void BuildCoeff();
void BoundaryConditions(const char *opt, Int_t &beg, Int_t &end,
const char *&cb1, const char *&ce1, const char *&cb2,
const char *&ce2);
void SetBoundaries(Double_t b1, Double_t e1, Double_t b2, Double_t e2,
const char *cb1, const char *ce1, const char *cb2,
const char *ce2);
public:
TSpline5() : TSpline() , fPoly(0) {}
TSpline5(const char *title,
Double_t x[], Double_t y[], Int_t n,
const char *opt=0, Double_t b1=0, Double_t e1=0,
Double_t b2=0, Double_t e2=0);
TSpline5(const char *title,
Double_t xmin, Double_t xmax,
Double_t y[], Int_t n,
const char *opt=0, Double_t b1=0, Double_t e1=0,
Double_t b2=0, Double_t e2=0);
TSpline5(const char *title,
Double_t x[], const TF1 *func, Int_t n,
const char *opt=0, Double_t b1=0, Double_t e1=0,
Double_t b2=0, Double_t e2=0);
TSpline5(const char *title,
Double_t xmin, Double_t xmax,
const TF1 *func, Int_t n,
const char *opt=0, Double_t b1=0, Double_t e1=0,
Double_t b2=0, Double_t e2=0);
TSpline5(const char *title,
const TGraph *g,
const char *opt=0, Double_t b1=0, Double_t e1=0,
Double_t b2=0, Double_t e2=0);
TSpline5(const TH1 *h,
const char *opt=0, Double_t b1=0, Double_t e1=0,
Double_t b2=0, Double_t e2=0);
TSpline5(const TSpline5&);
TSpline5& operator=(const TSpline5&);
Int_t    FindX(Double_t x) const;
Double_t Eval(Double_t x) const;
Double_t Derivative(Double_t x) const;
virtual ~TSpline5() {if (fPoly) delete [] fPoly;}
void GetCoeff(Int_t i, Double_t &x, Double_t &y, Double_t &b,
Double_t &c, Double_t &d, Double_t &e, Double_t &f)
{x=fPoly[i].X();y=fPoly[i].Y();b=fPoly[i].B();
c=fPoly[i].C();d=fPoly[i].D();
e=fPoly[i].E();f=fPoly[i].F();}
void GetKnot(Int_t i, Double_t &x, Double_t &y) const
{x=fPoly[i].X(); y=fPoly[i].Y();}
virtual  void     SaveAs(const char *filename,Option_t *option="") const;
virtual  void     SavePrimitive(ostream &out, Option_t *option = "");
virtual  void     SetPoint(Int_t i, Double_t x, Double_t y);
virtual  void     SetPointCoeff(Int_t i, Double_t b, Double_t c, Double_t d,
Double_t e, Double_t f);
static void Test();

ClassDef (TSpline5,2) // Class to create quintic natural splines
};

#endif
```
TSpline.h:1
TSpline.h:2
TSpline.h:3
TSpline.h:4
TSpline.h:5
TSpline.h:6
TSpline.h:7
TSpline.h:8
TSpline.h:9
TSpline.h:10
TSpline.h:11
TSpline.h:12
TSpline.h:13
TSpline.h:14
TSpline.h:15
TSpline.h:16
TSpline.h:17
TSpline.h:18
TSpline.h:19
TSpline.h:20
TSpline.h:21
TSpline.h:22
TSpline.h:23
TSpline.h:24
TSpline.h:25
TSpline.h:26
TSpline.h:27
TSpline.h:28
TSpline.h:29
TSpline.h:30
TSpline.h:31
TSpline.h:32
TSpline.h:33
TSpline.h:34
TSpline.h:35
TSpline.h:36
TSpline.h:37
TSpline.h:38
TSpline.h:39
TSpline.h:40
TSpline.h:41
TSpline.h:42
TSpline.h:43
TSpline.h:44
TSpline.h:45
TSpline.h:46
TSpline.h:47
TSpline.h:48
TSpline.h:49
TSpline.h:50
TSpline.h:51
TSpline.h:52
TSpline.h:53
TSpline.h:54
TSpline.h:55
TSpline.h:56
TSpline.h:57
TSpline.h:58
TSpline.h:59
TSpline.h:60
TSpline.h:61
TSpline.h:62
TSpline.h:63
TSpline.h:64
TSpline.h:65
TSpline.h:66
TSpline.h:67
TSpline.h:68
TSpline.h:69
TSpline.h:70
TSpline.h:71
TSpline.h:72
TSpline.h:73
TSpline.h:74
TSpline.h:75
TSpline.h:76
TSpline.h:77
TSpline.h:78
TSpline.h:79
TSpline.h:80
TSpline.h:81
TSpline.h:82
TSpline.h:83
TSpline.h:84
TSpline.h:85
TSpline.h:86
TSpline.h:87
TSpline.h:88
TSpline.h:89
TSpline.h:90
TSpline.h:91
TSpline.h:92
TSpline.h:93
TSpline.h:94
TSpline.h:95
TSpline.h:96
TSpline.h:97
TSpline.h:98
TSpline.h:99
TSpline.h:100
TSpline.h:101
TSpline.h:102
TSpline.h:103
TSpline.h:104
TSpline.h:105
TSpline.h:106
TSpline.h:107
TSpline.h:108
TSpline.h:109
TSpline.h:110
TSpline.h:111
TSpline.h:112
TSpline.h:113
TSpline.h:114
TSpline.h:115
TSpline.h:116
TSpline.h:117
TSpline.h:118
TSpline.h:119
TSpline.h:120
TSpline.h:121
TSpline.h:122
TSpline.h:123
TSpline.h:124
TSpline.h:125
TSpline.h:126
TSpline.h:127
TSpline.h:128
TSpline.h:129
TSpline.h:130
TSpline.h:131
TSpline.h:132
TSpline.h:133
TSpline.h:134
TSpline.h:135
TSpline.h:136
TSpline.h:137
TSpline.h:138
TSpline.h:139
TSpline.h:140
TSpline.h:141
TSpline.h:142
TSpline.h:143
TSpline.h:144
TSpline.h:145
TSpline.h:146
TSpline.h:147
TSpline.h:148
TSpline.h:149
TSpline.h:150
TSpline.h:151
TSpline.h:152
TSpline.h:153
TSpline.h:154
TSpline.h:155
TSpline.h:156
TSpline.h:157
TSpline.h:158
TSpline.h:159
TSpline.h:160
TSpline.h:161
TSpline.h:162
TSpline.h:163
TSpline.h:164
TSpline.h:165
TSpline.h:166
TSpline.h:167
TSpline.h:168
TSpline.h:169
TSpline.h:170
TSpline.h:171
TSpline.h:172
TSpline.h:173
TSpline.h:174
TSpline.h:175
TSpline.h:176
TSpline.h:177
TSpline.h:178
TSpline.h:179
TSpline.h:180
TSpline.h:181
TSpline.h:182
TSpline.h:183
TSpline.h:184
TSpline.h:185
TSpline.h:186
TSpline.h:187
TSpline.h:188
TSpline.h:189
TSpline.h:190
TSpline.h:191
TSpline.h:192
TSpline.h:193
TSpline.h:194
TSpline.h:195
TSpline.h:196
TSpline.h:197
TSpline.h:198
TSpline.h:199
TSpline.h:200
TSpline.h:201
TSpline.h:202
TSpline.h:203
TSpline.h:204
TSpline.h:205
TSpline.h:206
TSpline.h:207
TSpline.h:208
TSpline.h:209
TSpline.h:210
TSpline.h:211
TSpline.h:212
TSpline.h:213
TSpline.h:214
TSpline.h:215
TSpline.h:216
TSpline.h:217
TSpline.h:218
TSpline.h:219
TSpline.h:220
TSpline.h:221
TSpline.h:222
TSpline.h:223
TSpline.h:224
TSpline.h:225
TSpline.h:226
TSpline.h:227
TSpline.h:228
TSpline.h:229
TSpline.h:230
TSpline.h:231
TSpline.h:232
TSpline.h:233
TSpline.h:234
TSpline.h:235
TSpline.h:236
TSpline.h:237
TSpline.h:238
TSpline.h:239
TSpline.h:240
TSpline.h:241
TSpline.h:242
TSpline.h:243
TSpline.h:244
TSpline.h:245
TSpline.h:246
TSpline.h:247
TSpline.h:248
TSpline.h:249
TSpline.h:250
TSpline.h:251
TSpline.h:252
TSpline.h:253
TSpline.h:254
TSpline.h:255
TSpline.h:256
TSpline.h:257
TSpline.h:258
TSpline.h:259
TSpline.h:260
TSpline.h:261
TSpline.h:262
TSpline.h:263
TSpline.h:264
TSpline.h:265
TSpline.h:266
TSpline.h:267
TSpline.h:268
TSpline.h:269
TSpline.h:270
TSpline.h:271
TSpline.h:272
TSpline.h:273
TSpline.h:274
TSpline.h:275
TSpline.h:276
TSpline.h:277
TSpline.h:278
TSpline.h:279
TSpline.h:280
TSpline.h:281
TSpline.h:282
TSpline.h:283
TSpline.h:284
TSpline.h:285
TSpline.h:286
TSpline.h:287
TSpline.h:288
TSpline.h:289
TSpline.h:290
TSpline.h:291
TSpline.h:292
TSpline.h:293
TSpline.h:294
TSpline.h:295
TSpline.h:296
TSpline.h:297
TSpline.h:298
TSpline.h:299
TSpline.h:300
TSpline.h:301
TSpline.h:302
TSpline.h:303
TSpline.h:304
TSpline.h:305
TSpline.h:306
TSpline.h:307
TSpline.h:308
TSpline.h:309
TSpline.h:310