#!/usr/bin/env node /** * Direct server-side test of TRUE O(log n) sublinear solver * This bypasses MCP to test the core algorithm directly */ import path from 'path'; import fs from 'fs'; import { fileURLToPath } from 'url'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); // Import the TRUE sublinear solver directly import { TrueSublinearSolverTools } from '../dist/mcp/tools/true-sublinear-solver.js'; async function testTrueSublinearDirect() { console.log('๐Ÿงช Testing TRUE O(log n) Sublinear Solver - Direct Mode'); console.log('================================================'); const solver = new TrueSublinearSolverTools(); // Test 1: Small matrix (should use base case) console.log('\n๐Ÿ“Š Test 1: Small 3x3 matrix (base case)'); const smallMatrix = { rows: 3, cols: 3, values: [4, -1, -1, -1, 4, -1, -1, -1, 4], rowIndices: [0, 0, 0, 1, 1, 1, 2, 2, 2], colIndices: [0, 1, 2, 0, 1, 2, 0, 1, 2] }; const smallVector = [1, 1, 1]; try { const startTime = Date.now(); const result1 = await solver.solveTrueSublinear(smallMatrix, smallVector); const endTime = Date.now(); console.log(`โœ… Solution: [${result1.solution.map(x => x.toFixed(6)).join(', ')}]`); console.log(`โœ… Complexity: ${result1.actual_complexity}`); console.log(`โœ… Method: ${result1.method_used}`); console.log(`โœ… Time: ${endTime - startTime}ms`); console.log(`โœ… Residual norm: ${result1.residual_norm.toExponential(2)}`); } catch (error) { console.error(`โŒ Small matrix test failed:`, error.message); return; } // Test 2: Medium matrix (should trigger TRUE O(log n)) console.log('\n๐Ÿ“Š Test 2: Medium 200x200 matrix (TRUE O(log n))'); // Generate 200x200 diagonally dominant matrix const n = 200; const values = []; const rowIndices = []; const colIndices = []; // Create tridiagonal diagonally dominant matrix for (let i = 0; i < n; i++) { // Diagonal element (dominant) values.push(10 + Math.random() * 5); rowIndices.push(i); colIndices.push(i); // Off-diagonal elements if (i > 0) { values.push(-1 - Math.random()); rowIndices.push(i); colIndices.push(i - 1); } if (i < n - 1) { values.push(-1 - Math.random()); rowIndices.push(i); colIndices.push(i + 1); } } const mediumMatrix = { rows: n, cols: n, values, rowIndices, colIndices }; // Generate sparse vector const mediumVector = new Array(n).fill(0); for (let i = 0; i < 10; i++) { mediumVector[i] = 1; } try { const startTime = Date.now(); const result2 = await solver.solveTrueSublinear(mediumMatrix, mediumVector); const endTime = Date.now(); console.log(`โœ… First 10 solution elements: [${result2.solution.slice(0, 10).map(x => x.toFixed(6)).join(', ')}]`); console.log(`โœ… Complexity: ${result2.actual_complexity}`); console.log(`โœ… Method: ${result2.method_used}`); console.log(`โœ… Time: ${endTime - startTime}ms`); console.log(`โœ… Residual norm: ${result2.residual_norm.toExponential(2)}`); console.log(`โœ… Dimension reduction ratio: ${result2.dimension_reduction_ratio.toFixed(4)}`); } catch (error) { console.error(`โŒ Medium matrix test failed:`, error.message); return; } // Test 3: Load and test with the large vector file console.log('\n๐Ÿ“Š Test 3: Large matrix with file-based vector (1020x1020)'); try { // Load vector from file const vectorPath = path.join(__dirname, 'large_vector_1000.json'); const vectorData = JSON.parse(fs.readFileSync(vectorPath, 'utf8')); const largeVector = vectorData.data || vectorData; console.log(`โœ… Loaded vector from file: ${largeVector.length} elements`); // Generate matching 1020x1020 matrix (same size as vector) const m = largeVector.length; const largeValues = []; const largeRowIndices = []; const largeColIndices = []; // Create sparse diagonally dominant matrix for (let i = 0; i < m; i++) { // Strong diagonal dominance largeValues.push(15 + Math.random() * 10); largeRowIndices.push(i); largeColIndices.push(i); // Sparse off-diagonal pattern const connections = Math.min(5, m - 1); // Max 5 connections per row for (let c = 0; c < connections; c++) { const j = (i + c + 1) % m; if (j !== i) { largeValues.push(-(1 + Math.random())); largeRowIndices.push(i); largeColIndices.push(j); } } } const largeMatrix = { rows: m, cols: m, values: largeValues, rowIndices: largeRowIndices, colIndices: largeColIndices }; console.log(`โœ… Generated ${m}x${m} matrix with ${largeValues.length} non-zero entries`); const startTime = Date.now(); const result3 = await solver.solveTrueSublinear(largeMatrix, largeVector); const endTime = Date.now(); console.log(`โœ… First 10 solution elements: [${result3.solution.slice(0, 10).map(x => x.toFixed(6)).join(', ')}]`); console.log(`โœ… Complexity: ${result3.actual_complexity}`); console.log(`โœ… Method: ${result3.method_used}`); console.log(`โœ… Time: ${endTime - startTime}ms`); console.log(`โœ… Residual norm: ${result3.residual_norm.toExponential(2)}`); console.log(`โœ… Dimension reduction ratio: ${result3.dimension_reduction_ratio.toFixed(4)}`); console.log(`โœ… Series terms used: ${result3.series_terms_used}`); } catch (error) { console.error(`โŒ Large matrix test failed:`, error.message); console.error(`โŒ Stack trace:`, error.stack); return; } console.log('\n๐ŸŽ‰ All tests completed successfully!'); console.log('โœ… TRUE O(log n) sublinear solver is working correctly'); } // Run the test testTrueSublinearDirect().catch(console.error);