npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

tadiff

v0.0.5-d

Published

Numeric and symbolic automatic differentation

Downloads

5

Readme

Tora's Automatic Differentiation

Reverse-mode automatic differentiation for javascript and typescript. Supports symbolic and numeric modes. Only scalars are supported right now.

Demo GitHub

Installation

npm install tadiff

Can also be built by cloning this repository and running npm run build. Tests can be run with npm run test.

Usage

Import the module in typescript import * as tad from "tadiff" or in javascript const tad = require("tadiff");

1. Build an expression

Building a math expression can be done by constructing the tree with the expression classes manually. This can get verbose very quickly so alternatively a string parser is available.

With expression objects:

import * as tad from "tadiff"

const varA = new tad.Variable("a")
const varB = new tad.Variable("b")
const expr = new tad.Divide(new tad.Multiply(new tad.Constant(4), new tad.Exp(new tad.Multiply(varA, varB))), new tad.Abs(new tad.Tan(varB)))

With string parser:

import * as tad from "tadiff"

const expr = tad.parseExpression("4 * exp(a * b) / abs(tan(b))")

// Get the variables of the expression.
// Stored as variables["a"] and variables["b"].
const vars = tad.getAllVariables(expr)

The expression can now be used for numeric evaluation using numbers. Values for all variables have to be passed. The expression can also be printed symbolically.

console.log(expr.evaluateToString())

const evalContext = {
    variableValues: {
        "a": 2,
        "b": 3
    }
}

console.log(expr.evaluate(evalContext))

2. Differentiate an expression

To differentiate an expression we first get all derivatives of an expression using getAllDerivatives. An output derivative has to be passed, this is typically just 1. This will produce all derivatives for all variables within the expression, although each variable has multiple derivatives which have to be summed up using getDerivativeForExpression. Note that this will give back an expression for the derivative. There is nothing special about this expression and it can be used just like any other expression, for example it can be used to build higher order derivatives.

const derivativeA = tad.getDerivativeForExpression(variables["a"], tad.getAllDerivatives(expr, new tad.Constant(1)))
const derivativeB = tad.getDerivativeForExpression(variables["b"], tad.getAllDerivatives(expr, new tad.Constant(1)))

It is also possible to have derivatives within the expression itself.

const derivativeExpr = tad.parseExpression("4 * D(x, cos(x * y))")

3. Interop with mathjs

This library uses mathjs for some of its operations such as parsing and simplification. To convert from tadiff expressions to mathjs expressions use expressionToNode. To convert from mathjs expressions to tadiff expressions use nodeToExpression. Here we will also have to pass a tad.Variable for each of the variable symbols occuring in the node tree.

A good use-case of converting to mathjs nodes is to simplify the tadiff expressions as no simplification is done in tadiff. expressionToNode automatically calls the simplify function.

Expressions

Listed below are the available expressions as both the tadiff classes and the string that can be used for string parsing.

| Operation | Class | String parsing | | --------- | :---: | :---------------: | | Constant number | Constant | a number (eg. 5, 3.45) | | Variable | Variable | letters (eg. v, px3) | | Differentiation | Derivative | D(x, f(x)) | | Addition | Add | + | | Subtraction | Subtract | - | | Multiplication | Multiply | * | | Division | Divide | / | | Exponentiation | Power | ^ | | Sine | Sin | sin | | Cosine | Cos | cos | | Tan | Tan | tan | | Natural logarithm | Log | log | | Negation | Negate | - | | Natural exponential | Exp | exp | | Sign | Sign | sign | | Absolute value | Abs | abs | | Square root | Power(..., 0.5) | sqrt |

Adding new operations

Creating new operations requires implementing the tad.Expression interface. Most importantly the used inputs are passed through the constructor and need to be returned from getDependencies. evaluateImpl will need to return the numeric result. evaluateToString returns a symbolic string. getDependencyDerivatives needs to return the derivatives for the dependencies in the same order as getDependencies. For more information look at the expressions.ts source code as most expressions are only around 20 lines long. If you do implement a new operation I would be happy to accept a pull request for it.