-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pull request - extended circulant functionality + DFT representation. #13
Pull request - extended circulant functionality + DFT representation. #13
Conversation
…, however, somewhat patchy.
…ectly use dispatch to determine what to cast back to. Previous implementation used dynamic type checking and missed some edge cases. Not re-implemented the in-place multiplication functionality in this commit, nor have the tests been updated. Also added typealias for Circulant to reduce verbosity.
…ing multiplication in terms of DFT matrices, (conjugate) transposition, addition, subtraction, eigenvalues + eigenvectors. dft.jl has been further extended to cover more functionality and a few bugs have been fixed.
Hi,
there is lot of changes which are not so easy to follow.
The previous approach with just fft and ifft needs O(n) operations.
This is especially interesting when using Lanczos method to compute SOME eigenvalues and eigenvectors (or singular values and vectors)
of Hankel and Toplitz matrices using eigs() (svds() ), since the multiplication can be defined as an operator.
For large Hankel matrix (say n=50.000) computation of 40 eigenpairs with this approach is very fast (5 seconds).
On the the other hand, the full eigenvalue matrix of the underlying Circulant cannot be stored at all.
So, I just want to make sure that the new approach is the same in terms of operation count.
Cheers, Ivan
Prof. dr. sc. Ivan Slapničar
Sveučilište u Splitu / University of Split
FESB
R. Boškovića 32
HR-21000 Split
Hrvatska / Croatia
Phone: + 385 21 305893
Ured/Office: B803
…________________________________
Šalje: Will Tebbutt <[email protected]>
Poslano: 19. siječnja 2017. 19:10
Prima: jiahao/SpecialMatrices.jl
Kopija: Subscribed
Predmet: [jiahao/SpecialMatrices.jl] Pull request - extended circulant functionality + DFT representation. (#13)
Hi.
I have extended the package in a couple of ways. Firstly, the Discrete Fourier Transform (DFT) matrix has been added in src/DFT.jl. This is interesting semantically as it allows for (in certain circumstances) a more natural way of expressing the Fourier Transform of vectors and matrices (where a matrix is just viewed as a collection of vectors to be transformed). Note that there are primarily two implementations of this matrix, Unitary DFT (UDFT) uses the matrix U defined such that ctranspose(U) = inv(U), whereas this does not hold for DFT.
This is particularly useful for cleaning up the implementation of the Circulant matrix, as we can now describe all of the operations one might expect to be able to perform with Circulant matrices in terms of multiplication by the DFT matrix or it's conjugate transpose (or some re-scaling thereof). Furthermore, I have added a significant amount of extra functionality involving Circulant matrices, the vast majority of which is tested in test/circulant.jl. (Note that I have separated out the functionality involving Toeplitz and Circulant matrices). Furthermore, I have changed the behaviour of the multiplication of real and integer Circulant matrices. Multiplication now always returns a complex-valued float, but helper functions have been added (see the end of src/circulant.jl) to extend the casting functionality from Base necessary to enable the user to explicitly round and cast. It is my feeling that this is the correct thing to do as it is unwise to mask type conversions that may result in some loss of accuracy from the user. Commenting in src/circulant.jl is fairly sparse as most code should be self-documenting. Let me know if more comments are wanted.
I appreciate that this is a fairly substantial modification / addition, so please review and let me know what you think!
________________________________
You can view, comment on, or merge this pull request online at:
#13
[https://avatars0.githubusercontent.com/u/3628294?v=3&s=400]<https://github.com/jiahao/SpecialMatrices.jl/pull/13>
Pull request - extended circulant functionality + DFT representation. by willtebbutt · Pull Request #13 · jiahao/SpecialMatrices.jl<#13>
github.com
Hi. I have extended the package in a couple of ways. Firstly, the Discrete Fourier Transform (DFT) matrix has been added in src/DFT.jl. This is interesting semantically as it allows for (in certain...
Commit Summary
* Basic DFT functionality added. Coverage of the expected operations is, however, somewhat patchy.
* Re-implmented existing Circulant multiplication functionality to correctly use dispatch to determine what to cast back to. Previous implementation used dynamic type checking and missed some edge cases. Not re-implemented the in-place multiplication functionality in this commit, nor have the tests been updated. Also added typealias for Circulant to reduce verbosity.
* Completed + tested basic functionality for circulant matrices, including multiplication in terms of DFT matrices, (conjugate) transposition, addition, subtraction, eigenvalues + eigenvectors. dft.jl has been further extended to cover more functionality and a few bugs have been fixed.
* Commit to bring remote up to speed.
* Circulant functionality sufficiently complete for a first vesion.
File Changes
* M src/SpecialMatrices.jl<https://github.com/jiahao/SpecialMatrices.jl/pull/13/files#diff-0> (32)
* A src/circulant.jl<https://github.com/jiahao/SpecialMatrices.jl/pull/13/files#diff-1> (124)
* A src/dft.jl<https://github.com/jiahao/SpecialMatrices.jl/pull/13/files#diff-2> (86)
* M src/hankel.jl<https://github.com/jiahao/SpecialMatrices.jl/pull/13/files#diff-3> (3)
* M src/toeplitz.jl<https://github.com/jiahao/SpecialMatrices.jl/pull/13/files#diff-4> (47)
* A test/circulant.jl<https://github.com/jiahao/SpecialMatrices.jl/pull/13/files#diff-5> (127)
* A test/dft.jl<https://github.com/jiahao/SpecialMatrices.jl/pull/13/files#diff-6> (19)
* M test/runtests.jl<https://github.com/jiahao/SpecialMatrices.jl/pull/13/files#diff-7> (6)
Patch Links:
* https://github.com/jiahao/SpecialMatrices.jl/pull/13.patch
* https://github.com/jiahao/SpecialMatrices.jl/pull/13.diff
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub<#13>, or mute the thread<https://github.com/notifications/unsubscribe-auth/AIRrsFLMvK0H6EVCviNlx_EvKrMQKBsYks5rT6cQgaJpZM4LobS6>.
|
Removed two lines of redundant test code from circulant.jl.
Hi Ivan, Thanks for the response. With regards to your concerns about the underlying Circulant implementation, I have been careful to ensure that (U)DFT matrices are never explicitly evaluated - as you point out doing so would require As evidence for this, I would first highlight lines 10-14 of
for some StridedVecOrMat X and (U)DFT U, and the correct (i)fft operation will be used to compute the requested operations efficiently under the hood. This propagates through to the Circulant matrices in Note that the discussed multiplication function accepts the eigen-factorisation of some Circulant matrix. This is done so that if one is, for example, left-multiplying multiple vectors/matrices by a Circulant matrix, the initial fft required to obtain the eigenvalues can be done once and cached (this is relevant to some of the work that I am doing). However, line 76 of The rest of the functionality in The only notable changes to your API are that the indexing on line 18 of Best, |
|
||
function full{T}(C::Circ{T}) | ||
n = size(C, 1) | ||
M = Array(T, n, n) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This syntax is deprecated and Array{T}(n, n)
is now preferred
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general when creating an array with a known number of dimensions you should call a specific constructor (in this case Array{T, 2}(n, n)
or Matrix{T}(n, n)
.
include("toeplitz.jl") #Toeplitz matrix | ||
include("vandermonde.jl") #Vandermonde matrix | ||
include("vandermonde.jl") #Vandermonde matrix |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add back newlines at the end of your files
M | ||
end | ||
|
||
# getindex(C::Circ, i::Int, j::Int) = C.c[mod(i-j,length(C.c))+1] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since show
relies on getindex
, you'll have to override it for Circulant
so it doesn't error when trying to display Circulant
s
real(C::Circ) = Circ(real(C.c)) | ||
convert{T}(::Type{Circ{T}}, C::Circ) = Circ(convert(Vector{T}, C.c)) | ||
|
||
round(C::Circ) = Circ(round(C.c)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the two round
methods you should pass-through trailing args...
to allow the other options to round
to be used.
size(M::AbstractDFT) = M.N, M.N | ||
length(M::AbstractDFT) = M.N^2 | ||
|
||
# Don't bother to implement an in-place transpose as U is sufficiently |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the DFT types are immutable and the contents are immutable, you can just return the item itself, e.g. transpose(U::AbstractDFT) = U
and transpose!(U::AbstractDFT) = U
eig{T<:Real}(C::Circ{T}) = (N = length(C.c); (DFT{Complex{T}}(N) * C.c, UDFT{Complex{T}}(N))) | ||
eig{T<:Complex}(C::Circ{T}) = (N = length(C.c); (DFT{T}(N) * C.c, UDFT{T}(N))) | ||
eigfact(C::Circ) = Eigen(eig(C)...) | ||
typealias CircEig{T<:Complex} Eigen{T, T, UDFT{T}, Vector{T}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Calling show
on an instance of this type causes a StackOverflowError.
show(STDOUT, eigfact(Circulant(collect(1.0:10.0))));
to replicate
# and the eigenvectors are represented efficiently using a UnitaryDFT object. | ||
eig{T<:Real}(C::Circ{T}) = (N = length(C.c); (DFT{Complex{T}}(N) * C.c, UDFT{Complex{T}}(N))) | ||
eig{T<:Complex}(C::Circ{T}) = (N = length(C.c); (DFT{T}(N) * C.c, UDFT{T}(N))) | ||
eigfact(C::Circ) = Eigen(eig(C)...) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function should convert/promote to the right types such that the answer is a CircEig
. Currently that is not the case for Circ{T} where T <: Integer
. That should either be fixed or disallowed.
Hi.
I have extended the package in a couple of ways. Firstly, the Discrete Fourier Transform (DFT) matrix has been added in src/DFT.jl. This is interesting semantically as it allows for (in certain circumstances) a more natural way of expressing the Fourier Transform of vectors and matrices (where a matrix is just viewed as a collection of vectors to be transformed). Note that there are primarily two implementations of this matrix, Unitary DFT (UDFT) uses the matrix U defined such that ctranspose(U) = inv(U), whereas this does not hold for DFT.
This is particularly useful for cleaning up the implementation of the Circulant matrix, as we can now describe all of the operations one might expect to be able to perform with Circulant matrices in terms of multiplication by the DFT matrix or it's conjugate transpose (or some re-scaling thereof). Furthermore, I have added a significant amount of extra functionality involving Circulant matrices, the vast majority of which is tested in test/circulant.jl. (Note that I have separated out the functionality involving Toeplitz and Circulant matrices). Furthermore, I have changed the behaviour of the multiplication of real and integer Circulant matrices. Multiplication now always returns a complex-valued float, but helper functions have been added (see the end of src/circulant.jl) to extend the casting functionality from Base necessary to enable the user to explicitly round and cast. It is my feeling that this is the correct thing to do as it is unwise to mask type conversions that may result in some loss of accuracy from the user. Commenting in src/circulant.jl is fairly sparse as most code should be self-documenting. Let me know if more comments are wanted.
I appreciate that this is a fairly substantial modification / addition, so please review and let me know what you think!