Язык Wolfram Language ™
Функция QuantityArray обеспечивает эффективное хранение и манипуляцию массивами объектов Quantity , и, таким образом, идеальнa для анализа данных с физическими единицами измерения. Продолжая интеграцию величин по всей системе, несколько функций теперь успешно работают с объектами QuantityArray .
RandomVariate[ParetoDistribution[Quantity[500., «USDollars»], 4], 300]

Объект QuantityArray эквивалентен обычному массиву элементов Quantity .
RandomVariate[ParetoDistribution[Quantity[500., «USDollars»], 4], 300]; Normal[Take[%, 10]]

Рассчитайте или загрузите массивы географических данных, например, высоты над уровнем моря и данных о магнитном поле.
Как разделить массив в wolfram mathematica
Есть большой массив данных, нужно разделить его на отдельные массивы. То есть, грубо говоря, есть график, на промежутке от 0 до 100 секунд, а мне нужно превратить его в пять отдельных графиков и массивов значений по 20 секунд (0-20, 20-40 итд)
Может кто-нибудь подскажет как это можно реализовать в математике?

Разделить массив на 2 части
Добрый вечер, возможно вопрос будет слишком простым для кого-то, но я информации именно по такому.
Разделить массив на 4 части
Прошу прощения за глупую просьбу, подскажите пожалуйста как разбить массив допустим из 40 элементов.
Разделить массив на части
Такое дело. Есть массив: $tochki = ; Этот массив мне необходимо разделить на несколько.

Разделить массив на две части
1. Разделить массив на две части, поместив в первую элементы, большие среднего арифметического их.
Нужен чёткий формат входных и выходных данных и пример (test case).
Допустим, входные данные — список пар data= , , . > и список интервалов intervals= , , . >, выходные — список списков пар.

Разделить массив на две части
Помогите решить адачку очень срочно надо Разделить массив на две части, поместив в первую.

Разделить массив на две части
Помогите с решением задачи. Условие вот такое "дан массив целых чисел, лежащих в диапазоне .
Разделить одномерный массив на две части
Здравствуйте, есть данная заготовка, как массив А, поделить на две, три равные части? Каждая часть.
Разделить байтовый массив на части и поместить с список
Есть байтовый массив massiv = bytearray() Нужно разделить этот массив на части, которые по длине.
Форматирование чисел при записи в файлы в Mathematica
Это продолжение этого вопроса о форматировании чисел и связанного с моим предыдущим вопрос о получении очень специфичного вывода Mathematica в текстовые файлы.
Мне часто приходится использовать в системе Mathematica высокую точность для генерации данных, но для визуализации требуется только относительно низкая точность. Я также хочу сохранить данные для последующего использования с сохранением всех имен символов и структур массивов. Для этого я использовал Save[] , но есть две связанные проблемы.
Высокая точность «засоряет» мои результаты лишними цифрами, от которых очень трудно избавиться:
где мне действительно нужно только 0,448799.
Оба из них приводят к значительным накладным расходам на размер файла, и, хотя хранилище на жестком диске дешевое, размер файла имеет огромное значение при последующей загрузке файлов обратно в Mathematica.
Итак, начиная, например, с aa , который содержит 50-значные числа произвольной точности в нерегулярном массиве, есть ли у меня встроенный способ получить текстовый файл, который будет читать что-то вроде этого
РЕДАКТИРОВАТЬ : у меня нет проблем с отображением чисел, отслеживанием точности чисел или изменением точности чисел. У меня проблемы с контролем того, как число записывается в файл.
Использование N , NumberForm , OutputForm , InputForm , *Form и т. Д., Все не работают должным образом с Save . И Save — единственный вариант экспорта, который я могу найти, который экспортирует структуру символов и массивов. Export и Put* можно использовать для лучшего управления форматированием, но они не включают символ (и в случае Export структура массива также теряется).
Wolfram Mathematica to Latex — массив, не полностью сохраняющий точность
У меня есть набор данных, которые я организовал в массиве в mathematica . Значение энергии должно быть таким, как показано ниже, когда я LaTex формате LaTex :
Theta Phi Energy (Хартри)
1.5329 & -1.5708 & -2775.20972374594\\
1.53476 & -1.25646 & -2775.209669993\\
1.54014 & -0.942167 & -2775.20947403366\\
Что я на самом деле получаю, когда копирую:
Я сделал несколько наборов данных и получил работу для всех, кроме одного. Кажется, есть набор из 100 пунктов, которые усекаются. Я попытался выполнить следующий код:
Проблема, похоже, находится в «энергиях100». Значения были введены с 12 цифрами, но обрезаются до 6, когда я вызываю значения.
«NumberForm» корректирует значения в mathematica но когда я LaTex форму LaTex она возвращается к укороченным значениям.
Любые идеи о том, как я могу получить эти ценности, какими они должны быть?
Wolfram alpha на русском языке. Wolfram mathematica как пользоваться, вольфрам альфа построить график онлайн. Вычисление параметров для настройки фотокамеры
Математический процессор онлайн, процессор знаний, который по вашему запросу предоставляет данные об окружающем мире в числах.
Работает все это с виду очень просто — вводишь свой запрос в поисковое поле, жмешь кнопку » How many students are in Russia now? » Вам интересно, что WolframAlpha ответит?
Как пользоваться WolframAlpha? Краткое описание возможностей сервиса на русском языке можно .
Чтобы детально познакомиться с WolframAlpha, и получше узнать, как использовать этот сервис для математических расчетов, стоит заглянуть на единственный веб-ресурс, где математические возможности WolframAlpha подробно, доступно и систематически описываются на русском языке — это блог Wolfram|Alpha по-русски .
Этот блог, пока единственный в этом роде, наверное еще и потому, что компетентное и полное описание математических возможностей WolframAlpha — задача достаточно сложная для студентов (энтузиастов или манимейкеров) (пусть даже очень хороших!), которые обычно берут на себя труд размещать и поддерживать математические ресурсы в Рунете. К тому же математические способности WolframAlpha, которые начинаются с самого что ни на есть элементарного, простираются слишком далеко за пределы стандартного университетского курса математики. Думаю, что их без натяжки можно сравнить с математическими способностями самого Стивена Вольфрама (Stephen Wolfram) — разработчика системы Mathematica и вдохновителя WolframAlpha.
Упомянутые способности отчасти иллюстрируют размещенные на сайте поддержки сервиса примеры решения задач из разных областей математики .
Взгляните, вот как WolframAlpha решает систему двух нелинейных алгебраических уравнений уравнений x^2-2y+1=0, x^3+y^2=6 :

