2

我目前正在从事一个项目,其中包括机器学习的高斯过程。考虑到书中的示例和解释,我正在尝试为作为训练的 GP 对象的一部分的各种参数创建一个通用函数 - 因此,以下声明是(简单)训练函数的最通用声明。

def train[T, M <: MatrixInverter[T], S <: Kernel[T]](): GP_Spawn[T] = null

(如果您想知道,我已经删除了参数列表和实现。) T描述了数字类型,例如它可能是Doubleor IntMatrixInverter[T]是执行calculateInverse功能的特征。Kernel[T]是核函数的相应特征。正如你们中的一些人可能已经知道的那样,当使用Cholesky-Decomposition作为矩阵逆变器时,可以更改高斯过程中的训练(以某种方式简化)- 因此,我考虑过专门化上述功能。由于@specialized标签的文档,它应该是这样的:

def train[T, @specialized(CholeskyDecomposition[T]) M <: MatrixInverter[T], S <: Kernel[T]](): GP_Spawn[T] 

很明显,所有参数或多或少都依赖于T,因为它们需要使用一些依赖于它的变量(类型TVector[T]、 )。Matrix[T]如果我尝试编译上面提到的代码,scala-compiler (2.9.2) 抱怨

错误:未找到:值 CholeskyDecomposition

我不确定这意味着什么,因为导入import algorithms.{CholeskyDecomposition, MatrixInverter}是正确的。此外,很奇怪看到 importCholeskyDecomposition被标记为Unused import statementCholeskyDecomposition有一个同伴,其中包含一些与算法本身相关的常量,但我不认为这方面是导致此错误的原因。

任何想法可能导致此错误?而且,如何在削减通用方法的情况下解决它?

编辑:

在阅读了答案后正在考虑对我的代码进行一些重新排序,我最终在运行时得到了一个使用类型匹配的解决方案。

val testMat = new Matrix[T](3, 3)
val testInv = fac(testMat)    
testInv match {
    case chol : CholeskyDecomposition[T] => println("Found Cholesky!")
    case _ => println("Found something different.")
}

它现在可以工作了:) 谢谢大家!

4

3 回答 3

5

您只能将泛型参数特化为原始类型:IntDouble等。因此您可以特化TFoo[T]即使T是原始类型也不能。

于 2012-11-22T11:25:45.350 回答
3

如果您有一个C专门研究 type的课程T,那么

class D[@specialized T, C[T]](c: C[T]) { ... }

将使用 的T-specialized 版本C

无论如何,这就是你所需要的。没有必要专门研究对象;通用代码也同样有效,因为所有非原始的东西都是对象。

于 2012-11-22T13:54:22.600 回答
1

根据API,它说:

Type T can be specialized on a subset of the primitive types by
specifying a list of primitive types to specialize at:

所以它基本上只适用于原始类型。

于 2012-11-22T11:28:14.150 回答