2017-04-13 101 views
0

我相對較新的斯卡拉,一直使用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 =() 

更新:我有固定的代碼,現在我收到以下錯誤:

Column must be in bounds for slice!

有人可以幫我理解我做錯了什麼嗎?

回答

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]這就是爲什麼沒有得到執行。

+0

通過這樣做,我得到了我的代碼幾個問題,也許這意味着我的代碼也不正確。感謝你們對我的幫助。 – Jamil

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 
+0

我認爲問題在於AAprediction沒有在循環內部填充,或者沒有輸出。 – Jamil

0

我將簡化部分,你沒看錯或誤解,但我相信這將是足夠的瞭解什麼地方出了錯,你就會知道如何解決它。

你定義它看起來像這樣的預測功能:

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

,然後你用2點所需的參數,而現在如果你將替代該變量,它應該是這樣的: prediction(2, 3)

number => (number + 2) * 3 < - 這是一個功能,不是嗎?

要計算最終值,您需要使用anonymous function中的第三個參數。

所以在我們的例子prediction(2, 3)(1)會給我們的實際輸出9. ,也可以定義def addTwoMultiplyByThree = prediction(2, 3) 並與多個其他值使用。

+0

這是一個表達式(number + 2)* 3' – pedrofurla

+0

'number =>(number + 2)* 3'這是一個函數。 – pedrofurla