Поскольку математический движок WolframAlpha работает на основе алгоритмов известной системы компьютерной математики Mathametica, этим результатам можно полностью доверять.
База знаний, из которой черпает свои способности WolframAlpha, постоянно пополняется актуальными материалами, фактическими и числовыми данными, алгоритмами — с каждым днем WolframAlpha становится «умнее»! Возможности этой системы лучше всего позволяют оценить многочисленные примеры ее использования из разных областей знания.
Кроме всего прочего, WolframAlpha предлагает разнообразные математические продукты : здесь и бесплатные виджеты для сайтов, и недорогие мобильные математические приложения для установки на смартфоны студентов, надстройки и плагины для основных браузеров, инструменты для разработчиков и всякое такое.
Например, для удобства использования вы можете вставить окно запроса Wolfram Alpha на свой сайт . Но если вы уже оценили возможности Wolfram Alpha, то наверняка захотите иметь этот инструмент всегда под рукой. Достаточно установить в ваш браузер подходящее расширение, тулбар или плагин из числа тех, которые предлагает официальный сайт Wolfram Alpha. С ними вы в любой момент сможете обратиться к Wolfram Alpha. Подробнее об этом .
С недавнего времени WolframAlpha начал использовать новый формат математических документов — CDF . Это формат, позволяющий создавать документы, содержащие интерактивные математические объекты. Например, в качестве таковых могут быть графики функций, дифференциальные уравнения и т.п. Параметры таких объектов пользователь может изменять при помощи встроенных в документ элементов управления, одновременно наблюдая происходящие изменения (похоже на Java-апплеты GeoGebra). На основе этого формата, а также виджетов Wolfram Alpha можно, например, создавать динамические иллюстрации математических правил и алгоритмов, проводить исследования, лабораторные занятия по математике.
Познакомьтесь с Wolfram Alpha немедленно, если вы уже не сделаии этого ранее!
В июле 2020 года NASA запускает экспедицию на Марс. Космический аппарат доставит на Марс электронный носитель с именами всех зарегистрированных участников экспедиции.
Регистрация участников открыта. Получите свой билет на Марс по этой ссылке .
Если этот пост решил вашу проблему или просто понравился вам, поделитесь ссылкой на него со своими друзьями в социальных сетях.
Один из этих вариантов кода нужно скопировать и вставить в код вашей веб-станицы, желательно между тегами и или же сразу после тега . По первому варианту MathJax подгружается быстрее и меньше тормозит страницу. Зато второй вариант автоматически отслеживает и подгружает свежие версии MathJax. Если вставить первый код, то его нужно будет периодически обновлять. Если вставить второй код, то страницы будут загружаться медленнее, зато вам не нужно будет постоянно следить за обновлениями MathJax.
Подключить MathJax проще всего в Blogger или WordPress: в панели управления сайтом добавьте виджет, предназначенный для вставки стороннего кода JavaScript, скопируйте в него первый или второй вариант кода загрузки, представленного выше, и разместите виджет поближе к началу шаблона (кстати, это вовсе не обязательно, поскольку скрипт MathJax загружается асинхронно). Вот и все. Теперь изучите синтаксис разметки MathML, LaTeX и ASCIIMathML, и вы готовы вставлять математические формулы на веб-страницы своего сайта.
Очередной канун Нового Года. морозная погода и снежинки на оконном стекле. Все это побудило меня вновь написать о. фракталах, и о том, что знает об этом Вольфрам Альфа. По этому поводу есть интересная статья , в которой имеются примеры двумерных фрактальных структур. Здесь же мы рассмотрим более сложные примеры трехмерных фракталов.
Фрактал можно наглядно представить (описать), как геометрическую фигуру или тело (имея ввиду, что и то и другое есть множество, в данном случае, множество точек), детали которой имеют такую же форму, как и сама исходная фигура. То есть, это самоподобная структура, рассматривая детали которой при увеличении, мы будем видеть ту же самую форму, что и без увеличения. Тогда как в случае обычной геометрической фигуры (не фрактала), при увеличении мы увидим детали, которые имеют более простую форму, чем сама исходная фигура. Например, при достаточно большом увеличении часть эллипса выглядит, как отрезок прямой. С фракталами такого не происходит: при любом их увеличении мы снова увидим ту же самую сложную форму, которая с каждым увеличением будет повторяться снова и снова.
Бенуа Мандельброт (Benoit Mandelbrot), основоположник науки о фракталах, в своей статье Фракталы и искусство во имя науки написал: «Фракталы — это геометрические формы, которые в равной степени сложны в своих деталях, как и в своей общей форме. То есть, если часть фрактала будет увеличена до размера целого, она будет выглядеть, как целое, или в точности, или, возможно, с небольшой деформацией».
Основные операции
- 314+278; 314—278; 314*278; 314^278;
- (a^2+b^2)+(a^2-b^2); (a^2+b^2)/(a^2-b^2); (a+b)^(2+2/3).
Знаки сравнения
Логические символы
Основные константы
Основные функции
Решение уравнений
Чтобы получить решение уравнения вида достаточно записать в строке Wolfram|Alpha: f[x]=0, при этом Вы получите некоторую дополнительную информацию, которая генерируется автоматически. Если же Вам необходимо только решение, то необходимо ввести: Solve=0, x].
- Solve+Cos+Sin=0,x] или Cos[x]+Cos+Sin=0;
- Solve или x^5+x^4+x+1=0;
- Solve-Log=0,x] или \Log-Log=0.
Если Ваше уравнение содержит несколько переменных, то запись: f=0 даст весьма разнообразный набор сведений, таких как решение в целых числах, частные производные функции и т. д. Чтобы получить решение уравнения вида по какой-либо одной из переменных, нужно написать в строке: Solve=0, j], где — интересующая Вас переменная.
- Cos=0 или Solve=0,x] или Solve=0,y];
- x^2+y^2-5=0 или Solve или Solve;
- x+y+z+t+p+q=9.
Решение неравенств
Решение в Wolfram Alpha неравенств типа , полностью аналогично решению уравнения . Нужно написать в строке WolframAlpha: f[x]>0 или f[x]>=0 или Solve>0, x] или Solve>=0,x].
- Cos-1/2>0 или Solve-1/2>0,x];
- x^2+5x+10>=0 или Solve.
Если Ваше неравенство содержит несколько переменных, то запись: f>0 или f>=0 даст весьма разнообразный набор сведений, как и в случае соответствующих уравнений. Чтобы получить решение такого неравенства по какой-либо одной из переменных нужно написать в строке: Solve>0,j] или Solve>=0,j], где — интересующая Вас переменная.
- Cos>0 или Solve>0,x] или Solve>0,y];
- x^2+y^3-5 =9.
Решение различных систем уравнений, неравенств и уравнений
Решение систем различного вида в Wolfram Alpha крайне просто. Достаточно набрать уравнения и неравенства Вашей системы, точно так, как это описано выше в пунктах 7. и 8., соединяя их союзом «И», который в Wolfram Alpha имеет вид &&.
- x^3+y^3==9&&x+y=1;
- x+y+z+p==1&&x+y-2z+3p=2&&x+y-p=-3;
- Sin+Cos==Sqrt/4&&x+y²=1;
- Log=0&&x+y+z Построение графиков функций
- Plot;
- Plot;
- Plot^x, ];
- Plot^x, , ].
Если Вам требуется построить сразу несколько графиков на одном рисунке, то перечислите их, используя союз «И»:Plot&&g[x]&&h[x]&&…&&t[x], ].
- Plot;
- Plot&&Sin&&Sin&&Sin, ].
Для того, чтобы построить график функции на прямоугольнике , нужно написать в строке Wolfram Alpha: Plot, , ]. К сожалению, диапазон изменения аппликаты пока что нельзя сделать конкретным. Тем не менее, интересно отметить, что при построении графика функции Вы получите не только поверхность, которую она определяет, но и «контурную карту» поверхности (линии уровня).
Математический анализ
Wolfram Alpha способен находить пределы функций, последовательностей, различные производные, определенные и неопределенные интегралы, решать дифференциальные уравнения и их системы и многое многое другое.
Пределы
Для того, чтобы найти предел последовательности нужно написать в строке Wolfram Alpha: Limit.
- Limit;
- Limit[(1+1/n)^n, n -> Infinity].
Найти предел функции при можно совершенно аналогично: Limit, x -> a].
- Limit/x, x -> 0];
- Limit[(1-x)/(1+x), x -> −1].
Производные

