Multiple dimensional sampling with first element string

Where does SobolSample come from? It doesn’t seem to belong to either JuMP or DataStructures.

Yes.

But I am rather trying to understand how to input the correct type of data to x_train/y_train. This is dependent on how I formulate lb and ub (lower and upper bounds respectively).

From the error that y_train is returning (see below). I believe it is expecting a Tuple{Float64,Float64} but I am giving it (::String, ::Int64).

MethodError: no method matching getindex(::Tuple{Float64,Float64}, ::String, ::Int64)
Closest candidates are:
getindex(::Tuple, ::Int64) at tuple.jl:24
getindex(::Tuple, ::Real) at tuple.jl:25
getindex(::Tuple, ::UnitRange) at range.jl:293

Sorry it is part of the package Surrogates. I forgot to include it in the MWE

We are somehow misunderstanding each other. You are not inputting anything into x_train or y_train. They are outputs from sample and g, respectively.

Can you confirm on which line your code fails?

Oh yes. My mistake. My wording was not communicating that.
My code is failing here.

y_train = g.(x_train);

With this error:

MethodError: no method matching getindex(::Tuple{Float64,Float64}, ::String, ::Int64)
Closest candidates are:
getindex(::Tuple, ::Int64) at tuple.jl:24
getindex(::Tuple, ::Real) at tuple.jl:25
getindex(::Tuple, ::UnitRange) at range.jl:293

Stacktrace:
[1] (::var"#195#376"{Int64,Tuple{Float64,Float64},OrderedDict{String,Int64}})(::String) at .\none:0
[2] MappingRF at .\reduce.jl:93 [inlined]
[3] _foldl_impl(::Base.MappingRF{var"#195#376"{Int64,Tuple{Float64,Float64},OrderedDict{String,Int64}},Base.BottomRF{typeof(Base.add_sum)}}, ::Base._InitialValue, ::Array{String,1}) at .\reduce.jl:58
[4] FlatteningRF at .\reduce.jl:119 [inlined]
[5] MappingRF at .\reduce.jl:93 [inlined]
[6] _foldl_impl(::Base.MappingRF{var"#196#375"{Tuple{Float64,Float64},OrderedDict{String,Int64}},Base.FlatteningRF{Base.BottomRF{typeof(Base.add_sum)}}}, ::Base._InitialValue, ::UnitRange{Int64}) at .\reduce.jl:58
[7] foldl_impl at .\reduce.jl:48 [inlined]
[8] mapfoldl_impl at .\reduce.jl:44 [inlined]
[9] #mapfoldl#204 at .\reduce.jl:160 [inlined]
[10] mapfoldl at .\reduce.jl:160 [inlined]
[11] #mapreduce#208 at .\reduce.jl:287 [inlined]
[12] mapreduce at .\reduce.jl:287 [inlined]
[13] sum at .\reduce.jl:494 [inlined]
[14] sum(::Base.Iterators.Flatten{Base.Generator{UnitRange{Int64},var"#196#375"{Tuple{Float64,Float64},OrderedDict{String,Int64}}}}) at .\reduce.jl:511
[15] macro expansion at C:\Users\glmab.julia\packages\MutableArithmetics\bPWR4\src\rewrite.jl:276 [inlined]
[16] macro expansion at C:\Users\glmab.julia\packages\JuMP\y5vgk\src\macros.jl:928 [inlined]
[17] (::var"#194#374"{OrderedDict{String,Int64}})(::Tuple{Float64,Float64}) at .\In[17]:206
[18] _broadcast_getindex_evalf at .\broadcast.jl:648 [inlined]
[19] _broadcast_getindex at .\broadcast.jl:621 [inlined]
[20] getindex at .\broadcast.jl:575 [inlined]
[21] copy at .\broadcast.jl:876 [inlined]
[22] materialize(::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1},Nothing,var"#194#374"{OrderedDict{String,Int64}},Tuple{Array{Tuple{Float64,Float64},1}}}) at .\broadcast.jl:837
[23] top-level scope at In[51]:1
[24] include_string(::Function, ::Module, ::String, ::String) at .\loading.jl:1091

I’m trying to condense your problem into a minimal working example (MWE), see here Please read: make it easier to help you for how to structure questions that are easy to understand.

It is not certain that I can help, but I can help to simplify your question, at least.

So most of your code plays no part here. I reduced your example to this:

