Julia - implementing to_index(::Symbol) - julia

The following fails on load. It says the problem is with the to_index method but it only happens when using the colon operator.
S = InputOhlcSeries{Int}(5)
push!(S, 0,0,0,1)
push!(S, 0,0,0,2)
push!(S, 0,0,0,3)
push!(S, 0,0,0,4)
push!(S, 0,0,0,5)
push!(S, 0,0,0,6)
#assert S[end, :close] == 6 # Works fine
#assert S[:, 4] == [2,3,4,5,6] # Works fine
#assert S[:, :close] == [2,3,4,5,6] # Will fail here
ERROR: LoadError: LoadError: ArgumentError: invalid index: close of type Symbol
Stacktrace:
[1] to_index(::Symbol) at ./indices.jl:270
[2] to_index(::InputOhlcSeries{Int64}, ::Symbol) at ./indices.jl:247
[3] to_indices at ./indices.jl:298 [inlined]
[4] to_indices at ./indices.jl:294 [inlined]
[5] getindex(::InputOhlcSeries{Int64}, ::Function, ::Symbol) at ./abstractarray.jl:927
[6] top-level scope at none:0
[7] include at ./boot.jl:326 [inlined]
using Match
mutable struct InputOhlcSeries{T} <: AbstractArray{T,2}
data::CircularBuffer{Vector{T}}
function InputOhlcSeries{T}(length::Int) where T
data = CircularBuffer{Vector{T}}(length)
fill!(data, [0,0,0,0])
new{T}(data)
end
end
#inline Base.getindex(S::InputOhlcSeries, i::Int, j::Int) = S.data[i][j]
#inline Base.setindex!(S::InputOhlcSeries, value, i::Int, j::Int) = S.data[i][j] = value
Base.size(S::InputOhlcSeries) = (length(S.data), 4)
Base.eltype(::Type{InputOhlcSeries{T}}) where {T} = T
#inline Base.push!(S::InputOhlcSeries, open, high, low, close) = push!(S.data, [open, high, low, close])
#inline function Base.getindex(S::InputOhlcSeries, r::Int, c::Symbol)
S[r, to_index(c)]
end
#inline function Base.setindex!(S::InputOhlcSeries, value, r::Int, c::Symbol)
S[r, to_index(c)] = value
end
#inline function to_index(r::Symbol)::Int
#match r begin
:open => 1
:high => 2
:low => 3
:close => 4
_ => throw(ArgumentError("Expected one of :open, :high, :low, :close"))
end
end

Made the following mods:
import Base: to_index
#inline Base.getindex(S::InputOhlcSeries, r::Int, c::Symbol) = S[r, to_index(S, c)]
#inline function Base.setindex!(S::InputOhlcSeries, value, r::Int, c::Symbol)
S[r, to_index(S, c)] = value
end
#inline Base.push!(S::InputOhlcSeries, open, high, low, close) = push!(S.data, [open, high, low, close])
function to_index(S::InputOhlcSeries, s::Symbol)
#match s begin
:open => 1
:high => 2
:low => 3
:close => 4
_ => throw(ArgumentError("Expected one of :open, :high, :low, :close"))
end
end

Related

LoadError: UndefVarError: #defVar not defined

I have a piece of code about JuMP. When I run it ,it says that LoadError: UndefVarError: #defVar not defined. I have tried using global forward or backward but both fails.
See:
function T1(w_func,grid_b,β,u,z)
# objective for each grid point
for j in 1:cp.Nb
b = grid_b[j]
choice1 = Model(solver=GLPKSolverLP())
#defVar (choice1, a >= 0)
#setObjective(choice1, Max, u(a) + cp.β * (w_func.((b*(1+cp.r)+cp.w-a) .* cp.z[i])))
results1 = solve(choice1)
Tw1 = getObjectiveValue(choice1)
c_choice1 = getValue(x)
return Tw, σ
end
end
LoadError: UndefVarError: #defVar not defined
in expression starting at In[44]:37
Stacktrace:
[1] top-level scope
# :0
[2] eval
# ./boot.jl:360 [inlined]
[3] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
# Base ./loading.jl:1094
thanks
It seems that you're using an outdated code. Look at the fresh documentation and make sure you have installed the latest versions of libraries and Julia.
In short, #defVar and #setObjective were replaced by #variable and #objective correspondingly.
function T1(w_func,grid_b,β,u,z)
# objective for each grid point
for j in 1:cp.Nb
b = grid_b[j]
choice1 = Model(solver=GLPKSolverLP())
#variable(choice1, a >= 0)
#objective(choice1, Max, u(a) + cp.β * (w_func.((b*(1+cp.r)+cp.w-a) .* cp.z[i])))
results1 = solve(choice1)
Tw1 = getObjectiveValue(choice1)
c_choice1 = getValue(x)
return Tw, σ
end
end

Julia not accepting this constraint. No method matching cartesian index

I have the following code in which the JuMP constraint is throwing an error.
using JuMP
using MosekTools
K = 3
N = 2
penalties = [1.0, 3.9, 8.7]
function A_tau(r::Number, n::Number, tau::Float64)
fac = 1
for m in 1:r
fac *= (n - (m - 1))
end
if n >= r
return fac * tau ^ (n - r)
else
return 0.0
end
end
function A_tau_mat(tau::Float64)
mat = Array{Float64, 2}(undef, N+1, N+1)
for i in 1:N+1
for j in 1:N+1
mat[i, j] = A_tau(i, j, tau)
end
end
return mat
end
m = Model(optimizer_with_attributes(Mosek.Optimizer, "QUIET" => false, "INTPNT_CO_TOL_DFEAS" => 1e-7))
#variable(m, p[1:1:K,1:1:N+1])
#variable(m, A[1:1:K+1,1:1:K,1:1:N+1,1:1:N+1])
#constraint(m, -A_tau_mat(0.0) * p[1, :] == [0.0, 0.0, 0.0])
optimize!(m)
println("p value is ", value.(p[1, :]))
println(A_tau_mat(0.0))
The error happens when the #constraint line is added and there's no error without it. The error is as follows. The error shows no method matching CartesianIndex ::Int64.
ERROR: LoadError: MethodError: no method matching -(::CartesianIndex{1}, ::Int64)
Closest candidates are:
-(!Matched::Complex{Bool}, ::Real) at complex.jl:307
-(!Matched::Missing, ::Number) at missing.jl:115
-(!Matched::MutableArithmetics.Zero, ::Any) at /Users/prikshetsharma/.julia/packages/MutableArithmetics/0tlz5/src/rewrite.jl:55
...
Stacktrace:
[1] _add_mul_array(::Array{GenericAffExpr{Float64,VariableRef},1}, ::Array{Float64,2}, ::JuMP.Containers.DenseAxisArray{VariableRef,1,Tuple{StepRange{Int64,Int64}},Tuple{Dict{Int64,Int64}}}) at /Users/prikshetsharma/.julia/packages/MutableArithmetics/0tlz5/src/linear_algebra.jl:166
[2] mutable_operate! at /Users/prikshetsharma/.julia/packages/MutableArithmetics/0tlz5/src/linear_algebra.jl:196 [inlined]
[3] mutable_operate_to!(::Array{GenericAffExpr{Float64,VariableRef},1}, ::typeof(*), ::Array{Float64,2}, ::JuMP.Containers.DenseAxisArray{VariableRef,1,Tuple{StepRange{Int64,Int64}},Tuple{Dict{Int64,Int64}}}) at /Users/prikshetsharma/.julia/packages/MutableArithmetics/0tlz5/src/linear_algebra.jl:208
[4] operate at /Users/prikshetsharma/.julia/packages/MutableArithmetics/0tlz5/src/linear_algebra.jl:221 [inlined]
[5] operate at /Users/prikshetsharma/.julia/packages/MutableArithmetics/0tlz5/src/rewrite.jl:43 [inlined]
[6] operate_fallback! at /Users/prikshetsharma/.julia/packages/MutableArithmetics/0tlz5/src/interface.jl:275 [inlined]
[7] operate!(::typeof(MutableArithmetics.sub_mul), ::MutableArithmetics.Zero, ::Array{Float64,2}, ::JuMP.Containers.DenseAxisArray{VariableRef,1,Tuple{StepRange{Int64,Int64}},Tuple{Dict{Int64,Int64}}}) at /Users/prikshetsharma/.julia/packages/MutableArithmetics/0tlz5/src/rewrite.jl:70
[8] top-level scope at /Users/prikshetsharma/.julia/packages/MutableArithmetics/0tlz5/src/rewrite.jl:227
[9] top-level scope at /Users/prikshetsharma/.julia/packages/JuMP/qhoVb/src/macros.jl:440
[10] top-level scope at /Users/prikshetsharma/Documents/clotorch/src/clotorch/flight/trajectory.jl:72
[11] include(::Function, ::Module, ::String) at ./Base.jl:380
[12] include(::Module, ::String) at ./Base.jl:368
[13] exec_options(::Base.JLOptions) at ./client.jl:296
[14] _start() at ./client.jl:506
in expression starting at /Users/prikshetsharma/Documents/clotorch/src/clotorch/flight/trajectory.jl:72
How to fix this error and use the constraint like I want to? What's wrong with this constraint?
You can try this
#variable(m, p[1:K,1:N+1])
#variable(m, A[1:K+1,1:K,1:N+1,1:N+1])
#constraint(m, -A_tau_mat(0.0) * p[1, :] .== [0.0, 0.0, 0.0])
There are two problems. First, the p's type in your original is DenseAxisArray rather than the normal Array because a StepRange (1:1:3) rather than a UnitRange (1:3) is provided. Though having the same elements, their types are different and the matrix multiplication implementation for it is somewhat problematic. I think it is a bug that should be fixed on the JuMP side. The other change is the dot . before the ==, which indicates broadcasting.

