LINUX.ORG.RU

Работа с векторами в sbcl. Kann es besser sein?

 ,


0

2

Здравствуйте, Василий здесь.

Тут говорили, что в sbcl ничто не мешает запилить свой бордель с sse-векторами. Я в этом ихнем sbcl не большой спец и вообще считаю, что любителю компьютеров моего уровня нефиг лезть в такие дебри (а уровень мой маленький, я только включаю компьютер уверенно). Но я постарался, и вышло вот что:

http://pastebin.com/TKv583sb

Оно умеет складывать, вычитать, умножать (mulps), делить(divps) упакованные в xmm сингл-флоаты. Кто не знал, в sbcl есть тип simd-pack, а запакованный вектор можно сделать с помощью sb-vm::%make-simd-pack-single (ну или double, int).

Кроме того, оно умеет считать даже скалярное и векторное произведения 2 векторов (нижние 32 бита из пака в расчет не идут).

Да, внизу там векторное произведение, каким бы его написал нормальный человек. И оно работает медленнее, чем sse-вариант. Но это ни о чём не говорит (в sse варианте мы ещё ничего не консим).

Ну вот я хотел бы, чтобы вы покритиковали код (который 100% быдло) и ответели на пару вопросов:

1. Что фактически дает ключ :target в args и :from в results/temporary? 2. Что дает ключ load-if в args? Я так понял, что при пересылке, например, когда пересылка осуществляется в источник, это позволяет ничего не делать. Но точнее сказать не могу 3. А можно ли в define-vop сделать так, чтобы результат сохранялся в аргументе? Будет ли это правильно? Можно ли так сэкономить регистры?

Матчасть

=========================

А теперь, казалось бы, к чему это я? А к тому, что в этих ваших sse регистрах можно хранить кватернионы. И это очень хорошо для моих воксельных черепов! Все знают формулу

v' = qvq^{-1}, где q = cos a + p sin a
|p| = 1

которая позволяет повернуть вектор v вокруг вектора p на угол 2a (v,p - чисто мнимые кватернионы). Но в интернете я увидел якобы формулу аналог, которая, якобы, проще считается:

http://mollyrocket.com/forums/viewtopic.php?t=833&sid=3a84e00a70ccb046cfc...

t = 2 sin a * [p,v];
v' = v + cos a * t + sin a * [p,t]; 

[a,b] - cross product
(a,b) - dot product

Заметьте, что я её немного переписал, по определению q выше. Но ошибки нет, не так ли? А теперь я дам контрпруф, по которому она работать не должна. Я хотел бы понять, кто из нас не прав.

Итак, для чисто мнимых кватернионов: pv = [p,v] - (p,v) (*).

Пусть p перпендикулярен v, тогда pv = [p,v], так?

Окей, значит

v' = v + 2 * sin a* cos a * [p,v] + 2 * sin^2 a [p, [p, v]] или
v' = v + 2*sin a*cos a * pv + 2*sin^2 a p(pv) или
v' = v + 2*sin a*cos a * pv + 2*sin^2 a (pp)v (ассоциативность кватернионов)
v' = v + 2*sin a*cos a * pv + 2*sin^2 a (p,p)v (В силу (*)) или
v' = v + 2*sin a*cos a * pv + 2*sin^2 a*v  (т.к. |p| = 1) или
v' = 2*sin a*cos a * pv + (1+2*sin^2 a)v
Квадрат нормы будет
v' = (2*sin a*cos a)^2 + (1+2*sin^2 a)^2 (v,v)  (В силу (pv,pv) = (p,p)(v,v))

Явно, она не сохраняется. Что, формула не пашет? Проверил всё ещё раз и вроде я как бы тоже прав, помогайте.



Последнее исправление: JB (всего исправлений: 1)

Приложение этого к программированию (к гамедеву хотя бы) я думаю местным модераторам не надо объяснять. К тому же чисто прогерские вопросы тоже есть.

Это на всякий случай

shamaz
() автор топика

v' = v + 2*sin a*cos a * pv + 2*sin^2 a (p,p)v (В силу (*)) или

В этой строке (и далее ошибка) pp = -(p,p). Ща исправим:

v' = v + 2*sin a*cos a * pv - 2*sin^2 a (p,p)v
v' = v + 2*sin a*cos a * pv - 2*sin^2 a*v
v' = 2*sin a*cos a * pv (1-2*sin^2 a) v

Всё равно результат тот же

shamaz
() автор топика

Явно треды с викусей шли лучше

Очевидно

shamaz
() автор топика
Ответ на: комментарий от shamaz

Это маленькое преобразование тебе ничем не поможет? Формулы двойного угла, если что.

v' = 2*sin a*cos a * pv + (1-2*sin^2 a) v
v' = sin(2a)pv + cos(2a)v = v(cos(2a) + psin(2a))

Вот смотри:

http://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation#Proof_of_the_qu...

Там уже механическую работу проделали в твоих терминах (обрати внимание - там уже двойной угол a/2 vs a):

v' = v_перп. * cos(2a)  + [p,v_перп.] * sin(2a) + v_парал.

Пусть p перпендикулярен v, тогда pv = [p,v], так?

Раз перпендикулярны, то v_парал. ноль, v_перп. = v, a [p,v_перп] = pv. Получаем

v' = v(cos(2a) + psin(2a))

То, что ты и получил.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Формулы двойного угла, если что.

Ого, я бы не догадался :)

Теперь у этого есть смысл. Интересненько, как теперь оно будет работать в sbcl-е

shamaz
() автор топика
Ответ на: комментарий от yyk

Да там кватернионов вроде нет. А так вместо того, чтобы разбираться, что там, лучше наваять своё. Была бы она ещё официально частью этот ихнего sbcl, тогда был бы смысл её допиливать.

shamaz
() автор топика
Ответ на: комментарий от shamaz

ещё можно на SSE icXML прикрутить...

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.