/** * SystemSolver — System input, method selector, step-by-step solution display */ const SystemSolver = (() => { let container = null; let currentSize = 3; let currentMethod = 'gauss'; function render() { container.innerHTML = `

Matriz de coeficientes | Términos independientes

`; renderGrid(); } function renderGrid() { const gridContainer = document.getElementById('systemGridContainer'); if (!gridContainer) return; const n = currentSize; // n columns for coefficients + divider + 1 column for constants let html = `
`; for (let i = 0; i < n; i++) { for (let j = 0; j < n; j++) { html += ``; } // Divider column (one per row, but we only need 1 actual divider) if (i === 0) { html += `
`; } else { // Empty cell for grid alignment — no, the divider spans all rows } html += ``; } html += '
'; gridContainer.innerHTML = html; } function getSystem() { const n = currentSize; const A = []; const b = []; let hasError = false; for (let i = 0; i < n; i++) { const row = []; for (let j = 0; j < n; j++) { const cell = document.getElementById(`sys-coeff-${i}-${j}`); if (!cell) return null; const val = cell.value.trim(); if (val === '') { cell.classList.add('matrix-grid__cell--error'); hasError = true; } else { cell.classList.remove('matrix-grid__cell--error'); } const num = parseFloat(val); if (isNaN(num)) { cell.classList.add('matrix-grid__cell--error'); hasError = true; } row.push(num || 0); } A.push(row); const bCell = document.getElementById(`sys-const-${i}`); if (!bCell) return null; const bVal = bCell.value.trim(); if (bVal === '') { bCell.classList.add('matrix-grid__cell--error'); hasError = true; } else { bCell.classList.remove('matrix-grid__cell--error'); } b.push(parseFloat(bVal) || 0); } if (hasError) { showError('Completá todas las celdas con valores numéricos.'); return null; } hideError(); return { A, b }; } function showError(msg) { const el = document.getElementById('systemError'); if (el) { el.textContent = msg; el.classList.add('error-message--visible'); } } function hideError() { const el = document.getElementById('systemError'); if (el) el.classList.remove('error-message--visible'); } function showResult(title, value, steps) { const resultEl = document.getElementById('systemResult'); const titleEl = document.getElementById('resultTitle'); const valueEl = document.getElementById('resultValue'); const stepsEl = document.getElementById('resultSteps'); titleEl.textContent = title; resultEl.classList.add('matrix-result--visible'); // Render value if (typeof value === 'object' && value !== null && value.type) { // Classification result let text = ''; if (value.type === 'CD') text = 'Compatible Determinado'; else if (value.type === 'CI') text = `Compatible Indeterminado (${value.freeVars || '?'} parámetros libres)`; else if (value.type === 'SI') text = 'Sistema Incompatible'; else if (value.type === 'indeterminate') text = 'Compatible Indeterminado'; else if (value.type === 'trivial') text = 'Solución trivial'; valueEl.textContent = text; if (value.solution) { const solDiv = document.createElement('div'); solDiv.style.marginTop = '8px'; if (typeof KatexRenderer !== 'undefined') { KatexRenderer.renderDisplay(solDiv, 'x = ' + MathEngine.vecToLatex(value.solution)); } else { solDiv.textContent = 'x = ' + JSON.stringify(value.solution); } valueEl.appendChild(solDiv); } } else if (Array.isArray(value)) { if (typeof KatexRenderer !== 'undefined') { KatexRenderer.renderDisplay(valueEl, 'x = ' + MathEngine.vecToLatex(value)); } else { valueEl.textContent = 'x = ' + JSON.stringify(value); } } else { valueEl.textContent = String(value); } // Render steps stepsEl.innerHTML = ''; if (steps && steps.length > 0) { const ol = document.createElement('ol'); ol.className = 'matrix-result__steps'; steps.forEach((step) => { const li = document.createElement('li'); li.className = 'matrix-result__step'; const descDiv = document.createElement('div'); descDiv.textContent = step.desc; const exprDiv = document.createElement('div'); if (typeof KatexRenderer !== 'undefined' && (step.latex || step.expression)) { KatexRenderer.renderDisplay(exprDiv, step.latex || step.expression); } else { exprDiv.textContent = step.latex || step.expression || ''; } li.appendChild(descDiv); li.appendChild(exprDiv); ol.appendChild(li); }); stepsEl.appendChild(ol); } } function solve() { const system = getSystem(); if (!system) return; const { A, b } = system; let result; try { const ME = MathEngine; switch (currentMethod) { case 'gauss': result = ME.system.gaussElimination(A, b); break; case 'gauss-jordan': result = ME.system.gaussJordan(A, b); break; case 'cramer': result = ME.system.cramer(A, b); break; case 'rouche-frobenius': result = ME.system.roucheFrobenius(A, b); break; default: showError('Método no reconocido.'); return; } if (result.error) { showError(result.error); // Still show steps if (result.steps && result.steps.length > 0) { showResult('Clasificación', null, result.steps); } return; } const titles = { 'gauss': 'Eliminación de Gauss', 'gauss-jordan': 'Gauss-Jordan', 'cramer': 'Regla de Cramer', 'rouche-frobenius': 'Rouché-Frobenius' }; showResult(titles[currentMethod] || currentMethod, result.value, result.steps); } catch (e) { showError('Error: ' + e.message); } } function clearGrid() { const n = currentSize; for (let i = 0; i < n; i++) { for (let j = 0; j < n; j++) { const cell = document.getElementById(`sys-coeff-${i}-${j}`); if (cell) { cell.value = ''; cell.classList.remove('matrix-grid__cell--error'); } } const bCell = document.getElementById(`sys-const-${i}`); if (bCell) { bCell.value = ''; bCell.classList.remove('matrix-grid__cell--error'); } } const resultEl = document.getElementById('systemResult'); if (resultEl) resultEl.classList.remove('matrix-result--visible'); hideError(); } function fillExample() { const examples = { 2: { A: [[2, 1], [1, 1]], b: [7, 4] }, 3: { A: [[2, 1, -1], [-3, -1, 2], [-2, 1, 2]], b: [8, -11, -3] } }; const ex = examples[currentSize]; const n = currentSize; for (let i = 0; i < n; i++) { for (let j = 0; j < n; j++) { const cell = document.getElementById(`sys-coeff-${i}-${j}`); if (cell) cell.value = ex.A[i][j]; } const bCell = document.getElementById(`sys-const-${i}`); if (bCell) bCell.value = ex.b[i]; } } function init(el) { container = el; render(); container.addEventListener('change', (e) => { if (e.target.id === 'systemSize') { currentSize = parseInt(e.target.value); renderGrid(); const resultEl = document.getElementById('systemResult'); if (resultEl) resultEl.classList.remove('matrix-result--visible'); hideError(); } if (e.target.id === 'systemMethod') { currentMethod = e.target.value; } }); container.addEventListener('click', (e) => { if (e.target.id === 'solveBtn') solve(); }); container.addEventListener('click', (e) => { const btn = e.target.closest('[data-action]'); if (!btn) return; const action = btn.dataset.action; if (action === 'clear') clearGrid(); else if (action === 'example') fillExample(); }); } function destroy() { if (container) container.innerHTML = ''; container = null; } return { init, destroy, clearGrid, fillExample }; })();