-
Notifications
You must be signed in to change notification settings - Fork 19
Added AcbVector support struct #30
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
Conversation
|
(I wanted this for a wrapper of the |
JeffreySarnoff
left a comment
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.
We cannot offer AcbVector without also offering ArbVector and ArfVector.
I have not reviewed the code yet.
|
What's the difference between these types? |
|
I missed the |
|
I just realized. There is no So |
|
The library offers see https://github.com/JeffreySarnoff/ArbNumerics.jl/blob/master/src/float/elliptic.jl |
|
Can you just freely cast a pointer to an |
|
no -- one must explicitly cast values of each type to the other, target type. Otherwise bad things happen. |
|
Hmm, reading the API documentation, there seems to be no functions accepting a vector of When would a EDIT: Typo |
|
The idea of ArbNumerics is that users have a Julia-centric way of working with |
|
Then I think it's easiest to just add a helper function, that automatically promotes a vector of ArblibVector(v::AbstractVector{ArbFloat{P}}) where P =
ArblibVector(ArbReal.(v))This works like so: julia> f = rand(ArbFloat{128}, 5)
5-element Array{ArbFloat{128},1}:
0.5953977471776002041348507759413
0.4982507430703087645009724322786
0.7010188632230956411011589105102
0.5026129464948069049729481221645
0.4253157939327851802021822646549
julia> ArblibVector(v::AbstractVector{ArbFloat{P}}) where P =
ArblibVector(ArbReal.(v))
ArblibVector
julia> F = ArblibVector(f)
5-element ArblibVector{ArbReal{128}}:
0.5953977471776002041348507759413
0.4982507430703087645009724322786
0.7010188632230956411011589105102
0.5026129464948069049729481221645
0.4253157939327851802021822646549Converting back to a julia> Vector(F)
5-element Array{ArbReal{128},1}:
0.5953977471776002041348507759413
0.4982507430703087645009724322786
0.7010188632230956411011589105102
0.5026129464948069049729481221645
0.4253157939327851802021822646549
julia> Vector{ArbFloat{128}}(F)
5-element Array{ArbFloat{128},1}:
0.5953977471776002041348507759413
0.4982507430703087645009724322786
0.7010188632230956411011589105102
0.5026129464948069049729481221645
0.4253157939327851802021822646549 |
|
I understand your approach. It is concise. And it would be workable if it existed behind the scenes, rather than as the "way to do it", because the way do it must be syntactically similar for each of the types to keep harmony with the way all of the rest of the package works (and exports for use). Also, it does not automagically allow the correct type to flow through .. a specific correction, maybe outside of the logical flow where the initial conversion occurred must be attached. In all other functional use, any type facilitating conversion -> operations -> type recovering conversion flow happens inside of the client's functional call, so no mistyping can occur accidentally. This is both nice as an interface standard and important when working with a C library that manipulates C structs internally in a way that requires Julia follow along properly. I lived this when it became necessary to provide Matrix types and Julia <-> Arb interconversion. Vectors are easier, but the constraints and considerations are much the same. A look at So your approach will work, and still we need a smoother approach. I will post some scaffolding here later on. And that you are more than welcome to alter or reshape. |
|
I'm afraid you've lost me. I never intended for the function coulomb!(F::AcbVector{P}, G::AcbVector{P},
H⁺::AcbVector{P}, H⁻::AcbVector{P},
λ::ArbComplex{P}, η::ArbComplex{P}, z::ArbComplex{P};
prec::Int=P) where P
len = F.len
@assert G.len ≥ len
@assert H⁺.len ≥ len
@assert H⁻.len ≥ len
ccall(@libarb(acb_hypgeom_coulomb_jet), Cvoid,
(Ref{ArbComplex{P}}, Ref{ArbComplex{P}}, Ref{ArbComplex{P}}, Ref{ArbComplex{P}},
Ref{ArbComplex}, Ref{ArbComplex}, Ref{ArbComplex}, Clong, Clong),
F.ptr, G.ptr, H⁺.ptr, H⁻.ptr, λ, η, z, len, prec)
F,G,H⁺,H⁻
end
# Taylor series version
function coulomb(λ::ArbComplex{P}, η::ArbComplex{P}, z::ArbComplex{P}, len::Int; kwargs...) where P
F = ArblibVector(ArbComplex{P}, len)
G = ArblibVector(ArbComplex{P}, len)
H⁺ = ArblibVector(ArbComplex{P}, len)
H⁻ = ArblibVector(ArbComplex{P}, len)
coulomb!(F,G,H⁺,H⁻,λ,η,z;kwargs...)
take!(F),take!(G),take!(H⁺),take!(H⁻)
end
# Scalar version
function coulomb(λ::ArbComplex{P}, η::ArbComplex{P}, z::ArbComplex{P}; prec::Int=P) where P
F = ArbComplex{P}()
G = ArbComplex{P}()
H⁺ = ArbComplex{P}()
H⁻ = ArbComplex{P}()
ccall(@libarb(acb_hypgeom_coulomb), Cvoid,
(Ref{ArbComplex}, Ref{ArbComplex}, Ref{ArbComplex}, Ref{ArbComplex},
Ref{ArbComplex}, Ref{ArbComplex}, Ref{ArbComplex}, Clong),
F, G, H⁺, H⁻, λ, η, z, prec)
F,G,H⁺,H⁻
end
coulomb(λ, η, z, args...; kwargs...) =
coulomb(ArbComplex(λ), ArbComplex(η), ArbComplex(z), args...; kwargs...)I am of course happy to adapt the code to your preferences, but I don't immediately see what's missing. |
|
Thank you for the clarification. We have discussing two different things. |
|
Just my 2 cents. While working on the DFT, I saw a couple of things:
|
|
You now understand this quite well -- if you like this as is, I will merge it, |
|
It has been a while -- "one of these is that convert(Array{ArbComplex}) does not return a well formed pointer to an array of acb", what does it return (and I assume you are referring to a Matrix)? |
|
@orkolorko Could you provide a unit test for the DFT and its inverse? Such that we know that it works as it should? I'll make a PR (as soon as this PR is merged) for the Coulomb routines I posted above, along with unit tests, and then we would have two different cases of real usage of this PR. |
|
good work, nice to see All functions from LinearAlgebra that had been avoided were omitted after the inappropriateness of some fallthroughs when used with Arb types became clear. There has been improvement in LinearAlgebra, which along with some alternative versions of very low level float functionality implemented in this package, suggests revisiting additional vector-related ops. The Arb polynomial routines are not available because providing a Julian approach to each next Arb structured type requires a good deal of time/testing/automatic-interconversion-provision. |
Yes, I will provide a unit test
I tink the reason why is that in ARB you're not really supposed to use ArbFloats directly: ARB is a library made for rigorous and efficient numerical types, with ball representation. |
|
For the Julian perspective, we manually create the functional equivalents that allow the user to work as if the Arb C library better supported the |
|
is this ready to merge? |
|
From my point-of-view, yes, barring the fact that there still are no unit tests ensuring that the (I)DFT routines work as they should. |
|
Please jot down two tests each for |
Well, that would be up to @orkolorko. Although I've used DFTs a long time ago, I have no example at hand presently. |
|
@orkolorko I need to provide others with a few |
|
I'm sorry it is taking me some time, it is the end of the semester and I'm in grading swamp. How should I do, clone your branch @jagot and then work on it and then send you a pull-request? What is the right process to do this? Should I add the unit test to my branch and then send a pull request? |
|
I think the absolute easiest is to just take an example you already have and paste it here in the PR conversation, and then me or @JeffreySarnoff can turn it into a test. E.g. something like this: x = ...
y = ArbNumerics.dft(x)
@test y ≈ reference_solution
x̃ = ArbNumerics.inverse_dft(y)
@test x̃ ≈ xThe last step assumes that |
|
These were some tests I checked by hand dft([ArbComplex(1.0), ArbComplex(2.0), ArbComplex(3.0), ArbComplex(4.0)])== [ArbComplex(10.0), ArbComplex(-2.0,+2.0), ArbComplex(-2.0),ArbComplex(-2.0,-2.0)] inverse_dft(dft([ArbComplex(1.0), ArbComplex(2.0), ArbComplex(3.0), ArbComplex(4.0)]))== [ArbComplex(1.0), ArbComplex(2.0), ArbComplex(3.0),ArbComplex(4.0)] dft([ArbComplex(1.0), ArbComplex(0), ArbComplex(0), ArbComplex(0),ArbComplex(0), ArbComplex(0), ArbComplex(0), ArbComplex(0) ])==[ArbComplex(1.0), ArbComplex(1.0), ArbComplex(1.0), ArbComplex(1.0), ArbComplex(1.0), ArbComplex(1.0), ArbComplex(1.0), ArbComplex(1.0)] dft([ArbComplex(0,1), ArbComplex(0), ArbComplex(0), ArbComplex(0),ArbComplex(0), ArbComplex(0), ArbComplex(0), ArbComplex(0) ])==[ArbComplex(0,1.0), ArbComplex(0,1.0), ArbComplex(0,1.0), ArbComplex(0,1.0), ArbComplex(0,1.0), ArbComplex(0,1.0), ArbComplex(0,1.0), ArbComplex(0,1.0)] I will prepare some examples with the dft of samples of trigonometric functions to show the use case. |
|
much appreciated -- what you prepare, I will incorporate into the docs |
|
Thanks @orkolorko, those tests enabled me to find some bugs in the DFT wrappers. |
|
I am merging this so adding to the documentation will be easier. When that is done, a new release. |
|
@orkolorko @jagot Something is not correct with the merged #master: |
|
@JeffreySarnoff Well, there is no C library function for initializing vectors of mixed real/complex numbers. As you see in your REPL, As I said above, I don't think EDIT: I read too quickly, it seems you're trying to create an julia> using ArbNumerics
julia> using LinearAlgebra
julia> import ArbNumerics: ArblibVector, take!, free!
julia> v = ones(ArbReal{128}, 5)
5-element Array{ArbReal{128},1}:
1.0
1.0
1.0
1.0
1.0
julia> vv = ArblibVector(v)
5-element ArblibVector{ArbReal{128}}:
1.0
1.0
1.0
1.0
1.0
# Be sure to free! the allocated memory, either by free!, or take! which also returns the contents:
julia> free!(vv)
0
julia> vv
0-element ArblibVector{ArbReal{128}}
julia> vv = ArblibVector(v)
5-element ArblibVector{ArbReal{128}}:
1.0
1.0
1.0
1.0
1.0
julia> take!(vv)
5-element Array{ArbReal{128},1}:
1.0
1.0
1.0
1.0
1.0
julia> vv
0-element ArblibVector{ArbReal{128}} |
|
I think something like this could enter the documentation of the function The DFT permits is often used as a tool to analyze a collection of samples as a sum of periodic signals DFT on Wikipedia. To see how it works, and how it can be used, we can look at its behavior on a sample from a periodic signal The result of the DFT (ignoring the small terms) is the vector with value 8 (which divided by n is 1) at the first component, this tells us that the original signal is a periodic signal generated by In the same way tells us that the sample was generated by The output of the DFT is a vector whose components contain, by index: Remember that the result is multiplied by a factor N. The DFT is a linear operator Resuming, the idea is that the DFT permits us to see the frequency composition of a signal means that the original signal is approximately $(0.74+0.53im)+(-0.023-0.087im)e^{i 2\pi x}+(0.15+0.2im)e^{-i 2\pi x}+(0.083+0.27im)e^{2 i 2\pi x}$. |
|
When I test ArbNumerics#master on Windows it crashes because the |
|
@orkolorko @jagot I am working to integrate the examples into the docs. Help me with the |
|
@JeffreySarnoff I'm afraid I can't reproduce; I am normally only using Mac & Linux, but I tried the following in a VirtualBox instance of Win10: _
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.3.0 (2019-11-26)
_/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |
julia> cd(mkpath("test"))
(v1.3) pkg> activate .
Activating new environment at `C:\Users\Jagot\AppData\Local\Julia-1.3.0\test\Project.toml`
(test) pkg> add LinearAlgebra, ArbNumerics#master
Updating registry at `C:\Users\Jagot\.julia\registries\General`
Updating git-repo `https://github.com/JuliaRegistries/General.git`
Updating git-repo `https://github.com/JeffreySarnoff/ArbNumerics.jl.git`
Resolving package versions...
Updating `C:\Users\Jagot\AppData\Local\Julia-1.3.0\test\Project.toml`
[7e558dbc] + ArbNumerics v1.0.1 #master (https://github.com/JeffreySarnoff/ArbNumerics.jl.git)
[37e2e46d] + LinearAlgebra
Updating `C:\Users\Jagot\AppData\Local\Julia-1.3.0\test\Manifest.toml`
[7e558dbc] + ArbNumerics v1.0.1 #master (https://github.com/JeffreySarnoff/ArbNumerics.jl.git)
[b99e7846] + BinaryProvider v0.5.8
[01680d73] + GenericSVD v0.2.2
[c145ed77] + GenericSchur v0.3.0
[efe28fd5] + OpenSpecFun_jll v0.5.3+1
[0d4725de] + Readables v0.3.3
[276daf66] + SpecialFunctions v0.9.0
[2a0f44e3] + Base64
[ade2ca70] + Dates
[8ba89e20] + Distributed
[b77e0a4c] + InteractiveUtils
[76f85450] + LibGit2
[8f399da3] + Libdl
[37e2e46d] + LinearAlgebra
[56ddb016] + Logging
[d6f4376e] + Markdown
[44cfe95a] + Pkg
[de0858da] + Printf
[3fa0cd96] + REPL
[9a3f8284] + Random
[ea8e919c] + SHA
[9e88b42a] + Serialization
[6462fe0b] + Sockets
[8dfed614] + Test
[cf7118a7] + UUIDs
[4ec0a83e] + Unicode
julia> using ArbNumerics
julia> using LinearAlgebra
julia>
julia> T=ArbComplex{128}
ArbComplex{128}
julia> o = ones(T, 5)
5-element Array{ArbComplex{128},1}:
1.0 + 0im
1.0 + 0im
1.0 + 0im
1.0 + 0im
1.0 + 0im
julia> d=dot(o,o)
5.0 + 0im
julia> T=ArbReal{128}
ArbReal{128}
julia> o = ones(T, 5)
5-element Array{ArbReal{128},1}:
1.0
1.0
1.0
1.0
1.0
julia> d = dot(o,o)
5.0
julia> versioninfo()
Julia Version 1.3.0
Commit 46ce4d7933 (2019-11-26 06:09 UTC)
Platform Info:
OS: Windows (x86_64-w64-mingw32)
CPU: Intel(R) Core(TM) i7-7920HQ CPU @ 3.10GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-6.0.1 (ORCJIT, skylake)
julia> |
|
That was very helpful. The problem only exists in 1.3.0-rc not in 1.3.0 -- thanks, I will clean up doc and rerelease |
|
it has been registered -- I do not know how to explain [let alone simply] that |
This helper struct simplifies calls to Arb functions that expect vector inputs. There were no tests for the DFT routines, so I am not sure if they have been broken or not, but they should not be.