# Las mates del GPS
(Solución extendida para STACK)

Tomado de: Kalman, D. (s.f.). An Undetermined Linear System for GPS. The Mathematical Association of America.
29/10/2024.

## Sistema de ecuaciones lineales (SEL)

S(P0,t0):=(P-P0).(P-P0)-(0.047*(t-t0))^2$
P:[x,y,z]$
ec1:S([1,2,0],19.9);
ec2:S([2,0,2],2.4);
ec3:S([1,1,1],32.6);
ec4:S([2,1,0],19.9);

## SEL resultante al restar ec1 a cada ecuación del sistema

### Solución

Ec1:expand(ec2-ec1);
Ec2:expand(ec3-ec1);
Ec3:expand(ec4-ec1);

### Maxicomandos para respuesta decimal del alumno (en STACK)

/*Ejemplo de respuesta del alumno*/
ans1:-4*z+4*y-2*x-0.08*t+3.86;

/*Variables necesarias cuando el alumno ingresa la respuesta con decimales*/
   /*Coeficientes de la respuesta correcta*/
   [a,b,c,d,e]:[coeff(Ec1,x,1),coeff(Ec1,y,1),coeff(Ec1,z,1),coeff(Ec1,t,1),coeff(coeff(coeff(coeff(Ec1,x,0),y,0),z,0),t,0)];
   /*Coeficientes de la respuesta del alumno*/
   [ans1_a,ans1_b,ans1_c,ans1_d,ans1_e]:[coeff(ans1,x,1),coeff(ans1,y,1),coeff(ans1,z,1),coeff(ans1,t,1),coeff(coeff(coeff(coeff(ans1,x,0),y,0),z,0),t,0)];
   /*Error absoluto*/
   error_abs:float(abs([a,b,c,d,e]-[ans1_a,ans1_b,ans1_c,ans1_d,ans1_e]));
   /*Tolerancia establecida*/
   tol:0.01;
   /*Verificación de que se satisface la tolerancia para los tres valores)*/
   test1:if(lhs(error_abs[1])<tol and lhs(error_abs[2])<tol and lhs(error_abs[3])<tol and lhs(error_abs[4])<tol and lhs(error_abs[5])<tol) then true else false;

/*Verificación de que se haya introducido una ecuación*/
   /*Convertimos a cadena la respuesta*/
   cadena:string(ans1);
   /*Creamos una lista a partir de la cadena y determinamos su 
   longitud*/
   longitud:length(charlist(cadena));
   /*Buscamos si los últimos dos caracteres son "=" y "0"*/
   
   test2:if is(equal(charlist(cadena)[longitud-2],"="))=true and 
   is(equal(charlist(cadena)[longitud],"0"))=true then true else 
   false;

test:if test1=true and test2=true then true else false;

if test1= false then mensaje1:"Tus cifras decimales no son lo suficientemente precisas. Emplea en cada caso redondeo a, por lo menos, tres cifras decimales. " else mensaje1:" ";
if test2=false then mensaje2:"Parece que no has igualado con cero." else mensaje2:" ";
mensaje:sconcat(mensaje1,mensaje2);

## Solución del SEL con t libre

### Solución

solns:solve([Ec1,Ec2,Ec3],[x,y,z]);

### Maxicomandos para respuesta decimal del alumno (en STACK)

/*Obtenemos la forma decimal de la solución*/
float(expand(solns));

/*Quitamos un par de corchetes a la solución arrojada previamente*/
float(expand(solns))[1];

/*Seleccionamos la solución de x*/
float(expand(solns))[1][1];

/*Extraemos en valor de la solución de x*/
rhs(float(expand(solns))[1][1]);

/*El escalar que multiplica a la variable libre t en la solución de x*/
coeff(rhs(float(expand(solns))[1][1]),t,1);

/*El término independiente en la solución de x*/
coeff(rhs(float(expand(solns))[1][1]),t,0);

