27 декабря 2012 в 19:24

Математическая библиотека Numbers.js

Numbers.js добавляет к стандартным математическим возможностям JavaScript немного продвинутой математики — интегралы, операции над матрицами и комплексными числами, статистические функции, факторизацию и некоторые другие функции. Кроме того, библиотека определяет базовые арифметические операции над массивами — сложение, вычитание и умножение элементов, поиск минимума и максимума, случайное перемешивание массива и позволяет в явном виде задавать необходимую точность вычислений, что помогает избежать ошибок округления.

Примеры использования


Подключаем библиотеку под Node.js и вычисляем интеграл Римана (с разбиением на 200 отрезков и точностью 0.0001):

var numbers = require('numbers');

numbers.calculus.riemann(Math.sin, -2, 4, 200, 0.0001);

Использование собственных функций:

var myFunc = function(x) {
  return 2*Math.pow(x,2) + 1;
}

numbers.calculus.riemann(myFunc, -2, 4, 200);

Статистические функции:

numbers.statistic.mean(array);
numbers.statistic.median(array);
numbers.statistic.mode(array);
numbers.statistic.standardDev(array);
numbers.statistic.randomSample(lower, upper, n);
numbers.statistic.correlation(array1, array2);

Сложение матриц:

var array1 = [0, 1, 2];
var array2 = [3, 4, 5];

numbers.matrix.addition(array1, array2);

Наибольший общий делитель:

numbers.basic.gcd(x, y);

Библиотеке всего около месяца, но она смогла привлечь внимание разработчиков на Гитхабе и активно пополняется (пару недель назад набор функций был почти вдвое скромнее).

Ссылки


Гитхаб, документация.

Илья Сименко @ilya42
карма
528,7
рейтинг 0,0
full stack javascript developer
Похожие публикации
Самое читаемое Разработка

