Разрабатывайте пользовательские алгоритмы Длинный массив

Длинные массивы - это мощный, интуитивно понятный способ работы с большими наборами данных с помощью традиционного MATLAB® синтаксис. Однако, поскольку длинные массивы работают с блоками данных, каждый из которых по отдельности помещается в память, традиционные алгоритмы большинства функций необходимо обновить, чтобы использовать параллелизированный подход для поддержки длинных массивов. В этой теме показано, как разработать свои собственные параллелизированные алгоритмы для работы с длинные массивы.

В настоящее время доступными подходами для применения пользовательских функций к длинные массивы являются:

Независимо от того, какую операцию вы выбираете, существуют опции, эффективность факторов и общие проблемы, которые применяются ко всем подходам.

Причины реализации пользовательских алгоритмов

Наиболее распространенные математические функции и операции MATLAB уже поддерживают длинные массивы. Если функциональность уже поддерживается, запись собственного алгоритма может оказаться ненужной.

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

  • Реализация функций, не поддерживаемых в настоящее время - Если конкретная функция в данный момент не поддерживает длинные массивы, то можно использовать API, описанные здесь, чтобы написать версию этой функции, которая поддерживает длинные массивы.

  • Использование существующего кода - Если у вас есть существующий код, который выполняет некоторые операции с данными в памяти, то только с незначительными изменениями вы можете сделать его совместимым для работы с длинными массивами. Этот подход избегает необходимости преобразования кода в соответствии с подмножеством языка MATLAB, который поддерживает длинные массивы.

  • Gain Эффективности - Для примера можно переписать функцию MATLAB как MEX-функцию C++, а затем можно использовать описанные здесь API, чтобы вызвать MEX-функцию для работы с данными.

  • Использовать предпочитаемую внешнюю библиотеку - Для совместимости в организации иногда требуется использовать определенную внешнюю библиотеку для определенных вычислений. Можно использовать API, описанные здесь, для повторной имплементации функции с этими внешними библиотеками.

Поддерживаемые API

Поддерживаемые API предназначены для расширенного использования и не включают обширную проверку входных параметров. Рассчитывайте потратить некоторое время на тестирование, чтобы дополнительные функции, которые вы реализуете, удовлетворяли всем требованиям и выполняли ожидаемые расчеты. Здесь перечислены поддерживаемые в настоящее время API для разработки алгоритмов длинный массив.

Имя функции пакетаОписание
matlab.tall.transformПрименить указанную функцию к каждому блоку одного или нескольких длинные массивы.
matlab.tall.reduceПрименить указанную функцию к каждому блоку одного или нескольких длинные массивы. Затем передайте выход этой функции во вторую функцию редукции.
matlab.tall.movingWindowПрименить функцию окна для блоков данных.
matlab.tall.blockMovingWindow

Применить функцию окна и блочное сокращение к заполненным блокам данных.

Фон: Блоки Длинный массив

Когда вы создаете длинный массив из datastore, базовый datastore облегчает перемещение данных во время вычисления. Данные перемещаются дискретными частями, называемыми блоками, где каждый блок является набором последовательных строк, которые могут помещаться в памяти. Например, один блок 2-D массива (такого как таблица) X(n:m,:). Размер каждого блока основан на значении ReadSize свойство datastore, но блок не всегда является таким точным размером. В целях разработки алгоритмов длинный массив, длинный массив рассматривается как вертикальная конкатенация многих таких блоков.

Блоки данного массива выбираются во время выполнения на основе доступной памяти, поэтому они могут быть динамическими. Поэтому блоки могут быть не совсем одинакового размера между запусками. Если на компьютере есть изменения, которые влияют на доступную память, это может повлиять на размер блоков.

Хотя эта страница ссылается только на блоки и строки в 2-D смысле, эти концепции распространяются на N-D длинные массивы. Размер блока ограничен только в первой размерности, поэтому блок включает все элементы в других размерностях; для примера, X(n:m,:,:,...). Кроме того, вместо строк N-D- массивов имеют такие срезы, как X(p,:,:,...).

