# # lowRank package # Copyright (C) 2005 Jan de Leeuw # UCLA Department of Statistics, Box 951554, Los Angeles, CA 90095-1554 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # ################################################################### # # version 0.1.00, 2006-04-14, first release # version 0.2.00, 2006-04-15, added Huber, Talwar, Barya methods # version 0.3.00, 2006-04-16, added symmetric case # ipRectLS<-function(target,w=matrix(1,dim(target)[1],dim(target)[2]),ndim=2,init=FALSE,itmax=100,eps=1e-6,verbose=FALSE) { if (is.list(init)) { x<-init[[1]]; y<-init[[2]] } else { z<-svd(target); x<-z$u[,1:ndim]; y<-crossprod(target,x) } n<-dim(target)[1]; m<-dim(target)[2]; xy<-tcrossprod(x,y) oloss<-sum(w*(target-xy)^2); itel<-1 repeat { for (i in 1:n) { wi<-w[i,]; wti<-wi*target[i,] x[i,]<-solve(crossprod(y,wi*y),as.vector(wti%*%y)) } for (j in 1:m) { wj<-w[,j]; wtj<-wj*target[,j] y[j,]<-solve(crossprod(x,wj*x),as.vector(wtj%*%x)) } xy<-tcrossprod(x,y); nloss<-sum(w*(target-xy)^2) if (verbose) cat("Iteration: ",formatC(itel,digits=6,width=6), "Previous Loss: ",formatC(oloss,digits=6,width=12,format="f"), "Current Loss: ",formatC(nloss,digits=6,width=12,format="f"), "\n") if (((oloss-nloss) < eps) || (itel == itmax)) break() oloss<-nloss; itel<-itel+1 } q<-qr(x); x<-qr.Q(q); y<-tcrossprod(y,qr.R(q)) return(list(x=x,y=y)) } ipRectLAV<-function(target,w=matrix(1,dim(target)[1],dim(target)[2]),ndim=2,init=FALSE,reg=1e-6,itmax=100,eps=1e-6,verbose=FALSE) { if (is.list(init)) { x<-init[[1]]; y<-init[[2]] } else { z<-svd(target); x<-z$u[,1:ndim]; y<-crossprod(target,x) } n<-dim(target)[1]; m<-dim(target)[2]; xy<-tcrossprod(x,y) oloss<-sum(w*abs(target-xy)); itel<-1 repeat { res<-target-xy; ww<-w/sqrt((res^2)+reg) z<-ipRectLS(target,ww,init=list(x,y),ndim=ndim,itmax=1,verbose=FALSE) x<-z$x; y<-z$y; xy<-tcrossprod(x,y); nloss<-sum(w*abs(target-xy)) if (verbose) cat("Iteration: ",formatC(itel,digits=6,width=6), "Previous Loss: ",formatC(oloss,digits=6,width=12,format="f"), "Current Loss: ",formatC(nloss,digits=6,width=12,format="f"), "\n") if (((oloss-nloss) < eps) || (itel == itmax)) break() oloss<-nloss; itel<-itel+1 } q<-qr(x); x<-qr.Q(q); y<-tcrossprod(y,qr.R(q)) return(list(x=x,y=y)) } ipRectRobust<-function( target, w=matrix(1,dim(target)[1],dim(target)[2]), ndim=2, init=FALSE, fnc=list(f=fHuber,g=gHuber), cut=Inf, par=1, itmax=100, eps=1e-6, verbose=FALSE) { if (is.list(init)) { x<-init[[1]]; y<-init[[2]] } else { z<-svd(target); x<-z$u[,1:ndim]; y<-crossprod(target,x) } n<-dim(target)[1]; m<-dim(target)[2]; xy<-tcrossprod(x,y) oloss<-sum(w*(fnc$f)(target-xy,cut,par)); itel<-1 repeat { res<-target-xy; ntarg<-xy+(fnc$g)(res,cut,par) z<-ipRectLS(ntarg,w,init=list(x,y),ndim=ndim,itmax=1,verbose=FALSE) x<-z$x; y<-z$y; xy<-tcrossprod(x,y); nloss<-sum(w*(fnc$f)(target-xy,cut,par)) if (verbose) cat("Iteration: ",formatC(itel,digits=6,width=6), "Previous Loss: ",formatC(oloss,digits=6,width=12,format="f"), "Current Loss: ",formatC(nloss,digits=6,width=12,format="f"), "\n") if (((oloss-nloss) < eps) || (itel == itmax)) break() oloss<-nloss; itel<-itel+1 } q<-qr(x); x<-qr.Q(q); y<-tcrossprod(y,qr.R(q)) return(list(x=x,y=y)) } fHuber<-function(x,cut,par) { ifelse(abs(x)