Difficulties of implementing function in Julia involving if, else and matrices - julia

I am trying to implement this function in Julia and I am not getting it. I think it's because of broadcasting, it doesn't seem to work with arrays.
When I write the relational operators with dot (like .> instead of >), the number of errors decreases, but it accuses "TypeError: non-boolean (BitVector) used in boolean context".
How can I fix this?
function Rulkov(N, X, Y, α)
global σ, μ
for n=1:1:N
if (X[n, 1]<=0)
X[n, 2] = α[n] / (1 - X[n, 1]) + Y[n, 1]
elseif (X[n, 1]>0 && X[n, 1]<(α .+ Y[n, 1]))
X[n, 2] = α[n] + Y[n, 1]
else
X[n, 2] = -1
end
Y[n, 2] = Y[n, 1] - μ*(X[n, 1] .+ 1) .+ μ*σ
end
return sum(X[:, 2])/N
end

Assuming that X and Y are matrices, X[n, 1] is a scalar and α .+ Y[n, 1] is a Vector, so there is no meaningful comparison between these objects. So, depending on what you want you can either use
all(X[n, 1] .< (α .+ Y[n, 1])))
or (probably more correct from the mathematical point of view)
X[n, 1] < minimum(α .+ Y[n, 1])
or non-allocating version of the previous calculation
X[n, 1] < minimum(x -> x + Y[n, 1], α)
or (as it was proposed in comments)
X[n, 1] < minimum(α) + Y[n, 1]

if, else only accepts a boolean. So I guess you need to call all or any on the BitVector first?

Related

Symbolics: Replacing symbolic equation with variables to solve

In Symbolics.jl, I can formulate a set of equations purely symbolically.
I can for example define this differential equation using #syms:
using Symbolics
#syms α ρ[1:2, 1:2] dαdt dρdt[1:2, 1:2]
eqs = []
push!(eqs, dαdt == α*(ρ[1,1] +ρ[1,2] + ρ[2,1] + ρ[2,2]))
for i in 1:2, j in 1:2
push!(eqs, dρdt[i,j] == α*ρ[j,i])
end
eqs then has the form:
5-element Vector{Any}:
dαdt == (α*(ρ[1, 1] + ρ[1, 2] + ρ[2, 1] + ρ[2, 2]))
dρdt[1, 1] == (α*ρ[1, 1])
dρdt[1, 2] == (α*ρ[2, 1])
dρdt[2, 1] == (α*ρ[1, 2])
dρdt[2, 2] == (α*ρ[2, 2])
To solve the above equation using e.g. ModelingToolkit.jl, the symbolic parameters must be replaced by variables, e.g.
#variables t::Real, αvar(t)::Complex{Real}, ρvar(t)[1:2, 1:2]::Complex{Real}
Question: How can I transform the above symbolic equation to the correct variables, so that it can be solved using e.g. an ODEProblem?
Remark: A trivial solution is of course to just use the variables as defined above in the first place. This is however not the point of this question.
Something like this may work:
using Symbolics
#syms τ α ρ[1:2, 1:2]
D = Differential(τ)
eqs = []
push!(eqs, D(α) ~ α*(ρ[1,1] +ρ[1,2] + ρ[2,1] + ρ[2,2]))
for i in 1:2, j in 1:2
push!(eqs, D(ρ[i,j]) ~ α*ρ[j,i])
end
and then
using ModelingToolkit
#parameters t
#variables αvar(t), ρvar(t)[1:2, 1:2]
subs = Dict(τ => t, α => αvar, ρ => ρvar)
eqs_subbed = substitute.(eqs, Ref(subs))

Using Lsq-Fit in Julia

I am trying to practice fitting with the Lsq-Fit-function in Julia.
The derivative of a Cauchy-distribution with parameters \gamma and x_0.
Following this manual I tried
f(x, x_0, γ) = -2*(x - x_0)*(π * γ^3 * (1 + ((x - x_0)/γ)^2)^2)^(-1)
x_0 = 3350
γ = 50
xarr = range(3000, length = 5000, stop = 4000)
yarr = [f(x, x_0, γ) for x in xarr]
using LsqFit
# p ≡ [x_0, γ]
model(x, p) = -2*(x - p[1])*(π * (p[2])^3 * (1 + ((x - p[1])/p[2])^2)^2)^(-1)
p0 = [3349, 49]
curve_fit(model, xarr, yarr, p0)
param = fit.param
... and it does not work, giving a MethodError: no method matching -(::StepRangeLen[...], leaving me confused.
Can please somebody tell me what I am doing wrong?
There are a few issues with what you've written:
the model function is meant to be called with its first argument (x) being the full vector of independent variables, not just one value. This is where the error you mention comes from:
julia> model(x, p) = -2*(x - p[1])*(π * (p[2])^3 * (1 + ((x - p[1])/p[2])^2)^2)^(-1);
julia> p0 = [3349, 49];
julia> model(xarr, p0);
ERROR: MethodError: no method matching -(::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}, ::Float64)
One way to fix this is to use the dot notation to broadcast all operators so that they work elementwise:
julia> model(x, p) = -2*(x .- p[1]) ./ (π * (p[2])^3 * (1 .+ ((x .- p[1])/p[2]).^2).^2);
julia> model(xarr, p0); # => No error
but if this is too tedious you can let the #. macro do the work for you:
# just put #. in front of the expression to transform every
# occurrence of a-b into a.-b (and likewise for all operators)
# which means to compute the operation elementwise
julia> model(x, p) = #. -2*(x - p[1])*(π * (p[2])^3 * (1 + ((x - p[1])/p[2])^2)^2)^(-1);
julia> model(xarr, p0); # => No error
Another issue is that the parameters you're looking for are meant to be floating-point values. But your initial guess p0 is initialized with integers, which confuses curve_fit. There are two ways of fixing this. Either put floating-point values in p0:
julia> p0 = [3349.0, 49.0]
2-element Array{Float64,1}:
3349.0
49.0
or use a typed array initializer to specify explicitly the element type:
julia> p0 = Float64[3349, 49]
2-element Array{Float64,1}:
3349.0
49.0
This is not really an error, but I would find it more intuitive to compute a/b instead of a*b^(-1). Also, yarr can be computed with a simple broadcast using dot notation instead of a comprehension.
Wrapping all this together:
f(x, x_0, γ) = -2*(x - x_0)*(π * γ^3 * (1 + ((x - x_0)/γ)^2)^2)^(-1)
(x_0, γ) = (3350, 50)
xarr = range(3000, length = 5000, stop = 4000);
# use dot-notation to "broadcast" f and map it
# elementwise to elements of xarr
yarr = f.(xarr, x_0, γ);
using LsqFit
model(x, p) = #. -2*(x - p[1]) / (π * (p[2])^3 * (1 + ((x - p[1])/p[2])^2)^2)
p0 = Float64[3300, 10]
fit = curve_fit(model, xarr, yarr, p0)
yields:
julia> fit.param
2-element Array{Float64,1}:
3349.999986535933
49.99999203625603

How do I raise a float to an exponent in OCaml?

I am trying to write a function that takes x and raises it to the power of n.
This code works if x and n are integers:
let rec pow x n =
if n == 0 then 1 else
if (n mod 2 = 0) then pow x (n/2) * pow x (n/2) else
x * pow x (n/2) * pow x (n/2);;
If I try to change the code to work if x is a float, it falls apart:
let rec float_pow x n =
if n == 0.0 then 1.0 else
if n mod_float 2.0 == 0.0 then float_pow x (n /. 2) *. float_pow x (n /. 2) else
x *. float_pow x (n /. 2) *. float_pow x (n /. 2);;
I get this error:
Error: This expression has type float
This is not a function; it cannot be applied.
What do I do?
The key problem, I think, is that mod is a keyword in OCaml, and is treated as an infix operator. But mod_float is just an ordinary function. You need to use it in prefix form.
So x mod n should be translated to mod_float x n.
You have another problem, which is that you're using the special-purpose == operator for equality comparison. You want to use = for equality comparisons in OCaml unless you need a "physical" comparison (which is not what you want here).
This isn't just stylistic--it really makes a difference. Note the following results:
# 0.0 == 0.0;;
- : bool = false
# 0.0 = 0.0;;
- : bool = true

How can I use universal and existential quantification in julia?

I want to code domination definition in Julia. x dom y. x , y are 2 vectors.
b=all(x<=y) && any(x<y)
would you please help me. How can I code this concept in Julia?
Thank you
The simplest approach can be almost like you have specified it:
dom(x, y) = all(x .<= y) && any(x .< y)
You could also use a loop e.g. like this:
function dom(x::AbstractVector, y::AbstractVector)
#assert length(x) == length(y)
wasless = false
for (xi, yi) in zip(x, y)
if xi < yi
wasless = true
elseif xi > yi
return false
end
end
return wasless
end

Sage's (or Maxima's) solve gives a bad answer for diff(p, x) == 0?

I am using Sage to (within a script) solve a simple equation in two variables:
sage: x, y = var("x y")
sage: p = x*y + x/y + 1/x
sage: diff(p, x)
y + 1/y - 1/x^2
sage: diff(p, y)
x - x/y^2
sage: solve([diff(p,x)==0, diff(p,y)==0], [x,y])
[[x == 0, y == 0], [x == -1/2*sqrt(2), y == 1],
[x == 1/2*sqrt(2), y == 1], [x == -1/2*I*sqrt(2), y == -1],
[x == 1/2*I*sqrt(2), y == -1]]
For some reason, Sage returns a solution that isn't a solution at all, here [x == 0, y == 0] can easily be seen NOT to be an answer of [y + 1/y - 1/x^2 == 0, x - x/y^2 == 0].
Is this a bug? a known bug? or am I doing something wrong?
UPDATE: rephrased the title, and I am wondering, worst case, how can I substitute the solutions back in the system to manually check if the equations are verified?
PS: I would post this on AskSage, but it is currently down.
Well, looks like Maxima's solve function is returning the spurious solution [x = 0, y = 0]. I see that Maxima's to_poly_solve is better behaved here.
p : x*y + x/y + 1/x;
load (to_poly_solve);
[dpx, dpy] : [diff (p, x), diff (p, y)];
to_poly_solve ([dpx, dpy], [x, y]);
=> %union([x = -1/sqrt(2),y = 1],[x = 1/sqrt(2),y = 1],
[x = -%i/sqrt(2),y = -1],[x = %i/sqrt(2),y = -1])
for xy in args (%) do print (subst (xy, [dpx, dpy]));
=>
[0,0]
[0,0]
[0,0]
[0,0]
I don't know how to call to_poly_solve from Sage, although I'm pretty sure it's possible.
Hope this helps. Good luck & have fun.

Resources