Одношаговая операция преобразования

matlab.tall.transform функция применяет одну функцию к каждому блоку длинный массив, поэтому можно использовать ее для применения блочного преобразования, фильтрации или сокращения данных. Например, можно удалить строки с определенными значениями, центрировать и масштабировать данные или обнаружить определенные обстоятельства и преобразовать определенные части данных. Эти рисунки показывают, что происходит с блоками в массиве, когда они управляются matlab.tall.transform.

Операция

Описание

Примеры

Преобразование - количество строк в каждом блоке остается неизменным, но изменяются значения.

  • A = matlab.tall.transform(@sin, tX) вычисляет синус элементов в каждом блоке.

  • A = matlab.tall.transform(@(X) X.^2, tX) строит квадраты элементов в каждом блоке.

Фильтрация - количество строк в каждом блоке уменьшено, поэтому блоки в новом массиве могут включать строки, первоначально существующие в других блоках.

  • A = matlab.tall.transform(@(X) topkrows(X,5), tX) извлекает только 5 лучших строк из каждого блока, отфильтровывая другие строки.

  • A = matlab.tall.transform(@sum, tX) вычисляет сумму элементов в каждом блоке, что уменьшает каждый блок до скаляра. Количество элементов в A равно количеству блоков.

Синтаксис преобразования

Типовой синтаксис для применения одношагового преобразования:

[tA, tB, tC, ...] = matlab.tall.transform(fcn, tX, tY, tZ, ...)

Функциональные требования к fcn

Общая функциональная подпись fcn является

[a, b, c, ...] = fcn(x, y, z, ...)
fcn должны удовлетворять этим требованиям:

  1. Входные параметры - Входы [x, y, z, ...] являются блоками данных, которые помещаются в памяти. Блоки генерируются путем извлечения данных из соответствующих входов длинный массив [tX, tY, tZ, ...]. Входы [x, y, z, ...] удовлетворить этим свойствам:

    • Все [x, y, z, ...] иметь тот же размер в первой размерности после любого допустимого расширения.

    • Блоки данных в [x, y, z, ...] происходит от того же индекса в tall размерности, принимая, что длинный массив является nonsingleton в tall размерности. Для примера, если tX и tY nonsingleton в tall размерности, тогда первый набор блоков может быть x = tX(1:20000,:) и y = tY(1:20000,:).

    • Если первая размерность любого из [tX, tY, tZ, ...] имеет размер 1, затем соответствующий блок [x, y, z, ...] состоит из всех данных в этот длинный массив.

  2. Выходные аргументы - выходы [a, b, c, ...] являются блоками, помещаемыми в памяти, которые передаются на соответствующие выходы [tA, tB, tC, ...]. Выходные выходы [a, b, c, ...] удовлетворить этим свойствам:

    • Все [a, b, c, ...] должен иметь тот же размер в первой размерности.

    • Все [a, b, c, ...] сгруппированы по вертикали с соответствующими результатами предыдущих вызовов в fcn.

    • Все [a, b, c, ...] передаются к тому же индексу в первой размерности в соответствующих выходных массивах назначения.

  3. Функциональные правила - fcn должен удовлетворять функциональному правилу:

    • F([inputs1; inputs2]) == [F(inputs1); F(inputs2)]Применение функции к конкатенации входов должно быть таким же, как применение функции к входам отдельно, а затем конкатенация результатов.

  4. Пустые входы - убедитесь, что fcn может обрабатывать вход высотой 0. Пустые входы могут возникнуть, когда файл пуст или если вы сделали много фильтрации данных.

Двухэтапная операция сокращения

matlab.tall.reduce применяет две функции к длинный массив, в результате чего первый шаг подается как вход на конечный шаг сокращения. Функция сокращения применяется неоднократно к промежуточным результатам до тех пор, пока не будет получен один конечный блок, который помещается в памяти. В парадигме MapReduce этот процесс похож на операцию «одного ключа» MapReduce, где промежуточные результаты все имеют один и тот же ключ и объединяются в шаге сокращения.

