D中线性代数包的固定维特化

D中线性代数包的固定维特化,d,linear-algebra,D,Linear Algebra,如果指数是一个常量整数,D可以将函数专门化为常量参数(在编译时已知),通常用于pow(base,exponent)。由于C++缺乏此特性,它不得不求助于模板专用的HAKS,这些模板使API变得模糊不清,例如Boo.No.< /P>中的 POW函数模板。 但是,在线性代数软件包中,常量参数专门化不能也用于专门化矩阵运算,如固定维情况下的矩阵向量乘法,如二维/三维图形中通常使用的2x2、3x3、3x3、4x3和4x4。这些重载通常使用SIMD指令(intrinsic)实现,如果这些实现能够由这样一个

如果
指数
是一个常量整数,D可以将函数专门化为常量参数(在编译时已知),通常用于
pow(base,exponent)
。由于C++缺乏此特性,它不得不求助于模板专用的HAKS,这些模板使API变得模糊不清,例如Boo.No.< /P>中的<代码> POW函数模板。 但是,在线性代数软件包中,常量参数专门化不能也用于专门化矩阵运算,如固定维情况下的矩阵向量乘法,如二维/三维图形中通常使用的2x2、3x3、3x3、4x3和4x4。这些重载通常使用SIMD指令(intrinsic)实现,如果这些实现能够由这样一个库自动挑选出适合固定大小的矩阵和向量,那就太棒了

我相信这将是D的真正杀手级应用,尤其是在科学可视化方面。这是因为高维/动态维线性代数和固定维2-D/3-D之间的桥梁对于使用实现这些思想的软件包的开发人员来说是完全透明的

现在已经有一些很好的二维、三维和四维线性代数包,比如gl3n。 我希望看到它被扩展以提供包含在C++库中的函数,例如特征符和犰狳。 但是,在线性代数软件包中,常量参数专门化不能也用于专门化矩阵运算,如固定维情况下的矩阵向量乘法,如通常在2d/3d图形中使用的2x2、3x3、3x3、4x3和4x4

是的,这是完全可能的,而且相当容易。有几种方法可以做到这一点:

  • 使用模板专业化
  • 使用模板函数约束
  • 如果,则使用
    静态
下面是一个使用
静态if
进行向量加法的示例

Vec!N add(int N)(Vec!N a, Vec!N b)
{
    static if (N == 4)
    {
        // Use vector ops
    }
    else
    {
        // Use generic routine
    }
}
静态if
是在编译时计算的,因此在运行时没有分支开销

但是,在线性代数软件包中,常量参数专门化不能也用于专门化矩阵运算,如固定维情况下的矩阵向量乘法,如通常在2d/3d图形中使用的2x2、3x3、3x3、4x3和4x4

是的,这是完全可能的,而且相当容易。有几种方法可以做到这一点:

  • 使用模板专业化
  • 使用模板函数约束
  • 如果,则使用
    静态
下面是一个使用
静态if
进行向量加法的示例

Vec!N add(int N)(Vec!N a, Vec!N b)
{
    static if (N == 4)
    {
        // Use vector ops
    }
    else
    {
        // Use generic routine
    }
}

>代码>静态I/<代码>在编译时进行评估,因此在运行时没有分支成本。

但是,在C++中,通过模板特化,在这种情况下,可以使用代码>添加< /代码>。我的主要问题是,如果C++中的常数函数除了在上面提到的 POW//C> >之外,还可以实现更灵活的行为。不,不能自动检测常数参数。这样做将打破D的编译模型(函数如何在没有编译后就没有了源代码)?理论上它可以使用模板来完成,但是它没有。但是,在C++中,通过模板特化,在这种情况下,可以使用代码>添加< /代码>。我的主要问题是,如果C++中的常数函数除了在上面提到的 POW//C> >之外,还可以实现更灵活的行为。不,不能自动检测常数参数。这样做会破坏D的编译模型(没有源代码,函数在编译后如何进行自我专门化?),理论上可以使用模板来完成,但事实并非如此。