.packageName <- "classPP"

#############################################
#
# PP index calculation
#
#############################################
PPindex.class<-function(PPmethod,data,class,weight=TRUE,r=NULL,lambda=NULL,...)
{
 if(PPmethod =="LDA") 
      index<-PPindex.LDA(data,class,weight)
  else if(PPmethod =="Lp") 
     index<-PPindex.Lp(data,class,r)
  else if(PPmethod =="PDA") 
     index<-PPindex.PDA(data,class,lambda)
  else
     return("ERROR : You need to select PPmethod!")
  return(index)
}
  
PPindex.LDA<-function(data,class,weight=TRUE,...)
{
  data<-as.matrix(data);
  class<-as.matrix(class);
  if(ncol(class)!=1) class<-t(class)
  p<-ncol(data);n<-nrow(data);
  ngroup<-table(class)
  groups<-length(ngroup)

  gn<-names(table(class))
  class.i<-matrix(rep(0,n),n)
  for (i in 1:n) {
      for (j in 1:groups) if (class[i, 1] == gn[j]) 
          class.i[i, 1] <- j
  }

  val<-1;
  class.sort<-sort.list(class.i)
  class<-class.i[class.sort]
  data<-data[class.sort,]
  ngroup<-table(class.i)
  groups<-length(ngroup)
  gname<-names(ngroup)
  
  if(weight==TRUE)
   LDA  = .C("discriminant1", 
             as.integer(n),
             as.integer(p),
             as.integer(groups),
             x=as.double(data),
             class=as.integer(class), 
             as.integer(gname),
             ngroup=as.integer(ngroup),
             index=as.double(val))
  else
   LDA  = .C("discriminant2", 
             as.integer(n),
             as.integer(p),
             as.integer(groups),
             x=as.double(data),
             class=as.integer(class), 
             as.integer(gname),
             ngroup=as.integer(ngroup),
             index=as.double(val))

  return(LDA$index)
}   
  
PPindex.PDA<-function(data,class,lambda,...)
{
  if(is.null(lambda)) 
   return("ERROR : You need to use parameter lambda !")
  data<-as.matrix(data);
  class<-as.matrix(class);
  if(ncol(class)!=1) class<-t(class)
  p<-ncol(data);n<-nrow(data);
  ngroup<-table(class)
  groups<-length(ngroup)

  gn<-names(table(class))
  class.i<-matrix(rep(0,n),n)
  for (i in 1:n) {
      for (j in 1:groups) if (class[i, 1] == gn[j]) 
          class.i[i, 1] <- j
  }

  val<-1;
  class.sort<-sort.list(class.i)
  class<-class.i[class.sort]
  data<-data[class.sort,]
  ngroup<-table(class.i)
  groups<-length(ngroup)
  gname<-names(ngroup)
  
   PDA  = .C("pda", 
             as.integer(n),
             as.integer(p),
             as.integer(groups),
             x=as.double(data),
             class=as.integer(class), 
             as.integer(gname),
             ngroup=as.integer(ngroup),
             index=as.double(val),
             as.double(lambda))
  return(PDA$index)
}   

PPindex.Lp<-function(data,class,r,...)
{
  if(is.null(r)) 
   return("ERROR : You need to select parameter r !")

  data<-as.matrix(data);
  class<-as.matrix(class);
  if(ncol(class)!=1) class<-t(class)
  p<-ncol(data);n<-nrow(data);
  ngroup<-table(class)
  groups<-length(ngroup)

  gn<-names(table(class))
  class.i<-matrix(rep(0,n),n)
  for (i in 1:n) {
      for (j in 1:groups) if (class[i, 1] == gn[j]) 
          class.i[i, 1] <- j
  }

  val<-1;
  class.sort<-sort.list(class.i)
  class<-class.i[class.sort]
  data<-data[class.sort,]
  ngroup<-table(class.i)
  groups<-length(ngroup)
  gname<-names(ngroup)

  LDA  = .C("discriminant3", 
             as.integer(n),
             as.integer(p),
             as.integer(groups),
             x=as.double(data),
             class=as.integer(class), 
             as.integer(gname),
             ngroup=as.integer(ngroup),
             index=as.double(val),
             as.integer(r))
  return(LDA$index)
}   