Первый шаг аналогичен matlab.tall.transform и имеет те же требования. Однако шаг сокращения всегда уменьшает промежуточные результаты до одного блока, который помещается в памяти. Эти рисунки показывают, что происходит с блоками в массиве, когда они управляются matlab.tall.reduce.

Операция

Описание

Примеры

Преобразование + Сокращение - количество строк в каждом блоке остается неизменным после первого шага, и затем промежуточные результаты сводятся к одному блоку.

  • A = matlab.tall.reduce(@sin,@max,tX) вычисляет синус каждого блока значений, а затем находит общее максимальное значение во время шага сокращения.

  • A = matlab.tall.reduce(@(X) X.^2, @mean, tX) Строит квадраты элементов в каждом блоке, а затем вычисляет общее среднее значение на шаге сокращения.

Фильтрация + Сокращение - количество строк в каждом блоке уменьшается на первом шаге. Затем промежуточные результаты сводятся к одному блоку.

  • A = matlab.tall.reduce(@sum, @sum, tX) вычисляет сумму элементов в каждом блоке, а затем находит общую сумму элементов на шаге сокращения.

  • A = matlab.tall.reduce(@(X) X(X>0), @mean, tX) отфильтровывает все отрицательные значения, а затем вычисляет общее среднее оставшиеся значения.

Синтаксис шага сокращения

Типовой синтаксис для применения двухэтапного сокращения:

[rA, rB, rC, ...] = matlab.tall.reduce(fcn, reducefcn, tX, tY, tZ, ...)

Функциональная подпись fcn является

[a, b, c, ...] = fcn(x, y, z, ...)

Функциональная подпись reducefcn является

[rA, rB, rC, ...] = reducefcn(a, b, c, ...)

То есть вход длинные массивы [tX, tY, tZ, ...] разбиты на блоки [x, y, z, ...] которые являются входами в fcn. Затем, fcn возвращает выходы [a, b, c, ...] которые являются входами в reducefcn. Наконец, reducefcn возвращает конечные результаты [rA, rB, rC] которые возвращаются matlab.tall.reduce.

Функциональные требования к reducefcn

Требования к fcn являются такими же, как те, которые были изложены в Функциональных требованиях для fcn. Однако требования к reducefcn разные.

Общая функциональная подпись reducefcn является

[rA, rB, rC, ...] = reducefcn(a, b, c, ...)
reducefcn должны удовлетворять этим требованиям:

  1. Входные параметры - Входы [a, b, c, ...] являются блоками, которые помещаются в памяти. Блоки данных являются выходами, возвращаемыми fcn, или частично уменьшенная выход от reducefcn который снова эксплуатируется для дальнейшего сокращения. Входы [a, b, c, ...] удовлетворить этим свойствам:

    • Входы [a, b, c, ...] иметь тот же размер в первой размерности.

    • Для заданного индекса в первой размерности каждая строка блоков данных [a, b, c, ...] происходит либо от входа, либо от того же предыдущего вызова, к reducefcn.

    • Для заданного индекса в первой размерности каждая строка входов [a, b, c, ...] для этого индекса происходит от того же индекса в первой размерности.

  2. Выходные аргументы - Все выходы [rA, rB, rC, ...] должен иметь тот же размер в первой размерности. Кроме того, они должны быть вертикально конкатенируемыми с соответствующими входами [a, b, c, ...] для обеспечения повторных сокращений при необходимости.

  3. Функциональные правила - reducefcn должны удовлетворять этим функциональным правилам (до округления ошибки):

    • F(input) == F(F(input)): Многократное применение функции к одним и тем же входам не должно изменять результат.

    • F([input1; input2]) == F([input2; input1]): Результат не должен зависеть от порядка конкатенации.

    • F([input1; input2]) == F([F(input1); F(input2)]): Применение функции один раз к конкатенации некоторых промежуточных результатов должно быть таким же, как применение ее отдельно, конкатенация и повторное применение.

  4. Пустые входы - убедитесь, что reducefcn может обрабатывать вход высотой 0. Пустые входы могут возникнуть, когда файл пуст или если вы сделали много фильтрации данных. Для этого вызова все входные блоки являются пустыми массивами правильного типа и размера в размерностях, выходящих за пределы первого.

