Skip to content

Commit

Permalink
feat: taylor expand, primary function 9c5f387
Browse files Browse the repository at this point in the history
  • Loading branch information
plantain-00 committed Nov 6, 2023
1 parent 45c3d2e commit 111a446
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 6 deletions.
19 changes: 17 additions & 2 deletions dev/expression-expansion.story.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react"
import { Button, Factor, StringEditor, composeExpression, deriveExpressionWith, divideFactors, expandExpression, expressionToFactors, factorToExpression, factorsToExpression, groupAllFactors, groupFactorsBy, groupFactorsByVariables, mathStyleExpressionToExpression, optimizeExpression, optimizeFactors, printMathStyleExpression, reactSvgRenderTarget, renderExpression, sortFactors } from "../src"
import { Button, Factor, StringEditor, composeExpression, deriveExpressionWith, divideFactors, expandExpression, expressionHasVariable, expressionToFactors, factorToExpression, factorsToExpression, groupAllFactors, groupFactorsBy, groupFactorsByVariables, mathStyleExpressionToExpression, optimizeExpression, optimizeFactors, printMathStyleExpression, reactSvgRenderTarget, renderExpression, sortFactors, taylorExpandExpressionWith } from "../src"
import { Expression2, parseExpression, printExpression, tokenizeExpression } from "expression-engine"

export default () => {
Expand Down Expand Up @@ -106,7 +106,7 @@ export default () => {
if (!secondValue) return
if (!value) return
const r = parseInputExpression(value)
const g = deriveExpressionWith(r, secondValue)
const g = optimizeExpression(deriveExpressionWith(r, secondValue), v => expressionHasVariable(v, secondValue))
setExpression(g)
setError(undefined)
} catch (error) {
Expand Down Expand Up @@ -143,6 +143,19 @@ export default () => {
setError(String(error))
}
}
const taylorExpand = (toPrimaryFunction: boolean) => {
try {
if (!secondValue) return
if (!value) return
const r = parseInputExpression(value)
const g = taylorExpandExpressionWith(r, secondValue, +thirdValue || 5, toPrimaryFunction)
setExpression(g)
setError(undefined)
} catch (error) {
setError(String(error))
setExpression(undefined)
}
}
const setText = (text: string) => {
setValue(text)
setError(undefined)
Expand Down Expand Up @@ -177,6 +190,8 @@ export default () => {
<Button disabled={!value || !secondValue} onClick={deriveWith}>derive with</Button>
<Button disabled={!value} onClick={optimize}>optimize</Button>
<Button disabled={!secondValue || !factors} onClick={groupByVariables}>group by variables</Button>
<Button disabled={!value || !secondValue} onClick={() => taylorExpand(false)}>taylor expand</Button>
<Button disabled={!value || !secondValue} onClick={() => taylorExpand(true)}>primary function</Button>
{factors && factors.length > 0 && <div style={{ border: '1px solid black', maxHeight: '150px', overflowY: 'auto', marginBottom: '5px' }}>
{factors.map((f, i) => <div key={i}><code>{outputExpression(factorToExpression(f))}</code></div>)}
</div>}
Expand Down
2 changes: 1 addition & 1 deletion main.bundle.js

Large diffs are not rendered by default.

25 changes: 25 additions & 0 deletions src/components/equation-solver/model.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1231,6 +1231,31 @@ export function optimizeExpression(
}
}
}
} else if (expression.type === 'CallExpression') {
expression.arguments = expression.arguments.map(arg => arg.type === 'SpreadElement' ? arg : optimize(arg))
if (expression.callee.type === 'Identifier') {
if (expression.callee.name === 'sin') {
if (expression.arguments.length === 1) {
const arg = expression.arguments[0]
if (arg.type === 'NumericLiteral') {
return {
type: 'NumericLiteral',
value: Math.sin(arg.value),
}
}
}
} else if (expression.callee.name === 'cos') {
if (expression.arguments.length === 1) {
const arg = expression.arguments[0]
if (arg.type === 'NumericLiteral') {
return {
type: 'NumericLiteral',
value: Math.cos(arg.value),
}
}
}
}
}
}
return expression
}
Expand Down
14 changes: 13 additions & 1 deletion src/components/equation-solver/solver.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,12 @@ export function composeExpression(
if (v && !Array.isArray(v)) {
return v
}
} else if (expression.type === 'CallExpression') {
expression.arguments.forEach((arg, i) => {
if (arg.type !== 'SpreadElement') {
expression.arguments[i] = composeExpression(arg, context)
}
})
}
return expression
}
Expand Down Expand Up @@ -442,7 +448,7 @@ function cloneEquation(equation: Equation): Equation {
}
}

