[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