library("Matrix") # library("fields") # library('dr') # library('mvtnorm') # library(mgcv) # library(pracma) # library(RVAideMemoire) library("MAVE") # library(pls) # library(LaplacesDemon) # library(earth) # library("latex2exp") ################################################# ############################## ################################ fsquare<-function(x){ ret<-0 for (h in 1:length(x)){ret<-ret+x[h]^2} return(ret) } f_id<-function(x){return(x[1])} vfun<-function(x)return(c(cos(x),sin(x))) vfun_grad<-function(x)return(c(-sin(x),cos(x))) f_true<-function(x,sigma){return(sigma^2 + cos(x)^2)} ############################### ##creat sample for M2, b is B matrix of model, N..sample size, #f...link function, sigma..standard deviation of error term #produces sample with X standard normal with dimension to columnlength of b an # epsilon centered normal with standard deviation sigma creat_sample<-function(b,N,f,sigma){ if (is.vector(b)==1){dim<-length(b)} if (is.vector(b)==0){dim<-length(b[,1])} X<-mat.or.vec(N,dim) Y<-mat.or.vec(N,1) for (i in 1:N){ X[i,]<-rnorm(dim,0,1) Y[i]<-f(t(b)%*%X[i,])+rnorm(1,0,sigma) } dat<-cbind(Y,X) return(dat) } ##### creat_b<-function(dim,n){ temp<-mat.or.vec(dim,n) if (n>1){ while (rankMatrix(temp,method = 'qr')< min(dim,n)){ for (i in 1:n){ temp[,i]<-rnorm(dim,0,1) temp[,i]<-temp[,i]/sqrt(sum(temp[,i]^2)) } } } if (n==1) {temp<-rnorm(dim,0,1) temp<-temp/sqrt(sum(temp^2))} return(temp) } ### ### creat sample for M1,M3 ## b is B matrix of model, N..sample size, #f...link function, sigma..standard deviation of error term #produces sample with X normal with Covariancematrix SS' with dimension to columnlength of b an # epsilon centered normal with standard deviation sigma creat_sample_nor_nonstand<-function(b,N,f,S,sigma){ #Var(x)= SS' if (is.vector(b)==1){dim<-length(b)} if (is.vector(b)==0){dim<-length(b[,1])} X<-mat.or.vec(N,dim) Y<-mat.or.vec(N,1) for (i in 1:N){ X[i,]<-rnorm(dim,0,1)%*%t(S) Y[i]<-f(t(b)%*%X[i,])+rnorm(1,0,sigma) } dat<-cbind(Y,X) return(dat) } #### #### ### #### #### #### creat sample for M4 ##creat sample for M2, b is B matrix of model, N..sample size, #f...link function, sigma..standard deviation of error term #produces sample with X Gausian mixture #(i.e. X ~ (Zrep(-1,dim) + (1_Z)rep(1,dim))*dispers_para + N(0, I_p) and Z~B(pi) #with dimension to columnlength of b an # epsilon centered normal with standard deviation sigma creat_sample_noneliptic_gausmixture<-function(b,N,f,sigma,pi,dispers_para=1){ if (is.vector(b)==1){dim<-length(b)} if (is.vector(b)==0){dim<-length(b[,1])} X<-mat.or.vec(N,dim) Y<-mat.or.vec(N,1) for (i in 1:N){ p<-rbinom(1,1,pi) X[i,]<-(-rep(1,dim)*p+rep(1,dim)*(1-p))*dispers_para+rnorm(dim,0,1) Y[i]<-f(t(b)%*%X[i,])+rnorm(1,0,sigma) } dat<-cbind(Y,X) return(dat) } ### ############################### #estimates covariance matrix by ML estimate # X...n times dim data matrix with rows corresponding to X_i est_varmat<-function(X){ dim<-length(X[1,]) Sig<-mat.or.vec(dim,dim)#Cov(X) X<-scale(X,center = T,scale = F) Sig<-t(X)%*%X/length(X[,1]) return(Sig) } #### # normalizes a vector x such that it sums to 1 column_normalize<-function(x){return(x/sum(x))} #### #squared 2-norm of a vector x norm2<-function(x){return(sum(x^2))} ### # fills up the matrix estb (dim times q) (dim > q) to a dim times dim orthonormal matrix fill_base<-function(estb){ dim<-length(estb[,1]) k<-length(estb[1,]) P<-(diag(rep(1,dim))-estb%*%t(estb)) rk<-0 while (rk < dim){ tmp1<-P%*%creat_b(dim,1) nor<-sqrt(sum(tmp1^2)) if(nor>10^(-4)){ estb<-cbind(tmp1/nor,estb) rkn<-rankMatrix(estb,method = 'qr') if (rkn > rk){P<-(diag(rep(1,dim))-estb%*%t(estb)) rk<-rkn} } if(nor <=10^(-4)){rk<-0} } return(estb) } ################## ###new stiefel optimization #draws from the uniform measure of Stiefel(p,k) #returns a p times k dimensional semiorthogonal matrix stiefl_startval<-function(p,k){return(qr.Q(qr(matrix(rnorm(p*k,0,1),p,k))))} ##### chooses shifting points #auxiliary function for stielfel_opt # X... N times dim data matrix #S... sample covariance matrix #0 < p <=1 fraction of data point used as shifting points # if p=1 all data points used as shifting points q_ind<-function(X,S,p){ dim<-length(X[1,]) N<-length(X[,1]) if (p < 1){ Sinv<-solve(S) ind<-c() bound<-qchisq(p,dim) for (j in 1:N){if(t(X[j,])%*%Sinv%*%X[j,]<=bound){ind<-c(ind,j)}}#maybe demean q<-length(ind) if (q<=2){ q<-N ind<-seq(1,N)} } else { q<-N ind<-seq(1,N) } ret<-list(q,ind) names(ret)<-c('q','ind') return(ret) } #### #calculates the trace of a quadratic matrix S var_tr<-function(x){return(sum(diag(x)))} #### #chooses bandwith h according to formula in paper #dim...dimension of X vector #k... row dim of V (dim times q matrix) corresponding to a basis of orthogonal complement of B in model # N...sample size #nObs... nObs in bandwith formula #tr...trace of sample covariance matrix of X choose_h_2<-function(dim,k,N,nObs,tr){ #h1<-qchisq(nObs/N,2*(dim-k)) h2<-qchisq((nObs-1)/(N-1),(dim-k)) return(h2*2*tr/dim) } #### #auxiliary function for stiefel_opt #X... data matrix of random variable X #q,ind... output of function q_ind Xl_fun<-function(X,q,ind){ N<-length(X[,1]) Xl<-(kronecker(rep(1,q),X)-kronecker(X[ind,],rep(1,N))) return(Xl) } ########### # evaluates L(V) and returns L_n(V),(L_tilde_n(V,X_i))_{i=1,..,n} and grad_V L_n(V) (p times k) # V... (dim times q) matrix # Xl... output of Xl_fun # dtemp...vector with pairwise distances |X_i - X_j| # q...output of q_ind function # Y... vector with N Y_i values # if grad=T, gradient of L(V) also returned LV<-function(V,Xl,dtemp,h,q,Y,grad=T){ N<-length(Y) if(is.vector(V)){k<-1} else{k<-length(V[1,])} Xlv<-Xl%*%V d<-dtemp-((Xlv^2)%*%rep(1,k)) w<-dnorm(d/h)/dnorm(0) w<-matrix(w,N,q) w<-apply(w,2,column_normalize) mY<-t(w)%*%Y sig<-t(w)%*%(Y^2)-(mY)^2 # \tilde{L}_n(V, s_0) mit s_0 coresponds to q_ind if(grad==T){ grad<-mat.or.vec(dim,k) tmp1<-(kronecker(sig,rep(1,N))-(as.vector(kronecker(rep(1,q),Y))-kronecker(mY,rep(1,N)))^2) if(k==1){ grad_d<- -2*Xl*as.vector(Xlv) grad<-(1/h^2)*(1/q)*t(grad_d*as.vector(d)*as.vector(w))%*%tmp1 } else{ for (j in 1:(k)){ grad_d<- -2*Xl*as.vector(Xlv[,j]) grad[,j]<- (1/h^2)*(1/q)*t(grad_d*as.vector(d)*as.vector(w))%*%tmp1 } } ret<-list(mean(sig),sig,grad) names(ret)<-c('var','sig','grad') } else{ ret<-list(mean(sig),sig) names(ret)<-c('var','sig') } return(ret) } #### performs stiefle optimization of argmin_{V : V'V=I_k} L_n(V) #through curvilinear search with k0 starting values drawn uniformly on stiefel maniquefold #dat...(N times dim+1) matrix with first column corresponding to Y values, the other columns #consists of X data matrix, (i.e. dat=cbind(Y,X)) #h... bandwidth #k...row dimension of V that is calculated, corresponds to dimension of orthogonal complement of B #k0... number of arbitrary starting values #p...fraction of data points used as shifting point #maxit... number of maximal iterations in curvilinear search #nObs.. nObs parameter for choosing bandwidth if no h is supplied #lambda_0...initial stepsize #tol...tolerance for stoping iterations #sclack_para...if relative improvment is worse than sclack_para the stepsize is reduced #output: #est_base...Vhat_k= argmin_V:V'V=I_k L_n(V) a (dim times k) matrix where dim is row-dimension of X data matrix #var...value of L_n(Vhat_k) #aov_dat... (L_tilde_n(Vhat_k,X_i))_{i=1,..,N} #count...number of iterations #h...bandwidth #count2...number of times sclack_para is active stiefl_opt<-function(dat,h=NULL,k,k0=30,p=1,maxit=50,nObs=sqrt(length(dat[,1])),lambda_0=1,tol=10^(-3),sclack_para=0){ history <- matrix(NA, maxit, k0) Y<-dat[,1] X<-dat[,-1] N<-length(Y) dim<-length(X[1,]) S<-est_varmat(X) if(p<1){ tmp1<-q_ind(X,S,p) q<-tmp1$q ind<-tmp1$ind } else{ q<-N ind<-1:N } Xl<-(kronecker(rep(1,q),X)-kronecker(X[ind,],rep(1,N))) dtemp<-apply(Xl,1,norm2) tr<-var_tr(S) if(is.null(h)){h<-choose_h(dim,k,N,nObs,tr)} best<-exp(10000) Vend<-mat.or.vec(dim,k) sig<-mat.or.vec(q,1) for(u in 1:k0){ Vnew<-Vold<-stiefl_startval(dim,k) #print(Vold) #print(LV(Vold,Xl,dtemp,h,q,Y)$var) Lnew<-Lold<-exp(10000) lambda<-lambda_0 err<-10 count<-0 count2<-0 while(err>tol&count sclack_para){#/(count+1)^(0.5) lambda=lambda/2 err<-10 count2<-count2+1 count<-count-1 Vnew<-Vold #!!!!! } Vold<-Vnew count<-count+1 #print(count) # Write to history history[count, u] <- Lnew } if(best>Lnew){ best<-Lnew Vend<-Vnew sig<-tmp3$sig } } ret<-list(Vend,best,sig,count,h,count2, history) names(ret)<-c('est_base','var','aov_dat','count','h','count2', 'history') return(ret) } ##### calculates distance between two subspaces #i.e. |b1%*%(b1%*%b1')^{-1}%*%b1' - b2%*%(b2%*%b2')^{-1}%*%b2'|_2 subspace_dist<-function(b1,b2){ #b1<-orth(b1) #b2<-orth(b2) P1<-b1%*%solve(t(b1)%*%b1)%*%t(b1) P2<-b2%*%solve(t(b2)%*%b2)%*%t(b2) return(sqrt(sum((P1-P2)^2))) } ####performs local linaer regression #x...datapoint at where estimated function should be evaluated #h...bandwidth #dat..(N times dim+1) matrix with first column corresponding to Y values, the other columns #consists of X data matrix, (i.e. dat=cbind(Y,X)) #beta...projection matrix local_linear<-function(x,h,dat,beta){ Y<-dat[,1] X<-dat[,-1] N<-length(Y) X<-X%*%beta x<-x%*%beta#beta%*%x D_mat<-cbind(rep(1,N),X) if (is.vector(X)){ dim<-1 d<-abs(X-rep(x,N)) } else{ dim<-length(X[1,]) d<-sqrt(apply(X-t(matrix(rep(x,N),dim,N)),1,norm2)) } K<-diag(dnorm(d/h)/dnorm(0)) pred<-c(1,x)%*%solve(t(D_mat)%*%K%*%D_mat)%*%t(D_mat)%*%K%*%Y return(pred) }