Re: [R] matrix of higher order differences

From: Hans W Borchers <hwborchers_at_googlemail.com>
Date: Wed, 27 Apr 2011 11:25:42 +0000

Jeroen Ooms <jeroenooms <at> gmail.com> writes:

>
> Is there an easy way to turn a vector of length n into an n by n matrix, in
> which the diagonal equals the vector, the first off diagonal equals the
> first order differences, the second... etc. I.e. to do this more
> efficiently:
>
> diffmatrix <- function(x){
> n <- length(x);
> M <- diag(x);
> for(i in 1:(n-1)){
> differences <- diff(x, dif=i);
> for(j in 1:length(differences)){
> M[j,i+j] <- differences[j]
> }
> }
> M[lower.tri(M)] <- t(M)[lower.tri(M)];
> return(M);
> }
>
> x <- c(1,2,3,5,7,11,13,17,19);
> diffmatrix(x);
>

I do not know whether you will call the appended version more elegant, but at least it is much faster -- up to ten times for length(x) = 1000, i.e. less than 2 secs for generating and filling a 1000-by-1000 matrix. I also considered col(), row() indexing:

    M[col(M) == row(M) + k] <- x

Surprisingly (for me), this makes it even slower than your version with a double 'for' loop.

# ----
diffmatrix <- function(x){

	n <- length(x)
	if (n == 1) return(x)

	M <- diag(x)
	for(i in 1:(n-1)){
		x <- diff(x)           # use 'diff' in a loop
		for(j in 1:(n-i)){     # length is known
			M[j, i+j] <- x[j]  # and reuse x
		}
	}
	M[lower.tri(M)] <- t(M)[lower.tri(M)]
	return(M)

}
# ----

R-help_at_r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. Received on Wed 27 Apr 2011 - 11:28:51 GMT

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.2.0, at Wed 27 Apr 2011 - 15:10:33 GMT.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-help. Please read the posting guide before posting to the list.

list of date sections of archive