Conversation
jpfairbanks
left a comment
There was a problem hiding this comment.
This is cool, I think we can definitely make it work and be elegant at the same time. I think the biggest thing is to define the new operators with eval (see inline comment), and then to sand down some interface things.
| end | ||
| end | ||
|
|
||
| function regress(vec_a::Array{IndepVar{Float64}, 2}, vec_b::Array{IndepVar{Float64}, 2}, orig_x::Array{IndepVar{Float64}, 2}, orig_y::Array{DepVar{Float64}, 2}, op) |
There was a problem hiding this comment.
To make these more generic, you can use this construction over Float64:
julia> function foo(a::Vector{T}) where {T<:Number}
return a .+ 1
end
foo (generic function with 1 method)
julia> foo([1,2,3])
3-element Array{Int64,1}:
2
3
4
julia> foo([1,2,3.0])
3-element Array{Float64,1}:
2.0
3.0
4.0There was a problem hiding this comment.
Actual I think this is what they call "triangular dispatch"
Array{T} and then where {T <: DepVar} and then you don't have the constraint that DepVar{U} where U<:Number
There was a problem hiding this comment.
Maybe this is a way to do it
Define a parametric struct
julia> struct Bar{T}
data::T
end
# define a method that expects Bar{T<:Number}
julia> function foo(b::Bar{T}) where T<:Number
return b.data .+ 1
end
foo (generic function with 2 methods)
# it works, this is the easy case
julia> foo(Bar(1))
2
# it doesn't work if T is not a subtype of number
julia> foo(Bar([1,2]))
ERROR: MethodError: no method matching foo(::Bar{Array{Int64,1}})
Closest candidates are:
foo(::Array{T<:Number,1}) where T<:Number at REPL[4]:2
foo(::Bar{T<:Number}) where T<:Number at REPL[10]:2
Stacktrace:
[1] top-level scope at none:0
# define a case for Bar of Array containing numbers
julia> function foo(b::Bar{Array{T,1}}) where T<:Number
return b.data .+ 1
end
foo (generic function with 3 methods)
# this works so nested type constraints are possible.
julia> foo([1,2,3])
3-element Array{Int64,1}:
2
3
4
# now test that the array can be on the outside and the parametric struct can be on the inside.
julia> function foo(b::Array{Bar{T},1}) where T<:Number
return [x.data .+ 1 for x in b]
end
foo (generic function with 4 methods)
# success
julia> foo(Bar.([1,2,3]))
3-element Array{Int64,1}:
2
3
4
There was a problem hiding this comment.
So a relatively straightforward fix seems to work unless there's something I've overlooked:
regress(vec_a::Array{IndepVar{T}}, vec_b::Array{DepVar{T}}, orig_x::Array{IndepVar{T}}, orig_y::Array{DepVar{T}}, op) where {T<:Number}
e.g., constrain for the RegComponent parameter type but don't include a constraint that the array dimension parameter <: Integer.
This PR references #183 and is intended to prevent the user from regressing on the dependent variable during feature transformation that may accidentally involve the DV.
The checks are hard-coded right now; need the idiomatic syntax to convert/promote, etc. so that the multi-dispatch on element/col type will work as intended.