function cloneExpression(expression: Expression): Expression {
export function cloneExpression(expression: Expression): Expression {
if (expression.type === 'BinaryExpression') {
return {
...expression,
Expand All @@ -456,6 +462,12 @@ function cloneExpression(expression: Expression): Expression {
argument: cloneExpression(expression.argument),
}
}
if (expression.type === 'CallExpression') {
return {
...expression,
arguments: expression.arguments.map(arg => arg.type === 'SpreadElement' ? arg : cloneExpression(arg)),
}
}
return {
...expression,
}
Expand Down
73 changes: 71 additions & 2 deletions src/utils/expression-expansion.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Expression2, SpreadElement2, priorizedBinaryOperators } from "expression-engine";
import { Factor, FactorVariable, divideFactors, expressionHasVariable, factorToExpression, getReverseOperator, isLetter, isNumber, powerFactor } from "../components";
import { Factor, FactorVariable, cloneExpression, composeExpression, divideFactors, expressionHasVariable, factorToExpression, getReverseOperator, isLetter, isNumber, optimizeExpression, powerFactor } from "../components";
import { factorial } from "./factorial";

export function expandExpression(e: Expression2): Expression2 {
if (e.type === 'BinaryExpression') {
Expand Down Expand Up @@ -531,7 +532,12 @@ export function deriveExpressionWith(e: Expression2, by: string): Expression2 {
return {
type: 'BinaryExpression',
operator: '*',
left: e.right,
left: {
type: 'BinaryExpression',
operator: '*',
left: deriveExpressionWith(e.left, by),
right: e.right,
},
right: {
type: 'BinaryExpression',
operator: '**',
Expand Down Expand Up @@ -616,3 +622,66 @@ export function deriveExpressionWith(e: Expression2, by: string): Expression2 {
}
return e
}

export function taylorExpandExpressionWith(e: Expression2, by: string, num: number, toPrimaryFunction?: boolean): Expression2 {
const hasVariable = (v: Expression2) => expressionHasVariable(v, by)
let result = optimizeExpression(composeExpression(cloneExpression(e), { [by]: { type: 'NumericLiteral', value: 0 } }), hasVariable)
if (toPrimaryFunction) {
result = optimizeExpression({
type: 'BinaryExpression',
operator: '*',
left: result,
right: {
type: 'Identifier',
name: by,
}
}, hasVariable)
}
for (let i = 1; i < num; i++) {
e = optimizeExpression(deriveExpressionWith(e, by), hasVariable)
const c = optimizeExpression(composeExpression(cloneExpression(e), { [by]: { type: 'NumericLiteral', value: 0 } }), hasVariable)
let d: Expression2 = {
type: 'NumericLiteral',
value: factorial(i)
}
if (toPrimaryFunction) {
d = {
type: 'BinaryExpression',
operator: '*',
left: d,
right: {
type: 'NumericLiteral',
value: i + 1,
},
}
}
result = optimizeExpression({
type: 'BinaryExpression',
left: {
type: 'BinaryExpression',
operator: '*',
left: {
type: 'BinaryExpression',
operator: '/',
left: c,
right: d,
},
right: {
type: 'BinaryExpression',
operator: '**',
left: {
type: 'Identifier',
name: by,
},
right: {
type: 'NumericLiteral',
value: toPrimaryFunction ? i + 1 : i,
},
}
},
operator: '+',
right: result,
}, hasVariable)
}
return result
}
8 changes: 8 additions & 0 deletions src/utils/factorial.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export function factorial(num: number): number {
for (let i = result.length; i <= num; i++) {
result.push(i * result[i - 1])
}
return result[num]
}

const result: number[] = [1]
1 change: 1 addition & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ export * from './bezier'
export * from './triangles'
export * from './nurbs'
export * from './parallel'
export * from './factorial'

0 comments on commit 111a446

Please sign in to comment.