Why am I getting no method matching Complex(::Sym)?

I am having one function to be executed, it has been compiled but for the execution it shows me a MethodError, here is the function
For this function I'm using SymPy
function op_mat(op)
op = op.as_poly(domain="C")
op_a = op.x.gens
nab = op.length()
op_ab = ones(SymPy.Sym, nab)
coef = zeros(Complex, nab)
mat = zeros(Int64, length(op_a), nab)
for (i, (ps, c)) in enumerate(op.as_dict())
for (j, p) in enumerate(ps)
mat[j, i] = p
op_ab[i] = op_a[j]^p * op_ab[i]
end
coef[i] = c
end
return op_a, op_ab, mat, coef
end
The error message that I'm having is this one:
Complex(::T<:Number) where T<:Number at boot.jl:718
Complex(::Real) at complex.jl:16
Complex(::T<:Real, ::T<:Real) where T<:Real at complex.jl:12
...
Stacktrace:
[1] convert(::Type{Complex}, ::Sym) at ./number.jl:7
[2] setindex!(::Array{Complex,1}, ::Sym, ::Int64) at ./array.jl:766
[3] op_mat(::Sym) at ./REPL[3]:13
[4] top-level scope at REPL[7]:1
since the type of c is Sym i should have only change the type to complex coef[i]=complex(c) or coef[i]=N(c)

Saving an OrderedDict to Julia Data Format