Операции скользящего окна

matlab.tall.movingWindow и matlab.tall.blockMovingWindow функции применяют функцию к окнам данных в длинный массив. В то время как matlab.tall.transform и matlab.tall.reduce работать с целыми блоками данных за раз, функции скользящего окна работают с окнами данных, когда окно переходит от начала к концу массива. Окна могут находиться между блоками данных, считываемых с диска.

Эти рисунки показывают, что происходит с блоками в массиве, когда они управляются matlab.tall.movingWindow или matlab.tall.blockMovingWindow.

ОперацияОписаниеПримеры

Оконное преобразование - количество строк в каждом блоке остается неизменным, но изменяются значения. Выходы содержат результаты операций, выполненных в неполных и полных окнах данных.

Оба matlab.tall.movingWindow и matlab.tall.blockMovingWindow преобразуйте данные при 'EndPoints' - значение по умолчанию 'shrink', или когда задано значение заливки. Оба значения гарантируют, что выход в первой размерности совпадает с исходным.

  • A = matlab.tall.movingWindow(@mean, 100, tX) вычисляет скользящее среднее значение с использованием размера окна 100.

Оконная фильтрация - Неполные окна данных отбрасываются, поэтому выход имеет меньше элементов, чем вход. Выходы содержат только результаты операций, выполненных в полных окнах данных.

Оба matlab.tall.movingWindow и matlab.tall.blockMovingWindow удаление неполных окон данных при 'EndPoints' является 'discard'.

  • A = matlab.tall.movingWindow(@mean, 100, tX, 'EndPoints', 'discard') вычисляет скользящее среднее значение в полных окнах данных, используя размер окна 100.

Вы можете использовать matlab.tall.movingWindow и matlab.tall.blockMovingWindow для применения оконных преобразований или фильтров к данным. Например, вы можете вычислить конечное среднее значение или скользящую медиану, или можно применить несколько операций сразу к тому же окну. Эти две функции различаются этими способами:

  • matlab.tall.movingWindow применяется fcn ко всем окнам данных, независимо от того, закончены ли окна. matlab.tall.blockMovingWindow применяется windowfcn к неполным окнам данных и применяется blockfcn для заполнения окон данных.

  • matlab.tall.movingWindow работает с отдельными окнами данных за раз. matlab.tall.blockMovingWindow работает со всеми блоками данных, содержащими несколько полных окон, что уменьшает количество вызовов функций, необходимых для вычисления.

Синтаксисы скользящего окна

Синтаксис для применения операции скользящего окна к отдельным окнам данных:

[tA, tB, tC, ...] = matlab.tall.movingWindow(fcn, window, tX, tY, tZ, ...)

Функциональная подпись fcn должен быть

[a, b, c, ...] = fcn(x, y, z, ...)

Точно так же синтаксис для применения операции скользящего окна к целым блокам данных:

[tA, tB, tC, ...] = matlab.tall.blockMovingWindow(windowfcn, blockfcn, window, tX, tY, tZ, ...)

Функциональные сигнатуры windowfcn и blockfcn должен быть

[a, b, c, ...] = windowfcn(info, x, y, z, ...)
[a, b, c, ...] = blockfcn(info, bX, bY, bZ, ...)

The info вход - структура, содержащая поля Window и Stride. Когда вы пишете функцию. используйте эти поля для выбора окон данных в каждом блоке.

Контур общих правил, которые fcn, windowfcn, и blockfcn необходимо следовать, см. «Функциональные требования» для fcn. В стороне от info вход, fcn и windowfcn имеют те же требования. Однако требования к blockfcn отличаются, поскольку эта функция действует на целых блоках данных.

Функциональные требования к windowfcn

Общая функциональная подпись windowfcn является

[a, b, c, ...] = windowfcn(info, x, y, ...)
The info вход является структурой, обеспечиваемой matlab.tall.blockMovingWindow который включает в себя следующие поля:

  • Stride - Заданный размер шага между окнами (по умолчанию: 1). Установите это значение с помощью 'Stride' Пара "имя-значение".

  • Window - Заданный размер окна. Установите это значение с помощью window входной параметр.

