Hi everybody
Right now I use Julia for maths educational purpose. There’s a lot of subjects but I concentrate on linear algebra. Representation of real vector spaces by Floats of any kind isn’t convenient because some determinants which should be null are actually epsilon, and so on.
Exact computation occurs with the field of rationals or any finite field like Fp=Z/pZ where p is a prime number. These cases are better suited for teaching.
My question is contained in the following code . Instructions which lead to errors have been commented . if this matter is of any interest for you please uncomment and check by yourself.
Till now I find solutions for every case and I’m not stuck nowhere…
I simply would like to understand why, sometimes Julia forces me to do some extra-job:
Thanks for reading !
#generates model for field Z/pZ with prime integer p
macro Z(p)
quote
struct F_p
x::Int
function F_p(n::Int)#internal constructor
r=n % $p
if r>= 0
return new(r) # possible to use keyword 'new' only here
else
return new($p+r) # because of the special definition of remainder in Julia
end
end
end
end
end
@Z 5 # calling this macro with parameter 5 realizes construction of F_p=Z/5Z
#overloading standard operators, just a minimum for illustration of my request
Base.:+(k::F_p,h::F_p) = F_p(k.x+h.x)
Base.:*(k::F_p,h::F_p) = F_p(k.x*h.x)
Base.:-(k::F_p)=F_p(-k.x)
Base.:-(k::F_p,h::F_p)=F_p(k.x-h.x)
#basic use
K=[F_p(i) for i in 0:4] #the elements of the field
println(typeof(K)) # appears as a vector which can be used as an iterator
#the following is just cosmetic sugar
prettyprint(k::F_p)=print(k.x)
prettyprint(V::Vector{F_p})= map(k->print(k.x," "),V)
#let's give it a try
prettyprint(K);print("\n")
#so K is a vector with coordinates in Z/5Z
# since Julia knows how to add in F5 it can compute K+K
#let's try
prettyprint(K+K);print("\n")# result is correct
#the following is quite logically refused because Julia doesn't know how to multiply an integer by an element of Z/5Z
#prettyprint(2K)
#so try something else
two=F_p(2)
println(two) #just to make sure...
#Again the following
#println(2*two)
#fails !!!
#Julia pretends not to know how to multiply an int by a F_p which is true,
#but C++ has more imagination finding a constructor taking an int as an argument
#it will automatically promote an int to a F_p and apply internal F_p multiplication
# too difficult for Julia ?
#Nevertheless normally the following has meaning
#two*K
#but Julia answers that he doesn't know how to multiply a scalar by a vector although he does it very well, coordinates by coordinate for usual types Int, Float and so on.
#let's see an example with rationals
println(1//2*[0//1,1//1,2//1,3//1,4//1])
#so we must explain by a new overload
Base.:*(k::F_p,V::Vector{F_p}) = [k*h for h in V]
#and now
prettyprint(two*K); println("\n")
#gives exactly what was expected K+K
#isn't it possible to implement scalar multiplication of a vector with coordinates in any field ?
#and what about automatic promotion ?