##########################################################
PP.optimize.random<-function(PPmethod,projdim,data,class,std=TRUE,cooling=0.99,temp=1,r=NULL,lambda=NULL,weight=TRUE,...)
{
  data<-as.matrix(data);
  class<-as.matrix(class);
  pp<-ncol(data)
  if(std)
  { remove<-c(1:pp)*(apply(data,2,sd)==0);remove<-remove[remove!=0];
    if(length(remove)!=0)
    { #print("Remove variables with variance 0"); print(colnames(data)[remove]);
      data<-data[,-remove]
    } 
   data<-apply(data,2,function(x){(x-mean(x))/sd(x)})
  }

  if(ncol(class)!=1) class<-t(class)
  p<-ncol(data);n<-nrow(data);
  ngroup<-table(class)
  groups<-length(ngroup)

  gn<-names(table(class))
  class.i<-matrix(rep(0,n),n)
  for (i in 1:n) {
      for (j in 1:groups) if (class[i, 1] == gn[j]) 
          class.i[i, 1] <- j
  }

  val<-1;
  proj<-matrix(rep(1,p*projdim),p)
  class.sort<-sort.list(class.i)
  class<-class.i[class.sort]
  data<-data[class.sort,]
  ngroup<-table(class.i)
  groups<-length(ngroup)
  gname<-names(ngroup)

  if(PPmethod =="LDA" &&weight==TRUE) 
      method<-1
  else if(PPmethod =="LDA" &&weight==FALSE) 
      method<-2
  else if(PPmethod =="Lp") 
    { method<-3
      if(is.null(r)) 
        return("ERROR : You need to select parameter r !")
    }
  else if(PPmethod =="Gini") 
      method<-4
  else if(PPmethod =="Ent") 
      method<-5
  else  if(PPmethod =="PDA") 
    { method<-6
      if(is.null(lambda)) 
        return("ERROR : You need to select parameter lambda !")
      }
  else
      method<-NULL
  if(is.null(method))
   return("ERROR : You need to select PPmethod!")
     
  temp.start<-1;
  temp.end<-0.001;
  heating<-1;
  restart<-1;
  success<-0;
  maxproj<-1000;  

  Opt  = .C("optimize1", 
             as.integer(n),
             as.integer(p),
             as.integer(groups),
             x=as.double(data),
             as.integer(class),
             as.integer(gname), 
             as.integer(ngroup),
             as.integer(method),
             cooling=as.double(cooling),
             temp=as.double(temp),
             projdim=as.integer(projdim),
             index=as.double(val),
             proj=as.double(proj),
             as.integer(r),
             as.double(lambda))
  index.best<-Opt$index
  if(pp !=p)
  { proj.best<-matrix(rep(0,pp*projdim),ncol=projdim)
    proj.best[-remove,]<-matrix(Opt$proj,ncol=projdim)
  }
  else
    proj.best<-matrix(Opt$proj,ncol=projdim)
  return(index.best,proj.best)
}

