2013-11-07 4 views
0

Я пытаюсь реплицировать функцию для WLS (взвешенных наименьших квадратов), которую я нашел в учебнике в excel. Существует ошибка значения, и я думаю, что я делаю что-то неправильно в использовании функции.Программирование Функция WLS excel vba

Ниже приведен код VBA для опорной функции Diag (W) и функции самого WLSregress():

Function Diag(W) As Variant 
Dim n, i, j, k As Integer 
Dim temp As Variant 
n = W.Count 
ReDim temp(n, n) 
For i = 1 To n 
    For j = 1 To n 
     If j = i Then temp(i, j) = W(i) Else temp(i, j) = 0 
    Next j 
Next i 
Diag = temp 

End Function 

Function WLSregress(y As Variant, X As Variant, W As Variant) As Variant 
Wmat = Diag(W) 
n = W.Count 
Dim Xtrans, Xw, XwX, XwXinv, Xwy As Variant 
Dim m1, m2, m3, m4 As Variant 
Dim output() As Variant 
Xtrans = Application.Tranpose(X) 
Xw = Application.MMult(Xtrans, Wmat) 
XwX = Application.MMult(Xw, X) 
XwXinv = Application.MInverse(XwX) 
Xwy = Application.MMult(Xw, y) 
b = Application.MMult(XwXinv, Xwy) 
k = Application.Count(b) 
ReDim output(k) As Variant 
    For bcnt = 1 To k 
     output(bcnt) = b(bcnt, 1) 
    Next bcnt 
WLSregress = Application.Transpose(output) 
End Function 

Эта функция должна возвращать оценщик WLS для объясняющих переменных уравнения оценивается. Я понимаю код, ведущий к линии k = Application.Count(b), но не слишком уверен, как работает выходной бит.

Если кто-нибудь может помочь мне понять, почему это не работает, я был бы очень благодарен.

Ниже приведен пример изображения функции, пытающейся работать. example

ответ

3

По умолчанию Excel начнет калибровать свои массивы с помощью 0, если вы не указали иначе. Например,

Redim arr(2,2)

будет на самом деле даст вам массив 3 х 3

 0  1  2 
0 blank | blank | blank 
1 blank | blank | blank 
2 blank | blank | blank 

Из-за этого, когда у вас есть ReDim temp(n, n), вы на самом деле создаете массив с более одной строки и столбца чем вы на самом деле хотите. В вашем примере, можно ожидать, что диалог для A3: 18, чтобы быть диалоговым окно 16 х 16, но это будет на самом деле создать диалог 17 х 17, сбросив свои матричные умножения (т.е. Application.MMult)

Замените эту строку

ReDim temp(n, n)

С этой линией

ReDim temp(1 to n, 1 to n)

И теперь вы должны получить результаты возвращаются. До вас, чтобы определить, является ли результат точным или нет.

+0

хороший улов ... однако по какой-то причине он по-прежнему не работает. Мне придется посмотреть еще раз. –

+0

Интересно; Я проверил его с вашим образцом данных, и я смог получить результаты. Попробуйте изменить весь код с «Application.Transpose» на «Application.WorksheetFunction.Transpose» – Jaycal

+0

Кажется, ничего не делал. Может быть, это связано с тем, как я вхожу в эту функцию? Я ввел его как нормальную формулу и как формулу массива и не получил никакой удачи. –

Смежные вопросы