A circulant matrix is a square matrix generated from a vector as the first row (or column). Successive rows use the same elements as the first row, but each such row is circularly shifted by one element. See that both Wikipedia and Mathworld show the circular shifts as forward shifts.
http://en.wikipedia.org/wiki/Circulant_matrix
http://mathworld.wolfram.com/CirculantMatrix.html
At the same time, others seem to employ backwards shifts (see FEX 22814), so there is clearly a dichotomy in the set of people who use circulant matrices. I'll offer my own version of circulant.m to cover either style. It allows the user to specify either form as desired, although the default uses the forwards shift. For example:
A backwards (-1) shift, the result is a symmetric matrix.
circulant([2 3 5 7 11 13],-1)
ans =
2 3 5 7 11 13
3 5 7 11 13 2
5 7 11 13 2 3
7 11 13 2 3 5
11 13 2 3 5 7
13 2 3 5 7 11
A forwards (+1) shifted circulant matrix, built using the first row defined by vec.
circulant([2 3 5 7 11],1)
ans =
2 3 5 7 11
11 2 3 5 7
7 11 2 3 5
5 7 11 2 3
3 5 7 11 2
And a positively shifted circulant matrix, built from vec as the first column. Here I've provided only one argument, so it uses the default.
circulant([2;3;5;7;11])
ans =
2 11 7 5 3
3 2 11 7 5
5 3 2 11 7
7 5 3 2 11
11 7 5 3 2
Finally, a negative shift applied to build a character circulant matrix.
circulant('abcdefghij',-1)
ans =
abcdefghij
bcdefghija
cdefghijab
defghijabc
efghijabcd
fghijabcde
ghijabcdef
hijabcdefg
ijabcdefgh
jabcdefghi
Finally, I'll note that the algorithms I chose internally are not absolutely the fastest, although they are fully vectorized. I could have achieved a further 10-20% speed boost with the use of bsxfun. The code for the bsxfun variants is included, but commented out. The problem is that many people still have not upgraded to a release that includes bsxfun. While I could have put in a test to see if bsxfun exists, that test itself takes some time since exist is relatively slow. On small vectors, the test itself might take more time than it takes to generate the matrix.
So for any user who has bsxfun and needs maximal throughput, I've put it all in there for you. |