返回顶部

收藏

任意维实验数据的简单差值处理

更多
//一、标题
//类名:InsertValues
//修改完成日期:2006.6.12
//二、功能说明
//InsertValues类是用来从文件中读出实验数据,针对给出插值点,求出插值。
//三、实现过程
//步骤:
//1、读入文件的数据,并且取出数列的维数、各维的值、各维对应的点值、数列的值。数据必须是按以下规定书写的:
//对应的函数为:InsertValues(string filename)
//从文件(*.txt)中读入实验数据,filename为文件的全路径

//类成员将存储数列维数,各子维对应的数据,数列和各维对应的数据相对应
//2、计算插值
//对应的函数为:double Calculate(double *dInsertValue)
//dInsertValue为存储插入点的数组,其大小必须与数列的维数相当
//从最后一维开始计算,不考虑前面所有维的情况。计算出对应的插值,插值的个数为前面所有子维值的乘积。
//那么,我们得到的是n-1维的数列。同上,我们可以得到n-2维的数列。依次类推,我们得到1维的数列,那么
//依据插值,我们可以得到最终的结果。
14 10:07
//完成人 陈亮

//

#include <math.h>
#include <vector>
#include <iostream>
#include <fstream>
using namespace std;

//计算任意一维的插值
template <typename T>
T lag(T* xa,T* ya,long n,T x)//xa,X轴的点。ya,Y轴上的点。n,点的个数。x,插入点的值。
{
    if(x<0)
    {
        return -888;//工程计算一般不应有负数。
    }
    if(fabs(x)<0.0001)
    {
        return 0;
    }

    T tp;

    if(1==n)
    {

        tp=((ya[n-1]-0)/(xa[n-1]-0))*(x-xa[n-1])+ya[n-1];
        return tp;      
    }

    T absX=999999;
    int k=-1;

    //先找到最近的一个样本点,记录下其序号k
    for(int i=0;i<n;++i)
    {
        if(absX>fabs(xa[i]-x))
        {
            absX=fabs(xa[i]-x);
            k=i;    
        }
    }

    //分析所求位置与最近样本点的位置关系

    if((x-xa[k])>0)//在最近样本点右边
    {
        if(k>=n-1)//最近样本点是最后一个样本点,用它个它前边的样本点表示趋势简单插值计算
        {

            tp=((ya[n-1]-ya[n-2])/(xa[n-1]-xa[n-2]))*(x-xa[n-1])+ya[n-1];
            return tp;
        }
        else//用x两边的样本点插值计算
        {
            tp=((ya[k+1]-ya[k])/(xa[k+1]-xa[k]))*(x-xa[k])+ya[k];
            return tp;

        }
    }
    else//在最近样本点左边
    {
        if(fabs(x-xa[k])<0.0005)//(几乎)就是我们的样本点,直接取值
        {
            return ya[k];
        }
        else if( 0==k)
        {

            return tp = ((ya[0] - 0)/(xa[0] - 0))*(x - 0);
        }
        else//用x两边的样本点插值计算
        {

            tp=((ya[k]-ya[k-1])/(xa[k]-xa[k-1]))*(x-xa[k-1])+ya[k-1];
            return tp;
        }
    }
}

class InsertValues
{
    //datas..
private:
    int iNumOfDism;//存放维数
    vector<int> iDism;//放各维数量
    vector<vector<double> > dDataOfDism;//放各维下标对应实际数值
    vector<double> dArray;//存放数列

public:
    //得到数列的维数
    inline int GetNumOfDism()
    {
        return iNumOfDism;
    }
    //得到对应维的子维个数
    //输入范围错返回-1
    inline int GetNumOfEachDism(int iNum)
    {
        if(iNum > iNumOfDism || iNum <= 0)
        {       
            return -1;
        }
        return iDism[iNum - 1];

    }

    InsertValues(string filename)
    {
        int i;//用于循环
        int iTemp;//暂时存放整数

        locale lc=locale::global(locale(""));

        //读出维数
        ifstream infile(filename.c_str());
        infile >> iNumOfDism;

        //读出各维数量
        //if(infile.eof())
        //{
        for(i=0;i<iNumOfDism;i++)
        {
            infile>>iTemp;
            iDism.push_back(iTemp);
        }
        iDism.resize(iNumOfDism);
        //}
        //else return;

        //读出各维下标对应实际数值
        dDataOfDism.resize(iNumOfDism);
        for( i=0;i<iNumOfDism;++i)
        {
            dDataOfDism[i].resize(iDism[i]);
            for(int j=0;j<iDism[i];j++)
            {
                infile>>dDataOfDism[i][j];
            }
        }

        int iTotalNum = 1;
        double dTemp;

        //计算数列的总和
        for(int i = 0; i < iNumOfDism; i++)
        {
            iTotalNum *= iDism[i];
        }

        //读出数列的值
        for(int i=0;i < iTotalNum;++i)
        {
            infile>>dTemp;
            dArray.push_back(dTemp);
        }   
        dArray.resize(iTotalNum);

        locale::global(lc);

    }