windowfcn должны удовлетворять этим требованиям:

  1. Входные параметры - Входы [x, y, z, ...] являются блоками данных, которые помещаются в памяти. Блоки генерируются путем извлечения данных из соответствующих входов длинный массив [tX, tY, tZ, ...]. Входы [x, y, z, ...] удовлетворить этим свойствам:

    • Все входы [x, y, z, ...] иметь тот же размер в первой размерности.

    • Блоки данных в [x, y, z, ...] происходит от того же индекса в tall размерности, принимая, что длинный массив является nonsingleton в tall размерности. Для примера, если tX и tY nonsingleton в tall размерности, тогда первый набор блоков может быть x = tX(1:20000,:) и y = tY(1:20000,:).

    • Когда первая размерность любого из [tX, tY, tZ, ...] имеет размер 1, соответствующий блок [x, y, z, ...] состоит из всех данных в этот длинный массив.

    • Применение windowfcn должно привести к уменьшению входных данных до скаляра или среза массива высотой 1.

      Когда вход является матрицей, N-D массивом, таблицей или расписанием, применение windowfcn должно привести к сокращению входных данных в каждом из его столбцов или переменных.

  2. Выходные аргументы - выходы [a, b, c, ...] являются блоками, которые помещаются в памяти и отправляются на соответствующие выходы [tA, tB, tC, ...]. Выходные выходы [a, b, c, ...] удовлетворить этим свойствам:

    • Все выходы [a, b, c, ...] должен иметь тот же размер в первой размерности.

    • Все выходы [a, b, c, ...] сгруппированы по вертикали с соответствующими результатами предыдущих вызовов в windowfcn.

    • Все выходы [a, b, c, ...] передаются к тому же индексу в первой размерности в соответствующих выходных массивах назначения.

  3. Функциональные правила - windowfcn должен удовлетворять этому функциональному правилу:

    • F([inputs1; inputs2]) == [F(inputs1); F(inputs2)]Применение функции к конкатенации входов должно быть таким же, как применение функции к входам отдельно, а затем конкатенация результатов.

Функциональные требования к blockfcn

Общая функциональная подпись blockfcn является

[a, b, c, ...] = blockfcn(info, bX, bY, bZ, ...)
The info вход является структурой, обеспечиваемой matlab.tall.blockMovingWindow который включает в себя следующие поля:

  • Stride - Заданный размер шага между окнами (по умолчанию: 1). Установите это значение с помощью 'Stride' Пара "имя-значение".

  • Window - Заданный размер окна. Установите это значение с помощью window входной параметр.

Блоки данных bX, bY, bZ, ... это matlab.tall.blockMovingWindow обеспечивает blockfcn имеют следующие свойства:

  • Блоки содержат только полноразмерные окна. blockfcn не должен задавать поведение для неполных окон данных.

  • Первое окно данных начинается с первого элемента блока. Последний элемент последнего окна является последним элементом блока.

