Not : Bu cevabın genişletilmiş versiyonunu web siteme gönderdim .
Açıkça gerçek R motoruyla benzer bir cevap göndermeyi düşünür müsünüz?
Emin! Tavşan deliğinden aşağıya gidiyoruz.
İlk katman, lm
arayüz R programlayıcısına maruz kalmış. Bunun için kaynağa sadece lm
R konsoluna yazarak bakabilirsiniz . Bunların çoğunluğu (çoğu üretim seviyesi kodunun çoğunluğu gibi) girdilerin kontrolü, nesne niteliklerinin ayarlanması ve hataların atılmasıyla meşgul; ama bu çizgi yapışıyor
lm.fit(x, y, offset = offset, singular.ok = singular.ok,
...)
lm.fit
is another R function, you can call it yourself. While lm
conveniently works with formulas and data frame, lm.fit
wants matrices, so that's one level of abstraction removed. Checking the source for lm.fit
, more busywork, and the following really interesting line
z <- .Call(C_Cdqrls, x, y, tol, FALSE)
Now we are getting somewhere. .Call
is R's way of calling into C code. There is a C function, C_Cdqrls in the R source somewhere, and we need to find it. Here it is.
Looking at the C function, again, we find mostly bounds checking, error cleanup, and busy work. But this line is different
F77_CALL(dqrls)(REAL(qr), &n, &p, REAL(y), &ny, &rtol,
REAL(coefficients), REAL(residuals), REAL(effects),
&rank, INTEGER(pivot), REAL(qraux), work);
So now we are on our third language, R has called C which is calling into fortran. Here's the fortran code.
The first comment tells it all
c dqrfit is a subroutine to compute least squares solutions
c to the system
c
c (1) x * b = y
(ilginç bir şekilde, bu rutinin adı bir noktada değiştirilmiş gibi görünüyor, ancak birisi yorumu güncellemeyi unuttu). Bu yüzden nihayet bazı lineer cebir yapabileceğimiz ve aslında denklem sistemini çözdüğümüz noktadayız. Bu, fortran'ın gerçekten iyi olduğu bir şey. Bu, neden buraya ulaşmak için bu kadar çok katmandan geçtiğimizi açıklıyor.
Bu yorum ayrıca kodun ne yapacağını da açıklar
c on return
c
c x contains the output array from dqrdc2.
c namely the qr decomposition of x stored in
c compact form.
Fortran bularak sistemini çözeceğini mi Yani QR ayrışma.
Olan ve en önemlisi olan ilk şey
call dqrdc2(x,n,n,p,tol,k,qraux,jpvt,work)
Bu dqrdc2
giriş matrisindeki fortran fonksiyonunu çağırır x
. Bu nedir?
c dqrfit uses the linpack routines dqrdc and dqrsl.
Sonunda Linpack için yaptık. Linpack is a fortran linear algebra library that has been around since the 70s. Most serious linear algebra eventualy finds its way to linpack. In our case, we are using the function dqrdc2
c dqrdc2 uses householder transformations to compute the qr
c factorization of an n by p matrix x.
XX=QRQRQR you can solve the linear equations for regression
XtXβ=XtY
very easily. Indeed
XtX=RtQtQR=RtR
so the whole system becomes
RtRβ=RtQty
but R is upper triangular and has the same rank as XtX, so as long as our problem is well posed, it is full rank, and we may as well just solve the reduced system
Rβ=Qty
But here's the awesome thing. R is upper triangular, so the last linear equation here is just constant * beta_n = constant
, so solving for βn is trivial. You can then go up the rows, one by one, and substitute in the βs you already know, each time getting a simple one variable linear equation to solve. So, once you have Q and R, the whole thing collapses to what is called backwards substitution, which is easy. You can read about this in more detail here, where an explicit small example is fully worked out.