2017-05-31 101 views
1

我不完全确定要调用什么。2d字典或查找表?

enter image description here

我在一个CSV文件,并在SQL数据库中有这样的数据。我需要做的是能够使用该表进行双线性插值。所以当说d = 2.5和HVL = 1.6时,解决这个问题的最好方法是什么?我可以执行的计算只是不知道如何从表中选择适当的数字,某种形式的LINQ语句?

编辑:

结合附图1.6和2.5我需要选择围绕它作为一个2×2矩阵(Bilinear interpolation

enter image description here

由于

+0

你想做什么? –

+0

这是辐射背向散射因子(BSF),因此深度为2厘米,HVL为1.0毫米,BSF = 1.070。如上所述,当深度和HVL未列出时,我想插入以找到BSF。 – James

+0

这是什么意思?你在这些方程中折腾,就像有人应该知道他们的意思。我看到你有一个d列和HVL列。给出2.5和1.6的例子,你想要返回什么? –

回答

4

1)我的号码把你的矩阵的一小部分看起来像这样:

enter image description here

2)然后,我们把你的MATIX和动态规范(见CTE 0),以及看起来像这样:

enter image description here

现在,为了性能考虑,如果这是一个静态的矩阵,我会建议你实际存储的数据是这种时尚。

3)给定您的目标值@X和@Y,然后我们需要确定所需的行和列(在cte1中)。结果是这样的:

enter image description here

  • 的字段和值所需的行/列数

4)在CTE2,我们要抢在X/Y范围和价值观,看起来像这样:

enter image description here

4)最后的查询是X/Y范围/值插值的一个小问题。我使用UDF只是为了方便数学。

我应该注意如下图所示的结果进行了验证:

enter image description here

OK,怎么样的代码?

我应该补充说,我将​​这些部分留作cte,以便您可以看到各个部分如何协同工作。当然,这可以进一步压缩(见下面的编辑)。

Declare @YourTable Table ([y] int,[x1.5] float,[x2.0] float,[x3.0] float,[x4.0] float) 
Insert Into @YourTable Values 
(1,1.050,1.055,1.057,1.057) 
,(2,1.080,1.089,1.097,1.098) 
,(3,1.091,1.103,1.114,1.446) 

Declare @XML xml = (Select * from @YourTable for XML Raw) 
Declare @Y float = 2.5 
Declare @X float = 1.6 

;with cte0 as (
       Select RowNr = Dense_Rank() over (Order By r.value('@y','float')) 
         ,ColNr = Dense_Rank() over (Order By convert(float,replace(attr.value('local-name(.)','varchar(100)'),'x',''))) 
         ,Y  = r.value('@y','float') 
         ,X  = convert(float,replace(attr.value('local-name(.)','varchar(100)'),'x','')) 
         ,V  = attr.value('.','float') 
       From @XML.nodes('/row') as A(r) 
       Cross Apply A.r.nodes('./@*') AS B(attr) 
       Where attr.value('local-name(.)','varchar(100)') not in ('y')) 
    ,cte1 as ( 
       Select * 
       From (Select R1=max(RowNr),R2=max(RowNr)+1 From cte0 A where Y<@Y) A 
       Join (Select C1=max(ColNr),C2=max(ColNr)+1 From cte0 A where X<@X) B 
        on 1=1 
      ) 
    ,cte2 as (
       Select X1 = max(case when C=1 then X end) 
         ,X2 = max(case when C=2 then X end) 
         ,Y1 = max(case when R=1 then Y end) 
         ,Y2 = max(case when R=2 then Y end) 
         ,Q11 = max(case when R=1 and C=1 then V end) 
         ,Q12 = max(case when R=1 and C=2 then V end) 
         ,Q21 = max(case when R=2 and C=1 then V end) 
         ,Q22 = max(case when R=2 and C=2 then V end) 
       From (
         Select * 
           ,R=Dense_Rank() over (Order By RowNr) 
           ,C=Dense_Rank() over (Order By ColNr) 
         From cte0 A 
         Cross Join cte1 
         Where RowNr between R1 and R2 
          and ColNr between C1 and C2 
        ) A 
      ) 
Select Value = [dbo].[udf-Stat-Interpolate](@Y,Y1,Y2,[dbo].[udf-Stat-Interpolate](@X,X1,X2,Q11,Q12) ,[dbo].[udf-Stat-Interpolate](@X,X1,X2,Q21,Q22)) 
From cte2 

返回

Value 
1.0876 

最后,UDF如果有意

CREATE Function [dbo].[udf-Stat-Interpolate] (@PosNr float,@PosMin float,@PosMax float,@ValMin float,@ValMax float) 
Returns Float as 
Begin 
    Return (((@[email protected])/(@[email protected])*(@[email protected])))[email protected] 
End 

编辑 - 如果矩阵被存储如上述所示(#2)

Declare @Y float = 2.5 
Declare @X float = 1.6 

Select Value = [dbo].[udf-Stat-Interpolate](@Y,Y1,Y2,[dbo].[udf-Stat-Interpolate](@X,X1,X2,Q11,Q12),[dbo].[udf-Stat-Interpolate](@X,X1,X2,Q21,Q22)) 
From (
     Select X1 = max(case when C=1 then X end) 
       ,X2 = max(case when C=2 then X end) 
       ,Y1 = max(case when R=1 then Y end) 
       ,Y2 = max(case when R=2 then Y end) 
       ,Q11 = max(case when R=1 and C=1 then V end) 
       ,Q12 = max(case when R=1 and C=2 then V end) 
       ,Q21 = max(case when R=2 and C=1 then V end) 
       ,Q22 = max(case when R=2 and C=2 then V end) 
     From (
       Select * 
        ,R=Dense_Rank() over (Order By RowNr) 
        ,C=Dense_Rank() over (Order By ColNr) 
       From YourTable A 
       Cross Join (
          Select * 
          From (Select R1=max(RowNr),R2=max(RowNr)+1 From YourTable A where Y<@Y) A 
          Join (Select C1=max(ColNr),C2=max(ColNr)+1 From YourTable A where X<@X) B on 1=1 
          ) B 
       Where RowNr between R1 and R2 
        and ColNr between C1 and C2 
      ) A 
    ) A 
+0

真棒,就是我之后的事情。我正在用存储过程来研究它,并在被要求查看更紧急的其他东西之前部分地通过了它。 – James

+0

快乐它帮助 –