#########################
PP.optimize.anneal<-function(PPmethod,projdim,data,class,std=TRUE,cooling=0.999,temp=1,energy=0.01,r=NULL,lambda=NULL,weight=TRUE,...)
{
  data<-as.matrix(data);
  class<-as.matrix(class);
  pp<-ncol(data)
  if(std)
  { remove<-c(1:pp)*(apply(data,2,sd)==0);remove<-remove[remove!=0];
    if(length(remove)!=0)
    { #print("Remove variables with variance 0"); print(colnames(data)[remove]);
      data<-data[,-remove]
    } 
   data<-apply(data,2,function(x){(x-mean(x))/sd(x)})
  }

  if(ncol(class)!=1) class<-t(class)
  p<-ncol(data);n<-nrow(data);
  ngroup<-table(class)
  groups<-length(ngroup)

  gn<-names(table(class))
  class.i<-matrix(rep(0,n),n)
  for (i in 1:n) {
      for (j in 1:groups) if (class[i, 1] == gn[j]) 
          class.i[i, 1] <- j
  }

  val<-1;
  proj<-matrix(rep(1,p*projdim),p)
  class.sort<-sort.list(class.i)
  class<-class.i[class.sort]
  data<-data[class.sort,]
  ngroup<-table(class.i)
  groups<-length(ngroup)
  gname<-names(ngroup)
  if(PPmethod =="LDA" &&weight==TRUE) 
      method<-1
  else if(PPmethod =="LDA" &&weight==FALSE) 
      method<-2
  else if(PPmethod =="Lp") 
    { method<-3
      if(is.null(r)) 
        return("ERROR : You need to select parameter r !")
    }
  else if(PPmethod =="Gini") 
      method<-4
  else if(PPmethod =="Ent") 
      method<-5
  else  if(PPmethod =="PDA") 
    { method<-6
      if(is.null(lambda)) 
        return("ERROR : You need to select parameter lambda !")
      }
  else
      method<-NULL
  if(is.null(method))
   return("ERROR : You need to select PPmethod!")

  Opt  = .C("optimize2", 
             as.integer(n),
             as.integer(p),
             as.integer(groups),
             x=as.double(data),
             as.integer(class), 
             as.integer(gname),
             as.integer(ngroup),
             as.integer(method),
             cooling=as.double(cooling),
             temp=as.double(temp),
             projdim=as.integer(projdim),
             index=as.double(val),
             proj=as.double(proj),
             as.double(energy),
             as.integer(r),
             as.double(lambda))
  index.best<-Opt$index
  if(pp !=p)
  { proj.best<-matrix(rep(0,pp*projdim),ncol=projdim)
    proj.best[-remove,]<-matrix(Opt$proj,ncol=projdim)
  }
  else
    proj.best<-matrix(Opt$proj,ncol=projdim)

  return(index.best,proj.best)
}

###############
PP.optimize.Huber <-function(PPmethod,projdim,data,class,std=TRUE,cooling=0.99,temp=1,r=NULL,lambda=NULL,weight=TRUE,...)
{
   

  data<-as.matrix(data);
  class<-as.matrix(class);
  pp<-ncol(data)
  if(std)
  { remove<-c(1:pp)*(apply(data,2,sd)==0);remove<-remove[remove!=0];
    if(length(remove)!=0)
    { #print("Remove variables with variance 0"); print(colnames(data)[remove]);
      data<-data[,-remove]
    } 
   data<-apply(data,2,function(x){(x-mean(x))/sd(x)})
  }

  if(ncol(class)!=1) class<-t(class)
  p<-ncol(data);n<-nrow(data);
  ngroup<-table(class)
  groups<-length(ngroup)

  gn<-names(table(class))
  class.i<-matrix(rep(0,n),n)
  for (i in 1:n) {
      for (j in 1:groups) if (class[i, 1] == gn[j]) 
          class.i[i, 1] <- j
  }

  val<-1;
  proj<-matrix(rep(1,p*projdim),p)
  class.sort<-sort.list(class.i)
  class<-class.i[class.sort]
  data<-data[class.sort,]
  ngroup<-table(class.i)
  groups<-length(ngroup)
  gname<-names(ngroup)
  if(PPmethod =="LDA" &&weight==TRUE) 
      method<-1
  else if(PPmethod =="LDA" &&weight==FALSE) 
      method<-2
  else if(PPmethod =="Lp") 
    { method<-3
      if(is.null(r)) 
        return("ERROR : You need to select parameter r !")
    }
  else if(PPmethod =="Gini") 
      method<-4
  else if(PPmethod =="Ent") 
      method<-5
  else  if(PPmethod =="PDA") 
    { method<-6
      if(is.null(lambda)) 
        return("ERROR : You need to select parameter lambda !")
      }
  else
      method<-NULL
  if(is.null(method))
   return("ERROR : You need to select PPmethod!")

  Opt  = .C("optimize3", 
             as.integer(n),
             as.integer(p),
             as.integer(groups),
             x=as.double(data),
             as.integer(class), 
             as.integer(gname),
             as.integer(ngroup),
             as.integer(method),
             cooling=as.double(cooling),
             temp=as.double(temp),
             projdim=as.integer(projdim),
             index=as.double(val),
             proj=as.double(proj),
             as.integer(r))
  index.best<-Opt$index
  if(pp !=p)
  { proj.best<-matrix(rep(0,pp*projdim),ncol=projdim)
    proj.best[-remove,]<-matrix(Opt$proj,ncol=projdim)
  }
  else
    proj.best<-matrix(Opt$proj,ncol=projdim)

  return(index.best,proj.best)
}

