Setting ApproxFun Space , tried several tricks but still receive **ERROR: LoadError: Cannot infer spaces** – specifically when using GeneralizedGenerated.jl for Generalized generated functions

Setting ApproxFun Space , tried several tricks but still receive ERROR: LoadError: Cannot infer spaces – specifically when using GeneralizedGenerated.jl for Generalized generated functions

# Begin Preamble 
using LinearAlgebra
using GeneralizedGenerated #
using ApproxFun, Test
    import ApproxFunBase: testfunctional, testbandedoperator
using SpecialFunctions

## Avazzadev et al # Example 1
 ctoli_Q1=gamma(0.5)*LeftIntegral(0.5)
 r_left_x = 0.0 ; r_right_x = 1.0
 fun_f1=mk_function(
           Meta.parse("x -> ApproxFun.Fun(Chebyshev(Domain(r_left_x..r_right_x)),
                                                2/105*sqrt(x)*(105-56x^2+48x^3))" )
       )
# 
# Tried next line 
fun_f1=ApproxFunBase.setdomain(fun_f1,r_left_x..r_right_x)
# But then receive this ERRROR: >>
ERROR: LoadError: MethodError: no method matching setdomain(::ggfunc,::IntervalSets.Interval{:closed,:closed,Float64})
Closest candidates are: ..

## Then I try to set the space unambiguously so that the space is known,  and so does not need to be inferred here >>  
  funjac_u1=Fun( Chebyshev(Domain(r_left_x..r_right_x)), ctoli_Q1\fun_f1 )

But I keep getting this issue :
ERROR: LoadError: Cannot infer spaces
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] \(::ApproxFunBase.ConstantTimesOperator{ApproxFun.ConcreteLeftIntegral{ApproxFunBase.UnsetSpace,Float64,Float64},Float64}, ::**ggfunc;** kwds::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}) at /home/marc/.julia/packages/ApproxFunBase/92sMu/src/Operators/ldiv.jl:7
.
.

            if isambiguous(domainspace(A))
		..
		[7] isambiguous(sp::Space) in ApproxFunBase at /home/marc/.julia/packages/ApproxFunBase/92sMu/src/Space.jl:102
			.. isambiguous(sp::Space) = isambiguous(rangetype(sp))

Any hints or tips are appreciated Thanks !

I’m a bit confused what you are trying to do: note that it is not a good idea to expand sqrt(x) times a polynomial in a Chebyshev (polynomial) expansion.

That said the code seems to be broken as it is trying to use lgamma which is now called loggamma. Please file a GitHub issue.

Thank You for putting together this wonderful package, and also for looking into this.
Sorry if unclear, I’m new to ApproxFun and trying to intuitively feel my way around it
by trying out things …

Re:

  • I’m a bit confused what you are trying to do: note that it is not a good idea to expand sqrt(x) times a polynomial in a Chebyshev (polynomial) expansion.

As for ? what you are trying to do ? Look in folder: … /.julia/dev/ApproxFun/test file: FractionalTest.jl , specifically this Section:

    ## Avazzadev et al
    # Example 1
    x=Fun(0..1)
    Q=gamma(0.5)*LeftIntegral(0.5)
    @time f=(2/105*sqrt(x)*(105-56x^2+48x^3))
    u=Q\f
    @test norm(u-(x^3-x^2+1))<100eps()

So I am trying adapt the code above plus using GeneralizedGenerated so that we can use ApproxFun to take the Fractional Derivative of any arbitrary function defined in parseable String – below is the

Pseudo Code for that >>
    using GeneralizedGenerated #
    using ApproxFun, Test
    import ApproxFunBase: testfunctional, testbandedoperator
    using SpecialFunctions

        ## Avazzadev et al # Example 1           
	    x=Fun(0..1)
        Q=gamma(0.5)*LeftIntegral(0.5)
   	    f=mk_function(
            Meta.parse( "x -> ApproxFun.Fun(2/105*sqrt(x)*(105-56x^2+48x^3))" )
                          )
    u=Q\f
    @test norm(u-(x^3-x^2+1))<100eps()

