Socket
Socket
Sign inDemoInstall

2d-algebra

Package Overview
Dependencies
0
Maintainers
1
Versions
19
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    2d-algebra

Library for building expressions and computing derivatives


Version published
Weekly downloads
3
increased by200%
Maintainers
1
Install size
63.4 kB
Created
Weekly downloads
 

Readme

Source

2D Algebra Typescript Module

A library for programatically building up large systems of equations for numerical analysis.

NPM Version Downloads Stats

Technologies

Project is created with:

  • Typescript version: 3.6.2
  • Node version: 12.10.0
  • No external dependencies

Setup

To use this library

npm install 2d-algebra yarn add 2d-algebra

Then in your code you can import and use the expression(...) function to fluently build expressions.

import expression from "2d-algebra";

const m = 3; // slope
const b = 4; // point
const x = Symbol("x");
const y = Symbol(); // naming your symbols is optional
const line = expression(m).times(x).plus(b).eq(y);

const solution = new Map([[x, 7483], [y, 22453]]);

const err = line.eval(solution)
// err === 0

const dxLine = line.derivative(x);
const xSlope = dxLine.eval(solution);
// xSlope === 0

const dyLine = line.derivative(y);
const ySlope = dyLine.eval(solution);
// ySlope === 0

const dx2Line = dxLine.derivative(x);
const xCup = dx2Line.eval(solution);
// xCup > 0

const dy2Line = dyLine.derivative(y);
const yCup = dx2Line.eval(solution);
// yCup > 0

const dxdyLine = dxLine.derivative(y);
const hessianDet = dx2Line.times(dy2Line).minus(dxdyLine.squared());    
const xySaddle = hessianDet.eval(solution);
// xySaddle === 0

API

Creating a new Expression is a easy as starting it off with the first symbol or number.

const one = expression(1).eval(new Map());

From there you can use the following methods to additional complexity. All methods do not change the existing Expression but return a new Expression (AKA immutable). The b argument must be either a symbol, number or Expression.

MethodDescription
plus(b)add the top term to b and simplifies
minus(b)equivalent to plus(-b)
times(b)multiplies the top term with b and simplifies
dividedBy(b)equivalent to times(b^-1)
toThe(n)raises the top term by the number n.
squared()equivalent to toThe(2)
sin()replaces the top term with the sin(a)
cos()replaces the top term with the cos(a)
tan()equivalent to sin(a).dividedBy(cos(a))
eq(b)equivalent to minus(b).squared()

Once the expression is complete you can use the following methods

MethodDescription
eval(Map<symbol, number>)fully evaluate the expression. throw error if not all of the symbols are defined.
apply(Map<symbol, Expression>)substitute one or more variables with expressions and return the new expression.
derivative(symbol)compute the partial derivative with respect to one symbol.
toString()makes a ASCII art tree diagram of the expression tree.

Why no parentheses? ( or )

At this point you've probably run into an expression where you only want to apply the next times or squared to only part of what comes before. For example the unit (of radius 1) circle one might mistakenly define it as:

const r = 1;
const x = Symbol();
const y = Symbol();

// EXAMPLE OF HOW TO DO IT WRONG
const circle = expression(x)
  .squared()  //   x^2 
  .plus(y)    //   x^2 + y
  .squared()  //  (x^2 + y)^2
  .eq(r)      //  (x^2 + y)^2 - r)^2
  .squared(); // ((x^2 + y)^2 - r)^2)^2

Would produce ((x^2 + y)^2 - r)^2)^2. When I would have expected (x^2 + y^2 - r^2)^2. Notice how in the wrong expression each application of the squared() applied to the whole of expression defined up to that point. To fix this I'll introduce the push(b) method that starts a new mini expression separate from what has been defined so far. When push is used new zero argument versions of plus(), minus(), times(), divide(), and eq() are available to cause the two mini expressions to be merged into one again.

The corrected code now looks like:

const circle = expression(x)
  .squared()  //  x^2
  .push(y)    //  x^2 | y   <---- y here is separate from x^2
  .squared()  //  x^2 | y^2 <---- now that y is squared on its own
  .plus()     //  x^2 + y^2 <---- merge y^2 by adding it to x^2
  .push(r)    //  x^2 + y^2 | r
  .squared()  //  x^2 + y^2 | r^2
  .eq();      // (x^2 + y^2 - r^2)^2

Contributing

To submit changes to the project

  1. fork and clone the git repository
  2. make changes to the tests and source.
    • If making changes to the Expression class make sure matching changes are made to ExpressionStack.
    • Changes to simplification logic can be quite tricky with all the symbiotic recursion.
  3. run yarn test. if they fail goto step 2
  4. push changes to your fork
  5. submit pull request

Other ussful commands

  • yarn compile: compile the typescript code to POJS
  • yarn test: run unit tests once.
  • yarn watch: continuously run unit tests.

Keywords

FAQs

Last updated on 11 Jan 2022

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc