nyaload

Журнал Пушыстого

Журнал Пушыстого

Entries by tag: paint mad skilz

mspaint circles
nyaload
_winnie
По ходу работы скриптов рисовал в задумчивости кружочки по-быстрому (под рукой оказался mspaint), внезапно вылезло вот такое:


(no subject)
nyaload
_winnie

because we can
nyaload
_winnie
Захотел сегодня сделать из зацикленного gif - не зацикленый. Чтобы анимация показывалась только один раз.

Нашёл описание формата, поправил два байта (unsigned number of repetitions) с количеством повторения с нуля (бесконечно зацикленый) на 1 (попробовал оба варианта, big endian и little endian). Не получилось, картинка осталась зацикленой. Тогда просто испортил заголовок описывающий анимацию, поменяв 21FF на 21AA. Получилось, gif теперь в FF и хроме не зацикленый. Но IE отказался его показывать. Тогда просто стёр этот блок. Получилось. Но FireFox действительно теперь показывает анимацию ровно один раз, а для перезапуска анимации - нужно перезагружать браузер. Блок легко кстати ищется глазами по строке "!..NETSCAPE2.0"

Давно ничего не редактировал в бинарном виде. Узнал, что в vim принято переключаться из бинарного режима в текстовый при помощи внешней программы конвертирования ( «:%!xxd» туда, и «:%!xxd -r» обратно ). Работает, но до нормального hex-редактора далеко (нельзя даже найти последовательность, которую перенесли на другую строку, для удаления байтов нужно переключиться в text-режим и запоминать в голове в штуках смещения, положение курсора естественно забывается).

Read more...Collapse )

Рефакторинг классиков
nyaload
_winnie
Почитал в n-й раз про метод Гаусса-Зейделя (wiki). Заметил, что внутренний цикл переписывается в одну строчку, если не выкидывать одно слагаемое из цикла, а вычесть его в самом конце. Причем "вычитается" оно заменой с x[i] = ... на x[i] +=

Метод Гаусса-Зейделя получается из метода Якоби добавлением бага "пишем данные туда же, откуда читаем". Наверняка так оно и было, а "разделение на верхне- и нижнетреугольную матрицы" уже потом (где-то в 1820-1870 годах) придумали.

Read more...Collapse )

bootstrap и квантили
nyaload
_winnie
Есть подозрение, что в bootstrap-семплировании для некоторых статистик можно избежать собственно семлирования, честно по формуле посчитав мат-ожидание результата или [2.5%, 97.5%] интервал распределения результата.

Выборка с возвращением в bootstrap - это тоже самое что и семплирование из эмпирического распределения выборки
обозначим эту эмпирическую функцию распределения как
применим -1 к равномерно распределённой на [0, 1] величине U(0,1), получим снова распределение

Чтобы создать одну bootstrap-выборку - можно взять выборку из n штук из U(0, 1) чисел и применить к ним -1
медиана bootstrap-выборки - это применение -1 к i-й порядковой статистике, где i равно n/2.
i-я порядковая статистика U(0, 1) - это вдоль и поперёк изученное бета-распределение
Берем это бета-распределение, берем его [2.5%, 97.5%] интервал распределения (через неполную бета-функцию или приближение нормальным распределением), втыкаем его границы в -1, получаем интервал в котором (97.5% - 2.5%) будет bootstrap-медиана

Таким же образом можно получать остальные квантили, не только медиану.

Велосипед? Или грабли? Или это настолько очевидно, что так всегда и делается?

плацебо Магия
nyaload
_winnie
Надо снять порчу с компьютера, — сказала цыганка, запустив DrWeb.


локальные минимумы
nyaload
_winnie
Придумал наверное очередной велосипед, но гугл по "gradient descent smoothing" находит pdf-ки за 2009+ года, но не времен Лапласа.

Что бы избежать попадания в миллион локальных минимумов, можно сделать так что бы их было чуть-чуть. Т.е. сделать из первого графика второй:



Сделать это можно например смешиванием g(x) = f(x-10α)+f(x-9α)+f(x-8α)+ ... +f(x+9α)+f(x+10α) или каким-нибудь другим умным low-pass фильтром. Подбирать 10 и α перебором, так что бы gradient descent из разных случайных точек приходил в одни и те же места, а не каждый раз в новую норку.

bayes theorem illustration
nyaload
_winnie
Когда в универе впервые рассказали про теорему байеса, было непонятно что это такое. Ну взяли определение
P(A|B) = P(A&B)/P(B),
разделили на такое же симметричное равенство
P(B|A) = P(A&B)/P(A),
P(A&B) сократилось, получили теорему байеса
P(A|B) = P(B|A)·P(A)/P(B)

Совершенно тривиальное доказательство на уровне подстановки букв. Одновременно с этим - непонятно, как привязано к реальности. Постоянно путаешь, что там в знаменателе, что в числителе, что надо ставить справа от |, а что слева. Почему B или A - это априорные или апостериорные вероятности, ведь B от A в доказательстве ничем не отличаются (P(болезнь|видимый симптом) - апостериорная, P(болезнь вообще) - априорная).