I think there was also some work done towards this here >> Using ApproxFun for dynamic programming << but only with regards to limiting accuracy to save compute cycles during numerous iterations , but not so much about using ApproxFun to take the Fractional Derivative of any arbitrary function defined in a parsable String, by the way I’m also interested in any other symbolic equation function form you might suggest besides Strings.

Re:

  • That said the code seems to be broken as it is trying to use lgamma which is now called loggamma. Please file a GitHub issue.

As for “ … Please file a GitHub issue … trying to use lgamma which is now called loggamma. “ I’ll be glad to file a GitHub issue if I can help you out , but that doesn’t seem to be (at least not directly) related to my immediate issue of parsing in arbitrary functions to ApproxFun, possibly because I’m already using SpecialFunctions as a workaround ?

Ok so MWE code below is how to recreate this Error message >>

ERROR: LoadError: Cannot infer spaces
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] \(::ApproxFunBase.ConstantTimesOperator{ApproxFun.ConcreteLeftIntegral{ApproxFunBase.UnsetSpace,Float64,Float64},Float64}, ::ggfunc; kwds::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}) at /home/marc/.julia/packages/ApproxFunBase/92sMu/src/Operators/ldiv.jl:7
 [3] \(::ApproxFunBase.ConstantTimesOperator{ApproxFun.ConcreteLeftIntegral{ApproxFunBase.UnsetSpace,Float64,Float64},Float64}, ::ggfunc) at /home/marc/.julia/packages/ApproxFunBase/92sMu/src/Operators/ldiv.jl:4

MWE code in a nutshell below >>Preformatted text

# As for ? what you are trying to do ?
# Look in folder: … /.julia/dev/ApproxFun/test file: FractionalTest.jl ,
# specifically this Section:
#
#     ## Avazzadev et al
#     # Example 1
#     x=Fun(0..1)
#     Q=gamma(0.5)*LeftIntegral(0.5)
#     @time f=(2/105*sqrt(x)*(105-56x^2+48x^3))
#     u=Q\f
#     @test norm(u-(x^3-x^2+1))<100eps()
#
# So I am trying adapt the code above
# plus using GeneralizedGenerated
# so that we can use ApproxFun to take the Fractional Derivative of any arbitrary function
#  defined in parseable String – below is the
#  Pseudo Code for that >>
    using GeneralizedGenerated #
    using ApproxFun, Test
    import ApproxFunBase: testfunctional, testbandedoperator
    using SpecialFunctions

        ## Avazzadev et al # Example 1
	    x=Fun(0..1)
        Q=gamma(0.5)*LeftIntegral(0.5)
   	    f=mk_function(
                      Meta.parse( "x -> ApproxFun.Fun(2/105*sqrt(x)*(105-56x^2+48x^3))" )
                	 )
    u=Q\f
    @test norm(u-(x^3-x^2+1))<100eps()

What about with RuntimeGeneratedFunctions.jl?

1 Like

Thanks Chris ! RuntimeGeneratedFunctions.jl looks promising. I will try it out tomorrow !

This is the line that’s confusing:

It looks very different to the example code so I’m not sure what you’re trying to do. Note on the example x = Fun(0..1) so is an instance of type Fun.

Note I’m in the process of revamping ApproxFun.jl as OrthogonalPolynomialsQuasi.jl, in part to make what the linked post was trying to do a lot easier. Eg one can now fix a truncation size via

T = Chebyshev()
T[:,1:n] # first n Chebyshev polynomials

Coincidentally I have a phd student adding support for fractional derivatives as we speak. So if you need the “dynamic” part it might be best to use that, I can Try to get the example code working in the next few weeks.

2 Likes

Sounds Great and Thank You please keep me apprised :+1::smiley: :+1:

