mátrixos kötelező program

Fórumok

Szervusztok!

Egyetemi kötelező beadandó programról lenne szó. Akinek esetleg előítéletei lennének, azok ne is olvassák tovább ;~))

A feladat generikus programozás C++-ban template-ek segítségével, ami a mátrixműveleteket valósítja meg. (összeadás, skaláris szorzás, mátrix-szorzás). A műveletekkel tisztában vagyok, inkább a sablonok kreálásával vannak problémáim.

Addig már eljutottam, hogy két azonos méretű mátrixot össze tud adni, független attól, hogy ez előzőleg mátrix, vagy mátrixösszeg.
Ha csak C-ben lenne, akkor már régen kész is lennék, de itt az a cél, hogy operator overloading segítségével temporális mátrixok nélkül kell megoldani, ami egy erőteljes nehezítés, mert eddig ilyent nem csináltam.

A határidő 15-e, szóval lassan közeleg, és napok óta nem tudom megugrani a skaláris szorzást, pláne a mátrix-szorzást. Az a sejtésem, hogy az iterátorok táján kellene kutatni, de nem tudok elindulni.

A kód amivel eddig készen vagyok:

PASTEBIN

Egy hónapig lesz fenn, hiszen utána már nem fontos.

Eddig egy vektorösszeadásos példán kereszül jutottam el, de mosz kifogytam a támpontokból. ;~((

Tudom, nem teljesen elegáns mátrix esetén a Matrix(i,j) hivatkozás, szebb lenne a Matrix[i][j], de a []operátor overloading-ja helyett a kényelmesebb ()operátor overloading-ot választottam.

Előre is köszönöm a segítséget.
/mazursky

Hozzászólások

Az akkor nem baj, ha a mátrixszorzás nem hatékony?

Ilyesmi lesz a cél, valóban.
Néhány dolog tényleg nincs benne, de az értékadáson már túl vagyok.
A kivonás majdnem összeadás, tehát az kódmásolás apró módosítással, de igazad van, legyen teljes.

A negálás alatt mit értesz? Az összes elem (-1)-szeresét, vagy a mátrix transzponáltját (főátlón történő tükrözés)? Végülis annyira egyik sem veszélyes. Beleveszem.

matrix m1->(a,b); matrix m2->(b,a);
//transzponált
for (i=0,i"<"a;i++) for (j=0;j"<"b; j++) m2(j,i)=m1(i,j);

(MOD)
az idézőjelek a relációs jel előtt és után csak a defense_of_drupal_features=YES; miatt van ;~))

/mazursky

Love your job but never love your company!
Because you never know when your company stops loving you!

Érdekes úgy belefogni egy feladat megoldásába, hogy nem egészen érted. :)

Amiről itt szó van az az Expression-template

A template használata pedig nem erőltetett, csak elsőre talán nem világos mi történik.

C-ben hogy is nézne ki egy mátrix lib?
Legyen a Matrix egy struct egy mutatóval, meg a méretekkel.
Az A*B+C+D pedig kb így nézne ki:


Matrix T1=create_matrix(N,N);
Matrix T2=create_matrix(N,N);
Matrix T3=create_matrix(N,N);

mul(&T1,&A,&B);
add(&T2,&T1,&C);
add(&T3,&T2,&D);

A probléma itt a rengeteg temp változó. A memória foglalás lassú, plusz rengeteg felesleges értékadás is van.

Épp ezért ha megnézel egy komolyabb C-s mátrix libet találni fogsz ilyen fv-t:


mul_add(Matrix* ret,Matrix* a,Matrix* b,Matrix* c);

Azaz a gyakoribb eseteket kézzel optimalizálták. Viszont szinte biztos nem lesz mul_add_add fv.

Meg nem is olyan átlátható dolog ilyen fv-eket hivogatni...

Nade C++:
Matrix osztály a megfelelő opertátor-overloadinggal:


Matrix<N,M> operator* (const Matrix<N,L>&,const Matrix<L,M>&);
Matrix<N,M> operator+ (const Matrix<N,M>&,const Matrix<N,M>&);

Már írhatom ezt:


Matrix<N,N> M=A*B+C+D;

A baj csak az, hogy ez a kód ugyanúgy létrehoz 3 temp mátrixot, azaz pont olyan gyors mint az első C-s verzió. Igaz némileg kényelmesebb.

Viszont expression-template-tel nincs temp változó. Miért?
Mert az A*B eredménye nem egy mátrix, csak egy objektum két referenciával.
Ha ehhez hozzáadunk C-t, az megint csak egy új objektum két referenciával.
Stb.

Gyakorlatilag semmi számítás nem történik, amíg nem hivatkozunk a kifejezés egy elemére. Ezt persze értékadáskor megtesszük.

Az egész azért jó, mert írhatjuk azt, hogy A*B+C+D, de az eredmény olyan, mintha kézzel optimalizált mul_add_add fvb-t hívtunk volna.

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o