I'm currently trying to print the following function in my plot and I'm not allowed to use any imports or other libraries:
using Plots
amplitude = 1
frequenz_E = 329.63
frequenz_G_SHARP = 415.30
frequenz_B = 493.88
k(t) = amplitude * sin * (2 * pi * frequenz_E * t)
p = plot(0:0.005:0.001, k , label="E = 329.63 Hz", title="Triade sound wave", xlabel="t (seconds)", ylabel="y(t)")
display(p)
I do want to start at 0 and then increase the value by 0.005 up to 0.01.
Now if I want to print the function, I do get the following error:
include("/home/user/Applied_Mathmatics/Assignment_01/templates/waves.jl")
ERROR: LoadError: MethodError: no method matching *(::Int64, ::typeof(sin))
Closest candidates are:
*(::Any, ::Any, ::Any, ::Any...) at operators.jl:529
*(::ChainRulesCore.NotImplemented, ::Any) at /home/user/.julia/packages/ChainRulesCore/8NXnp/src/tangent_arithmetic.jl:37
*(::ChainRulesCore.ZeroTangent, ::Any) at /home/user/.julia/packages/ChainRulesCore/8NXnp/src/tangent_arithmetic.jl:104
How can I work around the error and just print the function?
The output should look like this (I did not implement all functions yet):
As the error states, you cannot multiply a function with an Integer. You should write
k(t) = amplitude * sin(2 * pi * frequenz_E * t)
And by the way the range 0:0.005:0.001 is just one element, i.e., 0.. You can try that by
julia> collect(0:0.005:0.001)
1-element Vector{Float64}:
0.0
In Julia the middle element is the step and the third element is the end of the range. Thus something like 0:0.001:0.005 makes more sense.
Related
I have some problems with JuMP. When I run it, it says:
MethodError: no method matching (::Interpolations.Extrapolation{Float64, 1, ScaledInterpolation{Float64, 1, Interpolations.BSplineInterpolation{Float64, 1, Vector{Float64}, BSpline{Linear{Throw{OnGrid}}}, Tuple{Base.OneTo{Int64}}}, BSpline{Linear{Throw{OnGrid}}}, Tuple{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}}}, BSpline{Linear{Throw{OnGrid}}}, Throw{Nothing}})(::AffExpr)
Use square brackets [] for indexing an Array.
thanks!
using JuMP
import Ipopt
β = 0.88
Nb = 1000
δ = 1.5
wage = 1
rate = 1
grid_b = range(0, 5, length = 1000)
w = 5 * (grid_b).^2
w_func = LinearInterpolation(grid_b, w)
choice1 = Model(Ipopt.Optimizer)
#variable(choice1, x >= 0)
#NLobjective(choice1, Max, x^δ/(1-δ) + β * (w_func.((grid_b[3]*(1+rate)+wage-x) * 3)))
optimize!(choice1)
If I try to run your code, I get
ERROR: UndefVarError: LinearInterpolation not defined
which package is that from? Also, what version of JuMP are you using?
You can’t use arbitrary functions in JuMP. You need to use a user-defined function:
https://jump.dev/JuMP.jl/stable/manual/nlp/#User-defined-Functions
But this will only work if it’s possible to automatically differentiate the function. I don’t know if that works with Interpolations.jl.
p.s. Please provide a link when posting the same question in multiple places: https://discourse.julialang.org/t/methoderror-no-method-matching-in-jump/66543/2
This is the function I want to use. I am trying to use temperature data & precipiation data of a whole week. This means the arguments: temp & precip, will be an array of length 7. How do i make this work?
function humidityindex(temp, precip)
moist_effect = 0
temp_effect = 0
for i in 1:size(precip)
moist_effect += ((precip[i]/100) * (1-(i/10)))
temp_effect -= ((temp[i]/25) * (1-(i/10)))
end
effect = temp_effect + moist_effect
return effect
end
The function results in the following MethodError:
julia> t = rand(7); p = rand(7);
julia> humidityindex(t, p)
ERROR: MethodError: no method matching (::Colon)(::Int64, ::Tuple{Int64})
Closest candidates are:
Any(::T, ::Any, ::T) where T<:Real at range.jl:41
Any(::A, ::Any, ::C) where {A<:Real, C<:Real} at range.jl:10
Any(::T, ::Any, ::T) where T at range.jl:40
...
Stacktrace:
[1] humidityindex(::Array{Float64,1}, ::Array{Float64,1}) at ./REPL[1]:4
[2] top-level scope at REPL[3]:1
The problem is how you create the iteration space: for i in 1:size(precip). size in Julia returns a tuple. You want to use length instead (or size(precip, 1) for the size in the first dimension).
function humidityindex(temp, precip)
moist_effect = 0
temp_effect = 0
for i in 1:length(precip) # <-- Updated this line
moist_effect += ((precip[i]/100) * (1-(i/10)))
temp_effect -= ((temp[i]/25) * (1-(i/10)))
end
effect = temp_effect + moist_effect
return effect
end
The answer given by the first Fredrik is the answer to your question. This is simply a short and efficient way of calculating the same thing.
moist_effect((i,x)) = (x/100) * (1-(i/10))
temp_effect((i,x)) = -(x/25) * (1-(i/10))
function humidityindex(temp, precip)
sum(moist_effect, enumerate(precip)) + sum(temp_effect, enumerate(temp))
end
Notice the tuple destructuring in moist_effect((i,x)), I added this since enumerate iterates tuples of indices and values.
The function sum has a method that accepts a function as its first argument. This method applies that function to all elements before summing them up.
I am trying to implement to Swing equation for a n-Machine system using Julia.
When i run the following code I get this Error Message:
LoadError: InexactError: Float64(0.0 + 1.0im)
in expression starting at /home/Documents/first_try.jl:61
Swing_Equation(::Array{Float64,1}, ::Array{Float64,1}, ::Array{Float64,1}, ::Float64) at complex.jl:37
ODEFunction at diffeqfunction.jl:219 [inlined]
initialize!
The problem is occuring since I am using du[3] = (u[3] * u[2]) * im which can not be a Float64 type. The code is working fine when I remove the im - but then it is not the model I want to implement anymore.
What way is there to work around my problem?
using Plots
using DifferentialEquations
inspectdr()
# Constants
P_m0 = 0.3 # constant Mechanical Power
P_emax = 1
H = 1.01 # Inertia constant of the system
θ_0 = asin(P_m0 / P_emax) # angle of the system
ω_0 = 1.0 # initial angular velocity
M = 2 * H / ω_0
D = 0.9 # Damping constant
u02 = [θ_0;ω_0] # Initial Conditions
tspan = (0.0,100.0) # Time span to solve for
p = [M;P_m0;D]
i = 3
function Swing_Equation(du,u,t,p) # u[1] = angle θ
du[1] = u[2] # u[2] = angular velocity ω
P_e = real(u[3] * conj(i))
du[2] = (1 / M) * ( P_m0 - P_e - D * u[2]) # du[2] = angular acceleration
du[3] = (u[3] * u[2]) * im
end
# solving the differential equations
prob2 = ODEProblem(Swing_Equation,u0,tspan,p)
print(prob2)
sol2 = solve(prob2)
# Visualizing the solutoins
plot(sol2; vars = 1, label = "Θ_kura", line = ("red"))
plot!(sol2; vars = 2, label = "ω_kura", line = ("blue"))
gui()
plot(sol2,vars = (1,2),label="Kurmamoto" ,line = ("purple"))
xlabel!("Θ")
ylabel!("ω")
gui()
The problem is most likely in your input.
prob2 = ODEProblem(Swing_Equation,u0,tspan,p)
I am guessing that in this part you are providing an array of Float64 for u0? Your Swing_Equation then receives u as an Array{Float64} type. I suspect that also means du is the same.
This causes the expression
du[3] = (u[3] * u[2]) * im
to fail because you are trying to assign a Complex{Float64} number to du[3] which is of type Float64. Julia will then try to perform a
convert(Float64, (u[3] * u[2]) * im)
Which will cause the inexact error, because you cannot convert a complex number to a floating point number.
The Solution is to make sure du and u are complex numbers so you avoid this conversion. A quick and dirty way to solve that would be to write:
prob2 = ODEProblem(Swing_Equation, collect(Complex{Float64}, u0),tspan,p)
This will collect all elements in u0 and create a new array where every element is a Complex{Float64}. However this assumes a 1D array. I don't know your case. I don't work with ODE solvers myself.
General Advice to avoid this kind of problem
Add some more type assertions to in your code to make sure you get the kind of inputs you expect. This will help catch these kinds of problem and make you more easily see what is going on.
function Swing_Equation(du::AbstractArray{T}, u::AbstractArray{T}, t,p) where T<:Complex # u[1] = angle θ
du[1] = u[2] :: Complex{Float64}
P_e = real(u[3] * conj(i))
du[2] = (1 / M) * ( P_m0 - P_e - D * u[2]) # du[2] = angular acceleration
du[3] = (u[3] * u[2]) * im
end
Keep in mind Julia is a bit more demanding when it comes to matching up types than other dynamic languages. That is what gives it the performance.
Why is Julia different from Python in this case?
Julia does not upgrade types like Python to whatever fits. Arrays are typed. They cannot contain anything like in Python and other dynamic languages. If you e.g. made an array where each element is an integer, then you cannot assign float values to each element without doing an explicit conversion to floating point first. Otherwise Julia has to warn you that you are getting an inexact error by throwing an exception.
In Python this is not a problem because every element in an array can be a different type. If you want every element in a Julia array to be a different number type then you must create the array as a Array{Number} type but these are very inefficient.
Hope that helps!
I can write in function in Matlab in this way:
function res=resid(theta,alpha,beta);
RHS=[];
LHS=[];
RHS= theta-alpha;
LHS= theta*beta;
res = (LHS-RHS);
We set the parameters, call the function:
alpha=0.3;beta=0.95;
a01=[1.0;1.0];
th=fsolve('resid',a01,[],alpha,beta)
This will return [6.0;6.0]. Does the option"[]" signal to fsolve that the input is a vector?
Anyway, how can I implement this in Julia using a NLsolve, Optim or JuMP? The original problem has more than 10 variables, so I would prefer a vector approach.
I can implement the function in Julia:
h! =function (theta)
RHS=[];
LHS=[];
RHS= theta-alpha;
LHS= theta*beta;
res= (LHS-RHS);
return res;
end
But simply using NLsolve:
a01 = [1.0;1.0];
res = nlsolve(h!,a01)
Returns:
MethodError: no method matching (::##17#18)(::Array{Float64,1}, ::Array{Float64,1})
Closest candidates are:
#17(::Any) at In[23]:3
If I alternatively use Optim, I get:
using Optim
optimize(h!, a01)
which returns:
MethodError: Cannot `convert` an object of type Array{Float64,1} to an object of type Float64
This may have arisen from a call to the constructor Float64(...),
since type constructors fall back to convert methods.
Thank you for your suggestions!
Following the suggestion by Chris Rackauckas, the solution would be to keep the definition of h:
h =function (theta)
RHS=[];
LHS=[];
RHS= theta-alpha;
LHS= theta*beta;
res= (LHS-RHS);
return res;
end
and to use not_in_place:
a01 = [1.0;1.0];
solve = nlsolve(not_in_place(h),a01)
Returning a solution:
Results of Nonlinear Solver Algorithm
* Algorithm: Trust-region with dogleg and autoscaling
* Starting Point: [1.0,1.0]
* Zero: [6.0,6.0]
* Inf-norm of residuals: 0.000000
* Iterations: 3
* Convergence: true
* |x - x'| < 0.0e+00: false
* |f(x)| < 1.0e-08: true
* Function Calls (f): 4
* Jacobian Calls (df/dx): 4
Thank you!
I'm trying to use JuMP to solve a non-linear problem, where the number of variables are decided by the user - that is, not known at compile time.
To accomplish this, the #NLobjective line looks like this:
#eval #JuMP.NLobjective(m, Min, $(Expr(:call, :myf, [Expr(:ref, :x, i) for i=1:n]...)))
Where, for instance, if n=3, the compiler interprets the line as identical to:
#JuMP.NLobjective(m, Min, myf(x[1], x[2], x[3]))
The issue is that #eval works only in the global scope, and when contained in a function, an error is thrown.
My question is: how can I accomplish this same functionality -- getting #NLobjective to call myf with a variable number of x[1],...,x[n] arguments -- within the local, not-known-at-compilation scope of a function?
def testme(n)
myf(a...) = sum(collect(a).^2)
m = JuMP.Model(solver=Ipopt.IpoptSolver())
JuMP.register(m, :myf, n, myf, autodiff=true)
#JuMP.variable(m, x[1:n] >= 0.5)
#eval #JuMP.NLobjective(m, Min, $(Expr(:call, :myf, [Expr(:ref, :x, i) for i=1:n]...)))
JuMP.solve(m)
end
testme(3)
Thanks!
As explained in http://jump.readthedocs.io/en/latest/nlp.html#raw-expression-input , objective functions can be given without the macro. The relevant expression:
JuMP.setNLobjective(m, :Min, Expr(:call, :myf, [x[i] for i=1:n]...))
is even simpler than the #eval based one and works in the function. The code is:
using JuMP, Ipopt
function testme(n)
myf(a...) = sum(collect(a).^2)
m = JuMP.Model(solver=Ipopt.IpoptSolver())
JuMP.register(m, :myf, n, myf, autodiff=true)
#JuMP.variable(m, x[1:n] >= 0.5)
JuMP.setNLobjective(m, :Min, Expr(:call, :myf, [x[i] for i=1:n]...))
JuMP.solve(m)
return [getvalue(x[i]) for i=1:n]
end
testme(3)
and it returns:
julia> testme(3)
:
EXIT: Optimal Solution Found.
3-element Array{Float64,1}:
0.5
0.5
0.5