[R] problem in waveslim *package* ?

Martin Maechler maechler at stat.math.ethz.ch
Sat Nov 5 22:02:27 CET 2005


>>>>> "tom" == tom wright <tom at maladmin.com>
>>>>>     on Fri, 04 Nov 2005 09:37:24 -0500 writes:

    tom> This code consistenly segfaults for me. Can someone
    tom> please take a look and tell me if the problem is due to
    tom> something I am doing or is there a problems with the
    tom> dwt (idwt) functions in the waveslim library.  

it's the waveslim *package* (!!)  Try
	install.packages("fortunes")
	fortune(58)
in order to understand the exclamation marks ;-) 
{ I still hope for the next version
  of R to have a use() function for attaching packages so you'll
  have no excuse to call them "li....s" (I'm not going to spell out the abomination :-)
}

Back to the track: I can confirm the seg.fault;  
The reasons are simple:

1) Your code is slightly incorrect:  setZeros()  doesn't do what you
   thought it would do.  Look at

    > str(nd <- setZeros(data.dwt, 1))
    List of 9
     $ d1: num 0
     $ d2: num [1:256]  24.92 -32.17  -2.32   1.21   1.70 ...
     $ d3: num [1:128]   5.21 -41.61 -19.99   6.93  -6.23 ...
     $ d4: num [1:64]  -5.47 -28.69  49.38  -9.44 -17.04 ...
     $ d5: num [1:32]  0.723 -5.647  5.397  3.534 14.719 ...
     $ d6: num [1:16]  28.40   1.82  14.12 -45.44  18.70 ...
     $ d7: num [1:8]  92.8 183.5 -19.4  36.0 -18.2 ...
     $ d8: num [1:4] -1382  1895  -187   260
     $ s8: num [1:4] 19164 16690 15083 14648
     - attr(*, "class")= chr "dwt"
     - attr(*, "wavelet")= chr "la8"
     - attr(*, "boundary")= chr "periodic"

 i.e.,  $d1 is of length 1 instead of 512 .
 The  mistake was to assume that  data.dwt["d1"] would be a
 vector; however it is still a list but with only one component;
 instead  [["d1"]] (or " $d1 " ) really gives the list  *component*.


This fixes your problem {but read on!} :

setZeros <- function(data, factors = list()) {
    for(factor in factors) {
        sFac <- paste('d',factor,sep = '')
        ## wrong: data[sFac]   <- rep(0,length(data[sFac]))
        ## good:  data[[sFac]] <- rep(0,length(data[[sFac]]))
        ## more elegant(?); note the '[]' !
        data[[sFac]][] <- 0
    }
    return(data)
}


2) The idwt() function is not programmed robustly enough:
   It ensures that its main argument is of S3 class "dwt" -- which
   the above is; but with the S3 class system, you have no
   guarantee; there's no  validObject() function like with the
   nice formal classes in S4.   There, in S4, this problem could easily
   be prevented, but not here:  After checking for the "dwt"
   class, idwt() just assumes that it has a proper object and
   quickly passes stuff to .C(.....) where it bombs because 'd1'
   is not of length 512 but of length 1.

So another "moral of the story" could be that  S4 classes are
really something to consider, maybe inspite of what others told
you...

Martin

    tom> library(waveslim)

    tom> data<-c(936.944,936.944,936.944,936.944,.............................)

 [ of length 1024 -- doesn't really matter ]

    tom> setZeros<-function(data,factors=list()){
    tom>  for(factor in factors){
    tom>    sFac<-paste('d',factor,sep='')
    tom>    data[sFac]<-rep(0,length(data[sFac]))
    tom>   }
    tom>  return(data)
    tom> }

    tom> data.dwt<-dwt(data[[2]],n.levels=8)

should probably have been

         data.dwt <- dwt(data, n.levels=8)

    tom> opar<-par(mfrow=c(4,2),mar=c(2,2,2,2))
    tom> mlist<-c(1:8)
    tom> for(iFac in 1:8){
    tom> #flist<-mlist[mlist!=iFac]
    tom> ndata<-setZeros(data.dwt,iFac)
    tom> plot(idwt(ndata),type='l')
    tom> }




More information about the R-help mailing list