/*Asignamos los dos elementos anteriores a las variables a y b*/
[a,b]:[coeff(rhs(float(expand(solns))[1][1]),t,1),coeff(rhs(float(expand(solns))[1][1]),t,0)];

/*Ejemplo de respuesta del alumno*/
ans1:5.40-0.09*t;

/*Asignamos los elementos de la respuesta del alumno a las variables ans1_a y ans1_b*/
[ans1_a,ans1_b]:[coeff(ans1,t,1),coeff(ans1,t,0)];

/*Determinamos el error absoluto entre la respuesta del alumno y la solución de Maxima */
error_abs:abs([a,b]-[ans1_a,ans1_b]);

/*Verificamos si el error absoluto en ambos casos satisface la tolerancia fijada*/
test:if error_abs[1]<tol and error_abs[2]<tol then true else false;
mensaje: if test=false then "Tus cifras decimales no son lo suficientemente precisas. Emplea en cada caso redondeo a, por lo menos, tres cifras decimales." else " ";

## Sustitución de x, y, z en ec1

### Solución 

Ec:expand(psubst([x=rhs(val[1]),y=rhs(val[2]),z=rhs(val[3])],ec1));

### Maxicomandos para respuesta decimal del alumno (en STACK)

/*Obtención de coeficientes de la solución*/
[a,b,c]:[coeff(Ec,t,2),coeff(Ec,t,1),coeff(Ec,t,0)];

/*Ejemplo de respuesta ingresada*/
ans1:0.020*t^2-1.881*t+43.556;

/*Obtención de coeficientes de la respuesta ingresada*/
[ans1_a,ans1_b,ans1_c]:[coeff(ans1,t,2),coeff(ans1,t,1),coeff(ans1,t,0)];

/*Cálculo del error absoluto cometido*/
error_abs:abs([a,b,c]-[ans1_a,ans1_b,ans1_c]);

/*Establecimiento de tolerancia*/
tol:0.001;

/*Verificación de que los tres valores satisfagan la tolerancia*/
test2:if (error_abs[1]<tol and error_abs[2]<tol and error_abs[3]<tol) then true else false;

### Maxicomandos para verificar que la respuesta decimal del alumno es ecuación

/*No podemos apoyarnos en rhs porque por default arroja cero en el segundo miembro:*/
is(rhs(ans1)=0);

/*Entonces, convertimos la respuesta en cadena*/
cadena:string(ans1);

/*Y luego creamos una lista con los caracteres de la cadena*/
lista:charlist(cadena);

/*Obtenemos la longitud de la lista*/
longitud:length(charlist(cadena));

/*Y verificamos que los últimos dos, separados por un espacio sean "=0"*/
test1:if is(equal(charlist(cadena)[longitud-2],"="))=true and 
   is(equal(charlist(cadena)[longitud],"0"))=true then true else 
   false;

/*De manera que el test global, es decir, que los decimales estén correctos y que se trate de una ecuación, es:*/
test:if test1=true and test2=true then true else false;

## Solución de ec1 (valores de t)

t_val:float(solve(Ec,t));

## Posibles puntos (x,y,z) de ubicación del GPS

x1:subst(rhs(t_val[1]),t,rhs(val[1]))$
y1:subst(rhs(t_val[1]),t,rhs(val[2]))$
z1:subst(rhs(t_val[1]),t,rhs(val[3]))$

P1:[x1,y1,z1];

x2:subst(rhs(t_val[2]),t,rhs(val[1]))$
y2:subst(rhs(t_val[2]),t,rhs(val[2]))$
z2:subst(rhs(t_val[2]),t,rhs(val[3]))$

P2:[x2,y2,z2];

## Identificación del punto correcto

L1:sqrt(P1.P1);

L2:sqrt(P2.P2);

if 1<L1 then print("El GPS se localiza en el punto: ",P2) else print("El GPS se localiza en el punto: ",P1)$