### 1. Being stupid - need help

Hi,

I translated 2 routines "HoltWinterspredictAdd" and "HoltWinterspredictMult" from [https://github.com/antoinevastel/zodiac-ts/blob/master/index.js].

```-- Calculates the mean squared error
public function MeanSquaredError(sequence truth, sequence prediction)
for i = 1 to length(truth) do
end for
end function

public function HoltWinterspredictMult(sequence data, atom alpha, atom delta, atom gamma, integer seasonLength)
integer datalen = length(data)
sequence A = repeat(0.0, datalen)
sequence B = repeat(0.0, datalen)
sequence S = repeat(0.0, datalen)
A[seasonLength] = 0.0
atom averageFirstSeason = 0.0
for i = 1 to seasonLength do
averageFirstSeason += data[i]
end for
B[seasonLength] = averageFirstSeason/seasonLength
for i = 1 to seasonLength+1 do
S[i] = data[i]/(averageFirstSeason/seasonLength)
end for
for i = seasonLength+1 to datalen do
B[i] = alpha * (data[i]/S[i - seasonLength]) + (1.0-alpha)*(B[i-1]+A[i-1])
A[i] = gamma * (B[i]-B[i-1])  + (1.0-gamma)*A[i-1]
S[i] = delta * (data[i]/B[i]) + (1.0-delta)*S[i-seasonLength]
end for
sequence forecast = repeat(0.0, datalen + seasonLength)
for i = seasonLength+1 to datalen do
forecast[i] = (A[i-1] + B[i-1])*S[i - seasonLength]
end for
for i = datalen to datalen + seasonLength do
forecast[i] = (B[datalen-1] + (i - datalen-1) * A[datalen-1]) * S[i - seasonLength]
end for
A = {} B = {} S = {}
atom sse = MeanSquaredError(data, forecast)
return {sse, forecast}
end function

public public function HoltWinterspredictAdd(sequence data, atom alpha, atom delta, atom gamma, integer seasonLength)
integer datalen = length(data)
sequence A = repeat(0.0, datalen)
sequence B = repeat(0.0, datalen)
sequence S = repeat(0.0, datalen)
A[seasonLength] = 0.0
atom averageFirstSeason = 0.0
for i = 1 to seasonLength do
averageFirstSeason += data[i]
end for
B[seasonLength] = averageFirstSeason/seasonLength+1
for i = 1 to seasonLength+1 do
S[i] = data[i] - averageFirstSeason/seasonLength
end for
for i = seasonLength+1 to datalen do
B[i] = alpha * (data[i] - S[i - seasonLength]) + (1.0-alpha) * (B[i-1]+A[i-1])
A[i] = gamma * (B[i]-B[i-1])  + (1.0-gamma) * A[i-1]
S[i] = delta * (data[i] - B[i]) + (1.0-delta) * S[i-seasonLength]
end for
sequence forecast = repeat(0.0, datalen + seasonLength)
for i = seasonLength+1 to datalen do
forecast[i] = A[i-1] + B[i-1] + S[i - seasonLength]
end for
for i = datalen to datalen + seasonLength do
forecast[i] = B[datalen-1] + ((i - datalen) * A[datalen-1]) + S[i - seasonLength]
end for
A = {} B = {} S = {}
atom sse = MeanSquaredError(data, forecast)
return {sse, forecast}
end function
```

the functions are tested via:

```atom alpha = 0.4
atom gamma = 0.2
atom delta = 0.5
atom ret
sequence result
sequence data = {61.5, 63.2, 55.8, 71.4, 70, 71.4, 63.9, 78.9, 78.3, 78.6, 71.9, 87, 86.2, 87.5, 80.1, 92.5}
{ret, result} = HoltWinterspredictAdd(data, alpha, delta, gamma, 4)
sequence expectedResult = {0.0, 0.0, 0.0, 0.0, 61.5, 67.28, 62.537600000000005, 79.80115200000003, 73.13719104, 77.04783918080001,71.025120930816, 87.94969470636033,83.61671728317809,85.7372107163745,79.93725983621758,96.31433531356754,91.95095302251006,
92.64088086972602,85.36367192818317,100.17738187172976}

{ret, result} = HoltWinterspredictMult(data, alpha, delta, gamma, 4)
sequence expectedResult = {0, 0, 0, 0,61.5, 67.39278048780487, 61.81707875270145, 81.53022450414605,73.0764828139659, 77.07844011856474,69.47490699048109, 90.35656320643135,83.73280606463544, 85.74340016330459,77.7770276222308, 98.90911323239595,92.39012665258913, 92.99431396647569,83.54705489973043, 101.37471727927124}
```

when i run the functions, i get almost the correct expected results and i have no idea where my error is. So I need help - can any one venture a try?
I use phix and thank you in advance
Richard

### 2. Re: Being stupid - need help

Hi, I may be being equally stupid, and hopefully this will stimulate some thought rather than just a solution, but your mean squared error formula seems to be different to the .js one

```-- Calculates the mean squared error
public function MeanSquaredError(sequence truth, sequence prediction)
for i = 1 to length(truth) do
end for
end function
```
```exports.HoltWintersSmoothing.prototype.computeMeanSquaredError = function()
{
var SSE = 0.0;
var n = 0;
for(var i = 0; i < this.data.length; ++i)
{
if(this.data[i] != null && this.forecast[i] != null)
{
SSE += Math.pow(this.data[i] - this.forecast[i], 2);
n++;
}

}
return 1/(n-1)*SSE;
};
```

I might have tried

```-- Calculates the mean squared error
public function MeanSquaredError(sequence truth, sequence prediction)
integer n = 0
for i = 1 to length(truth) do
if truth[i] !=0 and prediction[i] !=0 then   --assumes that truth and prediction are same lenghts/elements
rss += power(truth[i] - prediction[i], 2)
n += 1
end if
end for
return 1/(n-1) * rss     --better check that n>1
end function
```

Anyway just a thought.

Chris

### 3. Re: Being stupid - need help

thank for your answer Chris. Yes you are correct, the MSE is different, since i think the one supplied is not correct. the MSE has no influence on the calculation of the prediction, but yes, I should augment it with your suggestions.
The prediction results of the functions seem to be correct, but they are slightly off and i can't find out why. That drives me really mad.

Richard

### 4. Re: Being stupid - need help

The other things to ask of course, are rounding errors, and which is the correct answer, yours or the .js script.

Chris

### 5. Re: Being stupid - need help

read it and weep (Seems to pass your tests 100% anyway - changing 0-based indexing to 1-based is a bit of a black art)

```-- Calculates the mean squared error
public function MeanSquaredError(sequence truth, prediction)
integer n = length(truth)
end function

public function HoltWinterspredictMult(sequence data, atom alpha, delta, gamma, integer seasonLength)
integer datalen = length(data)
sequence {A,B,S} @= repeat(0.0, datalen)
atom averageFirstSeason = sum(data[1..seasonLength])/seasonLength
B[seasonLength] = averageFirstSeason
S[1..seasonLength] = sq_div(data[1..seasonLength],averageFirstSeason)
for i=seasonLength+1 to datalen do
B[i] = alpha*(data[i]/S[i-seasonLength])+(1-alpha)*(B[i-1]+A[i-1])
A[i] = gamma*(B[i]-B[i-1])+(1-gamma)*A[i-1]
S[i] = delta*(data[i]/B[i])+(1-delta)*S[i-seasonLength]
end for
sequence forecast = repeat(0.0, datalen+seasonLength)
for i=seasonLength+1 to datalen do
forecast[i] = (A[i-1]+B[i-1])*S[i-seasonLength]
end for
for i=datalen+1 to datalen+seasonLength do
forecast[i] = (B[datalen]+(i-datalen)*A[datalen])*S[i-seasonLength]
end for
{A,B,S} @= {}
atom sse = MeanSquaredError(data, forecast)
return {sse, forecast}
end function

public function HoltWinterspredictAdd(sequence data, atom alpha, delta, gamma, integer seasonLength)
integer datalen = length(data)
sequence {A,B,S} @= repeat(0.0, datalen)
atom averageFirstSeason = sum(data[1..seasonLength])/seasonLength
B[seasonLength] = averageFirstSeason
S[1..seasonLength] = sq_sub(data[1..seasonLength],averageFirstSeason)
for i=seasonLength+1 to datalen do
B[i] = alpha*(data[i]-S[i-seasonLength])+(1-alpha)*(B[i-1]+A[i-1])
A[i] = gamma*(B[i]-B[i-1])+(1-gamma)*A[i-1]
S[i] = delta*(data[i]-B[i])+(1-delta)*S[i-seasonLength]
end for
sequence forecast = repeat(0.0, datalen+seasonLength)
for i=seasonLength+1 to datalen do
forecast[i] = A[i-1]+B[i-1]+S[i-seasonLength]
end for
for i=datalen+1 to datalen+seasonLength do
forecast[i] = B[datalen]+((i-datalen)*A[datalen])+S[i-seasonLength]
end for
{A,B,S} @= {}
atom sse = MeanSquaredError(data, forecast)
return {sse, forecast}
end function
```

### 6. Re: Being stupid - need help

Ok Pete,

I am weeping T_T.

Thanx for the code, I learned a lot from it - writing phix and not some mixture.

Richard