Комментарии (37)

  • –17
    Про похожую библиотеку писали ранее habrahabr.ru/post/163321/
    • +11
      У них нет ничего похожего кроме названия. Та библиотека предназначена для форматирования, а не для вычислений.
    • +8
      Топик не читай — комментарий скорее оставляй…
  • +4
    Интересно было бы увидеть Usecase с этой библиотекой. Единственное, что приходит на ум — продвинутые игры?
    • 0
      И вы это серьезно?
      • +7
        Какой развернутый аргументированный и главное полезный коммент. Я вот тоже задаюсь тем же вопросом про юзкейс
    • +4
      Да что угодно. Сейчас все типы софта уходят в веб. И 3д редакторы, и редакторы музыки, и программы для решения мат. задач. Все что есть в десктопе, вскоре может быть и в вебе. А без математики — ололо будет.
      • 0
        Ну с тяжелой математикой на клиенте, по моему логичнее организовать веб-сервис — расчет, который занимает больше чем 100ms, выгоднее сделать на сервере, чем грузить браузер (тут задумываемся над различным перформансом разных браузеров)

        Как модуль для Node.js или какой нибуть скриптовый игровой движок — годится, вот только что с этим делать на сервере (ну допустим можно в случае веб-сервиса на ноде, но такие проекты вроде изначально выгоднее реализовать на Java/.NET)
        • 0
          хотя вероятно для небольшой размерности вполне сгодится и на клиенте сделать, придумал например электронные таблицы — такое там показано
        • 0
          Математические задачи не имеют алгоритмической сложности.
          Если сложные задачи делать на сервере — он может лопнуть.
          • 0
            Это для меня сюрприз. Особенно про сервера.
          • 0
            Сервер-то не лопнет, а вот заставлять слабого клиента тужиться на серьезных вычислениях — это не гуманно.
            • 0
              Ну, не такие уж и слабые клиенты нынче пошли. Хотя, разумеется, клиент клиенту рознь, но всё же — какого уровня вычисления становятся серьёзными? Сейчас на иных клиентах, вон, десктоп игрушки запускают, портированные в JS, HD видео силами то же JS декодируют в реальном времени…
              • 0
                Если в арсенале имеются статистические функции, то это как бы подразумевает работу с большим объемом данных, а переносить это на какой-нибудь мобильный клиент, когда проще отдать уже готовый результат, как минимум странно. Хотя это, конечно, все inDepend.
        • 0
          Тут нельзя однозначно утверждать. Если результатами планируется воспользоваться как основой для других вычислений — то на клиент не спихнёшь, а в целом во многих прикладных задачах, имхо, куда выгоднее озадачить 1000 клиентов, чем под то же самое покупать сервера. Ну и опять же — то ли это вычисление одно на всех и его можно закешировать — это одно, а если это нечто уникальное — проще отдаль клиенту. Много pro et contra в этом вопросе.
        • 0
          WebWorkers нам помогут.
    • 0
      А разве не гораздо удобнее вместо того, чтобы городить дебри многострочного кода с умеренно кривыми (особенно при самостоятельном написании) реализациями численных методов, задействовать готовое решение в виде одного вызова функции?
    • 0
      Любые серверные приложения на Node.js, где нужна не только тривиальная арифметика. Домашняя бухгалтерия, игра, исследовательская база с большим количеством разных выброк данных и динамическим подсчётом результатов и статистик по ним.
    • +1
      У меня огромная торговая система для биржи написана на Node.js. В том числе я там сделал свою библиотечку для таких вещей как рассчет гауссова распределения и так далее. Появись эта либа на несколько лет раньше… :)
  • +1
    А работу с числами произвольной длины (как GMP) эта библиотека умеет?
    • 0
      Пока не умеет, никаких типов для длинных чисел там нет. Тут ведь всё от популярности и необходимости зависит, может, в будущем и вырастет до уровня GMP, но только если кому-нибудь это будет нужно на ноде.
    • 0
      Для произвольной длинны есть, например, leemon.com/crypto/BigInt.html и копия на github.com/vjeux/BigInt
  • 0
    У библиотеки 2 больших минуса:
    Она похоже не прописывается просто так в window в браузере. А как бы небрежно писать в доках «With node, simply require it: var numbers = require('numbers');», и не упоминать о первом синусе, как минимум некрасиво.

    Там как-то пофигистично относятся к производительности. Глянул 1-ю функцию, дальше наверное еще хуже. jsperf.com/numbers-js-sum
    • +1
      Все почему-то смотрят на использование в браузере. Однако, мне кажется, что даже по докам основной юзкеис — Node.js на сервере. С производительностью, думаю, со временем будет лучше, пока важно, чтобы был какой-то удобный и общий интерфейс доступа к функциям, а там уже народ подтянется и допилит не оптимальные решения.
      • 0
        Node.js это тот же V8 что и в WebKit-браузерах. Поэтому тесты в Хроме позволяют сравнить производительность на сервере.
        • 0
          Прошу прощения, про браузеры это было в тему комментариев чуть выше, где все ищут способ использования на клиенте. Да, в плане производительности библиотека не фонтан. Просто потому, что там везде стоят проверки и пока нет никаких оптимизаций. Такие вещи делаются со временем, не сразу и, вообще говоря, не всегда.
  • +3
    Подключаем библиотеку под Node.js и вычисляем интеграл Римана


    Понимаете, хотя разных интегралов действительно много, но с точки зрения численного счета бывают только интегралы Римана, а никаких других не бывает (если вдруг кому-то захочется просветить меня насчет других интегралов, которые таки считаются численно, то сразу скажу, что все они в конечном счете сводятся именно к интегралу Римана). И для вычисления этого одного типа интегралов есть как минимум два десятка широко применяемых сейчас методов и в каждом случае выбирается оптимальный (если этим занимается специалист). Так что и само название функции совершенно неинформативно и сама функция опасна (поскольку ничего не говорит о том, как и что она там на самом деле считает).

    позволяет в явном виде задавать необходимую точность вычислений, что помогает избежать ошибок округления


    Эх, если бы явное задание необходимой точности вычислений позволяло всегда достигать этой точности и магическим образом избегать ошибок округления, то мне бы давно пришлось уйти в веб-программисты (чур меня, чур).

    Все же язык в очень большой степени определяет мышление.
  • –5
    Понимаете, хотя разных интегралов действительно много

    Да? Не перечислите?

    если вдруг кому-то захочется просветить меня насчет других интегралов, которые таки считаются численно, то сразу скажу, что все они в конечном счете сводятся именно к интегралу Риман

    Интеграл Лебега. Сведите к Риману для функции Дирихле
    • +4
      И как Вы будете численно считать интеграл Лебега? Особенно интересуют функции, неинтегрируемые по Риману.
  • 0
    Библиотека для меня оказалась очень полезная, т.к. она решает кучу геморроя, связанного с анализом данных (для получения красивых графиков в админке). Потихоньку портирую ее на PHP, репозиторий на github: github.com/powder96/numbers.php. Буду рад, если пригодится кому-нибудь кроме меня.
  • +1
    if (Object.prototype.toString.call(arr) === '[object Array]') { ... }
    


    Зачем? Может я чего-то не понимаю, но почему так, а не

    if (arr instanceof Array) { ... }
    

    • +3
      На самом деле вообще дурная на голову проверка, потому что JS следует концепции duck-typing'а, а проверка её нарушает. Без неё я бы мог спокойно создать свой объект со свойством length и числовыми свойствами 0, 1, 2 и т. д. Или подсунуть в функцию arguments. А так я ограничен только объектами Array.
    • 0
      Может я чего-то не понимаю

      Ответ тут: JS Garden
      • +1
        Насчёт typeof ладно — его поведение не всегда очевидно и его стоит использовать только в случаях, определенных спецификацией.

        Но с instanceof-то что не так? Написанное здесь мне непонятно.

        <<цитата>>
        function Foo() {}
        function Bar() {}
        Bar.prototype = new Foo();
        
        new Bar() instanceof Bar; // true
        new Bar() instanceof Foo; // true
        
        // Всего лишь присваиваем Bar.prototype объект функции Foo,
        // но не экземпляра Foo
        Bar.prototype = Foo;            // # WAT???!!!
        new Bar() instanceof Foo; // false # А с чего бы должно быть true?
        
        <<конец цитаты>>

        Зачем присваивать прототипу не экземпляр, а класс и удивляться, что instanceof возвращает false?

        В общем:
        console.log([] instanceof Array); // true
        console.log(new Array() instanceof Array); // true
        console.log(Array() instanceof Array); // true
        

        Это работает.
        • 0
          Внимательно читали?
          Здесь надо отметить одну важную вещь: instanceof не работает на объектах, которые происходят из разных контекстов JavaScript (например, из различных документов в web-браузере), так как их конструкторы и правда не будут конструкторами тех самых объектов.

          Заключение

          Оператор instanceof должен использоваться только при обращении к пользовательским объектам, происходящим из одного контекста JavaScript.
          • 0
            Да, вы правы.
          • 0
            Спасибо, прочитал спецификацию, п. 15.2.4.2

            Буду знать.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.