Для того, чтобы найти производную функции нужно написать в строке WolframAlpha: D, x]. Если Вам требуется найти производную n-го порядка, то следует написать: D, ]. В том случае, если Вам требуется найти частную производную функции напишите в окне гаджета: D, j], где — интересующая Вас переменная. Если нужно найти частную производную по некоторой переменной порядка n, то следует ввести: D, ], где означает тоже, что и Выше.
Важно подчеркнуть, что Wolfram Alpha выдает пошаговое нахождение производной при нажатии на «Show Steps» в правом верхнем углу выдаваемого ей ответа.
Интегралы
Для того, чтобы найти неопределенный интеграл от функции нужно написать в строке WolframAlpha: Integrate f[x], x. Найти определенный интеграл так же просто: Integrate, ] либо Integrate f(x), x=a..b.
Важно подчеркнуть, что Wolfram Alpha выдает пошаговое нахождение интеграла при нажатии на «Show Steps» в правом верхнем углу выдаваемого ей ответа.
- Integrate/x², x];
- Integrate, x];
- Integrate[(x+Sin[x])/x, ];
- Integrate/x^5, ].
Дифференциальные уравнения и их системы
Чтобы найти общее решение дифференциального уравнения нужно написать в строке WolframAlpha: F (при k-й производной y ставится k штрихов).
Если Вам требуется решить задачу Коши, то впишите: F, y[s]==A,y»[s]==B, …. Если нужно получить решение краевой задачи, что краевые условия, так же перечисляются через запятую, причем они должны иметь вид y[s]==S.
Решение систем дифференциальных уравнений также просто, достаточно вписать: , где f_1, f_2, …, f_n — дифференциальные уравнения, входящие в систему. К сожалению, решение задач Коши и краевых задач для систем дифференциальных уравнений пока-что не поддерживается.
- y»»»+y»»+y=Sin[x];
- y»»+y»+y=ArcSin[x];
- y»»+y+y^2=0;
- y»»=y, y==0, y»=4;
- y+x*y»=x, y=2;
- y»»»[x]+2y»»[x]-3y»[x]+y=x, y=1, y=2, y»=2;
- .
Ошибки при работе с системой
Система может допускать некоторые ошибки при решении сложных задач. К примеру, если попытаться решить неравенство , для чего ввести запрос solve (3x^2-18x+24)/(2x-2)-(3x-12)/(2x^2-6x+4) Laurent expansion z*cos(1/z) at z =0
Найти вычет функции в точке:
residue of (e^(1/(1-z^2))/((1-e^z)* sin(z^2))) at point z = 0
Чтобы упростить выражение f[x], наберите команду Simplify]
Комплексно сопряженное z*
Египетская дробь:
Egyptian fraction expansion:
Обратное преобразование Лапласа — ILT (находим оригинал по изображению)
2 Point ) функцией Plot, полученных линий в отдельности (условие If), подогнанного спектра (model/.fit)
AxesOrigin – интервал значений по оси Ox
PlotRange – интервал значений по оси Oy
PlotStyle – совокупность параметров графика
Axes->True – видимость осей
Thickness – толщина линий
AxesLabel – подписи по осям.
Выделение подогнанных значений по точкам (функция Evaluate), соответственно данным из файла (iName).
Вычисляем разницу между подогнанными значениями и экспериментальными данными.
Вывод на экран значения Diff – погрешности подгонки (функция ListLinePlot)
PlotRange – интервал значений по оси Ox
AxesOrigin – точка пересечения осей
FillingAxis – заполнение цветом области под графиком.
Присвоение массиву подогнанных значений имени tmp.
Дополнение массива ResultData массивом tmp на каждом шаге цикла (функция Append).
Вывод на экран массива значений tmp.
Окончание работы цикла.
Вывод на экран полученных значений в табличной форме с помощью функции TableForm.
2. Пример текста программы с использованием модели подгонки спектров Lorentz:
Программа, описанная в данном параграфе, по своей структуре практически полностью соответствует программе, описанной ранее, за исключением модели подгонки.


