12#include "include/cli.h"
14#include "include/calculus.h"
15#include "include/complex_number.h"
16#include "include/differential_equations.h"
17#include "include/expression.h"
18#include "include/fourier.h"
19#include "include/laplace.h"
20#include "include/numerical_methods.h"
21#include "include/polynomial.h"
25 std::cout <<
"=== sokobo - Computational Algebra System ===" <<
'\n';
26 std::cout <<
"Type 'help' for available commands or 'quit' to exit." <<
'\n';
30 std::cout <<
"sokobo > ";
31 if (!std::getline(std::cin, line)) {
36 line.erase(0, line.find_first_not_of(
" \t"));
37 line.erase(line.find_last_not_of(
" \t") + 1);
42 if (line ==
"quit" || line ==
"exit") {
46 std::vector<std::string> tokens = split(line);
52 std::string cmd = tokens[0];
53 std::transform(cmd.begin(), cmd.end(), cmd.begin(), ::tolower);
57 }
else if (cmd ==
"clear") {
59 }
else if (cmd ==
"list") {
61 }
else if (cmd ==
"expr") {
62 handleExpression(tokens);
63 }
else if (cmd ==
"deriv") {
64 handleDerivative(tokens);
65 }
else if (cmd ==
"integral") {
66 handleIntegral(tokens);
67 }
else if (cmd ==
"limit") {
69 }
else if (cmd ==
"series") {
71 }
else if (cmd ==
"poly") {
72 handlePolynomial(tokens);
73 }
else if (cmd ==
"peval") {
74 handlePolynomialEvaluate(tokens);
75 }
else if (cmd ==
"padd") {
76 handlePolynomialAdd(tokens);
77 }
else if (cmd ==
"pmult") {
79 }
else if (cmd ==
"pgcd") {
81 }
else if (cmd ==
"proots") {
82 handlePolynomialRoots(tokens);
83 }
else if (cmd ==
"pfactor") {
85 }
else if (cmd ==
"complex") {
86 handleComplex(tokens);
87 }
else if (cmd ==
"cadd") {
88 handleComplexAdd(tokens);
89 }
else if (cmd ==
"cmult") {
90 handleComplexMultiply(tokens);
91 }
else if (cmd ==
"cpower") {
92 handleComplexPower(tokens);
93 }
else if (cmd ==
"croots") {
94 handleComplexRoots(tokens);
95 }
else if (cmd ==
"matrix") {
97 }
else if (cmd ==
"matrix_raw") {
98 handleMatrixRaw(tokens);
99 }
else if (cmd ==
"madj") {
100 handleMatrixAdjoint(tokens);
101 }
else if (cmd ==
"mdisp") {
102 handleMatrixDisplay(tokens);
103 }
else if (cmd ==
"mrank") {
104 handleMatrixRank(tokens);
105 }
else if (cmd ==
"mset") {
106 handleMatrixSet(tokens);
107 }
else if (cmd ==
"mdet") {
108 handleMatrixDeterminant(tokens);
109 }
else if (cmd ==
"minv") {
110 handleMatrixInverse(tokens);
111 }
else if (cmd ==
"meigen") {
112 handleMatrixEigenvalues(tokens);
113 }
else if (cmd ==
"meigenv") {
114 handleMatrixEigenvectors(tokens);
115 }
else if (cmd ==
"laplace") {
116 handleLaplace(tokens);
117 }
else if (cmd ==
"fourier") {
118 handleFourier(tokens);
119 }
else if (cmd ==
"ode") {
121 }
else if (cmd ==
"pde") {
123 }
else if (cmd ==
"root") {
125 }
else if (cmd ==
"optimize") {
127 }
else if (cmd ==
"interpolate") {
130 std::cout <<
"Unknown command: " << cmd <<
'\n';
131 std::cout <<
"Type 'help' for available commands." <<
'\n';
133 }
catch (
const std::exception& e) {
134 std::cout <<
"Error: " << e.what() <<
'\n';
138 std::cout <<
"Goodbye!" <<
'\n';
141std::vector<std::string> CAS_CLI::split(
const std::string& str)
143 std::vector<std::string> tokens;
144 std::istringstream iss(str);
146 while (iss >> token) {
147 tokens.push_back(token);
152void CAS_CLI::showHelpMatrices()
154 std::cout <<
"\nMatrices:" <<
'\n';
155 std::cout <<
" matrix <name> <rows> <cols> - Create matrix" <<
'\n';
157 <<
" matrix_raw <name> <raw> - Create a matrix from a raw input"
159 std::cout <<
" mdisp <name> - Display matrix" <<
'\n';
160 std::cout <<
" mset <matrix> <i> <j> <val> - Set matrix element" <<
'\n';
161 std::cout <<
" mdet <matrix> - Matrix determinant" <<
'\n';
162 std::cout <<
" minv <matrix> - Matrix inverse" <<
'\n';
163 std::cout <<
" meigen <matrix> - Matrix eigenvalues" <<
'\n';
164 std::cout <<
" meigenv <matrix> - Matrix eigenvectors"
166 std::cout <<
" madj <matrix> - Matrix adjoint" <<
'\n';
167 std::cout <<
" mrank <matrix> - Matrix rank" <<
'\n';
168 std::cout <<
" mtrans <matrix> - Matrix transpose" <<
'\n';
171void CAS_CLI::showHelp()
173 std::cout <<
"\n=== CAS Commands ===" << std::endl;
175 std::cout <<
"\nGeneral:" << std::endl;
176 std::cout <<
" help - Show this help" << std::endl;
177 std::cout <<
" list - List all stored objects"
179 std::cout <<
" clear - Clear all stored objects"
181 std::cout <<
" quit/exit - Exit the program" << std::endl;
183 std::cout <<
"\nExpressions:" << std::endl;
184 std::cout <<
" expr <name> <expression> - Define expression" << std::endl;
185 std::cout <<
" deriv <expr> <var> - Compute derivative" << std::endl;
186 std::cout <<
" integral <expr> <var> <a> <b> - Numerical integration"
188 std::cout <<
" limit <expr> <var> <val> - Compute limit" << std::endl;
189 std::cout <<
" series <expr> <var> <center> <degree> - Taylor series"
192 std::cout <<
"\nPolynomials:" << std::endl;
193 std::cout <<
" poly <name> <coeffs...> - Define polynomial" << std::endl;
194 std::cout <<
" peval <poly> <value> - Evaluate polynomial" << std::endl;
195 std::cout <<
" padd <p1> <p2> <result> - Add polynomials" << std::endl;
196 std::cout <<
" pmult <p1> <p2> <result> - Multiply polynomials" << std::endl;
197 std::cout <<
" pgcd <p1> <p2> - Compute polynomial GCD"
199 std::cout <<
" proots <poly> - Find polynomial roots" << std::endl;
200 std::cout <<
" pfactor <poly> - Factor polynomial" << std::endl;
202 std::cout <<
"\nComplex Numbers:" << std::endl;
203 std::cout <<
" complex <name> <real> <imag> - Define complex number"
205 std::cout <<
" cadd <c1> <c2> <result> - Add complex numbers" << std::endl;
206 std::cout <<
" cmult <c1> <c2> <result> - Multiply complex numbers"
208 std::cout <<
" cpower <c> <n> <result> - Complex power" << std::endl;
209 std::cout <<
" croots <n> - Roots of unity" << std::endl;
211 CAS_CLI::showHelpMatrices();
213 std::cout <<
"\nTransforms:" << std::endl;
214 std::cout <<
" laplace <expr> <var> - Laplace transform" << std::endl;
215 std::cout <<
" fourier <signal> - Fourier transform" << std::endl;
217 std::cout <<
"\nDifferential Equations:" << std::endl;
218 std::cout <<
" ode <method> <expr> <x0> <y0> <h> <steps> - Solve ODE"
220 std::cout <<
" pde <type> <params...> - Solve PDE" << std::endl;
222 std::cout <<
"\nNumerical Methods:" << std::endl;
223 std::cout <<
" root <method> <expr> <params...> - Find roots" << std::endl;
224 std::cout <<
" optimize <method> <expr> <params...> - Optimization"
226 std::cout <<
" interpolate <method> <x_vals> <y_vals> - Interpolation"
228 std::cout << std::endl;
231void CAS_CLI::handleExpression(
const std::vector<std::string>& tokens)
233 if (tokens.size() < 3) {
234 std::cout <<
"Usage: expr <name> <expression>" << std::endl;
238 std::string name = tokens[1];
239 std::string exprStr = tokens[2];
240 for (
size_t i = 3; i < tokens.size(); ++i) {
241 exprStr +=
" " + tokens[i];
246 auto expr = parseExpression(exprStr);
249 expressions[name] = expr;
251 std::cout <<
"Expression '" << name <<
"' = " << exprStr
252 <<
" stored successfully." << std::endl;
255 std::cout <<
"Parsed as: " << expr->toString() << std::endl;
257 }
catch (
const std::exception& e) {
258 std::cout <<
"Error parsing expression: " << e.what() << std::endl;
259 std::cout <<
"Expression '" << name <<
"' was not stored." << std::endl;
263void CAS_CLI::clearAll()
265 int totalObjects = expressions.size() + polynomials.size()
266 + complexNumbers.size() + matrices.size();
268 if (totalObjects == 0) {
269 std::cout <<
"No objects to clear." << std::endl;
276 complexNumbers.clear();
279 std::cout <<
"All objects cleared (" << totalObjects <<
" objects removed)."
283void CAS_CLI::listObjects()
285 bool hasObjects =
false;
288 if (!expressions.empty()) {
289 std::cout <<
"\nExpressions:" << std::endl;
290 for (
const auto& pair : expressions) {
291 std::cout <<
" " << pair.first <<
" = " << pair.second->toString()
298 if (!polynomials.empty()) {
299 std::cout <<
"\nPolynomials:" << std::endl;
300 for (
const auto& pair : polynomials) {
301 std::cout <<
" " << pair.first <<
" = " << pair.second.toString()
308 if (!complexNumbers.empty()) {
309 std::cout <<
"\nComplex Numbers:" << std::endl;
310 for (
const auto& pair : complexNumbers) {
311 std::cout <<
" " << pair.first <<
" = " << pair.second.toString()
318 if (!matrices.empty()) {
319 std::cout <<
"\nMatrices:" << std::endl;
320 for (
const auto& pair : matrices) {
321 std::cout <<
" " << pair.first <<
" (" << pair.second.getRows() <<
"x"
322 << pair.second.getCols() <<
")" << std::endl;
328 std::cout <<
"No objects stored." << std::endl;
331 std::cout << std::endl;
335std::shared_ptr<Expression> CAS_CLI::parseExpression(
const std::string& exprStr)
338 std::string cleanExpr = removeWhitespace(exprStr);
340 if (cleanExpr.empty()) {
341 throw std::runtime_error(
"Empty expression");
346 return parseAddSub(cleanExpr, pos);
350std::string CAS_CLI::removeWhitespace(
const std::string& str)
354 if (!std::isspace(c)) {
362std::shared_ptr<Expression> CAS_CLI::parseAddSub(
const std::string& expr,
365 auto left = parseMulDiv(expr, pos);
367 while (pos < expr.length() && (expr[pos] ==
'+' || expr[pos] ==
'-')) {
368 char op = expr[pos++];
369 auto right = parseMulDiv(expr, pos);
370 left = std::make_shared<BinaryOp>(left, op, right);
377std::shared_ptr<Expression> CAS_CLI::parseMulDiv(
const std::string& expr,
380 auto left = parsePower(expr, pos);
382 while (pos < expr.length() && (expr[pos] ==
'*' || expr[pos] ==
'/')) {
383 char op = expr[pos++];
384 auto right = parsePower(expr, pos);
385 left = std::make_shared<BinaryOp>(left, op, right);
392std::shared_ptr<Expression> CAS_CLI::parsePower(
const std::string& expr,
395 auto left = parseFactor(expr, pos);
397 if (pos < expr.length() && expr[pos] ==
'^') {
399 auto right = parsePower(expr, pos);
400 left = std::make_shared<BinaryOp>(left,
'^', right);
407std::shared_ptr<Expression> CAS_CLI::parseFactor(
const std::string& expr,
410 if (pos >= expr.length()) {
411 throw std::runtime_error(
"Unexpected end of expression");
415 if (expr[pos] ==
'(') {
417 auto result = parseAddSub(expr, pos);
418 if (pos >= expr.length() || expr[pos] !=
')') {
419 throw std::runtime_error(
"Missing closing parenthesis");
426 if (expr[pos] ==
'-') {
428 auto operand = parseFactor(expr, pos);
429 return std::make_shared<BinaryOp>(
430 std::make_shared<Constant>(-1),
'*', operand);
434 if (expr[pos] ==
'+') {
436 return parseFactor(expr, pos);
440 if (std::isdigit(expr[pos]) || expr[pos] ==
'.') {
441 return parseNumber(expr, pos);
445 if (std::isalpha(expr[pos])) {
446 return parseVariableOrFunction(expr, pos);
449 throw std::runtime_error(
"Unexpected character: "
450 + std::string(1, expr[pos]));
454std::shared_ptr<Expression> CAS_CLI::parseNumber(
const std::string& expr,
458 bool hasDecimal =
false;
460 while (pos < expr.length()
461 && (std::isdigit(expr[pos]) || (expr[pos] ==
'.' && !hasDecimal)))
463 if (expr[pos] ==
'.') {
469 std::string numStr = expr.substr(start, pos - start);
470 double value = std::stod(numStr);
471 return std::make_shared<Constant>(value);
475std::shared_ptr<Expression> CAS_CLI::parseVariableOrFunction(
476 const std::string& expr,
size_t& pos)
481 while (pos < expr.length() && (std::isalnum(expr[pos]) || expr[pos] ==
'_')) {
485 std::string identifier = expr.substr(start, pos - start);
488 if (pos < expr.length() && expr[pos] ==
'(') {
490 auto argument = parseAddSub(expr, pos);
491 if (pos >= expr.length() || expr[pos] !=
')') {
492 throw std::runtime_error(
"Missing closing parenthesis in function call");
495 return std::make_shared<Function>(identifier, argument);
499 return std::make_shared<Variable>(identifier);
502void CAS_CLI::handleDerivative(
const std::vector<std::string>& tokens)
504 if (tokens.size() < 3) {
505 std::cout <<
"Usage: deriv <expression> <variable>" << std::endl;
509 std::string expr = tokens[1];
510 std::string var = tokens[2];
512 if (expressions.find(expr) == expressions.end()) {
513 std::cout <<
"Expression '" << expr <<
"' not found." << std::endl;
517 auto derivative = Calculus::differentiate(expressions[expr], var);
518 std::cout <<
"d/d" << var <<
"(" << expr <<
") = " << derivative->toString()
522void CAS_CLI::handleIntegral(
const std::vector<std::string>& tokens)
524 if (tokens.size() < 5) {
525 std::cout <<
"Usage: integral <expression> <variable> <lower> <upper>"
530 std::string expr = tokens[1];
531 std::string var = tokens[2];
532 double lower = std::stod(tokens[3]);
533 double upper = std::stod(tokens[4]);
536 auto f = [](
double x) {
return x * x; };
537 double result = Calculus::simpsonsRule(f, lower, upper);
538 std::cout <<
"∫[" << lower <<
"," << upper <<
"] " << expr <<
" d" << var
539 <<
" ≈ " << result << std::endl;
542void CAS_CLI::handleLimit(
const std::vector<std::string>& tokens)
544 if (tokens.size() < 4) {
545 std::cout <<
"Usage: limit <expression> <variable> <value>" << std::endl;
549 std::string expr = tokens[1];
550 std::string var = tokens[2];
551 double value = std::stod(tokens[3]);
553 auto f = [](
double x) {
return x * x; };
554 double result = Calculus::limit(f, value);
555 std::cout <<
"lim(" << var <<
"→" << value <<
") " << expr <<
" = " << result
559void CAS_CLI::handleSeries(
const std::vector<std::string>& tokens)
561 if (tokens.size() < 5) {
562 std::cout <<
"Usage: series <expression> <variable> <center> <degree>"
567 std::string expr = tokens[1];
568 std::string var = tokens[2];
569 double center = std::stod(tokens[3]);
570 int degree = std::stoi(tokens[4]);
572 auto f = [](
double x) {
return std::exp(x); };
573 Polynomial series = Calculus::taylorSeries(f, center, degree);
574 std::cout <<
"Taylor series of " << expr <<
" around " << var <<
"=" << center
575 <<
" (degree " << degree <<
"): " << series.toString() << std::endl;
578void CAS_CLI::handlePolynomial(
const std::vector<std::string>& tokens)
580 if (tokens.size() < 3) {
581 std::cout <<
"Usage: poly <name> <coefficient0> <coefficient1> ..."
586 std::string name = tokens[1];
587 std::vector<double> coeffs;
588 for (
size_t i = 2; i < tokens.size(); ++i) {
589 coeffs.push_back(std::stod(tokens[i]));
593 std::cout <<
"Polynomial '" << name <<
"' = " << polynomials[name].toString()
594 <<
" stored." << std::endl;
597void CAS_CLI::handlePolynomialEvaluate(
const std::vector<std::string>& tokens)
599 if (tokens.size() < 3) {
600 std::cout <<
"Usage: peval <polynomial> <value>" << std::endl;
604 std::string name = tokens[1];
605 double value = std::stod(tokens[2]);
607 if (polynomials.find(name) == polynomials.end()) {
608 std::cout <<
"Polynomial '" << name <<
"' not found." << std::endl;
612 double result = polynomials[name].evaluate(value);
613 std::cout << name <<
"(" << value <<
") = " << result << std::endl;
616void CAS_CLI::handlePolynomialAdd(
const std::vector<std::string>& tokens)
618 if (tokens.size() < 4) {
619 std::cout <<
"Usage: padd <poly1> <poly2> <result_name>" << std::endl;
623 std::string p1_name = tokens[1];
624 std::string p2_name = tokens[2];
625 std::string result_name = tokens[3];
627 if (CAS_CLI::polynomials.find(p1_name) == CAS_CLI::polynomials.end()
628 || CAS_CLI::polynomials.find(p2_name) == CAS_CLI::polynomials.end())
630 std::cout <<
"One or both polynomials not found." << std::endl;
634 CAS_CLI::polynomials[result_name] =
635 CAS_CLI::polynomials[p1_name] + CAS_CLI::polynomials[p2_name];
636 std::cout << result_name <<
" = "
637 << CAS_CLI::polynomials[result_name].toString() << std::endl;
688void CAS_CLI::handlePolynomialRoots(
const std::vector<std::string>& tokens)
690 if (tokens.size() < 2) {
691 std::cout <<
"Usage: proots <polynomial>" <<
'\n';
695 std::string
const name = tokens[1];
697 if (polynomials.find(name) == polynomials.end()) {
698 std::cout <<
"Polynomial '" << name <<
"' not found." << std::endl;
702 auto roots = polynomials[name].roots();
703 std::cout <<
"Roots of " << name <<
":" << std::endl;
704 for (
size_t i = 0; i < roots.size(); ++i) {
705 std::cout <<
" r" << (i + 1) <<
" = " <<
ComplexNumber(roots[i]).toString()
733void CAS_CLI::handleComplex(
const std::vector<std::string>& tokens)
735 if (tokens.size() < 4) {
736 std::cout <<
"Usage: complex <name> <real> <imaginary>" << std::endl;
740 std::string name = tokens[1];
741 double real = std::stod(tokens[2]);
742 double imag = std::stod(tokens[3]);
745 std::cout <<
"Complex number '" << name
746 <<
"' = " << complexNumbers[name].toString() <<
" stored."
750void CAS_CLI::handleComplexAdd(
const std::vector<std::string>& tokens)
752 if (tokens.size() < 4) {
753 std::cout <<
"Usage: cadd <complex1> <complex2> <result_name>" << std::endl;
757 std::string c1_name = tokens[1];
758 std::string c2_name = tokens[2];
759 std::string result_name = tokens[3];
761 if (complexNumbers.find(c1_name) == complexNumbers.end()
762 || complexNumbers.find(c2_name) == complexNumbers.end())
764 std::cout <<
"One or both complex numbers not found." << std::endl;
768 complexNumbers[result_name] =
769 complexNumbers[c1_name] + complexNumbers[c2_name];
770 std::cout << result_name <<
" = " << complexNumbers[result_name].toString()
774void CAS_CLI::handleComplexMultiply(
const std::vector<std::string>& tokens)
776 if (tokens.size() < 4) {
777 std::cout <<
"Usage: cmult <complex1> <complex2> <result_name>"
782 std::string c1_name = tokens[1];
783 std::string c2_name = tokens[2];
784 std::string result_name = tokens[3];
786 if (complexNumbers.find(c1_name) == complexNumbers.end()
787 || complexNumbers.find(c2_name) == complexNumbers.end())
789 std::cout <<
"One or both complex numbers not found." << std::endl;
793 complexNumbers[result_name] =
794 complexNumbers[c1_name] * complexNumbers[c2_name];
795 std::cout << result_name <<
" = " << complexNumbers[result_name].toString()
799void CAS_CLI::handleComplexPower(
const std::vector<std::string>& tokens)
801 if (tokens.size() < 4) {
802 std::cout <<
"Usage: cpower <complex> <power> <result_name>" << std::endl;
806 std::string c_name = tokens[1];
807 int power = std::stoi(tokens[2]);
808 std::string result_name = tokens[3];
810 if (complexNumbers.find(c_name) == complexNumbers.end()) {
811 std::cout <<
"Complex number '" << c_name <<
"' not found." << std::endl;
815 complexNumbers[result_name] = complexNumbers[c_name] ^ power;
816 std::cout << result_name <<
" = " << complexNumbers[result_name].toString()
820void CAS_CLI::handleComplexRoots(
const std::vector<std::string>& tokens)
822 if (tokens.size() < 2) {
823 std::cout <<
"Usage: croots <n>" << std::endl;
827 int n = std::stoi(tokens[1]);
829 auto roots = ComplexNumber::rootsOfUnity(n);
830 std::cout << n <<
"th roots of unity:" << std::endl;
831 for (
size_t i = 0; i < roots.size(); ++i) {
832 std::cout <<
" ω^" << i <<
" = " << roots[i].toString() << std::endl;
836void CAS_CLI::handleMatrixAdjoint(
const std::vector<std::string>& tokens)
838 if (tokens.size() < 2) {
839 std::cout <<
"Usage: madj <name>";
841 std::string name = tokens[1];
842 std::cout << matrices[name].adjoint().toString() <<
'\n';
845void CAS_CLI::handleMatrixRaw(
const std::vector<std::string>& tokens)
847 if (tokens.size() < 3) {
848 std::cout <<
"Usage: matrix <name> (<raw>)\n";
852 const std::string& name = tokens[1];
853 const std::string& raw = tokens[2];
855 if (raw.front() !=
'(' || raw.back() !=
')') {
856 std::cout <<
"Invalid format: expected '(...)'\n";
860 std::string content = raw.substr(1, raw.size() - 2);
862 std::vector<std::vector<float>> data;
864 int expected_cols = -1;
866 while (i < content.size()) {
867 if (content[i] !=
'[') {
868 std::cout <<
"Invalid format: expected '['\n";
872 size_t close = content.find(
']', i);
873 if (close == std::string::npos) {
874 std::cout <<
"Invalid format: missing ']'\n";
878 std::string row_str = content.substr(i + 1, close - i - 1);
879 std::stringstream ss(row_str);
881 std::vector<float> row;
884 while (getline(ss, value,
',')) {
886 row.push_back(std::stof(value));
888 std::cout <<
"Invalid numeric value\n";
894 std::cout <<
"Empty row not allowed\n";
898 if (expected_cols == -1) {
899 expected_cols = row.size();
900 }
else if (row.size() != expected_cols) {
901 std::cout <<
"Rows with different column count\n";
908 if (i < content.size() && content[i] ==
',') {
914 std::cout <<
"Matrix cannot be empty\n";
920 for (
size_t r = 0; r < data.size(); ++r) {
921 for (
size_t c = 0; c < data[r].size(); ++c) {
922 matrix(r, c) = data[r][c];
926 matrices[name] = matrix;
928 std::cout <<
"Matrix '" << name <<
"' created (" << data.size() <<
"x"
929 << expected_cols <<
")\n";
932void CAS_CLI::handleMatrix(
const std::vector<std::string>& tokens)
934 if (tokens.size() < 4) {
935 std::cout <<
"Usage: matrix <name> <rows> <cols>" << std::endl;
939 std::string name = tokens[1];
940 int rows = std::stoi(tokens[2]);
941 int cols = std::stoi(tokens[3]);
944 std::cout <<
"Matrix '" << name <<
"' (" << rows <<
"x" << cols
945 <<
") created." << std::endl;
948void CAS_CLI::handleMatrixDisplay(
const std::vector<std::string>& tokens)
950 if (tokens.size() < 2) {
951 std::cout <<
"Usage: mdisp <name>" << std::endl;
953 std::string name = tokens[1];
954 std::cout << matrices[name].toString() << std::endl;
957void CAS_CLI::handleMatrixRank(
const std::vector<std::string>& tokens)
959 if (tokens.size() < 2) {
960 std::cout <<
"Usage: mrank <name>" << std::endl;
962 std::string name = tokens[1];
963 std::cout << matrices[name].rank() << std::endl;
966void CAS_CLI::handleMatrixSet(
const std::vector<std::string>& tokens)
968 if (tokens.size() < 5) {
969 std::cout <<
"Usage: mset <matrix> <row> <col> <value>" << std::endl;
973 std::string name = tokens[1];
974 int row = std::stoi(tokens[2]);
975 int col = std::stoi(tokens[3]);
976 double value = std::stod(tokens[4]);
978 if (matrices.find(name) == matrices.end()) {
979 std::cout <<
"Matrix '" << name <<
"' not found." << std::endl;
983 matrices[name](row, col) = value;
984 std::cout << name <<
"[" << row <<
"][" << col <<
"] = " << value
988void CAS_CLI::handleMatrixDeterminant(
const std::vector<std::string>& tokens)
990 if (tokens.size() < 2) {
991 std::cout <<
"Usage: mdet <matrix>" << std::endl;
995 std::string name = tokens[1];
997 if (matrices.find(name) == matrices.end()) {
998 std::cout <<
"Matrix '" << name <<
"' not found." << std::endl;
1002 double det = matrices[name].determinant();
1003 std::cout <<
"det(" << name <<
") = " << det << std::endl;
1004 std::cout << matrices[name].toString() << std::endl;
1007void CAS_CLI::handleMatrixInverse(
const std::vector<std::string>& tokens)
1009 if (tokens.size() < 2) {
1010 std::cout <<
"Usage: minv <matrix>" << std::endl;
1014 std::string name = tokens[1];
1016 if (matrices.find(name) == matrices.end()) {
1017 std::cout <<
"Matrix '" << name <<
"' not found." << std::endl;
1023 std::cout <<
"Inverse of " << name <<
":" << std::endl;
1024 std::cout << inv.
toString() << std::endl;
1025 }
catch (
const std::exception& e) {
1026 std::cout <<
"Cannot compute inverse: " << e.what() << std::endl;
1030void CAS_CLI::handleMatrixEigenvalues(
const std::vector<std::string>& tokens)
1032 if (tokens.size() < 2) {
1033 std::cout <<
"Usage: meigen <matrix>" << std::endl;
1037 std::string name = tokens[1];
1039 if (matrices.find(name) == matrices.end()) {
1040 std::cout <<
"Matrix '" << name <<
"' not found." << std::endl;
1044 auto eigenvals = matrices[name].eigenvalues();
1045 std::cout <<
"Eigenvalues of " << name <<
":" << std::endl;
1046 for (
size_t i = 0; i < eigenvals.size(); ++i) {
1047 std::cout <<
"lambda_" << (i + 1) <<
" = " << eigenvals[i] << std::endl;
1051void CAS_CLI::handleMatrixEigenvectors(
const std::vector<std::string>& tokens)
1053 if (tokens.size() < 2) {
1054 std::cout <<
"Usage: meigenv <matrix> " << std::endl;
1057 std::string name = tokens[1];
1058 if (matrices.find(name) == matrices.end()) {
1059 std::cout <<
"Matrix '" << name <<
"' not found." << std::endl;
1062 auto eigenvectors = matrices[name].eigenvectors();
1063 for (
int i = 0; i < eigenvectors.getRows(); i++) {
1064 for (
int j = 0; j < eigenvectors.getCols(); j++) {
1065 std::cout << eigenvectors(i, j) <<
" ";
1071void CAS_CLI::handleLaplace(
const std::vector<std::string>& tokens)
1073 if (tokens.size() < 3) {
1074 std::cout <<
"Usage: laplace <expression> <variable>" << std::endl;
1078 std::string expr = tokens[1];
1079 std::string var = tokens[2];
1081 std::cout <<
"Laplace transform of " << expr <<
" with respect to " << var
1082 <<
":" << std::endl;
1084 <<
"Note: Full Laplace transform implementation not shown in this demo."
1088void CAS_CLI::handleFourier(
const std::vector<std::string>& tokens)
1090 if (tokens.size() < 2) {
1091 std::cout <<
"Usage: fourier <signal_values...>" << std::endl;
1095 std::vector<ComplexNumber> signal;
1096 for (
size_t i = 1; i < tokens.size(); ++i) {
1100 auto spectrum = FourierTransform::FFT(signal);
1101 std::cout <<
"FFT result:" << std::endl;
1102 for (
size_t i = 0; i < spectrum.size(); ++i) {
1103 std::cout <<
" X[" << i <<
"] = " << spectrum[i].toString() << std::endl;
1107void CAS_CLI::handleODE(
const std::vector<std::string>& tokens)
1109 if (tokens.size() < 7) {
1110 std::cout <<
"Usage: ode <method> <dy/dx_expression> <x0> <y0> <h> <steps>"
1112 std::cout <<
"Methods: euler, rk4" << std::endl;
1116 std::string method = tokens[1];
1117 std::string expr = tokens[2];
1118 double x0 = std::stod(tokens[3]);
1119 double y0 = std::stod(tokens[4]);
1120 double h = std::stod(tokens[5]);
1121 int steps = std::stoi(tokens[6]);
1124 auto f = [](
double x,
double y) {
return x + y; };
1126 std::vector<double> solution;
1127 if (method ==
"euler") {
1128 solution = DifferentialEquations::eulerMethod(f, x0, y0, h, steps);
1129 }
else if (method ==
"rk4") {
1130 solution = DifferentialEquations::rungeKutta4(f, x0, y0, h, steps);
1132 std::cout <<
"Unknown method: " << method << std::endl;
1136 std::cout <<
"ODE solution using " << method <<
" method:" << std::endl;
1137 for (
int i = 0; i < steps && i < static_cast<int>(solution.size()); ++i) {
1138 double x = x0 + i * h;
1139 std::cout <<
" x = " << x <<
", y = " << solution[i] << std::endl;
1143void CAS_CLI::handlePDE(
const std::vector<std::string>& tokens)
1145 if (tokens.size() < 2) {
1146 std::cout <<
"Usage: pde <type> <parameters...>" << std::endl;
1147 std::cout <<
"Types: heat, wave, laplace" << std::endl;
A templated matrix class supporting various linear algebra operations.
std::string toString() const
Converts the matrix to a formatted string representation.
Matrix< T > inverse() const
Computes the inverse of the matrix.