How can I mange the index of the loop in julia? - julia

It is the section of the Genetic algorithm that is coding in Julia. the code was wrote as follow:
popc= [individual(rand(0:1,nvar),[]) for i in 1:nc/4,j in 1:2];
for k=1:nc/4
#select firdt parent
i1=rand(1:npop);
p1=pop[i1];
#select second parent
i2=rand(1:npop);
if i1==i2
i2=rand(1:npop);
end
p2=pop[i2]
#apply crossover
m=singlepointcrossover(p1.position,p2.position);
append!(popc[k,1].position, m[1]);
append!(popc[k,2].position, m[2]);
end
function singlepointcrossover(x1,x2)
nvar=length(x1);
cutpoint=rand(1:nvar-1);
y1=append!(x1[1:cutpoint],x2[cutpoint+1:end]);
y2=append!(x2[1:cutpoint],x1[cutpoint+1:end]);
return y1,y2
end
but it has this error. would you pleas help me?. why is it happened?
ArgumentError: invalid index: 1.0
getindex(::Array{individual,2}, ::Float64, ::Int64) at abstractarray.jl:883
macro expansion at GA.juliarc.jl:87 [inlined]
anonymous at <missing>:?
include_string(::String, ::String) at loading.jl:522
include_string(::String, ::String, ::Int64) at eval.jl:30
include_string(::Module, ::String, ::String, ::Int64, ::Vararg{Int64,N} where N) at eval.jl:34
(::Atom.##102#107{String,Int64,String})() at eval.jl:82
withpath(::Atom.##102#107{String,Int64,String}, ::String) at utils.jl:30
withpath(::Function, ::String) at eval.jl:38
hideprompt(::Atom.##101#106{String,Int64,String}) at repl.jl:67
macro expansion at eval.jl:80 [inlined]
(::Atom.##100#105{Dict{String,Any}})() at task.jl:80

The problem is / operator gives floating-point results for integer arguments and floating point results cannot be used for indexing an Array. You can index an Array with an Integer.
/(x, y)
Right division operator: multiplication of x by the inverse of y on the
right. Gives floating-point results for integer arguments.
for k=1:nc/4
1:nc/4 will create a Float64 range and k, a Float64, is later used in indexing in your code at append!(popc[k,1].position, m[1]);. You should, therefore, make k an Integer.
If nc is an integer, you should use Euclidean division with div(nc, 4) or simply nc ÷ 4, or bit shift operators nc >> 2 and nc >>> 2 (for Euclidean division by 2^n you should shift by n). They will all give integer results for integer arguments.
If nc itself is a floating-point number, you should probably use one of the options pointed out by #Colin T Bowers.
popc= [individual(rand(0:1,nvar),[]) for i in 1:nc/4,j in 1:2];
You do not have an error on the first line, since you do not use i for indexing here. It is still better to replace nc/4 with one of the options I listed above.

Fractions in Julia always output Float64, even if the answer can be exactly converted to Int.
Importantly, in your case, note that Int can be used to index arrays, but Float64 cannot. So you'll need to adjust:
for k=1:nc/2
to
for k=1:Int(nc/2)
so that your index k is will be of type Int, not Float64.
If nc is not guaranteed to be an even integer, then you may need to use floor(Int, nc/2) or ceil(Int, nc/2), depending on which is more appropriate.

Related

Difference between character and string when constructing a 1-d array of the specified type

I am confusing with when constructing a 1-d array of the specified type by usung getindex(type[, elements...]).
Of course, that I can convert Int 8 when the element are Int
getindex(Int8, 1, 2)
2-element Vector{Int8}:
1
2
Even when the element are character format, I can convert it to Int8 :
getindex(Int8, '1', '2')
2-element Vector{Int8}:
49
50
However, I can not convert when the element are in string format.
getindex(Int8, "1", "2")
and, raise the following error :
MethodError: Cannot `convert` an object of type String to an object of type Int8
Closest candidates are:
convert(::Type{T}, ::Ptr) where T<:Integer at pointer.jl:23
convert(::Type{IT}, ::GeometryBasics.OffsetInteger) where IT<:Integer at C:\Users\Admin\.julia\packages\GeometryBasics\WMp6v\src\offsetintegers.jl:40
convert(::Type{T}, ::SentinelArrays.ChainedVectorIndex) where T<:Union{Signed, Unsigned} at C:\Users\CARVI\.julia\packages\SentinelArrays\tV9lH\src\chainedvector.jl:209
...
Stacktrace:
[1] setindex!(A::Vector{Int8}, x::String, i1::Int64)
# Base .\array.jl:839
[2] getindex(#unused#::Type{Int8}, x::String, y::String)
# Base .\array.jl:393
[3] top-level scope
# In[35]:1
[4] eval
# .\boot.jl:360 [inlined]
[5] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
# Base .\loading.jl:1116
Why getindex() allow character element to convert to different format (like character -> Int8), but string ?
First of all, that's a rather weird way of writing array literals: getindex(T, xs...) is usually written as T[xs...].
However, the error already quite clearly tells you what went wrong:
Cannot convert an object of type String to an object of type Int8
How do you imagine a general conversion from String to Int8 to look like? What 8-bit integer should correspond to the string "slkdfjls", for example? A string is after all a pretty much arbitrary sequence of bytes. And contrary to your expectation, Julia does not make an attempt to do any parsing of the contained value (for that, use parse(Int8, "1").
Characters on the other hand represent (if valid) single UTF-8 code points, and it is meaningful to reinterpret their fixed amount of bytes as a number:
julia> convert(Int16, '†')
8224
julia> convert(Int8, '1') # certainly not Int8(1)!
49
The conversion is already borderline meaningful when the value exceeds the range of the target type:
julia> convert(Int8, '†')
ERROR: InexactError: trunc(Int8, 8224)
...
UTF-8 characters that happen to be representable by only one byte can be losslessly converted to Int8; this covers all of ASCII. Above that, an error is raised. This is no different from convert(Int8, Int32(something)).

Why does Julia fails to solve linear system systematically?

The problem Ax=b for square A is solved by the \ function. With that in mind, I've tried to do the following:
A = rand(1:4,3,3)
x = fill(1.0, 3)
b = A * x
A\b
For some reason, the code seems to works at times. But sometimes it returns me the following error:
LinearAlgebra.SingularException(3)
Stacktrace:
[1] checknonsingular
# /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/LinearAlgebra/src/factorization.jl:19 [inlined]
[2] checknonsingular
# /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/LinearAlgebra/src/factorization.jl:21 [inlined]
[3] #lu!#136
# /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/LinearAlgebra/src/lu.jl:85 [inlined]
[4] #lu#140
# /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/LinearAlgebra/src/lu.jl:273 [inlined]
[5] lu (repeats 2 times)
# /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/LinearAlgebra/src/lu.jl:272 [inlined]
[6] \(A::Matrix{Int64}, B::Vector{Float64})
# LinearAlgebra /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/LinearAlgebra/src/generic.jl:1136
[7] top-level scope
# In[208]:4
[8] eval
# ./boot.jl:360 [inlined]
[9] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
# Base ./loading.jl:1116
So, I tried to understand what is happening, and executed the code 10000000 times and found out that it failed 10% of the times it was executed.
using Printf
i = 0
test = 10000000
for x in 1:test
try
A = rand(1:4,3,3)
x = fill(1.0, 3)
b = A * x
A\b
catch
i = i+1
end
end
fail_percentage = (i/test)*100
#printf "this code has failed in %.2f%%" fail_percentage
Can someone explain me what is happening here?
The error is explicit: LinearAlgebra.SingularException. This is not a failure of Julia, but a property of a system of equations.
There is no single solution if the matrix A is singular - either an infinite amount of solutions if the system is homogeneous, or none in the general case. Seems you have empirically calculated the probability of generating a singular system using the properties you tested (dimensions of A and x, x filled with 1s, A filled between 1 and 4).
In case, like OP, you are looking to skip singular matrices, you need to ensure determinant of A is not 0. You can either use the built in function to check and skip such matrices, or generate them by noting that the determinant is itself an equation, and so, say for your 3x3 example with no 0 entries, you choose 8 numbers, you can calculate what the 9th one cannot be to ensure the determinant is non-zero. If you allow for 0s you need to check all possibilities.

Return values in Prolog

I'm supposed to write a predicate that does some math stuff. But I don't know how to pass numbers or return numbers.
Maybe you can give me an example?
Let's say a predicate divide/2 that takes two numbers a and b and returns a/b.
Yes, you pass numbers in in some arguments, and you get the result back in some other argument(s) (usually last). For example
divide( N, D, R) :-
R is N / D.
Trying:
112 ?- divide(100,5,X).
X = 20.
113 ?- divide(100,7,X).
X = 14.285714285714286.
Now, this predicate is divide/3, because it has three arguments: two for inputs and one for the output "information flow".
This is a simplified, restricted version of what a Prolog predicate can do. Which is, to not be that uni-directional.
I guess "return" is a vague term. Expression languages have expressions e-value-ated so a function's last expression's value becomes that function's "return" value; Prolog does not do that. But command-oriented languages return values by putting them into some special register. That's not much different conceptually from Prolog putting some value into some logvar.
Of course unification is more complex, and more versatile. But still, functions are relations too. Predicates "return" values by successfully unifying their arguments with them, or fail to do so, as shown in the other answer.
Prolog is all about unifying variables. Predicates don't return values, they just succeed or fail.
Typically when a predicate is expected to produce values based on some of the arguments then the left-most arguments are inputs and the right-most are the outputs. However, many predicates work with allowing any argument to be an input and any to be a output.
Here's an example for multiply showing how it is used to perform divide.
multiply(X,Y,Z) :- number(X),number(Y),Z is X * Y.
multiply(X,Y,Z) :- number(X),number(Z),X \= 0,Y is Z / X.
multiply(X,Y,Z) :- number(Y),number(Z),Y \= 0,X is Z / Y.
Now I can query it like this:
?- multiply(5,9,X).
X = 45 .
But I can easily do divide:
?- multiply(5,X,9).
X = 1.8 .
It even fails if I try to do a division by 0:
?- multiply(X,0,9).
false.
Here's another approach. So let's say you have a list [22,24,34,66] and you want to divide each answer by the number 2. First we have the base predicate where if the list is empty and the number is zero so cut. Cut means to come out of the program or just stop don't go to the further predicates. The next predicate checks each Head of the list and divides it by the number A, meaning (2). And then we simply print the Answer. In order for it to go through each element of the list we send back the Tail [24,34,66] to redo the steps. So for the next step 24 becomes the Head and the remaining digits [34,66] become the Tail.
divideList([],0,0):-!.
divideList([H|T],A,Answer):-
Answer is H//A,
writeln(Answer),
divideList(T,A,_).
?- divideList([22,24,34,66],2,L).
OUTPUT:
11
12
17
33
Another simpler approach:
divideList([],_,[]).
divideList([H|T],A,[H1|L]):-
H1 is H//A,!,
divideList(T,A,L).
?-divideList([22,4,56,38],2,Answer).
Answer = [11, 2, 28, 19]

Calculating an *integer* binomial coefficient in R

The number of ways of choosing k objects from n, i.e. the binomial coefficient n!/(k!(n-k)!), is an integer when n and k are integers. How can I calculate this guaranteeing that the result is both correct and of integer type? The choose function returns a double even with integer arguments:
> typeof(choose(4L, 2L))
[1] "double"
as does manual calculation, e.g. n-choose-2 = n(n-1)/2
typeof((4L * (4L - 1L)) / 2L)
[1] "double"
Of course I can coerce to an integer with as.integer() but I'm nervous about machine precision:
> as.integer(3.999999999999999)
[1] 3
> as.integer(3.9999999999999999)
[1] 4
round() (with the default digits=0) rounds to the nearest integer, but returns a value of double type. If I could be certain that supplying an integer stored in double format to as.integer(round(...)) is guaranteed to round to the correct integer, never being tripped up by machine precision, then as.integer(round(choose(n, k))) would be acceptable. Is this the case? Or is there an alternative to choose() that will return an integer for integer arguments?
One way is to use the VeryLargeIntegers package. The function is:
binom(n, k)
e.g. binom(1000,50) or even binom(10000000,50)
It's wise to learn how to make very large integers too cf: as.vli('1234567890123456789')
https://www.rdocumentation.org/packages/VeryLargeIntegers/versions/0.1.8/topics/06.%20Binomial%20coefficients
The package is not completely bug-free, and larger computations will take a while.
Dr Jo.
Do not worry about the conversion, the machine precision will not be a problem. L after the integer is definitely not a double, [R] has a weird syntax, it is definitely not a long value and cannot have a decimal point.

How to store currency values and format their output in julia-lang?

At the moment I'm storing currency amounts in type ::Float64, the majoirty of amounts are in the billions to hundreds-of-millions in differing currency units. In other use-cases I also have it that currency values are necessary to be kept in tens-of-thousands of a unit of currency, e.g 0.7564
However, given the rounding errors associated double-precision-floating numbers, should I be converting everything into fixed-point integers for storing the currency units?
Secondly, how do you format the string output of an currency unit, and allow for the relevant currency symbol to be displayed?
Secondly, are their any packages that provide a "currency" data type that would be safe to use?
Here's a really basic starting point for storing currency and displaying it:
immutable Currency
symbol::Symbol
amount::Int
end
function Base.show(io::IO, c::Currency)
print(io, c.symbol, c.amount/100)
end
Currency(:£, 1275) #=> £12.75
This stores the currency as an exact value in pennies, so no rounding error, but displays it in the usual way. You could of course easily parameterise on the number of decimal places to store. I can't answer as to whether you should use fixed point numbers like this, but they'll certainly be more accurate for addition, subtraction and multiplication.
As for prior art, a quick google for "currency.jl" turned up this – it looks way out of date but might be useful as a reference.
You should definitely not be using floating point numbers for currencies — you should define your own fixed-point numeric type, and use that. The Julia manual has a good tutorial about defining a new numeric type in the chapter about conversions and promotions.
Let's assume that you will only ever need two digits after the decimal point — never mind pounds, shillings and pence. Your new type will look something like
immutable Monetary <: Number
hundredths :: Int64
end
Monetary(ones :: Int64, hundredths :: Int64) = Monetary(hundredths + 100 * ones)
Obviously, you'll want to be able to display monetary mounts:
Base.show(io :: IO, x :: Monetary) =
#printf(io, "%lld.%02lld", fld(x.hundredths, 100), mod(x.hundredths, 100))
you'll also want to be able to add and subtract them:
+(x :: Monetary, y :: Monetary) = Monetary(x.hundredths + y.hundredths)
-(x :: Monetary, y :: Monetary) = Monetary(x.hundredths - y.hundredths)
On the other hand, you'll never want to multiply them ­— but multiplying a monetary sum by an integer is fine:
*(x :: Bool, y :: Monetary) = ifelse(x, y, Monetary(0))
*(x :: Monetary, y :: Bool) = ifelse(y, x, Monetary(0))
*(x :: Integer, y :: Monetary) = Monetary(x * y.hundredths)
*(x :: Monetary, y :: Integer) = Monetary(x.hundredths * y)
Finally, if you mix integers with monetary sums in an expression, it's fine to convert everything to monetary values:
Base.convert(::Type{Monetary}, x :: Int64) = Monetary(x, 0)
Base.promote_rule(::Type{Monetary}, ::Type{Int64}) = Monetary
This is good enough to perform useful computations:
julia> Scrooge.Monetary(30,5) * 3 + 12
102.15
but will reliably catch incorrect operations:
julia> Scrooge.Monetary(30,5) * 3.5
ERROR: no promotion exists for Monetary and Float64
in * at ./promotion.jl:159
Currencies.jl provides an interface for working with currencies:
using Currencies
#usingcurrencies USD
format(1.23USD + 4.56USD, styles=[:us, :brief]) # $5.79
It supports type-safe arithmetic, currency conversion, and flexible pretty-printing.
Disclaimer: I am the maintainer of Currencies.jl.

Resources