    void printit()
    {
        int i;
        for(i=0;i<iNumOfDism;i++)
        {
            cout<<iDism[i]<<"  ";
        }
        cout<<endl<<endl;

        //输出各维对应的实际的值
        for( i=0;i<iNumOfDism;++i)
        {

            for(int j=0;j<iDism[i];j++)
            {
                cout<<dDataOfDism[i][j]<<"  ";
            }
            cout << endl;
        }
        cout << endl << endl << endl;

        //输出所有的数据
        for(int i=0; i < dArray.size(); ++i)
        {
            cout << dArray[i]<<"    ";
            if((i+1) % iDism[iNumOfDism - 1] == 0)
                cout << endl;
        }
        cout<<endl<<endl<<endl;
    }
    //计算插值
    //dInsertValue为存储插入点的数组,其大小必须与数列的维数相当
    double Calculate(double *dInsertValue)
    {
        int i;//以下三个均用做循环
        int j;
        int k;
        double dTemp;

        //显示插入点
        cout << "插入点为:" <<endl;
        for(i = 0; i < iNumOfDism; i++)
            cout << dInsertValue[i] <<"    ";

        int iMaxOfDism = 0;//所有维中最大维数
        for(k = 0;k < iNumOfDism;k++)
        {
            if(iMaxOfDism < iDism[k])
                iMaxOfDism = iDism[k];
        }

        //记录所有数据的个数
        int iTotalNum = 1;
        for(i = 0;i < iNumOfDism;i++)
            iTotalNum *=iDism[i]; 

        //将插值问题看成X-Y平面的线性问题
        //记录Y方向的值
        double *dY = new double[iMaxOfDism];
        //记录X方向的值
        double *dX = new double[iMaxOfDism];

        //从最后一维开始计算,不考虑前面所有维的情况。计算出对应的插值,插值的个数为前面所有维值的乘积。
        //那么,我们得到的是n-1维的数列。同上,我们可以得到n-2维的数列。依次类推,我们得到1维的数列,那么
        //依据插值,我们可以得到最终的结果。
        int iCyc = iTotalNum;//每依次迭代我们将得到的数列的元素个数
        int iStep;
        for(j = 0;j < iNumOfDism;j++)//迭代次数为,数列的维数
        {
            iStep = iDism[iNumOfDism -1 -j];
            for(i = 0;i < iStep; i++)//得到X轴上点值
            {
                *(dX + i) = dDataOfDism[iNumOfDism -1 -j][i];
            }
            iCyc = iCyc/iDism[iNumOfDism -1 -j];
            for(k = 0;k < iCyc;k++)//计算对应Y轴上的值
            {
                for(i = 0;i < iStep; i++)
                {
                    *(dY + i) = dArray[i + iStep * k];
                }
                dTemp = lag(dX,dY, iDism[iNumOfDism -1 -j], *(dInsertValue + iNumOfDism -1 -j));
                dArray[k] = dTemp;//将新得到的插值放到dArray,dArray作为新的数列的载体
            }
            dArray.resize(iCyc);//重置dArray的容积
        }
        dTemp = dArray[0];
        //delete []dInsertValue;
        delete []dX;
        delete []dY;
        return dTemp;//返回最后计算得到的插值
    }
};
//该片段来自于http://outofmemory.cn

标签:c++,基础

收藏

0人收藏

支持

0

反对

0

相关聚客文章
  1. tanglei 发表 2014-05-28 15:08:01 struct与class区别联系
  2. 博主 发表 2016-06-28 05:17:59 Bazel C++ 基础[翻译]
  3. 博主 发表 2011-11-03 16:00:00 C++ 语言基础
  4. thinkpc 发表 2016-03-04 13:55:30 c++&nbsp;11 map基础value排序
  5. pansunyou 发表 2014-11-30 02:51:00 C++通用跨数据库访问方案之一: 基础组件cdbc
  6. linux@linux.cn (linu 发表 2016-11-04 02:37:00 C++ 程序员 Protocol Buffers 基础指南
  7. 剑豪 发表 2013-01-22 05:57:06 不得不留意的STL string重载函数和隐式类型转换
  8. smartdj 发表 2013-03-04 03:42:17 小括号,解决大问题
  9. Herb Sutter 发表 2012-04-22 01:05:35 GotW #103: Solution
  10. Herb Sutter 发表 2012-08-02 11:26:37 “Strong” and “weak” hardware memory models
  11. Herb Sutter 发表 2012-12-04 18:06:54 Compatibility
  12. guenter 发表 2012-11-19 10:53:22 New Applied Informatics C++ Libraries and Tools Re

发表评论