Hi everybody !
This follows the previous discussion “Is Julia lazy” about models of vector spaces for educational purposes. Many propositions, suggestions have been made, all of them interesting, a lot of links too. I couldn’t check everything into detail but I will, little by little.
So, what I propose now is to continue with ‘Affine Geometry’ what I did with ‘Linear Algebra’.
The question of knowing if ‘affine geometry’ exists at all is pertinent . Some world famous mathematicians (Jean Dieudonné among them) state that it’s just a re-formulation of linear algebra and it doesn’t deserve any additional chapter in textbooks.
Well it’s the point of view of a ‘pure’ mathematician, I have a great respect for Mr Dieudonné person and work but …
Point is an abstraction more easily accessible than vector. Introductory plan and 3D geometry at school begins with points, continues with lines, etc… vectors are usually introduced by mean of couples of points. I’m not sure it’s the best way to introduce the usual physical space for children, much better than a plain ℝ³.
In any case I wrote a full chapter dedicated to affine geometry following linear algebra for French students and joined a lot of Python 3.4 objects to illustrate concepts of point, massive point, barycenters, varieties , hyperplanes, equindependence, and so on.
Now it’s my purpose to add the same in Julia language.
So I must have a good start.
I decided to show examples for the ℝⁿ spaces but to allow exact calculations with ℚⁿ and Fⁿ as well where F is a primary finite p-field;
Here’s my first attempt :
using LinearAlgebra
using GaloisFields
const F = @GaloisField 5 #F will be the primary 𝔽₅=ℤ/5ℤ field
#point sans masse
struct Point{T <: Number}
C::Vector{T}
Point{T}(V::Vector{T}) where {T}=new{T}(V)
end
gettype(P::Point{T}) where {T}= T
Base.show(io::IO, P::Point{T}) where {T} = print(io,P.C)
Base.:-(A::Point{T},B::Point{T}) where {T}= A.C-B.C
Base.:+(A::Point{T},V) where {T}=Point{T}(A.C+V)
const RP=Point{Float64}
RP(V::Vector{Int64})=Point{Float64}(Vector{Float64}(V))
const QP=Point{Rational{Int64}}
const FP=Point{F}
#fin de la section
#point pondéré
struct MassPoint{T <: Number}
C::Vector{T}
M::T
MassPoint{T}(V::Vector{T},M::T) where {T}=new{T}(V,M)
end
const
Base.show(io::IO, MP::MassPoint{T}) where {T} = print(io,MP.C," M=",MP.M)
const RMP=MassPoint{Float64}
RMP(P::RP,M)=MassPoint{Float64}(P.C,Float64(M))
const QMP=MassPoint{Rational{Int64}}
const FMP=MassPoint{F}
#fin de la section
#systèmes de points
struct PointsSystem{P}
Pts::Vector{P}
PointsSystem{P}(V::Vector{P}) where {P}=new{P}(V)
end
Base.show(io::IO, S::PointsSystem{P}) where {P} = print(io,S.Pts)
const PSR=PointsSystem{RP}
const PSQ=PointsSystem{QP}
const PSF=PointsSystem{FP}
#fin de la section
#Systèmes de points pondérés
struct MassPointsSystem{P}
MassPts::Vector{P}
MassPointsSystem{P}(V::Vector{P}) where {P}=new{P}(V)
end
Base.show(io::IO, S::MassPointsSystem{P}) where {P} = print(io,S.MassPts)
const PMSR=MassPointsSystem{RMP}
const PMSQ=MassPointsSystem{QMP}
const PMSF=MassPointsSystem{FMP}
function barycentre(S::MassPointsSystem{P}) where P
L1=[p.M for p in S.MassPts]
L2=[p.C for p in S.MassPts]
m=reduce(+,L1)
s=inv(m)*(reduce(+,L2))
return P(s,m)
end
#fin de la définition
#systèmes de vecteurs
struct VectorsSystem{T}
Vectors::Vector{Vector{T}}
VectorsSystem{T}(L::Vector{Vector{T}}) where {T}=new{T}(L)
end
Base.show(io::IO, S::VectorsSystem{T}) where {T} = print(io,S.Vectors)
gettype(S::VectorsSystem{T}) where {T}=T
function Base.size(S::VectorsSystem{T},n) where {T}
if n==1
return length(S.Vectors)
elseif n==2
return length(S.Vectors[1])
else
return 0
end
end
function matrice(S::VectorsSystem{T}) where {T}
s1=size(S,1)
s2=size(S,2)
M=zeros(gettype(S),s1,s2)
for i in 1:s1, j in 1:s2
M[i,j]=S.Vectors[i][j]
end
return M
end
rang(S::VectorsSystem{T}) where {T} = rank(matrice(S))
const VSR=VectorsSystem{Float64}
const VSQ=VectorsSystem{Rational{Int64}}
const VSF=VectorsSystem{F}
VSR(V::Vector{Vector{Int64}})=VectorsSystem{Float64}(Vector{Vector{Float64}}(V))
and with another Jupyter Icell for testing :
#fonctions de test
function test_point()
P1=RP([1,2,3])
println(P1)
println(gettype(P1))
P2=QP([1//2,2,3])
println(P2)
P3=FP(F[4,5,6])
println(P3)
P4=RP([1.0,3,6])
println(P1-P4)
println(typeof(P1-P4))
println(P1+[1,1,1])
end
function test_pointssystem()
P1=RP([1,2,3])
P2=RP([1.0,3,6])
S=[P1,P2]
println(typeof(S))
S1=PSR(S)
end
function test_masspoint()
P1=QMP([1//2,3,1//3],2//1)
println(P1)
P2=RMP(RP([1.0,2,3]),3)
println(P2)
P3=FMP(F[4,5,6],F(3))
println(P3)
end
function test_masspointssystem()
P1=QMP([1//2,3,1//3],2//1)
P2=QMP([1//3,3,5//2],3//1)
S=[P1,P2]
S1=PMSQ(S)
println(S1)
println(barycentre(S1))
end
#fn de la section
function test_vectorssystem()
V1=[1,2,3]
V2=[4,5,6]
S=[V1,V2]
VS=VSR(S)
println(VS)
println(gettype(VS))
println(size(VS,1))
println(size(VS,2))
println(matrice(VS))
println(rang(VS))
end
function main()
test_point()
test_pointssystem()
test_masspoint()
test_masspointssystem()
test_vectorssystem()
end
main()
If you have some comments or suggestions for improvements, you’re welcome !