/*************************************************************************************************************************************/
/* */
/* R E C H E R C H E D E P O I N T S R A T I O N N E L S S U R U N E C O U R B E E L L I P T I Q U E : */
/* */
/* */
/* Author of '$xtc/CourbesElliptiques.11$c' : */
/* */
/* Jean-Francois COLONNA (LACTAMME, 20211123141952). */
/* */
/*************************************************************************************************************************************/
#include "INCLUDES.01.I"
extern double floor();
#include "CourbesElliptiques.01.I"
/* Definition du polynome : */
/* */
/* 3 2 1 0 */
/* A.x + B.x + C.x + D.x */
/* */
#define XPN \
(-1.0)
#define XPD \
(+1.0)
#define YPN \
(+1.0)
#define YPD \
(+1.0)
/* Point rationnel 'P' = {-1/1,+1/1} ('v $xtc/CourbesElliptiques.01$c'). */
#define XQN \
(+1.0)
#define XQD \
(+4.0)
#define YQN \
(+7.0)
#define YQD \
(+8.0)
/* Point rationnel 'Q' = {+1/4,+7/8} ('v $xtc/CourbesElliptiques.01$c'). */
#define EPSILON \
0.000001
#define CHECK_POINT(x,y) \
{ \
double Gdroite=y; \
double Ddroite=PQa*x+PQb; \
double Gcourbe=y*y; \
double Dcourbe=A*(x*x*x)+B*(x*x)+C*(x)+D; \
\
printf("Le point {%+f,%+f} ",x,y); \
\
if (ABSO(Gdroite-Ddroite) < EPSILON) \
{ \
printf("appartient a la droite"); \
} \
else \
{ \
printf("n'appartient pas a la droite %f.x+%f (%f#%f)",PQa,PQb,Gdroite,Ddroite); \
} \
\
printf(" et "); \
\
if (ABSO(Gcourbe-Dcourbe) < EPSILON) \
{ \
printf("appartient a la courbe elliptique"); \
} \
else \
{ \
printf("n'appartient pas a la courbe elliptique (%f#%f)",Gcourbe,Dcourbe); \
} \
\
printf(".\n"); \
}
#define PLUS_GRAND_DENOMINATEUR_POSSIBLE \
1000000
int An,Ad;
ApproximationRationnelle(x)
double x;
{
int iterer=VRAI;
double a0=1,a1,a;
double b0=0,b1=1,b=1;
double en,q;
a1=floor(x);
en=x-a1;
printf("\nApproximations rationnelles de %f :\n\n",x);
while (iterer == VRAI)
{
q=floor(1/en);
en=(1/en)-q;
a=(q*a1)+a0;
b=(q*b1)+b0;
if (b <= PLUS_GRAND_DENOMINATEUR_POSSIBLE)
{
An=a;
Ad=b;
printf("%d/%d\n",An,Ad);
a0=a1;
b0=b1;
a1=a;
b1=b;
}
else
{
iterer=FAUX;
printf("\nsoit en flottant : %f\n",a/b);
}
}
}
void main()
{
double PQa,PQb;
/* Definition de la droite 'PQ'. */
double XR,YR;
int XRn,XRd,YRn,YRd;
/* Coordonnees du troisieme point d'intersection 'R'. */
PQa=((YQN/YQD)-(YPN/YPD))/((XQN/XQD)-(XPN/XPD));
PQb=(YPN/YPD)-(PQa*(XPN/XPD));
XR=-((D-(PQb*PQb))/((XPN/XPD)*(XQN/XQD)));
YR=PQa*XR+PQb;
/* Equation de la droite 'PQ' : */
/* */
/* y = PQa.x + PQb */
/* */
/* Equation de la courbe elliptique : */
/* */
/* 2 3 2 1 0 */
/* y = A.x + B.x + C.x + D.x */
/* */
/* On reporte l'equation de la droite 'PQ' dans celle de la courbe elliptique : */
/* */
/* 2 3 2 1 0 */
/* (PQa.x + PQb) = A.x + B.x + C.x + D.x */
/* */
/* 3 2 2 1 2 0 */
/* [1] A.x + (B-PQa ).x + (C-2.PQa.PQb).x + (D-PQb ).x = 0 */
/* */
/* On cherche le troisieme point d'intersection 'R' en prolongement de 'P' et 'Q'. Les */
/* abscisses sont solutions de l'equation du troisieme degre : */
/* */
/* (x-XP).(x-XQ).(x-XR) = 0 */
/* */
/* soit : */
/* */
/* 3 2 1 0 */
/* [2] x - (XP+XQ+XR).x + [(XP.XQ)+(XQ.XR)+(XR.XP)].x - (XP.XQ.XR).x = 0 */
/* */
/* En identifiant [1] et [2], on obtient par exemple : */
/* */
/* 2 */
/* -(XP.XQ.XR) = (D-PQb ) */
/* */
/* d'ou : */
/* */
/* 2 */
/* -(D-PQb ) */
/* XR = ----------- */
/* XP.XQ */
/* */
/* puis enfin : */
/* */
/* YR = PQa.XR + PQb */
/* */
printf("XR=%f YR=%f\n",XR,YR);
ApproximationRationnelle(XR);
XRn=An;
XRd=Ad;
ApproximationRationnelle(YR);
YRn=An;
YRd=Ad;
printf("\n");
CHECK_POINT(XPN/XPD,YPN/YPD);
CHECK_POINT(XQN/XQD,YQN/YQD);
CHECK_POINT(((double)XRn)/((double)XRd),((double)YRn)/((double)YRd));
}