Scala引用另一个函数

时间:2017-04-13 14:25:30

标签: scala intellij-idea scala-breeze

我对Scala比较陌生,之前一直在使用R和MATLAB。我在Scala中编写了以下代码。我在R和MATLAB中编写了相同的代码,两者都运行得很好,但由于我对Scala缺乏经验,下面的代码不起作用。

import breeze.linalg._
import breeze.numerics.exp
import scala.math.log



val data =  breeze.stats.distributions.Uniform(0, 1)

val ep: DenseMatrix[Double] = DenseMatrix.rand(39, 3, data).t

val a = DenseVector(1.0)

val out: DenseMatrix[Double] = tile(a, 1, 39)

val fout: DenseVector[Double] = out.toDenseVector

val A: Double = 0.0

val B: Double = 1.0

val eta: Double = 2.0 / Math.pow(B - A, 2.0)

val nCol: Int = 39

val nRow: Int = 3

var gA = 0.0

var gB = 0.0

var gamma = 0.0


def SubstFunction(predictions: DenseVector[Double], expertsPrediction: DenseVector[Double]): Double = {

  gA = -(1 / eta) * log(predictions dot exp(-eta * (expertsPrediction :- A)) :^ 2.0)

  gB = -(1 / eta) * log(predictions dot exp(-eta * (expertsPrediction :- B)) :^ 2.0)

  gamma = (0.5 * (B + A)) - ((gB - gA) / 2 * (B - A))

  gamma

}


def prediction(Input: DenseMatrix[Double], outcomes: DenseVector[Double]): DenseVector[Double] = {

  var weights = DenseVector(1.0,1.0,1.0)

  val AAprediction = DenseVector.fill(nCol)(0.0)

  //DenseVector.ones[Double](nCol).t

  for (l<-0 to Input.cols) {

    val normalisedWeights = weights / sum(weights)

    AAprediction(l) = SubstFunction(normalisedWeights, Input(::,l))

    weights = normalisedWeights :* exp(eta :* (Input(::,l) :- outcomes(l)) :^ 2.0).toDenseVector
  }
  AAprediction: DenseVector[Double]
}

prediction(ep,fout)

我认为问题可能出在预测中调用sbstFunction时。我在intelliJ中使用Scala工作表。当我运行代码时,我没有得到任何错误,但我没有获得数字输出而是得到:

<function1> res1: Unit = ()

更新:我修复了代码,现在我收到以下错误:

  

列必须在切片的边界内!

有人可以帮我理解我做错了吗?

3 个答案:

答案 0 :(得分:1)

def prediction(Input: DenseMatrix[Double], outcomes: DenseMatrix[Double]) = 
  (AAprediction: DenseVector[Double]) => {

这是prediction的声明。这是一个接受两个参数并返回一个函数的方法。快速查看代码看起来它的函数类型为DenseVector[Double] => DenseVector[Double],更精确的声明是:

def prediction(Input: DenseMatrix[Double], 
   outcomes: DenseMatrix[Double]): DenseVector[Double] => DenseVector[Double]

基本上它在prediction(ep,out)中所做的是构建一个函数。一个更简单的例子:

scala> def addConst(x:Int):Int => Int = y => x + y 
addConst: (x: Int)Int => Int

scala> addConst(10)
res1: Int => Int = <function1>

在这种情况下,我们再次构建了一个函数。要使用此功能,我们可以调用res1(5)

scala> addConst(10)(5)
res2: Int = 15

答案 1 :(得分:0)

scala中的基本功能定义如下:

def f(x:Int):Int = {
  x
}

在您定义输入类型Int的位置,返回类型Int和函数体。

你拥有的是什么(对于prediction方法):

def f(x:Int) = (y:Int) => y + x

其中f返回另一个函数Int => Int。在您的情况下,prediction函数返回一个函数DenseVector[Double] => DenseVector[Double],这就是为什么没有执行任何内容。

答案 2 :(得分:0)

我会简化部分,你做错了或误解了,但我相信它足以理解出了什么问题,你会知道如何解决它。

您定义了预测函数,如下所示:

def prediction(addTo: Int, multiplyBy: Int) = (number: Int) => { (number + addTo) * multiplyBy }

然后你使用了2个必需参数,现在如果你要替换这个变量,它将如下所示: prediction(2, 3)

number => (number + 2) * 3&lt; - 这是一个函数,不是吗?

要计算最终值,您需要使用anonymous function内的第3个参数。

所以在我们的例子中prediction(2, 3)(1)会给我们一个实际的输出9。 或者您可以定义def addTwoMultiplyByThree = prediction(2, 3) 并将其与多个其他值一起使用。