У нас препод был формалист, он даже не объяснил почему условная вероятность называется условной. Вот вам детки определения, вот аксиомы. Борелевскаясигмаалгебра — это минимальнаясигмаалгебрасодержащаявсеоткрытыеподмножества, переходим к интегралу лебега. Подстанавливаем буквы в формулы, получаем новые формулы.

Тогда нарисовал себе картинку, что бы легче было применять её для решения задач типа:
Если пациента у волчанка, то он пердит с вероятностью 90%, если болеет не волчанкой - то пердит с вероятностью 10%, всего волчанкой болеют 1% пациентов. Пациент пернул, надо выяснить насколько велика вероятность волчанки.
собственно, иллюстрация:Collapse )

И визуальное решение задачи про волчанку. Видно, что, несмотря на кажущуюся надёжность симптома пердежа, среди больных с этим с симптомом доля больных волчанкой (вертикальный синий прямоугольник справа) заметно меньше, чем доля не больных (синий прямоугольник снизу справа): Read more...Collapse )

упаковка float 01 <-> byte
nyaload
_winnie
Часто значения float из промежутка [0, 1] хранят в виде байта или в двух байтах, для экономии места.

Когда незадумчивые программисты пишут код конвертации float2byte и byte2float, возникают следующие ошибки:

1) float2byte( byte2float (X) ) != X
2) float2byte( 1.0 ) отображается в 256, то есть в байт 0.
3) float2byte( byte2float (X) + небольшой шум ) != X
4) часто важно что бы byte2float(255) == 1.0 и byte2float(0) == 0.0
5) множества float соответствующие значению байта - имеют разный размер. Напр. 0 и 255 отображаются в промежутки длины 1/510, а 1,2,..254 - в промежутки 1/255

1,2 - тупо багло. 3,4,5 - важны, но иногда можно пожертвовать, например часто забивают на 5 без особых проблем, или даже с пользой если есть выход за пределы [0..1] в промежуточных вычислениях.

Формулы которые пишут незадумчиво с налёту - это обычно {b=int(f*255.0), f=b/255.0}, {b=min(int(f*256.0),255), f=b/256.0} и тп.

Получают небольшие изменения яркости при каждом save/load, странные шумы, превращение 255 в 254, белый цвет умноженый на белый - даёт не белый, и тп.

Что бы избежать этих ошибок, надо представлять себе такую картинку: делим отрезок [0..1] на 256 равных отрезков (полуоткрытых интервалов). Байты должны превращаться в серединки или другие внутренности этих отрезков, а эти отрезки - в байты, взаимно однозначно. Вариант: промежутки для 1,2,..254 одинаковые, а для 0 и 255 - в два раза меньше.

Примеры устойчивых упаковок:

byte2float:
   f = (b/255.0f - чуть меньше устойчиво к шуму, max-шума=1/(255*256). Зато 0 и 255 превращаются в 0.0f и 1.0f.
   или f = (b + 0.5f)/256.0f - устойчиво к шуму, max-шума=1/(2*256), но 255 отображается в 511.0/512.0 а не в 1.0. Белый цвет умноженый на белый много раз станет серым.

float2byte:
   b = min( int(f*256), 255 )
   или b = int(f*255.9999f)

И ещё вариант, классический, спасибо zeux за его комментарий (рекомендую, если сомневаетесь что выбрать):

byte2float:
   f = b/255.0f
float2byte:
   b = int(f*255 + 0.5)
Хорош всем, только интервалы для 0 и 255 в два раза меньше чем для 1,2,..,254.



Увы, многие библиотеки об этом не задумываются. Если у вас есть многократный save load с преобразованием float/byte, сделайте code review в этом месте. Это могут быть упакованые анимации, heighmap ландшафтов, очевидно текстуры, веса костей для скелетной анимации, всякие веса смешиваний и долей. В базах данных тоже любят оптимизировать такие float.

Read more...Collapse )

mspaint.exe как векторный mad skilz редактор
nyaload
_winnie
Сегодня скачал новый Inkscape (свободный векторный редактор), интерфейс остался антигуманным. Ну или я остался слишком тупым для его интерфейса.

Надо было-то нарисовать два круга и вычесть из них прямоугольник, то что осталось - заштриховать. В процессе наткнулся на следующие грабли.
1) в тултипах к кнопкам не подписаны горячие клавиши.
2) Группа объектов не может быть сконвертирована в path.
3) в диалоге паттернов (для штриховки) написано "используйте node tool что бы повернуть штриховку". Тем не менее, вдумчивое десятиминутное изучение документации и тыканья мышкой (patterns, node tool) ручек управления паттерном не дало.

upd: ручки управления паттерном были в километре от фигуры, в углу документа, за пределами экрана, handles will appear in the upper-left corner of the canvas. Что тем не менее не снимает мой rage по поводу гуманности к новичкам-дизайнерам и юзабилити. И я не один такой.

Только зря время потерял, закрыл, буду ждать следующей версии, а схему нарисовал в mspaint.exeCollapse )

?

Log in