-
Notifications
You must be signed in to change notification settings - Fork 13
Multivariate functions #185
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
Changes from 7 commits
9199067
4e6a8ab
00c8118
bb0f8f6
2758897
568c3f5
00d75e3
a821c96
9263003
03e123a
2f23248
775ace3
64c9b54
2d61874
2cfe115
e9a0032
236eab4
98eaa53
c9430a8
f25efa7
2033c82
effb5a4
582c232
5adac34
d08dcb8
dd3cb6b
d7313fc
e1fb701
6640875
656a717
36d9411
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,16 @@ | |
|
|
||
| export ProductFun | ||
|
|
||
| ## TODO: | ||
| ## In a newer version, an abstract type of ProducFun is needed, where different implementations are possible | ||
| ## however, refactoring this is a lot of effort... | ||
| struct TensorIteratorFun{S<:UnivariateSpace, d, SS<:TensorSpace{NTuple{d, S}}, T<:Number} <: MultivariateFun{T, d} | ||
| space::SS | ||
| coefficients::Vector{T} | ||
| iterator::TrivialTensorizer{d} | ||
| orders::Block | ||
| end | ||
|
|
||
| struct ProductFun{S<:UnivariateSpace,V<:UnivariateSpace,SS<:AbstractProductSpace,T} <: BivariateFun{T} | ||
| coefficients::Vector{VFun{S,T}} # coefficients are in x | ||
| space::SS | ||
|
|
@@ -35,6 +45,15 @@ function ProductFun(cfs::AbstractMatrix{T},sp::AbstractProductSpace{Tuple{S,V},D | |
| end | ||
| end | ||
|
|
||
| ## TODO: This Product Fun actually does not return a productfun, dirty but was easiest to implement. Probably an abstract type of ProductFuns | ||
| # is needed in the future. | ||
| function ProductFun(iter::TrivialTensorizer{d},cfs::Vector{T},blk::Block, sp::AbstractProductSpace{NTuple{d, S},DD}) where {S<:UnivariateSpace,T<:Number,d,DD} | ||
|
||
|
|
||
| @assert d>2 | ||
|
|
||
| TensorIteratorFun{S, d, typeof(sp), T}(sp, cfs, iter, blk) # This is not a ProductFun | ||
| end | ||
|
|
||
| ## Construction in a ProductSpace via a Vector of Funs | ||
|
|
||
| function ProductFun(M::Vector{VFun{S,T}},dy::V) where {S<:UnivariateSpace,V<:UnivariateSpace,T<:Number} | ||
|
|
@@ -174,7 +193,8 @@ function coefficients(f::ProductFun,ox::Space,oy::Space) | |
| end | ||
|
|
||
| (f::ProductFun)(x,y) = evaluate(f,x,y) | ||
| (f::ProductFun)(x,y,z) = evaluate(f,x,y,z) | ||
benjione marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| (f::TensorIteratorFun)(x...) = evaluate(f, x...) | ||
|
|
||
| coefficients(f::ProductFun,ox::TensorSpace) = coefficients(f,ox[1],ox[2]) | ||
|
|
||
|
|
@@ -209,7 +229,6 @@ canonicalevaluate(f::ProductFun,xx::AbstractVector,yy::AbstractVector) = | |
|
|
||
|
|
||
| evaluate(f::ProductFun,x,y) = canonicalevaluate(f,tocanonical(f,x,y)...) | ||
| evaluate(f::ProductFun,x,y,z) = canonicalevaluate(f,tocanonical(f,x,y,z)...) | ||
|
|
||
| # TensorSpace does not use map | ||
| evaluate(f::ProductFun{S,V,SS,T},x::Number,::Colon) where {S<:UnivariateSpace,V<:UnivariateSpace,SS<:TensorSpace,T} = | ||
|
|
@@ -219,6 +238,33 @@ evaluate(f::ProductFun{S,V,SS,T},x::Number,y::Number) where {S<:UnivariateSpace, | |
| evaluate(f,x,:)(y) | ||
|
|
||
|
|
||
| # TensorSpace evaluation | ||
| function evaluate(f::TensorIteratorFun{S, d, SS, T},x...) where {S<:UnivariateSpace, d, SS, T} | ||
| highest_order = f.orders.n[1] | ||
| n = length(f.coefficients) | ||
|
|
||
| # this could be lazy evaluated for the sparse case | ||
| A = [Fun(f.space.spaces[i], [zeros(k);1])(x[i]) for k=0:highest_order, i=1:d] | ||
| result::T = 0 | ||
| coef_counter::Int = 1 | ||
| for i in f.iterator | ||
| tmp = f.coefficients[coef_counter] | ||
| if tmp != 0 | ||
| tmp_res = 1 | ||
| for k=1:d | ||
| tmp_res *= A[i[k], k] | ||
| end | ||
| result += tmp * tmp_res | ||
| end | ||
| coef_counter += 1 | ||
| if coef_counter > n | ||
| break | ||
| end | ||
| end | ||
| return result | ||
| end | ||
|
|
||
|
|
||
| evaluate(f::ProductFun,x) = evaluate(f,x...) | ||
|
|
||
| *(c::Number,f::F) where {F<:ProductFun} = F(c*f.coefficients,f.space) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| using ApproxFunBase: tensorizer | ||
| using Test | ||
| using ApproxFunOrthogonalPolynomials | ||
|
|
||
| @testset "Multivariate Tests" begin | ||
|
|
||
| @testset "iterator order" begin | ||
| S = Chebyshev()^2 | ||
| it = tensorizer(S) | ||
| expected_order = [(1, 1) | ||
| (1,2) | ||
| (2,1) | ||
| (1,3) | ||
| (2,2) | ||
| (3,1) | ||
| (1,4) | ||
| (2,3)] | ||
| k = 0 | ||
| for i in it | ||
| k = k + 1 | ||
| if k>length(expected_order) | ||
| break | ||
| end | ||
| @test i == expected_order[k] | ||
| end | ||
| end | ||
|
|
||
| @testset "Evaluation" begin | ||
|
|
||
| # 2D | ||
| f2 = Fun(Chebyshev()^2, [1.0]) | ||
| @test f2(0.2, 0.4) == 1.0 | ||
|
|
||
| # 3D | ||
| f3 = Fun(Chebyshev()^3, [1.0]) | ||
| @test f3(0.2, 0.4, 0.2) == 1.0 | ||
| end | ||
|
|
||
| @testset "Arithmetic" begin | ||
| @testset "Addition" begin | ||
| # coefficients | ||
| c_1 = rand(20) | ||
| c_2 = rand(30) | ||
|
|
||
| added_coef = [c_2[1:20]+c_1;c_2[21:end]] | ||
|
|
||
| # 2D | ||
| f2_1 = Fun(Chebyshev()^2, c_1) | ||
| f2_2 = Fun(Chebyshev()^2, c_2) | ||
| @test coefficients(f2_1+f2_2) == added_coef | ||
|
|
||
| @test (f2_1+f2_2)(0.3, 0.5)≈f2_1(0.3, 0.5)+f2_2(0.3, 0.5) | ||
|
|
||
| # 3D | ||
| f3_1 = Fun(Chebyshev()^3, c_1) | ||
| f3_2 = Fun(Chebyshev()^3, c_2) | ||
| @test coefficients(f3_1+f3_2) == added_coef | ||
|
|
||
| @test (f3_1+f3_2)(0.3, 0.5, 0.6)≈f3_1(0.3, 0.5, 0.6)+f3_2(0.3, 0.5, 0.6) | ||
| end | ||
|
|
||
| @testset "Multiplication" begin | ||
| # coefficients | ||
| c_1 = rand(20) | ||
| c_2 = rand(30) | ||
|
|
||
| # 2D | ||
| f2_1 = Fun(Chebyshev()^2, c_1) | ||
| f2_2 = Fun(Chebyshev()^2, c_2) | ||
|
|
||
| # @test (f2_1 * f2_2)(0.4, 0.5) ≈ f2_1(0.4, 0.5) * f2_2(0.4, 0.5) broken=true | ||
|
|
||
| # 3D: not implemented in code yet | ||
| #f3_1 = Fun(Chebyshev()^3, c_1) | ||
| #f3_2 = Fun(Chebyshev()^3, c_2) | ||
|
|
||
| #@test (f3_1*f3_2)(0.4,0.5,0.6) ≈ f3_1(0.4,0.5,0.6)*f3_2(0.4,0.5,0.6) | ||
| end | ||
| end | ||
|
|
||
| end | ||
benjione marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -326,4 +326,5 @@ end | |
| end | ||
|
|
||
| @time include("ETDRK4Test.jl") | ||
| @time include("MultivariateTest.jl") | ||
| include("show.jl") | ||
Uh oh!
There was an error while loading. Please reload this page.