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