Так я и пишу: исходное пространство. Domain, если хотите, не codomain.
Кажется, я понял Ваш вопрос. Вы спрашиваете, почему бы не взять в качестве примера H=R вместо L^2 и t вместо 1_{[0,t]}? Ну потому что это был бы тривиальный пример. Броуновского движения и тем более интеграла Ито Вы бы не получили.
Тогда я вообще ничего не понимаю. Умножение чего на что?
1_{[0,t]}(s) * f(s). Я надеялся, что это будет понятно из контекста.
Долгое время я следовал этому правилу, потому что «так принято». Но недавно сам себя спросил, если там, за бугром, это называется probability theory, то чем мы хуже? Есть у нас теория меры, теория относительности, но вот почему-то теория вероятностей. Вероятность — это же та же мера. Я могу понять теорию игр или теорию чисел, так как там мы имеем дело с чем-то разделяемым. Но здесь… Здесь абсолютная неправильность «теории вероятности» для меня пока под вопросом.
Я не до конца неграмотный человек, но все же решил: пускай уж сегодня цепляет глаз, завтра, может, мы привыкнем.
P.S. теория поля или теория полей?
Когда вы вводите понятие винеровского процесса, почему в качестве исходного пространства вы рассматриваете L^2, а не, ну, R, постулируя B(t) = W(t) ~ N(0; t)?
Путаетесь. В этом примере Винеровский процесс отображает из пространства функций L^2 в вероятностное пространство. R тут не причем.
Чуть ниже вы вводите понятие интеграла Ито, и там справа у W в скобочках фигурирует 1_[0; t] и f. А как они связаны? Это не скалярное произведение — формула тогда не тайпчекается. При этом это и не композиция (1_[0; t] \dot f = 1_[0; t], что не очень интересно).
Это не композиция и не скалярное произведение, а простое умножение.
Возможно, у нас путаница в терминологии. Под коллизией я подразумевал совпадения значений seed у двух экземпляров. В Вашем примере они и так равны по умолчанию. Но две одинаковые выборки нам не нужны.
Если мы работаем в одном потоке, нужно ли нам создавать несколько экземпляров FRand? Я исходил из того, что нет, и поэтому генератор был статическим. Иначе, для разных экземпляров может возникать проблема коллизии. Или я не прав?
Про поддержку многопоточности в статье указано не было, но в дальнейших версиях это будет учтено. Смысл Вашего комментария лишь в том чтобы повторить вышесказанное.
По поводу С++17, он в основном был нужен ввиду появившихся в нем специальных математических функций.
Ваша библиотека выглядит прелестно. Но это лишь обертка вокруг функций std, а RandLib в свою очередь полная альтернатива стандартной библиотеке. Кроме того, у Вас только генераторы. Возможности RandLib куда шире (функции распределения, моменты и т.п.). Тут не уложиться в header-only.
Грешен, но упомянутые макросы единственные на всю библиотеку. Знаю, какая на них реакция в целом, но в данном случае их использование было удобно мне как разработчику, и виделось удобным пользователю. Про префикс Вы правы, будет учтено.
1. Согласен с тем, что нужно добавить функционал на подобие srand. Но не стоит заставлять пользователя всегда его использовать. В целом, Вы правы.
2. Наверное, еще лучше их сделать static thread_local. Однако это сильно повлияет на скорость. В таком случае надо предоставлять выбор. В конце концов, rand() сделан по схожему принципу и тоже не является потоко-безопасным.
В своё время мне объяснили разницу подобным образом: пусть на вход подаётся K выборок, в каждой из которых примерно N элементов.
Если N >> K — это задача статистики.
Если N << K — это data science.
Как я писал выше, Вы можете сослаться на книгу «Curve and Surface fitting with splines» автора Paul Dierckx. Я лишь модифицировал взятый оттуда алгоритм.
А лично у меня лишь одна статья в англоязычном научном журнале, и ссылаться на неё Вам вряд ли придётся =)
Посмотрите книгу Curve and Surface Fitting with Splines (Numerical Mathematics and Scientific Computation), автор Paul Dierckx. Основные идеи в статье взяты оттуда.
Не то, на чем бы я хотел акцентировать внимание в этой статье. Включен ли 0 или включен ли 1 в генерации равномерно распределенной величины не имеет большого значения. Всегда можно обработать непредвиденные ситуации. Я лишь пытался рассказать о быстрых алгоритмах для разных распределений
Маловероятно, что функция Uniform(0, 1) вернет 0. И (практически) невероятно, что это произойдет два раза подряд. Тем не менее, вопрос хороший.
В приложенном коде я не обрабатывал опасные ситуации, дабы сделать его более понятным. Можете обратить внимание на функцию PoissonKnuth и увидеть, что произойдет, если Uniform(0, 1) вернет 0. Во избежание подобных казусов можно использовать в качестве базового генератора функцию, возвращающую натуральные числа, начиная с 1. Тогда функция Uniform(0,1) = BasicRandGenerator() / RAND_MAX будет генерировать числа в диапазоне (0, 1], что будет считаться эквивалентным распределением почти всюду.
1_{[0,t]}(s) * f(s). Я надеялся, что это будет понятно из контекста.
Я не до конца неграмотный человек, но все же решил: пускай уж сегодня цепляет глаз, завтра, может, мы привыкнем.
P.S. теория поля или теория полей?
Путаетесь. В этом примере Винеровский процесс отображает из пространства функций L^2 в вероятностное пространство. R тут не причем.
Это не композиция и не скалярное произведение, а простое умножение.
P.s. Если использовать только time, то seedы тоже будут одинаковыми, если созданы в одно время.
По поводу С++17, он в основном был нужен ввиду появившихся в нем специальных математических функций.
Грешен, но упомянутые макросы единственные на всю библиотеку. Знаю, какая на них реакция в целом, но в данном случае их использование было удобно мне как разработчику, и виделось удобным пользователю. Про префикс Вы правы, будет учтено.
2. Наверное, еще лучше их сделать static thread_local. Однако это сильно повлияет на скорость. В таком случае надо предоставлять выбор. В конце концов, rand() сделан по схожему принципу и тоже не является потоко-безопасным.
Если N >> K — это задача статистики.
Если N << K — это data science.
А лично у меня лишь одна статья в англоязычном научном журнале, и ссылаться на неё Вам вряд ли придётся =)
Приоткрою завесу интриги с палочками и цифрами:
В приложенном коде я не обрабатывал опасные ситуации, дабы сделать его более понятным. Можете обратить внимание на функцию PoissonKnuth и увидеть, что произойдет, если Uniform(0, 1) вернет 0. Во избежание подобных казусов можно использовать в качестве базового генератора функцию, возвращающую натуральные числа, начиная с 1. Тогда функция Uniform(0,1) = BasicRandGenerator() / RAND_MAX будет генерировать числа в диапазоне (0, 1], что будет считаться эквивалентным распределением почти всюду.