slangmath 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.MD +366 -0
- package/LICENSE +21 -0
- package/README.md +953 -0
- package/package.json +23 -0
- package/slang-advanced.js +559 -0
- package/slang-basic.js +766 -0
- package/slang-cache.js +519 -0
- package/slang-convertor.js +652 -0
- package/slang-errors.js +454 -0
- package/slang-extended.js +501 -0
- package/slang-helpers.js +284 -0
- package/slang-math.js +3 -0
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SLaNg Extended Mathematical Functions
|
|
3
|
+
* Extends the converter with support for trigonometric, logarithmic, and other functions
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { createTerm, createFraction } from './slang-basic.js';
|
|
7
|
+
import { slangToLatex, latexToSlang } from './slang-convertor.js';
|
|
8
|
+
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// FUNCTION DEFINITIONS
|
|
11
|
+
// ============================================================================
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Supported mathematical functions with their LaTeX representations
|
|
15
|
+
*/
|
|
16
|
+
export const SUPPORTED_FUNCTIONS = {
|
|
17
|
+
// Trigonometric
|
|
18
|
+
sin: { latex: '\\sin', arity: 1, category: 'trigonometric' },
|
|
19
|
+
cos: { latex: '\\cos', arity: 1, category: 'trigonometric' },
|
|
20
|
+
tan: { latex: '\\tan', arity: 1, category: 'trigonometric' },
|
|
21
|
+
cot: { latex: '\\cot', arity: 1, category: 'trigonometric' },
|
|
22
|
+
sec: { latex: '\\sec', arity: 1, category: 'trigonometric' },
|
|
23
|
+
csc: { latex: '\\csc', arity: 1, category: 'trigonometric' },
|
|
24
|
+
|
|
25
|
+
// Inverse trigonometric
|
|
26
|
+
arcsin: { latex: '\\arcsin', arity: 1, category: 'inverse_trig' },
|
|
27
|
+
arccos: { latex: '\\arccos', arity: 1, category: 'inverse_trig' },
|
|
28
|
+
arctan: { latex: '\\arctan', arity: 1, category: 'inverse_trig' },
|
|
29
|
+
|
|
30
|
+
// Hyperbolic
|
|
31
|
+
sinh: { latex: '\\sinh', arity: 1, category: 'hyperbolic' },
|
|
32
|
+
cosh: { latex: '\\cosh', arity: 1, category: 'hyperbolic' },
|
|
33
|
+
tanh: { latex: '\\tanh', arity: 1, category: 'hyperbolic' },
|
|
34
|
+
|
|
35
|
+
// Logarithmic
|
|
36
|
+
ln: { latex: '\\ln', arity: 1, category: 'logarithmic' },
|
|
37
|
+
log: { latex: '\\log', arity: 1, category: 'logarithmic' },
|
|
38
|
+
log10: { latex: '\\log_{10}', arity: 1, category: 'logarithmic' },
|
|
39
|
+
|
|
40
|
+
// Exponential
|
|
41
|
+
exp: { latex: '\\exp', arity: 1, category: 'exponential' },
|
|
42
|
+
sqrt: { latex: '\\sqrt', arity: 1, category: 'exponential' },
|
|
43
|
+
|
|
44
|
+
// Other functions
|
|
45
|
+
abs: { latex: '\\left|', arity: 1, category: 'absolute' },
|
|
46
|
+
floor: { latex: '\\lfloor', arity: 1, category: 'floor' },
|
|
47
|
+
ceil: { latex: '\\lceil', arity: 1, category: 'ceiling' }
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// ============================================================================
|
|
51
|
+
// EXTENDED SLaNg STRUCTURES
|
|
52
|
+
// ============================================================================
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Create a function expression in SLaNg format
|
|
56
|
+
*/
|
|
57
|
+
export function createFunction(name, args) {
|
|
58
|
+
const funcInfo = SUPPORTED_FUNCTIONS[name];
|
|
59
|
+
if (!funcInfo) {
|
|
60
|
+
throw new Error(`Unsupported function: ${name}`);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (funcInfo.arity !== args.length) {
|
|
64
|
+
throw new Error(`Function ${name} expects ${funcInfo.arity} arguments, got ${args.length}`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
type: 'function',
|
|
69
|
+
name,
|
|
70
|
+
args,
|
|
71
|
+
latex: funcInfo.latex
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Check if an expression is a function
|
|
77
|
+
*/
|
|
78
|
+
export function isFunction(expr) {
|
|
79
|
+
return expr && expr.type === 'function';
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Get function information
|
|
84
|
+
*/
|
|
85
|
+
export function getFunctionInfo(expr) {
|
|
86
|
+
if (!isFunction(expr)) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return SUPPORTED_FUNCTIONS[expr.name] || null;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// ============================================================================
|
|
94
|
+
// EXTENDED CONVERSION FUNCTIONS
|
|
95
|
+
// ============================================================================
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Convert SLaNg function to LaTeX
|
|
99
|
+
*/
|
|
100
|
+
export function functionToLatex(func, options = {}) {
|
|
101
|
+
if (!isFunction(func)) {
|
|
102
|
+
throw new Error('Expression is not a function');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const funcInfo = getFunctionInfo(func);
|
|
106
|
+
if (!funcInfo) {
|
|
107
|
+
throw new Error(`Unknown function: ${func.name}`);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const argsLatex = func.args.map(arg => slangToLatex(arg, options));
|
|
111
|
+
|
|
112
|
+
// Special handling for absolute value
|
|
113
|
+
if (func.name === 'abs') {
|
|
114
|
+
return `\\left|${argsLatex[0]}\\right|`;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Special handling for floor and ceiling
|
|
118
|
+
if (func.name === 'floor') {
|
|
119
|
+
return `\\lfloor${argsLatex[0]}\\rfloor`;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (func.name === 'ceil') {
|
|
123
|
+
return `\\lceil${argsLatex[0]}\\rceil`;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Special handling for sqrt
|
|
127
|
+
if (func.name === 'sqrt') {
|
|
128
|
+
return `\\sqrt{${argsLatex[0]}}`;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// General function format
|
|
132
|
+
return `${func.latex}{${argsLatex.join(', ')}}`;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Parse LaTeX function to SLaNg
|
|
137
|
+
*/
|
|
138
|
+
export function parseFunction(latex) {
|
|
139
|
+
// Try to match function patterns
|
|
140
|
+
for (const [name, info] of Object.entries(SUPPORTED_FUNCTIONS)) {
|
|
141
|
+
const pattern = new RegExp(`^\\${info.latex.replace('\\', '\\\\')}\\s*\\{([^{}]+)\\}`);
|
|
142
|
+
const match = latex.match(pattern);
|
|
143
|
+
|
|
144
|
+
if (match) {
|
|
145
|
+
const argStr = match[1];
|
|
146
|
+
const arg = latexToSlang(argStr);
|
|
147
|
+
return createFunction(name, [arg]);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Special handling for absolute value
|
|
152
|
+
const absMatch = latex.match(/^\\left\|([^|]+)\\right\|$/);
|
|
153
|
+
if (absMatch) {
|
|
154
|
+
const arg = latexToSlang(absMatch[1]);
|
|
155
|
+
return createFunction('abs', [arg]);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Special handling for floor
|
|
159
|
+
const floorMatch = latex.match(/^\\lfloor([^\\]+)\\rfloor$/);
|
|
160
|
+
if (floorMatch) {
|
|
161
|
+
const arg = latexToSlang(floorMatch[1]);
|
|
162
|
+
return createFunction('floor', [arg]);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Special handling for ceiling
|
|
166
|
+
const ceilMatch = latex.match(/^\\lceil([^\\]+)\\rceil$/);
|
|
167
|
+
if (ceilMatch) {
|
|
168
|
+
const arg = latexToSlang(ceilMatch[1]);
|
|
169
|
+
return createFunction('ceil', [arg]);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
throw new Error(`Unable to parse function from LaTeX: ${latex}`);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Extended SLaNg to LaTeX converter that handles functions
|
|
177
|
+
*/
|
|
178
|
+
export function extendedSlangToLatex(expr, options = {}) {
|
|
179
|
+
// Handle functions
|
|
180
|
+
if (isFunction(expr)) {
|
|
181
|
+
return functionToLatex(expr, options);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Handle composite expressions with functions
|
|
185
|
+
if (expr.terms) {
|
|
186
|
+
const processedTerms = expr.terms.map(term => {
|
|
187
|
+
if (term.func) {
|
|
188
|
+
return { ...term, func: extendedSlangToLatex(term.func, options) };
|
|
189
|
+
}
|
|
190
|
+
return term;
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
return slangToLatex({ ...expr, terms: processedTerms }, options);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Default to original converter
|
|
197
|
+
return slangToLatex(expr, options);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Extended LaTeX to SLaNg converter that handles functions
|
|
202
|
+
*/
|
|
203
|
+
export function extendedLatexToSlang(latex, options = {}) {
|
|
204
|
+
latex = latex.trim();
|
|
205
|
+
|
|
206
|
+
// Try to parse as function first
|
|
207
|
+
try {
|
|
208
|
+
return parseFunction(latex);
|
|
209
|
+
} catch (error) {
|
|
210
|
+
// Not a function, try original parser
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Handle expressions with embedded functions
|
|
214
|
+
const functionPattern = /\\(sin|cos|tan|cot|sec|csc|arcsin|arccos|arctan|sinh|cosh|tanh|ln|log|exp|sqrt|left\||lfloor|lceil)/g;
|
|
215
|
+
|
|
216
|
+
if (functionPattern.test(latex)) {
|
|
217
|
+
// Extract and process functions
|
|
218
|
+
let processedLatex = latex;
|
|
219
|
+
const functions = [];
|
|
220
|
+
|
|
221
|
+
// Find all function occurrences
|
|
222
|
+
let match;
|
|
223
|
+
const regex = /(\\(sin|cos|tan|cot|sec|csc|arcsin|arccos|arctan|sinh|cosh|tanh|ln|log|exp|sqrt|left\||lfloor|lceil)\s*\{([^{}]+)\}|\\left\|([^|]+)\\right\||\\lfloor([^\\]+)\\rfloor|\\lceil([^\\]+)\\rceil)/g;
|
|
224
|
+
|
|
225
|
+
while ((match = regex.exec(latex)) !== null) {
|
|
226
|
+
const fullMatch = match[0];
|
|
227
|
+
const funcName = match[2] ||
|
|
228
|
+
(match[3] ? 'abs' :
|
|
229
|
+
match[4] ? 'floor' :
|
|
230
|
+
match[5] ? 'ceil' : null);
|
|
231
|
+
|
|
232
|
+
if (funcName) {
|
|
233
|
+
const argStr = match[3] || match[4] || match[5] || match[6];
|
|
234
|
+
const funcExpr = parseFunction(fullMatch);
|
|
235
|
+
functions.push({ original: fullMatch, parsed: funcExpr });
|
|
236
|
+
|
|
237
|
+
// Replace with placeholder
|
|
238
|
+
processedLatex = processedLatex.replace(fullMatch, `__FUNC_${functions.length - 1}__`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Parse the remaining expression
|
|
243
|
+
const baseExpr = latexToSlang(processedLatex, options);
|
|
244
|
+
|
|
245
|
+
// Reinsert functions
|
|
246
|
+
if (baseExpr.terms) {
|
|
247
|
+
baseExpr.terms.forEach(term => {
|
|
248
|
+
functions.forEach((func, index) => {
|
|
249
|
+
// This is a simplified approach - in practice, you'd need more sophisticated handling
|
|
250
|
+
if (term.var && term.var['__FUNC_' + index + '__']) {
|
|
251
|
+
delete term.var['__FUNC_' + index + '__'];
|
|
252
|
+
term.func = func.parsed;
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return baseExpr;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Default to original parser
|
|
262
|
+
return latexToSlang(latex, options);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// ============================================================================
|
|
266
|
+
// FUNCTION EVALUATION
|
|
267
|
+
// ============================================================================
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Evaluate a function expression at a given point
|
|
271
|
+
*/
|
|
272
|
+
export function evaluateFunction(func, point = {}) {
|
|
273
|
+
if (!isFunction(func)) {
|
|
274
|
+
throw new Error('Expression is not a function');
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const evaluatedArgs = func.args.map(arg => {
|
|
278
|
+
if (arg.terms) {
|
|
279
|
+
// Evaluate polynomial at point
|
|
280
|
+
let result = 0;
|
|
281
|
+
arg.terms.forEach(term => {
|
|
282
|
+
let termValue = term.coeff;
|
|
283
|
+
if (term.var) {
|
|
284
|
+
for (const [variable, power] of Object.entries(term.var)) {
|
|
285
|
+
if (point[variable] !== undefined) {
|
|
286
|
+
termValue *= Math.pow(point[variable], power);
|
|
287
|
+
} else {
|
|
288
|
+
// Variable not provided, return symbolic
|
|
289
|
+
return arg; // Return original if can't evaluate
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
result += termValue;
|
|
294
|
+
});
|
|
295
|
+
return result;
|
|
296
|
+
} else if (arg.coeff !== undefined) {
|
|
297
|
+
return arg.coeff;
|
|
298
|
+
}
|
|
299
|
+
return arg;
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
// Apply the mathematical function
|
|
303
|
+
switch (func.name) {
|
|
304
|
+
case 'sin': return Math.sin(evaluatedArgs[0]);
|
|
305
|
+
case 'cos': return Math.cos(evaluatedArgs[0]);
|
|
306
|
+
case 'tan': return Math.tan(evaluatedArgs[0]);
|
|
307
|
+
case 'cot': return 1 / Math.tan(evaluatedArgs[0]);
|
|
308
|
+
case 'sec': return 1 / Math.cos(evaluatedArgs[0]);
|
|
309
|
+
case 'csc': return 1 / Math.sin(evaluatedArgs[0]);
|
|
310
|
+
case 'arcsin': return Math.asin(evaluatedArgs[0]);
|
|
311
|
+
case 'arccos': return Math.acos(evaluatedArgs[0]);
|
|
312
|
+
case 'arctan': return Math.atan(evaluatedArgs[0]);
|
|
313
|
+
case 'sinh': return Math.sinh(evaluatedArgs[0]);
|
|
314
|
+
case 'cosh': return Math.cosh(evaluatedArgs[0]);
|
|
315
|
+
case 'tanh': return Math.tanh(evaluatedArgs[0]);
|
|
316
|
+
case 'ln': return Math.log(evaluatedArgs[0]);
|
|
317
|
+
case 'log': return Math.log10(evaluatedArgs[0]);
|
|
318
|
+
case 'exp': return Math.exp(evaluatedArgs[0]);
|
|
319
|
+
case 'sqrt': return Math.sqrt(evaluatedArgs[0]);
|
|
320
|
+
case 'abs': return Math.abs(evaluatedArgs[0]);
|
|
321
|
+
case 'floor': return Math.floor(evaluatedArgs[0]);
|
|
322
|
+
case 'ceil': return Math.ceil(evaluatedArgs[0]);
|
|
323
|
+
default:
|
|
324
|
+
throw new Error(`Evaluation not implemented for function: ${func.name}`);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// ============================================================================
|
|
329
|
+
// FUNCTION DIFFERENTIATION
|
|
330
|
+
// ============================================================================
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Differentiate a function expression
|
|
334
|
+
*/
|
|
335
|
+
export function differentiateFunction(func, variable) {
|
|
336
|
+
if (!isFunction(func)) {
|
|
337
|
+
throw new Error('Expression is not a function');
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
const [arg] = func.args;
|
|
341
|
+
const argDerivative = differentiate(arg, variable);
|
|
342
|
+
|
|
343
|
+
// Chain rule: d/dx[f(g(x))] = f'(g(x)) * g'(x)
|
|
344
|
+
switch (func.name) {
|
|
345
|
+
case 'sin':
|
|
346
|
+
return createFunction('cos', [arg]);
|
|
347
|
+
case 'cos':
|
|
348
|
+
return createTerm(-1);
|
|
349
|
+
case 'tan':
|
|
350
|
+
return createFraction(
|
|
351
|
+
[createTerm(1)],
|
|
352
|
+
[createFunction('cos', [arg]), createFunction('cos', [arg])]
|
|
353
|
+
);
|
|
354
|
+
case 'cot':
|
|
355
|
+
return createTerm(-1);
|
|
356
|
+
case 'sec':
|
|
357
|
+
return createTerm(1);
|
|
358
|
+
case 'csc':
|
|
359
|
+
return createTerm(-1);
|
|
360
|
+
case 'arcsin':
|
|
361
|
+
return createFraction(
|
|
362
|
+
[createTerm(1)],
|
|
363
|
+
[createFunction('sqrt', [createTerm(1, {}, createTerm(-1))])]
|
|
364
|
+
);
|
|
365
|
+
case 'arccos':
|
|
366
|
+
return createTerm(-1);
|
|
367
|
+
case 'arctan':
|
|
368
|
+
return createFraction(
|
|
369
|
+
[createTerm(1)],
|
|
370
|
+
[createTerm(1, {}, createTerm(1))]
|
|
371
|
+
);
|
|
372
|
+
case 'sinh':
|
|
373
|
+
return createFunction('cosh', [arg]);
|
|
374
|
+
case 'cosh':
|
|
375
|
+
return createFunction('sinh', [arg]);
|
|
376
|
+
case 'tanh':
|
|
377
|
+
return createFraction(
|
|
378
|
+
[createTerm(1)],
|
|
379
|
+
[createFunction('cosh', [arg]), createFunction('cosh', [arg])]
|
|
380
|
+
);
|
|
381
|
+
case 'ln':
|
|
382
|
+
return createFraction([createTerm(1)], [arg]);
|
|
383
|
+
case 'log':
|
|
384
|
+
return createFraction([createTerm(1)], [createTerm(Math.LN10)]);
|
|
385
|
+
case 'exp':
|
|
386
|
+
return createFunction('exp', [arg]);
|
|
387
|
+
case 'sqrt':
|
|
388
|
+
return createFraction([createTerm(1)], [createTerm(2)]);
|
|
389
|
+
case 'abs':
|
|
390
|
+
return createFunction('sign', [arg]); // Would need sign function implementation
|
|
391
|
+
case 'floor':
|
|
392
|
+
case 'ceil':
|
|
393
|
+
// These are not differentiable in the classical sense
|
|
394
|
+
throw new Error(`Function ${func.name} is not differentiable`);
|
|
395
|
+
default:
|
|
396
|
+
throw new Error(`Differentiation not implemented for function: ${func.name}`);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// Helper function for differentiation (would need to import from slang-math.js)
|
|
401
|
+
function differentiate(expr, variable) {
|
|
402
|
+
// This would be implemented in the main math module
|
|
403
|
+
// For now, return a placeholder
|
|
404
|
+
return createTerm(1, { [variable]: 1 });
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// ============================================================================
|
|
408
|
+
// UTILITY FUNCTIONS
|
|
409
|
+
// ============================================================================
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Get all supported functions by category
|
|
413
|
+
*/
|
|
414
|
+
export function getFunctionsByCategory(category) {
|
|
415
|
+
return Object.entries(SUPPORTED_FUNCTIONS)
|
|
416
|
+
.filter(([name, info]) => info.category === category)
|
|
417
|
+
.map(([name, info]) => ({ name, ...info }));
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* Check if a function is supported
|
|
422
|
+
*/
|
|
423
|
+
export function isSupportedFunction(name) {
|
|
424
|
+
return name in SUPPORTED_FUNCTIONS;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Get function LaTeX representation
|
|
429
|
+
*/
|
|
430
|
+
export function getFunctionLatex(name) {
|
|
431
|
+
const info = SUPPORTED_FUNCTIONS[name];
|
|
432
|
+
return info ? info.latex : null;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// ============================================================================
|
|
436
|
+
// EXAMPLES AND DEMO
|
|
437
|
+
// ============================================================================
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Demo function showing extended capabilities
|
|
441
|
+
*/
|
|
442
|
+
export function demoExtendedFunctions() {
|
|
443
|
+
console.log('š SLaNg Extended Functions Demo');
|
|
444
|
+
console.log('='.repeat(50));
|
|
445
|
+
|
|
446
|
+
// Create function expressions
|
|
447
|
+
const sinExpr = createFunction('sin', [createTerm(1, { x: 1 })]);
|
|
448
|
+
const logExpr = createFunction('ln', [createTerm(1, { x: 1 }), createTerm(1)]);
|
|
449
|
+
const sqrtExpr = createFunction('sqrt', [createTerm(1, { x: 2 }), createTerm(1)]);
|
|
450
|
+
|
|
451
|
+
console.log('\nš Function to LaTeX:');
|
|
452
|
+
console.log(`sin(x): ${functionToLatex(sinExpr)}`);
|
|
453
|
+
console.log(`ln(x + 1): ${functionToLatex(logExpr)}`);
|
|
454
|
+
console.log(`sqrt(x² + 1): ${functionToLatex(sqrtExpr)}`);
|
|
455
|
+
|
|
456
|
+
console.log('\nš LaTeX to Function:');
|
|
457
|
+
const parsedSin = parseFunction('\\sin{x}');
|
|
458
|
+
const parsedLog = parseFunction('\\ln{x + 1}');
|
|
459
|
+
const parsedSqrt = parseFunction('\\sqrt{x^{2} + 1}');
|
|
460
|
+
|
|
461
|
+
console.log(`\\sin{x}: ${JSON.stringify(parsedSin)}`);
|
|
462
|
+
console.log(`\\ln{x + 1}: ${JSON.stringify(parsedLog)}`);
|
|
463
|
+
console.log(`\\sqrt{x^{2} + 1}: ${JSON.stringify(parsedSqrt)}`);
|
|
464
|
+
|
|
465
|
+
console.log('\nš§® Function Evaluation:');
|
|
466
|
+
console.log(`sin(Ļ/2): ${evaluateFunction(sinExpr, { x: Math.PI / 2 })}`);
|
|
467
|
+
console.log(`ln(e): ${evaluateFunction(logExpr, { x: Math.E - 1 })}`);
|
|
468
|
+
console.log(`sqrt(4): ${evaluateFunction(sqrtExpr, { x: Math.sqrt(3) })}`);
|
|
469
|
+
|
|
470
|
+
console.log('\nš Supported Functions:');
|
|
471
|
+
Object.entries(SUPPORTED_FUNCTIONS).forEach(([name, info]) => {
|
|
472
|
+
console.log(` ${name}: ${info.latex} (${info.category})`);
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// Export all extended functions
|
|
477
|
+
export default {
|
|
478
|
+
// Core structures
|
|
479
|
+
createFunction,
|
|
480
|
+
isFunction,
|
|
481
|
+
getFunctionInfo,
|
|
482
|
+
|
|
483
|
+
// Conversion functions
|
|
484
|
+
functionToLatex,
|
|
485
|
+
parseFunction,
|
|
486
|
+
extendedSlangToLatex,
|
|
487
|
+
extendedLatexToSlang,
|
|
488
|
+
|
|
489
|
+
// Evaluation and differentiation
|
|
490
|
+
evaluateFunction,
|
|
491
|
+
differentiateFunction,
|
|
492
|
+
|
|
493
|
+
// Utilities
|
|
494
|
+
getFunctionsByCategory,
|
|
495
|
+
isSupportedFunction,
|
|
496
|
+
getFunctionLatex,
|
|
497
|
+
SUPPORTED_FUNCTIONS,
|
|
498
|
+
|
|
499
|
+
// Demo
|
|
500
|
+
demoExtendedFunctions
|
|
501
|
+
};
|