test_glsl.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998
  1. from sympy.core import (pi, symbols, Rational, Integer, GoldenRatio, EulerGamma,
  2. Catalan, Lambda, Dummy, Eq, Ne, Le, Lt, Gt, Ge)
  3. from sympy.functions import Piecewise, sin, cos, Abs, exp, ceiling, sqrt
  4. from sympy.testing.pytest import raises, warns_deprecated_sympy
  5. from sympy.printing.glsl import GLSLPrinter
  6. from sympy.printing.str import StrPrinter
  7. from sympy.utilities.lambdify import implemented_function
  8. from sympy.tensor import IndexedBase, Idx
  9. from sympy.matrices import Matrix, MatrixSymbol
  10. from sympy.core import Tuple
  11. from sympy.printing.glsl import glsl_code
  12. import textwrap
  13. x, y, z = symbols('x,y,z')
  14. def test_printmethod():
  15. assert glsl_code(Abs(x)) == "abs(x)"
  16. def test_print_without_operators():
  17. assert glsl_code(x*y,use_operators = False) == 'mul(x, y)'
  18. assert glsl_code(x**y+z,use_operators = False) == 'add(pow(x, y), z)'
  19. assert glsl_code(x*(y+z),use_operators = False) == 'mul(x, add(y, z))'
  20. assert glsl_code(x*(y+z),use_operators = False) == 'mul(x, add(y, z))'
  21. assert glsl_code(x*(y+z**y**0.5),use_operators = False) == 'mul(x, add(y, pow(z, sqrt(y))))'
  22. assert glsl_code(-x-y, use_operators=False, zero='zero()') == 'sub(zero(), add(x, y))'
  23. assert glsl_code(-x-y, use_operators=False) == 'sub(0.0, add(x, y))'
  24. def test_glsl_code_sqrt():
  25. assert glsl_code(sqrt(x)) == "sqrt(x)"
  26. assert glsl_code(x**0.5) == "sqrt(x)"
  27. assert glsl_code(sqrt(x)) == "sqrt(x)"
  28. def test_glsl_code_Pow():
  29. g = implemented_function('g', Lambda(x, 2*x))
  30. assert glsl_code(x**3) == "pow(x, 3.0)"
  31. assert glsl_code(x**(y**3)) == "pow(x, pow(y, 3.0))"
  32. assert glsl_code(1/(g(x)*3.5)**(x - y**x)/(x**2 + y)) == \
  33. "pow(3.5*2*x, -x + pow(y, x))/(pow(x, 2.0) + y)"
  34. assert glsl_code(x**-1.0) == '1.0/x'
  35. def test_glsl_code_Relational():
  36. assert glsl_code(Eq(x, y)) == "x == y"
  37. assert glsl_code(Ne(x, y)) == "x != y"
  38. assert glsl_code(Le(x, y)) == "x <= y"
  39. assert glsl_code(Lt(x, y)) == "x < y"
  40. assert glsl_code(Gt(x, y)) == "x > y"
  41. assert glsl_code(Ge(x, y)) == "x >= y"
  42. def test_glsl_code_constants_mathh():
  43. assert glsl_code(exp(1)) == "float E = 2.71828183;\nE"
  44. assert glsl_code(pi) == "float pi = 3.14159265;\npi"
  45. # assert glsl_code(oo) == "Number.POSITIVE_INFINITY"
  46. # assert glsl_code(-oo) == "Number.NEGATIVE_INFINITY"
  47. def test_glsl_code_constants_other():
  48. assert glsl_code(2*GoldenRatio) == "float GoldenRatio = 1.61803399;\n2*GoldenRatio"
  49. assert glsl_code(2*Catalan) == "float Catalan = 0.915965594;\n2*Catalan"
  50. assert glsl_code(2*EulerGamma) == "float EulerGamma = 0.577215665;\n2*EulerGamma"
  51. def test_glsl_code_Rational():
  52. assert glsl_code(Rational(3, 7)) == "3.0/7.0"
  53. assert glsl_code(Rational(18, 9)) == "2"
  54. assert glsl_code(Rational(3, -7)) == "-3.0/7.0"
  55. assert glsl_code(Rational(-3, -7)) == "3.0/7.0"
  56. def test_glsl_code_Integer():
  57. assert glsl_code(Integer(67)) == "67"
  58. assert glsl_code(Integer(-1)) == "-1"
  59. def test_glsl_code_functions():
  60. assert glsl_code(sin(x) ** cos(x)) == "pow(sin(x), cos(x))"
  61. def test_glsl_code_inline_function():
  62. x = symbols('x')
  63. g = implemented_function('g', Lambda(x, 2*x))
  64. assert glsl_code(g(x)) == "2*x"
  65. g = implemented_function('g', Lambda(x, 2*x/Catalan))
  66. assert glsl_code(g(x)) == "float Catalan = 0.915965594;\n2*x/Catalan"
  67. A = IndexedBase('A')
  68. i = Idx('i', symbols('n', integer=True))
  69. g = implemented_function('g', Lambda(x, x*(1 + x)*(2 + x)))
  70. assert glsl_code(g(A[i]), assign_to=A[i]) == (
  71. "for (int i=0; i<n; i++){\n"
  72. " A[i] = (A[i] + 1)*(A[i] + 2)*A[i];\n"
  73. "}"
  74. )
  75. def test_glsl_code_exceptions():
  76. assert glsl_code(ceiling(x)) == "ceil(x)"
  77. assert glsl_code(Abs(x)) == "abs(x)"
  78. def test_glsl_code_boolean():
  79. assert glsl_code(x & y) == "x && y"
  80. assert glsl_code(x | y) == "x || y"
  81. assert glsl_code(~x) == "!x"
  82. assert glsl_code(x & y & z) == "x && y && z"
  83. assert glsl_code(x | y | z) == "x || y || z"
  84. assert glsl_code((x & y) | z) == "z || x && y"
  85. assert glsl_code((x | y) & z) == "z && (x || y)"
  86. def test_glsl_code_Piecewise():
  87. expr = Piecewise((x, x < 1), (x**2, True))
  88. p = glsl_code(expr)
  89. s = \
  90. """\
  91. ((x < 1) ? (
  92. x
  93. )
  94. : (
  95. pow(x, 2.0)
  96. ))\
  97. """
  98. assert p == s
  99. assert glsl_code(expr, assign_to="c") == (
  100. "if (x < 1) {\n"
  101. " c = x;\n"
  102. "}\n"
  103. "else {\n"
  104. " c = pow(x, 2.0);\n"
  105. "}")
  106. # Check that Piecewise without a True (default) condition error
  107. expr = Piecewise((x, x < 1), (x**2, x > 1), (sin(x), x > 0))
  108. raises(ValueError, lambda: glsl_code(expr))
  109. def test_glsl_code_Piecewise_deep():
  110. p = glsl_code(2*Piecewise((x, x < 1), (x**2, True)))
  111. s = \
  112. """\
  113. 2*((x < 1) ? (
  114. x
  115. )
  116. : (
  117. pow(x, 2.0)
  118. ))\
  119. """
  120. assert p == s
  121. def test_glsl_code_settings():
  122. raises(TypeError, lambda: glsl_code(sin(x), method="garbage"))
  123. def test_glsl_code_Indexed():
  124. n, m, o = symbols('n m o', integer=True)
  125. i, j, k = Idx('i', n), Idx('j', m), Idx('k', o)
  126. p = GLSLPrinter()
  127. p._not_c = set()
  128. x = IndexedBase('x')[j]
  129. assert p._print_Indexed(x) == 'x[j]'
  130. A = IndexedBase('A')[i, j]
  131. assert p._print_Indexed(A) == 'A[%s]' % (m*i+j)
  132. B = IndexedBase('B')[i, j, k]
  133. assert p._print_Indexed(B) == 'B[%s]' % (i*o*m+j*o+k)
  134. assert p._not_c == set()
  135. def test_glsl_code_list_tuple_Tuple():
  136. assert glsl_code([1,2,3,4]) == 'vec4(1, 2, 3, 4)'
  137. assert glsl_code([1,2,3],glsl_types=False) == 'float[3](1, 2, 3)'
  138. assert glsl_code([1,2,3]) == glsl_code((1,2,3))
  139. assert glsl_code([1,2,3]) == glsl_code(Tuple(1,2,3))
  140. m = MatrixSymbol('A',3,4)
  141. assert glsl_code([m[0],m[1]])
  142. def test_glsl_code_loops_matrix_vector():
  143. n, m = symbols('n m', integer=True)
  144. A = IndexedBase('A')
  145. x = IndexedBase('x')
  146. y = IndexedBase('y')
  147. i = Idx('i', m)
  148. j = Idx('j', n)
  149. s = (
  150. 'for (int i=0; i<m; i++){\n'
  151. ' y[i] = 0.0;\n'
  152. '}\n'
  153. 'for (int i=0; i<m; i++){\n'
  154. ' for (int j=0; j<n; j++){\n'
  155. ' y[i] = A[n*i + j]*x[j] + y[i];\n'
  156. ' }\n'
  157. '}'
  158. )
  159. c = glsl_code(A[i, j]*x[j], assign_to=y[i])
  160. assert c == s
  161. def test_dummy_loops():
  162. i, m = symbols('i m', integer=True, cls=Dummy)
  163. x = IndexedBase('x')
  164. y = IndexedBase('y')
  165. i = Idx(i, m)
  166. expected = (
  167. 'for (int i_%(icount)i=0; i_%(icount)i<m_%(mcount)i; i_%(icount)i++){\n'
  168. ' y[i_%(icount)i] = x[i_%(icount)i];\n'
  169. '}'
  170. ) % {'icount': i.label.dummy_index, 'mcount': m.dummy_index}
  171. code = glsl_code(x[i], assign_to=y[i])
  172. assert code == expected
  173. def test_glsl_code_loops_add():
  174. n, m = symbols('n m', integer=True)
  175. A = IndexedBase('A')
  176. x = IndexedBase('x')
  177. y = IndexedBase('y')
  178. z = IndexedBase('z')
  179. i = Idx('i', m)
  180. j = Idx('j', n)
  181. s = (
  182. 'for (int i=0; i<m; i++){\n'
  183. ' y[i] = x[i] + z[i];\n'
  184. '}\n'
  185. 'for (int i=0; i<m; i++){\n'
  186. ' for (int j=0; j<n; j++){\n'
  187. ' y[i] = A[n*i + j]*x[j] + y[i];\n'
  188. ' }\n'
  189. '}'
  190. )
  191. c = glsl_code(A[i, j]*x[j] + x[i] + z[i], assign_to=y[i])
  192. assert c == s
  193. def test_glsl_code_loops_multiple_contractions():
  194. n, m, o, p = symbols('n m o p', integer=True)
  195. a = IndexedBase('a')
  196. b = IndexedBase('b')
  197. y = IndexedBase('y')
  198. i = Idx('i', m)
  199. j = Idx('j', n)
  200. k = Idx('k', o)
  201. l = Idx('l', p)
  202. s = (
  203. 'for (int i=0; i<m; i++){\n'
  204. ' y[i] = 0.0;\n'
  205. '}\n'
  206. 'for (int i=0; i<m; i++){\n'
  207. ' for (int j=0; j<n; j++){\n'
  208. ' for (int k=0; k<o; k++){\n'
  209. ' for (int l=0; l<p; l++){\n'
  210. ' y[i] = a[%s]*b[%s] + y[i];\n' % (i*n*o*p + j*o*p + k*p + l, j*o*p + k*p + l) +\
  211. ' }\n'
  212. ' }\n'
  213. ' }\n'
  214. '}'
  215. )
  216. c = glsl_code(b[j, k, l]*a[i, j, k, l], assign_to=y[i])
  217. assert c == s
  218. def test_glsl_code_loops_addfactor():
  219. n, m, o, p = symbols('n m o p', integer=True)
  220. a = IndexedBase('a')
  221. b = IndexedBase('b')
  222. c = IndexedBase('c')
  223. y = IndexedBase('y')
  224. i = Idx('i', m)
  225. j = Idx('j', n)
  226. k = Idx('k', o)
  227. l = Idx('l', p)
  228. s = (
  229. 'for (int i=0; i<m; i++){\n'
  230. ' y[i] = 0.0;\n'
  231. '}\n'
  232. 'for (int i=0; i<m; i++){\n'
  233. ' for (int j=0; j<n; j++){\n'
  234. ' for (int k=0; k<o; k++){\n'
  235. ' for (int l=0; l<p; l++){\n'
  236. ' y[i] = (a[%s] + b[%s])*c[%s] + y[i];\n' % (i*n*o*p + j*o*p + k*p + l, i*n*o*p + j*o*p + k*p + l, j*o*p + k*p + l) +\
  237. ' }\n'
  238. ' }\n'
  239. ' }\n'
  240. '}'
  241. )
  242. c = glsl_code((a[i, j, k, l] + b[i, j, k, l])*c[j, k, l], assign_to=y[i])
  243. assert c == s
  244. def test_glsl_code_loops_multiple_terms():
  245. n, m, o, p = symbols('n m o p', integer=True)
  246. a = IndexedBase('a')
  247. b = IndexedBase('b')
  248. c = IndexedBase('c')
  249. y = IndexedBase('y')
  250. i = Idx('i', m)
  251. j = Idx('j', n)
  252. k = Idx('k', o)
  253. s0 = (
  254. 'for (int i=0; i<m; i++){\n'
  255. ' y[i] = 0.0;\n'
  256. '}\n'
  257. )
  258. s1 = (
  259. 'for (int i=0; i<m; i++){\n'
  260. ' for (int j=0; j<n; j++){\n'
  261. ' for (int k=0; k<o; k++){\n'
  262. ' y[i] = b[j]*b[k]*c[%s] + y[i];\n' % (i*n*o + j*o + k) +\
  263. ' }\n'
  264. ' }\n'
  265. '}\n'
  266. )
  267. s2 = (
  268. 'for (int i=0; i<m; i++){\n'
  269. ' for (int k=0; k<o; k++){\n'
  270. ' y[i] = a[%s]*b[k] + y[i];\n' % (i*o + k) +\
  271. ' }\n'
  272. '}\n'
  273. )
  274. s3 = (
  275. 'for (int i=0; i<m; i++){\n'
  276. ' for (int j=0; j<n; j++){\n'
  277. ' y[i] = a[%s]*b[j] + y[i];\n' % (i*n + j) +\
  278. ' }\n'
  279. '}\n'
  280. )
  281. c = glsl_code(
  282. b[j]*a[i, j] + b[k]*a[i, k] + b[j]*b[k]*c[i, j, k], assign_to=y[i])
  283. assert (c == s0 + s1 + s2 + s3[:-1] or
  284. c == s0 + s1 + s3 + s2[:-1] or
  285. c == s0 + s2 + s1 + s3[:-1] or
  286. c == s0 + s2 + s3 + s1[:-1] or
  287. c == s0 + s3 + s1 + s2[:-1] or
  288. c == s0 + s3 + s2 + s1[:-1])
  289. def test_Matrix_printing():
  290. # Test returning a Matrix
  291. mat = Matrix([x*y, Piecewise((2 + x, y>0), (y, True)), sin(z)])
  292. A = MatrixSymbol('A', 3, 1)
  293. assert glsl_code(mat, assign_to=A) == (
  294. '''A[0][0] = x*y;
  295. if (y > 0) {
  296. A[1][0] = x + 2;
  297. }
  298. else {
  299. A[1][0] = y;
  300. }
  301. A[2][0] = sin(z);''' )
  302. assert glsl_code(Matrix([A[0],A[1]]))
  303. # Test using MatrixElements in expressions
  304. expr = Piecewise((2*A[2, 0], x > 0), (A[2, 0], True)) + sin(A[1, 0]) + A[0, 0]
  305. assert glsl_code(expr) == (
  306. '''((x > 0) ? (
  307. 2*A[2][0]
  308. )
  309. : (
  310. A[2][0]
  311. )) + sin(A[1][0]) + A[0][0]''' )
  312. # Test using MatrixElements in a Matrix
  313. q = MatrixSymbol('q', 5, 1)
  314. M = MatrixSymbol('M', 3, 3)
  315. m = Matrix([[sin(q[1,0]), 0, cos(q[2,0])],
  316. [q[1,0] + q[2,0], q[3, 0], 5],
  317. [2*q[4, 0]/q[1,0], sqrt(q[0,0]) + 4, 0]])
  318. assert glsl_code(m,M) == (
  319. '''M[0][0] = sin(q[1]);
  320. M[0][1] = 0;
  321. M[0][2] = cos(q[2]);
  322. M[1][0] = q[1] + q[2];
  323. M[1][1] = q[3];
  324. M[1][2] = 5;
  325. M[2][0] = 2*q[4]/q[1];
  326. M[2][1] = sqrt(q[0]) + 4;
  327. M[2][2] = 0;'''
  328. )
  329. def test_Matrices_1x7():
  330. gl = glsl_code
  331. A = Matrix([1,2,3,4,5,6,7])
  332. assert gl(A) == 'float[7](1, 2, 3, 4, 5, 6, 7)'
  333. assert gl(A.transpose()) == 'float[7](1, 2, 3, 4, 5, 6, 7)'
  334. def test_Matrices_1x7_array_type_int():
  335. gl = glsl_code
  336. A = Matrix([1,2,3,4,5,6,7])
  337. assert gl(A, array_type='int') == 'int[7](1, 2, 3, 4, 5, 6, 7)'
  338. def test_Tuple_array_type_custom():
  339. gl = glsl_code
  340. A = symbols('a b c')
  341. assert gl(A, array_type='AbcType', glsl_types=False) == 'AbcType[3](a, b, c)'
  342. def test_Matrices_1x7_spread_assign_to_symbols():
  343. gl = glsl_code
  344. A = Matrix([1,2,3,4,5,6,7])
  345. assign_to = symbols('x.a x.b x.c x.d x.e x.f x.g')
  346. assert gl(A, assign_to=assign_to) == textwrap.dedent('''\
  347. x.a = 1;
  348. x.b = 2;
  349. x.c = 3;
  350. x.d = 4;
  351. x.e = 5;
  352. x.f = 6;
  353. x.g = 7;'''
  354. )
  355. def test_spread_assign_to_nested_symbols():
  356. gl = glsl_code
  357. expr = ((1,2,3), (1,2,3))
  358. assign_to = (symbols('a b c'), symbols('x y z'))
  359. assert gl(expr, assign_to=assign_to) == textwrap.dedent('''\
  360. a = 1;
  361. b = 2;
  362. c = 3;
  363. x = 1;
  364. y = 2;
  365. z = 3;'''
  366. )
  367. def test_spread_assign_to_deeply_nested_symbols():
  368. gl = glsl_code
  369. a, b, c, x, y, z = symbols('a b c x y z')
  370. expr = (((1,2),3), ((1,2),3))
  371. assign_to = (((a, b), c), ((x, y), z))
  372. assert gl(expr, assign_to=assign_to) == textwrap.dedent('''\
  373. a = 1;
  374. b = 2;
  375. c = 3;
  376. x = 1;
  377. y = 2;
  378. z = 3;'''
  379. )
  380. def test_matrix_of_tuples_spread_assign_to_symbols():
  381. gl = glsl_code
  382. with warns_deprecated_sympy():
  383. expr = Matrix([[(1,2),(3,4)],[(5,6),(7,8)]])
  384. assign_to = (symbols('a b'), symbols('c d'), symbols('e f'), symbols('g h'))
  385. assert gl(expr, assign_to) == textwrap.dedent('''\
  386. a = 1;
  387. b = 2;
  388. c = 3;
  389. d = 4;
  390. e = 5;
  391. f = 6;
  392. g = 7;
  393. h = 8;'''
  394. )
  395. def test_cannot_assign_to_cause_mismatched_length():
  396. expr = (1, 2)
  397. assign_to = symbols('x y z')
  398. raises(ValueError, lambda: glsl_code(expr, assign_to))
  399. def test_matrix_4x4_assign():
  400. gl = glsl_code
  401. expr = MatrixSymbol('A',4,4) * MatrixSymbol('B',4,4) + MatrixSymbol('C',4,4)
  402. assign_to = MatrixSymbol('X',4,4)
  403. assert gl(expr, assign_to=assign_to) == textwrap.dedent('''\
  404. X[0][0] = A[0][0]*B[0][0] + A[0][1]*B[1][0] + A[0][2]*B[2][0] + A[0][3]*B[3][0] + C[0][0];
  405. X[0][1] = A[0][0]*B[0][1] + A[0][1]*B[1][1] + A[0][2]*B[2][1] + A[0][3]*B[3][1] + C[0][1];
  406. X[0][2] = A[0][0]*B[0][2] + A[0][1]*B[1][2] + A[0][2]*B[2][2] + A[0][3]*B[3][2] + C[0][2];
  407. X[0][3] = A[0][0]*B[0][3] + A[0][1]*B[1][3] + A[0][2]*B[2][3] + A[0][3]*B[3][3] + C[0][3];
  408. X[1][0] = A[1][0]*B[0][0] + A[1][1]*B[1][0] + A[1][2]*B[2][0] + A[1][3]*B[3][0] + C[1][0];
  409. X[1][1] = A[1][0]*B[0][1] + A[1][1]*B[1][1] + A[1][2]*B[2][1] + A[1][3]*B[3][1] + C[1][1];
  410. X[1][2] = A[1][0]*B[0][2] + A[1][1]*B[1][2] + A[1][2]*B[2][2] + A[1][3]*B[3][2] + C[1][2];
  411. X[1][3] = A[1][0]*B[0][3] + A[1][1]*B[1][3] + A[1][2]*B[2][3] + A[1][3]*B[3][3] + C[1][3];
  412. X[2][0] = A[2][0]*B[0][0] + A[2][1]*B[1][0] + A[2][2]*B[2][0] + A[2][3]*B[3][0] + C[2][0];
  413. X[2][1] = A[2][0]*B[0][1] + A[2][1]*B[1][1] + A[2][2]*B[2][1] + A[2][3]*B[3][1] + C[2][1];
  414. X[2][2] = A[2][0]*B[0][2] + A[2][1]*B[1][2] + A[2][2]*B[2][2] + A[2][3]*B[3][2] + C[2][2];
  415. X[2][3] = A[2][0]*B[0][3] + A[2][1]*B[1][3] + A[2][2]*B[2][3] + A[2][3]*B[3][3] + C[2][3];
  416. X[3][0] = A[3][0]*B[0][0] + A[3][1]*B[1][0] + A[3][2]*B[2][0] + A[3][3]*B[3][0] + C[3][0];
  417. X[3][1] = A[3][0]*B[0][1] + A[3][1]*B[1][1] + A[3][2]*B[2][1] + A[3][3]*B[3][1] + C[3][1];
  418. X[3][2] = A[3][0]*B[0][2] + A[3][1]*B[1][2] + A[3][2]*B[2][2] + A[3][3]*B[3][2] + C[3][2];
  419. X[3][3] = A[3][0]*B[0][3] + A[3][1]*B[1][3] + A[3][2]*B[2][3] + A[3][3]*B[3][3] + C[3][3];'''
  420. )
  421. def test_1xN_vecs():
  422. gl = glsl_code
  423. for i in range(1,10):
  424. A = Matrix(range(i))
  425. assert gl(A.transpose()) == gl(A)
  426. assert gl(A,mat_transpose=True) == gl(A)
  427. if i > 1:
  428. if i <= 4:
  429. assert gl(A) == 'vec%s(%s)' % (i,', '.join(str(s) for s in range(i)))
  430. else:
  431. assert gl(A) == 'float[%s](%s)' % (i,', '.join(str(s) for s in range(i)))
  432. def test_MxN_mats():
  433. generatedAssertions='def test_misc_mats():\n'
  434. for i in range(1,6):
  435. for j in range(1,6):
  436. A = Matrix([[x + y*j for x in range(j)] for y in range(i)])
  437. gl = glsl_code(A)
  438. glTransposed = glsl_code(A,mat_transpose=True)
  439. generatedAssertions+=' mat = '+StrPrinter()._print(A)+'\n\n'
  440. generatedAssertions+=' gl = \'\'\''+gl+'\'\'\'\n'
  441. generatedAssertions+=' glTransposed = \'\'\''+glTransposed+'\'\'\'\n\n'
  442. generatedAssertions+=' assert glsl_code(mat) == gl\n'
  443. generatedAssertions+=' assert glsl_code(mat,mat_transpose=True) == glTransposed\n'
  444. if i == 1 and j == 1:
  445. assert gl == '0'
  446. elif i <= 4 and j <= 4 and i>1 and j>1:
  447. assert gl.startswith('mat%s' % j)
  448. assert glTransposed.startswith('mat%s' % i)
  449. elif i == 1 and j <= 4:
  450. assert gl.startswith('vec')
  451. elif j == 1 and i <= 4:
  452. assert gl.startswith('vec')
  453. elif i == 1:
  454. assert gl.startswith('float[%s]('% j*i)
  455. assert glTransposed.startswith('float[%s]('% j*i)
  456. elif j == 1:
  457. assert gl.startswith('float[%s]('% i*j)
  458. assert glTransposed.startswith('float[%s]('% i*j)
  459. else:
  460. assert gl.startswith('float[%s](' % (i*j))
  461. assert glTransposed.startswith('float[%s](' % (i*j))
  462. glNested = glsl_code(A,mat_nested=True)
  463. glNestedTransposed = glsl_code(A,mat_transpose=True,mat_nested=True)
  464. assert glNested.startswith('float[%s][%s]' % (i,j))
  465. assert glNestedTransposed.startswith('float[%s][%s]' % (j,i))
  466. generatedAssertions+=' glNested = \'\'\''+glNested+'\'\'\'\n'
  467. generatedAssertions+=' glNestedTransposed = \'\'\''+glNestedTransposed+'\'\'\'\n\n'
  468. generatedAssertions+=' assert glsl_code(mat,mat_nested=True) == glNested\n'
  469. generatedAssertions+=' assert glsl_code(mat,mat_nested=True,mat_transpose=True) == glNestedTransposed\n\n'
  470. generateAssertions = False # set this to true to write bake these generated tests to a file
  471. if generateAssertions:
  472. gen = open('test_glsl_generated_matrices.py','w')
  473. gen.write(generatedAssertions)
  474. gen.close()
  475. # these assertions were generated from the previous function
  476. # glsl has complicated rules and this makes it easier to look over all the cases
  477. def test_misc_mats():
  478. mat = Matrix([[0]])
  479. gl = '''0'''
  480. glTransposed = '''0'''
  481. assert glsl_code(mat) == gl
  482. assert glsl_code(mat,mat_transpose=True) == glTransposed
  483. mat = Matrix([[0, 1]])
  484. gl = '''vec2(0, 1)'''
  485. glTransposed = '''vec2(0, 1)'''
  486. assert glsl_code(mat) == gl
  487. assert glsl_code(mat,mat_transpose=True) == glTransposed
  488. mat = Matrix([[0, 1, 2]])
  489. gl = '''vec3(0, 1, 2)'''
  490. glTransposed = '''vec3(0, 1, 2)'''
  491. assert glsl_code(mat) == gl
  492. assert glsl_code(mat,mat_transpose=True) == glTransposed
  493. mat = Matrix([[0, 1, 2, 3]])
  494. gl = '''vec4(0, 1, 2, 3)'''
  495. glTransposed = '''vec4(0, 1, 2, 3)'''
  496. assert glsl_code(mat) == gl
  497. assert glsl_code(mat,mat_transpose=True) == glTransposed
  498. mat = Matrix([[0, 1, 2, 3, 4]])
  499. gl = '''float[5](0, 1, 2, 3, 4)'''
  500. glTransposed = '''float[5](0, 1, 2, 3, 4)'''
  501. assert glsl_code(mat) == gl
  502. assert glsl_code(mat,mat_transpose=True) == glTransposed
  503. mat = Matrix([
  504. [0],
  505. [1]])
  506. gl = '''vec2(0, 1)'''
  507. glTransposed = '''vec2(0, 1)'''
  508. assert glsl_code(mat) == gl
  509. assert glsl_code(mat,mat_transpose=True) == glTransposed
  510. mat = Matrix([
  511. [0, 1],
  512. [2, 3]])
  513. gl = '''mat2(0, 1, 2, 3)'''
  514. glTransposed = '''mat2(0, 2, 1, 3)'''
  515. assert glsl_code(mat) == gl
  516. assert glsl_code(mat,mat_transpose=True) == glTransposed
  517. mat = Matrix([
  518. [0, 1, 2],
  519. [3, 4, 5]])
  520. gl = '''mat3x2(0, 1, 2, 3, 4, 5)'''
  521. glTransposed = '''mat2x3(0, 3, 1, 4, 2, 5)'''
  522. assert glsl_code(mat) == gl
  523. assert glsl_code(mat,mat_transpose=True) == glTransposed
  524. mat = Matrix([
  525. [0, 1, 2, 3],
  526. [4, 5, 6, 7]])
  527. gl = '''mat4x2(0, 1, 2, 3, 4, 5, 6, 7)'''
  528. glTransposed = '''mat2x4(0, 4, 1, 5, 2, 6, 3, 7)'''
  529. assert glsl_code(mat) == gl
  530. assert glsl_code(mat,mat_transpose=True) == glTransposed
  531. mat = Matrix([
  532. [0, 1, 2, 3, 4],
  533. [5, 6, 7, 8, 9]])
  534. gl = '''float[10](
  535. 0, 1, 2, 3, 4,
  536. 5, 6, 7, 8, 9
  537. ) /* a 2x5 matrix */'''
  538. glTransposed = '''float[10](
  539. 0, 5,
  540. 1, 6,
  541. 2, 7,
  542. 3, 8,
  543. 4, 9
  544. ) /* a 5x2 matrix */'''
  545. assert glsl_code(mat) == gl
  546. assert glsl_code(mat,mat_transpose=True) == glTransposed
  547. glNested = '''float[2][5](
  548. float[](0, 1, 2, 3, 4),
  549. float[](5, 6, 7, 8, 9)
  550. )'''
  551. glNestedTransposed = '''float[5][2](
  552. float[](0, 5),
  553. float[](1, 6),
  554. float[](2, 7),
  555. float[](3, 8),
  556. float[](4, 9)
  557. )'''
  558. assert glsl_code(mat,mat_nested=True) == glNested
  559. assert glsl_code(mat,mat_nested=True,mat_transpose=True) == glNestedTransposed
  560. mat = Matrix([
  561. [0],
  562. [1],
  563. [2]])
  564. gl = '''vec3(0, 1, 2)'''
  565. glTransposed = '''vec3(0, 1, 2)'''
  566. assert glsl_code(mat) == gl
  567. assert glsl_code(mat,mat_transpose=True) == glTransposed
  568. mat = Matrix([
  569. [0, 1],
  570. [2, 3],
  571. [4, 5]])
  572. gl = '''mat2x3(0, 1, 2, 3, 4, 5)'''
  573. glTransposed = '''mat3x2(0, 2, 4, 1, 3, 5)'''
  574. assert glsl_code(mat) == gl
  575. assert glsl_code(mat,mat_transpose=True) == glTransposed
  576. mat = Matrix([
  577. [0, 1, 2],
  578. [3, 4, 5],
  579. [6, 7, 8]])
  580. gl = '''mat3(0, 1, 2, 3, 4, 5, 6, 7, 8)'''
  581. glTransposed = '''mat3(0, 3, 6, 1, 4, 7, 2, 5, 8)'''
  582. assert glsl_code(mat) == gl
  583. assert glsl_code(mat,mat_transpose=True) == glTransposed
  584. mat = Matrix([
  585. [0, 1, 2, 3],
  586. [4, 5, 6, 7],
  587. [8, 9, 10, 11]])
  588. gl = '''mat4x3(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)'''
  589. glTransposed = '''mat3x4(0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11)'''
  590. assert glsl_code(mat) == gl
  591. assert glsl_code(mat,mat_transpose=True) == glTransposed
  592. mat = Matrix([
  593. [ 0, 1, 2, 3, 4],
  594. [ 5, 6, 7, 8, 9],
  595. [10, 11, 12, 13, 14]])
  596. gl = '''float[15](
  597. 0, 1, 2, 3, 4,
  598. 5, 6, 7, 8, 9,
  599. 10, 11, 12, 13, 14
  600. ) /* a 3x5 matrix */'''
  601. glTransposed = '''float[15](
  602. 0, 5, 10,
  603. 1, 6, 11,
  604. 2, 7, 12,
  605. 3, 8, 13,
  606. 4, 9, 14
  607. ) /* a 5x3 matrix */'''
  608. assert glsl_code(mat) == gl
  609. assert glsl_code(mat,mat_transpose=True) == glTransposed
  610. glNested = '''float[3][5](
  611. float[]( 0, 1, 2, 3, 4),
  612. float[]( 5, 6, 7, 8, 9),
  613. float[](10, 11, 12, 13, 14)
  614. )'''
  615. glNestedTransposed = '''float[5][3](
  616. float[](0, 5, 10),
  617. float[](1, 6, 11),
  618. float[](2, 7, 12),
  619. float[](3, 8, 13),
  620. float[](4, 9, 14)
  621. )'''
  622. assert glsl_code(mat,mat_nested=True) == glNested
  623. assert glsl_code(mat,mat_nested=True,mat_transpose=True) == glNestedTransposed
  624. mat = Matrix([
  625. [0],
  626. [1],
  627. [2],
  628. [3]])
  629. gl = '''vec4(0, 1, 2, 3)'''
  630. glTransposed = '''vec4(0, 1, 2, 3)'''
  631. assert glsl_code(mat) == gl
  632. assert glsl_code(mat,mat_transpose=True) == glTransposed
  633. mat = Matrix([
  634. [0, 1],
  635. [2, 3],
  636. [4, 5],
  637. [6, 7]])
  638. gl = '''mat2x4(0, 1, 2, 3, 4, 5, 6, 7)'''
  639. glTransposed = '''mat4x2(0, 2, 4, 6, 1, 3, 5, 7)'''
  640. assert glsl_code(mat) == gl
  641. assert glsl_code(mat,mat_transpose=True) == glTransposed
  642. mat = Matrix([
  643. [0, 1, 2],
  644. [3, 4, 5],
  645. [6, 7, 8],
  646. [9, 10, 11]])
  647. gl = '''mat3x4(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)'''
  648. glTransposed = '''mat4x3(0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11)'''
  649. assert glsl_code(mat) == gl
  650. assert glsl_code(mat,mat_transpose=True) == glTransposed
  651. mat = Matrix([
  652. [ 0, 1, 2, 3],
  653. [ 4, 5, 6, 7],
  654. [ 8, 9, 10, 11],
  655. [12, 13, 14, 15]])
  656. gl = '''mat4( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)'''
  657. glTransposed = '''mat4(0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15)'''
  658. assert glsl_code(mat) == gl
  659. assert glsl_code(mat,mat_transpose=True) == glTransposed
  660. mat = Matrix([
  661. [ 0, 1, 2, 3, 4],
  662. [ 5, 6, 7, 8, 9],
  663. [10, 11, 12, 13, 14],
  664. [15, 16, 17, 18, 19]])
  665. gl = '''float[20](
  666. 0, 1, 2, 3, 4,
  667. 5, 6, 7, 8, 9,
  668. 10, 11, 12, 13, 14,
  669. 15, 16, 17, 18, 19
  670. ) /* a 4x5 matrix */'''
  671. glTransposed = '''float[20](
  672. 0, 5, 10, 15,
  673. 1, 6, 11, 16,
  674. 2, 7, 12, 17,
  675. 3, 8, 13, 18,
  676. 4, 9, 14, 19
  677. ) /* a 5x4 matrix */'''
  678. assert glsl_code(mat) == gl
  679. assert glsl_code(mat,mat_transpose=True) == glTransposed
  680. glNested = '''float[4][5](
  681. float[]( 0, 1, 2, 3, 4),
  682. float[]( 5, 6, 7, 8, 9),
  683. float[](10, 11, 12, 13, 14),
  684. float[](15, 16, 17, 18, 19)
  685. )'''
  686. glNestedTransposed = '''float[5][4](
  687. float[](0, 5, 10, 15),
  688. float[](1, 6, 11, 16),
  689. float[](2, 7, 12, 17),
  690. float[](3, 8, 13, 18),
  691. float[](4, 9, 14, 19)
  692. )'''
  693. assert glsl_code(mat,mat_nested=True) == glNested
  694. assert glsl_code(mat,mat_nested=True,mat_transpose=True) == glNestedTransposed
  695. mat = Matrix([
  696. [0],
  697. [1],
  698. [2],
  699. [3],
  700. [4]])
  701. gl = '''float[5](0, 1, 2, 3, 4)'''
  702. glTransposed = '''float[5](0, 1, 2, 3, 4)'''
  703. assert glsl_code(mat) == gl
  704. assert glsl_code(mat,mat_transpose=True) == glTransposed
  705. mat = Matrix([
  706. [0, 1],
  707. [2, 3],
  708. [4, 5],
  709. [6, 7],
  710. [8, 9]])
  711. gl = '''float[10](
  712. 0, 1,
  713. 2, 3,
  714. 4, 5,
  715. 6, 7,
  716. 8, 9
  717. ) /* a 5x2 matrix */'''
  718. glTransposed = '''float[10](
  719. 0, 2, 4, 6, 8,
  720. 1, 3, 5, 7, 9
  721. ) /* a 2x5 matrix */'''
  722. assert glsl_code(mat) == gl
  723. assert glsl_code(mat,mat_transpose=True) == glTransposed
  724. glNested = '''float[5][2](
  725. float[](0, 1),
  726. float[](2, 3),
  727. float[](4, 5),
  728. float[](6, 7),
  729. float[](8, 9)
  730. )'''
  731. glNestedTransposed = '''float[2][5](
  732. float[](0, 2, 4, 6, 8),
  733. float[](1, 3, 5, 7, 9)
  734. )'''
  735. assert glsl_code(mat,mat_nested=True) == glNested
  736. assert glsl_code(mat,mat_nested=True,mat_transpose=True) == glNestedTransposed
  737. mat = Matrix([
  738. [ 0, 1, 2],
  739. [ 3, 4, 5],
  740. [ 6, 7, 8],
  741. [ 9, 10, 11],
  742. [12, 13, 14]])
  743. gl = '''float[15](
  744. 0, 1, 2,
  745. 3, 4, 5,
  746. 6, 7, 8,
  747. 9, 10, 11,
  748. 12, 13, 14
  749. ) /* a 5x3 matrix */'''
  750. glTransposed = '''float[15](
  751. 0, 3, 6, 9, 12,
  752. 1, 4, 7, 10, 13,
  753. 2, 5, 8, 11, 14
  754. ) /* a 3x5 matrix */'''
  755. assert glsl_code(mat) == gl
  756. assert glsl_code(mat,mat_transpose=True) == glTransposed
  757. glNested = '''float[5][3](
  758. float[]( 0, 1, 2),
  759. float[]( 3, 4, 5),
  760. float[]( 6, 7, 8),
  761. float[]( 9, 10, 11),
  762. float[](12, 13, 14)
  763. )'''
  764. glNestedTransposed = '''float[3][5](
  765. float[](0, 3, 6, 9, 12),
  766. float[](1, 4, 7, 10, 13),
  767. float[](2, 5, 8, 11, 14)
  768. )'''
  769. assert glsl_code(mat,mat_nested=True) == glNested
  770. assert glsl_code(mat,mat_nested=True,mat_transpose=True) == glNestedTransposed
  771. mat = Matrix([
  772. [ 0, 1, 2, 3],
  773. [ 4, 5, 6, 7],
  774. [ 8, 9, 10, 11],
  775. [12, 13, 14, 15],
  776. [16, 17, 18, 19]])
  777. gl = '''float[20](
  778. 0, 1, 2, 3,
  779. 4, 5, 6, 7,
  780. 8, 9, 10, 11,
  781. 12, 13, 14, 15,
  782. 16, 17, 18, 19
  783. ) /* a 5x4 matrix */'''
  784. glTransposed = '''float[20](
  785. 0, 4, 8, 12, 16,
  786. 1, 5, 9, 13, 17,
  787. 2, 6, 10, 14, 18,
  788. 3, 7, 11, 15, 19
  789. ) /* a 4x5 matrix */'''
  790. assert glsl_code(mat) == gl
  791. assert glsl_code(mat,mat_transpose=True) == glTransposed
  792. glNested = '''float[5][4](
  793. float[]( 0, 1, 2, 3),
  794. float[]( 4, 5, 6, 7),
  795. float[]( 8, 9, 10, 11),
  796. float[](12, 13, 14, 15),
  797. float[](16, 17, 18, 19)
  798. )'''
  799. glNestedTransposed = '''float[4][5](
  800. float[](0, 4, 8, 12, 16),
  801. float[](1, 5, 9, 13, 17),
  802. float[](2, 6, 10, 14, 18),
  803. float[](3, 7, 11, 15, 19)
  804. )'''
  805. assert glsl_code(mat,mat_nested=True) == glNested
  806. assert glsl_code(mat,mat_nested=True,mat_transpose=True) == glNestedTransposed
  807. mat = Matrix([
  808. [ 0, 1, 2, 3, 4],
  809. [ 5, 6, 7, 8, 9],
  810. [10, 11, 12, 13, 14],
  811. [15, 16, 17, 18, 19],
  812. [20, 21, 22, 23, 24]])
  813. gl = '''float[25](
  814. 0, 1, 2, 3, 4,
  815. 5, 6, 7, 8, 9,
  816. 10, 11, 12, 13, 14,
  817. 15, 16, 17, 18, 19,
  818. 20, 21, 22, 23, 24
  819. ) /* a 5x5 matrix */'''
  820. glTransposed = '''float[25](
  821. 0, 5, 10, 15, 20,
  822. 1, 6, 11, 16, 21,
  823. 2, 7, 12, 17, 22,
  824. 3, 8, 13, 18, 23,
  825. 4, 9, 14, 19, 24
  826. ) /* a 5x5 matrix */'''
  827. assert glsl_code(mat) == gl
  828. assert glsl_code(mat,mat_transpose=True) == glTransposed
  829. glNested = '''float[5][5](
  830. float[]( 0, 1, 2, 3, 4),
  831. float[]( 5, 6, 7, 8, 9),
  832. float[](10, 11, 12, 13, 14),
  833. float[](15, 16, 17, 18, 19),
  834. float[](20, 21, 22, 23, 24)
  835. )'''
  836. glNestedTransposed = '''float[5][5](
  837. float[](0, 5, 10, 15, 20),
  838. float[](1, 6, 11, 16, 21),
  839. float[](2, 7, 12, 17, 22),
  840. float[](3, 8, 13, 18, 23),
  841. float[](4, 9, 14, 19, 24)
  842. )'''
  843. assert glsl_code(mat,mat_nested=True) == glNested
  844. assert glsl_code(mat,mat_nested=True,mat_transpose=True) == glNestedTransposed