COMPASSi/trunk/code/inc/DataManager/Infrastructure.Interface/Arithmetics/Interpolation.h

65 lines
1.9 KiB
C
Raw Permalink Normal View History

2025-06-25 15:06:42 +08:00
#pragma once
#include <string>
#include <unordered_map>
#include <vector>
#include <cmath>
#include <stdexcept>
#include <any>
#include <concepts>
#include <memory>
#include "DataManagerGlobal.h"
// /// <summary>
// /// 内插法字典表
// /// </summary>
// class InterpolationTable
// {
// };
/// <summary>
/// 内插法算法类
/// </summary>
class DATAMANAGER_DLL_API_EXPORTS Interpolation : public std::enable_shared_from_this<Interpolation>
{
/// <summary>
/// 内插法(线性求取插值算法)
/// </summary>
/// <param name="dic">字典表</param>
/// <param name="propName">所取字段(属性)名</param>
/// <param name="step">键值步长</param>
/// <param name="key">实际键值</param>
/// <returns></returns>
public:
template <typename T>
static double Interpolate(std::unordered_map<int, T> &dic, const std::string &propName, int step, double key)
{
double key1 = key / step;
int keyFloor = static_cast<int>(std::floor(key1)) * step;
int keyCeiling = static_cast<int>(std::ceil(key1)) * step;
double offset = (key - keyFloor) / step;
int keyMax = dic.Keys->Max([&](std::any m)
{ m; });
int keyMin = dic.Keys->Min([&](std::any m)
{ m; });
if (keyFloor >= keyMax)
{
keyFloor = keyMax;
keyCeiling = keyMax;
}
if (!dic.contains(keyFloor) || !dic.contains(keyCeiling))
{
throw std::runtime_error("提供的键值不在内插法字典键值范围内");
}
std::any oFloor = dic[keyFloor];
std::any oCeiling = dic[keyCeiling];
std::shared_ptr<PropertyInfo> prop = typeid(T).GetProperty(propName);
double vFloor = std::any_cast<double>(prop->GetValue(oFloor, std::vector<std::any>()));
double vCeiling = std::any_cast<double>(prop->GetValue(oCeiling, std::vector<std::any>()));
double rtn = vFloor + (offset == 0.0 ? 0 : (vCeiling - vFloor) / offset);
return rtn;
}
static double Linear(std::vector<double> &points, std::vector<double> &values, double t);
};