From 7d5560ecf2c0cf97aa0ce50742647ae30e27139e Mon Sep 17 00:00:00 2001 From: Thomas Heijligen Date: Fri, 6 Feb 2026 19:33:08 +0100 Subject: [PATCH 1/2] Add testing for MatOp.Transpose Currently there is no interface that allows yout to generate mfiles on the fly with Python. Therefore all testing data must be checked-in as blobs. To limit the file sizes of these blobs, only two small matrices and their transposes are checked in. These matrices were generated using `create_mtx.c`. This code can also generate larger matrices to test possible edge cases in the MatOp.Transpose implementation. --- tests/rootext/complex.mtx | Bin 0 -> 74232 bytes tests/rootext/complex.tmtx | Bin 0 -> 74232 bytes tests/rootext/create_mtx.c | 254 ++++++++++++++++++++++++++++++++++++ tests/rootext/simple.mtx | Bin 0 -> 74232 bytes tests/rootext/simple.tmtx | Bin 0 -> 74232 bytes tests/rootext/test_matop.py | 69 ++++++++++ 6 files changed, 323 insertions(+) create mode 100644 tests/rootext/complex.mtx create mode 100644 tests/rootext/complex.tmtx create mode 100644 tests/rootext/create_mtx.c create mode 100644 tests/rootext/simple.mtx create mode 100644 tests/rootext/simple.tmtx create mode 100644 tests/rootext/test_matop.py diff --git a/tests/rootext/complex.mtx b/tests/rootext/complex.mtx new file mode 100644 index 0000000000000000000000000000000000000000..8d63a5ee490c4ebd4236c4aac4611b8023213294 GIT binary patch literal 74232 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 literal 0 HcmV?d00001 diff --git a/tests/rootext/complex.tmtx b/tests/rootext/complex.tmtx new file mode 100644 index 0000000000000000000000000000000000000000..9f3b0c5264e1a0bdfc643b742d19232e52226226 GIT binary patch literal 74232 zcmYhk|C?ePLgVi-w}g&twf>>diI3Rt2<_YvII&|VQp{095W9iVw z?$FMj(8He%9oZXt`*WcspATKSFEsvz&>elD{a*|{w?A~^OQE|mp`~9AJ)*H}m@jDK zSHgTpI}e0;_E$p>>#~Dk9?=b73-fK=*&pVTuZJGerH8_NUgO^g^CP+jSf`d=D58umY_7xZ7h6V@B`n|eoIJ{a~pH8Sz? z$p8Boepj44(;M- zfTK~4COInQD8^AEN1YrU=4gbY+Z=UqG>4x7U7ii+j_O8!CUqA_rTiSx7(W-Zk)J!- z$1);YYqO9%A7bvZYm z(ouaHFB|n+I;pSVXV(Kqh2b6}4~1qngyuL(wAlYZXo{m^jv6|`dWNHMjw(57<0!{b z0Y~L~!h5yp&_s7=4@W~BUFIm#8}`dMs^O@aqZCJj9F1{wkE0YvbNLz671{9JG2O(^ zJ>AVwl%Jzo&Cf+`;^(e*aWsdY0bS0|sBYwEQg?Aw%Fhvv@pC~N`MIOj+eG2? z(r@cseI++t`fHuT%e!fvaJqstsc_(^LSKgYBt z8_vC?&HUWg6i0LU8Ppa0jOiwR?&)rhqWm1yYJM(i6F+ygi=#RG4Cr!xMs*`Ullm%d zcI$66%FDa;sQ!;ubMtAvs88pmNx!Xk^_Bc|J#aKL++*^g(ENtbNONeaB{a&>07p@d znmWS%07sJ?#W?EZXoRC8jw<(r_v+K3ZQY@L9OXE=#!(?h6&%%Z)XGsWM<+PSb2NpY z9-YU}kgm*zb1&;=ej@y&wTz!*TEovJZRY2`rZ}3*&!Dd0XG}Nob5D136y@irR`YXF zoA|k_E4cZLj_EUa*`(jmd-^JFcI$66%FDa;sQ!;u^YiHkj!MEk<{k=-ydyNqQKlu# zl^o?bD(5KC5%z~TihLr>H5{cl8sn&#qeXkda}DXx_U_OON2fU&=ctIIN{;F|YU8Mn zqZ~)qI4a<0ua@(3Tx+x8+$);kXbL|)I**?rUCGa7-ONvfpR|_ob4+Xaxunhf+}9LG zbNLz675t3pCVuYetGP+(Z*?v&@6kd1UtPh?XLL-T!OJH7j^5K(@w5AZqtbAXk^0am zM=_2DTEcpaqY;iOIcn<&`#FvZIjZBRm!mvKGdZf-6W&{w4o!B49^h!0qnjKRbF_$~ z29DY}%5Zd=qj8R=^3$vH`8lDhvf<@EP%uxeJ8IHy|D&c79p735g9lE1Cw4bAM98GXE zlcOq*)^U{N=m1B<9Npxoke_{8!Ouyp%Z78WYAZ)m`RUd9{G8BL{N%NTqXK^RYB@j0 zwU(bNn&4;(KRr5+pCMhz&t=`rPlT7(Xj*@#WxTvskLmwu4L5uAl0K7{X8o?-*H`nC zdf;eoxW^<%agLH4jkJXQI7bs4#W?Eh2>T-(m2ed2sGp+=j!IME`PiP&#&l?Bcj#e` zMmW07Q3*#&If`?%gQI?q&T%xs(KLSgbOAp(U7Zc*Uem1{74oxBEBHC7b^Kh_R*t6f z)2s9OIiaig$!iNo1^n#Qa(<3$Ek9Q@!O^35S*hK6S)awrX8oQg4D!MTeokr~KUcMtqpAG#>U@4q=qi5l+QQKkUS6v``g@(n&HHpnAH~Z`?bgfs zEM7M2_cX%IYc#EqdEp)-Zw$?Fl;dckC9EeoD(0w;qu!3NpXaEYqXb7o97T4A=gLx{ zH5@gk!<_049pq??qk9}hIjZKUiK8x#1~?k!Xp*Dp{A6??Kc{s~Hk>=I+c+xXXTMhR zb4u&^xvp&-P2;Ce7x0tQ)%;x3tsE8dvrjAdIjMF0T-8>N9?eUwepavOv$;v=_jL*{ zuhky?z0Tw2eLAF%;%23GKX6nY?lHzuj-xzBku70A#Zi=_297cvVSk*XN{-q%%5hZ4 zQF$snU%MwXkq+(Y4jtm?GDnfmh4nIyYB*}l%K>bsI-T{Os3CeokpUKi9R5qiOu~=>mRox|*MBx|O2>US6kr^$%Lk z&BJAZOmdXxDDvL0Uc4nV!%-ziagO>s!u|wD zRU9Qb8s?~&ql#2`zK)~TbeMa)Lr-v&=cs_Aa*k>_N^sP}(GW+MIg0o@_6&Xw=wg0` zb!|4BdsDY_RLoCS7x8mO8~C}Q?Ho<#C!-7bIjw8>8P{zb74frQEBQI4_557dHjW;{ z%PRex=Jh$;wCE4CfS1?lUj2iXbMvqs*GF?xtDk+~s3P2Bj-yCpn4=s;w}g3sqZmg` z91V1Y{Yj2u9CdOu!chrFm8tN2Jx6WnF!yzb<~X{>Q6Wba9My5u%26*zCpgM;RKU?p zehz9CKWBAaHk^A)lN`<9=YTHeXIR(rb5pl-RLoCS7x8mO8~C}Q?Ho<#C!-7bIjw8> z8P{zbP37hF+N*!m`P^*L6Z#llR_W(7ug~G8MSq|L+`LZrK5(=k++$=-Xq2NEN0nQ` zdXA$yjuIRVb$I{dp*0+(I2z+9%F&`!c&>q?_H>vt-Jz#B8t15pqe_nIIcnpmkE0w% z*ElNVXcj;Hx`dx|x;`7uozM=BX7Y1TtN1yq>-f2)Nsealb3hmKGpuX*xvASZD&{Av zi}*RC4gB2Dc8(s)OPzjRuj+HTY1JRB`>DMLvoYVFEOlSv3Gx<5FRs5XQb^P4Y zBu6v&IiQRA8P>J@+|=zH74q^1-KT%j3U1!7C-t$s)amE-sy>&SR{fz)<>vL;`@qo) z!aXKAigT3YsBTNx&vTUED9O=qN7ygssDYylN8=n-a&4;(EF_n6}-$x()*_?ECg!BLWqn&7C4qgX0D-^fvCI?RW= zLq|Be%~1(QOF4>jw1cC5j?Qs3!O={PO8GgWF@7#+V>X<7M>{#1&Cg+7#?Odu;ODmP zUKpx5+y z+-%h!X(2an(0vaay)fKkvasXsjcwM>%TZXn>aB73OA+Qt2=cc88Ajgx=#Q%272(O&oP`G{Dg)N0S_tauns~s8;iHQJb>iyt~@P z(HwpTbU8nxx{;qr-NjKUKSwmi&joGd=ZbE}ekDh3 z9OXDF9p<6#(90Y}_J+BPqZ*EyIZAOf$k7-__c)4jG?$-2UBSEpSn*DpSBv^d;jj-$vs!yMfln%NRs$x)7@ zevT$O!hRJ;Nsfj&D(0wxqq8%A(PfSz{*GP7 zQ5iqSw1%Hc+MEsN-q#dIbNLz675t3pCVuYeZjPe-9Mx)mE@~4$ceRV7Is6Rha(+g2 zBR`Y6i=*khyh$_qS6#@>hxD{QftNMrDQC~XDx$e+w92Ig@!BHJYtsM1obb_Ni zM+F>}b2N{iAzjJOW!;<&=SKKRYZ*Vsw1%Hc+RV>=O>s1rpFv&0&zNrF=brB7D9X=K zt>)*VHt};;yEu9xFAe%-y`eAUrd@xk(|LK5X7sPRked(bX?+4WYxGMG994yTjBym> zD9%xCOW3dDD9_OlN0E<({Thx^9F1`l<*13HhE#aIouf=T%%{6U$2ltEsFI_4j@mft z<0!|`HI527s^F-cpW|A~&lOE%!?{!V>Ct)o4CzXKF6(A~BK)MajGtp#!_Osc=I6eq zIGW4PpswI&OgHg!Pj_=v%*&fKtAEo)+ zJtjGdbCl$0WJ}nOb2PzGj-x`3>Nx7> z=P1L`X^zG@D&nY;qxt-t&{h28wIv(QE#PObmh*F5Yx%jN367@l)1&kF8Pb*fT-MF} zMEFT-89&FghM!B?%+GyIar7i!*6LUEroM=q?fNq<=H<}NB!wApX&~t;AkdC zRUED3D9OgVVjM-v>)S^gs$QzuPq!E@UvIT`8lq&{9MrlM^pIe(I@k=PQR+R^u^pH_2)W+m$&Ev{ktya z<|8_+PvT~+e&vCqrQsf99OXF5a};R}`zem19F1`l<*13H0gfg)igDD*QBx{>uWL`} zKst1kqsg8ymvR*2sF9;ijt+A)!qIJxN;q1|Q6)d8w4R^q+LjIHP2;Ce7x0tQ)%;x3 ztsE8dvrjAdIjMF0T-8>Nrt;IP^Z7ZUtN6)l3r7X~?A4jPyj2hCKeURQkLp={GB4}& zt9nac%uP~%t~0oKiyqL(%fdY-Im&Ysd0$vBZVkOhVzQ}*{_xS zoYH!Ju4@}d)A;Gr1^nc6H9yyMD@TR=?9&QZnQ+QdgU(*SF2{#@3 z3!TZ!TlJv+L#w#?sGij)bF)srs*z>k9&;Q;Hu@boinfM%fTI{k;~Z6T)W%Vcqe71A zIO^pnkqY1I;bD&l9qR`PR7>-o8^Z5&PGr%xB~lhf7wT+^)_74oxBXYukj?bmk7jQIex! zj*2;I;3&gUYbu=6%h8E+nDZPJa8%AwEk_BCdN>;5=rTutt!wxh*KHgX@v~nm`8lQa{9M;Ij;8U`r%&Z2 zu3y(j^rhVF&|m5-Uf!nt`cGZL&ByedK82h0`n3m+V&NWR9K|?_a}?ufgrhh|lN`l3 z>f~sIqY{qd9QAY5mI~+fagl%K>bsI-T{Os2f zUf!;U^gnbdHy_vY`cz)x`gMIoU&_r6{iV+0=55-qNsf{n#W_lHRL4=CqXb8hkB0lN z;V8w?7)Mc#nm8KZs67?l%W!l$9p-V4ia4s|sGg%Xj`}#tadeHNLXIjps^e%0Kj(Bk zKNH%K4d>6~=b%>cb5_^!b4!yP&EV&NF6L)g*Ya~yw{uj?PgWQ4b4DBZxuNYGP3I@0 z|H8`#{f6GwmvOUG|4mDHdAlCc|Inq}d|c1#Q@M%j*ERBraF02Tk{o3?igPrXemGE zHO|i?x+5FTpT$qVF5%~#uIFb$J2;xj&q1x?=d7;d=awcpn!(QjUCht0uI1;ZZs(|& zpRCU24zlB395!hL2q%5jw7DDuIu zpW>*PqXv#L9F22S$x$0eIgWOu!gu;PI+qUf1V=MDs^VxJM@fzja5T)(O^%8=TEtNU zN6Yvb(GC3E)}7gKehEK^bSXdQHO|i?x`U%x{PgP*e$MH7ekQboqnZ31)GB_?>Nug@$p@;Q9bs0CG&=LI?ZZ_yQG_pM0V~nF5M|qBt z92Ikv;i!b8I7j^)O>k7jQIex!jyhA}yu%!gq{DohqY{pmaunxi2S@!Jo#SYNqnR94 zakP%37(W-Zk)J!-nGNU9=I5|3<7Y%S@N-*ta#X_4AzjMPd5!b)i0Ll0|mdAP?UM|qAS ziLjpHD9X_QM^TQNI2zz+lA{<$og9sD)RhX~9pGp*9p*`nN;!&g)W}gMM~68Y;pjF; zB^)i~D9+Jxenxd8Ka;vE8_qA~=ZMDmxuA{w+|f>sX7h7cm+>>A8~C}cJ2@)h=a4St z=e)-Gc|><`G>e~peHt$t^;Q(F^*EHus_JrSUSx2IEr#q%~2CaT^tQ? zG|JH=N2MIaIBMjmnxBi>#Lr#r%7*jj@H3#x`5D!X{7mXDj!OACqA`9hXd^#&w3DOR z{2bP0{EX-Zes1edj!O7Bq;q(Amk#KE>vC>BrK9>ZUN-8tbW&fz%`W|wmU8n>J)%jD zBJ09^MmdTm!aTrHjH3~bDmiN7D92GDM|B+aa+K$&Cl$Us#L?w+m?J%*WgOLT)XY(e zqd|_wIJ(DCl%r~nnmAg)&zNrF=brA)hI6C*9Mx)mE@~4$ceRV7Is6Rha(+g2BR`Y6 zi=$G0j%bXZ3);xf9qr_3Ha~~;>AW=QxAm^RlAA95wa($?T{@uut;@Ojl#c4txY?-R z(nxi<#~4R3jw%yjJ=Ypq$5Ec6DvpvI4Rch?Q3FRAj>b9aO@;5B;3%ICb3spNIY+e| zB{=HgXo#cB97X&cyNsh6j+!~D;pdVz^K)NQ*>LV$eg<^~KV!OypL@ESqbNT|wVI!c z+QiRY?c!(-KLfg)pHbb&&!q0+sFa^08s+8PdQ|^MtGW5KUeu@a(xl(kyZTCQy7bpN zhnsilfF?Ogaunw%mI(Jd(i$4)Xo8~{N1Ysva8$xkoTGk@COGO#h41A!x|R-eVNYlU zM|B*va@5Pw36Am{6>wC}Q7uOaj#lz>SvT_&$%gaNTE@>Yt>NdAHuG~|Qyk6ZXHZx0 zGp3vPxu?51it=+*tNFR8P5j)|E{^8#Goa7lWs`nK@9C?!*{#3PC@=5UqxwHu&CRFv zqCTCQCjGWXUKQ>$$5E1_xL zT+|a<$x%H=Z5;J+l;h|cM}-_!a8$=pD@V2bT+swaQ?lW_9-YU}kgnwCvTo)l!cSVu z_&KIE{9Mvze(r0Eqq+PH>I#0wbQ3@KbT>y)evax~Uf!dF`oFq@o6qQ&K7*G{`W?Ne zui|F6{zjwRyjzcIlB395!@XuWiYLN6(HffMsFN2fU&=ctIIN{;F|YU5}XKY4B8s3058+pFdL9M@WYu4saz zDg5;4Jbs3BB|n#SGd~f2(ptvPF|Fa}k~Z^mUsD{-47buKUO z(Lw!RUBS&~bWESY%_jYhMplITjB%9XD3J*3k@ttDIEr%Az)^;yagHiEYU3!!Q6WeD zsqnpXdqOADp))zE;%FU5NsbP1G|bUWj*2;2#8CrB?Htwdb5&b8nwkyg_Ue3oPUtFr z^4h{t0Y7`SoS)-b%g+@}a5ROV9-YU}kgnwCvTo)l!cSVu_&KI!yu4SB>HldBH+%Gw zK9iSb{jT2ES96on-|Ad$-lKz>RDy5sq%B!(77AQjX#r?ck`NqjMZha5R&nDvs81l;mhNKi70CM}_?C(+Yl0Y8^jU zwUwi({PgO4eop8re)8JFQ2{@DwVa>hTFcKBO>i`YpB|mZ&yYTgm(BV;jqvgsP3!Np zjFqZmh>9F1^P z!qGq~e0OwD=wv#yl%p6&jU07ybeN+Nj&5^Q!qHNW;vDVZsGgte+Q!keY&f@17x0tQ z)%;x3tsE8dvrjAdIjMF0T-8>Nrt;IP^Z7ZUtN6)l3r7X~?A3C9j_W*b-ls$QC|*`- zw_es~@v>RJrx9LWqiOw}mT~i5J*G*HBJ0DwMmfqP!d%Hwj-xt`5*!V26xkV`ui+@g z(HKWjjs{cVxv@Q=_c)4jRLxNnM_n8Za5T!%BuAwj#W-r@sFR~L{EX{1j*7D3{QX+V z&nd0v=eo9WG>xA=UBFLHSMzgCw{ld-&pxf-=cLy0b5&b8n#xbF&gbWZKAW3_eqX2X z@>=cD-|IYX-ls$QC|*`-w_es~akE*!r;(a)pD~VNO<^8LSm$Vjqc}%x9OXDF;5=rTtUf5$H4sD`6vj#3=0<>#hu z=cqUv&dur~e$HqEKR2|Uqv`x)bRj>dbqzn`x{aeEe)el6Kc}>wpX=Jj(KLSgbOAp( zeGWG*`U5TC<#oDO|DfgEJgmp{(Y(~^XZ4Cco127wUn8#x_nG4;$tW@N*;2Xrw%!@8EAo4TE&Vt%r^h@Ugsz|ReB=V&@V8C}TFX! z%qfmi9F1`l<*13H0gfg)ig9#06}~gRC$y+Lw34HGj@mft<0!|`HI527s^F-OqgIZ3 zIa<%pgm!Q=GaJr5s8#%&)ph*b(j-SS_&K19`5D%={M^*-92N7E)kXZA(FT5QXgf#K z`N`-)eopIixoOoO>Qr7{uf6(5ozKk{J)w``WtDzT^ZFcaTJ#4RSsCs##!-%=i9}dW za#YMwhNE7N@*I_Ol;CKHqsXVjcWO8qPKEjAp3vg%&_x_IaMaFGhNIIQjdN7QQ6)$9 z9JO)O$5EW0M|1~Av$EmbeqF-PIbF}sgm!Q=lb?fH#m`w?$ImTIax{aV1G<=>VO`75 zP2J8>F+W*d#LpS6;O6~$QXk7poqk@g>T|hi)gS6qUS6-g`bVA5%@#eONsf{n=IACz#T+f- zsDYz)jxro=;ODmPkZ_s`EC#~S-{d!U#%S)YpUa#tNxoOoOYUH)ycg%4V zd3TtL9}dlMRLN0}qkfJiII7|($mN$-Jwf4igUDsqkfLgaWuiv zOpdBJTE|h6qXQf@@^eQ!Ihvgf=N{H&{EX-Zes1edj!O7Bq)YiZuW^1J(H$Jk;-_Di z@N-Vr^E06x9L?nCpjPp7Ru^#d0nO>-cv-Dq&};fUZno-=w2+rK=sx|ER&euvJ*i2K zBJpsqQI4Vyhk1ab7)K)<4RAEcQH-Nbjz%~t;V910C`Xff!uLzNLt`8@a@5JuVU9*P zy3J7uM@u=1bF_n_evUTsGpV~cD$Ry-k7$ga3);xf9qr_3Ha~}T89yVsfuGyDlcN%T z4(U>U&TE{XM|1~Av-s)PCH$Pz=X2AhKh|lyJfwa4XI;R}2Q;UT<7KseL9glaxY?>d z(nxK%&nQPRjw&Ax>p70({6h~tmMLBBXXpEzKdz{-HTFp@tM_n8Z za5T!%BuAwj#W-r@sFS0^95wNCSGzcxlMUw%=yHBWbt6BMx{ISyevW92p9|W^&mHaL zXf{8Gbs0Y+x`ChDx|5?4eh%qUe$HzpHy_kf`gmUI^^1C4pU+L3{#d8+@{soFpLGE@ zAJCj8If`)<=P34YxaSd$;v7wIl;fz7qdJayIm&ZX&QXG+%N#}0;rnIXp*0*ebClv} zkfSkowN!`U! zDL+Rv#?J+9<|#LF9Xzy3ulx%r@;(#P{suV2*b`h0HM z^v4=`UHBd293?rbdpNA;IZAL8`AAqF=BSvX297cujdN7VQ5#2jjtV#`?+)Lq>pP*?CXrknV=r@J|d@^e(H`MIb~ z{M^+pj^^+)pv(Cg)s6g2>Mo8-`8lF7elF-jZa$=^^$EPJ(J$$^zJQx;`V%eU<&C;u z|Du)Ld{9qmlA|O?8IIx)hkKsjD9KSVMwC}Q7uOaj(Rv6;%GBJ5q{EI#?LXW;pdVz^K)NQ9L?otP*?CXrknV= zr@J|d@^e(H`MIb~{M^+pj^^+)pv(Cg)faNpu0Pf3yu3*>`d3}Z&4=`~K7p4t`XwFL z7jUypf1;69;djh%l;bGza9EFQ4NY+rb7E;;6Dae7~Nf zHjer@%5ij!qe6}dqXbL|)Ixic}9nzKjT-MF}MEFT-89&FghM!B? z%+GyIaWt2oL0!Smm~P_dp6=!-%Fj`)=I5d=;^xD8MxV$_gML|W=nJ`N*PrTiUf!e` z{i`nI=0kc~lN{wZ%5#)_INWnFM;VSPIm&ZX&QXG+A&w%S3h&o&l;Y?nN5vd1>JHB} zaMaFGhNIIQjdN7QQ6)$99JO)O$5D=>7LE$|*{kLJ9M@WYu4sazDg5;4Jbs3BB|n#S zGd~f2(ptvPF|Fa}k~Z^mUsD{-gx`>+(>lu9_FAe%- zy`eAUrd@xkk=KXcG0#zCQaok{li2Xqcm$92Il4h@%FM+BwQ_bef}9j;8X{tMjwr+!MNrpS-qkRKU+(E$8RB z*79>j6C6$9r$^`UGo&l|xvZP{iSU!wGJcL}4L_H3F*hI4VSN%WYxOI7Q(wf*cKw+a z^YUiR>fdw`Hy_qBn&c?*_HeIJjxrC2xsszCM|B)ca8$)nlA~dciaBcFD8tchj!HOM z+8xe`bF_n_evZy@G{MnKj;c6X$5E1_0~`%=w3VYme)eevKPR=0pR3x+(NunVbv{2Q zbQM2&ZQ-bZpS@bn&vC8g=ZYpcn!-z|DsFR}+j!HO+bJWk#WGZ~O zl%rU8m>W6j!BIa)=QwKPXc|9#x*!|Q&FN}>uIW~e3i;Wm z75tpkI)1KdD@RlL>DBrCoX}PLmY*wH#mz_ctUj5Sb^2Akr7z|t zsXx~lyu3vZ=-+iQHy_bqjn#$wjBym_DEDw!uj44sQG%mLN7%37D8DmDzCaDXr({y0&pN zjh{YUz)wzB^K(tNa#YCAKCR&Aq}K6sRa-fl%1^J(=jVj3;wP^!;if}>p)+}Ts~*&U zXcadf)wB9!Ue@VX^_ISvo235y!CV*aGtNLV@UBl0~ zZsVwkpZ!|N&nd0v=eo9WG>xA=UBFLHSMzgCw{ld-&pxf-=cLy0b5)mc^D#ZAPvK>~ zeoZIzCERrAFLWj^Z`FhP53SNLPy5Xahetw4I~r{A6?? zKc{sKKjZo`Zg%RwX$dcH*F*Xrx|Exb>v?@DFLC|4KB6z>W{3V#lWz$3ndd0-o-h}; zgl0IZA-pIe&bXa+wAbTL1}x|W}t zx}Bq9ezLlVpEKIP&kbG1%_nq3|Am(g`VGCUFXLvX{+pKY@^(F>|Dj8{`M93f+#AAu zMmB^--=i&|102OT8sVt2BkZ?vl;fz7qq$*de939|jn4_B< z6?3$RqXv%JIm&Q!nxk=!c5+n0&mmo!4d-f2)Nsealb3hmKGpuX*xv4Mbrc?i2XY=w7J*@w!%eeW3j_AMevO&M0xAkS* z?9_kL$m(#P(G8(7jw)Nioa3mDqdZ4d9brGo(J)8F95ry1;b@$rl0D(QrRmUkcjyj| z`Z+qs(F8{`IjZ7l9Y;xy4sbNg(M^szIhxJSVO^FD=Z@$Ges1edj!O7Bq)YiZuW^1J z(H$Jk;-_Di@N-Vr^E06x9L?nCpjPp7R@d=!OJm%8QZMMg^3tf^)I0ieZaVefbv7^W z(8Kzlx{RAo=!nKvhx?3e2#s?TYYFoRM{$lOIErN&QU){6C9Q93Gc2Zg%Ofw3L^3>Jj}fjdAly zy`cZfOQU{M@94|9>C}JMUc5*bEpToM0pAp@_&u!hwQ3*eXbSXdQHO|i?x}2L&>8L)9myP-@ zozz!wvrB)arM$dTkLZ7CjGIsD1yCUqA_rTiSx7(W-Zk)J!-$MOX}rN7e1L*YI%8$xp&C0fE9`9NrjqhgL4I>LH} zqj8QZIcno5$58=C<$J<=wdv4AcW4hsLmXY^DB|zfWgOLT)XY(eqd|_wIJ(DCile#w z4C;z(ICo4p@pDgia}?$0s8;iHQJeU=t6dz;;b%aX^E0X&`I*#R9F_8OL}UD1&_;gl zXf-#V){FXdUYhjVdRJe`O_%;!=kW3_9nk;Q<=lKqM>Y0PxX;{%&^$-UmM|A{l;Nm^ zqj*Qy@8@WOqbiP)91U|+$Wg_f@LpXyw6#05m!lILI#0wbQ3@KbT>y)evWE2KNq!$pS#+{(HwpTbU8nx zx{;qreHAym^*0*j<=uKz|3|C2`Ltftr}NUJ-`2bON^ZLJ*P47N+-H76Xrwtb)e;)z zXn>bqY94dIBMmnm!lIL z&qlIZAYd{UMGbp9pgeM=6fRI4b67(Vp;JLprp*J2b=5X^zG@D&nY;qk4|o zIO^jl$I&&83i#Qp<@_Ai+H5%YiY7Rk!cULR<7Y@$@^e`?^Aq7Gt!4Zi(;9v*X){0f zHO0|feg<^~KV!OypL_ahZc_SNoy*I6bWs0SS8($g9n)vxg&fs!)XPzxqnR94?FsL#ONS=ALl5+X4s&#qqhgL0 zan!(3J4YFgPIENQ(NunVbv{2QbX7K-m)91K3i#Qp<@_AiT7Ir*f}<(?^yoZ(hIA!A zmvu8g5q{EI#?LXW;pdVz^K)NoxY?tZ^qIUg>v#3OzM7kq{#NJm@*W-3|J4=Td`8DK zRv+#&#!;N3TuWH5<0#Kj6-UXAus_UEF-Hv?WjGq=sDz`Xd%}D1bm)%m(Egs#a~w@@ zG?Sw$j@EIMeey(VOqetq4s%y` z=s-{CC`XeVm2wp0sF9;ijt+A)!qIJxiul>DmHeF2`fNDwy0&pNjh{YUz)wzB^K(tN za#YCAKCR&Aq}K6sRa-fl%1^J(=jVj3;wP^y98KZnwc4Y<*LmE$PlxnTysXr2y{ymT zWwU-yBfPvu)A~D&yfNHohNB!u6D?sq$x$&!bsY6}g#A26zZshZ(O%=RK(AIt>ovF z*7I{++c=uWPoFN}C#S3Vxu#n=D&%LMR`7FD>-f2HT;b0Hjaw;*{_xSoYH!Ju4@}d)A;Gr1^nc6H9yyMD@O&qyiWJ(AGDmChxNEV znwMJrtX|P)bCb~T>l9vIt3CRAO>&gyDDvKLzr|ZZGaOZN6z8bFBkWIbRK-z}qhXGU zIjTs7=j%9XO^3O+JM=_PXr7}2j>JgaNbSb z&QUQxSzW}>8ExR_hPHDwou7;@?O;Q5{FE9QAT^f}=b~1su)f=b%>cb5_@7 z!+Ezf$VO`75P2J8>F+W*d#LpRR;OB<6 zbM#nV>h$w^RiDdEtNu`@^74A^)j#TdZno$NeGD(F^mCfm7)LRV;vB`cgnJ(0D9%wE zN4bu$U&v7%N4*^7IV$Is5U&H?8_ZoyyDWwO9YBNsi(iB{{0w67D(A zQG%l+N5dUqznG&2jxrpLb5zOE(o}dp&e4u^nESg!&-H{(a5R&nDvs81l;r3DN5dT5 z5tYx+EHw(5_xke4^;KK+wcaPxjWsgLEQPCu_#HOEnsqYOv! zEq+&yk{oq%G}00FOE`*i)X&ibM^zlfQsMbVjyls}KHMET(i3`{qY{pmaunxi2S@!J zo#SYNqnR9)@^eIE{9Mq+Y&h?Zc5*bEpToM0pAp@_&u!hwQ3*eXbSXdQHO|i?x`U%x z{PgP*e$MH7ekQboqiMW6q<#8lUBJx;G^dZ_Wwm}muj%u+*{VO%LSEjW`}9v5c~iL0 z3`aSR5?jK0q%AbXQHrCnj<6o(sEMNijwU&Zaa5fO&o}J}?MjCZbcc@igidl)%2AA? zMvgi;I?T}sN4GgD;b;y&1G=1_QQeqzp6=qPl%FFS+$6r+?N3+lgHz z#yHAxl;lA}_NqWm1yYJM(iQ#PD;SGzcx!_R;&=Vw$m@-wNsI4b4mh{pK2 zppE?8(N2zL^K)32@iU?u__?h+IV$4ijk;g|qLtiyP*3UOd8yYg>UDiSH*NZ3oyN;U z+NXckBu9CUBAdhgrnZDeIU3+7!_jz0*stWMjiVe#g&fuG4$sx5LK7VIq{BSa9eTMZ zG_p6ejH4QknmI~wG|15yNB202ax|BpL0!Smm~P63bMEPGj-vb=)oOk&Y7;+qwTq)U z{0!)Fenxd8Ka;wPqf&m3XpEl=+Q`ox?d0eQysXhL>A1dtn{E0NE#l>kx?lgImE3$# zPwC@%sn;*+b_Et2jz>G|W*kM-3d+rNZ;A9QCHd ze4;xv-xFHEQ8`Do93?pF;b@4X%N#}g9lMO9GJcL}4L_H(IUCNquPKh^@-wI__!-kp z{M^&s97Xv#s@42l)FyuJY8OXy_!-dU{EX^GekOGnN7H$ElV>1lleFKhHm zI<7C^W}E&*i+FjX?$^I)q#@jAl%p6&16#s+jH3~b1~{7Ru+LE^MvIjYtCT+}9h?rIlDPvoURzpOX(h1|63Pjxyk zZ_F&_+p3owWDmkj>sEwmOj&dAbI#0wbQ3@KbT>!Eyu4Yn`Zry~&4=}j zK9QFO{j%QB7jo0CKh^2Hyh$_qS50yh=P1e1$d+)=agHW9%5hZ4Q5{FU9OXGG=P1F^ zx>WdHlA{CZFb{W!-s}l2=4cT|4IH&|l;P+!N8=n7aa76Ce11;oDt_|Xk`3n-@UvIT z`8lq&{9MrlM^pIe(Rus~=}LYs>t=o;{G_#vpJQ6X&n0c<=f0*mdJ->d^(%T)U&PIJ z{h1c?@@CEI-*gc-AJ#MaL|z*7%X&j|93?r*aFpK??m59x}NB!wApX&~t=n0+4Q58q)I7)JKfTLlKZgN!2(ISp2_&KR{{9M)6Y&dT! zKfOAipA))@pS-qkRKU+(E$8RB*79>j6C6$9r$^`UGo&l|xvZP{iSU!w8N9qj59r@@ zF*hI4VSN%WYxOI7Q(wf*cKw+a^YUiR>fbc-=5U`Gj&dALYzga0j*2-N;i!b8I7j^) zO>k7jQIey^RQO&eM~Bm49_bFf-4j~E(Nd1$9PQw!pQCdeO>i`mqbiOT@RQTk{9Mzm z*>GMVKl`+TpOae0&sA;ZXevLwI-j2tx{9B?ws2Iy&t5I(=eXALb43#zP2s0UpUlfT z{i@#57ju);pX&@>-l7Ne@4A?qkLa*IiI=td6}_o3j&dC3If}G~drol_8dtG}%2hyRV98LCwxs;iW9Np^)bCjcMj+!{?;%I=QQH~}#D&;7~(L#Ps z>l%K>bz3%^SH#bLt>ovF*7I{++c=uWPoFN}C#S3Vxu#n=D&%LMR`7FD>-f2Cj*3OkUoq2lXFX#mz_ctUj5Sb^2Akr8$lw8~u(PMO(u>z)_5& zagHiEYU3!!Q6Wcl9QAUPNQLk9a5R(-^JR`A{*GP7Q4L4U9HlrK8P{zb74frQEBQI4_557dHjbw8)29pg$?0l-uIW~e z3i;Wmvv_%%_Uk`&2{#|pbNUos*6Y`FLSMp7hyFrm^72+asQ=K&+Hjvyj$#~Dwubc_ zM|B)ca8$)nlA~dciaBcFD8o@}Dtxb(qZ8>c=Q%3isGOr(juIU8a5TixWsV|W4Bsi^ zsD`7({0!?_es1daYrNexUqe6}dxsDPt# zj%qoo;^(ZcLPy5Xahetw4I~r{A6??Kc{sK zKjXTMqauFxYY8uJ*F*Xrx|Exb>v?@DFLC|4KB6z>W{3V#XYukj?bm;5lA}0BNsj7T z!#(FYN^lhUXjre|D8f|8%`bFJzs<`I{k_iWzi@L%|4U1F z`MI9b|Ix_5g?nZ=%5juPhR-Aa5t`&q#(&3#xjz+t}Ji}2j zN7WoPa+Knzm!lDmra3C&sEVTojyCW!raSnV)kE2^zl5Jtx}KlQ8t3P>wsEwSpFUm3 z&!}$aXGRZlRLsvwt>)*FHu7^zQyeYfr&k~1rAgn`JNi9t+Vu~*jF;!MUq9Ck-26hv z^xM4b(BJE<#yHAxl;J@#6mnMB%@96iqY1cpK zGG3n3e*Iii9OXHRB*J~u$HN6Yx>*A4uP z=?;Eo^$BGG2)OU1Fzt7EK{iBxh^1PnbFEqx@FZGH( z#7mRDt#>rXQRIbi*P=vdCK+1EQI4Z>juIRVaTI9}->>B;&Cvu$>2&!0AV(8jVV>tG z%25qR%^Y=bG{Dg~M{^vNaunmJiK7~Ru4*$sceNuM_AlpWKsWL;t~>de)59E<@^e~a z{9Mr{e(q>HN6Yx>*A4uP=?;Eo^$ftEQQFl7LH^k9oSC}K+ zp=BJ^a@4|6nxjFECODesD9TX{N6j2<;%7p4@iVVSvSDwOpEFv+&sA;a=dN~ew49#- z-N?_l?&N1q4|7z?&uNYEb48o@xufkIE#s$OAK|50-_^VN18zF>Pr96!7j!_s)Q#Ny zO2_qKUUup`I;Sy?VjNW_!hLhe(0Y#Y9946a;%J1UB90n3%5XHrQBOL&H_TDKE6fGm zq2(Oaag^Ywo1-C)COL}uKXw^MwH&o@RLjpbZQOS8VKcl8I{ zbm*USIWI5hfPSedj^Z4}65+mM$W{w6pn&T*w4u5}#8V@N-Yo9IfDIP#@!^MbGLz{Sh~5{fn;P0)D!6B|k&DnV(7B%}<1%E-mBdoR;zOvYyj#w3eGry{3=x(xPYe zp8klNwEjg`@bZ!l>erg$D9=$U5$;^XQHG;Rj^Z5kaWunGHAg9qMmQ?ss6QRv9ph-W zE6gR`q3bz{bJWIBA4j7c&2UuAQ8h=69HlsVhM$|dm!raL*mqnj__?6<{M^taM+^Ds z(N+8m>lS|Ux`(3zevWB5Kj*cMpX-|7XaPUnx{{wEeVmuw`o2bZ`LTBCU$u;vm-U=} zqqW?0>NS0gmli#%_cX^*q&eI-od}I`G{8}eqh^i{JOj(3L6 zb%mC8hsHQ+;;5aYevZaCn&qg3qxBrcIcno*D?guVD@Tj6Vc!W|%}-9B;pe9A<*1OK z<66Pb1+C}jh9)^$$WM>1;%8X5@RQd)92M|$Ow0K>uPeEEMThi0UN-Adoz%y9*{$zu zgqI&{m;P1DczIdR={FkL9_||DD3b_tB}X}q>N!eqG{jNlQ22f=M`?~GIEr#Km=52Y z=nS3bDB2z78jhMd>fmUAqj8SrI4b2R#!(YT?HoPJ&y?=tXmK{|drK?%`B=B|^QpFS zw1}S*x|*MyKEuyV-OEuSKgYF#p9@;g&kap-w2+@3UB%C^KEX{wKhOod{6xF;Z@QA3 zS9D14<7KlR)k%Gvm)-jQ|M@u^?iu4K#?e5+=Nyf36z8awqZ~(t9MyBw!%?22a*l@5 z;oZs3(8$ryGLC9FYT+o&(I7_?9L;kS<*0_EW{x^IYT)NH-Otg3*|0aGYxudS&+;>+ z`#4(6&s$o_&&RrzpHH=wqec9j(AE6p^cj9`>Ryft`8lo?{9Mp-ZeG>%dOt69`fI(e zPjHja4|D-9KhbXeo37;M6&=$1I7)F8=O~v5cdq9s&ryP-6h|W*6>-$SQHG-_jw(4C zPKS5%ouLIsL(4g;<0!#VH%CJpO>z|Rf9x`jYB_4*D9zC}ex~&RM@8ANH>*|re4-8f ze5U(3dXS%tuHomRKFiOP?&D}NKW}LzKOgH>em>P!ju!EALRa&X( zjpp@9ZuaPhTENTGdQAVW<=nig=kW{w6p zn&T+O(ZzIlXR0%F@zKyqj<#~t%Fzjqava^{sF0%yj_Nr|a@51oc7A5`AVj936_{nM&Kc8p=KcDG-jvnMEqiguNs84Z|)Q@x_ zFF(~D{fDmN<~1GG2YA_{ztOxt$;}@9PzyMUag^g|CK2wO;;4wD3`ad2&oPIjZMql%tu>@P6^p&}xnvIZAQV%h3o&(;O9XRK-yPNBcR-aI}M;Sv|y22|uTF zJwKN<&d+Ua<7g>AeY%dHQQgkZj2`5un4gnc&Cexm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* + * This program generates matrices to test the HDTV MatOp Transpose function. + * + * First build src/hdtv/rootext/mfile-root/mfile and copy the libmfile.so and + * mfile.h into this directory. To compile this file, run + * + * cc -o create_mtx create_mtx.c -Wl,-rpath,'$ORIGIN' -I. -L. -lmfile + * + * To create a matrix and it's transpose, run + * + * ./create_mtx + * + * E.g. `./create_mtx simple 600 800` creates a 'simple.mtx' with 600 lines and + * 800 columns, and a transposed 'simple.tmtx' with 800 lines and 600 columns. + * + * The `simple` mode produces a matrix with it's 1st column set to 600 and a + * transposed matrix with it's 1st line set to 600. + * + * 0------- 0----- + * |6 0 0 0 |6 6 6 + * |6 0 0 0 => |0 0 0 + * |6 0 0 0 |0 0 0 + * |0 0 0 + * + * The `complex` mode produces a matrix where every value is unique. Since the + * default format is MAT_LC (line compressed), the resulting matrices are quite + * large. + * + * 0------- 0----- + * |0 1 2 3 |0 4 8 + * |4 5 6 7 => |1 5 9 + * |8 9 A B |2 6 A + * |3 7 B + * + */ + +#include +#include +#include +#include +#include + +#include "mfile.h" + +static MFILE *mcreate(const char *name, unsigned lines, unsigned columns) { + MFILE *mtx = mopen(name, "w"); + if (!mtx) { + return NULL; + } + + minfo info; + if (mgetinfo(mtx, &info)) { + mclose(mtx); + return NULL; + } + + info.levels = 1; + info.lines = lines; + info.columns = columns; + + if (msetinfo(mtx, &info)) { + mclose(mtx); + return NULL; + } + + return mtx; +} + +static int simple(unsigned lines, unsigned columns) { + const char *MTX_NAME = "simple.mtx"; + const char *TMTX_NAME = "simple.tmtx"; + const double VALUE = 600; + MFILE *mtx; + double *buffer; + + mtx = mcreate(MTX_NAME, lines, columns); + if (!mtx) { + printf("Failed to create '%s'\n", MTX_NAME); + return -1; + } + + buffer = calloc(columns, sizeof(*buffer)); + if (!buffer) { + mclose(mtx); + printf("Failed to create buffer of size %u\n", columns); + return -1; + } + buffer[0] = VALUE; + + for (unsigned l = 0; l < lines; l++) { + if (mputdbl(mtx, buffer, 0, (int32_t)l, 0, (int32_t)columns) != (int32_t)columns) { + free(buffer); + mclose(mtx); + printf("Failed to write '%s' line %u\n", MTX_NAME, l); + return -1; + } + } + free(buffer); + mclose(mtx); + + mtx = mcreate(TMTX_NAME, columns, lines); + if (!mtx) { + printf("Failed to create '%s'\n", TMTX_NAME); + return -1; + } + + buffer = calloc(lines, sizeof(*buffer)); + if (!buffer) { + mclose(mtx); + printf("Failed to create buffer of size %u\n", columns); + return -1; + } + for (unsigned i = 0; i < lines; i++) { + buffer[i] = VALUE; + } + + if (mputdbl(mtx, buffer, 0, 0, 0, (int32_t)lines) != (int32_t)lines) { + free(buffer); + mclose(mtx); + printf("Failed to write '%s' line 0\n", TMTX_NAME); + return -1; + } + + for (unsigned i = 0; i < lines; i++) { + buffer[i] = 0; + } + + for (unsigned c = 1; c < columns; c++) { + if (mputdbl(mtx, buffer, 0, (int32_t)c, 0, (int32_t)lines) != (int32_t)lines) { + free(buffer); + mclose(mtx); + printf("Failed to write '%s' line %u\n", TMTX_NAME, c); + return -1; + } + } + free(buffer); + mclose(mtx); + + return 0; +} + +static int complex(unsigned lines, unsigned columns) { + const char *MTX_NAME = "complex.mtx"; + const char *TMTX_NAME = "complex.tmtx"; + MFILE *mtx; + double *buffer; + + mtx = mcreate(MTX_NAME, lines, columns); + if (!mtx) { + printf("Failed to create '%s'\n", MTX_NAME); + return -1; + } + + buffer = calloc(columns, sizeof(*buffer)); + if (!buffer) { + mclose(mtx); + printf("Failed to create buffer of size %u\n", columns); + return -1; + } + + for (unsigned l = 0; l < lines; l++) { + for (unsigned c = 0; c < columns; c++) { + buffer[c] = (l * lines) + c; + } + if (mputdbl(mtx, buffer, 0, (int32_t)l, 0, (int32_t)columns) != (int32_t)columns) { + free(buffer); + mclose(mtx); + printf("Failed to write '%s' line %u\n", MTX_NAME, l); + return -1; + } + } + + free(buffer); + mclose(mtx); + + mtx = mcreate(TMTX_NAME, columns, lines); + if (!mtx) { + printf("Failed to create '%s'\n", TMTX_NAME); + return -1; + } + + buffer = calloc(lines, sizeof(*buffer)); + if (!buffer) { + mclose(mtx); + printf("Failed to create buffer of size %u\n", lines); + return -1; + } + + for (unsigned c = 0; c < columns; c++) { + for (unsigned l = 0; l < lines; l++) { + buffer[l] = (l * lines) + c; + } + if (mputdbl(mtx, buffer, 0, (int32_t)c, 0, (int32_t)lines) != (int32_t)lines) { + free(buffer); + mclose(mtx); + printf("Failed to write '%s' line %u\n", MTX_NAME, c); + return -1; + } + } + + free(buffer); + mclose(mtx); + + return 0; +} + +static void print_help(const char *argv0) { + printf("Usage %s \n\n" + " e.g. '%s simple 600 800` creates a 'simple.mtx' with 600 lines and 800" + " columns, and a transposed 'simple.tmtx' with 800 lines and 600 columns", + argv0, argv0); +} + +int main(int argc, char *argv[]) { + if (argc != 4) { + print_help(argv[0]); + return -1; + } + + errno = 0; + const unsigned lines = (unsigned)strtoul(argv[2], NULL, 10); + if (errno == ERANGE) { + printf("Failed to parse \n\n"); + print_help(argv[0]); + return -1; + } + const unsigned columns = (unsigned)strtoul(argv[3], NULL, 10); + if (errno == ERANGE) { + printf("Failed to parse \n\n"); + print_help(argv[0]); + return -1; + } + + if (!strcmp(argv[1], "simple")) { + return simple(lines, columns); + } + + if (!strcmp(argv[1], "complex")) { + return complex(lines, columns); + } + + print_help(argv[0]); + return -1; +} diff --git a/tests/rootext/simple.mtx b/tests/rootext/simple.mtx new file mode 100644 index 0000000000000000000000000000000000000000..b7a6f22eb3f6dcf347c497717465f48121533d3f GIT binary patch literal 74232 zcmeIxp%KDR6hzVJR6zxqA&4+hC>%v#P~cJll~EcnLjm}EzWI93z8!|odp%Fz&m%w} zBw+WUvPC8E6R>-yK%ggJ_r1;~CSdn&fIv^c?t7g}Ou+8l0D+!>-S;||n1J280RlY% zyYF=_F#)@G0|a^kcHiq?%e=^o`Bu=I+vJ$-Maw-JpsG#buKXhyLSTwdIEOe z>s(?2cJBrV^aSj_*SW+5?A{F!=n2?;uXBkB*u5Jd&=auxUgr`MuzNQ^peJDWz0M^j zVE1l-Ku^H#d!0*6!0z1ufu4Zf_d1uDfZe+R0zCn{?{zLQ0lRkt1bPB?-|Jjr0(S2P z2=oN(zSp_L1nk}o5a+XK%ggJ_r1;~CSdn&fIv^c w?t7g}Ou+8l0D+!>-S;||n1J280Rkz3@p9eHk8Ry8hiN}A)BSc_=kb4nH#_-rpa1{> literal 0 HcmV?d00001 diff --git a/tests/rootext/simple.tmtx b/tests/rootext/simple.tmtx new file mode 100644 index 0000000000000000000000000000000000000000..b32045c0a520c610649c7941497a05ecde83d6ca GIT binary patch literal 74232 zcmeIup%H*E5ClMUs-Oa901+lC3P%wb6gVnKWt0Y?0`Pm{PW_8*nkQGub!^F%fkVla z;kUzkqzDioK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF l5FkK+009C72oNAZ;EzC9)^k42)b>N{;@Iuml!oyA!wp5-bD#hK literal 0 HcmV?d00001 diff --git a/tests/rootext/test_matop.py b/tests/rootext/test_matop.py new file mode 100644 index 00000000..1e6d00f6 --- /dev/null +++ b/tests/rootext/test_matop.py @@ -0,0 +1,69 @@ +# HDTV - A ROOT-based spectrum analysis software +# Copyright (C) 2006-2019 The HDTV development team (see file AUTHORS) +# +# This file is part of HDTV. +# +# HDTV is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# HDTV is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with HDTV; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +""" +Test whether the rootext Matop Transpose operation performs as intended. + +At time of writing, there is no interface to generate mfiles with Python. +The test files were generated using create_mtx.c. +Note that the checked-in test files are deliberately small and may not +cover all edge cases of the transpose implementation. Generate larger +files to trigger these cases. + +""" +import hashlib +import os +import tempfile + +import pytest +import ROOT + + +@pytest.fixture +def load_rootext(lib="mfile-root"): + import hdtv.rootext.dlmgr + hdtv.rootext.dlmgr.LoadLibrary(lib) + +@pytest.mark.parametrize( + "mtx, tmtx",[ + ("simple.mtx", "simple.tmtx"), + ("simple.tmtx", "simple.mtx"), + ("complex.mtx", "complex.tmtx"), + ("complex.tmtx", "complex.mtx"), + ] +) +def test_matop_transpose(mtx : str, tmtx : str): + mtx = os.path.join(os.path.dirname(__file__), mtx) + tmtx = os.path.join(os.path.dirname(__file__), tmtx) + + tmtx_hash = hashlib.md5() + with open(tmtx, "rb") as _tmtx: + for block in iter(lambda: _tmtx.read(65536), b''): + tmtx_hash.update(block) + + calc_hash = hashlib.md5() + with tempfile.NamedTemporaryFile(mode= "r+b", delete=True) as _tmtx: + result = ROOT.MatOp.Transpose(mtx, _tmtx.name) + assert result == 0, \ + f"MatOp.Transpose failed with error code {result}: {ROOT.MatOp.GetErrorString(result)}" + for block in iter(lambda: _tmtx.read(65536), b''): + calc_hash.update(block) + + assert calc_hash.digest() == tmtx_hash.digest(), \ + f"Hash mismatch: expected {tmtx_hash.hexdigest()}, got {calc_hash.hexdigest()}" From d2d125003d66bd4ca3882e5e48461d23ccb598e7 Mon Sep 17 00:00:00 2001 From: Thomas Heijligen Date: Wed, 14 Jan 2026 12:30:38 +0100 Subject: [PATCH 2/2] Reimplement rootext MatOp in pure C++ MatOp.cc implements projection and transposing of mfile based matrices with the help of functions derived from the matop package. Reimplement those two functions directly in C++ to reduce code size and complexity. Furthermore, this helps to prepare the rootext code to be loaded via the ROOT CLING interpreter. --- src/hdtv/rootext/mfile-root/CMakeLists.txt | 21 +- src/hdtv/rootext/mfile-root/MFileRoot.cc | 43 -- src/hdtv/rootext/mfile-root/MFileRoot.hh | 43 -- src/hdtv/rootext/mfile-root/MatOp.cc | 305 +++++++++-- src/hdtv/rootext/mfile-root/matop/matop.h | 54 -- .../rootext/mfile-root/matop/matop_adjust.c | 112 ---- .../rootext/mfile-root/matop/matop_adjust.h | 53 -- .../rootext/mfile-root/matop/matop_conv.c | 501 ------------------ .../rootext/mfile-root/matop/matop_conv.h | 52 -- .../rootext/mfile-root/matop/matop_project.c | 318 ----------- .../rootext/mfile-root/matop/matop_project.h | 50 -- 11 files changed, 255 insertions(+), 1297 deletions(-) delete mode 100644 src/hdtv/rootext/mfile-root/MFileRoot.cc delete mode 100644 src/hdtv/rootext/mfile-root/MFileRoot.hh delete mode 100644 src/hdtv/rootext/mfile-root/matop/matop.h delete mode 100644 src/hdtv/rootext/mfile-root/matop/matop_adjust.c delete mode 100644 src/hdtv/rootext/mfile-root/matop/matop_adjust.h delete mode 100644 src/hdtv/rootext/mfile-root/matop/matop_conv.c delete mode 100644 src/hdtv/rootext/mfile-root/matop/matop_conv.h delete mode 100644 src/hdtv/rootext/mfile-root/matop/matop_project.c delete mode 100644 src/hdtv/rootext/mfile-root/matop/matop_project.h diff --git a/src/hdtv/rootext/mfile-root/CMakeLists.txt b/src/hdtv/rootext/mfile-root/CMakeLists.txt index 5a4c7423..cf24f06b 100644 --- a/src/hdtv/rootext/mfile-root/CMakeLists.txt +++ b/src/hdtv/rootext/mfile-root/CMakeLists.txt @@ -7,11 +7,7 @@ project(mfile-root LANGUAGES C CXX) set(SOURCES MatOp.cc MFileHist.cc - MFileRoot.cc VMatrix.cc - matop/matop_adjust.c - matop/matop_conv.c - matop/matop_project.c mfile/src/callindir.c mfile/src/converters.c mfile/src/disk_access.c @@ -39,15 +35,7 @@ set(SOURCES mfile/src/txt_getput.c mfile/src/txt_minfo.c) -set(HEADERS - MatOp.hh - MFileHist.hh - MFileRoot.hh - VMatrix.hh - matop/matop.h - matop/matop_adjust.h - matop/matop_conv.h - matop/matop_project.h) +set(HEADERS MatOp.hh MFileHist.hh VMatrix.hh) find_package(ROOT REQUIRED COMPONENTS Core Hist) message(STATUS "ROOT Version ${ROOT_VERSION} found in ${ROOT_root_CMD}") @@ -78,11 +66,8 @@ set_target_properties( "${CMAKE_CURRENT_BINARY_DIR}/lib${PROJECT_NAME}.rootmap;${CMAKE_CURRENT_BINARY_DIR}/lib${PROJECT_NAME}_rdict.pcm" ) target_include_directories( - ${PROJECT_NAME} - PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/matop - ${CMAKE_CURRENT_SOURCE_DIR}/mfile/include - ${CMAKE_CURRENT_SOURCE_DIR}/mfile/src) + ${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/mfile/include + ${CMAKE_CURRENT_SOURCE_DIR}/mfile/src) target_link_libraries(${PROJECT_NAME} ROOT::Core ROOT::Hist) # For mfile diff --git a/src/hdtv/rootext/mfile-root/MFileRoot.cc b/src/hdtv/rootext/mfile-root/MFileRoot.cc deleted file mode 100644 index 9fc38d00..00000000 --- a/src/hdtv/rootext/mfile-root/MFileRoot.cc +++ /dev/null @@ -1,43 +0,0 @@ -/* - * HDTV - A ROOT-based spectrum analysis software - * Copyright (C) 2006-2010 The HDTV development team (see file AUTHORS) - * - * This file is part of HDTV. - * - * HDTV is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * HDTV is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with HDTV; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - * - */ - -#include "MFileRoot.hh" -#include - -MFile::MFile(const char *fname, const char *mode) : fZombie(false), fFile(nullptr) { - if (fname) { - fFile = mopen(const_cast(fname), const_cast(mode)); - if (fFile == nullptr) { - fZombie = true; - } - } -} - -MFile::~MFile() { - if (IsZombie() || IsNull()) { - return; - } - - if (mclose(fFile) != 0) { - std::cerr << "WARNING: mclose() failed" << std::endl; - } -} diff --git a/src/hdtv/rootext/mfile-root/MFileRoot.hh b/src/hdtv/rootext/mfile-root/MFileRoot.hh deleted file mode 100644 index e059fa51..00000000 --- a/src/hdtv/rootext/mfile-root/MFileRoot.hh +++ /dev/null @@ -1,43 +0,0 @@ -/* - * HDTV - A ROOT-based spectrum analysis software - * Copyright (C) 2006-2010 The HDTV development team (see file AUTHORS) - * - * This file is part of HDTV. - * - * HDTV is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * HDTV is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with HDTV; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - * - */ - -#ifndef __MFileRoot_h__ -#define __MFileRoot_h__ - -#include - -class MFile { -public: - explicit MFile(const char *fname = nullptr, const char *mode = "r"); - ~MFile(); - - bool IsZombie() { return fZombie; } - bool IsNull() { return fFile == nullptr; } - MFILE *File() { return fFile; } - explicit operator MFILE *() { return fFile; } - -private: - bool fZombie; - MFILE *fFile; -}; - -#endif diff --git a/src/hdtv/rootext/mfile-root/MatOp.cc b/src/hdtv/rootext/mfile-root/MatOp.cc index c234ae51..30c2a9af 100644 --- a/src/hdtv/rootext/mfile-root/MatOp.cc +++ b/src/hdtv/rootext/mfile-root/MatOp.cc @@ -1,6 +1,6 @@ /* * HDTV - A ROOT-based spectrum analysis software - * Copyright (C) 2006-2010 The HDTV development team (see file AUTHORS) + * Copyright (C) 2006-2026 The HDTV development team (see file AUTHORS) * * This file is part of HDTV. * @@ -22,12 +22,11 @@ #include "MatOp.hh" -#include +#include +#include +#include -#include "MFileRoot.hh" -#include "matop/matop_adjust.h" -#include "matop/matop_conv.h" -#include "matop/matop_project.h" +#include const int MatOp::ERR_SUCCESS = 0; const int MatOp::ERR_UNKNOWN = 1; @@ -56,85 +55,285 @@ const char *MatOp::ErrDesc[] = { "Transposition failed" // ERR_TRANS_FAIL }; -int MatOp::Project(const char *src_fname, const char *prx_fname, const char *pry_fname) { - if (prx_fname && !(*prx_fname)) { - prx_fname = nullptr; +const char *MatOp::GetErrorString(int error_nr) { + if (error_nr < 0 || error_nr > MAX_ERR) { + error_nr = ERR_UNKNOWN; } - if (pry_fname && !(*pry_fname)) { - pry_fname = nullptr; + + return ErrDesc[error_nr]; +} + +namespace { +template +int ProjectGeneric(MFILE *dstx, MFILE *dsty, unsigned int level, MFILE *src) { + minfo info; + mgetinfo(src, &info); + if (level >= info.levels) { + return MatOp::ERR_PROJ_FAIL; } - MFile in_matrix(src_fname, "r"); - if (in_matrix.IsZombie()) { - return ERR_SRC_OPEN; + auto lbuf = std::make_unique(info.columns); + auto prx = dstx ? std::make_unique(info.columns) : nullptr; + auto pry = dsty ? std::make_unique(info.lines) : nullptr; + + for (uint32_t l = 0; l < info.lines; l++) { + if (static_cast(mget_(src, lbuf.get(), level, l, 0, info.columns)) != info.columns) { + return MatOp::ERR_PROJ_FAIL; + } + + if (prx) { + for (uint32_t c = 0; prx && c < info.columns; c++) { + prx[c] += lbuf[c]; + } + } + + if (pry) { + T sum = 0; + for (uint32_t c = 0; c < info.columns; c++) { + sum += lbuf[c]; + } + pry[l] += sum; + } } - // std::cout << "Info: input format is " << mgetfmt(in_matrix, NULL) << - // std::endl; + int err = MatOp::ERR_SUCCESS; + if (prx && static_cast(mput_(dstx, prx.get(), level, 0, 0, info.columns)) != info.columns) { + err = MatOp::ERR_PROJ_FAIL; + } + + if (pry && static_cast(mput_(dsty, pry.get(), level, 0, 0, info.lines)) != info.lines) { + err = MatOp::ERR_PROJ_FAIL; + } + return err; +} +} // namespace + +int MatOp::Project(const char *src_fname, const char *prx_fname, const char *pry_fname) { + int err = ERR_SUCCESS; + + MFILE *src_matrix = nullptr; + MFILE *prx_matrix = nullptr; + MFILE *pry_matrix = nullptr; - MFile out_prx(prx_fname, "w"); - if (out_prx.IsZombie()) { - return ERR_PRX_OPEN; + src_matrix = mopen(src_fname, "r"); + if (src_matrix == nullptr) { + err = ERR_SRC_OPEN; + goto exit; } - if (!out_prx.IsNull()) { - if (matop_adjustfmts_prx(static_cast(out_prx), static_cast(in_matrix)) != 0) { - return ERR_PRX_FMT; + minfo src_info; + mgetinfo(src_matrix, &src_info); + if (src_info.levels > 2) { + err = ERR_PROJ_FAIL; + goto exit; + } + + if (prx_fname != nullptr && *prx_fname != '\0') { + prx_matrix = mopen(prx_fname, "w"); + if (prx_matrix == nullptr) { + err = ERR_PRX_OPEN; + goto exit; + } + + minfo prx_info; + mgetinfo(prx_matrix, &prx_info); + + prx_info.levels = src_info.levels; + prx_info.lines = 1; + prx_info.columns = src_info.columns; + + if (msetinfo(prx_matrix, &prx_info)) { + err = ERR_PRX_FMT; + goto exit; } } - MFile out_pry(pry_fname, "w"); - if (out_pry.IsZombie()) { - return ERR_PRY_OPEN; + if (pry_fname != nullptr && *pry_fname != '\0') { + pry_matrix = mopen(pry_fname, "w"); + if (pry_matrix == nullptr) { + err = ERR_PRY_OPEN; + goto exit; + } + + minfo pry_info; + mgetinfo(pry_matrix, &pry_info); + + pry_info.levels = src_info.levels; + pry_info.lines = 1; + pry_info.columns = src_info.lines; + + if (msetinfo(pry_matrix, &pry_info)) { + err = ERR_PRY_FMT; + goto exit; + } } - if (!out_pry.IsNull()) { - if (matop_adjustfmts_pry(static_cast(out_pry), static_cast(in_matrix)) != 0) { - return ERR_PRY_FMT; + // Projection of level 0 and 1. src_info.levels is <= 2 + for (uint32_t l = 0; l < src_info.levels; l++) { + switch (src_matrix->filetype) { + case MAT_LE2: + case MAT_LE4: + case MAT_HE2: + case MAT_HE4: + + case MAT_LE2T: + case MAT_LE4T: + case MAT_HE2T: + case MAT_HE4T: + + case MAT_SHM: + case MAT_LC: + case MAT_MATE: + case MAT_TRIXI: + err = ProjectGeneric(prx_matrix, pry_matrix, l, src_matrix); + break; + case MAT_LF4: + case MAT_HF4: + case MAT_VAXF: + err = ProjectGeneric(prx_matrix, pry_matrix, l, src_matrix); + break; + case MAT_LF8: + case MAT_HF8: + case MAT_VAXG: + case MAT_TXT: + err = ProjectGeneric(prx_matrix, pry_matrix, l, src_matrix); + break; + default: + err = ERR_PROJ_FAIL; + goto exit; + } + + if (err != ERR_SUCCESS) { + break; } } - if (matop_proj(static_cast(out_prx), static_cast(out_pry), static_cast(in_matrix)) != 0) { - return ERR_PROJ_FAIL; +exit: + // using mclose on a nullptr has no effect + mclose(src_matrix); + mclose(prx_matrix); + mclose(pry_matrix); + + return err; +} + +namespace { +// This function is implemented in this way because the default matrix type of libmfile is MAT_LC, +// which is a line-compressed format. This format does not allow writes to random positions. +// Only (sequential) writes of full lines are possible. Otherwise the matrix file will contain garbage. +template +int TransposeGeneric(MFILE *dst_matrix, MFILE *src_matrix) { + minfo info; + mgetinfo(src_matrix, &info); + + constexpr int32_t MAX_BUFFER_ELEMENTS = 16 * 1024 * 1024 / sizeof(T); + + int32_t buffered_dst_columns = std::max(1, MAX_BUFFER_ELEMENTS / static_cast(info.lines)); + auto src_buffer = std::make_unique(buffered_dst_columns); + auto dst_buffer = std::make_unique(buffered_dst_columns * info.lines); + + for (int32_t level = 0; level < static_cast(info.levels); level++) { + for (int32_t column = 0; column < static_cast(info.columns); column += buffered_dst_columns) { + + int32_t cc = std::min(buffered_dst_columns, static_cast(info.columns) - column); + + for (int32_t line = 0; line < static_cast(info.lines); line++) { + if (mget_(src_matrix, &src_buffer[0], level, line, column, cc) != cc) { + return MatOp::ERR_TRANS_FAIL; + } + for (auto c = 0; c < buffered_dst_columns; c++) { + dst_buffer[(c * info.lines) + line] = src_buffer[c]; + } + } + + for (auto c = 0; c < cc; c++) { + if (mput_(dst_matrix, &dst_buffer[c * info.lines], level, column + c, 0, info.lines) != + static_cast(info.lines)) { + return MatOp::ERR_TRANS_FAIL; + } + } + } } - return ERR_SUCCESS; + return MatOp::ERR_SUCCESS; } +} // namespace int MatOp::Transpose(const char *src_fname, const char *dst_fname) { - MFile in_matrix(src_fname, "r"); - if (in_matrix.IsZombie()) { - return ERR_SRC_OPEN; - } + int err = ERR_SUCCESS; - // std::cout << "Info: input format is " << mgetfmt(in_matrix, NULL) << - // std::endl; + // All MFILE* are initialized to have defined behavior when exiting early + MFILE *src_matrix = nullptr; + MFILE *dst_matrix = nullptr; - MFile out_matrix(dst_fname, "w"); - if (out_matrix.IsZombie()) { - return ERR_TRANS_OPEN; + src_matrix = mopen(src_fname, "r"); + if (src_matrix == nullptr) { + err = ERR_SRC_OPEN; + goto exit; } - if (matop_adjustfmts_trans(static_cast(out_matrix), static_cast(in_matrix)) != 0) { - return ERR_TRANS_FMT; + dst_matrix = mopen(dst_fname, "w"); + if (dst_matrix == nullptr) { + err = ERR_TRANS_OPEN; + goto exit; } - // std::cout << "Info: output format is " << mgetfmt(out_matrix, NULL) << - // std::endl; + minfo src_info; + minfo dst_info; + + mgetinfo(src_matrix, &src_info); + mgetinfo(dst_matrix, &dst_info); - if (matop_conv(static_cast(out_matrix), static_cast(in_matrix), MAT_TRANS) != 0) { - return ERR_TRANS_FAIL; + dst_info.levels = src_info.levels; + dst_info.lines = src_info.columns; + dst_info.columns = src_info.lines; + if (msetinfo(dst_matrix, &dst_info)) { + err = ERR_TRANS_FMT; + goto exit; } - matop_conv_free_cache(); + switch (src_matrix->filetype) { + case MAT_LE2: + case MAT_LE4: + case MAT_HE2: + case MAT_HE4: - return ERR_SUCCESS; -} + case MAT_LE2T: + case MAT_LE4T: + case MAT_HE2T: + case MAT_HE4T: -const char *MatOp::GetErrorString(int error_nr) { - if (error_nr < 0 || error_nr > MAX_ERR) { - error_nr = ERR_UNKNOWN; + case MAT_SHM: + case MAT_LC: + case MAT_MATE: + case MAT_TRIXI: + err = TransposeGeneric(dst_matrix, src_matrix); + break; + case MAT_LF4: + case MAT_HF4: + case MAT_VAXF: + err = TransposeGeneric(dst_matrix, src_matrix); + break; + case MAT_LF8: + case MAT_HF8: + case MAT_VAXG: + case MAT_TXT: + err = TransposeGeneric(dst_matrix, src_matrix); + break; + default: + err = ERR_TRANS_FAIL; } - return ErrDesc[error_nr]; +exit: + // using mclose on a nullpointer has no effect + mclose(src_matrix); + mclose(dst_matrix); + + return err; } diff --git a/src/hdtv/rootext/mfile-root/matop/matop.h b/src/hdtv/rootext/mfile-root/matop/matop.h deleted file mode 100644 index 9bc77edf..00000000 --- a/src/hdtv/rootext/mfile-root/matop/matop.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1992-2008, Stefan Esser - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This code was derived from the matop package, the license of which is - * reproduced above. - * - * Adapted for HDTV by Norbert Braun, 2010. - */ - -#ifndef __MATOP_H__ -#define __MATOP_H__ - -/* 16 MByte Buffer for Symm. und Transpose */ -#define MBUFSIZE 16 * 1024 * 1024 - -enum MAT_OP { - MAT_OP_NONE, - MAT_CONV, - MAT_SYMM, - MAT_TRANS, - MAT_PROJ, - MAT_SUM, - MAT_SUB, - MAT_POLY, - MAT_MINMAX, - MAT_FILE, - MAT_STAT -}; - -#endif diff --git a/src/hdtv/rootext/mfile-root/matop/matop_adjust.c b/src/hdtv/rootext/mfile-root/matop/matop_adjust.c deleted file mode 100644 index 91f55136..00000000 --- a/src/hdtv/rootext/mfile-root/matop/matop_adjust.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 1992-2008, Stefan Esser - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This code was derived from the matop package, the license of which is - * reproduced above. - * - * Adapted for HDTV by Norbert Braun, 2010. - */ - -#include "matop_adjust.h" - -int matop_adjustfmts(MFILE *matw, MFILE *matr) { - - minfo infor; - minfo infow; - - mgetinfo(matr, &infor); - mgetinfo(matw, &infow); - - if (infow.levels && infow.lines && infow.columns) { - infor.levels = infow.levels; - infor.lines = infow.lines; - infor.columns = infow.columns; - return msetinfo(matr, &infor); - } else { - infow.levels = infor.levels; - infow.lines = infor.lines; - infow.columns = infor.columns; - return msetinfo(matw, &infow); - } -} - -int matop_adjustfmts_trans(MFILE *matw, MFILE *matr) { - - minfo infor; - minfo infow; - - mgetinfo(matr, &infor); - mgetinfo(matw, &infow); - - if (infow.levels && infow.lines && infow.columns) { - infor.levels = infow.levels; - infor.lines = infow.columns; - infor.columns = infow.lines; - return msetinfo(matr, &infor); - } else { - infow.levels = infor.levels; - infow.lines = infor.columns; - infow.columns = infor.lines; - return msetinfo(matw, &infow); - } -} - -int matop_adjustfmts_prx(MFILE *matw, MFILE *matr) { - - minfo infor; - minfo infow; - - mgetinfo(matr, &infor); - mgetinfo(matw, &infow); - - if (infor.levels > 2) - return -1; // FIXME - - infow.levels = infor.levels; - infow.lines = 1; - infow.columns = infor.columns; - - return msetinfo(matw, &infow); -} - -int matop_adjustfmts_pry(MFILE *matw, MFILE *matr) { - - minfo infor; - minfo infow; - - mgetinfo(matr, &infor); - mgetinfo(matw, &infow); - - if (infor.levels > 2) - return -1; // FIXME - - infow.levels = infor.levels; - infow.lines = 1; - infow.columns = infor.lines; - - return msetinfo(matw, &infow); -} diff --git a/src/hdtv/rootext/mfile-root/matop/matop_adjust.h b/src/hdtv/rootext/mfile-root/matop/matop_adjust.h deleted file mode 100644 index 46b00bd0..00000000 --- a/src/hdtv/rootext/mfile-root/matop/matop_adjust.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 1992-2008, Stefan Esser - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This code was derived from the matop package, the license of which is - * reproduced above. - * - * Adapted for HDTV by Norbert Braun, 2010. - */ - -#ifndef __MATOP_ADJUST_H__ -#define __MATOP_ADJUST_H__ - -/* Allow the use in C++ code. */ -#ifdef __cplusplus -extern "C" { -#endif - -#include - -extern int matop_adjustfmts(MFILE *matw, MFILE *matr); -extern int matop_adjustfmts_prx(MFILE *matw, MFILE *matr); -extern int matop_adjustfmts_pry(MFILE *matw, MFILE *matr); -extern int matop_adjustfmts_trans(MFILE *matw, MFILE *matr); - -#ifdef __cplusplus -} -#endif /* C++ */ - -#endif diff --git a/src/hdtv/rootext/mfile-root/matop/matop_conv.c b/src/hdtv/rootext/mfile-root/matop/matop_conv.c deleted file mode 100644 index cd399747..00000000 --- a/src/hdtv/rootext/mfile-root/matop/matop_conv.c +++ /dev/null @@ -1,501 +0,0 @@ -/* - * Copyright (c) 1992-2008, Stefan Esser - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This code was derived from the matop package, the license of which is - * reproduced above. - * - * Adapted for HDTV by Norbert Braun, 2010. - */ - -/* - * matop_conv: Copyright by - * Stefan Esser - * Institute for Nuclear Physics - * University of Cologne, Germany - * - */ - -/* Description: - * - * program to convert between different matrix file formats without - * changing the contents of the file (except rounding, depending on - * the precision and range of the data representations) - */ - -#include "matop_conv.h" -#include -#include - -static int mcopyint(MFILE *dst, MFILE *src, int op); -static int mcopyflt(MFILE *dst, MFILE *src, int op); -static int mcopydbl(MFILE *dst, MFILE *src, int op); - -struct cache_int_t { - int *buf; - int size, lines, columns; - int level, col, cachecols; - MFILE *mat; -}; -struct cache_int_t cache_int = {NULL}; - -static int mgetint_col(MFILE *mat, int *buf, int level, int line, int col, int num) { - if (mat != cache_int.mat) { - int size; - int columns = mat->columns; - int lines = mat->lines; - int cachecols = (int)(MBUFSIZE / (lines * sizeof(*cache_int.buf))); - if (cachecols < 1) - cachecols = 1; - if (cachecols > columns) - cachecols = columns; - - size = lines * cachecols; - - if (size > cache_int.size) { - cache_int.size = 0; - if (cache_int.buf) - free(cache_int.buf); - cache_int.buf = (int *)malloc(size * sizeof(*cache_int.buf)); - if (cache_int.buf) - cache_int.size = size; - } - cache_int.mat = mat; - cache_int.cachecols = cachecols; - cache_int.level = -1; - cache_int.lines = lines; - cache_int.columns = columns; - } - - if (level != cache_int.level || col < cache_int.col || col >= cache_int.col + cache_int.cachecols) { - - int n; - int l; - int *p = cache_int.buf; - - cache_int.level = -1; - n = cache_int.cachecols; - if (col + n > cache_int.columns) - n = cache_int.columns - col; - - for (l = 0; l < cache_int.lines; l++) { - int nread; - nread = mgetint(mat, p, level, l, col, n); - if (nread != n) - return -1; - p += cache_int.cachecols; - } - cache_int.level = level; - cache_int.col = col; - } - { - int i; - int *p = cache_int.buf + (line * cache_int.cachecols + col - cache_int.col); - - for (i = 0; i < num; i++) { - *buf++ = *p; - p += cache_int.cachecols; - } - } - return num; -} - -/* ======================================================================== */ -struct cache_flt_t { - float *buf; - int size, lines, columns; - int level, col, cachecols; - MFILE *mat; -}; -struct cache_flt_t cache_flt = {NULL}; - -static int mgetflt_col(MFILE *mat, float *buf, int level, int line, int col, int num) { - if (mat != cache_flt.mat) { - int size; - int columns = mat->columns; - int lines = mat->lines; - int cachecols = (int)(MBUFSIZE / (lines * sizeof(*cache_flt.buf))); - if (cachecols < 1) - cachecols = 1; - if (cachecols > columns) - cachecols = columns; - - size = lines * cachecols; - - if (size > cache_flt.size) { - cache_flt.size = 0; - if (cache_flt.buf) - free(cache_flt.buf); - cache_flt.buf = (float *)malloc(size * sizeof(*cache_flt.buf)); - if (cache_flt.buf) - cache_flt.size = size; - } - cache_flt.mat = mat; - cache_flt.cachecols = cachecols; - cache_flt.level = -1; - cache_flt.lines = lines; - cache_flt.columns = columns; - } - - if (level != cache_flt.level || col < cache_flt.col || col >= cache_flt.col + cache_flt.cachecols) { - - int n; - int l; - float *p = cache_flt.buf; - - cache_flt.level = -1; - n = cache_flt.cachecols; - if (col + n > cache_flt.columns) - n = cache_flt.columns - col; - - for (l = 0; l < cache_flt.lines; l++) { - int nread; - nread = mgetflt(mat, p, level, l, col, n); - if (nread != n) - return -1; - p += cache_flt.cachecols; - } - cache_flt.level = level; - cache_flt.col = col; - } - { - int i; - float *p = cache_flt.buf + (line * cache_flt.cachecols + col - cache_flt.col); - - for (i = 0; i < num; i++) { - *buf++ = *p; - p += cache_flt.cachecols; - } - } - return num; -} - -/* ======================================================================== */ -struct cache_dbl_t { - double *buf; - int size, lines, columns; - int level, col, cachecols; - MFILE *mat; -}; -struct cache_dbl_t cache_dbl = {NULL}; - -static int mgetdbl_col(MFILE *mat, double *buf, int level, int line, int col, int num) { - if (mat != cache_dbl.mat) { - int size; - int columns = mat->columns; - int lines = mat->lines; - int cachecols = (int)(MBUFSIZE / (lines * sizeof(*cache_dbl.buf))); - if (cachecols < 1) - cachecols = 1; - if (cachecols > columns) - cachecols = columns; - - size = lines * cachecols; - - if (size > cache_dbl.size) { - cache_dbl.size = 0; - if (cache_dbl.buf) - free(cache_dbl.buf); - cache_dbl.buf = (double *)malloc(size * sizeof(*cache_dbl.buf)); - if (cache_dbl.buf) - cache_dbl.size = size; - } - cache_dbl.mat = mat; - cache_dbl.cachecols = cachecols; - cache_dbl.level = -1; - cache_dbl.lines = lines; - cache_dbl.columns = columns; - } - - if (level != cache_dbl.level || col < cache_dbl.col || col >= cache_dbl.col + cache_dbl.cachecols) { - - int n; - int l; - double *p = cache_dbl.buf; - - cache_dbl.level = -1; - n = cache_dbl.cachecols; - if (col + n > cache_dbl.columns) - n = cache_dbl.columns - col; - - for (l = 0; l < cache_dbl.lines; l++) { - int nread; - nread = mgetdbl(mat, p, level, l, col, n); - if (nread != n) - return -1; - p += cache_dbl.cachecols; - } - cache_dbl.level = level; - cache_dbl.col = col; - } - { - int i; - double *p = cache_dbl.buf + (line * cache_dbl.cachecols + col - cache_dbl.col); - - for (i = 0; i < num; i++) { - *buf++ = *p; - p += cache_dbl.cachecols; - } - } - return num; -} - -/* ======================================================================== */ - -int matop_conv(MFILE *dst, MFILE *src, int op) { - - switch (src->filetype) { - case MAT_LE2: - case MAT_LE4: - case MAT_HE2: - case MAT_HE4: - - case MAT_LE2T: - case MAT_LE4T: - case MAT_HE2T: - case MAT_HE4T: - - case MAT_SHM: - case MAT_LC: - case MAT_MATE: - case MAT_TRIXI: - return mcopyint(dst, src, op); - - case MAT_LF4: - case MAT_HF4: - case MAT_VAXF: - return mcopyflt(dst, src, op); - - case MAT_LF8: - case MAT_HF8: - case MAT_VAXG: - case MAT_TXT: - return mcopydbl(dst, src, op); - } - return -1; -} - -void matop_conv_free_cache(void) { - if (cache_int.buf) - free(cache_int.buf); - memset(&cache_int, 0, sizeof(cache_int)); - - if (cache_flt.buf) - free(cache_flt.buf); - memset(&cache_flt, 0, sizeof(cache_flt)); - - if (cache_dbl.buf) - free(cache_dbl.buf); - memset(&cache_dbl, 0, sizeof(cache_dbl)); -} - -static int mcopyint(MFILE *dst, MFILE *src, int op) { - - int sc = src->columns; - int dc = dst->columns; - - int *sbuf = NULL; - int *dbuf = NULL; - - int err = 0; - - dbuf = (int *)malloc(dc * sizeof(*dbuf)); - - if (op == MAT_SYMM) { - sbuf = (int *)malloc(sc * sizeof(*sbuf)); - } else { - sbuf = dbuf; - } - - if (sbuf && dbuf) { - int v, l; - int vmax = src->levels; - int lmax = src->lines; - - /* For asymmetric matrices, columns and rows are exchanged */ - if (op == MAT_TRANS) { - lmax = src->columns; - } - - for (v = 0; !err && v < vmax; v++) { - for (l = 0; !err && l < lmax; l++) { - - if (op == MAT_CONV || op == MAT_SYMM) { - if (mgetint(src, sbuf, v, l, 0, sc) != sc) - err = -1; - } - - if (op == MAT_TRANS || op == MAT_SYMM) { - if (mgetint_col(src, dbuf, v, 0, l, dc) != dc) - err = -1; - } - - if (op == MAT_SYMM) { - int c; - for (c = 0; c < sc; c++) - dbuf[c] += sbuf[c]; - } - - if (!err && mputint(dst, dbuf, v, l, 0, dc) != dc) - err = -1; - } - } - } else { - err = -1; - } - - if (mflush(dst) != 0) - err = -1; - - if (dbuf) - free(dbuf); - if (op == MAT_SYMM && sbuf) - free(sbuf); - - return err; -} - -static int mcopyflt(MFILE *dst, MFILE *src, int op) { - - int sc = src->columns; - int dc = dst->columns; - - float *sbuf = NULL; - float *dbuf = NULL; - - int err = 0; - - dbuf = (float *)malloc(dc * sizeof(*dbuf)); - - if (op == MAT_SYMM) { - sbuf = (float *)malloc(sc * sizeof(*sbuf)); - } else { - sbuf = dbuf; - } - - if (sbuf && dbuf) { - int v, l; - int vmax = src->levels; - int lmax = src->lines; - - for (v = 0; !err && v < vmax; v++) { - for (l = 0; !err && l < lmax; l++) { - - if (op == MAT_CONV || op == MAT_SYMM) { - if (mgetflt(src, sbuf, v, l, 0, sc) != sc) - err = -1; - } - - if (op == MAT_TRANS || op == MAT_SYMM) { - if (mgetflt_col(src, dbuf, v, 0, l, dc) != dc) - err = -1; - } - - if (op == MAT_SYMM) { - int c; - for (c = 0; c < sc; c++) - dbuf[c] += sbuf[c]; - } - - if (mputflt(dst, dbuf, v, l, 0, dc) != dc) - err = -1; - } - } - } else { - err = -1; - } - - if (mflush(dst) != 0) - err = -1; - - if (dbuf) - free(dbuf); - if (op == MAT_SYMM && sbuf) - free(sbuf); - - return err; -} - -static int mcopydbl(MFILE *dst, MFILE *src, int op) { - - int sc = src->columns; - int dc = dst->columns; - - double *sbuf = NULL; - double *dbuf = NULL; - - int err = 0; - - dbuf = (double *)malloc(dc * sizeof(*dbuf)); - - if (op == MAT_SYMM) { - sbuf = (double *)malloc(sc * sizeof(*sbuf)); - } else { - sbuf = dbuf; - } - - if (sbuf && dbuf) { - int v, l; - int vmax = src->levels; - int lmax = src->lines; - - for (v = 0; !err && v < vmax; v++) { - for (l = 0; !err && l < lmax; l++) { - - if (op == MAT_CONV || op == MAT_SYMM) { - if (mgetdbl(src, sbuf, v, l, 0, sc) != sc) - err = -1; - } - - if (op == MAT_TRANS || op == MAT_SYMM) { - if (mgetdbl_col(src, dbuf, v, 0, l, dc) != dc) - err = -1; - } - - if (op == MAT_SYMM) { - int c; - for (c = 0; c < sc; c++) - dbuf[c] += sbuf[c]; - } - - if (mputdbl(dst, dbuf, v, l, 0, dc) != dc) - err = -1; - } - } - } else { - err = -1; - } - - if (mflush(dst) != 0) - err = -1; - - if (dbuf) - free(dbuf); - if (op == MAT_SYMM && sbuf) - free(sbuf); - - return err; -} diff --git a/src/hdtv/rootext/mfile-root/matop/matop_conv.h b/src/hdtv/rootext/mfile-root/matop/matop_conv.h deleted file mode 100644 index 55cbcf45..00000000 --- a/src/hdtv/rootext/mfile-root/matop/matop_conv.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 1992-2008, Stefan Esser - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This code was derived from the matop package, the license of which is - * reproduced above. - * - * Adapted for HDTV by Norbert Braun, 2010. - */ - -#ifndef __MATOP_CONV_H__ -#define __MATOP_CONV_H__ - -/* Allow the use in C++ code. */ -#ifdef __cplusplus -extern "C" { -#endif - -#include "matop.h" -#include - -extern int matop_conv(MFILE *dst, MFILE *src, int op); -extern void matop_conv_free_cache(void); - -#ifdef __cplusplus -} -#endif /* C++ */ - -#endif diff --git a/src/hdtv/rootext/mfile-root/matop/matop_project.c b/src/hdtv/rootext/mfile-root/matop/matop_project.c deleted file mode 100644 index 8066df89..00000000 --- a/src/hdtv/rootext/mfile-root/matop/matop_project.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright (c) 1992-2008, Stefan Esser - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This code was derived from the matop package, the license of which is - * reproduced above. - * - * Adapted for HDTV by Norbert Braun, 2010. - */ - -#include "matop_project.h" -#include -#include - -static int mprojint(MFILE *dstx, MFILE *dsty, unsigned int level, MFILE *src); -static int mprojflt(MFILE *dstx, MFILE *dsty, unsigned int level, MFILE *src); -static int mprojdbl(MFILE *dstx, MFILE *dsty, unsigned int level, MFILE *src); -static int matop_proj_single(MFILE *dstx, MFILE *dsty, unsigned int level, MFILE *src); - -int matop_proj(MFILE *dstx, MFILE *dsty, MFILE *src) { - int err; - minfo info; - - mgetinfo(src, &info); - - if (info.levels > 2) - return -1; - - err = matop_proj_single(dstx, dsty, 0, src); - if (err != 0) - return err; - - if (info.levels > 1) - err = matop_proj_single(dstx, dsty, 1, src); - - return err; -} - -int matop_proj_single(MFILE *dstx, MFILE *dsty, unsigned int level, MFILE *src) { - - switch (src->filetype) { - case MAT_LE2: - case MAT_LE4: - case MAT_HE2: - case MAT_HE4: - - case MAT_LE2T: - case MAT_LE4T: - case MAT_HE2T: - case MAT_HE4T: - - case MAT_SHM: - case MAT_LC: - case MAT_MATE: - case MAT_TRIXI: - return mprojint(dstx, dsty, level, src); - - case MAT_LF4: - case MAT_HF4: - case MAT_VAXF: - return mprojflt(dstx, dsty, level, src); - - case MAT_LF8: - case MAT_HF8: - case MAT_VAXG: - case MAT_TXT: - return mprojdbl(dstx, dsty, level, src); - } - return -1; -} - -static int mprojint(MFILE *dstx, MFILE *dsty, unsigned int level, MFILE *src) { - - int err = 0; - int exitstatus = -1; - minfo info; - int *lbuf; - int *prx = NULL; - int *pry = NULL; - - int columns; - int lines; - - mgetinfo(src, &info); - columns = info.columns; - lines = info.lines; - if (level >= info.levels) - goto errexit; - - lbuf = (int *)malloc(columns * sizeof(int)); - if (dstx) - prx = (int *)malloc(columns * sizeof(int)); - if (dsty) - pry = (int *)malloc(lines * sizeof(int)); - - if (!lbuf || (dstx && !prx) || (dsty && !pry)) - goto errexit; - - { - int l, c; - - if (prx) - memset(prx, 0, columns * sizeof(int)); - if (pry) - memset(pry, 0, lines * sizeof(int)); - - for (l = 0; l < lines; l++) { - if (mgetint(src, lbuf, level, l, 0, columns) != columns) - goto errexit; - - if (prx) { - for (c = 0; c < columns; c++) { - prx[c] += lbuf[c]; - } - } - if (pry) { - int sum = 0; - for (c = 0; c < columns; c++) { - sum += lbuf[c]; - } - pry[l] += sum; - } - } - } - - free(lbuf); - - if (prx) { - if (mputint(dstx, prx, level, 0, 0, columns) != columns) - err = -1; - free(prx); - } - - if (pry) { - if (mputint(dsty, pry, level, 0, 0, lines) != lines) - err = -1; - free(pry); - } - - exitstatus = err; - -errexit: - - return exitstatus; -} - -static int mprojflt(MFILE *dstx, MFILE *dsty, unsigned int level, MFILE *src) { - - int err = 0; - int exitstatus = -1; - minfo info; - float *lbuf; - float *prx = NULL; - float *pry = NULL; - - int columns; - int lines; - - mgetinfo(src, &info); - columns = info.columns; - lines = info.lines; - if (level >= info.levels) - goto errexit; - - lbuf = (float *)malloc(columns * sizeof(float)); - if (dstx) - prx = (float *)malloc(columns * sizeof(float)); - if (dsty) - pry = (float *)malloc(lines * sizeof(float)); - - if (!lbuf || (dstx && !prx) || (dsty && !pry)) - goto errexit; - - { - int l, c; - - if (prx) - memset(prx, 0, columns * sizeof(float)); - if (pry) - memset(pry, 0, lines * sizeof(float)); - - for (l = 0; l < lines; l++) { - if (mgetflt(src, lbuf, level, l, 0, columns) != columns) - goto errexit; - - if (prx) { - for (c = 0; c < columns; c++) { - prx[c] += lbuf[c]; - } - } - if (pry) { - float sum = 0; - for (c = 0; c < columns; c++) { - sum += lbuf[c]; - } - pry[l] += sum; - } - } - } - - free(lbuf); - - if (prx) { - if (mputflt(dstx, prx, level, 0, 0, columns) != columns) - err = -1; - free(prx); - } - - if (pry) { - if (mputflt(dsty, pry, level, 0, 0, lines) != lines) - err = -1; - free(pry); - } - - exitstatus = err; - -errexit: - - return exitstatus; -} - -static int mprojdbl(MFILE *dstx, MFILE *dsty, unsigned int level, MFILE *src) { - - int err = 0; - int exitstatus = -1; - minfo info; - double *lbuf; - double *prx = NULL; - double *pry = NULL; - - int columns; - int lines; - - mgetinfo(src, &info); - columns = info.columns; - lines = info.lines; - if (level >= info.levels) - goto errexit; - - lbuf = (double *)malloc(columns * sizeof(double)); - if (dstx) - prx = (double *)malloc(columns * sizeof(double)); - if (dsty) - pry = (double *)malloc(lines * sizeof(double)); - - if (!lbuf || (dstx && !prx) || (dsty && !pry)) - goto errexit; - - { - int l, c; - - if (prx) - memset(prx, 0, columns * sizeof(double)); - if (pry) - memset(pry, 0, lines * sizeof(double)); - - for (l = 0; l < lines; l++) { - if (mgetdbl(src, lbuf, level, l, 0, columns) != columns) - goto errexit; - - if (prx) { - for (c = 0; c < columns; c++) { - prx[c] += lbuf[c]; - } - } - if (pry) { - double sum = 0; - for (c = 0; c < columns; c++) { - sum += lbuf[c]; - } - pry[l] += sum; - } - } - } - - free(lbuf); - - if (prx) { - if (mputdbl(dstx, prx, level, 0, 0, columns) != columns) - err = -1; - free(prx); - } - - if (pry) { - if (mputdbl(dsty, pry, level, 0, 0, lines) != lines) - err = -1; - free(pry); - } - - exitstatus = err; - -errexit: - - return exitstatus; -} diff --git a/src/hdtv/rootext/mfile-root/matop/matop_project.h b/src/hdtv/rootext/mfile-root/matop/matop_project.h deleted file mode 100644 index e5393bbc..00000000 --- a/src/hdtv/rootext/mfile-root/matop/matop_project.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 1992-2008, Stefan Esser - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This code was derived from the matop package, the license of which is - * reproduced above. - * - * Adapted for HDTV by Norbert Braun, 2010. - */ - -#ifndef __MATOP_PROJECT_H__ -#define __MATOP_PROJECT_H__ - -/* Allow the use in C++ code. */ -#ifdef __cplusplus -extern "C" { -#endif - -#include - -extern int matop_proj(MFILE *dstx, MFILE *dsty, MFILE *src); - -#ifdef __cplusplus -} -#endif /* C++ */ - -#endif