#########################
PP.optimize.plot<-function(PP.opt,data,class,std=TRUE)
{ 
  pp<-ncol(data);n<-nrow(data);
  if(std)
  { remove<-c(1:pp)*(apply(data,2,sd)==0);remove<-remove[remove!=0];
    if(length(remove)!=0)
    { #print("Remove variables with variance 0"); print(colnames(data)[remove]);
      data<-data[,-remove]
    } 
   data.s<-apply(data,2,function(x){(x-mean(x))/sd(x)})
  
  if(pp != ncol(data.s))
  { data<-matrix(rep(0,pp*n),ncol=pp)
    data[,-remove]<-matrix(data.s,ncol=pp)
  }
  }
  data<-as.matrix(data);
  n<-nrow(data)
  class<-as.matrix(class);
  if(ncol(class)!=1) class<-t(class)
  ngroup<-table(class)
  groups<-length(ngroup)

  gn<-names(table(class))
  t.class<-matrix(rep(0,n),n)
  for (i in 1:n) {
      for (j in 1:groups) if (class[i, 1] == gn[j]) 
          t.class[i, 1] <- j
  }

  p<-ncol(PP.opt$proj.best)
  proj.data<-as.matrix(data)%*%PP.opt$proj.best
  labels<-NULL
  for(i in 1:p)
      labels<-c(labels, paste("PP",i,sep=""))


 if(p==1)
 { 
   hist(proj.data,main=paste(" "),xlab=labels[1]) 
   ngroup<-table(t.class)
   ng<-length(ngroup)
   sort.index<-sort.list(t.class)
   sort.data<-sort(t.class)
   k<-0
   step<-n/10/ng
   for(j in 1:ng)
   {  ngg<-ngroup[j]
      for(i in 1:ngg)
      {  k<-k+1
         text(proj.data[sort.index[k]],step*j, 
              as.character(t.class[sort.index[k]]),cex=2)  
              
      }
    }
  }
 else if(p==2)
 { par(pty='s')
   plot(proj.data[,1],proj.data[,2],type='n',xlab=labels[1],ylab=labels[2])
   text(proj.data[,1],proj.data[,2],as.character(t.class),cex=2) 
  }
 else
 {  g<-length(table(t.class))
    t.class<-as.numeric(t.class)
    color<-colors()[c(1:g)*10]
    pairs(proj.data,pch=21,bg=color[t.class],labels)
 }
}

####################################################
# Initial Value : Tree.Struct, Alpha.Keep, C.Keep<-NULL
#                 id,rep1,rep<-1
#                 rep2<-2
####################################################