Btw yes @dlfivefifty now that we have the Fractional Calculus parts working, the (iterative) Dynamic function evaluation part is what I’m interested most in , and fyi @dlfivefifty && @ChrisRackauckas per the error message below it appears the issue of “Dynamism” may now be a matter of ApproxFun doesn’t (yet?) recognize type ::RuntimeGeneratedFunction (or such) as a bona fide subtype of ::Fun

ERROR: LoadError: MethodError: no method matching extrapolate(::RuntimeGeneratedFunction{(:u,)}, ::Float64)
Closest candidates are:
  extrapolate(::Fun, ::Any) at /home/marc/.julia/
packages/ApproxFunBase/92sMu/src/Fun.jl:237
  extrapolate(::Fun, ::Any, ::Any, ::Any...) at /home/marc/.julia
/packages/ApproxFunBase/92sMu/src/Fun.jl:238
Stacktrace:
 [1] (::var"#20#21")(::Float64) at ./none:0

Thanks for the suggestion Chris, Here is what I know (so far) …

… per the error message below it appears the issue of “Dynamism” may now be a matter of ApproxFun doesn’t (yet?) recognize type ::RuntimeGeneratedFunction (or such) as a bona fide subtype of ::Fun

ERROR: LoadError: MethodError: no method matching extrapolate(::RuntimeGeneratedFunction{(:u,)}, ::Float64)
Closest candidates are:
  extrapolate(::Fun, ::Any) at /home/marc/.julia/
packages/ApproxFunBase/92sMu/src/Fun.jl:237
  extrapolate(::Fun, ::Any, ::Any, ::Any...) at /home/marc/.julia
/packages/ApproxFunBase/92sMu/src/Fun.jl:238
Stacktrace:
 [1] (::var"#20#21")(::Float64) at ./none:0

And so now I’ll dive further into the mystery of the ancient arcana , hey think we might get the guy with the really cool Aussie hat sometimes known as @Chris_Foster Code name: c42f to take a look too ? You know in case I get too far inside an underwater cave without a map etc. :grimacing:

You defined a function with 1 input and tried to call it with 2.

Nope, Try this MWE / snippet out >>

		## Copied from above, Uncomment if needed.
		# using ApproxFun, Test
	    # import ApproxFunBase: testfunctional, testbandedoperator
	    # using SpecialFunctions
		# # using LinearAlgebra # nix if DUMP norm
		# using Statistics
		# #
		# using BenchmarkTools # Provides @btime for best case vs @time for worst case
		##
		## Avazzadev et al # Example 1
		x = Fun(0..1)
		Q = gamma(0.5)*LeftIntegral(0.5)
		#
		func_f4 = Meta.parse( "x -> 2/105*sqrt(x)*(105-56x^2+48x^3)" )
		func_f5 = @RuntimeGeneratedFunction(func_f4)
		println("##140 typeof(func_f5),typeof(func_f5()):=",
						typeof(func_f5))
		# Attempt to Dynamically define u=Q\f , or in this case u=Q\func_f5
		func_f6 = Meta.parse( "u -> Q\\func_f5" )
		func_f7 = @RuntimeGeneratedFunction(func_f6)
		println("##145 typeof(func_f7):=",typeof(func_f7))
		##145 typeof(func_f7):=RuntimeGeneratedFunction{(:u,)}
		##
		# NOTE BEWARE This is effectively SAMPLE RATE ! and a Possible BUG per NOT actually part of Approximating Function definition range/domain
		r_left_x = 0.0; r_length_sample_range_x = 200; r_right_x = 1.0
		range_x = range(r_left_x,
	                stop=r_right_x,
					length=convert(Integer,r_length_sample_range_x)
					); # a non-default grid
		# Previous working syntax template r_temp1 = Statistics.mean(ApproxFun.extrapolate(funjac_u1,r_x) for (r_x) in range_x)
		r_temp1 = Statistics.mean(ApproxFun.extrapolate(func_f7,r_x) for (r_x) in range_x)

That’s a doozy of an example. Maybe @Chris_Foster has an idea.

1 Like