Вследствие того, что при использовании модели подгонки Lorentz нужно отдельно учитывать температурный фактор Бозе — Эйнштейна, в тексте программы появился новый фрагмент.
Задается массив чисел с именем BoseFactor. Он заполняется нулями, имеет два столбца и колличество строк такое же, как и у массива FullData.
Задается массив элементов Eva1, который является фактором Бозе — Эйнштейна для стоксовой компоненты спектра (вычисляется для каждой точки массива FullData (массив экспериментальных данных)). Запись x-> FullData [] означает, что в выражении Eva1 переменная x принимает все значения первого столбца массива элементов FullData.
Вычисляется массив с именем Diff1с помощью массива Eva1 (фактора Бозе — Эйнштейна). Данная запись означает, что второй столбец массива FullData поэлементно делится на массив факторов Бозе — Эйнштейна.
— присвоение значений каждому столбцу массива BoseFactor. первый столбец равенпервому стобцу массива экспериментальных данных Fulldata. Второму столбцу присваивается значение Diff1. Diff1 имеет смысл интенсивности в каждой точке экспериментального спектра, домноженную на обратный температурный фактор Бозе — Эйнштейна.
— выбор интересующего нас спектрального диапазона с помощью функции Select. Аналогичная строка присутствует и в тексте программы, представленной в П.1, но исходным массивом там служит массив экспериментальных данных FullData.
Программа, описанная в данном разделе
Wolfram Alpha
Wolfram Alpha – это система, предназначенная для хранения, обработки и выдачи пользователям структурированных данных по запросам на естественном английском языке. Wolfram Alpha не является поисковой системой. Это обусловлено тем, что она не предназначена для автоматической обработки неструктурированных текстов. Для ее работы необходимо предварительно вручную ввести фактографическую информацию в базу данных, а также разработать и реализовать алгоритмы ее обработки. Данные процедуры выполняются вручную сообществом разработчиков и экспертов системы Wolfram Alpha.
Из анализа описания системы система Wolfram Alpha следует, что получения ответов система Wolfram Alpha должна:
— уметь правильно разобрать запрос пользователя на естественном языке;
— иметь соответствующую структурированную фактографическую информацию;
— иметь алгоритмы обработки фактографической информации, обеспечивающие формирование ответа на запрос пользователя.
Таким образом, система Wolfram Alpha автоматически способна обрабатывать только заранее структурированную вручную фактографическую информацию, хранящуюся в СУДБ. Для синтеза ответов могут использоваться детерминированные алгоритмы выборки дополнительной информации и проведения расчетов по фактографическим данным. По данным формальным признакам система Wolfram Alpha может быть отнесена к известному классу систем Business Intelligence. Системы данного класса являются узко специализированными, что обусловливает незначительный спектр вопросов, на которые можно получить ответы системы Wolfram Alpha. Данное ограничение является системным, так как заложено в концепцию ее функционирования.
Таким образом, система Wolfram Alpha принципиально не позволяет пользователям искать ответы на любые интересующие их вопросы. Для этого предназначены вопросно-ответные поисковые системы. В отличие от системы Wolfram Alpha вопросно-ответные поисковые системы автоматически выявляют фактографическую информацию в обрабатываемых текстах и проводят ее индексацию без участия человека. За счет этого достигается существенное повышение полноты поиска. Для обобщения, проведения логического вывода и синтеза ответов вопросно-ответные поисковые системы также используют правила обработки фактографической информации. Однако, в отличие от системы Wolfram Alpha, правила логической обработки при этом представляют из себя не отдельные алгоритмы, направленные на решение заранее определенных сравнительно простых задач, а логические правила, которые могут автоматически применяться в динамически формируемой последовательности, определяющей порядок обработки первичной фактографической информации и формирования ответа на вопрос пользователя. Для проверки данных положений проведем сравнительное тестирование систем Wolfram Alpha и AskNet.ru.
35 команд, которые наглядно покажут, в чем Wolfram Alpha круче Google
Методика сравнительного тестирования систем Wolfram Alpha и AskNet.ru
Для проведения объективного тестирования системы Wolfram Alpha была взята коллекция вопросов дорожки вопросно-ответного поиска конференции TREC 2003 (http://trec.nist.gov/data/qa/2003_qadata/03QA.tasks/test.set.t12.txt). Это обусловлено тем, что данные тестовые вопросы имеют достаточно общий характер и могут быть использованы для тестирования систем вопросно-ответного поиска, работающих в интернете. В отличие от других тестовых дорожек вопросно-ответного поиска конференции TREC, используемые тестовые случаи конференции TREC 2003 не привязаны к тестовым коллекциям документов и не имеют группировки в тематически связанные последовательности вопросов. Тестовые коллекции семинара РОМИП не использовались ввиду того, что они предназначены для оценки качества поиска на русском языке, а система Wolfram Alpha не работает с русскоязычными запросами пользователей – «Wolfram Alpha сейчас не понимает русский язык». Тестирование проводилось путем последовательного поочередного ввода запросов из тестовой коллекции конференции TREC 2003. Тестирование систем было проведено по первым 71 тестовым случаям из 500, имеющихся в коллекции конференции TREC 2003. Это было обусловлено получением результатов тестирования, явно отражающих характеристики систем и позволяющих сформулировать достоверные выводы.
Результаты сравнительного тестирования систем Wolfram Alpha и AskNet.ru
Обобщенные результаты сравнительного тестирования систем Wolfram Alpha и AskNet.ru представлены в таблице.
Детальная информация по тестовым случаям приведена в приложении. Всего поведено тестовых случаев – 71.
При анализе выдачи вопросно-ответной поисковой системы AskNet.ru проводился учет наличия и номера позиции правильного ответа. Среднее значение позиции правильного ответа на странице, если ответ был найден, составляет 1,63. Это означает, что в среднем правильный ответ находился в выдаче вопросно-ответной поисковой системы AskNet.ru на первом или на втором месте.
Система Wolfram Alpha в 57 случаях не могла определить смысл запроса пользователя и выдавала сообщение «Wolfram Alpha isn’t sure what to do with your input». В трех тестовых случаях система Wolfram Alpha вывела диалог уточнения смыслового содержания введенного пользователем запроса.
Сервис онлайн построения графиков
Этот сервис создан в помощь школьникам и студентам в изучении математики (алгебры и геометрии) и физики и предназначен для онлайн построения графиков функций (обычных и параметрических) и графиков по точкам (графиков по значениям), а также графиков функций в полярной системе координат.
Просто введите формулу функции в поле «Графики:» и нажмите кнопку «Построить».
WolframAlpha
Почитайте в cправкe, как правильно вводить формулы функций.
Загляните в раздел примеров, наверняка, там есть графики функций, похожие на то, что нужно Вам, останется только слегка откорректировать готовые формулы функций.
Дополнительно на нашем сайте вы можете воспользоваться калькулятором матриц, с помощью которого можно производить различные преобразования и действия с матрицами онлайн.
Список функций
| Имя | Описание |
|---|---|
| логарифм по основанию 2 от x | |
| логарифм по основанию 10 от x | |
| логарифм x по основанию b log(x;3) | |
| натуральный логарифм (логарифм по основанию e (2.71828…)) от x | |
| экспонента от х (e в степени x) | |
| квадратный корень из x | |
| функция знака: -1 если x 0 и 0 если x=0 | |
| Тригонометрические функции | |
| синус х | |
| косинус х | |
| или | тангенс х |
| или | котангенс х |
| или | арксинус х |
| или | арккосинус х |
| или | арктангенс х |
| или | арккотангенс х |
| или | гиперболический синус х |
| или | гиперболический косинус х |
| или | гиперболический тангенс х |
| или | гиперболический котангенс х |
| гиперболический арксинус х | |
| гиперболический арккосинус х | |
| гиперболический арктангенс х | |
| гиперболический арккотангенс х |
Встроенные константы

Скачать бесплатный Wolfram Mathematica 10.0.2 для MS Windows 2000/XP/Vista/7/8

Резонный вопрос — почему именно эта система?
Потому, что принципы — это важно! Более чем 25-летнее развитие на основе смелых, инновационных дизайн-принципов, и как апофеоз — Wolfram Mathematica , мощнейшая вычислительная платформа.
Автоматизация . Ключ ко всем продуктивным вычислениям. Принципиальное отличие Wolfram Mathematica — применение разумной автоматизации во всех без исключения частях, от выбора алгоритмов, до выведения графиков и построения пользовательских интерфейсов. Как итог — получение высококачественных итоговых результатов без необходимости алгоритмических знаний, плюс быстродействие даже при экспертном использовании.
Интегрированная универсальная платформа . Специальные программы и добавочные тулбоксы мешают творческим разработкам новых идей и направлений, а их стоимость даже выше, чем их номинал. Для работы системы Wolfram Mathematica не нужно дополнительных пакетов, а значит и ненужных затрат. В программу заложены специализированные функции многих технических направлений, таких как вычислительная биология, вейвлет — анализ и т.д.
Гибридная символьно-численная методология .
Wolfram Alpha
Обычно символьные и численные вычисления считаются раздельными, а это — ущерб для пользователей. В системе Mathematica они оба тесно интегрированы, что позволяет делать построения гибридных методов для быстрого решения различных видов задач и при этом гарантирует результаты при сочетаний величин произвольных точностей.

Мультипарадигмальный язык .
Языков и стилей программирования много, однако ни один из них не подходит для всех задач идеально. Mathematica отличается от стандартных языков программирования одновременной поддержкой большого количества программных парадигм: процедурной, функциональной, основанной на правилах или шаблонах и многих других.
Встроенная информация . Поиск различных данных в стандартных базах, а так же их постоянные обновления занимают массу времени и отвлекают от основной работы. Mathematica весьма выгодно отличается от других программ наличием огромной коллекции тщательно отобранных данных различного вида, которые периодически расширяются и обновляются.
Рабочий процесс с документацией . При обширных работах с электронной документацией возникает необходимость использования нескольких программ: для обработки, для визуализации, для интерактивного преподнесения… Система Mathematica включает в себя все элементы этого рабочего проекта, плюс интерактивные приложения — вместе, в уникально гибких документах.
Похожие публикации:
- Где в archicad поменять язык
- Где находится windows movie maker в windows 7
- Для чего нужна программа icq new
- Как в archicad добавить объект в библиотеку
Реализация AES на Wolfram Mathematica

В статье Wolfram Mathematica: знакомство хаброчеловек 8bitjoey познакомил сообщество с отличным математическим пакетом Wolfram Mathematica.
Сегодня я продолжу экскурс в данный продукт. Чтобы совместить приятное с полезным, реализуем алгоритм AES при помощи данного продукта.
Вместо введения
Данная статья ориентирована на пользователей, которые уже хоть как-то знакомы с Mathematica. В рассматриваемом пакете очень детальная документация. Для вызова справки о функции, достаточно выделит её и нажать F1. Хорошее пояснение алгоритма AES (с примерами на JavaScript) было сделано в статье Как устроен AES.
Реализация AES
Для начала объявим глобальные переменные: подстановку (S-box), количество раундов (Nr), размер блока (Nb) и ключа (Nk).
Needs["FiniteFields`"]; fld = FiniteFields`GF[2, ]; Sbox = ; Nr = 10; Nb = 4; Nk = 4;
Первая строка подключает пакет для работы с конечнечными полями, а вторая объявляет его. =1+x+x^3+x^4+x^8 — неприводимый полином в поле GF(256).
Стоит напомнить, что все переменные в Mathematica глобальные. Для того, чтобы сделать переменную локальной используется функция Module. Ниже представлен код функции Main с тесно с ней связанные.
Rijndael[State_, CipherKey_] := Module[, ( tState = State; (*переписываем входное значение state для работы с ним*) ExpandedKey = KeyExpansion[CipherKey]; (*вызываем функцию разворачивания ключа и получаем массив ключей для всех раундов*) tState = AddRoundKey[tState, ExpandedKey[[1]]]; (*первое сложение с ключом*) For[i = 1, i < Nr, i++, ( tState = RRound[tState, ExpandedKey[[i + 1]]]; (*раундовое преобразование*) ) ]; tState = FinalRRound[tState, ExpandedKey[[Nr + 1]]]; (*финальное преобразование*) Return[tState]; ) ]; Main[] := Module[<>, ( Plaintext = FromDigits["00112233445566778899aabbccddeeff", 16]; Key = FromDigits["000102030405060708090a0b0c0d0e0f", 16]; CipherText = Rijndael[Plaintext, Key]; Print[BaseForm[CipherText, 16]]; Print[CipherText == 16^^69c4e0d86a7b0430d8cdb78070b4c55a]; ) ]; Main[];
Уже по привычке любую функцию записываю через Module, даже с пустыми параметрами. Открытый текст (Plaintext ) и ключ (Key), указанные в функции Main, взяты из fips 197 для тестирования кода. Перевод из 16-ой системы в 10-ую можно осуществить двумя способами: через макрос «16^^» или функцию FromDigits.
При написании криптографических алгоритмов в Mathematica часто используются функции IntegerDigits и FromDigits. Первая переводит число в любой базис, а вторая выполняет обратное действие.
State всегда представляет Integer. Это сделано с целью простого понимания алгоритма.
Ниже представлен код функции разворачивания ключа:
KeyExpansion[CipherKey_] := Module[, ( ExpandedKey = Array[#*0 &, Nr + 1]; (*объявляем массив размером Nr + 1 с нулевыми значениями*) ExpandedKey[[1]] = CipherKey; For[i = 1, i &, Nr]; Rcon[[1, 1]] = 1; For[i = 2, i = 256, Rcon[[i, 1]] = BitXor[Rcon[[i, 1]], 283]]; ) ]; For[i = 2, i
Код прокомментирован, если возникнут вопросы, то задавайте.
RRound[State_, Key_] := Module[, ( tState = State; tState = ByteSub[tState]; tState = ShiftRow[tState]; tState = MixColumn[tState]; tState = AddRoundKey[tState, Key]; Return[tState]; ) ]; FinalRRound[State_, Key_] := Module[, ( tState = State; tState = ByteSub[tState]; tState = ShiftRow[tState]; tState = AddRoundKey[tState, Key]; Return[tState]; ) ];
Функции цикловой (раундовой) функции и конечного преобразования, представленные в данном коде, думаю, не требуют объяснения — они обозначены точно так же, как и в fips 197.
AddRoundKey[State_, RoundKey_] := Module[, ( tState = BitXor[State, RoundKey]; Return[tState]; ) ];
Функция сложения с ключём очень примитивная: необходимо сложитьпо модулю 2 входное значение и ключ. Для этого используем функцию BitXor, которой на вход подаются Integer.
ByteSub[State_] := Module[, ( tState = State; tState = IntegerDigits[tState, 2^8, 16]; For[i = 1, i
- разбиение Integer на 16 байтов;
- непосредственно замена входных значений на числа из переменной Sbox;
- объединение байтов обратно в Integer.
ShiftRow[State_] := Module[, ( tState = State; tState = IntegerDigits[tState, 2^8, 16]; tState = Partition[tState, 4]; tState = Transpose[tState]; tState[[2]] = RotateLeft[tState[[2]], 1]; tState[[3]] = RotateLeft[tState[[3]], 2]; tState[[4]] = RotateLeft[tState[[4]], 3]; tState = Transpose[tState]; tState = Flatten[tState]; tState = FromDigits[tState, 2^8]; Return[tState]; ) ];
Код функции ShiftRow довольно простой. С 1 по 3 строчки — преобразование Integer в матрицу, следующие 3 строки осуществляют сдвиг 1, 2 и 3 байтов соответственно, потом переводим обратно из матрицы в Integer.
И самая интересная, с точки зрения математики, функция MixColumn, которую я прокомментирую непосредственно в коде. Если возникнут вопросы — задавайте.
MixColumn[State_] := Module[, ( tState = State; (*Преобразование Integer в матрицу*) tState = IntegerDigits[tState, 2^8, 16]; tState = Partition[tState, 4]; tState = Transpose[tState]; (*Матрица из стандатра fips 197*) M = (< , , , >); (*Перевод чисел в элементы поля*) For[i = 1, i
Выводы
Таким образом, при помощи Mathematica можно с лёгкостью реализовать алгоритмы шифрования, при условии, что знаешь математику (по большей части теорию чисел).
Послесловие
Последний месяц я программирую, используя продукт sage. Причиной перехода послужила недостаточная производительность Mathematica для криптологических потребностей и дороговизна продукта. Менять Mathematica на sage было сложновато, из-за недостаточно развитой встроенной помощи. Но после нескольких дней привыкаешь и всё становится просто. Легко освоить sage будет людям, знающим python.
Если есть вопросы по Mathematica задавайте! По возможноти постараюсь ответить.
Исходный код всего алгоритма можно взять отсюда.
- wolfram mathematica
- AES
Вычисление весового спектра линейного подпространства в Wolfram Mathematica

Данная статья обязана своим появлением одному достаточно давнему вопросу, который был задан в группе русскоязычной поддержки Wolfram Mathematica. Однако, ответ на него сильно разросся и в итоге стал жить самостоятельной жизнью и даже обзавелся собственными проблемами. Как понятно из названия статьи, задача была посвящена вычислению весового спектра, а значит напрямую относится к дискретной математике и линейной алгебре. Здесь же демонстрируется решение на языке программирования Wolfram Language. Не смотря на то, что суть задачи очень проста (для простых базисных векторов она вполне решается в уме), гораздо больший интерес представляет процесс оптимизации алгоритма нахождения весового спектра. Авторы придерживаются мнения, что рассматриваемая в данной статье задача и способы ее решения очень хорошо показывают способы применения таких приемов в языке Wolfram как компиляция и параллелизация. Таким образом основная цель, это показать один из эффективных способов ускорения кода в Mathematica.
Формулировка
Процитируем первоначальную формулировку задачи:
a) Назовем вектором строку битов (значения 0 или 1) фиксированной длины N: то есть, всего возможно 2 N различных векторов.
b) Введем операцию сложения по модулю 2 векторов (операция xor), которая по двум векторам a и b получает вектор a + b той же длины N.
c) Пусть дано множество A = i | i ∈ 1..K> из 0 ≤ K ≤ 2 N векторов. Назовем его порождающим: при помощи сложения ai множества A можно получить 2 K векторов вида ∑i=1..Kbiai, где bi равно либо 0, либо 1.
d) Весом вектора назовем количество единичных (ненулевых) битов в векторе: то есть, вес — это натуральное число от 0 до N.
Требуется для заданных порождающих множества векторов и числа N построить гистограмму (спектр) количества различных векторов по их весу.
Формат входных данных:
Текстовый файл из набора строк одинаковой длины по одному вектору в строке (символы 0 и 1 без разделителей).
Формат выходных данных:
Текстовый файл с парой значений вес/количество разделенных символом табуляции, по одной паре на строку, сортированный по числовому значению веса.
Решение вручную
Для начала попробуем решить задачу в уме, чтобы понять принцип подсчета весового спектра. Для этого будем использовать векторы минимальной длины. Затем потребуется всего лишь расширить алгоритм для любого количества векторов и любой размерности. Пусть дан базис из двух векторов по два элемента в каждом:
basis = , >
Так как векторов всего два, то всех возможных линейных комбинаций и, соответственно, комбинаций значений bi будет 2 K , где K — количество базисных векторов. Получаем 4 следующие линейные комбинации:
mod2(0 * , 0 * ) = mod2(0 * , 1 * ) = mod2(1 * , 0 * ) = mod2(1 * , 1 * ) =
Здесь предполагается, что функция сложения по модулю два уже определена должным образом. Получилось четыре вектора, размерность каждого при этом равна двум. Чтобы наконец вычислить спектр нужно просто посчитать число единиц в каждом получившемся векторе, то есть:
sum() = 0 sum() = 2 sum() = 1 sum() = 1
Посчитаем количества вхождений в получившийся список каждого веса. И тогда согласно требованиям задачи, результат должен выглядеть следующим образом:

Реализация простого алгоритма в Wolfram Mathematica
Итак, теперь все то, что было проделано в уме попробуем записать и автоматизировать при помощи Wolfram Language. Для начала создадим функцию, выполняющую сложение по модулю 2 (как и было сказано в условии задачи):
(* сложение пары бит *) mod2[b1_Integer, b2_Integer] := Mod[b1 + b2, 2] (* сложение произвольного числа бит *) mod2[b1_Integer, b2__Integer] := mod2[b1, mod2[b2]] (* расширение функции для работы со списками бит - векторами *) Attributes[mod2] :=
Следующая функция должна принимать на вход список векторов и список коэффициентов bi — вектор, длина которого равна числу векторов в базисе. Возвращать вектор той же размерности что и элементы базиса — линейная комбинация.
(* вычисление линейной комбинации с проверкой длины базиса *) combination[basis: ..>, b: ] /; Length[basis] == Length[b] := Apply[mod2, Table[basis[[i]] * b[[i]], ]]
Теперь нужно получить список всех возможных наборов коэффициентов bi. Очевидно, что их количество равно 2 K , а все возможные наборы — это просто запись всех чисел от 0 до 2 K -1 в двоичном представлении. Тогда список всех возможных линейных комбинаций можно получить так:
linearCombinations[basis: ..>] := With[, Table[combination[basis, IntegerDigits[i, 2, len]], ] ]
Результат выполнения функции выше — список длиной 2 K векторов. Все что нам остается сделать — это посчитать вес каждого вектора в этом списке, а затем подсчитать число встреч каждого веса:
weightSpectrum[basis: ..>] := Tally[Map[Total, lenearCombination[basis]]];
Проверим как это будет работать. Создадим базис из списка случайных векторов и подсчитаем весовой спектр:
(* проверка вычислений *) basis = RandomInteger[, ] ws = weightSpectrum[basis] ListPlot[ws, PlotTheme -> "Web"] (* Out[..] := , , , , , > Out[..]:= <, , , , , , > *)

Но что будет, если попытаться посчитать все тоже самое, но для большего количества векторов? Воспользуемся функцией AbsoluteTiming[] и посмотрим как себя ведет зависимость времени расчета от размера базиса.
basisList = Table[RandomInteger[, ], ]; timeList = Table[ , ]; ListPlot[timeList, PlotTheme -> "Web", Joined -> True]

Зависимость времени расчета от размера базиса при одинаковой длине векторов
Как видно на получившемся графике, время расчета увеличивается по экспоненте вместе с добавлением числа векторов в базис. Получается что для базиса из 15 векторов, где по 10 элементов в каждом, вычисление спектра длится около 10 секунд. Такое время расчета достаточно большое, но ничего удивительного в этом нет, так как выше уже было сказано, что количество линейных комбинаций растет по экспоненте вместе с ростом размера базиса, а значит и число операций увеличивается с той же скоростью. Еще одним фактором, который понижает скорость вычислений является то, что код не оптимален. Wolfram Language — интерпретируемый язык программирования и поэтому изначально не считается достаточно быстрым, а значит стандартные функции не дадут нам максимальной производительности. Для решения этой проблемы воспользуемся компиляцией.
Использование скомпилированных функций
Коротко о Compile
Синтаксис этой функции достаточно прост и очень похож на Function. В качестве результата Compile всегда возвращает "объект" — скомпилированную функцию, которая может быть применена к числовым значениям или спискам чисел. Compile не поддерживает работу со строками, символами или составными выражениями Wolfram Language (кроме выражений состоящих из List). Ниже приведено несколько примеров создания скомпилированных функций.
cSqr = Compile[, x^2]; cSqr[2.0] (* Out[..] := 4.0 *) cNorm = Compile[, Sqrt[x^2 + y^2]]; cNorm[3.0, 4.0] (* Out[..] := 5.0 *) cReIm = Compile[>, ]; cReIm[1 + I] (* Out[..] := *) cSum = Compile[>, Module[, Do[s += el, ]; s]]; cSum[] (* Out[..] := 10.0 *)
Все доступные опции и более подробные примеры можно посмотреть в официальной документации по ссылке выше. Теперь же перейдем непосредственно к функции для вычисления весового спектра.
Компиляция вычисления весового спектра
Как и в простом случае, можно создать несколько простых функций, а затем применять их по очереди для получения результата. А можно выполнять все операции в теле всего лишь одной функции. И тот и другой способ вполне могут быть реализованы. Мы ради разнообразия пойдем по второму пути.
cWeightSpectrumSimple = Compile[ >, Module[ < k = Length[basis], spectrum = Table[0, ] >, Do[ With[ < (* вычисление веса одной из 2^k - 1 комбинаций *) weight = Total[Mod[Total[IntegerDigits[b, 2, k] * basis], 2]] + 1 >, (* Размер списка spectrum равен максимально возможному весу. переменная weight на каждой итерации - это вес линейной комбинации таким образом здесь мы увеличиваем на 1 элемент списка, индекс которого равен вычисленному только что весу. В результате spectrum содержит сразу же весовой спектр. Такой способ подсчета очень похож на алгоритм сортировки подсчетом, что уже экономит значительное количество операций. *) spectrum[[weight]] = spectrum[[weight]] + 1 ], ]; Return[Transpose[]] ] ]
Как всегда проведем небольшой тест правильности работы этой функции. Точно также возьмем список случайных базисов с размерами от 2 до 15 векторов, где каждый вектор состоит из 10 элементов и попробуем посчитать время за которое происходит подсчет весового спектра:
basisList = Table[RandomInteger[, ], ]; timeList=Table[,]; ListLinePlot[timeList, PlotTheme -> "Web"]

Как видно из последнего графика — разница с результатом из предыдущей части огромна. Небольшая оптимизация алгоритма в виде оптимального подсчета веса на последнем этапе и использование компиляции приводит к ускорению в 200 раз! Этот результат интересен тем, что с одной стороны он показывает Mathematica как достаточно быстрый язык, при правильном применении, а с другой — в очередной раз доказывает, что Mathematica из-за интерпретируемости является медленным языком, если не знать тонкостей внутренней работы функций.
Код Грея
О Коде Грея
Во время размышлений над способом решением задачи возникла простая мысль. Если вдруг очередное значение bi равно нулю, то вообще нет необходимости умножать базисный вектор на это число и прибавлять его. Те векторы, которые перемножаются с нулевыми значениями не меняют результат. Сначала это показалось отлично мыслью и она даже заработала. Ведь во время перебора элементов списка bi просто выходило меньше операций сложения векторов. Затем пришла следующая идея. Вычитание и сложение векторов при вычислении линейной комбинации ничем не отличается. Это значит, что выполнимо следующее:
1 * + 0 * + 1 * == + + == -> + ==
То есть прибавление вектора к промежуточной сумме ничем не отличается от вычитания. И тут все сложилось в отличную идею! Что если вдруг окажется так, что в цикле по списку bi разница между представлением bk и bk+1 всего в нескольких битах? Тогда можно получить линейную комбинацию с номером k и прибавить к ней только те базисные вектора, индекс которых совпадает с номерами отличающихся бит между k и k+1. Результатом будет линейная комбинация k+1. А что если пойти еще дальше? Вдруг окажется так, что разница между соседними линейными комбинациями всего в одном векторе? Если строить прямую последовательность от 0 до 2 N -1 — то это невозможно. Но вдруг можно перемешать и расположить эти числа в каком-нибудь другом порядке? Именно это, как оказалось, и называется Кодом Грея -последовательность чисел, в которой отличие между соседями всего в одном разряде. В Википедии описан один из бесконечного множества кодов — зеркальный Код Грея и метод по его получению. Ниже представлен пример такой последовательности:
| Decimal | Binary | Gray | Gray as decimal |
|---|---|---|---|
| 0 | 000 | 000 | 0 |
| 1 | 001 | 001 | 1 |
| 2 | 010 | 011 | 3 |
| 3 | 011 | 010 | 2 |
| 4 | 100 | 110 | 6 |
| 5 | 101 | 111 | 7 |
| 6 | 110 | 101 | 5 |
| 7 | 111 | 100 | 4 |
Использование в скомпилированной функции
Использование компиляции уже значительно ускоряет подсчет весового спектра, теперь попробуем использовать код Грея и оптимизировать сложение векторов линейной комбинации. Только нужно понять как вычислить позицию изменившегося бита на каждом шаге. К счастью на помощь пришла 13-ая глава вот этой книги. Целиком подсчитать линейную комбинацию потребуется лишь один раз в самом начале. Но, так как точно известно, что первая линейная комбинация — это набор нулей, то и это не потребуется. С учетом всего вышесказанного можно создать еще более оптимизированную функцию для расчета весового спектра:
WeightSpectrumLinearSubspaceGrayCodeEasy = Compile[>, Module[< n = Dimensions[basevectors][[-1]], k = Length[basevectors], s = Table[0, ], currentVector = Table[0, ], (*первая комбинация всегда *) m = 0, l = 0 >, (*точно известно, что в спектре у 0 будет вес больше или равен 1 так как первая линейная комбинация всегда является нулевым вектором*) s[[1]] = 1; Do[ (*позиция изменившегося бита*) m = Log2[BitAnd[-1 - b, b + 1]] + 1; (*здесь уже нет полного сложения векторов, а только прибавление разницы*) currentVector = BitXor[currentVector, basevectors[[m]]]; (*подсчет веса*) l = Total[currentVector] + 1; s[[l]] = s[[l]] + 1, ]; (* Return *) s ], (*дополнительные опции компиляции, вторая может использоваться только при наличии компилятора*) RuntimeOptions -> "Speed", (*CompilationTarget -> "C",*) CompilationOptions -> True> ];
Вот пример результата для базиса из 16 векторов размерностью 512:
basis = RandomInteger[, ]; ListPlot[WeightSpectrumLinearSubspaceGrayCodeEasy[basis], PlotTheme -> "Web", PlotRange -> All, Filling -> Bottom]

В качестве результата возвращается одномерный список весов. Такого вида список тоже вполне корректен, так как его легко привести к виду из предыдущей части. Первый элемент соответствует частоте встречи вектора нулевого веса. Последний — частоте встречи вектора из единиц. Используем тот же самый код для тестирования производительности:
basisList = Table[RandomInteger[, ], ]; timeList=Table[,]; ListLinePlot[timeList, PlotTheme -> "Web"]

Время вычислений от размера базиса
В результате для последнего базиса из списка из 15 векторов скорость вычислений выросла еще в 5 раз. Но это немного обманчивый результат. Чтобы понять насколько повысилась эффективность необходимо посчитать отношение времени расчета для двух последних функций:
basisList = Table[RandomInteger[, ], ]; timeList=Table[< Length[basis], First[RepeatedTiming[cWeightSpectrumSimple[basis]]] / First[RepeatedTiming[WeightSpectrumLinearSubspaceGrayCodeEasy[basis]]] >, ]; ListLinePlot[timeList, PlotTheme -> "Web"]

Отношение времени расчета спектра с использованием кода Грея и без
Из этого графика становится понятно, что на самом деле этот алгоритм понизил сложность вычислений на одну степень. И это будет тем заметнее и эффективнее чем больше размерность векторов в базисе. Вот такой результат получится если базис состоит из векторов с размерностью 128:

Параллелизация
Как что-то посчитать в Mathematica параллельно
В Mathematica есть небольшой набор функций, которые умеют выполнять асинхронные вычисления на разных ядрах. Только теперь надо определить с терминологией. Ведь запущенный процесс, который представляет собой что-то похожее на виртуальную машину в Mathematica тоже называется ядром, т.е. Kernel. Ядро Математики — это интерактивная среда исполнения, работающая в режиме интерпретатора. Каждое ядро занимает обязательно один процесс в системе. Потоков в привычном понимании язык не реализует. Соответственно, нужно понимать, что у ядер в стандартном использовании не будет общей памяти. В основном все функции такого типа начинают на Parallel. Самый просто способ посчитать что-то асинхронно:
ParallelTable[i^2,] (*Out[..] := *)
Подобным образом работает целый ряд функций:
ParallelMap, ParallelDo, ParallelProduct, ParallelSum,…
Есть несколько способов проверить, что это действительно выполнялось не на одном ядре. Вот так можно получить все запущенные ядра:
Kernels[] (* Out[..] := <"KernelObject"[1, "local"], . , "KernelObject"[N, "local"]>*)
В списке будут все запущенные на данный момент процессы. При этом они же должны отображаться и в диспетчере задач.

Два из шести процессов отвечают за запущенную сессию, а остальные — локальные ядра, которые используются для параллельных вычислений. При этом по умолчанию количество локальных ядер Mathematica совпадает с количеством физических ядер процессора. Но никто не мешает создать и большее количество. Делается это с помощью LaunchKernels[n]. В результате запускается дополнительно n ядер. А число доступных ядер процессора можно посмотреть в переменной $KernelCount.
Перечисленные в начале функции производят автоматическое распределение задач по процессам. Однако, есть способ самостоятельно отправить код выполняться на определенном ядре. Делается это при помощи ParallelEvaluate + ParallelSubmit:
ParallelEvaluate[$KernelID, Kernels[][[1 ;; 4 ;; 2]]] (* Out[..] := *)
Это набора функций будет достаточно, чтобы суметь распараллелить задачу по вычислению весового спектра.
Разделение основного цикла на части
Проверим, действительно ли вычисления происходят параллельно. Для четырех физических ядер это означает что вычисление на всех четырех ядрах займет столько же времени сколько и на одном:
basis = RandomInteger[, ]; AbsoluteTiming[WeightSpectrumLinearSubspaceGrayCodeEasy[basis];][[1]] AbsoluteTiming[ParallelEvaluate[WeightSpectrumLinearSubspaceGrayCodeEasy[basis]];][[1]] (* Out[..] := 6.518. Out[..] := 8.790. *)
Разница во времени есть, но не четырехкратная. Значит с этим все нормально. Следующим шагом надо понять, как разделить задачу на несколько частей. Самое логичное и эффективное -вычислять только часть линейных комбинаций на каждом ядре. То есть в результате каждое ядро возвращает частичный спектр. Но как поделить список bi. Ведь он не является прямой последовательностью! В этом случае необходима функция, которая вычисляет значение из последовательности Кода Грея по индексу. Делается это вот так:
grayNum[basis_List, index_Integer] := IntegerDigits[BitXor[index, Quotient[index, 2]], 2, Length[basis]] Grid[Table[, , >, i]]>, ]]
| index | code |
|---|---|
| 0 | 000 |
| 1 | 001 |
| 2 | 011 |
| 3 | 010 |
| 4 | 110 |
| 5 | 111 |
| 6 | 101 |
| 7 | 100 |
Теперь модифицируем скомпилированную функцию так, чтобы она считала только частичный спектр в определенном диапазоне индексов линейных комбинаций:
WeightSpectrumLinearSubspaceGrayCodeRange = Compile[, >, Module[< n = Dimensions[basis][[-1]], k = Length[basis], s = Table[0, ], currentVector = Table[0, ], m = 0, l = 0 >, (*вычисляем первый вектор и его вес*) If[range[[1]] =!= 0, currentVector = Mod[Total[basis Reverse[IntegerDigits[BitXor[range[[1]], Quotient[range[[1]] + 1, 2]], 2, k]]], 2]; ]; Mod[Total[basis IntegerDigits[BitXor[range[[1]] - 1, Quotient[range[[1]] - 1, 2]], 2, k]], 2]; s[[Total[currentVector] + 1]] = 1; Do[ m = Log2[BitAnd[-1 - b, b + 1]] + 1; currentVector = BitXor[currentVector, basis[[m]]]; l = Total[currentVector] + 1; s[[l]] = s[[l]] + 1, ]; (* Return *) s ], (*дополнительные опции компиляции, вторая может использоваться только при наличии компилятора*) RuntimeOptions -> "Speed", (*CompilationTarget -> "C",*) CompilationOptions -> True> ];
То есть, если раньше функция считала все комбинации с номерами от 0 до 2 N -1, то теперь этот диапазон можно задать вручную. Теперь попытаемся придумать как разделить этот самый диапазон на равные части в зависимости от количества доступных ядер:
partition[, n_Integer] := With[, Join[ >, Table[, ], <<(n - 1) * dn, iN>> ] ]
Теперь чтобы вычислить полный спектр таким образон необходимо посчитать его на каждом из отрезков, а затем все результаты сложить. Например:
WeightSpectrumLinearSubspaceGrayCodeEasy[, , >] WeightSpectrumLinearSubspaceGrayCodeRange[, , >, ] WeightSpectrumLinearSubspaceGrayCodeRange[, , >, ] (* Out[..] := = Out[..] := + Out[..] := *)
Последним этапом нужно отправить эти вычисления на разные ядра:
WeightSpectrumLinearSubspaceGrayCodeParallel[basis: ..>] := With[< kernels = (If[Kernels[] === <>, LaunchKernels[]]; Kernels[]), parts = partition[, Length[Kernels[]]] >, Total[WaitAll[Table[ ParallelEvaluate[ParallelSubmit[WeightSpectrumLinearSubspaceGrayCodeRange[basis, parts[[$KernelID]]]], kernel], ]]] ]
Здесь нужно внести ясность. Такая связка ParallelEvaluate + ParallelSubmit для того, чтобы в ручную контролировать то, на каком ядре будет выполняться какой участок кода. ParallelEvaluate в общем случае не может разобраться с тем, как правильно выполнять асинхронный код и делает это в итоге в один поток. А ParallelSubmit в общем случае не дает возможность точно указать нужное ядро, а выбирает его автоматически.
Проверим работает ли эта функция:
ListPlot[WeightSpectrumLinearSubspaceGrayCodeParallel[RandomInteger[, ]], PlotRange -> All, PlotTheme -> "Web", Filling -> Bottom]

И как обычно посмотрим на разницу в скорости вычислений. Так как испоьлзуется ноутбук с 4-х ядерным процессором — ожидается ускорение примерно в 4 раза. Плюс надо учитывать время на деление задач и сложение итогового результата:
basis = RandomInteger[, ]; AbsoluteTiming[WeightSpectrumLinearSubspaceGrayCodeEasy[basis];] AbsoluteTiming[WeightSpectrumLinearSubspaceGrayCodeParallel[basis];] (* Out[..] := Out[..] := *)
Естественно при наличии большего числа ядер процессора разница будет заметнее. Теперь попробуем посчитать спектр базиса побольше. Интересно сколько это займет времени? Допустим будем считать увеличивать размер базиса до тех пор, пока на один расчет не уйдет больше минуты:
spectrums = Block[, Reap[ While[True, i++; basis = RandomInteger[, ]; Sow[res = AbsoluteTiming[WeightSpectrumLinearSubspaceGrayCodeParallel[basis]]]; If[res[[1]] > 60, Break[]] ] ][[-1, -1]]] ListPlot[spectrums[[-1, -1]], PlotLabel->Row[], Filling->Bottom,PlotTheme->"Web",PlotRange->All]

На картинке хорошо видно, что за полторы минуты функция может посчитать спектр для базиса из 29 векторов. Это очень хороший результат, при учете, что самый первый вариант, который не использует компиляцию, код Грея, параллелизацию все тоже самое вряд ли способен выполнить за разумное время. Время вычислений будет больше в тысячи раз, если даже для 15 векторов с размерностью 10 расчет занимал больше 10 секунд.
Заключение
Мне неизвестно кто и где применяет все то, что было описано в статье. Википедия говорит, что Код Грея имеет практическое назначение. Также мне известно, что вычисление спектров часто бывает связано с шифрованием и некоторыми другими задачами линейной алгебры. Но, еще раз стоит отметить, что здесь мне хотелось в первую очередь продемонстрировать пошаговое решение задачи и пошаговое применение разного рода оптимизаций: улучшение самого алгоритма, использование возможностей языка и использование аппаратных возможностей многоядерных процессоров. Я искренне надеюсь, что статья будет полезна и интересна.
P.S. Автор выражает благодарность Александру Банникову, так как именно он является инициатором в деле по поиску оптимального решения этой задачи.
- wolfram language
- parallel computing
- Блог компании Wolfram Research
- Занимательные задачки
- Математика