PP.Tree<-function(PPmethod,i.class,i.data,weight=TRUE,r=NULL,lambda=NULL,...)
{
   i.data<-as.matrix(i.data);
 
Find.proj<-function(i.class,i.data,PPmethod,r,lambda,...)
{
   n<-nrow(i.data);
   p<-ncol(i.data);
   g<-table(i.class)
   g.name<-as.numeric(names(g))
   G<-length(g);
   a<-PP.optimize.anneal(PPmethod,1,i.data,i.class,std=TRUE, cooling=0.999,temp=1,energy=0.01,r,lambda)
   proj.data<-as.matrix(i.data)%*%a$proj.best
   sign<-sign(a$proj.best[abs(a$proj.best)==max(abs(a$proj.best))])
   index<-c(1:p)*(abs(a$proj.best)==max(abs(a$proj.best)))
   index<-index[index>0]
   if(G==2){
      class<-i.class
   }  else 
   {  m<-tapply(proj.data,i.class,mean)
      sd<-tapply(proj.data,i.class,sd)
      sd.sort<-sort.list(sd)
      m.list<-sort.list(m)
      m.sort<-sort(m)   
      m.name<-as.numeric(names(m.sort))
      G<-length(m)
      dist<-0;   split<-0;
      for(i in 1:(G-1))
      { if(m[m.list[i+1]]-m[m.list[i]] > dist) 
         {  split<-i
            dist<-m[m.list[i+1]]-m[m.list[i]] }
      }
      class<-rep(0,n)
      for(i in 1:split)
         class<-class+(i.class == m.name[i])
      class<-2-class

#
# 1st node - 2st projection 
#

      g<-table(class)
      g.name<-as.numeric(names(g))
      G<-length(g)
      n<-nrow(i.data)
   a<-PP.optimize.anneal(PPmethod,1,i.data,i.class,std=TRUE, cooling=0.999,temp=1,energy=0.01,r,lambda)
   if(sign!=sign(a$proj.best[index]))
    a$proj.best<- -1*a$proj.best

  proj.data<-as.matrix(i.data)%*%a$proj.best
 }
#  proj.data<-(proj.data-mean(proj.data))
   m.LR<-tapply(proj.data,class,mean)
   m.LR.sort<-sort(m.LR)
   LR.name<-as.numeric(names(m.LR.sort))
   var.LR<-tapply(proj.data,class,var)   
   median.LR<-tapply(proj.data,class,median)  
   n.LR<-table(class)
   n.name<-as.numeric(names(n.LR))   
   var.T<-sum(var.LR*n.LR)/sum(n.LR)
   if(LR.name != n.name)
    { temp<-n.LR[1]; n.LR[1]<-n.LR[2]; n.LR[2]<-temp}     

#   c1<-mean(proj.data)
   c1<-(m.LR[1]+m.LR[2])/2
   c2<-(m.LR[1]*n.LR[1]+m.LR[2]*n.LR[2])/sum(n.LR)
   max.LR<-tapply(proj.data,class,max)
   min.LR<-tapply(proj.data,class,min)

   c3<-sum(min.LR[2]+max.LR[1])/2
   c4<-(min.LR[2]*n.LR[2]+max.LR[1]*n.LR[1])/sum(n.LR)
   C<-c(c1,c2,c3,c4)
   Alpha<-t(a$proj.best)

   IOindexR<-NULL; IOindexL<-NULL

   sort.LR<-as.numeric(names(sort(m.LR)))
   IOindexL<-class==sort.LR[1]; IOindexR<-class==sort.LR[2]; 

   return(Alpha,C,IOindexL,IOindexR)
}

##################
Tree.construct<-function(i.class,i.data,Tree.Struct, id,rep,rep1,rep2,Alpha.Keep,C.Keep,PPmethod,r=NULL,lambda=NULL,...)
{ 
 i.class<-as.integer(i.class)
  n<-nrow(i.data)
  g<-table(i.class)
  G<-length(g)

   if(length(Tree.Struct)==0)
  {  Tree.Struct<-matrix(c(1:(2*G-1)),ncol=1); 
     Tree.Struct<-cbind(Tree.Struct, rep(0,(2*G-1)),rep(0,2*G-1),rep(0,2*G-1))
  } 
  if(G==1){  
 #    Tree.Struct<-rbind(Tree.Struct,c(rep,0,as.numeric(names(g)),0))
 #   rep<-rep+1
     Tree.Struct[id,3]=as.numeric(names(g));
     return(Tree.Struct,Alpha.Keep,C.Keep,rep,rep1,rep2)
  } else {
 #    Tree.Struct<-rbind(Tree.Struct,c(rep,rep1,(rep1+1),rep2))
 #    rep<-rep+1;rep1<-rep1+2;rep2<-rep2+1;
     Tree.Struct[id,2]=rep1; rep1<-rep1+1;
     Tree.Struct[id,3]=rep1; rep1<-rep1+1;
     Tree.Struct[id,4]=rep2; rep2<-rep2+1;      
     a<-Find.proj(i.class,i.data,PPmethod,r,lambda); 
     C.Keep<-rbind(C.Keep,a$C)
     Alpha.Keep<-rbind(Alpha.Keep,a$Alpha)

     t.class<-i.class; t.data<-i.data; 
     t.class<-t.class*a$IOindexL; 
     t.n<-length(t.class[t.class==0])
     t.index<-sort.list(t.class);t.index<-sort(t.index[-(1:t.n)])
     t.class<-t.class[t.index];t.data<-i.data[t.index,]
     b<-Tree.construct(t.class,t.data,Tree.Struct,Tree.Struct[id,2],
                       rep,rep1,rep2,Alpha.Keep,C.Keep,PPmethod,r,lambda)
     Tree.Struct<-b$Tree.Struct
     Alpha.Keep<-b$Alpha.Keep
     C.Keep<-b$C.Keep
     rep<-b$rep
     rep1<-b$rep1
     rep2<-b$rep2

     t.class<-i.class; t.data<-i.data;
     t.class<-(t.class*a$IOindexR);t.n<-length(t.class[t.class==0])
     t.index<-sort.list(t.class);t.index<-sort(t.index[-(1:t.n)])
     t.class<-t.class[t.index];t.data<-i.data[t.index,]
     n<-nrow(t.data);G<-length(table(t.class))

     b<-Tree.construct(t.class,t.data,Tree.Struct,Tree.Struct[id,3],
                       rep,rep1,rep2,Alpha.Keep,C.Keep,PPmethod,r,lambda)
     Tree.Struct<-b$Tree.Struct
     Alpha.Keep<-b$Alpha.Keep
     C.Keep<-b$C.Keep
     rep<-b$rep
     rep1<-b$rep1
     rep2<-b$rep2
  }
     return(Tree.Struct,Alpha.Keep,C.Keep,rep,rep1,rep2)
}
##############

   C.Keep<-NULL;Alpha.Keep<-NULL;Tree.Struct<-NULL
   id<-1;rep1<-2;rep2<-1;rep<-1; 
  if(PPmethod =="LDA" &&weight==TRUE) 
      method<-1
  else if(PPmethod =="LDA" &&weight==FALSE) 
      method<-2
  else if(PPmethod =="Lp") 
      method<-3
  else if(PPmethod =="Gini") 
      method<-4
  else if(PPmethod =="Ent") 
      method<-5
  else
      method<-NA
  if(is.na(method)) return("Error")

   Tree.final<-Tree.construct(i.class,i.data,Tree.Struct,id,rep,rep1,rep2,Alpha.Keep,C.Keep,PPmethod,r,lambda)

   Tree.Struct <-Tree.final$Tree.Struct
   Alpha.Keep <- Tree.final$Alpha.Keep
   C.Keep <- Tree.final$C.Keep
   return(Tree.Struct,Alpha.Keep, C.Keep)
}

##########################################################
#  Initial Value : id,rep<-1
#                  test.class<-(0,0,0,0,...,0)
#                  IOindex<-(1,1,1,1,...,1)
##########################################################

PP.classify<-function(test.data,true.class,Tree.result,Rule,...)
{
   test.data<-as.matrix(test.data)
   true.class<-as.matrix(true.class); 
   if(nrow(true.class)==1) true.class<-t(true.class)
#   test.data<-apply(test.data,2,function(x){(x-mean(x))/sd(x)})
   if(!is.numeric(true.class))
   { class.name<-names(table(true.class))
     temp<-rep(0,nrow(true.class))
     for(i in 1:length(class.name))
       temp<-temp+(true.class==class.name[i])*i
     true.class<-temp
   } 
#############
PP.Classification<-function(Tree.Struct,test.class.index,IOindex,test.class,id,rep)
{    if(Tree.Struct[id,4] ==0) {
        i.class<-test.class; i.class[i.class>0]<-1
        i.class<-1-i.class
        test.class<-test.class+IOindex*i.class*Tree.Struct[id,3]
        return(test.class,rep)
     } else
     {  
        IOindexL<-IOindex*test.class.index[rep,];        
        IOindexR<-IOindex*(1-test.class.index[rep,]); rep<-rep+1;
        a<-PP.Classification(Tree.Struct,test.class.index,IOindexL,test.class,Tree.Struct[id,2],rep)
        test.class<-a$test.class; rep<-a$rep;
        a<-PP.Classification(Tree.Struct,test.class.index,IOindexR,test.class,Tree.Struct[id,3],rep)
        test.class<-a$test.class; rep<-a$rep;
     }
     return(test.class,rep)

}
##############

PP.Class.index<-function(class.temp,test.class.index,test.data,Tree.Struct,Alpha.Keep, C.Keep, id,Rule)
{ class.temp<-as.integer(class.temp)
  if(Tree.Struct[id,2]==0){
      return(test.class.index,class.temp)
  } else
  {    t.class<-class.temp; 
       t.n<-length(t.class[t.class==0]);
       t.index<-sort.list(t.class);if(t.n !=0) t.index<-sort(t.index[-(1:t.n)])
       t.data<-test.data[t.index,]
       id.proj<-Tree.Struct[id,4]; 

      proj.test<-as.matrix(test.data)%*%as.matrix(Alpha.Keep[id.proj,]); 
#  proj.test<-(proj.test-mean(proj.test))
       proj.test<-as.real(proj.test)
       class.temp<-t(proj.test < C.Keep[id.proj,Rule]) ;
       test.class.index<-rbind(test.class.index,class.temp)
       a<-PP.Class.index(class.temp,test.class.index,test.data,
                         Tree.Struct,Alpha.Keep,C.Keep,Tree.Struct[id,2],Rule); 
       test.class.index<-a$test.class.index;
       a<-PP.Class.index(1-class.temp,test.class.index,test.data,
                         Tree.Struct,Alpha.Keep,C.Keep,Tree.Struct[id,3],Rule);
       test.class.index<-a$test.class.index;
  }
  return(test.class.index,class.temp)
}


#############
   n<-nrow(test.data)
   class.temp<-rep(1,n)
   test.class.index<-NULL
   temp<-PP.Class.index(class.temp,test.class.index,test.data,
                       Tree.result$Tree.Struct,Tree.result$Alpha.Keep,
                       Tree.result$C.Keep,1,Rule)
   test.class<-rep(0,n);IOindex<-rep(1,n)
   rep<-1
   temp<-PP.Classification(Tree.result$Tree.Struct,temp$test.class.index,
                         IOindex,test.class,1,1)
   predict.error<-sum(true.class != temp$test.class)
   predict.class<-temp$test.class
   return(predict.error,predict.class)
}

 .First.lib<-function(lib,pkg){
  library.dynam("classPP",pkg,lib)
}