Well it looks like ApproxFun.extrapolate only works with Fun, not Function in general. So the error you’ve got seems independent of RuntimeGeneratedFunction. You get the same error if you try to put in a normal function:

julia> ApproxFun.extrapolate(x->x, 1.0)
ERROR: MethodError: no method matching extrapolate(::var"#14#15", ::Float64)
Closest candidates are:
  extrapolate(::Fun, ::Any) at /home/chris/.julia/packages/ApproxFunBase/rkmP0/src/Fun.jl:237
  extrapolate(::Fun, ::Any, ::Any, ::Any...) at /home/chris/.julia/packages/ApproxFunBase/rkmP0/src/Fun.jl:238
Stacktrace:
 [1] top-level scope at REPL[14]:1
1 Like

To be honest I’m completely lost, but we could probably add a fallback extrapolate(f::Function, x) = f(x).

Note that you’ll need to wait til

is merged: fractional calculus was not being tested (due to a type-inference bug that was fixed in 1.3 or so) and stopped working.

1 Like

Yeah I should say I don’t know anything about ApproxFun or about the application here so I don’t know whether putting a RuntimeGeneratedFunction into extrapolate makes sense.

But I thought maybe it’s a just a bug in the example code, as this same code wouldn’t work even with normal closures?

1 Like

Thank you All for your input and insights !
You motivated me to push on until we found an answer together !

Ok so I’d like to take a swing at recapping
what we’ve learned so far here …

### 
# Template solution motivated by @Chris_Foster and @ChrisRackauckas Thanks Chrisss^2 :-) !
# .. Marc BEGIN WORKS NOW !!

julia> func_f161 = @RuntimeGeneratedFunction(Meta.parse("f16(x) = x"))
# Julia response @RuntimeGeneratedFunction( >>
RuntimeGeneratedFunction(#=in Main=#, :((x,)->begin
          #= none:1 =#
          x
      end))

julia> f17 = ApproxFun.Fun(x->func_f161(x),Domain(0.0..10.0))
# Julia response ApproxFun.Fun( >>
Fun(Chebyshev(0.0..10.0),[5.0, 5.000000000000001])

julia> f17(1)
0.9999999999999991

julia> f17(7)
7.000000000000001

julia> @btime f17(7)
  26.122 ns (1 allocation: 16 bytes)
7.000000000000001
## Yay !! good job Chris using RuntimeGeneratedFunctions.jl even beats Generalizedgenerated.jl for generalized generated functions

#
# .. Marc END WORKS NOW !!
###

Ps> @dlfivefifty Now that the above code works for defining Dynamic functions specified by a String would you like me to Test it out , clean it up, and possibly create a PR ?

… And Hope you all are up for another Question ?
It’s really for everyone but I’m guessing @dlfivefifty or @ChrisRackauckas might know off the top of their heads about why this section of Code:

julia> f17 = ApproxFun.Fun(x->func_f161(x),Domain(0.0..10.0))
# Julia response ApproxFun.Fun( >>
Fun(Chebyshev(0.0..10.0),[5.0, 5.000000000000001])

Note it doesn’t appear until specify the Domain( ,
so to develop Mathematical theory intuition further pls
where and why does the [5.0, 5.000000000000001] come from ?

… And @Chris_Foster and @dlfivefifty I have more questions about quickly handling / removing Inf from answers (possibly as Missing instead ) because Inf really renders LinearAlgebra.norm( and Statistics.mean( useless for further Tests or analysis ;
but I’m trying (but failing ? LOL :slight_smile: ) to keep things bite size and not “Fire Hose” everyone …

Dang, missed opportunity. It could’ve been GeneralizedGeneralizedGenerated.jl

3 Likes

:joy: :sunglasses: :+1:

Thank You very much Sheehan @dlfivefifty ^This will absolutely be helpful for managing and metering CPU cycles/time spent on each iteration while searching for solutions … what are your thoughts about doing the same for Jacobi etc. ?

:+1: :sunglasses: :+1: