My program in Julia sees syntax error where there is none - syntax-error

I have a problem with this bit of code. Every time I try to run it it says that I have "Unexpected" end. For me everything is on point and I cant figure it out can someone help me find solution? Full error code and program code below.
Program:
function mbisekcji(f, a::Float64, b::Float64, delta::Float64, epsilon::Float64)
e = b-a
u = f(a)
v = f(b)
err = 0
iterator = 0
if sign(u) == sign(v)
err = 1
return err
end
while true
e = e/2
c = a+e
w = f(c)
if (norm(e) < delta) || (norm(w) < epsilon)
return w, f(w), iterator, err
end
if sign(w) == sign(u)
b = c
v = w
else
a = c
u = w
end
iterator++
end
end
Error:
LoadError: [91msyntax: unexpected "end"[39m
while loading C:\Users\username\Desktop\Study\zad1.jl, in expression starting on line 60
include_string(::String, ::String) at loading.jl:522
include_string(::Module, ::String, ::String) at Compat.jl:84
(::Atom.##112#116{String,String})() at eval.jl:109
withpath(::Atom.##112#116{String,String}, ::String) at utils.jl:30
withpath(::Function, ::String) at eval.jl:38
hideprompt(::Atom.##111#115{String,String}) at repl.jl:67
macro expansion at eval.jl:106 [inlined]
(::Atom.##110#114{Dict{String,Any}})() at task.jl:80
Also, just to make thing easier, line 60 is second end from the back. The one closing while loop.

In order to increment a variable by 1 in Julia you have to write
iterator += 1
Julia does not support ++ to increment a variable.
But, for example, you could define a macro to do almost what you want:
julia> macro ++(x)
esc(:($x += 1))
end
#++ (macro with 1 method)
julia> x = 1
1
julia> #++x
2
julia> x
2

Related

No method matching error when working with Vector{Int64]

I have the following code where firstly I add the values for each index from two columns and creating Vector{Int64}
df = CSV.read(joinpath("data", "data.csv"), DataFrame)
adding_columns = df.firstcolumn + df.secondcolumn
Then I will create a function as following:
function fnct(data::Vector{T}; var= 8) where { T <: Number }
V = []
for x in 1:size(data)[1]
strt = x-var
ending = x+var
avg = 0
if strt < 1
for y in 1:x+var
avg = avg+data[y]
end
avg = avg/(x+var-1)
elseif ending > size(data)[1]
for y in x-var:size(data)[1]
avg = avg+data[y]
end
avg = avg/(size(data)-x-var)
else
for y in x-var:x+var
avg = avg+data[y]
end
avg = avg/(2*var)
end
push!(V,avg)
end
return V
end
When trying:
typeof(adding_columns)
I will get:
Vector{Int64}
however when calling
fnct(adding_columns)
I will get:
ERROR: MethodError: no method matching -(::Tuple{Int64}, ::Int64)
I presume that it takes my adding_columns as Tuple but I do not get it why, when the typeof is giving me Vector.
How could I solve this problem?
size(data) is a tuple:
julia> size([1,2,3]::Vector{Int})
(3,)
...but you're subtracting an integer from it in avg = avg/(size(data)-x-var).
Did you mean avg = avg/(length(data)-x-var) or avg = avg/(size(data, 1)-x-var)?

"Not defined variable" in a 'while loop' in Julia

I am trying to do a sensitivity analysis in Julia using JuMP. Here is my code:
using JuMP, Plots, Gurobi
m=Model(with_optimizer(Gurobi.Optimizer))
#variable(m, x>=0)
#variable(m, y>=0)
#variable(m, k>=0)
k = 0
while k<=1
φ(x,y,k)=3*x+k*y
#objective(m, Max, φ(x,y,k))
#constraint(m, 2*x-4>=0)
#constraint(m, y-0.5*x>=0)
pl=optimize!(m)
k=k+0.2
end
The problem is that I get an error:
UndefVarError: k not defined
What am I missing?
julia> k =0
0
julia> while k<10
k=k+1
end
ERROR: UndefVarError: k not defined
Stacktrace:
[1] top-level scope at ./REPL[11]:2
In julia if we are operating with loops the variables we initialise outside our loop can not be directly accessed within a loop on default. To do that we have to set those variable on to global use as on default they are considered to be local
julia> while k<10
global k=k+1
end
Now this works fine
Disclaimer: This is an alternative solution, that it was suggested by a member of Julia Discorse
In a discussion at Julia Discourse, it is suggested to wrap the code in a function in order to increase speed and to avoid the global issue:
function run_code()
model = Model(with_optimizer(Gurobi.Optimizer))
#variable(model, x >= 0)
#variable(model, y >= 0)
#constraint(model, 2x - 4 >= 0)
k = 0
while k <= 1
#objective(model, Max, 3x + k * y)
optimize!(model)
k = k + 0.2
end
end
run_code()

How to Plot a function of two variables in Julia with pyplot

I'm trying to plot a function of two variables with pyplot in Julia. The working starting-point is the following (found here at StackOverflow):
function f(z,t)
return z*t
end
z = linspace(0,5,11)
t = linspace(0,40,4)
for tval in t
plot(z, f(z, tval))
end
show()
This works right for me and is giving me exactly what I wanted:
a field of lines.
My own functions are as follows:
## needed functions ##
const gamma_0 = 6
const Ksch = 1.2
const Kver = 1.5
function Kvc(vc)
if vc <= 0
return 0
elseif vc < 20
return (100/vc)^0.1
elseif vc < 100
return 2.023/(vc^0.153)
elseif vc == 100
return 1
elseif vc > 100
return 1.380/(vc^0.07)
else
return 0
end
end
function Kgamma(gamma_t)
return 1-((gamma_t-gamma_0)/100)
end
function K(gamma_t, vc)
return Kvc(vc)*Kgamma(gamma_t)*Ksch*Kver
end
I've tried to plot them as follows:
i = linspace(0,45,10)
j = linspace(0,200,10)
for i_val in i
plot(i,K(i,j))
end
This gives me the following Error:
isless has no method matching isless(::Int64, ::Array{Float64,1})
while loading In[51], in expression starting on line 3
in Kvc at In[17]:2 in anonymous at no file:4
Obviously, my function cant deal with an array.
Next try:
i = linspace(0,200,11)
j = linspace(0,45,11)
for i_val in i
plot(i_val,map(K,i_val,j))
end
gives me a empty plot only with axes
Can anybody please give me a hint...
EDIT
A simpler example:
using PyPlot
function P(n,M)
return (M*n^3)/9550
end
M = linspace(1,5,5)
n = linspace(0,3000,3001)
for M_val in M
plot(n,P(n,M_val))
end
show()
Solution
OK, with your help I found this solution for the shortened example which works for me as intended:
function P(n,M)
result = Array(Float64, length(n))
for (idx, val) in enumerate(n)
result[idx] = (M*val^3)/9550
end
return result
end
n = linspace(0,3000,3001)
for M_val = 1:5
plot(n,P(n,M_val))
end
show()
This gives me what I wanted for this shortened example. The remainig question is: could it be done in a simpler more elegant way?
I'll try to apply it to the original example and post it when I'll succed.
I don't completely follow all the details of what you're trying to accomplish, but here are examples on how you can modify a couple of your functions so that they accept and return arrays:
function Kvc(vc)
result = Array(Float64, length(vc))
for (idx, val) in enumerate(vc)
if val <= 0
result[idx] = 0
elseif val < 20
result[idx] = (100/val)^0.1
elseif val < 100
result[idx] = 2.023/(val^0.153)
elseif val == 100
result[idx] = 1
elseif val > 100
result[idx] = 1.380/(val^0.07)
else
result[idx] = 0
end
end
return result
end
function Kgamma(gamma_t)
return ones(length(gamma_t))-((gamma_t - gamma_0)/100)
end
Also, for your loop, I think you probably want something like:
for i_val in i
plot(i_val,K(i_val,j))
end
rather than plot(i, K(i,j), as that would just print the same thing over and over.
< is defined for scalars. I think you need to broadcast it for arrays, i.e. use .<. Example:
julia> x = 2
2
julia> x < 3
true
julia> x < [3 4]
ERROR: MethodError: no method matching isless(::Int64, ::Array{Int64,2})
Closest candidates are:
isless(::Real, ::AbstractFloat)
isless(::Real, ::Real)
isless(::Integer, ::Char)
in <(::Int64, ::Array{Int64,2}) at .\operators.jl:54
in eval(::Module, ::Any) at .\boot.jl:234
in macro expansion at .\REPL.jl:92 [inlined]
in (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at .\event.jl:46
julia> x .< [3 4]
1x2 BitArray{2}:
true true

error loops, Gaussian elimination julia

the code below solves a linear system using Gauss method. when I run again, the error occurs:
LoadError: InexactError()
while loading In[176], in expression starting on line 4
in setindex! at array.jl:313
[inlined code] from In[176]:13
in anonymous at no file:12
Running more than 3 times the system is solved. what's up?
A = [4.1 -5 6.8;7.8 -8 -9;-17 4 1];
b = [1,2,3];
x = zeros(3);
m = 0;
al,ac = size(A)
for k= 1:(al-1)
#println("valor de k ",k)
for i = (k+1):al
#println("valor de i ",i)
m = A[i,k]/(A[k,k])
A[i,k] = 0
for j=(k+1):al
#println("valor de j",j)
A[i,j] = A[i,j] - m*A[k,j]
b[i]= b[i] - m*b[k]
end
end
end
x[al] = b[al]/(A[al,al])
for k = (al-1):-1:1
begin
s = 0;
for j = (k+1):al
s = s+A[k,j]*x[j]
end
x[k]=(b[k]-s)/A[k,k]
end
end
println(x)
The error is occurring mainly due to type mismatch between the variable and the value, consider the simple example,
julia> convert(Int64, 0.1)
ERROR: InexactError()
The InexactError() is thrown because it not possible to represent 0.1 as an integer.
julia>convert(Int64, 1.0)
1
As you can see the value 1.0 does not have problems being converted to Int64. So in your case since the type for array b is Array{Int64,1} and it sure cant hold floating point variables in due process and hence the error.
Considering #jeff 's inputs, it might be better to pakckthe code in a function,
julia>function f(A::Array{Float64,2}, b::Vector{Float64})
x = zeros(3);
m = 0.0;
al,ac = size(A)
for k= 1:(al-1)
#println("valor de k ",k)
for i = (k+1):al
#println("valor de i ",i)
m = A[i,k]/(A[k,k])
A[i,k] = 0
for j=(k+1):al
#println("valor de j",j)
A[i,j] = A[i,j] - m*A[k,j]
b[i]= b[i] - m*b[k]
end
end
end
x[al] = b[al]/(A[al,al])
for k = (al-1):-1:1
begin
s = 0;
for j = (k+1):al
s = s+A[k,j]*x[j]
end
x[k]=(b[k]-s)/A[k,k]
end
end
return x, A, b
end
f (generic function with 1 method)
julia> A = [4.1 -5 6.8;7.8 -8 -9;-17 4 1];
julia> b = [1,2,3.0];
This should result in the following transformation of matrix A into a upper triangular form,
julia> A
3×3 Array{Float64,2}:
4.1 -5.0 6.8
0.0 1.5122 -21.9366
0.0 0.0 -213.523

Given value p, return last element of sequence < p - Fortran

I have a sequence of numbers as follows:
1 , 1, 5, 13, 41, 121, 365, ....
The first two values are:
N(1) = 1 and N(2) = 1
As from 3rd value, N(i) = 2*N(i-1) + 3*N(i-2)
The issue I am facing with is: If I give an argument of p, it should return me the last values of the sequence < p (Using fortran77).
For instance, if p = 90, it should return the value 41.
a = 1
b = 1
while b < p:
c = 2 * b + 3 * a
a = b
b = c
return a
The Fortran equivalent is:
function fct(p) result(a)
integer, intent(in) :: p
integer :: a, b, c
a = 1
b = 1
do while (b < p)
c = 2 * b + 3 * a
a = b
b = c
enddo
end function
program test
integer :: fct
external fct
print *,fct(90)
end program
Assuming you already have the sequence in a variable lst, and p set,
max(filter(lambda x:x<=p, lst))
def get_last_element(p):
n1 = 1
n2 = 1
while True:
if n2 > p:
return n1
n1, n2 = n2, 2*n2 + 3 * n1
print(get_last_element(90))
I wrote a piece of code in Fortran 2003. I defined a type which has memory for two last parts of the sequence.The procedure is a recursive function. The type can be used standalone to get n-th part of the sequence or efficiently placed in a loop to find parts in a row (not necessarily beginning at 1) as it has memory of previous parts. (compiler: gfortran 4.8).
The type is defined in mymod.f90 file as
module mymod
implicit none
type seq_t
integer :: saved_i = 0, saved_val_i = 0, saved_val_i_1 = 0
contains
procedure :: getpart => getpart_seq
end type
contains
recursive function getpart_seq(this,i) result(r)
class(seq_t) :: this
integer, intent(in) :: i
integer :: r,r_1,r_2
if (i.eq.1.or.i.eq.2) then
r = 1
elseif(i.eq.this%saved_i) then
r = this%saved_val_i
elseif(i.eq.this%saved_i-1) then
r = this%saved_val_i_1
else
r_1 = this%getpart(i-1)
r_2 = this%getpart(i-2)
r = 2*r_1 + 3*r_2
this%saved_val_i_1 = r_1
end if
this%saved_i = i
this%saved_val_i = r
end function getpart_seq
end module mymod
The main program for the requested case is
program main
use mymod
implicit none
type (seq_t) :: seq
integer :: i,p,tmp_new,tmp_old,ans
! Set the threshold here
p = 90
! loop over parts of the sequence
i = 0
do
i = i + 1
tmp_new = seq%getpart(i)
print*,tmp_new
if (tmp_new>p) then
ans = tmp_old
exit
end if
tmp_old = tmp_new
end do
print*,"The last part of sequence less then",p," is equal to",ans
end program
The outcome is
1
1
5
13
41
121
The last part of sequence less then 90 is equal to 41.