Nota : Publiquei uma versão expandida desta resposta no meu site .
Você consideraria postar uma resposta semelhante com o mecanismo R real exposto?
Certo! Abaixo a toca do coelho nós vamos.
A primeira camada é lm
a interface exposta ao programador R. Você pode procurar a fonte disso apenas digitando lm
no console R. A maior parte (como a maioria da maioria dos códigos de nível de produção) é ocupada na verificação de entradas, na configuração de atributos de objetos e no lançamento de erros; mas essa linha se destaca
lm.fit(x, y, offset = offset, singular.ok = singular.ok,
...)
lm.fit
é outra função R, você pode chamá-lo você mesmo. Embora lm
trabalhe convenientemente com fórmulas e quadro de dados, lm.fit
deseja matrizes, então esse é um nível de abstração removido. Verificando a fonte lm.fit
, mais trabalho ocupado e a seguinte linha realmente interessante
z <- .Call(C_Cdqrls, x, y, tol, FALSE)
Agora estamos chegando a algum lugar. .Call
é a maneira de R chamar o código C. Existe uma função C, C_Cdqrls na fonte R em algum lugar, e precisamos encontrá-la. Aqui está .
Olhando para a função C, novamente, encontramos principalmente verificação de limites, limpeza de erros e trabalho ocupado. Mas essa linha é diferente
F77_CALL(dqrls)(REAL(qr), &n, &p, REAL(y), &ny, &rtol,
REAL(coefficients), REAL(residuals), REAL(effects),
&rank, INTEGER(pivot), REAL(qraux), work);
Então agora estamos no nosso terceiro idioma, R chamou C, que está chamando para o fortran. Aqui está o código fortran .
O primeiro comentário diz tudo
c dqrfit is a subroutine to compute least squares solutions
c to the system
c
c (1) x * b = y
(curiosamente, parece que o nome dessa rotina foi alterado em algum momento, mas alguém se esqueceu de atualizar o comentário). Então, finalmente chegamos ao ponto em que podemos fazer álgebra linear e resolver o sistema de equações. É nesse tipo de coisa que o fortran é realmente bom, o que explica por que passamos por tantas camadas para chegar até aqui.
O comentário também explica o que o código fará
c on return
c
c x contains the output array from dqrdc2.
c namely the qr decomposition of x stored in
c compact form.
Q R
A primeira coisa que acontece, e de longe a mais importante, é
call dqrdc2(x,n,n,p,tol,k,qraux,jpvt,work)
Isso chama a função fortran dqrdc2
em nossa matriz de entrada x
. O que é isso?
c dqrfit uses the linpack routines dqrdc and dqrsl.
Finalmente chegamos ao linpack . O Linpack é uma biblioteca de álgebra linear fortran que existe desde os anos 70. A álgebra linear mais séria acaba chegando ao linpack. No nosso caso, estamos usando a função dqrdc2
c dqrdc2 uses householder transformations to compute the qr
c factorization of an n by p matrix x.
XX= Q RQRQR
XtXβ= XtY
muito facilmente. De fato
XtX= RtQtQ R = RtR
então todo o sistema se torna
RtR β= RtQty
RXtX
R β= Qty
Rconstant * beta_n = constant
βnβQR