using Surrogates
x_train = sample(10, ["s1", 1], ["s4", 10], SobolSample())

This gives an error:

ERROR: MethodError: no method matching +(::String, ::Int64)

But you are saying that this is no longer a problem, and your code now fails at the next line:

instead?

How did you get the x_train?

1 Like

So the error in this line is caused by Surrogates.sample trying to call sum(ub) when ub is ["s4", 10], so apparently it makes no sense to use ["s1", 1], and ["s4", 10] as lower and upper bounds.

I am not saying it is no longer a problem but I now want to solve it from y_train moving up.

x_train needs to be correct for y_train to be correct. Because when x_train is Float64 (or Int64 or the likes). y_train returns the below error.

MethodError: no method matching getindex(::Tuple{Float64,Float64}, ::String, ::Int64)
Closest candidates are:
getindex(::Tuple, ::Int64) at tuple.jl:24
getindex(::Tuple, ::Real) at tuple.jl:25
getindex(::Tuple, ::UnitRange) at range.jl:293

This is my current x_train

x_train = sample(10, Float64[1,10] ,Float64[10,100], SobolSample())

This is taking some time to install, but just an idea: Have you tried using

N = 1:10

instead of

N = [1:10]

They mean very different things, and it looks like it could be a problem.

Using that remains the error same, Int64 changes to UnitRange{Int64}

MethodError: no method matching getindex(::Tuple{Float64,Float64}, ::String, ::UnitRange{Int64})
Closest candidates are:
getindex(::Tuple, ::Int64) at tuple.jl:24
getindex(::Tuple, ::Real) at tuple.jl:25
getindex(::Tuple, ::UnitRange) at range.jl:293

Do you perhaps know what the getindex error means? While the packages install.

But anyway, what is your intention with [1:10]? Do you intend to create a vector of length 1, containing a single element, which is the range 1:10?

But looking further at you code now, this function:

g = d -> @objective m Max begin
    sum((price[s]*d[s,n]) for n in N for s in S)
end

Since you broadcast g over the elements of x_train, the value of d is a tuple of two numbers, lets take the first element of x_train which equals (7.1875, 83.125). Then you try to index into it like this: d[s,n], but that won’t work, that’s how you index into a two-dimensional array, a tuple only takes a single index.

This fits with the error message:

julia> t = (7.1875, 83.125);

julia> t["s1", 1:10]
ERROR: MethodError: no method matching getindex(::Tuple{Float64, Float64}, ::String, ::UnitRange{Int64})
Closest candidates are:
  getindex(::Tuple, ::Int64) at tuple.jl:29
  getindex(::Tuple, ::Real) at tuple.jl:30
  getindex(::Tuple, ::Colon) at tuple.jl:33
1 Like

My intention with 1:10 is an array of 10 values 1, 2, 3,4… 10.

In the case of g, d is supposed d[s1,1] … d[s1,10] likewise for s2,s3,s4 etc. I assume that is why the getindex error is also saying.

Then you must write 1:10, not [1:10].

Then x_train has completely the wrong structure.

Maybe more broadly, could you describe what your code is trying to do?

I find it hard to guess what’s supposed to be happening here, and I have a feeling that this might be due to you maybe being a beginner with the language and struggling to express basic things in an idiomatic way?

Yes I agree.

I am trying to see how to get the correct structure of x_train, which should be (string, int64) if I’m correct? It should not be a Tuple{String,Int64} if I am correct.

x_train, y_train will pass through into the following:

sgt = NeuralSurrogate(x_train, y_train, bounds..., model=model, loss=loss, opt=optimizer, n_echos=n_epochs)

I’m not sure how to achieve that, but I can say that even if d is a Tuple{String, Int64}, you cannot index into it with d[s,n], only a single index can be used, and that index must be either 1 or 2, since they are the only valid indices in a tuple of length 2.

Edit: Well, to be honest, you can also index with a vector. For example, d[1:2], or d[[2,1]] will work.

Okay it appears you are roughly trying to follow the Neural network tutorial?

I don’t know much about JuMP or Surrogates, but in that tutorial it seems to me like they have an objective function schaffer which takes an input x and produces an output y, which you don’t seem to have. Is g supposed to be your objective function? It’s not defined in a way such that g(x) produces on objective value, so g.(x_train) won’t work pretty much irrespective of how you define x_train.