blockfcn должны удовлетворять этим требованиям:

  1. Входные параметры - Входы [bX, bY, bZ, ...] являются блоками данных, которые помещаются в памяти. Блоки генерируются путем извлечения данных из соответствующих входов длинный массив [tX, tY, tZ, ...]. Входы [bX, bY, bZ, ...] удовлетворить этим свойствам:

    • Все входы [bX, bY, bZ, ...] иметь тот же размер в первой размерности после любого допустимого расширения.

    • Блоки данных в [bX, bY, bZ, ...] происходит от того же индекса в tall размерности, принимая, что длинный массив является nonsingleton в tall размерности. Для примера, если tX и tY nonsingleton в tall размерности, тогда первый набор блоков может быть bX = tX(1:20000,:) и bY = tY(1:20000,:).

    • Если первая размерность любого из входов данных [tX, tY, tZ, ...] имеет размер 1, затем соответствующий блок [bX, bY, bZ, ...] состоит из всех данных в этот длинный массив.

    • Применение blockfcn должно привести к сокращению входных данных таким образом, чтобы результат имел высоту, равную количеству окон в блоке. Можно использовать info.Window и info.Stride для определения количества окон в блоке.

      Если вход является матрицей, N-D массивом, таблицей или расписанием, то применение blockfcn должно привести к сокращению входных данных в каждом из его столбцов или переменных.

  2. Выходные аргументы - выходы [a, b, c, ...] являются блоками, помещаемыми в памяти, которые передаются на соответствующие выходы [tA, tB, tC, ...]. Выходные выходы [a, b, c, ...] удовлетворить этим свойствам:

    • Все выходы [a, b, c, ...] должен иметь тот же размер в первой размерности.

    • Все выходы [a, b, c, ...] сгруппированы по вертикали с соответствующими результатами предыдущих вызовов в blockfcn.

    • Все выходы [a, b, c, ...] передаются к тому же индексу в первой размерности в соответствующих выходных массивах назначения.

  3. Функциональные правила - blockfcn должен удовлетворять этому функциональному правилу:

    • F([inputs1; inputs2]) == [F(inputs1); F(inputs2)]Применение функции к конкатенации входов должно быть таким же, как применение функции к входам отдельно, а затем конкатенация результатов.

Управляйте выходом данных

Если окончательный выход от любого из поддерживаемых API имеет различные типы данных от входных, то вы должны задать 'OutputsLike' пара "имя-значение", чтобы предоставить один или несколько прототипные массивы, которые имеют совпадающий тип данных и атрибуты, что и соответствующие выходы. Значение 'OutputsLike' всегда является массивом ячеек, причем каждая камера содержит прототипный массив для соответствующего выходного аргумента.

Для примера этот вызов на matlab.tall.transform принимает один длинный массив tX как вход и возвращает два выхода с различными типами, заданными прототипными массивами protoA и protoB. Выходные A имеет тот совпадающий тип данных и атрибуты, что и protoA, и аналогично для B и protoB.

C = {protoA protoB};
[A, B] = matlab.tall.transform(fcn, tX, 'OutputsLike', C)

Общим способом поставки прототипных массивов является вызов fcn с тривиальными входами соответствующего типа данных, поскольку выходы возвращаются fcn иметь правильный тип данных. В этом примере функция преобразования принимает tall double, но возвращает длинная таблица. При вызове функции прототипного массива генерируется fcn(0) и прототип задается как значение 'OutputsLike'.

ds = tabularTextDatastore('airlinesmall.csv','TreatAsMissing','NA');
ds.SelectedVariableNames = {'ArrDelay', 'DepDelay'};
tt = tall(ds);
tX = tt.ArrDelay;

fcn = @(x) table(x,'VariableNames',{'MyVar'});
proto_A = fcn(0);
A = matlab.tall.transform(fcn,tX,'OutputsLike',{proto_A});

Советы по кодированию и эффективности

  • Поместите всю аналитику в одну функцию, которую вы вызываете, чтобы работать непосредственно с данными, вместо использования ненужных вложенных функций.

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

  • Обратите внимание на ориентацию ваших данных, так как некоторые функции возвращают выходы в различных формах в зависимости от входных данных. Для примера, unique может вернуть вектор-строку или вектор-столбец в зависимости от ориентации входных данных.

  • Блоки динамически генерируются во время выполнения на основе доступной памяти компьютера. Убедитесь, что любая заданная функция сокращения подчиняется правилу функции F([input1; input2]) == F([F(input1); F(input2)]). Если это правило не соблюдается, результаты могут значительно отличаться между испытаниями.

  • Блоки могут иметь любой размер в первой размерности, включая 0 или 1. Размер 0 или 1 может возникнуть в промежуточных вычислениях в результате операций фильтрации или сокращения. Убедитесь, что ваша функция делает правильное для обоих этих случаев. Один из признаков того, что функция не обрабатывает эти случаи должным образом, когда вы получаете сообщение об ошибке «Output is different size».

См. также

| | |

Похожие темы