I wish to use the JLD package to write an OrderedDict to file in such a way that I can subsequently read it back unchanged.
Here was my first effort:
using JLD, HDF5, DataStructures
function testjld()
res = OrderedDict("A" => 1, "B" => 2)
filename = "c:/temp/test.jld"
save(File(format"JLD", filename), "res", res)
res2 = load(filename)["res"]
#Check if round-tripping works
res == res2
end
But the "round-tripping" doesn't work - the function returns false. It also raises a warning:
julia> testjld()
┌ Warning: type JLD.AssociativeWrapper{Core.String,Core.Int64,OrderedCollections.OrderedDict{Core.String,Core.Int64}} not present in workspace; reconstructing
└ # JLD C:\Users\Philip\.julia\packages\JLD\1BoSz\src\jld_types.jl:703
false
After reading the docs, I thought that JLD does not support OrderedDict "out of the box", but does support Dict and I can use that fact to write my own custom serialisation for OrderedDict. Something like this:
struct OrderedDictSerializer
d::Dict
end
JLD.writeas(data::OrderedDict) = OrderedDictSerializer(Dict("contents" => convert(Dict, data),
"keyorder" => [k for (k, v) in data]))
function JLD.readas(serdata::OrderedDictSerializer)
unordered = serdata.d["contents"]
keyorder = serdata.d["keyorder"]
OrderedDict((k, unordered[k]) for k in keyorder)
end
Hardly an exhaustive test, but this does seem to work:
julia> testjld()
true
Am I correct in thinking I need to write my own serializer for OrderedDict, and can my serializer be improved?
EDIT
The answer to to my question "Can my serializer be improved?" seems to be "It will have to be, though I don't yet understand how."
Consider the two following test functions:
function testjld2()
res = OrderedDict("A" => [1.0,2.0],"B" => [3.0,4.0])
#check if round-tripping of readas and writeas methods works:
JLD.readas(JLD.writeas(res)) == res
end
function testjld3()
res = OrderedDict("A" => [1.0,2.0],"B" => [3.0,4.0])
filename = "c:/temp/test.jld"
save(File(format"JLD", filename), "res", res)
res2 = load(filename)["res"]
#Check if round-tripping to jld file and back works
res == res2
end
testjld2 shows that my writeas and readas methods correctly round-trip for an OrderedDict{String,Array{Float64,1}} with 2 entries
julia> testjld2()
true
and yet testjld3 doesn't work at all, but yields an error:
julia> testjld3()
HDF5-DIAG: Error detected in HDF5 (1.10.5) thread 0:
#000: E:/mingwbuild/mingw-w64-hdf5/src/hdf5-1.10.5/src/H5Tfields.c line 60 in H5Tget_nmembers(): not a datatype
major: Invalid arguments to routine
minor: Inappropriate type
HDF5-DIAG: Error detected in HDF5 (1.10.5) thread 0:
#000: E:/mingwbuild/mingw-w64-hdf5/src/hdf5-1.10.5/src/H5Tfields.c line 60 in H5Tget_nmembers(): not a datatype
major: Invalid arguments to routine
minor: Inappropriate type
ERROR: Error getting the number of members
Stacktrace:
[1] error(::String) at .\error.jl:33
[2] h5t_get_nmembers at C:\Users\Philip\.julia\packages\HDF5\rF1Fe\src\HDF5.jl:2279 [inlined]
[3] _gen_h5convert!(::Any) at C:\Users\Philip\.julia\packages\JLD\1BoSz\src\jld_types.jl:638
[4] #s27#9(::Any, ::Any, ::Any, ::Any, ::Any, ::Any) at C:\Users\Philip\.julia\packages\JLD\1BoSz\src\jld_types.jl:664
[5] (::Core.GeneratedFunctionStub)(::Any, ::Vararg{Any,N} where N) at .\boot.jl:524
[6] #write_compound#24(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(JLD.write_compound), ::JLD.JldGroup, ::String, ::JLD.AssociativeWrapper{String,Any,Dict{String,Any}}, ::JLD.JldWriteSession) at C:\Users\Philip\.julia\packages\JLD\1BoSz\src\JLD.jl:700
[7] write_compound at C:\Users\Philip\.julia\packages\JLD\1BoSz\src\JLD.jl:694 [inlined]
[8] #_write#23 at C:\Users\Philip\.julia\packages\JLD\1BoSz\src\JLD.jl:690 [inlined]
[9] _write at C:\Users\Philip\.julia\packages\JLD\1BoSz\src\JLD.jl:690 [inlined]
[10] write_ref(::JLD.JldFile, ::Dict{String,Any}, ::JLD.JldWriteSession) at C:\Users\Philip\.julia\packages\JLD\1BoSz\src\JLD.jl:658
[11] macro expansion at C:\Users\Philip\.julia\packages\JLD\1BoSz\src\jld_types.jl:648 [inlined]
[12] h5convert!(::Ptr{UInt8}, ::JLD.JldFile, ::OrderedDictSerializer, ::JLD.JldWriteSession) at C:\Users\Philip\.julia\packages\JLD\1BoSz\src\jld_types.jl:664
[13] #write_compound#24(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(JLD.write_compound), ::JLD.JldFile, ::String, ::OrderedDictSerializer, ::JLD.JldWriteSession) at C:\Users\Philip\.julia\packages\JLD\1BoSz\src\JLD.jl:700
[14] write_compound at C:\Users\Philip\.julia\packages\JLD\1BoSz\src\JLD.jl:694 [inlined]
[15] #_write#23 at C:\Users\Philip\.julia\packages\JLD\1BoSz\src\JLD.jl:690 [inlined]
[16] _write at C:\Users\Philip\.julia\packages\JLD\1BoSz\src\JLD.jl:690 [inlined]
[17] #write#17(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(write), ::JLD.JldFile, ::String, ::OrderedDict{String,Array{Float64,1}}, ::JLD.JldWriteSession) at C:\Users\Philip\.julia\packages\JLD\1BoSz\src\JLD.jl:514
[18] write at C:\Users\Philip\.julia\packages\JLD\1BoSz\src\JLD.jl:514 [inlined]
[19] #35 at C:\Users\Philip\.julia\packages\JLD\1BoSz\src\JLD.jl:1223 [inlined]
[20] #jldopen#14(::Base.Iterators.Pairs{Symbol,Bool,Tuple{Symbol,Symbol},NamedTuple{(:compatible, :compress),Tuple{Bool,Bool}}}, ::typeof(jldopen), ::getfield(JLD, Symbol("##35#36")){String,OrderedDict{String,Array{Float64,1}},Tuple{}},
::String, ::Vararg{String,N} where N) at C:\Users\Philip\.julia\packages\JLD\1BoSz\src\JLD.jl:246
[21] testjld3() at .\none:0
[22] top-level scope at REPL[48]:1
Use JLD2 instead:
using JLD2, DataStructures, FileIO
function testjld2()
res = OrderedDict("A" => 1, "B" => 2)
myfilename = "c:/temp/test.jld2"
save(myfilename, "res", res)
res2 = load(myfilename)["res"]
#Check if round-tripping works
res == res2
end
Testing:
julia> testjld2()
true
Personally, whenever I can I use BJSON:
using DataStructures, BSON, OrderedCollections
function testbson()
res = OrderedDict("A" => 1, "B" => 2)
myfilename = "c:/temp/test.bjson"
BSON.bson(myfilename, Dict("res" => res))
res2 = BSON.load(myfilename)["res"]
#Check if round-tripping works
res == res2
end
julia> testbson()
true

My julia ray tracer returns StackOverFlowError

I'm trying to write a ray tracer in julia but my main function returns StackOverFlowError. Below is my main function:
function trace(ray::Ray, surfaces::Array{Any, 1}, depth::Int64, maxDepth::Int64)
material, t = findIntersection(ray, surfaces, Inf)
if typeof(material) == Empty
Vec3(0,0,0)
end
if depth > maxDepth
Vec3(0,0,0)
end
if material.isLight == true
material.emittance
end
normal = material.normal
ρ = material.reflectance
BRDF = ρ/3.14159
R = randHemi(normal)
cosθ = dot(R,normal)
newRay = Ray(ray.s + t*ray.d, R)
In = trace(newRay, surfaces, depth+1, maxDepth)
2.0*3.14159*BRDF*In
end
And here is my intersection function:
function findIntersection(ray::Ray, surfaces::Array{Any, 1}, tmin::Float64)
hitSurface = Empty(Vec3(0,0,0), Vec3(0,0,0), Vec3(0,0,0), false)
for surface in surfaces
t = intersect(surface, ray)
if t < tmin
hitSurface = surface
tmin = t
end
end
return hitSurface, tmin
end
But I receive this error:
StackOverflowError:
Stacktrace:
[1] findIntersection(::Ray, ::Array{Any,1}, ::Float64) at .\In[31]:10
[2] trace(::Ray, ::Array{Any,1}, ::Int64, ::Int64) at .\In[33]:2
[3] trace(::Ray, ::Array{Any,1}, ::Int64, ::Int64) at .\In[33]:18 (repeats
14493 times)
[4] top-level scope at In[35]:1
What is the cause of error?
Your problem is that you missed a return.
What you meant to have was
if depth > maxDepth
return Vec3(0,0,0)
end
Without the return, that line just allocates a Vec3, and the code continues looping.
Stackoverflow error usually occurs when there are too many recursive calls. In a nutshell, in most programming languages there is a limit on how many recursive calls you can make.
In your example, the trace functions calls itself recursively and it can cause an stack overflow. You have a parameters maxDepth that can limit that. Setting it to a lower value will probably solve this particular issue.

Resources