std.numeric
Этот модуль является портом фрагмента заголовка numeric из стандартной библиотеки шаблонов Александра Степанова (Standard Template Library) с несколькими дополнениями.
- Лицензия:
- Лицензия Boost 1.0.
- Авторы:
- Андрей Александреску, Дон Клугстон, Роберт Жак, Илья Ярошенков
- Источник
- std/numeric.d
- перечисление CustomFloatFlags: int;
-
Флаги формата для CustomFloat.
- signed
-
Добавляет бит знака для поддержки знаковых чисел.
- storeNormalized
-
По умолчанию хранить значения в нормализованной форме. Фактическая точность мантиссы увеличивается на 1 бит, предполагая неявный старший бит 1 вместо 0. т.е.
1.nnnnвместо0.nnnn. Действительно для всех типов IEE754 - allowDenorm
-
Хранит мантиссу в денормализованной форме IEEE754, когда порядок равен 0. Необходима для представления значения 0.
- infinity
-
Позволяет хранить значения бесконечности IEEE754.
- nan
-
Позволяет хранить значения IEEE754 Not a Number.
- probability
-
Если установлено, выбирает смещение порядка так, чтобы max_exp = 1. т.е. так, чтобы максимальное значение было >= 1.0 и < 2.0. Игнорируется, если смещение порядка указано вручную.
- negativeUnsigned
-
Если установлено, предполагается, что беззнаковые пользовательские числа являются отрицательными.
- allowDenormZeroOnly
-
Если установлено, 0 - единственное допустимое денормализованное число IEEE754. Требует allowDenorm и storeNormalized.
- ieee
-
Включает все варианты IEEE754.
- none
-
Не включает ни одного из вышеперечисленных вариантов.
- шаблон CustomFloat(uint bits) if (bits == 8 || bits == 16 || bits == 32 || bits == 64 || bits == 80)
шаблон CustomFloat(uint precision, uint exponentWidth, CustomFloatFlags flags = CustomFloatFlags.ieee) if (((flags & flags.signed) + precision + exponentWidth) % 8 == 0 && (precision + exponentWidth > 0))
структура CustomFloat(uint precision, uint exponentWidth, CustomFloatFlags flags, uint bias) if (isCorrectCustomFloat(precision, exponentWidth, flags)); -
Позволяет коду пользователя определять пользовательские форматы чисел с плавающей точкой. Эти форматы предназначены только для хранения; все операции над ними выполняются путём неявного преобразования в
realсначала. После завершения операции результат может быть сохранён в значении пользовательской плавающей точки путём присваивания.- Примеры:
-
import std.math : sin, cos; // Define a 16-bit floating point values CustomFloat!16 x; // Using the number of bits CustomFloat!(10, 5) y; // Using the precision and exponent width CustomFloat!(10, 5,CustomFloatFlags.ieee) z; // Using the precision, exponent width and format flags CustomFloat!(10, 5,CustomFloatFlags.ieee, 15) w; // Using the precision, exponent width, format flags and exponent offset bias // Use the 16-bit floats mostly like normal numbers w = x*y - 1; // Functions calls require conversion z = sin(+x) + cos(+y); // Use unary plus to concisely convert to a real z = sin(x.get!float) + cos(y.get!float); // Or use get!T z = sin(cast(float) x) + cos(cast(float) y); // Or use cast(T) to explicitly convert // Define a 8-bit custom float for storing probabilities alias Probability = CustomFloat!(4, 4, CustomFloatFlags.ieee^CustomFloatFlags.probability^CustomFloatFlags.signed ); auto p = Probability(0.5);
- шаблон FPTemporary(F) if (isFloatingPoint!F)
-
Определяет самый быстрый тип для хранения временных значений вычисления, предназначенного в конечном итоге для получения результата типа
F(гдеFдолжно быть одним изfloat,double, илиreal). При выполнении многоступенчатого вычисления вы можете хранить промежуточные результаты какFPTemporary!F.Необходимость в
FPTemporaryвытекает из оптимизированных операций с плавающей точкой и регистров, присутствующих практически во всех процессорах. При сложении чисел в примере, сложение фактически может выполняться вrealточности внутри. В этом случае, хранение промежуточныхresultвdouble formatне только менее точно, но и (удивительно) медленнее, поскольку преобразование изrealвdoubleвыполняется в каждом проходе цикла. Поскольку это проигрышная ситуация,FPTemporary!Fопределён как самый быстрый тип для вычислений с точностьюF. Нет необходимости определять тип для самых точных вычислений, поскольку это всегдаreal.
Наконец, нет гарантии, что использованиеFPTemporary!Fвсегда будет самым быстрым, так как скорость вычислений с плавающей точкой зависит от очень многих факторов.- Примеры:
-
import std.math : approxEqual; // Average numbers in an array double avg(in double[] a) { if (a.length == 0) return 0; FPTemporary!double result = 0; foreach (e; a) result += e; return result / a.length; } auto a = [1.0, 2.0, 3.0]; assert(approxEqual(avg(a), 2));
- шаблон secantMethod(alias fun)
-
Реализует метод секущих для нахождения корня функции
fun, начиная с точек[xn_1, x_n](желательно близких к корню).Numможет бытьfloat,double, илиreal.- Примеры:
-
import std.math : approxEqual, cos; float f(float x) { return cos(x) - x*x*x; } auto x = secantMethod!(f)(0f, 1f); assert(approxEqual(x, 0.865474));
- T findRoot(T, DF, DT)(scope DF f, const T a, const T b, scope DT tolerance)
Ограничения: if (isFloatingPoint!T && is(typeof(tolerance(T.init, T.init)) : bool) && is(typeof(f(T.init)) == R, R) && isFloatingPoint!R);
T findRoot(T, DF)(scope DF f, const T a, const T b); -
Находит действительный корень действительной функции f(x) с помощью отсечения.
Учитывая функцию
fи диапазон[a .. b]такой, чтоf(a)иf(b)имеют противоположные знаки или хотя бы одно из них равно ±0, возвращает значениеxв диапазоне, которое наиболее близко к корнюf(x). Еслиf(x)имеет более одного корня в диапазоне, один выбирается произвольно. Еслиf(x)возвращает NaN, возвращается NaN; в противном случае этот алгоритм гарантированно выполняется.
Использует алгоритм, основанный на TOMS748, который использует обратную кубическую интерполяцию, когда это возможно, в противном случае возвращается к параболической или секущей интерполяции. По сравнению с TOMS748, эта реализация улучшает производительность в худшем случае более чем в 100 раз, а типичную производительность - в 2 раза. Для 80-битных вещественных чисел для достижения полной машинной точности большинство проблем требуют от 8 до 15 вызововf(x). Худшая производительность (патологические случаи) приблизительно вдвое превышает количество битов.- Ссылки
- "On Enclosing Simple Roots of Nonlinear Equations", G. Alefeld, F.A. Potra, Yixun Shi, Mathematics of Computation 61, pp733-744 (1993). Исходный код Fortran доступен на www.netlib.org в качестве алгоритма TOMS478.
- Кортеж!(T, T, R, R) findRoot(T, R, DF, DT)(scope DF f, const T ax, const T bx, const R fax, const R fbx, scope DT tolerance)
Ограничения: if (isFloatingPoint!T && is(typeof(tolerance(T.init, T.init)) : bool) && is(typeof(f(T.init)) == R) && isFloatingPoint!R);
Кортеж!(T, T, R, R) findRoot(T, R, DF)(scope DF f, const T ax, const T bx, const R fax, const R fbx);
T findRoot(T, R)(scope R delegate(T) f, const T a, const T b, scope bool delegate(T lo, T hi) tolerance = (T a, T b) => false); -
Находит корень действительной функции f(x) с помощью отсечения, позволяя указать условие завершения.
- Параметры:
DF fФункция для анализа T axЛевая граница начального интервала fизвестного, содержащего корень.T bxПравая граница начального интервала fизвестного, содержащего корень.R faxЗначение f(ax).R fbxЗначение f(bx).faxиfbxдолжны иметь противоположные знаки. (f(ax)иf(bx)обычно известны заранее.)DT toleranceОпределяет условие раннего завершения. Получает текущие верхнюю и нижнюю границы корня. Делегат должен вернуть trueкогда эти границы приемлемы. Если эта функция всегда возвращаетfalse, будет достигнута полная машинная точность.
- Возвращает:
- Кортеж, состоящий из двух диапазонов. Первые два элемента — это диапазон (в
x) корня, а вторая пара элементов — соответствующие значения функции в этих точках. Если был найден точный корень, оба первых элемента будут содержать корень, а вторая пара элементов будет равна 0.
- Кортеж!(T, "x", Unqual!(ReturnType!DF), "y", T, "error") findLocalMin(T, DF)(scope DF f, const T ax, const T bx, const T relTolerance = sqrt(T.epsilon), const T absTolerance = sqrt(T.epsilon))
Ограничения: if (isFloatingPoint!T && __traits(compiles, () { T _ = DF.init(T.init); } ));
-
Найдите реальный минимум вещественной функции
f(x)с помощью метода отсечения. Учитывая функциюfи диапазон(ax .. bx), возвращает значениеxв диапазоне, которое наиболее близко к минимумуf(x).fникогда не вычисляется в конечных точкахaxиbx. Если уf(x)есть более одного минимума в диапазоне, один из них будет выбран произвольно. Еслиf(x)возвращает NaN или -Бесконечность,(x, f(x), NaN)будет возвращено; в противном случае, этот алгоритм гарантированно сработает.- Параметры:
DF fФункция для анализа T axЛевая граница начального диапазона f, известного как содержащий минимум. T bxПравая граница начального диапазона f, известного как содержащий минимум. T relToleranceОтносительная точность. T absToleranceАбсолютная точность.
- Предпосылки
-
axиbxдолжны быть конечными вещественными числами.
relToleranceдолжно быть нормальным положительным вещественным числом.
absToleranceдолжно быть нормальным положительным вещественным числом, не меньшеT.epsilon*2.
- Возвращает:
- Кортеж, состоящий из
x,y = f(x)иerror = 3 * (absTolerance * fabs(x) + relTolerance). Используемый метод представляет собой комбинацию поиска по золотому сечению и последующей параболической интерполяции. Скорость сходимости никогда не будет значительно медленнее, чем для поиска Фибоначчи.
- Ссылки
- "Algorithms for Minimization without Derivatives", Richard Brent, Prentice-Hall, Inc. (1973)
- См. также:
-
findRoot,std.math.isNormal
- Примеры:
-
import std.math : approxEqual; auto ret = findLocalMin((double x) => (x-4)^^2, -1e7, 1e7); assert(ret.x.approxEqual(4.0)); assert(ret.y.approxEqual(0.0));
- CommonType!(ElementType!Range1, ElementType!Range2) euclideanDistance(Range1, Range2)(Range1 a, Range2 b)
Constraints: if (isInputRange!Range1 && isInputRange!Range2);
CommonType!(ElementType!Range1, ElementType!Range2) euclideanDistance(Range1, Range2, F)(Range1 a, Range2 b, F limit)
Constraints: if (isInputRange!Range1 && isInputRange!Range2); -
Вычисляет евклидово расстояние между входными диапазонами
aиb. Две диапазона должны иметь одинаковую длину. В версии с тремя параметрами вычисление прекращается, как только расстояние станет больше или равноlimit(это полезно для экономии вычислений, если требуется небольшое расстояние). - CommonType!(ElementType!Range1, ElementType!Range2) dotProduct(Range1, Range2)(Range1 a, Range2 b)
Constraints: if (isInputRange!Range1 && isInputRange!Range2 && !(isArray!Range1 && isArray!Range2));
CommonType!(F1, F2) dotProduct(F1, F2)(in F1[] avector, in F2[] bvector);
F dotProduct(F, uint N)(ref scope const F[N] a, ref scope const F[N] b)
Constraints: if (N <= 16); -
Вычисляет скалярное произведение входных диапазонов
aиb. Две диапазона должны иметь одинаковую длину. Если оба диапазона определяют длину, проверка выполняется один раз; в противном случае она выполняется на каждой итерации. - CommonType!(ElementType!Range1, ElementType!Range2) cosineSimilarity(Range1, Range2)(Range1 a, Range2 b)
Constraints: if (isInputRange!Range1 && isInputRange!Range2); -
Вычисляет косинусное сходство входных диапазонов
aиb. Две диапазона должны иметь одинаковую длину. Если оба диапазона определяют длину, проверка выполняется один раз; в противном случае она выполняется на каждой итерации. Если в любом диапазоне все элементы равны нулю, возвращается 0. - bool normalize(R)(R range, ElementType!R sum = 1)
Constraints: if (isForwardRange!R); -
Нормализует значения в
rangeпутем умножения каждого элемента на число, выбранное таким образом, что сумма значений равнаsum. Если сумма элементов вrangeравна нулю, всем элементам присваиваетсяsum / range.length. Нормализация имеет смысл только в том случае, если все элементы вrangeположительны.normalizeпредполагает это, не проверяя.- Возвращает:
-
trueесли нормализация выполнена успешно,falseесли все элементы вrangeбыли равны нулю или еслиrangeпусто.
- Примеры:
-
double[] a = []; assert(!normalize(a)); a = [ 1.0, 3.0 ]; assert(normalize(a)); writeln(a); // [0.25, 0.75] assert(normalize!(typeof(a))(a, 50)); // a = [12.5, 37.5] a = [ 0.0, 0.0 ]; assert(!normalize(a)); writeln(a); // [0.5, 0.5]
- ElementType!Range sumOfLog2s(Range)(Range r)
Constraints: if (isInputRange!Range && isFloatingPoint!(ElementType!Range)); -
Вычисляет сумму двоичных логарифмов входного диапазона
r. Погрешность этого метода значительно меньше, чем при простом суммировании log2.- Примеры:
-
import std.math : isNaN; writeln(sumOfLog2s(new double[0])); // 0 writeln(sumOfLog2s([0.0L])); // -real.infinity writeln(sumOfLog2s([-0.0L])); // -real.infinity writeln(sumOfLog2s([2.0L])); // 1 assert(sumOfLog2s([-2.0L]).isNaN()); assert(sumOfLog2s([real.nan]).isNaN()); assert(sumOfLog2s([-real.nan]).isNaN()); writeln(sumOfLog2s([real.infinity])); // real.infinity assert(sumOfLog2s([-real.infinity]).isNaN()); writeln(sumOfLog2s([0.25, 0.25, 0.25, 0.125])); // -9
- ElementType!Range entropy(Range)(Range r)
Constraints: if (isInputRange!Range);
ElementType!Range entropy(Range, F)(Range r, F max)
Constraints: if (isInputRange!Range && !is(CommonType!(ElementType!Range, F) == void)); -
Вычисляет энтропию входного диапазона
rв битах. Эта функция предполагает (без проверки), что значения вrнаходятся в[0, 1]. Для того, чтобы энтропия имела смысл, часто необходимо также нормализоватьr(т.е., значения должны суммироваться до 1). В версии с двумя параметрами вычисление прекращается, как только промежуточный результат становится больше или равенmax. - CommonType!(ElementType!Range1, ElementType!Range2) kullbackLeiblerDivergence(Range1, Range2)(Range1 a, Range2 b)
Constraints: if (isInputRange!Range1 && isInputRange!Range2); -
Вычисляет расхождение Кульбака-Лейблера между входными диапазонами
aиb, которое является суммойai * log(ai / bi). Основание логарифма равно 2. Предполагается, что диапазоны содержат элементы в[0, 1]. Обычно диапазоны представляют собой нормализованные распределения вероятностей, но это не является требованием и не проверяетсяkullbackLeiblerDivergence. Если любой элементbiравен нулю, а соответствующий элементaiотличен от нуля, возвращается бесконечность. (В противном случае, еслиai == 0 && bi == 0, членai * log(ai / bi)считается равным нулю.) Если входные данные нормализованы, результат положителен.- Примеры:
-
import std.math : approxEqual; double[] p = [ 0.0, 0, 0, 1 ]; writeln(kullbackLeiblerDivergence(p, p)); // 0 double[] p1 = [ 0.25, 0.25, 0.25, 0.25 ]; writeln(kullbackLeiblerDivergence(p1, p1)); // 0 writeln(kullbackLeiblerDivergence(p, p1)); // 2 writeln(kullbackLeiblerDivergence(p1, p)); // double.infinity double[] p2 = [ 0.2, 0.2, 0.2, 0.4 ]; assert(approxEqual(kullbackLeiblerDivergence(p1, p2), 0.0719281)); assert(approxEqual(kullbackLeiblerDivergence(p2, p1), 0.0780719));
- CommonType!(ElementType!Range1, ElementType!Range2) jensenShannonDivergence(Range1, Range2)(Range1 a, Range2 b)
Constraints: if (isInputRange!Range1 && isInputRange!Range2 && is(CommonType!(ElementType!Range1, ElementType!Range2)));
CommonType!(ElementType!Range1, ElementType!Range2) jensenShannonDivergence(Range1, Range2, F)(Range1 a, Range2 b, F limit)
Constraints: if (isInputRange!Range1 && isInputRange!Range2 && is(typeof(CommonType!(ElementType!Range1, ElementType!Range2).init >= F.init) : bool)); -
Вычисляет расхождение Дженсена-Шеннона между
aиb, которое является суммой(ai * log(2 * ai / (ai + bi)) + bi * log(2 * bi / (ai + bi))) / 2. Основание логарифма равно 2. Предполагается, что диапазоны содержат элементы в[0, 1]. Обычно диапазоны представляют собой нормализованные распределения вероятностей, но это не является требованием и не проверяетсяjensenShannonDivergence. Если входные данные нормализованы, результат ограничен[0, 1]. Версия с тремя параметрами прекращает вычисления, как только промежуточный результат становится больше или равенlimit.- Примеры:
-
import std.math : approxEqual; double[] p = [ 0.0, 0, 0, 1 ]; writeln(jensenShannonDivergence(p, p)); // 0 double[] p1 = [ 0.25, 0.25, 0.25, 0.25 ]; writeln(jensenShannonDivergence(p1, p1)); // 0 assert(approxEqual(jensenShannonDivergence(p1, p), 0.548795)); double[] p2 = [ 0.2, 0.2, 0.2, 0.4 ]; assert(approxEqual(jensenShannonDivergence(p1, p2), 0.0186218)); assert(approxEqual(jensenShannonDivergence(p2, p1), 0.0186218)); assert(approxEqual(jensenShannonDivergence(p2, p1, 0.005), 0.00602366));
- F gapWeightedSimilarity(alias comp = "a == b", R1, R2, F)(R1 s, R2 t, F lambda)
Constraints: if (isRandomAccessRange!R1 && hasLength!R1 && isRandomAccessRange!R2 && hasLength!R2);
-
Так называемый «ядро строк с взвешенными пропуском всех длин» вычисляет меру сходства между
sиtна основе всех их общих подпоследовательностей всех длин. Также включаются подпоследовательности с пропусками.Чтобы понять, что вычисляет
gapWeightedSimilarity(s, t, lambda), сначала рассмотрим случайlambda = 1и строкиs = ["Hello", "brave", "new", "world"]иt = ["Hello", "new", "world"]. В этом случаеgapWeightedSimilarityподсчитывает следующие совпадения:
- три совпадения длины 1, а именно
"Hello","new", и"world"; - три совпадения длины 2, а именно (
"Hello", "new"), ("Hello", "world"), и ("new", "world"); - одно совпадение длины 3, а именно (
"Hello", "new", "world").
ВызовgapWeightedSimilarity(s, t, 1)просто подсчитывает все эти совпадения и складывает их, возвращая 7.
string[] s = ["Hello", "brave", "new", "world"]; string[] t = ["Hello", "new", "world"]; assert(gapWeightedSimilarity(s, t, 1) == 7);
Обратите внимание, как пропуски в совпадениях просто игнорируются, например ("Hello", "new") считается таким же хорошим совпадением, как ("new", "world"). Это может быть слишком либерально для некоторых применений. Чтобы полностью исключить совпадения с пропусками, используйтеlambda = 0:
string[] s = ["Hello", "brave", "new", "world"]; string[] t = ["Hello", "new", "world"]; assert(gapWeightedSimilarity(s, t, 0) == 4);
Вышеприведённый вызов исключил совпадения с пропусками ("Hello", "new"), ("Hello", "world"), и ("Hello", "new", "world") из подсчёта. Это оставляет только 4 совпадения.
Наиболее интересный случай — когда совпадения с пропусками всё ещё участвуют в результате, но не так сильно, как совпадения без пропусков. Результатом будет плавная, мелкозернистая мера сходства между входными строками. Здесь вступают в игру значенияlambdaмежду 0 и 1: совпадения с пропусками экспоненциально штрафуются по количеству пропусков с основаниемlambda. Это означает, что совпадение без пропусков добавляет 1 к возвращаемому значению; совпадение с одним пробелом в одной из строк добавляетlambdaк возвращаемому значению; ...; совпадение с общим числомnпробелов в обеих строках добавляетpow(lambda, n)к возвращаемому значению. В примере выше у нас есть 4 совпадения без пропусков, 2 совпадения с одним пробелом и 1 совпадение с тремя пробелами. Последнее совпадение ("Hello", "world") имеет два пробела в первой строке и один пробел во второй строке, в общей сложности три пробела. Суммируя это, получаем4 + 2 * lambda + pow(lambda, 3).
string[] s = ["Hello", "brave", "new", "world"]; string[] t = ["Hello", "new", "world"]; assert(gapWeightedSimilarity(s, t, 0.5) == 4 + 0.5 * 2 + 0.125);
gapWeightedSimilarityполезно везде, где необходима плавная мера сходства между последовательностями, допускающая приближённые совпадения. Примеры выше приведены со словами, но допускаются любые последовательности с элементами, сравнимыми по равенству, например, символы или числа.gapWeightedSimilarityиспользует высокооптимизированную реализацию динамического программирования, которая требует16 * min(s.length, t.length)дополнительных байтов памяти и Ο(s.length * t.length) времени для завершения. - три совпадения длины 1, а именно
- Select!(isFloatingPoint!F, F, double) gapWeightedSimilarityNormalized(alias comp = "a == b", R1, R2, F)(R1 s, R2 t, F lambda, F sSelfSim = F.init, F tSelfSim = F.init)
Constraints: if (isRandomAccessRange!R1 && hasLength!R1 && isRandomAccessRange!R2 && hasLength!R2); -
Мера сходства по
gapWeightedSimilarityимеет проблему, заключающуюся в том, что она растёт с длиной двух строк, даже если строки на самом деле не очень похожи. Например, диапазон["Hello", "world"]всё больше похож на диапазон["Hello", "world", "world", "world",...]по мере добавления большего количества экземпляров"world". Чтобы предотвратить это,gapWeightedSimilarityNormalizedвычисляет нормализованную версию сходства, вычисляемую какgapWeightedSimilarity(s, t, lambda) / sqrt(gapWeightedSimilarity(s, t, lambda) * gapWeightedSimilarity(s, t, lambda)). ФункцияgapWeightedSimilarityNormalized(так называемое нормализованное ядро) ограничена[0, 1], достигает0только для диапазонов, не совпадающих ни в одной позиции, и1только для идентичных диапазонов.Дополнительные параметры
sSelfSimиtSelfSimпредназначены для избежания дублирования вычислений. Многие приложения могут уже вычислитьgapWeightedSimilarity(s, s, lambda)и/илиgapWeightedSimilarity(t, t, lambda). В этом случае они могут быть переданы какsSelfSimиtSelfSimсоответственно.- Примеры:
-
import std.math : approxEqual, sqrt; string[] s = ["Hello", "brave", "new", "world"]; string[] t = ["Hello", "new", "world"]; writeln(gapWeightedSimilarity(s, s, 1)); // 15 writeln(gapWeightedSimilarity(t, t, 1)); // 7 writeln(gapWeightedSimilarity(s, t, 1)); // 7 assert(approxEqual(gapWeightedSimilarityNormalized(s, t, 1), 7.0 / sqrt(15.0 * 7), 0.01));
- struct GapWeightedSimilarityIncremental(Range, F = double) if (isRandomAccessRange!Range && hasLength!Range);
GapWeightedSimilarityIncremental!(R, F) gapWeightedSimilarityIncremental(R, F)(R r1, R r2, F penalty); -
Аналогично
gapWeightedSimilarity, но работает инкрементальным образом, сначала раскрывая совпадения длины 1, затем совпадения с пропусками длины 2 и так далее. Требование к памяти составляет Ο(s.length * t.length). Время выполнения составляет Ο(s.length * t.length) для вычисления каждого шага. Продолжая предыдущий пример:Реализация основана на псевдокоде на рис. 4 статьи "Efficient Computation of Gapped Substring Kernels on Large Alphabets" Русу и др., с дополнительными алгоритмическими и системными оптимизациями.
- Примеры:
-
string[] s = ["Hello", "brave", "new", "world"]; string[] t = ["Hello", "new", "world"]; auto simIter = gapWeightedSimilarityIncremental(s, t, 1.0); assert(simIter.front == 3); // three 1-length matches simIter.popFront(); assert(simIter.front == 3); // three 2-length matches simIter.popFront(); assert(simIter.front == 1); // one 3-length match simIter.popFront(); assert(simIter.empty); // no more match
- this(Range s, Range t, F lambda);
-
Создаёт объект, заданный двумя диапазонами
sиtи штрафомlambda. Конструктор выполняется за Ο(s.length * t.length) времени и вычисляет все совпадения длины 1. - ref GapWeightedSimilarityIncremental opSlice();
-
- Возвращает:
-
this.
- void popFront();
-
Вычисляет совпадение длины popFront. Выполняется за Ο(
s.length * t.length) времени. - @property F front();
-
- Возвращает:
- Сходство с пропусками на текущей длине совпадения (изначально 1, увеличивается с каждым вызовом
popFront).
- @property bool empty();
-
- Возвращает:
- Является ли список пустым (нет больше совпадений).
- T gcd(T)(T a, T b)
Constraints: if (isIntegral!T);
auto gcd(T)(T a, T b)
Constraints: if (!isIntegral!T && is(typeof(T.init % T.init)) && is(typeof(T.init == 0 || T.init > 0))); -
Вычисляет наибольший общий делитель
aиbс помощью эффективного алгоритма, такого как алгоритм Евклида или алгоритм Штейна.- Параметры:
T Любой числовой тип, поддерживающий оператор взятия остатка %. Если также поддерживаются сдвиги битов<<и>>, будет использован алгоритм Штейна; в противном случае используется алгоритм Евклида как резервный вариант.
- Возвращает:
- Наибольший общий делитель заданных аргументов.
- Примеры:
-
writeln(gcd(2 * 5 * 7 * 7, 5 * 7 * 11)); // 5 * 7 const int a = 5 * 13 * 23 * 23, b = 13 * 59; writeln(gcd(a, b)); // 13
- class Fft;
-
Класс для выполнения быстрых преобразований Фурье для размеров, являющихся степенями двойки. Этот класс инкапсулирует большое количество состояния, которое можно повторно использовать при выполнении нескольких БПФ с размерами, меньшими или равными размеру, указанному в конструкторе. Это приводит к значительному ускорению при выполнении нескольких БПФ с известным максимальным размером. Однако для удобства предоставляется API свободной функции, если вам нужно выполнить однократное БПФ.
- Ссылки
- en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm
- this(size_t size);
-
Создает объект
Fftдля вычисления быстрых преобразований Фурье для размеров, являющихся степенями двойки, размеромsizeили меньше.sizeдолжно быть степенью двойки. - const Complex!F[] fft(F = double, R)(R range)
Constraints: if (isFloatingPoint!F && isRandomAccessRange!R); -
Вычисляет преобразование Фурье диапазона с использованием алгоритма Кули-Туки Ο(
N log N).rangeдолжен быть диапазоном произвольного доступа с разбиением и длиной, равнойsize, как указано при создании этого объекта. Содержимое диапазона может быть числовых типов, которые будут интерпретироваться как чисто вещественные значения, или комплексных типов с свойствами или членами.reи.im, которые могут быть прочитаны.- Примечание
- Чисто вещественные БПФ автоматически обнаруживаются, и выполняются соответствующие оптимизации.
- Возвращает:
- Массив комплексных чисел, представляющих преобразованные данные в частотной области.
- Соглашения
- Показатель степени отрицательный, а множитель равен единице, т.е., output[j] := sum[ exp(-2 PI i j k / N) input[k] ].
- const void fft(Ret, R)(R range, Ret buf)
Constraints: if (isRandomAccessRange!Ret && isComplexLike!(ElementType!Ret) && hasSlicing!Ret); -
То же, что и перегрузка, но позволяет хранить результаты в предоставленном пользователем буфере. Буфер должен иметь ту же длину, что и диапазон, должен быть диапазоном произвольного доступа, должен иметь разбиение и должен содержать элементы, которые являются комплексноподобными. Это означает, что они должны иметь член или свойство .re и .im, которые можно как читать, так и записывать, и которые являются числами с плавающей запятой.
- const Complex!F[] inverseFft(F = double, R)(R range)
Constraints: if (isRandomAccessRange!R && isComplexLike!(ElementType!R) && isFloatingPoint!F); -
Вычисляет обратное преобразование Фурье диапазона. Диапазон должен быть диапазоном произвольного доступа с разбиением, иметь длину, равную размеру, указанному при создании этого объекта, и содержать элементы, которые являются либо типа std.complex.Complex, либо имеют по существу тот же интерфейс времени компиляции.
- Возвращает:
- Сигнал во временной области.
- Соглашения
- Показатель степени положительный, а множитель равен 1/N, т.е., output[j] := (1 / N) sum[ exp(+2 PI i j k / N) input[k] ].
- const void inverseFft(Ret, R)(R range, Ret buf)
Constraints: if (isRandomAccessRange!Ret && isComplexLike!(ElementType!Ret) && hasSlicing!Ret); -
Обратное БПФ, которое позволяет предоставить буфер, указанный пользователем. Буфер должен быть диапазоном произвольного доступа с разбиением, а его элементы должны быть каким-либо комплексноподобным типом.
- Complex!F[] fft(F = double, R)(R range);
void fft(Ret, R)(R range, Ret buf);
Complex!F[] inverseFft(F = double, R)(R range);
void inverseFft(Ret, R)(R range, Ret buf); -
Функции для удобства создания объекта
Fft, выполнения БПФ или обратного БПФ и возврата результата. Полезно для однократных БПФ.- Примечание
- В дополнение к удобству эти функции немного эффективнее, чем ручное создание объекта Fft для однократного использования, поскольку объект Fft детерминированно уничтожается до возврата этих функций.
- pure nothrow @nogc @safe size_t decimalToFactorial(ulong decimal, ref ubyte[21] fac);
-
Эта функция преобразует значение
decimalв значение в системе счисления факториалов, хранящееся вfac.Факториальное число строится как:
fac[0] * 0! + fac[1] * 1! + ... fac[20] * 20!- Параметры:
ulong decimalЗначение в десятичной системе счисления, которое нужно преобразовать в факториальную систему счисления. ubyte[21] facМассив для хранения факториального числа. Размер массива составляет 21, так как ulong.maxтребует 21 цифру в факториальной системе счисления.
- Возвращает:
- Переменная, хранящая количество цифр факториального числа, хранящегося в
fac.
- Примеры:
-
ubyte[21] fac; size_t idx = decimalToFactorial(2982, fac); writeln(fac[0]); // 4 writeln(fac[1]); // 0 writeln(fac[2]); // 4 writeln(fac[3]); // 1 writeln(fac[4]); // 0 writeln(fac[5]); // 0 writeln(fac[6]); // 0
© 1999–2021 The D Language Foundation
Licensed under the Boost License 1.0.
https://dlang.org/phobos/std_numeric.html