Interpolate.cpp
上传用户:weigute
上传日期:2007-03-02
资源大小:1287k
文件大小:38k
源码类别:

数学计算

开发平台:

Visual C++

  1. //////////////////////////////////////////////////////////////////////
  2. // Interpolate.cpp
  3. //
  4. // 插值类 CInterpolate 的实现代码
  5. //
  6. // 周长发编制, 2002/8
  7. //////////////////////////////////////////////////////////////////////
  8. #include "stdafx.h"
  9. #include "Interpolate.h"
  10. #ifdef _DEBUG
  11. #undef THIS_FILE
  12. static char THIS_FILE[]=__FILE__;
  13. #define new DEBUG_NEW
  14. #endif
  15. //////////////////////////////////////////////////////////////////////
  16. // Construction/Destruction
  17. //////////////////////////////////////////////////////////////////////
  18. //////////////////////////////////////////////////////////////////////
  19. // 基本构造函数
  20. //////////////////////////////////////////////////////////////////////
  21. CInterpolate::CInterpolate()
  22. {
  23. }
  24. //////////////////////////////////////////////////////////////////////
  25. // 析构函数
  26. //////////////////////////////////////////////////////////////////////
  27. CInterpolate::~CInterpolate()
  28. {
  29. }
  30. //////////////////////////////////////////////////////////////////////
  31. // 将字符串转化为结点的值
  32. //
  33. // 参数:
  34. // 1. CString s - 数字和分隔符构成的字符串
  35. // 2. int n - 结点的个数
  36. // 3. double dblNodes[] - 一维数组,长度为n,返回结点的值
  37. // 4. const CString& sDelim - 数字之间的分隔符,默认为空格
  38. //
  39. // 返回值:int 型,转换成功的结点的个数
  40. //////////////////////////////////////////////////////////////////////
  41. int CInterpolate::GetNodesFromString(CString s, int n, double dblNodes[], const CString& sDelim /*= " "*/)
  42. {
  43. // 将结点值初始化为0
  44. memset(dblNodes, 0, n*sizeof(double));
  45. // 构造根据指定的分界符将字符串分解为不同的子串的对象
  46. CTokenizer tk(s, sDelim);
  47. CString sElement;
  48. // 分解字符串,给结点赋值
  49. int i = 0;
  50. while (tk.Next(sElement))
  51. {
  52. sElement.TrimLeft();
  53. sElement.TrimRight();
  54. double v = atof(sElement);
  55. dblNodes[i++] = v;
  56. if (i == n)
  57. break;
  58. }
  59. return i;
  60. }
  61. //////////////////////////////////////////////////////////////////////
  62. // 一元全区间不等距插值
  63. //
  64. // 参数:
  65. // 1. int n - 结点的个数
  66. // 2. double x[] - 一维数组,长度为n,存放给定的n个结点的值x(i),
  67. //                 要求x(0)<x(1)<...<x(n-1)
  68. // 3. double y[] - 一维数组,长度为n,存放给定的n个结点的函数值y(i),
  69. //                 y(i) = f(x(i)), i=0,1,...,n-1
  70. // 4. double t - 存放指定的插值点的值
  71. //
  72. // 返回值:double 型,指定的查指点t的函数近似值f(t)
  73. //////////////////////////////////////////////////////////////////////
  74. double CInterpolate::GetValueLagrange(int n, double x[], double y[], double t)
  75. int i,j,k,m;
  76.     double z,s;
  77. // 初值
  78.     z=0.0;
  79.     
  80. // 特例处理
  81. if (n<1) 
  82. return(z);
  83.     if (n==1) 
  84. z=y[0];
  85. return(z);
  86. }
  87.     
  88. if (n==2)
  89.     { 
  90. z=(y[0]*(t-x[1])-y[1]*(t-x[0]))/(x[0]-x[1]);
  91.         return(z);
  92.     }
  93.     
  94. // 开始插值
  95. i=0;
  96.     while ((x[i]<t)&&(i<n)) 
  97. i=i+1;
  98.     
  99. k=i-4;
  100.     if (k<0) 
  101. k=0;
  102.     
  103. m=i+3;
  104.     if (m>n-1) 
  105. m=n-1;
  106.     for (i=k;i<=m;i++)
  107.     { 
  108. s=1.0;
  109.         for (j=k;j<=m;j++)
  110. {
  111. if (j!=i) 
  112. // 拉格朗日插值公式
  113. s=s*(t-x[j])/(x[i]-x[j]);
  114. }
  115.         z=z+s*y[i];
  116.     }
  117.     
  118. return(z);
  119. }
  120. //////////////////////////////////////////////////////////////////////
  121. // 一元全区间等距插值
  122. //
  123. // 参数:
  124. // 1. int n - 结点的个数
  125. // 2. double x0 - 存放等距n个结点中第一个结点的值
  126. // 3. double xStep - 等距结点的步长
  127. // 4. double y[] - 一维数组,长度为n,存放给定的n个结点的函数值y(i),
  128. //                 y(i) = f(x(i)), i=0,1,...,n-1
  129. // 5. double t - 存放指定的插值点的值
  130. //
  131. // 返回值:double 型,指定的查指点t的函数近似值f(t)
  132. //////////////////////////////////////////////////////////////////////
  133. double CInterpolate::GetValueLagrange(int n, double x0, double xStep, double y[], double t)
  134. int i,j,k,m;
  135.     double z,s,xi,xj;
  136.     float p,q;
  137.     
  138. // 初值
  139. z=0.0;
  140.     
  141. // 特例处理
  142. if (n<1) 
  143. return(z);
  144.     if (n==1) 
  145. z=y[0]; 
  146. return(z);
  147. }
  148.     if (n==2)
  149.     { 
  150. z=(y[1]*(t-x0)-y[0]*(t-x0-xStep))/xStep;
  151.         return(z);
  152.     }
  153.     
  154. // 开始插值
  155. if (t>x0)
  156.     { 
  157. p=(t-x0)/xStep; 
  158. i=(int)p; 
  159. q=(float)i;
  160.         
  161. if (p>q) 
  162. i=i+1;
  163.     }
  164.     else 
  165. i=0;
  166.     
  167. k=i-4;
  168.     if (k<0) 
  169. k=0;
  170.     
  171. m=i+3;
  172.     if (m>n-1) 
  173. m=n-1;
  174.     
  175. for (i=k;i<=m;i++)
  176.     { 
  177. s=1.0; 
  178. xi=x0+i*xStep;
  179.         
  180. for (j=k; j<=m; j++)
  181.         {
  182. if (j!=i)
  183.             { 
  184. xj=x0+j*xStep;
  185.                 // 拉格朗日插值公式
  186. s=s*(t-xj)/(xi-xj);
  187.             }
  188. }
  189.         z=z+s*y[i];
  190.     }
  191.     
  192. return(z);
  193. }
  194. //////////////////////////////////////////////////////////////////////
  195. // 一元三点不等距插值
  196. //
  197. // 参数:
  198. // 1. int n - 结点的个数
  199. // 2. double x[] - 一维数组,长度为n,存放给定的n个结点的值x(i)
  200. // 3. double y[] - 一维数组,长度为n,存放给定的n个结点的函数值y(i),
  201. //                 y(i) = f(x(i)), i=0,1,...,n-1
  202. // 4. double t - 存放指定的插值点的值
  203. //
  204. // 返回值:double 型,指定的查指点t的函数近似值f(t)
  205. //////////////////////////////////////////////////////////////////////
  206. double CInterpolate::GetValueLagrange3(int n, double x[], double y[], double t)
  207. int i,j,k,m;
  208.     double z,s;
  209.     
  210. // 初值
  211. z=0.0;
  212.     
  213. // 特例处理
  214. if (n<1) 
  215. return(z);
  216.     if (n==1) 
  217. z=y[0]; 
  218. return(z);
  219. }
  220.     if (n==2)
  221.     { 
  222. z=(y[0]*(t-x[1])-y[1]*(t-x[0]))/(x[0]-x[1]);
  223.         return(z);
  224.     }
  225.     
  226. // 开始插值
  227. if (t<=x[1]) 
  228. k=0; 
  229. m=2;
  230. }
  231.     else if (t>=x[n-2]) 
  232. k=n-3; 
  233. m=n-1;
  234. }
  235.     else
  236.     { 
  237. k=1; 
  238. m=n;
  239.         while (m-k!=1)
  240.         { 
  241. i=(k+m)/2;
  242.             
  243. if (t<x[i-1]) 
  244. m=i;
  245.             else 
  246. k=i;
  247.         }
  248.         
  249. k=k-1; 
  250. m=m-1;
  251.         
  252. if (fabs(t-x[k])<fabs(t-x[m])) 
  253. k=k-1;
  254.         else 
  255. m=m+1;
  256.     }
  257.     
  258. z=0.0;
  259.     for (i=k;i<=m;i++)
  260.     { 
  261. s=1.0;
  262.         for (j=k;j<=m;j++)
  263.         {
  264. if (j!=i) 
  265.                 // 抛物线插值公式
  266. s=s*(t-x[j])/(x[i]-x[j]);
  267. }
  268.         z=z+s*y[i];
  269.     }
  270.     
  271. return(z);
  272. }
  273. //////////////////////////////////////////////////////////////////////
  274. // 一元三点等距插值
  275. //
  276. // 参数:
  277. // 1. int n - 结点的个数
  278. // 2. double x0 - 存放等距n个结点中第一个结点的值
  279. // 3. double xStep - 等距结点的步长
  280. // 4. double y[] - 一维数组,长度为n,存放给定的n个结点的函数值y(i),
  281. //                 y(i) = f(x(i)), i=0,1,...,n-1
  282. // 5. double t - 存放指定的插值点的值
  283. //
  284. // 返回值:double 型,指定的查指点t的函数近似值f(t)
  285. //////////////////////////////////////////////////////////////////////
  286. double CInterpolate::GetValueLagrange3(int n, double x0, double xStep, double y[], double t)
  287. int i,j,k,m;
  288.     double z,s,xi,xj;
  289.     
  290. // 初值
  291. z=0.0;
  292.     
  293. // 特例处理
  294. if (n<1) 
  295. return(z);
  296.     if (n==1) 
  297. z=y[0]; 
  298. return(z);
  299. }
  300.     if (n==2)
  301.     { 
  302. z=(y[1]*(t-x0)-y[0]*(t-x0-xStep))/xStep;
  303.         return(z);
  304.     }
  305.     
  306. // 开始插值
  307. if (t<=x0+xStep) 
  308. k=0; 
  309. m=2;
  310. }
  311.     else if (t>=x0+(n-3)*xStep) 
  312. k=n-3; 
  313. m=n-1;
  314. }
  315.     else
  316.     { 
  317. i=(int)((t-x0)/xStep)+1;
  318.         if (fabs(t-x0-i*xStep)>=fabs(t-x0-(i-1)*xStep))
  319.         { 
  320. k=i-2; 
  321. m=i;
  322. }
  323.         else 
  324. {
  325. k=i-1; 
  326. m=i+1;
  327. }
  328.     }
  329.     
  330. z=0.0;
  331.     for (i=k;i<=m;i++)
  332.     { 
  333. s=1.0; 
  334. xi=x0+i*xStep;
  335.         for (j=k;j<=m;j++)
  336.         {
  337. if (j!=i)
  338.             { 
  339. xj=x0+j*xStep; 
  340.                 // 抛物线插值公式
  341. s=s*(t-xj)/(xi-xj);
  342. }
  343. }
  344.         z=z+s*y[i];
  345.     }
  346.     
  347. return(z);
  348. }
  349. //////////////////////////////////////////////////////////////////////
  350. // 连分式不等距插值
  351. //
  352. // 参数:
  353. // 1. int n - 结点的个数
  354. // 2. double x[] - 一维数组,长度为n,存放给定的n个结点的值x(i)
  355. // 3. double y[] - 一维数组,长度为n,存放给定的n个结点的函数值y(i),
  356. //                 y(i) = f(x(i)), i=0,1,...,n-1
  357. // 4. double t - 存放指定的插值点的值
  358. //
  359. // 返回值:double 型,指定的查指点t的函数近似值f(t)
  360. //////////////////////////////////////////////////////////////////////
  361. double CInterpolate::GetValuePqs(int n, double x[], double y[], double t)
  362. int i,j,k,m,l;
  363.     double z,h,b[8];
  364.     
  365. // 初值
  366. z=0.0;
  367.     
  368. // 特例处理
  369. if (n<1) 
  370. return(z);
  371.     if (n==1) 
  372. z=y[0]; 
  373. return(z);
  374. }
  375.     
  376. // 连分式插值
  377. if (n<=8) 
  378. k=0; 
  379. m=n;
  380. }
  381.     else if (t<x[4]) 
  382. k=0; 
  383. m=8;
  384. }
  385.     else if (t>x[n-5]) 
  386. k=n-8; 
  387. m=8;
  388. }
  389.     else
  390.     { 
  391. k=1; 
  392. j=n;
  393.         
  394. while (j-k!=1)
  395.         { 
  396. i=(k+j)/2;
  397.             if (t<x[i-1]) 
  398. j=i;
  399.             else 
  400. k=i;
  401.         }
  402.         
  403. k=k-4; 
  404. m=8;
  405.     }
  406.     
  407. b[0]=y[k];
  408.     for (i=2;i<=m;i++)
  409.     { 
  410. h=y[i+k-1]; 
  411. l=0; 
  412. j=1;
  413.         
  414. while ((l==0)&&(j<=i-1))
  415.         { 
  416. if (fabs(h-b[j-1])+1.0==1.0) 
  417. l=1;
  418.             else 
  419. h=(x[i+k-1]-x[j+k-1])/(h-b[j-1]);
  420.               
  421. j=j+1;
  422.         }
  423.         
  424. b[i-1]=h;
  425.         
  426. if (l!=0) 
  427. b[i-1]=1.0e+35;
  428.     }
  429.     
  430. z=b[m-1];
  431.     for (i=m-1;i>=1;i--) 
  432. z=b[i-1]+(t-x[i+k-1])/z;
  433.     
  434. return(z);
  435. }
  436. //////////////////////////////////////////////////////////////////////
  437. // 连分式等距插值
  438. //
  439. // 参数:
  440. // 1. int n - 结点的个数
  441. // 2. double x0 - 存放等距n个结点中第一个结点的值
  442. // 3. double xStep - 等距结点的步长
  443. // 4. double y[] - 一维数组,长度为n,存放给定的n个结点的函数值y(i),
  444. //                 y(i) = f(x(i)), i=0,1,...,n-1
  445. // 5. double t - 存放指定的插值点的值
  446. //
  447. // 返回值:double 型,指定的查指点t的函数近似值f(t)
  448. //////////////////////////////////////////////////////////////////////
  449. double CInterpolate::GetValuePqs(int n, double x0, double xStep, double y[], double t)
  450. int i,j,k,m,l;
  451.     double z,hh,xi,xj,b[8];
  452.     
  453. // 初值
  454. z=0.0;
  455.     
  456. // 特例处理
  457. if (n<1) 
  458. return(z);
  459.     if (n==1) 
  460. z=y[0]; 
  461. return(z);
  462. }
  463.     
  464. // 连分式插值
  465. if (n<=8) 
  466. k=0; 
  467. m=n;
  468. }
  469.     else if (t<(x0+4.0*xStep)) 
  470. k=0; 
  471. m=8;
  472. }
  473.     else if (t>(x0+(n-5)*xStep)) 
  474. k=n-8; 
  475. m=8;
  476. }
  477.     else 
  478. k=(int)((t-x0)/xStep)-3; 
  479. m=8;
  480. }
  481.     
  482. b[0]=y[k];
  483.     for (i=2;i<=m;i++)
  484.     { 
  485. hh=y[i+k-1]; 
  486. l=0; 
  487. j=1;
  488.         
  489. while ((l==0)&&(j<=i-1))
  490.         { 
  491. if (fabs(hh-b[j-1])+1.0==1.0) 
  492. l=1;
  493.             else
  494.             { 
  495. xi=x0+(i+k-1)*xStep;
  496.                 xj=x0+(j+k-1)*xStep;
  497.                 hh=(xi-xj)/(hh-b[j-1]);
  498.             }
  499.         
  500. j=j+1;
  501.         }
  502.         b[i-1]=hh;
  503.         if (l!=0) 
  504. b[i-1]=1.0e+35;
  505.     }
  506.     
  507. z=b[m-1];
  508.     for (i=m-1;i>=1;i--)
  509. z=b[i-1]+(t-(x0+(i+k-1)*xStep))/z;
  510.     
  511. return(z);
  512. }
  513. //////////////////////////////////////////////////////////////////////
  514. // 埃尔米特不等距插值
  515. //
  516. // 参数:
  517. // 1. int n - 结点的个数
  518. // 2. double x[] - 一维数组,长度为n,存放给定的n个结点的值x(i)
  519. // 3. double y[] - 一维数组,长度为n,存放给定的n个结点的函数值y(i),
  520. //                 y(i) = f(x(i)), i=0,1,...,n-1
  521. // 4. double dy[] - 一维数组,长度为n,存放给定的n个结点的函数导数值y'(i),
  522. //                 y'(i) = f'(x(i)), i=0,1,...,n-1
  523. // 5. double t - 存放指定的插值点的值
  524. //
  525. // 返回值:double 型,指定的查指点t的函数近似值f(t)
  526. //////////////////////////////////////////////////////////////////////
  527. double CInterpolate::GetValueHermite(int n, double x[], double y[], double dy[], double t)
  528. int i,j;
  529.     double z,p,q,s;
  530.     
  531. // 初值
  532. z=0.0;
  533.     
  534. // 循环插值
  535. for (i=1;i<=n;i++)
  536.     { 
  537. s=1.0;
  538.         
  539. for (j=1;j<=n;j++)
  540. {
  541. if (j!=i) 
  542. s=s*(t-x[j-1])/(x[i-1]-x[j-1]);
  543. }
  544.         s=s*s;
  545.         p=0.0;
  546.         
  547. for (j=1;j<=n;j++)
  548.         {
  549. if (j!=i) 
  550. p=p+1.0/(x[i-1]-x[j-1]);
  551. }
  552.         q=y[i-1]+(t-x[i-1])*(dy[i-1]-2.0*y[i-1]*p);
  553.         z=z+q*s;
  554.     }
  555.     
  556. return(z);
  557. }
  558. //////////////////////////////////////////////////////////////////////
  559. // 埃尔米特等距插值
  560. //
  561. // 参数:
  562. // 1. int n - 结点的个数
  563. // 2. double x0 - 存放等距n个结点中第一个结点的值
  564. // 3. double xStep - 等距结点的步长
  565. // 4. double y[] - 一维数组,长度为n,存放给定的n个结点的函数值y(i),
  566. //                 y(i) = f(x(i)), i=0,1,...,n-1
  567. // 4. double dy[] - 一维数组,长度为n,存放给定的n个结点的函数导数值y'(i),
  568. //                 y'(i) = f'(x(i)), i=0,1,...,n-1
  569. // 5. double t - 存放指定的插值点的值
  570. //
  571. // 返回值:double 型,指定的查指点t的函数近似值f(t)
  572. //////////////////////////////////////////////////////////////////////
  573. double CInterpolate::GetValueHermite(int n, double x0, double xStep, double y[], double dy[], double t)
  574. int i,j;
  575.     double z,s,p,q;
  576.     
  577. // 初值
  578. z=0.0;
  579.     
  580. // 循环插值
  581. for (i=1;i<=n;i++)
  582.     { 
  583. s=1.0; 
  584. q=x0+(i-1)*xStep;
  585.         
  586. for (j=1;j<=n;j++)
  587.         { 
  588. p=x0+(j-1)*xStep;
  589.             if (j!=i) 
  590. s=s*(t-p)/(q-p);
  591.         }
  592.         
  593. s=s*s;
  594.         p=0.0;
  595.         
  596. for (j=1;j<=n;j++)
  597.         {
  598. if (j!=i) 
  599. p=p+1.0/(q-(x0+(j-1)*xStep));
  600. }
  601.         q=y[i-1]+(t-q)*(dy[i-1]-2.0*y[i-1]*p);
  602.         z=z+q*s;
  603.     }
  604.     
  605. return(z);
  606. }
  607. //////////////////////////////////////////////////////////////////////
  608. // 埃特金不等距逐步插值
  609. //
  610. // 参数:
  611. // 1. int n - 结点的个数
  612. // 2. double x[] - 一维数组,长度为n,存放给定的n个结点的值x(i)
  613. // 3. double y[] - 一维数组,长度为n,存放给定的n个结点的函数值y(i),
  614. //                 y(i) = f(x(i)), i=0,1,...,n-1
  615. // 4. double t - 存放指定的插值点的值
  616. // 5. double eps - 控制精度参数,默认值为0.000001
  617. //
  618. // 返回值:double 型,指定的查指点t的函数近似值f(t)
  619. //////////////////////////////////////////////////////////////////////
  620. double CInterpolate::GetValueAitken(int n, double x[], double y[], double t, double eps /*= 0.000001*/)
  621. int i,j,k,m,l;
  622.     double z,xx[10],yy[10];
  623.     
  624. // 初值
  625. z=0.0;
  626.     
  627. // 特例处理
  628. if (n<1) 
  629. return(z);
  630.     if (n==1) 
  631. z=y[0]; 
  632. return(z);
  633. }
  634.     
  635. // 开始插值
  636. m=10;
  637.     if (m>n) 
  638. m=n;
  639.     
  640. if (t<=x[0]) 
  641. k=1;
  642.     else if (t>=x[n-1]) 
  643. k=n;
  644.     else
  645.     { 
  646. k=1; 
  647. j=n;
  648.         
  649. while ((k-j!=1)&&(k-j!=-1))
  650.         { 
  651. l=(k+j)/2;
  652.             if (t<x[l-1]) 
  653. j=l;
  654.             else 
  655. k=l;
  656.         }
  657.         
  658. if (fabs(t-x[l-1])>fabs(t-x[j-1])) 
  659. k=j;
  660.     }
  661.     
  662. j=1; 
  663. l=0;
  664.     
  665. for (i=1;i<=m;i++)
  666.     { 
  667. k=k+j*l;
  668.         if ((k<1)||(k>n))
  669.         { 
  670. l=l+1; 
  671. j=-j; 
  672. k=k+j*l;
  673. }
  674.         
  675. xx[i-1]=x[k-1]; 
  676. yy[i-1]=y[k-1];
  677.         l=l+1; 
  678. j=-j;
  679.     }
  680.     
  681. i=0;
  682.     
  683. do
  684.     { 
  685. i=i+1; 
  686. z=yy[i];
  687.         
  688. for (j=0;j<=i-1;j++)
  689. z=yy[j]+(t-xx[j])*(yy[j]-z)/(xx[j]-xx[i]);
  690.         
  691. yy[i]=z;
  692.     } while ((i!=m-1)&&(fabs(yy[i]-yy[i-1])>eps));
  693.     
  694. return(z);
  695. }
  696. //////////////////////////////////////////////////////////////////////
  697. // 埃特金等距逐步插值
  698. //
  699. // 参数:
  700. // 1. int n - 结点的个数
  701. // 2. double x0 - 存放等距n个结点中第一个结点的值
  702. // 3. double xStep - 等距结点的步长
  703. // 4. double y[] - 一维数组,长度为n,存放给定的n个结点的函数值y(i),
  704. //                 y(i) = f(x(i)), i=0,1,...,n-1
  705. // 5. double t - 存放指定的插值点的值
  706. // 6. double eps - 控制精度参数,默认值为0.000001
  707. //
  708. // 返回值:double 型,指定的查指点t的函数近似值f(t)
  709. //////////////////////////////////////////////////////////////////////
  710. double CInterpolate::GetValueAitken(int n, double x0, double xStep, double y[], double t, double eps /*= 0.000001*/)
  711. int i,j,k,m,l;
  712.     double z,xx[10],yy[10];
  713.     
  714. // 初值
  715. z=0.0;
  716.     
  717. // 特例处理
  718. if (n<1) 
  719. return(z);
  720.     if (n==1) 
  721. z=y[0]; 
  722. return(z);
  723. }
  724.     
  725. // 开始插值
  726. m=10;
  727.     if (m>n) 
  728. m=n;
  729.     
  730. if (t<=x0) 
  731. k=1;
  732.     else if (t>=x0+(n-1)*xStep) 
  733. k=n;
  734.     else
  735.     { 
  736. k=1; 
  737. j=n;
  738.         
  739. while ((k-j!=1)&&(k-j!=-1))
  740.         { 
  741. l=(k+j)/2;
  742.             
  743. if (t<x0+(l-1)*xStep) 
  744. j=l;
  745.             else 
  746. k=l;
  747.         }
  748.         
  749. if (fabs(t-(x0+(l-1)*xStep))>fabs(t-(x0+(j-1)*xStep))) 
  750. k=j;
  751.     }
  752.     
  753. j=1; 
  754. l=0;
  755.     for (i=1;i<=m;i++)
  756.     { 
  757. k=k+j*l;
  758.         if ((k<1)||(k>n))
  759.         { 
  760. l=l+1; 
  761. j=-j; 
  762. k=k+j*l;
  763. }
  764.         
  765. xx[i-1]=x0+(k-1)*xStep; 
  766. yy[i-1]=y[k-1];
  767.         l=l+1; 
  768. j=-j;
  769.     }
  770.     
  771. i=0;
  772.     do
  773.     { 
  774. i=i+1; 
  775. z=yy[i];
  776.         
  777. for (j=0;j<=i-1;j++)
  778. z=yy[j]+(t-xx[j])*(yy[j]-z)/(xx[j]-xx[i]);
  779.         
  780. yy[i]=z;
  781.     } while ((i!=m-1)&&(fabs(yy[i]-yy[i-1])>eps));
  782.     
  783. return(z);
  784. }
  785. //////////////////////////////////////////////////////////////////////
  786. // 光滑不等距插值
  787. //
  788. // 参数:
  789. // 1. int n - 结点的个数
  790. // 2. double x[] - 一维数组,长度为n,存放给定的n个结点的值x(i)
  791. // 3. double y[] - 一维数组,长度为n,存放给定的n个结点的函数值y(i),
  792. //                 y(i) = f(x(i)), i=0,1,...,n-1
  793. // 4. double t - 存放指定的插值点的值
  794. // 5. double s[] - 一维数组,长度为5,其中s(0),s(1),s(2),s(3)返回三次多项式的系数,
  795. // s(4)返回指定插值点t处的函数近似值f(t)(k<0时)或任意值(k>=0时)
  796. // 6. int k - 控制参数,若k>=0,则只计算第k个子区间[x(k), x(k+1)]上的三次多项式的系数
  797. //
  798. // 返回值:double 型,指定的查指点t的函数近似值f(t)
  799. //////////////////////////////////////////////////////////////////////
  800. double CInterpolate::GetValueAkima(int n, double x[], double y[], double t, double s[], int k /*= -1*/)
  801. int kk,m,l;
  802.     double u[5],p,q;
  803.     
  804. // 初值
  805. s[4]=0.0; 
  806. s[0]=0.0; 
  807. s[1]=0.0; 
  808. s[2]=0.0; 
  809. s[3]=0.0;
  810.     
  811. // 特例处理
  812. if (n<1) 
  813. return s[4];
  814.     if (n==1) 
  815. s[0]=y[0]; 
  816. s[4]=y[0]; 
  817. return s[4];
  818. }
  819.     if (n==2)
  820.     { 
  821. s[0]=y[0]; 
  822. s[1]=(y[1]-y[0])/(x[1]-x[0]);
  823.         if (k<0)
  824. s[4]=(y[0]*(t-x[1])-y[1]*(t-x[0]))/(x[0]-x[1]);
  825.         return s[4];
  826.     }
  827.     
  828. // 插值
  829. if (k<0)
  830.     { 
  831. if (t<=x[1]) 
  832. kk=0;
  833.         else if (t>=x[n-1]) 
  834. kk=n-2;
  835.         else
  836.         { 
  837. kk=1; 
  838. m=n;
  839.             while (((kk-m)!=1)&&((kk-m)!=-1))
  840.             { 
  841. l=(kk+m)/2;
  842.                 if (t<x[l-1]) 
  843. m=l;
  844.                 else 
  845. kk=l;
  846.             }
  847.             
  848. kk=kk-1;
  849.         }
  850.     }
  851.     else 
  852. kk=k;
  853.     
  854. if (kk>=n-1) 
  855. kk=n-2;
  856.     
  857. u[2]=(y[kk+1]-y[kk])/(x[kk+1]-x[kk]);
  858.     if (n==3)
  859.     { 
  860. if (kk==0)
  861.         { 
  862. u[3]=(y[2]-y[1])/(x[2]-x[1]);
  863.             u[4]=2.0*u[3]-u[2];
  864.             u[1]=2.0*u[2]-u[3];
  865.             u[0]=2.0*u[1]-u[2];
  866.         }
  867.         else
  868.         { 
  869. u[1]=(y[1]-y[0])/(x[1]-x[0]);
  870.             u[0]=2.0*u[1]-u[2];
  871.             u[3]=2.0*u[2]-u[1];
  872.             u[4]=2.0*u[3]-u[2];
  873.         }
  874.     }
  875.     else
  876.     { 
  877. if (kk<=1)
  878.         { 
  879. u[3]=(y[kk+2]-y[kk+1])/(x[kk+2]-x[kk+1]);
  880.             if (kk==1)
  881.             { 
  882. u[1]=(y[1]-y[0])/(x[1]-x[0]);
  883.                 u[0]=2.0*u[1]-u[2];
  884.                 
  885. if (n==4) 
  886. u[4]=2.0*u[3]-u[2];
  887.                 else 
  888. u[4]=(y[4]-y[3])/(x[4]-x[3]);
  889.             }
  890.             else
  891.             { 
  892. u[1]=2.0*u[2]-u[3];
  893.                 u[0]=2.0*u[1]-u[2];
  894.                 u[4]=(y[3]-y[2])/(x[3]-x[2]);
  895.             }
  896.         }
  897.         else if (kk>=(n-3))
  898.         { 
  899. u[1]=(y[kk]-y[kk-1])/(x[kk]-x[kk-1]);
  900.             if (kk==(n-3))
  901.             { 
  902. u[3]=(y[n-1]-y[n-2])/(x[n-1]-x[n-2]);
  903.                 u[4]=2.0*u[3]-u[2];
  904.                 if (n==4) 
  905. u[0]=2.0*u[1]-u[2];
  906.                 else 
  907. u[0]=(y[kk-1]-y[kk-2])/(x[kk-1]-x[kk-2]);
  908.             }
  909.             else
  910.             { 
  911. u[3]=2.0*u[2]-u[1];
  912.                 u[4]=2.0*u[3]-u[2];
  913.                 u[0]=(y[kk-1]-y[kk-2])/(x[kk-1]-x[kk-2]);
  914.             }
  915.         }
  916.         else
  917.         { 
  918. u[1]=(y[kk]-y[kk-1])/(x[kk]-x[kk-1]);
  919.             u[0]=(y[kk-1]-y[kk-2])/(x[kk-1]-x[kk-2]);
  920.             u[3]=(y[kk+2]-y[kk+1])/(x[kk+2]-x[kk+1]);
  921.             u[4]=(y[kk+3]-y[kk+2])/(x[kk+3]-x[kk+2]);
  922.         }
  923.     }
  924.     
  925. s[0]=fabs(u[3]-u[2]);
  926.     s[1]=fabs(u[0]-u[1]);
  927.     if ((s[0]+1.0==1.0)&&(s[1]+1.0==1.0))
  928.          p=(u[1]+u[2])/2.0;
  929.     else 
  930. p=(s[0]*u[1]+s[1]*u[2])/(s[0]+s[1]);
  931.     
  932. s[0]=fabs(u[3]-u[4]);
  933.     s[1]=fabs(u[2]-u[1]);
  934.     if ((s[0]+1.0==1.0)&&(s[1]+1.0==1.0))
  935.         q=(u[2]+u[3])/2.0;
  936.     else 
  937. q=(s[0]*u[2]+s[1]*u[3])/(s[0]+s[1]);
  938.     
  939. s[0]=y[kk];
  940.     s[1]=p;
  941.     s[3]=x[kk+1]-x[kk];
  942.     s[2]=(3.0*u[2]-2.0*p-q)/s[3];
  943.     s[3]=(q+p-2.0*u[2])/(s[3]*s[3]);
  944.     if (k<0)
  945.     { 
  946. p=t-x[kk];
  947.         s[4]=s[0]+s[1]*p+s[2]*p*p+s[3]*p*p*p;
  948.     }
  949.     
  950. return s[4];
  951. }
  952. //////////////////////////////////////////////////////////////////////
  953. // 光滑等距插值
  954. //
  955. // 参数:
  956. // 1. int n - 结点的个数
  957. // 2. double x0 - 存放等距n个结点中第一个结点的值
  958. // 3. double xStep - 等距结点的步长
  959. // 4. double y[] - 一维数组,长度为n,存放给定的n个结点的函数值y(i),
  960. //                 y(i) = f(x(i)), i=0,1,...,n-1
  961. // 5. double t - 存放指定的插值点的值
  962. // 5. double s[] - 一维数组,长度为5,其中s(0),s(1),s(2),s(3)返回三次多项式的系数,
  963. // s(4)返回指定插值点t处的函数近似值f(t)(k<0时)或任意值(k>=0时)
  964. // 6. int k - 控制参数,若k>=0,则只计算第k个子区间[x(k), x(k+1)]上的三次多项式的系数
  965. //
  966. // 返回值:double 型,指定的查指点t的函数近似值f(t)
  967. //////////////////////////////////////////////////////////////////////
  968. double CInterpolate::GetValueAkima(int n, double x0, double xStep, double y[], double t, double s[], int k /*= -1*/)
  969. int kk,m,l;
  970.     double u[5],p,q;
  971.     
  972. // 初值
  973. s[4]=0.0; 
  974. s[0]=0.0; 
  975. s[1]=0.0; 
  976. s[2]=0.0; 
  977. s[3]=0.0;
  978.     
  979. // 特例处理
  980. if (n<1) 
  981. return s[4];
  982.     if (n==1) 
  983. s[0]=y[0]; 
  984. s[4]=y[0]; 
  985. return s[4];
  986. }
  987.     if (n==2)
  988.     { 
  989. s[0]=y[0]; 
  990. s[1]=(y[1]-y[0])/xStep;
  991.         if (k<0)
  992. s[4]=(y[1]*(t-x0)-y[0]*(t-x0-xStep))/xStep;
  993.         return s[4];
  994.     }
  995.     
  996. // 插值
  997. if (k<0)
  998.     { 
  999. if (t<=x0+xStep) 
  1000. kk=0;
  1001.         else if (t>=x0+(n-1)*xStep) 
  1002. kk=n-2;
  1003.         else
  1004.         { 
  1005. kk=1; 
  1006. m=n;
  1007.             while (((kk-m)!=1)&&((kk-m)!=-1))
  1008.             { 
  1009. l=(kk+m)/2;
  1010.                 if (t<x0+(l-1)*xStep) 
  1011. m=l;
  1012.                 else 
  1013. kk=l;
  1014.             }
  1015.             
  1016. kk=kk-1;
  1017.         }
  1018.     }
  1019.     else 
  1020. kk=k;
  1021.     
  1022. if (kk>=n-1) 
  1023. kk=n-2;
  1024.     
  1025. u[2]=(y[kk+1]-y[kk])/xStep;
  1026.     if (n==3)
  1027.     { 
  1028. if (kk==0)
  1029.         { 
  1030. u[3]=(y[2]-y[1])/xStep;
  1031.             u[4]=2.0*u[3]-u[2];
  1032.             u[1]=2.0*u[2]-u[3];
  1033.             u[0]=2.0*u[1]-u[2];
  1034.         }
  1035.         else
  1036.         { 
  1037. u[1]=(y[1]-y[0])/xStep;
  1038.             u[0]=2.0*u[1]-u[2];
  1039.             u[3]=2.0*u[2]-u[1];
  1040.             u[4]=2.0*u[3]-u[2];
  1041.         }
  1042.     }
  1043.     else
  1044.     { 
  1045. if (kk<=1)
  1046.         { 
  1047. u[3]=(y[kk+2]-y[kk+1])/xStep;
  1048.             if (kk==1)
  1049.             { 
  1050. u[1]=(y[1]-y[0])/xStep;
  1051.                 u[0]=2.0*u[1]-u[2];
  1052.                 if (n==4) 
  1053. u[4]=2.0*u[3]-u[2];
  1054.                 else 
  1055. u[4]=(y[4]-y[3])/xStep;
  1056.             }
  1057.             else
  1058.             { 
  1059. u[1]=2.0*u[2]-u[3];
  1060.                 u[0]=2.0*u[1]-u[2];
  1061.                 u[4]=(y[3]-y[2])/xStep;
  1062.             }
  1063.         }
  1064.         else if (kk>=(n-3))
  1065.         { 
  1066. u[1]=(y[kk]-y[kk-1])/xStep;
  1067.             if (kk==(n-3))
  1068.             { 
  1069. u[3]=(y[n-1]-y[n-2])/xStep;
  1070.                 u[4]=2.0*u[3]-u[2];
  1071.                 if (n==4) 
  1072. u[0]=2.0*u[1]-u[2];
  1073.                 else 
  1074. u[0]=(y[kk-1]-y[kk-2])/xStep;
  1075.             }
  1076.             else
  1077.             { 
  1078. u[3]=2.0*u[2]-u[1];
  1079.                 u[4]=2.0*u[3]-u[2];
  1080.                 u[0]=(y[kk-1]-y[kk-2])/xStep;
  1081.             }
  1082.         }
  1083.         else
  1084.         { 
  1085. u[1]=(y[kk]-y[kk-1])/xStep;
  1086.             u[0]=(y[kk-1]-y[kk-2])/xStep;
  1087.             u[3]=(y[kk+2]-y[kk+1])/xStep;
  1088.             u[4]=(y[kk+3]-y[kk+2])/xStep;
  1089.         }
  1090.     }
  1091.     
  1092. s[0]=fabs(u[3]-u[2]);
  1093.     s[1]=fabs(u[0]-u[1]);
  1094.     if ((s[0]+1.0==1.0)&&(s[1]+1.0==1.0))
  1095. p=(u[1]+u[2])/2.0;
  1096.     else 
  1097. p=(s[0]*u[1]+s[1]*u[2])/(s[0]+s[1]);
  1098.     
  1099. s[0]=fabs(u[3]-u[4]);
  1100.     s[1]=fabs(u[2]-u[1]);
  1101.     if ((s[0]+1.0==1.0)&&(s[1]+1.0==1.0))
  1102. q=(u[2]+u[3])/2.0;
  1103.     else 
  1104. q=(s[0]*u[2]+s[1]*u[3])/(s[0]+s[1]);
  1105.     
  1106. s[0]=y[kk];
  1107.     s[1]=p;
  1108.     s[3]=xStep;
  1109.     s[2]=(3.0*u[2]-2.0*p-q)/s[3];
  1110.     s[3]=(q+p-2.0*u[2])/(s[3]*s[3]);
  1111.     
  1112. if (k<0)
  1113.     { 
  1114. p=t-(x0+kk*xStep);
  1115.         s[4]=s[0]+s[1]*p+s[2]*p*p+s[3]*p*p*p;
  1116.     }
  1117.     
  1118. return s[4];
  1119. }
  1120. //////////////////////////////////////////////////////////////////////
  1121. // 第一种边界条件的三次样条函数插值、微商与积分
  1122. //
  1123. // 参数:
  1124. // 1. int n - 结点的个数
  1125. // 2. double x[] - 一维数组,长度为n,存放给定的n个结点的值x(i)
  1126. // 3. double y[] - 一维数组,长度为n,存放给定的n个结点的函数值y(i),
  1127. //                 y(i) = f(x(i)), i=0,1,...,n-1
  1128. // 4. double dy[] - 一维数组,长度为n,调用时,dy(0)存放给定区间的左端点处的一阶导数值,
  1129. //                  dy(n-1)存放给定区间的右端点处的一阶导数值。返回时,存放n个给定点处的
  1130. //                  一阶导数值y'(i),i=0,1,...,n-1
  1131. // 5. double ddy[] - 一维数组,长度为n,返回时,存放n个给定点处的二阶导数值y''(i),
  1132. //                  i=0,1,...,n-1
  1133. // 6. int m - 指定插值点的个数
  1134. // 7. double t[] - 一维数组,长度为m,存放m个指定的插值点的值。
  1135. //                 要求x(0)<t(j)<x(n-1), j=0,1,…,m-1
  1136. // 8. double z[] - 一维数组,长度为m,存放m个指定的插值点处的函数值
  1137. // 9. double dz[] - 一维数组,长度为m,存放m个指定的插值点处的一阶导数值
  1138. // 10. double ddz[] - 一维数组,长度为m,存放m个指定的插值点处的二阶导数值
  1139. //
  1140. // 返回值:double 型,指定函数的x(0)到x(n-1)的定积分值
  1141. //////////////////////////////////////////////////////////////////////
  1142. double CInterpolate::GetValueSpline1(int n, double x[], double y[], double dy[], double ddy[], 
  1143.   int m, double t[], double z[], double dz[], double ddz[])
  1144. int i,j;
  1145.     double h0,h1,alpha,beta,g,*s;
  1146.     
  1147. // 初值
  1148. s=new double[n];
  1149.     s[0]=dy[0]; 
  1150. dy[0]=0.0;
  1151.     h0=x[1]-x[0];
  1152.     
  1153. for (j=1;j<=n-2;j++)
  1154.     { 
  1155. h1=x[j+1]-x[j];
  1156.         alpha=h0/(h0+h1);
  1157.         beta=(1.0-alpha)*(y[j]-y[j-1])/h0;
  1158.         beta=3.0*(beta+alpha*(y[j+1]-y[j])/h1);
  1159.         dy[j]=-alpha/(2.0+(1.0-alpha)*dy[j-1]);
  1160.         s[j]=(beta-(1.0-alpha)*s[j-1]);
  1161.         s[j]=s[j]/(2.0+(1.0-alpha)*dy[j-1]);
  1162.         h0=h1;
  1163.     }
  1164.     
  1165. for (j=n-2;j>=0;j--)
  1166. dy[j]=dy[j]*dy[j+1]+s[j];
  1167.     
  1168. for (j=0;j<=n-2;j++) 
  1169. s[j]=x[j+1]-x[j];
  1170.     
  1171. for (j=0;j<=n-2;j++)
  1172.     { 
  1173. h1=s[j]*s[j];
  1174.         ddy[j]=6.0*(y[j+1]-y[j])/h1-2.0*(2.0*dy[j]+dy[j+1])/s[j];
  1175.     }
  1176.     
  1177. h1=s[n-2]*s[n-2];
  1178.     ddy[n-1]=6.*(y[n-2]-y[n-1])/h1+2.*(2.*dy[n-1]+dy[n-2])/s[n-2];
  1179.     g=0.0;
  1180.     
  1181. for (i=0;i<=n-2;i++)
  1182.     { 
  1183. h1=0.5*s[i]*(y[i]+y[i+1]);
  1184.         h1=h1-s[i]*s[i]*s[i]*(ddy[i]+ddy[i+1])/24.0;
  1185.         g=g+h1;
  1186.     }
  1187.     
  1188. for (j=0;j<=m-1;j++)
  1189.     { 
  1190. if (t[j]>=x[n-1]) 
  1191. i=n-2;
  1192.         else
  1193.         { 
  1194. i=0;
  1195.             while (t[j]>x[i+1]) 
  1196. i=i+1;
  1197.         }
  1198.         
  1199. h1=(x[i+1]-t[j])/s[i];
  1200.         h0=h1*h1;
  1201.         z[j]=(3.0*h0-2.0*h0*h1)*y[i];
  1202.         z[j]=z[j]+s[i]*(h0-h0*h1)*dy[i];
  1203.         dz[j]=6.0*(h0-h1)*y[i]/s[i];
  1204.         dz[j]=dz[j]+(3.0*h0-2.0*h1)*dy[i];
  1205.         ddz[j]=(6.0-12.0*h1)*y[i]/(s[i]*s[i]);
  1206.         ddz[j]=ddz[j]+(2.0-6.0*h1)*dy[i]/s[i];
  1207.         h1=(t[j]-x[i])/s[i];
  1208.         h0=h1*h1;
  1209.         z[j]=z[j]+(3.0*h0-2.0*h0*h1)*y[i+1];
  1210.         z[j]=z[j]-s[i]*(h0-h0*h1)*dy[i+1];
  1211.         dz[j]=dz[j]-6.0*(h0-h1)*y[i+1]/s[i];
  1212.         dz[j]=dz[j]+(3.0*h0-2.0*h1)*dy[i+1];
  1213.         ddz[j]=ddz[j]+(6.0-12.0*h1)*y[i+1]/(s[i]*s[i]);
  1214.         ddz[j]=ddz[j]-(2.0-6.0*h1)*dy[i+1]/s[i];
  1215.     }
  1216.     
  1217. delete[] s;
  1218.     return(g);
  1219. }
  1220. //////////////////////////////////////////////////////////////////////
  1221. // 第二种边界条件的三次样条函数插值、微商与积分
  1222. //
  1223. // 参数:
  1224. // 1. int n - 结点的个数
  1225. // 2. double x[] - 一维数组,长度为n,存放给定的n个结点的值x(i)
  1226. // 3. double y[] - 一维数组,长度为n,存放给定的n个结点的函数值y(i),
  1227. //                 y(i) = f(x(i)), i=0,1,...,n-1
  1228. // 4. double dy[] - 一维数组,长度为n,返回时,存放n个给定点处的一阶导数值y'(i),
  1229. //                 i=0,1,...,n-1
  1230. // 5. double ddy[] - 一维数组,长度为n,返回时,存放n个给定点处的二阶导数值y''(i),
  1231. //                  i=0,1,...,n-1,调用时,ddy(0)存放给定区间的左端点处的二阶导数值,
  1232. //                  ddy(n-1)存放给定区间的右端点处的二阶导数值
  1233. // 6. int m - 指定插值点的个数
  1234. // 7. double t[] - 一维数组,长度为m,存放m个指定的插值点的值。
  1235. //                 要求x(0)<t(j)<x(n-1), j=0,1,…,m-1
  1236. // 8. double z[] - 一维数组,长度为m,存放m个指定的插值点处的函数值
  1237. // 9. double dz[] - 一维数组,长度为m,存放m个指定的插值点处的一阶导数值
  1238. // 10. double ddz[] - 一维数组,长度为m,存放m个指定的插值点处的二阶导数值
  1239. //
  1240. // 返回值:double 型,指定函数的x(0)到x(n-1)的定积分值
  1241. //////////////////////////////////////////////////////////////////////
  1242. double CInterpolate::GetValueSpline2(int n, double x[], double y[], double dy[], double ddy[], 
  1243.   int m, double t[], double z[], double dz[], double ddz[])
  1244. int i,j;
  1245.     double h0,h1,alpha,beta,g,*s;
  1246.     
  1247. // 初值
  1248. s=new double[n];
  1249.     dy[0]=-0.5;
  1250.     h0=x[1]-x[0];
  1251.     s[0]=3.0*(y[1]-y[0])/(2.0*h0)-ddy[0]*h0/4.0;
  1252.     
  1253. for (j=1;j<=n-2;j++)
  1254.     { 
  1255. h1=x[j+1]-x[j];
  1256.         alpha=h0/(h0+h1);
  1257.         beta=(1.0-alpha)*(y[j]-y[j-1])/h0;
  1258.         beta=3.0*(beta+alpha*(y[j+1]-y[j])/h1);
  1259.         dy[j]=-alpha/(2.0+(1.0-alpha)*dy[j-1]);
  1260.         s[j]=(beta-(1.0-alpha)*s[j-1]);
  1261.         s[j]=s[j]/(2.0+(1.0-alpha)*dy[j-1]);
  1262.         h0=h1;
  1263.     }
  1264.     
  1265. dy[n-1]=(3.0*(y[n-1]-y[n-2])/h1+ddy[n-1]*h1/2.0-s[n-2])/(2.0+dy[n-2]);
  1266.     for (j=n-2;j>=0;j--)
  1267. dy[j]=dy[j]*dy[j+1]+s[j];
  1268.     
  1269. for (j=0;j<=n-2;j++) 
  1270. s[j]=x[j+1]-x[j];
  1271.     
  1272. for (j=0;j<=n-2;j++)
  1273.     { 
  1274. h1=s[j]*s[j];
  1275.         ddy[j]=6.0*(y[j+1]-y[j])/h1-2.0*(2.0*dy[j]+dy[j+1])/s[j];
  1276.     }
  1277.     
  1278. h1=s[n-2]*s[n-2];
  1279.     ddy[n-1]=6.*(y[n-2]-y[n-1])/h1+2.*(2.*dy[n-1]+dy[n-2])/s[n-2];
  1280.     g=0.0;
  1281.     
  1282. for (i=0;i<=n-2;i++)
  1283.     { 
  1284. h1=0.5*s[i]*(y[i]+y[i+1]);
  1285.         h1=h1-s[i]*s[i]*s[i]*(ddy[i]+ddy[i+1])/24.0;
  1286.         g=g+h1;
  1287.     }
  1288.     
  1289. for (j=0;j<=m-1;j++)
  1290.     { 
  1291. if (t[j]>=x[n-1]) 
  1292. i=n-2;
  1293.         else
  1294.         { 
  1295. i=0;
  1296.             while (t[j]>x[i+1]) 
  1297. i=i+1;
  1298.         }
  1299.         
  1300. h1=(x[i+1]-t[j])/s[i];
  1301.         h0=h1*h1;
  1302.         z[j]=(3.0*h0-2.0*h0*h1)*y[i];
  1303.         z[j]=z[j]+s[i]*(h0-h0*h1)*dy[i];
  1304.         dz[j]=6.0*(h0-h1)*y[i]/s[i];
  1305.         dz[j]=dz[j]+(3.0*h0-2.0*h1)*dy[i];
  1306.         ddz[j]=(6.0-12.0*h1)*y[i]/(s[i]*s[i]);
  1307.         ddz[j]=ddz[j]+(2.0-6.0*h1)*dy[i]/s[i];
  1308.         h1=(t[j]-x[i])/s[i];
  1309.         h0=h1*h1;
  1310.         z[j]=z[j]+(3.0*h0-2.0*h0*h1)*y[i+1];
  1311.         z[j]=z[j]-s[i]*(h0-h0*h1)*dy[i+1];
  1312.         dz[j]=dz[j]-6.0*(h0-h1)*y[i+1]/s[i];
  1313.         dz[j]=dz[j]+(3.0*h0-2.0*h1)*dy[i+1];
  1314.         ddz[j]=ddz[j]+(6.0-12.0*h1)*y[i+1]/(s[i]*s[i]);
  1315.         ddz[j]=ddz[j]-(2.0-6.0*h1)*dy[i+1]/s[i];
  1316.     }
  1317.     
  1318. delete[] s;
  1319.     return(g);
  1320. }
  1321. //////////////////////////////////////////////////////////////////////
  1322. // 第三种边界条件的三次样条函数插值、微商与积分
  1323. //
  1324. // 参数:
  1325. // 1. int n - 结点的个数
  1326. // 2. double x[] - 一维数组,长度为n,存放给定的n个结点的值x(i)
  1327. // 3. double y[] - 一维数组,长度为n,存放给定的n个结点的函数值y(i),
  1328. //                 y(i) = f(x(i)), i=0,1,...,n-1
  1329. // 4. double dy[] - 一维数组,长度为n,返回时,存放n个给定点处的一阶导数值y'(i),
  1330. //                 i=0,1,...,n-1
  1331. // 5. double ddy[] - 一维数组,长度为n,返回时,存放n个给定点处的二阶导数值y''(i),
  1332. //                  i=0,1,...,n-1
  1333. // 6. int m - 指定插值点的个数
  1334. // 7. double t[] - 一维数组,长度为m,存放m个指定的插值点的值。
  1335. //                 要求x(0)<t(j)<x(n-1), j=0,1,…,m-1
  1336. // 8. double z[] - 一维数组,长度为m,存放m个指定的插值点处的函数值
  1337. // 9. double dz[] - 一维数组,长度为m,存放m个指定的插值点处的一阶导数值
  1338. // 10. double ddz[] - 一维数组,长度为m,存放m个指定的插值点处的二阶导数值
  1339. //
  1340. // 返回值:double 型,指定函数的x(0)到x(n-1)的定积分值
  1341. //////////////////////////////////////////////////////////////////////
  1342. double CInterpolate::GetValueSpline3(int n, double x[], double y[], double dy[], double ddy[], 
  1343.   int m, double t[], double z[], double dz[], double ddz[])
  1344. int i,j;
  1345.     double h0,y0,h1,y1,alpha,beta,u,g,*s;
  1346.     
  1347. // 初值
  1348. s=new double[n];
  1349.     h0=x[n-1]-x[n-2];
  1350.     y0=y[n-1]-y[n-2];
  1351.     dy[0]=0.0; ddy[0]=0.0; ddy[n-1]=0.0;
  1352.     s[0]=1.0; s[n-1]=1.0;
  1353.     for (j=1;j<=n-1;j++)
  1354.     { 
  1355. h1=h0; y1=y0;
  1356.         h0=x[j]-x[j-1];
  1357.         y0=y[j]-y[j-1];
  1358.         alpha=h1/(h1+h0);
  1359.         beta=3.0*((1.0-alpha)*y1/h1+alpha*y0/h0);
  1360.         
  1361. if (j<n-1)
  1362.         { 
  1363. u=2.0+(1.0-alpha)*dy[j-1];
  1364.             dy[j]=-alpha/u;
  1365.             s[j]=(alpha-1.0)*s[j-1]/u;
  1366.             ddy[j]=(beta-(1.0-alpha)*ddy[j-1])/u;
  1367.         }
  1368.     }
  1369.     
  1370. for (j=n-2;j>=1;j--)
  1371.     { 
  1372. s[j]=dy[j]*s[j+1]+s[j];
  1373.         ddy[j]=dy[j]*ddy[j+1]+ddy[j];
  1374.     }
  1375.     
  1376. dy[n-2]=(beta-alpha*ddy[1]-(1.0-alpha)*ddy[n-2])/
  1377.             (alpha*s[1]+(1.0-alpha)*s[n-2]+2.0);
  1378.     
  1379. for (j=2;j<=n-1;j++)
  1380.         dy[j-2]=s[j-1]*dy[n-2]+ddy[j-1];
  1381.     
  1382. dy[n-1]=dy[0];
  1383.     for (j=0;j<=n-2;j++) 
  1384. s[j]=x[j+1]-x[j];
  1385.     
  1386. for (j=0;j<=n-2;j++)
  1387.     { 
  1388. h1=s[j]*s[j];
  1389.         ddy[j]=6.0*(y[j+1]-y[j])/h1-2.0*(2.0*dy[j]+dy[j+1])/s[j];
  1390.     }
  1391.     
  1392. h1=s[n-2]*s[n-2];
  1393.     ddy[n-1]=6.*(y[n-2]-y[n-1])/h1+2.*(2.*dy[n-1]+dy[n-2])/s[n-2];
  1394.     g=0.0;
  1395.     
  1396. for (i=0;i<=n-2;i++)
  1397.     { 
  1398. h1=0.5*s[i]*(y[i]+y[i+1]);
  1399.         h1=h1-s[i]*s[i]*s[i]*(ddy[i]+ddy[i+1])/24.0;
  1400.         g=g+h1;
  1401.     }
  1402.     
  1403. for (j=0;j<=m-1;j++)
  1404.     { 
  1405. h0=t[j];
  1406.         while (h0>=x[n-1]) 
  1407. h0=h0-(x[n-1]-x[0]);
  1408.         
  1409. while (h0<x[0]) 
  1410. h0=h0+(x[n-1]-x[0]);
  1411.         
  1412. i=0;
  1413.         while (h0>x[i+1]) 
  1414. i=i+1;
  1415.         
  1416. u=h0;
  1417.         h1=(x[i+1]-u)/s[i];
  1418.         h0=h1*h1;
  1419.         z[j]=(3.0*h0-2.0*h0*h1)*y[i];
  1420.         z[j]=z[j]+s[i]*(h0-h0*h1)*dy[i];
  1421.         dz[j]=6.0*(h0-h1)*y[i]/s[i];
  1422.         dz[j]=dz[j]+(3.0*h0-2.0*h1)*dy[i];
  1423.         ddz[j]=(6.0-12.0*h1)*y[i]/(s[i]*s[i]);
  1424.         ddz[j]=ddz[j]+(2.0-6.0*h1)*dy[i]/s[i];
  1425.         h1=(u-x[i])/s[i];
  1426.         h0=h1*h1;
  1427.         z[j]=z[j]+(3.0*h0-2.0*h0*h1)*y[i+1];
  1428.         z[j]=z[j]-s[i]*(h0-h0*h1)*dy[i+1];
  1429.         dz[j]=dz[j]-6.0*(h0-h1)*y[i+1]/s[i];
  1430.         dz[j]=dz[j]+(3.0*h0-2.0*h1)*dy[i+1];
  1431.         ddz[j]=ddz[j]+(6.0-12.0*h1)*y[i+1]/(s[i]*s[i]);
  1432.         ddz[j]=ddz[j]-(2.0-6.0*h1)*dy[i+1]/s[i];
  1433.     }
  1434.  
  1435. delete[] s;
  1436.     return(g);
  1437. }
  1438. //////////////////////////////////////////////////////////////////////
  1439. // 二元三点插值
  1440. //
  1441. // 参数:
  1442. // 1. int n - x方向上给定结点的点数
  1443. // 2. double x[] - 一维数组,长度为n,存放给定n x m 个结点x方向上的n个值x(i)
  1444. // 3. int m - y方向上给定结点的点数
  1445. // 4. double y[] - 一维数组,长度为m,存放给定n x m 个结点y方向上的m个值y(i)
  1446. // 5. double z[] - 一维数组,长度为n x m,存放给定的n x m个结点的函数值z(i,j),
  1447. //                 z(i,j) = f(x(i), y(j)), i=0,1,...,n-1, j=0,1,...,m-1
  1448. // 6. double u - 存放插值点x坐标
  1449. // 7. double v - 存放插值点y坐标
  1450. //
  1451. // 返回值:double 型,指定函数值f(u, v)
  1452. //////////////////////////////////////////////////////////////////////
  1453. double CInterpolate::GetValueTqip(int n, double x[], int m, double y[], double z[], double u, double v)
  1454. int nn,mm,ip,iq,i,j,k,l;
  1455.     double b[3],h,w;
  1456.     
  1457. // 初值
  1458. nn=3;
  1459. // 特例
  1460.     if (n<=3) 
  1461. ip=0;  
  1462. nn=n;
  1463. }
  1464.     else if (u<=x[1]) 
  1465. ip=0;
  1466.     else if (u>=x[n-2]) 
  1467. ip=n-3;
  1468.     else
  1469.     { 
  1470. i=1; j=n;
  1471.         while (((i-j)!=1)&&((i-j)!=-1))
  1472.         { 
  1473. l=(i+j)/2;
  1474.             if (u<x[l-1]) 
  1475. j=l;
  1476.             else 
  1477. i=l;
  1478.         }
  1479.         
  1480. if (fabs(u-x[i-1])<fabs(u-x[j-1])) 
  1481. ip=i-2;
  1482.         else 
  1483. ip=i-1;
  1484.     }
  1485.     
  1486. mm=3;
  1487.     
  1488. if (m<=3) 
  1489. iq=0; 
  1490. mm=m;
  1491. }
  1492.     else if (v<=y[1]) 
  1493. iq=0;
  1494.     else if (v>=y[m-2]) 
  1495. iq=m-3;
  1496.     else
  1497.     { 
  1498. i=1; 
  1499. j=m;
  1500.         while (((i-j)!=1)&&((i-j)!=-1))
  1501.         { 
  1502. l=(i+j)/2;
  1503.             if (v<y[l-1]) 
  1504. j=l;
  1505.             else 
  1506. i=l;
  1507.         }
  1508.         
  1509. if (fabs(v-y[i-1])<fabs(v-y[j-1])) 
  1510. iq=i-2;
  1511.         else 
  1512. iq=i-1;
  1513.     }
  1514.     
  1515. for (i=0;i<=nn-1;i++)
  1516.     { 
  1517. b[i]=0.0;
  1518.         for (j=0;j<=mm-1;j++)
  1519.         { 
  1520. k=m*(ip+i)+(iq+j);
  1521.             h=z[k];
  1522.             for (k=0;k<=mm-1;k++)
  1523.             {
  1524. if (k!=j)
  1525. h=h*(v-y[iq+k])/(y[iq+j]-y[iq+k]);
  1526. }
  1527.             b[i]=b[i]+h;
  1528.         }
  1529.     }
  1530.     
  1531. w=0.0;
  1532.     for (i=0;i<=nn-1;i++)
  1533.     { 
  1534. h=b[i];
  1535.         for (j=0;j<=nn-1;j++)
  1536.         {
  1537. if (j!=i)
  1538. h=h*(u-x[ip+j])/(x[ip+i]-x[ip+j]);
  1539. }
  1540.         w=w+h;
  1541.     }
  1542.     
  1543. return(w);
  1544. }
  1545. //////////////////////////////////////////////////////////////////////
  1546. // 二元全区间插值
  1547. //
  1548. // 参数:
  1549. // 1. int n - x方向上给定结点的点数
  1550. // 2. double x[] - 一维数组,长度为n,存放给定n x m 个结点x方向上的n个值x(i)
  1551. // 3. int m - y方向上给定结点的点数
  1552. // 4. double y[] - 一维数组,长度为m,存放给定n x m 个结点y方向上的m个值y(i)
  1553. // 5. double z[] - 一维数组,长度为n x m,存放给定的n x m个结点的函数值z(i,j),
  1554. //                 z(i,j) = f(x(i), y(j)), i=0,1,...,n-1, j=0,1,...,m-1
  1555. // 6. double u - 存放插值点x坐标
  1556. // 7. double v - 存放插值点y坐标
  1557. //
  1558. // 返回值:double 型,指定函数值f(u, v)
  1559. //////////////////////////////////////////////////////////////////////
  1560. double CInterpolate::GetValueLagrange2(int n, double x[], int m, double y[], double z[], double u, double v)
  1561. int ip,ipp,i,j,l,iq,iqq,k;
  1562.     double h,w,b[10];
  1563.     
  1564. // 特例
  1565. if (u<=x[0]) 
  1566. ip=1; 
  1567. ipp=4;
  1568. }
  1569.     else if (u>=x[n-1]) 
  1570. ip=n-3; 
  1571. ipp=n;
  1572. }
  1573.     else
  1574.     { 
  1575. i=1; 
  1576. j=n;
  1577.         while (((i-j)!=1)&&((i-j)!=-1))
  1578.         { 
  1579. l=(i+j)/2;
  1580.             if (u<x[l-1]) 
  1581. j=l;
  1582.             else 
  1583. i=l;
  1584.         }
  1585.         
  1586. ip=i-3; 
  1587. ipp=i+4;
  1588.     }
  1589.     
  1590. if (ip<1) 
  1591. ip=1;
  1592.     if (ipp>n) 
  1593. ipp=n;
  1594.     if (v<=y[0]) 
  1595. iq=1; 
  1596. iqq=4;
  1597. }
  1598.     else if (v>=y[m-1]) 
  1599. iq=m-3; 
  1600. iqq=m;
  1601. }
  1602.     else
  1603.     { 
  1604. i=1; 
  1605. j=m;
  1606.         while (((i-j)!=1)&&((i-j)!=-1))
  1607.         { 
  1608. l=(i+j)/2;
  1609.             if (v<y[l-1]) 
  1610. j=l;
  1611.             else 
  1612. i=l;
  1613.         }
  1614.         
  1615. iq=i-3; 
  1616. iqq=i+4;
  1617.     }
  1618.     
  1619. if (iq<1) 
  1620. iq=1;
  1621.     if (iqq>m) 
  1622. iqq=m;
  1623.     for (i=ip-1;i<=ipp-1;i++)
  1624.     { 
  1625. b[i-ip+1]=0.0;
  1626.         for (j=iq-1;j<=iqq-1;j++)
  1627.         { 
  1628. h=z[m*i+j];
  1629.             for (k=iq-1;k<=iqq-1;k++)
  1630.             {
  1631. if (k!=j) 
  1632. h=h*(v-y[k])/(y[j]-y[k]);
  1633. }
  1634.             b[i-ip+1]=b[i-ip+1]+h;
  1635.         }
  1636.     }
  1637.     
  1638. w=0.0;
  1639.     for (i=ip-1;i<=ipp-1;i++)
  1640.     { 
  1641. h=b[i-ip+1];
  1642.         for (j=ip-1;j<=ipp-1;j++)
  1643.         {
  1644. if (j!=i) 
  1645. h=h*(u-x[j])/(x[i]-x[j]);
  1646. }
  1647.         w=w+h;
  1648.     }
  1649.     
  1650. return(w);
  1651. }