This project is an interactive implementation of several elementary algorithms from my linear algebra class. The goal is not to replace the theory, but to make the computations visible: you choose vectors or points in the plane, the app reconstructs the corresponding map, classifies it, shows the canonical form, and generates a detailed step-by-step report.
The user interface and generated reports are written in Spanish, because the project follows the notation and language of the course. This README is written in English for easier technical maintenance.
The app studies two related problems in
In the linear tab, the user chooses a basis
The algorithm is:
- Build the basis matrix $$ B=[b_1\ b_2] $$ and the image matrix $$ Y=[T(b_1)\ T(b_2)]. $$
- Check that
$B$ is invertible by computing$\det(B)$ . - Recover the linear map: $$ A=YB^{-1}. $$
- Compute the trace of
$A$ , the determinant of$A$ , and the discriminant of the characteristic polynomial. - Classify the real canonical form:
- two distinct real eigenvalues,
- a scalar matrix,
- a Jordan block,
- or a real block associated with a complex conjugate pair.
- Build an adapted basis and verify the reduction with $$ P^{-1}AP=J. $$
In the affine tab, the user chooses three source points
The algorithm is:
- Check affine independence by computing the oriented double area of the triangle
$(p_0,p_1,p_2)$ . - Pass from points to direction vectors: $$ S=[p_1-p_0\ p_2-p_0], \qquad T=[q_1-q_0\ q_2-q_0]. $$
- Recover the linear part: $$ A=TS^{-1}. $$
- Recover the translation using
$F(p_0)=q_0$ : $$ b=q_0-Ap_0. $$ - Study fixed points by solving $$ (I-A)x=b. $$
- Choose an adapted affine reference and verify the normal form with homogeneous matrices: $$ C^{-1}H_FC=H_{\mathrm{can}}. $$
The affine classification distinguishes cases with a unique fixed point, a line of fixed points, all points fixed, pure translations, and residual translations that cannot be removed by changing the origin.
Install dependencies:
npm installStart the local development version:
npm run devThis starts two processes:
- Vite frontend:
http://localhost:5173/ - Express backend:
http://localhost:4174/
Then open the Vite URL in your browser.
In the app:
- Choose either the
LinealorAfintab. - Drag points/vectors in the coordinate plane, or edit their coordinates in the side panel.
- Read the live classification and canonical form.
- Use
Restablecer ejemploto return to the default example. - Use the report button to generate a detailed explanation of the computation.
The project has two report paths.
When the Express backend is available, the report button asks the backend to build a LaTeX document and compile it into a PDF.
Endpoints:
POST /api/linear-pdfPOST /api/affine-pdfGET /api/health
The backend compiles with pdflatex, so a local LaTeX installation is required for true PDF generation. If pdflatex is not installed, the app can still run, but server-side PDF generation will fail.
When the backend is not available, the app opens a standalone printable report page instead. This is the mode used by static deployments such as GitHub Pages.
The static report:
- renders mathematics with KaTeX,
- stores the report data temporarily in
localStorage, - can be printed or saved as PDF from the browser,
- includes a
.texdownload when enough valid data are available.
In this repository, "local version" means running the app on your machine with Node.js. "Global version" means the deployed static web version, for example on GitHub Pages.
Run with:
npm run devor build and serve through Express:
npm startThe local version can use the Express API. If pdflatex is installed, it can generate deterministic PDF files directly from LaTeX.
Use the local version when:
- you are developing the app,
- you want server-side PDF generation,
- you need to test API endpoints,
- you want the closest version to a self-hosted deployment.
Build with:
npm run buildThe output is written to dist/ and can be hosted as static files. Static hosting cannot run the Express server, so the PDF API is not available there. The app therefore falls back to the printable HTML report flow.
Use the global version when:
- you want a public webpage that does not require a backend,
- you are deploying to GitHub Pages or another static host,
- browser print-to-PDF is enough,
- downloading the generated
.texsource is acceptable.
If the app is deployed under a subpath, set:
VITE_BASE_PATH=/your-subpath/During builds, the Vite base path is also derived from GITHUB_REPOSITORY when available.
It is possible to host the frontend statically but send PDF requests to a separate backend. Set:
VITE_PDF_API_BASE_URL=https://your-api.example.comWhen this variable is present, the frontend calls that server for /api/linear-pdf and /api/affine-pdf instead of relying on same-origin API routes.
src/
App.tsx Main interactive UI
components/
CartesianPlane.tsx SVG coordinate plane and draggable objects
PrintableReportPage.tsx Printable report page
lib/
math2d.ts Core 2D linear and affine algorithms
symbolicMath.ts Rational and radical formatting helpers
reportContent.ts Browser-rendered report content
reportTex.ts LaTeX report generation
reportExport.ts Report storage and export flow
server.mjs Express API and server-side PDF compilation
vite.config.ts Vite configuration and base path handling
npm run devRuns frontend and backend together.
npm run dev:clientRuns only the Vite frontend.
npm run dev:serverRuns only the Express backend.
npm run buildType-checks and builds the production static assets.
npm run previewBuilds the app and serves dist/ through Express.
npm startSame practical use as npm run preview: build, then serve with Express.
npm run lintRuns ESLint.
- Node.js and npm.
- A modern browser.
- Optional: a LaTeX distribution with
pdflatexfor local server-side PDF generation.
The app intentionally keeps the computations elementary. Most formulas shown in the reports are the same formulas one would write by hand:
- matrix reconstruction from images of a basis,
- determinant tests for independence,
- characteristic polynomial and discriminant,
- eigenvectors and generalized eigenvectors,
- fixed point equation for affine maps,
- homogeneous coordinates for affine conjugation.
That makes the project useful as a companion to the class: students can modify examples, see how each number changes, and compare the final canonical form with the intermediate calculations.
This project is licensed under the GNU General Public License v3.0 (GPL-3.0-only).
Copyright (C) 2026 Pablo Portilla.
Distributed without any warranty. See LICENSE for details.