Mat_meat.hpp 196 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931
  1. // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au)
  2. // Copyright 2008-2016 National ICT Australia (NICTA)
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // ------------------------------------------------------------------------
  15. //! \addtogroup Mat
  16. //! @{
  17. template<typename eT>
  18. inline
  19. Mat<eT>::~Mat()
  20. {
  21. arma_extra_debug_sigprint_this(this);
  22. if( (mem_state == 0) && (n_elem > arma_config::mat_prealloc) )
  23. {
  24. arma_extra_debug_print("Mat::destructor: releasing memory");
  25. memory::release( access::rw(mem) );
  26. }
  27. // try to expose buggy user code that accesses deleted objects
  28. if(arma_config::debug) { access::rw(mem) = 0; }
  29. arma_type_check(( is_supported_elem_type<eT>::value == false ));
  30. }
  31. template<typename eT>
  32. inline
  33. Mat<eT>::Mat()
  34. : n_rows(0)
  35. , n_cols(0)
  36. , n_elem(0)
  37. , vec_state(0)
  38. , mem_state(0)
  39. , mem()
  40. {
  41. arma_extra_debug_sigprint_this(this);
  42. }
  43. //! construct the matrix to have user specified dimensions
  44. template<typename eT>
  45. inline
  46. Mat<eT>::Mat(const uword in_n_rows, const uword in_n_cols)
  47. : n_rows(in_n_rows)
  48. , n_cols(in_n_cols)
  49. , n_elem(in_n_rows*in_n_cols)
  50. , vec_state(0)
  51. , mem_state(0)
  52. , mem()
  53. {
  54. arma_extra_debug_sigprint_this(this);
  55. init_cold();
  56. }
  57. template<typename eT>
  58. inline
  59. Mat<eT>::Mat(const SizeMat& s)
  60. : n_rows(s.n_rows)
  61. , n_cols(s.n_cols)
  62. , n_elem(s.n_rows*s.n_cols)
  63. , vec_state(0)
  64. , mem_state(0)
  65. , mem()
  66. {
  67. arma_extra_debug_sigprint_this(this);
  68. init_cold();
  69. }
  70. //! construct the matrix to have user specified dimensions and fill with specified pattern
  71. template<typename eT>
  72. template<typename fill_type>
  73. inline
  74. Mat<eT>::Mat(const uword in_n_rows, const uword in_n_cols, const fill::fill_class<fill_type>& f)
  75. : n_rows(in_n_rows)
  76. , n_cols(in_n_cols)
  77. , n_elem(in_n_rows*in_n_cols)
  78. , vec_state(0)
  79. , mem_state(0)
  80. , mem()
  81. {
  82. arma_extra_debug_sigprint_this(this);
  83. init_cold();
  84. (*this).fill(f);
  85. }
  86. template<typename eT>
  87. template<typename fill_type>
  88. inline
  89. Mat<eT>::Mat(const SizeMat& s, const fill::fill_class<fill_type>& f)
  90. : n_rows(s.n_rows)
  91. , n_cols(s.n_cols)
  92. , n_elem(s.n_rows*s.n_cols)
  93. , vec_state(0)
  94. , mem_state(0)
  95. , mem()
  96. {
  97. arma_extra_debug_sigprint_this(this);
  98. init_cold();
  99. (*this).fill(f);
  100. }
  101. //! constructor used by Row and Col classes
  102. template<typename eT>
  103. inline
  104. Mat<eT>::Mat(const arma_vec_indicator&, const uhword in_vec_state)
  105. : n_rows( (in_vec_state == 2) ? 1 : 0 )
  106. , n_cols( (in_vec_state == 1) ? 1 : 0 )
  107. , n_elem(0)
  108. , vec_state(in_vec_state)
  109. , mem_state(0)
  110. , mem()
  111. {
  112. arma_extra_debug_sigprint_this(this);
  113. }
  114. //! constructor used by Row and Col classes
  115. template<typename eT>
  116. inline
  117. Mat<eT>::Mat(const arma_vec_indicator&, const uword in_n_rows, const uword in_n_cols, const uhword in_vec_state)
  118. : n_rows(in_n_rows)
  119. , n_cols(in_n_cols)
  120. , n_elem(in_n_rows*in_n_cols)
  121. , vec_state(in_vec_state)
  122. , mem_state(0)
  123. , mem()
  124. {
  125. arma_extra_debug_sigprint_this(this);
  126. init_cold();
  127. }
  128. template<typename eT>
  129. inline
  130. Mat<eT>::Mat(const arma_fixed_indicator&, const uword in_n_rows, const uword in_n_cols, const uhword in_vec_state, const eT* in_mem)
  131. : n_rows (in_n_rows)
  132. , n_cols (in_n_cols)
  133. , n_elem (in_n_rows*in_n_cols)
  134. , vec_state (in_vec_state)
  135. , mem_state (3)
  136. , mem (in_mem)
  137. {
  138. arma_extra_debug_sigprint_this(this);
  139. }
  140. template<typename eT>
  141. inline
  142. void
  143. Mat<eT>::init_cold()
  144. {
  145. arma_extra_debug_sigprint( arma_str::format("n_rows = %d, n_cols = %d") % n_rows % n_cols );
  146. // ensure that n_elem can hold the result of (n_rows * n_cols)
  147. #if defined(ARMA_64BIT_WORD)
  148. const char* error_message = "Mat::init(): requested size is too large";
  149. #else
  150. const char* error_message = "Mat::init(): requested size is too large; suggest to compile in C++11 mode and/or enable ARMA_64BIT_WORD";
  151. #endif
  152. arma_debug_check
  153. (
  154. (
  155. ( (n_rows > ARMA_MAX_UHWORD) || (n_cols > ARMA_MAX_UHWORD) )
  156. ? ( (double(n_rows) * double(n_cols)) > double(ARMA_MAX_UWORD) )
  157. : false
  158. ),
  159. error_message
  160. );
  161. if(n_elem <= arma_config::mat_prealloc)
  162. {
  163. if(n_elem == 0)
  164. {
  165. access::rw(mem) = NULL;
  166. }
  167. else
  168. {
  169. arma_extra_debug_print("Mat::init(): using local memory");
  170. access::rw(mem) = mem_local;
  171. }
  172. }
  173. else
  174. {
  175. arma_extra_debug_print("Mat::init(): acquiring memory");
  176. access::rw(mem) = memory::acquire<eT>(n_elem);
  177. }
  178. }
  179. template<typename eT>
  180. inline
  181. void
  182. Mat<eT>::init_warm(uword in_n_rows, uword in_n_cols)
  183. {
  184. arma_extra_debug_sigprint( arma_str::format("in_n_rows = %d, in_n_cols = %d") % in_n_rows % in_n_cols );
  185. if( (n_rows == in_n_rows) && (n_cols == in_n_cols) ) { return; }
  186. bool err_state = false;
  187. char* err_msg = 0;
  188. const uhword t_vec_state = vec_state;
  189. const uhword t_mem_state = mem_state;
  190. arma_debug_set_error( err_state, err_msg, (t_mem_state == 3), "Mat::init(): size is fixed and hence cannot be changed" );
  191. if(t_vec_state > 0)
  192. {
  193. if( (in_n_rows == 0) && (in_n_cols == 0) )
  194. {
  195. if(t_vec_state == 1) { in_n_cols = 1; }
  196. if(t_vec_state == 2) { in_n_rows = 1; }
  197. }
  198. else
  199. {
  200. if(t_vec_state == 1) { arma_debug_set_error( err_state, err_msg, (in_n_cols != 1), "Mat::init(): requested size is not compatible with column vector layout" ); }
  201. if(t_vec_state == 2) { arma_debug_set_error( err_state, err_msg, (in_n_rows != 1), "Mat::init(): requested size is not compatible with row vector layout" ); }
  202. }
  203. }
  204. // ensure that n_elem can hold the result of (n_rows * n_cols)
  205. #if defined(ARMA_64BIT_WORD)
  206. const char* error_message = "Mat::init(): requested size is too large";
  207. #else
  208. const char* error_message = "Mat::init(): requested size is too large; suggest to compile in C++11 mode and/or enable ARMA_64BIT_WORD";
  209. #endif
  210. arma_debug_set_error
  211. (
  212. err_state,
  213. err_msg,
  214. (
  215. ( (in_n_rows > ARMA_MAX_UHWORD) || (in_n_cols > ARMA_MAX_UHWORD) )
  216. ? ( (double(in_n_rows) * double(in_n_cols)) > double(ARMA_MAX_UWORD) )
  217. : false
  218. ),
  219. error_message
  220. );
  221. arma_debug_check(err_state, err_msg);
  222. const uword old_n_elem = n_elem;
  223. const uword new_n_elem = in_n_rows * in_n_cols;
  224. if(old_n_elem == new_n_elem)
  225. {
  226. arma_extra_debug_print("Mat::init(): reusing memory");
  227. access::rw(n_rows) = in_n_rows;
  228. access::rw(n_cols) = in_n_cols;
  229. }
  230. else // condition: old_n_elem != new_n_elem
  231. {
  232. arma_debug_check( (t_mem_state == 2), "Mat::init(): mismatch between size of auxiliary memory and requested size" );
  233. if(new_n_elem < old_n_elem) // reuse existing memory if possible
  234. {
  235. if( (t_mem_state == 0) && (new_n_elem <= arma_config::mat_prealloc) )
  236. {
  237. if(old_n_elem > arma_config::mat_prealloc)
  238. {
  239. arma_extra_debug_print("Mat::init(): releasing memory");
  240. memory::release( access::rw(mem) );
  241. }
  242. if(new_n_elem == 0)
  243. {
  244. access::rw(mem) = NULL;
  245. }
  246. else
  247. {
  248. arma_extra_debug_print("Mat::init(): using local memory");
  249. access::rw(mem) = mem_local;
  250. }
  251. }
  252. else
  253. {
  254. arma_extra_debug_print("Mat::init(): reusing memory");
  255. }
  256. }
  257. else // condition: new_n_elem > old_n_elem
  258. {
  259. if( (t_mem_state == 0) && (old_n_elem > arma_config::mat_prealloc) )
  260. {
  261. arma_extra_debug_print("Mat::init(): releasing memory");
  262. memory::release( access::rw(mem) );
  263. }
  264. if(new_n_elem <= arma_config::mat_prealloc)
  265. {
  266. arma_extra_debug_print("Mat::init(): using local memory");
  267. access::rw(mem) = mem_local;
  268. }
  269. else
  270. {
  271. arma_extra_debug_print("Mat::init(): acquiring memory");
  272. access::rw(mem) = memory::acquire<eT>(new_n_elem);
  273. }
  274. access::rw(mem_state) = 0;
  275. }
  276. access::rw(n_rows) = in_n_rows;
  277. access::rw(n_cols) = in_n_cols;
  278. access::rw(n_elem) = new_n_elem;
  279. }
  280. }
  281. //! create the matrix from a textual description
  282. template<typename eT>
  283. inline
  284. arma_cold
  285. Mat<eT>::Mat(const char* text)
  286. : n_rows(0)
  287. , n_cols(0)
  288. , n_elem(0)
  289. , vec_state(0)
  290. , mem_state(0)
  291. , mem()
  292. {
  293. arma_extra_debug_sigprint_this(this);
  294. init( std::string(text) );
  295. }
  296. //! create the matrix from a textual description
  297. template<typename eT>
  298. inline
  299. arma_cold
  300. Mat<eT>&
  301. Mat<eT>::operator=(const char* text)
  302. {
  303. arma_extra_debug_sigprint();
  304. init( std::string(text) );
  305. return *this;
  306. }
  307. //! create the matrix from a textual description
  308. template<typename eT>
  309. inline
  310. arma_cold
  311. Mat<eT>::Mat(const std::string& text)
  312. : n_rows(0)
  313. , n_cols(0)
  314. , n_elem(0)
  315. , vec_state(0)
  316. , mem_state(0)
  317. , mem()
  318. {
  319. arma_extra_debug_sigprint_this(this);
  320. init(text);
  321. }
  322. //! create the matrix from a textual description
  323. template<typename eT>
  324. inline
  325. arma_cold
  326. Mat<eT>&
  327. Mat<eT>::operator=(const std::string& text)
  328. {
  329. arma_extra_debug_sigprint();
  330. init(text);
  331. return *this;
  332. }
  333. //! internal function to create the matrix from a textual description
  334. template<typename eT>
  335. inline
  336. arma_cold
  337. void
  338. Mat<eT>::init(const std::string& text_orig)
  339. {
  340. arma_extra_debug_sigprint();
  341. const bool replace_commas = (is_cx<eT>::yes) ? false : ( text_orig.find(',') != std::string::npos );
  342. std::string text_mod;
  343. if(replace_commas) { text_mod = text_orig; std::replace(text_mod.begin(), text_mod.end(), ',', ' '); }
  344. const std::string& text = (replace_commas) ? text_mod : text_orig;
  345. //
  346. // work out the size
  347. uword t_n_rows = 0;
  348. uword t_n_cols = 0;
  349. bool has_semicolon = false;
  350. bool has_token = false;
  351. std::string token;
  352. std::string::size_type line_start = 0;
  353. std::string::size_type line_end = 0;
  354. std::string::size_type line_len = 0;
  355. std::stringstream line_stream;
  356. while( line_start < text.length() )
  357. {
  358. line_end = text.find(';', line_start);
  359. if(line_end == std::string::npos)
  360. {
  361. has_semicolon = false;
  362. line_end = text.length()-1;
  363. line_len = line_end - line_start + 1;
  364. }
  365. else
  366. {
  367. has_semicolon = true;
  368. line_len = line_end - line_start; // omit the ';' character
  369. }
  370. line_stream.clear();
  371. line_stream.str( text.substr(line_start,line_len) );
  372. has_token = false;
  373. uword line_n_cols = 0;
  374. while(line_stream >> token) { has_token = true; ++line_n_cols; }
  375. if(t_n_rows == 0)
  376. {
  377. t_n_cols = line_n_cols;
  378. }
  379. else
  380. {
  381. if(has_semicolon || has_token) { arma_check( (line_n_cols != t_n_cols), "Mat::init(): inconsistent number of columns in given string"); }
  382. }
  383. ++t_n_rows;
  384. line_start = line_end+1;
  385. }
  386. // if the last line was empty, ignore it
  387. if( (has_semicolon == false) && (has_token == false) && (t_n_rows >= 1) ) { --t_n_rows; }
  388. Mat<eT>& x = (*this);
  389. x.set_size(t_n_rows, t_n_cols);
  390. if(x.is_empty()) { return; }
  391. line_start = 0;
  392. line_end = 0;
  393. line_len = 0;
  394. uword urow = 0;
  395. while( line_start < text.length() )
  396. {
  397. line_end = text.find(';', line_start);
  398. if(line_end == std::string::npos)
  399. {
  400. line_end = text.length()-1;
  401. line_len = line_end - line_start + 1;
  402. }
  403. else
  404. {
  405. line_len = line_end - line_start; // omit the ';' character
  406. }
  407. line_stream.clear();
  408. line_stream.str( text.substr(line_start,line_len) );
  409. uword ucol = 0;
  410. while(line_stream >> token)
  411. {
  412. diskio::convert_token( x.at(urow,ucol), token );
  413. ++ucol;
  414. }
  415. ++urow;
  416. line_start = line_end+1;
  417. }
  418. }
  419. //! create the matrix from std::vector
  420. template<typename eT>
  421. inline
  422. Mat<eT>::Mat(const std::vector<eT>& x)
  423. : n_rows(uword(x.size()))
  424. , n_cols(1)
  425. , n_elem(uword(x.size()))
  426. , vec_state(0)
  427. , mem_state(0)
  428. , mem()
  429. {
  430. arma_extra_debug_sigprint_this(this);
  431. init_cold();
  432. if(n_elem > 0)
  433. {
  434. arrayops::copy( memptr(), &(x[0]), n_elem );
  435. }
  436. }
  437. //! create the matrix from std::vector
  438. template<typename eT>
  439. inline
  440. Mat<eT>&
  441. Mat<eT>::operator=(const std::vector<eT>& x)
  442. {
  443. arma_extra_debug_sigprint();
  444. init_warm(uword(x.size()), 1);
  445. if(x.size() > 0)
  446. {
  447. arrayops::copy( memptr(), &(x[0]), uword(x.size()) );
  448. }
  449. return *this;
  450. }
  451. #if defined(ARMA_USE_CXX11)
  452. template<typename eT>
  453. inline
  454. Mat<eT>::Mat(const std::initializer_list<eT>& list)
  455. : n_rows(0)
  456. , n_cols(0)
  457. , n_elem(0)
  458. , vec_state(0)
  459. , mem_state(0)
  460. , mem()
  461. {
  462. arma_extra_debug_sigprint_this(this);
  463. init(list);
  464. }
  465. template<typename eT>
  466. inline
  467. Mat<eT>&
  468. Mat<eT>::operator=(const std::initializer_list<eT>& list)
  469. {
  470. arma_extra_debug_sigprint();
  471. init(list);
  472. return *this;
  473. }
  474. template<typename eT>
  475. inline
  476. Mat<eT>::Mat(const std::initializer_list< std::initializer_list<eT> >& list)
  477. : n_rows(0)
  478. , n_cols(0)
  479. , n_elem(0)
  480. , vec_state(0)
  481. , mem_state(0)
  482. , mem()
  483. {
  484. arma_extra_debug_sigprint_this(this);
  485. init(list);
  486. }
  487. template<typename eT>
  488. inline
  489. Mat<eT>&
  490. Mat<eT>::operator=(const std::initializer_list< std::initializer_list<eT> >& list)
  491. {
  492. arma_extra_debug_sigprint();
  493. init(list);
  494. return *this;
  495. }
  496. template<typename eT>
  497. inline
  498. Mat<eT>::Mat(Mat<eT>&& X)
  499. : n_rows (X.n_rows)
  500. , n_cols (X.n_cols)
  501. , n_elem (X.n_elem)
  502. , vec_state(0 )
  503. , mem_state(0 )
  504. , mem ( )
  505. {
  506. arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X);
  507. if( ((X.mem_state == 0) && (X.n_elem > arma_config::mat_prealloc)) || (X.mem_state == 1) || (X.mem_state == 2) )
  508. {
  509. access::rw(mem_state) = X.mem_state;
  510. access::rw(mem) = X.mem;
  511. access::rw(X.n_rows) = 0;
  512. access::rw(X.n_cols) = 0;
  513. access::rw(X.n_elem) = 0;
  514. access::rw(X.mem_state) = 0;
  515. access::rw(X.mem) = 0;
  516. }
  517. else
  518. {
  519. init_cold();
  520. arrayops::copy( memptr(), X.mem, X.n_elem );
  521. if( (X.mem_state == 0) && (X.n_elem <= arma_config::mat_prealloc) )
  522. {
  523. access::rw(X.n_rows) = 0;
  524. access::rw(X.n_cols) = 0;
  525. access::rw(X.n_elem) = 0;
  526. access::rw(X.mem) = 0;
  527. }
  528. }
  529. }
  530. template<typename eT>
  531. inline
  532. Mat<eT>&
  533. Mat<eT>::operator=(Mat<eT>&& X)
  534. {
  535. arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X);
  536. (*this).steal_mem(X);
  537. if( (X.mem_state == 0) && (X.n_elem <= arma_config::mat_prealloc) && (this != &X) )
  538. {
  539. access::rw(X.n_rows) = 0;
  540. access::rw(X.n_cols) = 0;
  541. access::rw(X.n_elem) = 0;
  542. access::rw(X.mem) = 0;
  543. }
  544. return *this;
  545. }
  546. #endif
  547. //! Set the matrix to be equal to the specified scalar.
  548. //! NOTE: the size of the matrix will be 1x1
  549. template<typename eT>
  550. inline
  551. Mat<eT>&
  552. Mat<eT>::operator=(const eT val)
  553. {
  554. arma_extra_debug_sigprint();
  555. init_warm(1,1);
  556. access::rw(mem[0]) = val;
  557. return *this;
  558. }
  559. //! In-place addition of a scalar to all elements of the matrix
  560. template<typename eT>
  561. inline
  562. Mat<eT>&
  563. Mat<eT>::operator+=(const eT val)
  564. {
  565. arma_extra_debug_sigprint();
  566. arrayops::inplace_plus( memptr(), val, n_elem );
  567. return *this;
  568. }
  569. //! In-place subtraction of a scalar from all elements of the matrix
  570. template<typename eT>
  571. inline
  572. Mat<eT>&
  573. Mat<eT>::operator-=(const eT val)
  574. {
  575. arma_extra_debug_sigprint();
  576. arrayops::inplace_minus( memptr(), val, n_elem );
  577. return *this;
  578. }
  579. //! In-place multiplication of all elements of the matrix with a scalar
  580. template<typename eT>
  581. inline
  582. Mat<eT>&
  583. Mat<eT>::operator*=(const eT val)
  584. {
  585. arma_extra_debug_sigprint();
  586. arrayops::inplace_mul( memptr(), val, n_elem );
  587. return *this;
  588. }
  589. //! In-place division of all elements of the matrix with a scalar
  590. template<typename eT>
  591. inline
  592. Mat<eT>&
  593. Mat<eT>::operator/=(const eT val)
  594. {
  595. arma_extra_debug_sigprint();
  596. arrayops::inplace_div( memptr(), val, n_elem );
  597. return *this;
  598. }
  599. //! construct a matrix from a given matrix
  600. template<typename eT>
  601. inline
  602. Mat<eT>::Mat(const Mat<eT>& in_mat)
  603. : n_rows(in_mat.n_rows)
  604. , n_cols(in_mat.n_cols)
  605. , n_elem(in_mat.n_elem)
  606. , vec_state(0)
  607. , mem_state(0)
  608. , mem()
  609. {
  610. arma_extra_debug_sigprint(arma_str::format("this = %x in_mat = %x") % this % &in_mat);
  611. init_cold();
  612. arrayops::copy( memptr(), in_mat.mem, in_mat.n_elem );
  613. }
  614. //! construct a matrix from a given matrix
  615. template<typename eT>
  616. inline
  617. Mat<eT>&
  618. Mat<eT>::operator=(const Mat<eT>& in_mat)
  619. {
  620. arma_extra_debug_sigprint(arma_str::format("this = %x in_mat = %x") % this % &in_mat);
  621. if(this != &in_mat)
  622. {
  623. init_warm(in_mat.n_rows, in_mat.n_cols);
  624. arrayops::copy( memptr(), in_mat.mem, in_mat.n_elem );
  625. }
  626. return *this;
  627. }
  628. #if defined(ARMA_USE_CXX11)
  629. template<typename eT>
  630. inline
  631. void
  632. Mat<eT>::init(const std::initializer_list<eT>& list)
  633. {
  634. arma_extra_debug_sigprint();
  635. const uword N = uword(list.size());
  636. set_size(1, N);
  637. arrayops::copy( memptr(), list.begin(), N );
  638. }
  639. template<typename eT>
  640. inline
  641. void
  642. Mat<eT>::init(const std::initializer_list< std::initializer_list<eT> >& list)
  643. {
  644. arma_extra_debug_sigprint();
  645. uword x_n_rows = uword(list.size());
  646. uword x_n_cols = 0;
  647. bool x_n_cols_found = false;
  648. auto it = list.begin();
  649. auto it_end = list.end();
  650. for(; it != it_end; ++it)
  651. {
  652. if(x_n_cols_found == false)
  653. {
  654. x_n_cols = uword((*it).size());
  655. x_n_cols_found = true;
  656. }
  657. else
  658. {
  659. arma_check( (uword((*it).size()) != x_n_cols), "Mat::init(): inconsistent number of columns in initialiser list" );
  660. }
  661. }
  662. Mat<eT>& t = (*this);
  663. if(t.mem_state == 3)
  664. {
  665. arma_debug_check( ((x_n_rows != t.n_rows) || (x_n_cols != t.n_cols)), "Mat::init(): size mismatch between fixed size matrix and initialiser list" );
  666. }
  667. else
  668. {
  669. t.set_size(x_n_rows, x_n_cols);
  670. }
  671. uword row_num = 0;
  672. auto row_it = list.begin();
  673. auto row_it_end = list.end();
  674. for(; row_it != row_it_end; ++row_it)
  675. {
  676. uword col_num = 0;
  677. auto col_it = (*row_it).begin();
  678. auto col_it_end = (*row_it).end();
  679. for(; col_it != col_it_end; ++col_it)
  680. {
  681. t.at(row_num, col_num) = (*col_it);
  682. ++col_num;
  683. }
  684. ++row_num;
  685. }
  686. }
  687. #endif
  688. //! for constructing a complex matrix out of two non-complex matrices
  689. template<typename eT>
  690. template<typename T1, typename T2>
  691. inline
  692. void
  693. Mat<eT>::init
  694. (
  695. const Base<typename Mat<eT>::pod_type, T1>& X,
  696. const Base<typename Mat<eT>::pod_type, T2>& Y
  697. )
  698. {
  699. arma_extra_debug_sigprint();
  700. typedef typename T1::elem_type T;
  701. arma_type_check(( is_cx<eT>::no )); //!< compile-time abort if eT is not std::complex
  702. arma_type_check(( is_cx< T>::yes )); //!< compile-time abort if T is std::complex
  703. arma_type_check(( is_same_type< std::complex<T>, eT >::no )); //!< compile-time abort if types are not compatible
  704. const Proxy<T1> PX(X.get_ref());
  705. const Proxy<T2> PY(Y.get_ref());
  706. arma_debug_assert_same_size(PX, PY, "Mat()");
  707. const uword local_n_rows = PX.get_n_rows();
  708. const uword local_n_cols = PX.get_n_cols();
  709. init_warm(local_n_rows, local_n_cols);
  710. eT* out_mem = (*this).memptr();
  711. const bool use_at = ( Proxy<T1>::use_at || Proxy<T2>::use_at );
  712. if(use_at == false)
  713. {
  714. typedef typename Proxy<T1>::ea_type ea_type1;
  715. typedef typename Proxy<T2>::ea_type ea_type2;
  716. const uword N = n_elem;
  717. ea_type1 A = PX.get_ea();
  718. ea_type2 B = PY.get_ea();
  719. for(uword ii=0; ii < N; ++ii)
  720. {
  721. out_mem[ii] = std::complex<T>(A[ii], B[ii]);
  722. }
  723. }
  724. else
  725. {
  726. for(uword ucol=0; ucol < local_n_cols; ++ucol)
  727. for(uword urow=0; urow < local_n_rows; ++urow)
  728. {
  729. *out_mem = std::complex<T>(PX.at(urow,ucol), PY.at(urow,ucol));
  730. out_mem++;
  731. }
  732. }
  733. }
  734. //! swap the contents of this matrix, denoted as matrix A, with given matrix B
  735. template<typename eT>
  736. inline
  737. void
  738. Mat<eT>::swap(Mat<eT>& B)
  739. {
  740. Mat<eT>& A = (*this);
  741. arma_extra_debug_sigprint(arma_str::format("A = %x B = %x") % &A % &B);
  742. bool layout_ok = false;
  743. if(A.vec_state == B.vec_state)
  744. {
  745. layout_ok = true;
  746. }
  747. else
  748. {
  749. const uhword A_vec_state = A.vec_state;
  750. const uhword B_vec_state = B.vec_state;
  751. const bool A_absorbs_B = (A_vec_state == 0) || ( (A_vec_state == 1) && (B.n_cols == 1) ) || ( (A_vec_state == 2) && (B.n_rows == 1) );
  752. const bool B_absorbs_A = (B_vec_state == 0) || ( (B_vec_state == 1) && (A.n_cols == 1) ) || ( (B_vec_state == 2) && (A.n_rows == 1) );
  753. layout_ok = A_absorbs_B && B_absorbs_A;
  754. }
  755. const uhword A_mem_state = A.mem_state;
  756. const uhword B_mem_state = B.mem_state;
  757. if( (A_mem_state == 0) && (B_mem_state == 0) && layout_ok )
  758. {
  759. const uword A_n_elem = A.n_elem;
  760. const uword B_n_elem = B.n_elem;
  761. const bool A_use_local_mem = (A_n_elem <= arma_config::mat_prealloc);
  762. const bool B_use_local_mem = (B_n_elem <= arma_config::mat_prealloc);
  763. if( (A_use_local_mem == false) && (B_use_local_mem == false) )
  764. {
  765. std::swap( access::rw(A.mem), access::rw(B.mem) );
  766. }
  767. else
  768. if( (A_use_local_mem == true) && (B_use_local_mem == true) )
  769. {
  770. eT* A_mem_local = &(A.mem_local[0]);
  771. eT* B_mem_local = &(B.mem_local[0]);
  772. access::rw(A.mem) = A_mem_local;
  773. access::rw(B.mem) = B_mem_local;
  774. const uword N = (std::max)(A_n_elem, B_n_elem);
  775. for(uword ii=0; ii < N; ++ii) { std::swap( A_mem_local[ii], B_mem_local[ii] ); }
  776. }
  777. else
  778. if( (A_use_local_mem == true) && (B_use_local_mem == false) )
  779. {
  780. eT* A_mem_local = &(A.mem_local[0]);
  781. eT* B_mem_local = &(B.mem_local[0]);
  782. arrayops::copy(B_mem_local, A_mem_local, A_n_elem);
  783. access::rw(A.mem) = B.mem;
  784. access::rw(B.mem) = B_mem_local;
  785. }
  786. else
  787. if( (A_use_local_mem == false) && (B_use_local_mem == true) )
  788. {
  789. eT* A_mem_local = &(A.mem_local[0]);
  790. eT* B_mem_local = &(B.mem_local[0]);
  791. arrayops::copy(A_mem_local, B_mem_local, B_n_elem);
  792. access::rw(B.mem) = A.mem;
  793. access::rw(A.mem) = A_mem_local;
  794. }
  795. std::swap( access::rw(A.n_rows), access::rw(B.n_rows) );
  796. std::swap( access::rw(A.n_cols), access::rw(B.n_cols) );
  797. std::swap( access::rw(A.n_elem), access::rw(B.n_elem) );
  798. }
  799. else
  800. if( (A_mem_state <= 2) && (B_mem_state <= 2) && (A.n_elem == B.n_elem) && layout_ok )
  801. {
  802. std::swap( access::rw(A.n_rows), access::rw(B.n_rows) );
  803. std::swap( access::rw(A.n_cols), access::rw(B.n_cols) );
  804. const uword N = A.n_elem;
  805. eT* A_mem = A.memptr();
  806. eT* B_mem = B.memptr();
  807. for(uword ii=0; ii < N; ++ii) { std::swap(A_mem[ii], B_mem[ii]); }
  808. }
  809. else
  810. if( (A.n_rows == B.n_rows) && (A.n_cols == B.n_cols) )
  811. {
  812. const uword N = A.n_elem;
  813. eT* A_mem = A.memptr();
  814. eT* B_mem = B.memptr();
  815. for(uword ii=0; ii < N; ++ii) { std::swap(A_mem[ii], B_mem[ii]); }
  816. }
  817. else
  818. {
  819. // generic swap to handle remaining cases
  820. if(A.n_elem <= B.n_elem)
  821. {
  822. Mat<eT> C = A;
  823. A.steal_mem(B);
  824. B.steal_mem(C);
  825. }
  826. else
  827. {
  828. Mat<eT> C = B;
  829. B.steal_mem(A);
  830. A.steal_mem(C);
  831. }
  832. }
  833. }
  834. //! try to steal the memory from a given matrix;
  835. //! if memory can't be stolen, copy the given matrix
  836. template<typename eT>
  837. inline
  838. void
  839. Mat<eT>::steal_mem(Mat<eT>& x)
  840. {
  841. arma_extra_debug_sigprint();
  842. if(this == &x) { return; }
  843. const uword x_n_rows = x.n_rows;
  844. const uword x_n_cols = x.n_cols;
  845. const uword x_n_elem = x.n_elem;
  846. const uhword x_vec_state = x.vec_state;
  847. const uhword x_mem_state = x.mem_state;
  848. const uhword t_vec_state = vec_state;
  849. const uhword t_mem_state = mem_state;
  850. bool layout_ok = false;
  851. if(t_vec_state == x_vec_state)
  852. {
  853. layout_ok = true;
  854. }
  855. else
  856. {
  857. if( (t_vec_state == 1) && (x_n_cols == 1) ) { layout_ok = true; }
  858. if( (t_vec_state == 2) && (x_n_rows == 1) ) { layout_ok = true; }
  859. }
  860. if( (t_mem_state <= 1) && ( ((x_mem_state == 0) && (x_n_elem > arma_config::mat_prealloc)) || (x_mem_state == 1) ) && layout_ok )
  861. {
  862. reset();
  863. access::rw(n_rows) = x_n_rows;
  864. access::rw(n_cols) = x_n_cols;
  865. access::rw(n_elem) = x_n_elem;
  866. access::rw(mem_state) = x_mem_state;
  867. access::rw(mem) = x.mem;
  868. access::rw(x.n_rows) = 0;
  869. access::rw(x.n_cols) = 0;
  870. access::rw(x.n_elem) = 0;
  871. access::rw(x.mem_state) = 0;
  872. access::rw(x.mem) = 0;
  873. }
  874. else
  875. {
  876. (*this).operator=(x);
  877. }
  878. }
  879. template<typename eT>
  880. inline
  881. void
  882. Mat<eT>::steal_mem_col(Mat<eT>& x, const uword max_n_rows)
  883. {
  884. arma_extra_debug_sigprint();
  885. const uword x_n_elem = x.n_elem;
  886. const uhword x_mem_state = x.mem_state;
  887. const uhword t_vec_state = vec_state;
  888. const uhword t_mem_state = mem_state;
  889. const uword alt_n_rows = (std::min)(x.n_rows, max_n_rows);
  890. if((x_n_elem == 0) || (alt_n_rows == 0))
  891. {
  892. (*this).set_size(0,1);
  893. return;
  894. }
  895. if( (this != &x) && (t_vec_state <= 1) && (t_mem_state <= 1) && (x_mem_state <= 1) )
  896. {
  897. if( (x_mem_state == 0) && ((x_n_elem <= arma_config::mat_prealloc) || (alt_n_rows <= arma_config::mat_prealloc)) )
  898. {
  899. (*this).set_size(alt_n_rows, uword(1));
  900. arrayops::copy( (*this).memptr(), x.memptr(), alt_n_rows );
  901. }
  902. else
  903. {
  904. reset();
  905. access::rw(n_rows) = alt_n_rows;
  906. access::rw(n_cols) = 1;
  907. access::rw(n_elem) = alt_n_rows;
  908. access::rw(mem_state) = x_mem_state;
  909. access::rw(mem) = x.mem;
  910. access::rw(x.n_rows) = 0;
  911. access::rw(x.n_cols) = 0;
  912. access::rw(x.n_elem) = 0;
  913. access::rw(x.mem_state) = 0;
  914. access::rw(x.mem) = 0;
  915. }
  916. }
  917. else
  918. {
  919. Mat<eT> tmp(alt_n_rows, 1);
  920. arrayops::copy( tmp.memptr(), x.memptr(), alt_n_rows );
  921. steal_mem(tmp);
  922. }
  923. }
  924. //! construct a matrix from a given auxiliary array of eTs.
  925. //! if copy_aux_mem is true, new memory is allocated and the array is copied.
  926. //! if copy_aux_mem is false, the auxiliary array is used directly (without allocating memory and copying).
  927. //! the default is to copy the array.
  928. template<typename eT>
  929. inline
  930. Mat<eT>::Mat(eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const bool copy_aux_mem, const bool strict)
  931. : n_rows ( aux_n_rows )
  932. , n_cols ( aux_n_cols )
  933. , n_elem ( aux_n_rows*aux_n_cols )
  934. , vec_state( 0 )
  935. , mem_state( copy_aux_mem ? 0 : ( strict ? 2 : 1 ) )
  936. , mem ( copy_aux_mem ? 0 : aux_mem )
  937. {
  938. arma_extra_debug_sigprint_this(this);
  939. if(copy_aux_mem)
  940. {
  941. init_cold();
  942. arrayops::copy( memptr(), aux_mem, n_elem );
  943. }
  944. }
  945. //! construct a matrix from a given auxiliary read-only array of eTs.
  946. //! the array is copied.
  947. template<typename eT>
  948. inline
  949. Mat<eT>::Mat(const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols)
  950. : n_rows(aux_n_rows)
  951. , n_cols(aux_n_cols)
  952. , n_elem(aux_n_rows*aux_n_cols)
  953. , vec_state(0)
  954. , mem_state(0)
  955. , mem()
  956. {
  957. arma_extra_debug_sigprint_this(this);
  958. init_cold();
  959. arrayops::copy( memptr(), aux_mem, n_elem );
  960. }
  961. //! DANGEROUS! Construct a temporary matrix, using auxiliary memory.
  962. //! This constructor is NOT intended for usage by user code.
  963. //! Its sole purpose is to be used by the Cube class.
  964. template<typename eT>
  965. inline
  966. Mat<eT>::Mat(const char junk, const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols)
  967. : n_rows (aux_n_rows )
  968. , n_cols (aux_n_cols )
  969. , n_elem (aux_n_rows*aux_n_cols)
  970. , vec_state(0 )
  971. , mem_state(3 )
  972. , mem (aux_mem )
  973. {
  974. arma_extra_debug_sigprint_this(this);
  975. arma_ignore(junk);
  976. }
  977. //! in-place matrix addition
  978. template<typename eT>
  979. inline
  980. Mat<eT>&
  981. Mat<eT>::operator+=(const Mat<eT>& m)
  982. {
  983. arma_extra_debug_sigprint();
  984. arma_debug_assert_same_size(*this, m, "addition");
  985. arrayops::inplace_plus( memptr(), m.memptr(), n_elem );
  986. return *this;
  987. }
  988. //! in-place matrix subtraction
  989. template<typename eT>
  990. inline
  991. Mat<eT>&
  992. Mat<eT>::operator-=(const Mat<eT>& m)
  993. {
  994. arma_extra_debug_sigprint();
  995. arma_debug_assert_same_size(*this, m, "subtraction");
  996. arrayops::inplace_minus( memptr(), m.memptr(), n_elem );
  997. return *this;
  998. }
  999. //! in-place matrix multiplication
  1000. template<typename eT>
  1001. inline
  1002. Mat<eT>&
  1003. Mat<eT>::operator*=(const Mat<eT>& m)
  1004. {
  1005. arma_extra_debug_sigprint();
  1006. glue_times::apply_inplace(*this, m);
  1007. return *this;
  1008. }
  1009. //! in-place element-wise matrix multiplication
  1010. template<typename eT>
  1011. inline
  1012. Mat<eT>&
  1013. Mat<eT>::operator%=(const Mat<eT>& m)
  1014. {
  1015. arma_extra_debug_sigprint();
  1016. arma_debug_assert_same_size(*this, m, "element-wise multiplication");
  1017. arrayops::inplace_mul( memptr(), m.memptr(), n_elem );
  1018. return *this;
  1019. }
  1020. //! in-place element-wise matrix division
  1021. template<typename eT>
  1022. inline
  1023. Mat<eT>&
  1024. Mat<eT>::operator/=(const Mat<eT>& m)
  1025. {
  1026. arma_extra_debug_sigprint();
  1027. arma_debug_assert_same_size(*this, m, "element-wise division");
  1028. arrayops::inplace_div( memptr(), m.memptr(), n_elem );
  1029. return *this;
  1030. }
  1031. template<typename eT>
  1032. template<typename T1>
  1033. inline
  1034. Mat<eT>::Mat(const BaseCube<eT,T1>& X)
  1035. : n_rows(0)
  1036. , n_cols(0)
  1037. , n_elem(0)
  1038. , vec_state(0)
  1039. , mem_state(0)
  1040. , mem()
  1041. {
  1042. arma_extra_debug_sigprint_this(this);
  1043. (*this).operator=(X);
  1044. }
  1045. template<typename eT>
  1046. template<typename T1>
  1047. inline
  1048. Mat<eT>&
  1049. Mat<eT>::operator=(const BaseCube<eT,T1>& X)
  1050. {
  1051. arma_extra_debug_sigprint();
  1052. Mat<eT>& out = *this;
  1053. const unwrap_cube<T1> tmp(X.get_ref());
  1054. const Cube<eT>& in = tmp.M;
  1055. arma_debug_assert_cube_as_mat(out, in, "copy into matrix", false);
  1056. const uword in_n_rows = in.n_rows;
  1057. const uword in_n_cols = in.n_cols;
  1058. const uword in_n_slices = in.n_slices;
  1059. const uword out_vec_state = out.vec_state;
  1060. if(in_n_slices == 1)
  1061. {
  1062. out.set_size(in_n_rows, in_n_cols);
  1063. for(uword ucol=0; ucol < in_n_cols; ++ucol)
  1064. {
  1065. arrayops::copy( out.colptr(ucol), in.slice_colptr(0, ucol), in_n_rows );
  1066. }
  1067. }
  1068. else
  1069. {
  1070. if(out_vec_state == 0)
  1071. {
  1072. if(in_n_cols == 1)
  1073. {
  1074. out.set_size(in_n_rows, in_n_slices);
  1075. for(uword i=0; i < in_n_slices; ++i)
  1076. {
  1077. arrayops::copy( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
  1078. }
  1079. }
  1080. else
  1081. if(in_n_rows == 1)
  1082. {
  1083. out.set_size(in_n_cols, in_n_slices);
  1084. for(uword slice=0; slice < in_n_slices; ++slice)
  1085. {
  1086. eT* out_colptr = out.colptr(slice);
  1087. uword i,j;
  1088. for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
  1089. {
  1090. const eT tmp_i = in.at(0, i, slice);
  1091. const eT tmp_j = in.at(0, j, slice);
  1092. out_colptr[i] = tmp_i;
  1093. out_colptr[j] = tmp_j;
  1094. }
  1095. if(i < in_n_cols)
  1096. {
  1097. out_colptr[i] = in.at(0, i, slice);
  1098. }
  1099. }
  1100. }
  1101. }
  1102. else
  1103. {
  1104. out.set_size(in_n_slices);
  1105. eT* out_mem = out.memptr();
  1106. for(uword i=0; i<in_n_slices; ++i)
  1107. {
  1108. out_mem[i] = in.at(0, 0, i);
  1109. }
  1110. }
  1111. }
  1112. return *this;
  1113. }
  1114. template<typename eT>
  1115. template<typename T1>
  1116. inline
  1117. Mat<eT>&
  1118. Mat<eT>::operator+=(const BaseCube<eT,T1>& X)
  1119. {
  1120. arma_extra_debug_sigprint();
  1121. Mat<eT>& out = *this;
  1122. const unwrap_cube<T1> tmp(X.get_ref());
  1123. const Cube<eT>& in = tmp.M;
  1124. arma_debug_assert_cube_as_mat(out, in, "addition", true);
  1125. const uword in_n_rows = in.n_rows;
  1126. const uword in_n_cols = in.n_cols;
  1127. const uword in_n_slices = in.n_slices;
  1128. const uword out_n_rows = out.n_rows;
  1129. const uword out_n_cols = out.n_cols;
  1130. const uword out_vec_state = out.vec_state;
  1131. if(in_n_slices == 1)
  1132. {
  1133. for(uword ucol=0; ucol < in_n_cols; ++ucol)
  1134. {
  1135. arrayops::inplace_plus( out.colptr(ucol), in.slice_colptr(0, ucol), in_n_rows );
  1136. }
  1137. }
  1138. else
  1139. {
  1140. if(out_vec_state == 0)
  1141. {
  1142. if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
  1143. {
  1144. for(uword i=0; i < in_n_slices; ++i)
  1145. {
  1146. arrayops::inplace_plus( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
  1147. }
  1148. }
  1149. else
  1150. if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
  1151. {
  1152. for(uword slice=0; slice < in_n_slices; ++slice)
  1153. {
  1154. eT* out_colptr = out.colptr(slice);
  1155. uword i,j;
  1156. for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
  1157. {
  1158. const eT tmp_i = in.at(0, i, slice);
  1159. const eT tmp_j = in.at(0, j, slice);
  1160. out_colptr[i] += tmp_i;
  1161. out_colptr[j] += tmp_j;
  1162. }
  1163. if(i < in_n_cols)
  1164. {
  1165. out_colptr[i] += in.at(0, i, slice);
  1166. }
  1167. }
  1168. }
  1169. }
  1170. else
  1171. {
  1172. eT* out_mem = out.memptr();
  1173. for(uword i=0; i<in_n_slices; ++i)
  1174. {
  1175. out_mem[i] += in.at(0, 0, i);
  1176. }
  1177. }
  1178. }
  1179. return *this;
  1180. }
  1181. template<typename eT>
  1182. template<typename T1>
  1183. inline
  1184. Mat<eT>&
  1185. Mat<eT>::operator-=(const BaseCube<eT,T1>& X)
  1186. {
  1187. arma_extra_debug_sigprint();
  1188. Mat<eT>& out = *this;
  1189. const unwrap_cube<T1> tmp(X.get_ref());
  1190. const Cube<eT>& in = tmp.M;
  1191. arma_debug_assert_cube_as_mat(out, in, "subtraction", true);
  1192. const uword in_n_rows = in.n_rows;
  1193. const uword in_n_cols = in.n_cols;
  1194. const uword in_n_slices = in.n_slices;
  1195. const uword out_n_rows = out.n_rows;
  1196. const uword out_n_cols = out.n_cols;
  1197. const uword out_vec_state = out.vec_state;
  1198. if(in_n_slices == 1)
  1199. {
  1200. for(uword ucol=0; ucol < in_n_cols; ++ucol)
  1201. {
  1202. arrayops::inplace_minus( out.colptr(ucol), in.slice_colptr(0, ucol), in_n_rows );
  1203. }
  1204. }
  1205. else
  1206. {
  1207. if(out_vec_state == 0)
  1208. {
  1209. if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
  1210. {
  1211. for(uword i=0; i < in_n_slices; ++i)
  1212. {
  1213. arrayops::inplace_minus( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
  1214. }
  1215. }
  1216. else
  1217. if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
  1218. {
  1219. for(uword slice=0; slice < in_n_slices; ++slice)
  1220. {
  1221. eT* out_colptr = out.colptr(slice);
  1222. uword i,j;
  1223. for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
  1224. {
  1225. const eT tmp_i = in.at(0, i, slice);
  1226. const eT tmp_j = in.at(0, j, slice);
  1227. out_colptr[i] -= tmp_i;
  1228. out_colptr[j] -= tmp_j;
  1229. }
  1230. if(i < in_n_cols)
  1231. {
  1232. out_colptr[i] -= in.at(0, i, slice);
  1233. }
  1234. }
  1235. }
  1236. }
  1237. else
  1238. {
  1239. eT* out_mem = out.memptr();
  1240. for(uword i=0; i<in_n_slices; ++i)
  1241. {
  1242. out_mem[i] -= in.at(0, 0, i);
  1243. }
  1244. }
  1245. }
  1246. return *this;
  1247. }
  1248. template<typename eT>
  1249. template<typename T1>
  1250. inline
  1251. Mat<eT>&
  1252. Mat<eT>::operator*=(const BaseCube<eT,T1>& X)
  1253. {
  1254. arma_extra_debug_sigprint();
  1255. const Mat<eT> B(X);
  1256. (*this).operator*=(B);
  1257. return *this;
  1258. }
  1259. template<typename eT>
  1260. template<typename T1>
  1261. inline
  1262. Mat<eT>&
  1263. Mat<eT>::operator%=(const BaseCube<eT,T1>& X)
  1264. {
  1265. arma_extra_debug_sigprint();
  1266. Mat<eT>& out = *this;
  1267. const unwrap_cube<T1> tmp(X.get_ref());
  1268. const Cube<eT>& in = tmp.M;
  1269. arma_debug_assert_cube_as_mat(out, in, "element-wise multiplication", true);
  1270. const uword in_n_rows = in.n_rows;
  1271. const uword in_n_cols = in.n_cols;
  1272. const uword in_n_slices = in.n_slices;
  1273. const uword out_n_rows = out.n_rows;
  1274. const uword out_n_cols = out.n_cols;
  1275. const uword out_vec_state = out.vec_state;
  1276. if(in_n_slices == 1)
  1277. {
  1278. for(uword ucol=0; ucol < in_n_cols; ++ucol)
  1279. {
  1280. arrayops::inplace_mul( out.colptr(ucol), in.slice_colptr(0, ucol), in_n_rows );
  1281. }
  1282. }
  1283. else
  1284. {
  1285. if(out_vec_state == 0)
  1286. {
  1287. if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
  1288. {
  1289. for(uword i=0; i < in_n_slices; ++i)
  1290. {
  1291. arrayops::inplace_mul( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
  1292. }
  1293. }
  1294. else
  1295. if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
  1296. {
  1297. for(uword slice=0; slice < in_n_slices; ++slice)
  1298. {
  1299. eT* out_colptr = out.colptr(slice);
  1300. uword i,j;
  1301. for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
  1302. {
  1303. const eT tmp_i = in.at(0, i, slice);
  1304. const eT tmp_j = in.at(0, j, slice);
  1305. out_colptr[i] *= tmp_i;
  1306. out_colptr[j] *= tmp_j;
  1307. }
  1308. if(i < in_n_cols)
  1309. {
  1310. out_colptr[i] *= in.at(0, i, slice);
  1311. }
  1312. }
  1313. }
  1314. }
  1315. else
  1316. {
  1317. eT* out_mem = out.memptr();
  1318. for(uword i=0; i<in_n_slices; ++i)
  1319. {
  1320. out_mem[i] *= in.at(0, 0, i);
  1321. }
  1322. }
  1323. }
  1324. return *this;
  1325. }
  1326. template<typename eT>
  1327. template<typename T1>
  1328. inline
  1329. Mat<eT>&
  1330. Mat<eT>::operator/=(const BaseCube<eT,T1>& X)
  1331. {
  1332. arma_extra_debug_sigprint();
  1333. Mat<eT>& out = *this;
  1334. const unwrap_cube<T1> tmp(X.get_ref());
  1335. const Cube<eT>& in = tmp.M;
  1336. arma_debug_assert_cube_as_mat(out, in, "element-wise division", true);
  1337. const uword in_n_rows = in.n_rows;
  1338. const uword in_n_cols = in.n_cols;
  1339. const uword in_n_slices = in.n_slices;
  1340. const uword out_n_rows = out.n_rows;
  1341. const uword out_n_cols = out.n_cols;
  1342. const uword out_vec_state = out.vec_state;
  1343. if(in_n_slices == 1)
  1344. {
  1345. for(uword ucol=0; ucol < in_n_cols; ++ucol)
  1346. {
  1347. arrayops::inplace_div( out.colptr(ucol), in.slice_colptr(0, ucol), in_n_rows );
  1348. }
  1349. }
  1350. else
  1351. {
  1352. if(out_vec_state == 0)
  1353. {
  1354. if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
  1355. {
  1356. for(uword i=0; i < in_n_slices; ++i)
  1357. {
  1358. arrayops::inplace_div( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
  1359. }
  1360. }
  1361. else
  1362. if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
  1363. {
  1364. for(uword slice=0; slice < in_n_slices; ++slice)
  1365. {
  1366. eT* out_colptr = out.colptr(slice);
  1367. uword i,j;
  1368. for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
  1369. {
  1370. const eT tmp_i = in.at(0, i, slice);
  1371. const eT tmp_j = in.at(0, j, slice);
  1372. out_colptr[i] /= tmp_i;
  1373. out_colptr[j] /= tmp_j;
  1374. }
  1375. if(i < in_n_cols)
  1376. {
  1377. out_colptr[i] /= in.at(0, i, slice);
  1378. }
  1379. }
  1380. }
  1381. }
  1382. else
  1383. {
  1384. eT* out_mem = out.memptr();
  1385. for(uword i=0; i<in_n_slices; ++i)
  1386. {
  1387. out_mem[i] /= in.at(0, 0, i);
  1388. }
  1389. }
  1390. }
  1391. return *this;
  1392. }
  1393. //! for constructing a complex matrix out of two non-complex matrices
  1394. template<typename eT>
  1395. template<typename T1, typename T2>
  1396. inline
  1397. Mat<eT>::Mat
  1398. (
  1399. const Base<typename Mat<eT>::pod_type,T1>& A,
  1400. const Base<typename Mat<eT>::pod_type,T2>& B
  1401. )
  1402. : n_rows(0)
  1403. , n_cols(0)
  1404. , n_elem(0)
  1405. , vec_state(0)
  1406. , mem_state(0)
  1407. , mem()
  1408. {
  1409. arma_extra_debug_sigprint_this(this);
  1410. init(A,B);
  1411. }
  1412. template<typename eT>
  1413. inline
  1414. #ifdef LUOYC20220705
  1415. Mat<eT>::Mat(subview<eT>& X, const bool use_colmem)
  1416. #else
  1417. Mat<eT>::Mat(const subview<eT>& X, const bool use_colmem)
  1418. #endif
  1419. : n_rows(X.n_rows)
  1420. , n_cols(X.n_cols)
  1421. , n_elem(X.n_elem)
  1422. , vec_state(0)
  1423. , mem_state(use_colmem ? 3 : 0)
  1424. , mem (use_colmem ? X.colptr(0) : NULL)
  1425. {
  1426. arma_extra_debug_sigprint_this(this);
  1427. if(use_colmem)
  1428. {
  1429. arma_extra_debug_print("Mat::Mat(): using existing memory in a submatrix");
  1430. }
  1431. else
  1432. {
  1433. init_cold();
  1434. subview<eT>::extract(*this, X);
  1435. }
  1436. }
  1437. //! construct a matrix from subview (e.g. construct a matrix from a delayed submatrix operation)
  1438. template<typename eT>
  1439. inline
  1440. Mat<eT>::Mat(const subview<eT>& X)
  1441. : n_rows(X.n_rows)
  1442. , n_cols(X.n_cols)
  1443. , n_elem(X.n_elem)
  1444. , vec_state(0)
  1445. , mem_state(0)
  1446. , mem()
  1447. {
  1448. arma_extra_debug_sigprint_this(this);
  1449. init_cold();
  1450. subview<eT>::extract(*this, X);
  1451. }
  1452. //! construct a matrix from subview (e.g. construct a matrix from a delayed submatrix operation)
  1453. template<typename eT>
  1454. inline
  1455. Mat<eT>&
  1456. Mat<eT>::operator=(const subview<eT>& X)
  1457. {
  1458. arma_extra_debug_sigprint();
  1459. const bool alias = (this == &(X.m));
  1460. if(alias == false)
  1461. {
  1462. init_warm(X.n_rows, X.n_cols);
  1463. subview<eT>::extract(*this, X);
  1464. }
  1465. else
  1466. {
  1467. Mat<eT> tmp(X);
  1468. steal_mem(tmp);
  1469. }
  1470. return *this;
  1471. }
  1472. //! in-place matrix addition (using a submatrix on the right-hand-side)
  1473. template<typename eT>
  1474. inline
  1475. Mat<eT>&
  1476. Mat<eT>::operator+=(const subview<eT>& X)
  1477. {
  1478. arma_extra_debug_sigprint();
  1479. subview<eT>::plus_inplace(*this, X);
  1480. return *this;
  1481. }
  1482. //! in-place matrix subtraction (using a submatrix on the right-hand-side)
  1483. template<typename eT>
  1484. inline
  1485. Mat<eT>&
  1486. Mat<eT>::operator-=(const subview<eT>& X)
  1487. {
  1488. arma_extra_debug_sigprint();
  1489. subview<eT>::minus_inplace(*this, X);
  1490. return *this;
  1491. }
  1492. //! in-place matrix mutiplication (using a submatrix on the right-hand-side)
  1493. template<typename eT>
  1494. inline
  1495. Mat<eT>&
  1496. Mat<eT>::operator*=(const subview<eT>& X)
  1497. {
  1498. arma_extra_debug_sigprint();
  1499. glue_times::apply_inplace(*this, X);
  1500. return *this;
  1501. }
  1502. //! in-place element-wise matrix mutiplication (using a submatrix on the right-hand-side)
  1503. template<typename eT>
  1504. inline
  1505. Mat<eT>&
  1506. Mat<eT>::operator%=(const subview<eT>& X)
  1507. {
  1508. arma_extra_debug_sigprint();
  1509. subview<eT>::schur_inplace(*this, X);
  1510. return *this;
  1511. }
  1512. //! in-place element-wise matrix division (using a submatrix on the right-hand-side)
  1513. template<typename eT>
  1514. inline
  1515. Mat<eT>&
  1516. Mat<eT>::operator/=(const subview<eT>& X)
  1517. {
  1518. arma_extra_debug_sigprint();
  1519. subview<eT>::div_inplace(*this, X);
  1520. return *this;
  1521. }
  1522. template<typename eT>
  1523. inline
  1524. Mat<eT>::Mat(const subview_row_strans<eT>& X)
  1525. : n_rows(X.n_rows)
  1526. , n_cols(X.n_cols)
  1527. , n_elem(X.n_elem)
  1528. , vec_state(0)
  1529. , mem_state(0)
  1530. , mem()
  1531. {
  1532. arma_extra_debug_sigprint_this(this);
  1533. init_cold();
  1534. X.extract(*this);
  1535. }
  1536. template<typename eT>
  1537. inline
  1538. Mat<eT>::Mat(const subview_row_htrans<eT>& X)
  1539. : n_rows(X.n_rows)
  1540. , n_cols(X.n_cols)
  1541. , n_elem(X.n_elem)
  1542. , vec_state(0)
  1543. , mem_state(0)
  1544. , mem()
  1545. {
  1546. arma_extra_debug_sigprint_this(this);
  1547. init_cold();
  1548. X.extract(*this);
  1549. }
  1550. template<typename eT>
  1551. inline
  1552. Mat<eT>::Mat(const xvec_htrans<eT>& X)
  1553. : n_rows(X.n_rows)
  1554. , n_cols(X.n_cols)
  1555. , n_elem(X.n_elem)
  1556. , vec_state(0)
  1557. , mem_state(0)
  1558. , mem()
  1559. {
  1560. arma_extra_debug_sigprint_this(this);
  1561. init_cold();
  1562. X.extract(*this);
  1563. }
  1564. template<typename eT>
  1565. template<bool do_conj>
  1566. inline
  1567. Mat<eT>::Mat(const xtrans_mat<eT,do_conj>& X)
  1568. : n_rows(X.n_rows)
  1569. , n_cols(X.n_cols)
  1570. , n_elem(X.n_elem)
  1571. , vec_state(0)
  1572. , mem_state(0)
  1573. , mem()
  1574. {
  1575. arma_extra_debug_sigprint_this(this);
  1576. init_cold();
  1577. X.extract(*this);
  1578. }
  1579. //! construct a matrix from a subview_cube instance
  1580. template<typename eT>
  1581. inline
  1582. Mat<eT>::Mat(const subview_cube<eT>& x)
  1583. : n_rows(0)
  1584. , n_cols(0)
  1585. , n_elem(0)
  1586. , vec_state(0)
  1587. , mem_state(0)
  1588. , mem()
  1589. {
  1590. arma_extra_debug_sigprint_this(this);
  1591. this->operator=(x);
  1592. }
  1593. //! construct a matrix from a subview_cube instance
  1594. template<typename eT>
  1595. inline
  1596. Mat<eT>&
  1597. Mat<eT>::operator=(const subview_cube<eT>& X)
  1598. {
  1599. arma_extra_debug_sigprint();
  1600. subview_cube<eT>::extract(*this, X);
  1601. return *this;
  1602. }
  1603. //! in-place matrix addition (using a single-slice subcube on the right-hand-side)
  1604. template<typename eT>
  1605. inline
  1606. Mat<eT>&
  1607. Mat<eT>::operator+=(const subview_cube<eT>& X)
  1608. {
  1609. arma_extra_debug_sigprint();
  1610. subview_cube<eT>::plus_inplace(*this, X);
  1611. return *this;
  1612. }
  1613. //! in-place matrix subtraction (using a single-slice subcube on the right-hand-side)
  1614. template<typename eT>
  1615. inline
  1616. Mat<eT>&
  1617. Mat<eT>::operator-=(const subview_cube<eT>& X)
  1618. {
  1619. arma_extra_debug_sigprint();
  1620. subview_cube<eT>::minus_inplace(*this, X);
  1621. return *this;
  1622. }
  1623. //! in-place matrix mutiplication (using a single-slice subcube on the right-hand-side)
  1624. template<typename eT>
  1625. inline
  1626. Mat<eT>&
  1627. Mat<eT>::operator*=(const subview_cube<eT>& X)
  1628. {
  1629. arma_extra_debug_sigprint();
  1630. const Mat<eT> tmp(X);
  1631. glue_times::apply_inplace(*this, tmp);
  1632. return *this;
  1633. }
  1634. //! in-place element-wise matrix mutiplication (using a single-slice subcube on the right-hand-side)
  1635. template<typename eT>
  1636. inline
  1637. Mat<eT>&
  1638. Mat<eT>::operator%=(const subview_cube<eT>& X)
  1639. {
  1640. arma_extra_debug_sigprint();
  1641. subview_cube<eT>::schur_inplace(*this, X);
  1642. return *this;
  1643. }
  1644. //! in-place element-wise matrix division (using a single-slice subcube on the right-hand-side)
  1645. template<typename eT>
  1646. inline
  1647. Mat<eT>&
  1648. Mat<eT>::operator/=(const subview_cube<eT>& X)
  1649. {
  1650. arma_extra_debug_sigprint();
  1651. subview_cube<eT>::div_inplace(*this, X);
  1652. return *this;
  1653. }
  1654. //! construct a matrix from diagview (e.g. construct a matrix from a delayed diag operation)
  1655. template<typename eT>
  1656. inline
  1657. Mat<eT>::Mat(const diagview<eT>& X)
  1658. : n_rows(X.n_rows)
  1659. , n_cols(X.n_cols)
  1660. , n_elem(X.n_elem)
  1661. , vec_state(0)
  1662. , mem_state(0)
  1663. , mem()
  1664. {
  1665. arma_extra_debug_sigprint_this(this);
  1666. init_cold();
  1667. diagview<eT>::extract(*this, X);
  1668. }
  1669. //! construct a matrix from diagview (e.g. construct a matrix from a delayed diag operation)
  1670. template<typename eT>
  1671. inline
  1672. Mat<eT>&
  1673. Mat<eT>::operator=(const diagview<eT>& X)
  1674. {
  1675. arma_extra_debug_sigprint();
  1676. const bool alias = (this == &(X.m));
  1677. if(alias == false)
  1678. {
  1679. init_warm(X.n_rows, X.n_cols);
  1680. diagview<eT>::extract(*this, X);
  1681. }
  1682. else
  1683. {
  1684. Mat<eT> tmp(X);
  1685. steal_mem(tmp);
  1686. }
  1687. return *this;
  1688. }
  1689. //! in-place matrix addition (using a diagview on the right-hand-side)
  1690. template<typename eT>
  1691. inline
  1692. Mat<eT>&
  1693. Mat<eT>::operator+=(const diagview<eT>& X)
  1694. {
  1695. arma_extra_debug_sigprint();
  1696. diagview<eT>::plus_inplace(*this, X);
  1697. return *this;
  1698. }
  1699. //! in-place matrix subtraction (using a diagview on the right-hand-side)
  1700. template<typename eT>
  1701. inline
  1702. Mat<eT>&
  1703. Mat<eT>::operator-=(const diagview<eT>& X)
  1704. {
  1705. arma_extra_debug_sigprint();
  1706. diagview<eT>::minus_inplace(*this, X);
  1707. return *this;
  1708. }
  1709. //! in-place matrix mutiplication (using a diagview on the right-hand-side)
  1710. template<typename eT>
  1711. inline
  1712. Mat<eT>&
  1713. Mat<eT>::operator*=(const diagview<eT>& X)
  1714. {
  1715. arma_extra_debug_sigprint();
  1716. glue_times::apply_inplace(*this, X);
  1717. return *this;
  1718. }
  1719. //! in-place element-wise matrix mutiplication (using a diagview on the right-hand-side)
  1720. template<typename eT>
  1721. inline
  1722. Mat<eT>&
  1723. Mat<eT>::operator%=(const diagview<eT>& X)
  1724. {
  1725. arma_extra_debug_sigprint();
  1726. diagview<eT>::schur_inplace(*this, X);
  1727. return *this;
  1728. }
  1729. //! in-place element-wise matrix division (using a diagview on the right-hand-side)
  1730. template<typename eT>
  1731. inline
  1732. Mat<eT>&
  1733. Mat<eT>::operator/=(const diagview<eT>& X)
  1734. {
  1735. arma_extra_debug_sigprint();
  1736. diagview<eT>::div_inplace(*this, X);
  1737. return *this;
  1738. }
  1739. template<typename eT>
  1740. template<typename T1>
  1741. inline
  1742. Mat<eT>::Mat(const subview_elem1<eT,T1>& X)
  1743. : n_rows(0)
  1744. , n_cols(0)
  1745. , n_elem(0)
  1746. , vec_state(0)
  1747. , mem_state(0)
  1748. , mem()
  1749. {
  1750. arma_extra_debug_sigprint_this(this);
  1751. this->operator=(X);
  1752. }
  1753. template<typename eT>
  1754. template<typename T1>
  1755. inline
  1756. Mat<eT>&
  1757. Mat<eT>::operator=(const subview_elem1<eT,T1>& X)
  1758. {
  1759. arma_extra_debug_sigprint();
  1760. subview_elem1<eT,T1>::extract(*this, X);
  1761. return *this;
  1762. }
  1763. template<typename eT>
  1764. template<typename T1>
  1765. inline
  1766. Mat<eT>&
  1767. Mat<eT>::operator+=(const subview_elem1<eT,T1>& X)
  1768. {
  1769. arma_extra_debug_sigprint();
  1770. subview_elem1<eT,T1>::plus_inplace(*this, X);
  1771. return *this;
  1772. }
  1773. template<typename eT>
  1774. template<typename T1>
  1775. inline
  1776. Mat<eT>&
  1777. Mat<eT>::operator-=(const subview_elem1<eT,T1>& X)
  1778. {
  1779. arma_extra_debug_sigprint();
  1780. subview_elem1<eT,T1>::minus_inplace(*this, X);
  1781. return *this;
  1782. }
  1783. template<typename eT>
  1784. template<typename T1>
  1785. inline
  1786. Mat<eT>&
  1787. Mat<eT>::operator*=(const subview_elem1<eT,T1>& X)
  1788. {
  1789. arma_extra_debug_sigprint();
  1790. glue_times::apply_inplace(*this, X);
  1791. return *this;
  1792. }
  1793. template<typename eT>
  1794. template<typename T1>
  1795. inline
  1796. Mat<eT>&
  1797. Mat<eT>::operator%=(const subview_elem1<eT,T1>& X)
  1798. {
  1799. arma_extra_debug_sigprint();
  1800. subview_elem1<eT,T1>::schur_inplace(*this, X);
  1801. return *this;
  1802. }
  1803. template<typename eT>
  1804. template<typename T1>
  1805. inline
  1806. Mat<eT>&
  1807. Mat<eT>::operator/=(const subview_elem1<eT,T1>& X)
  1808. {
  1809. arma_extra_debug_sigprint();
  1810. subview_elem1<eT,T1>::div_inplace(*this, X);
  1811. return *this;
  1812. }
  1813. template<typename eT>
  1814. template<typename T1, typename T2>
  1815. inline
  1816. Mat<eT>::Mat(const subview_elem2<eT,T1,T2>& X)
  1817. : n_rows(0)
  1818. , n_cols(0)
  1819. , n_elem(0)
  1820. , vec_state(0)
  1821. , mem_state(0)
  1822. , mem()
  1823. {
  1824. arma_extra_debug_sigprint_this(this);
  1825. this->operator=(X);
  1826. }
  1827. template<typename eT>
  1828. template<typename T1, typename T2>
  1829. inline
  1830. Mat<eT>&
  1831. Mat<eT>::operator=(const subview_elem2<eT,T1,T2>& X)
  1832. {
  1833. arma_extra_debug_sigprint();
  1834. subview_elem2<eT,T1,T2>::extract(*this, X);
  1835. return *this;
  1836. }
  1837. template<typename eT>
  1838. template<typename T1, typename T2>
  1839. inline
  1840. Mat<eT>&
  1841. Mat<eT>::operator+=(const subview_elem2<eT,T1,T2>& X)
  1842. {
  1843. arma_extra_debug_sigprint();
  1844. subview_elem2<eT,T1,T2>::plus_inplace(*this, X);
  1845. return *this;
  1846. }
  1847. template<typename eT>
  1848. template<typename T1, typename T2>
  1849. inline
  1850. Mat<eT>&
  1851. Mat<eT>::operator-=(const subview_elem2<eT,T1,T2>& X)
  1852. {
  1853. arma_extra_debug_sigprint();
  1854. subview_elem2<eT,T1,T2>::minus_inplace(*this, X);
  1855. return *this;
  1856. }
  1857. template<typename eT>
  1858. template<typename T1, typename T2>
  1859. inline
  1860. Mat<eT>&
  1861. Mat<eT>::operator*=(const subview_elem2<eT,T1,T2>& X)
  1862. {
  1863. arma_extra_debug_sigprint();
  1864. glue_times::apply_inplace(*this, X);
  1865. return *this;
  1866. }
  1867. template<typename eT>
  1868. template<typename T1, typename T2>
  1869. inline
  1870. Mat<eT>&
  1871. Mat<eT>::operator%=(const subview_elem2<eT,T1,T2>& X)
  1872. {
  1873. arma_extra_debug_sigprint();
  1874. subview_elem2<eT,T1,T2>::schur_inplace(*this, X);
  1875. return *this;
  1876. }
  1877. template<typename eT>
  1878. template<typename T1, typename T2>
  1879. inline
  1880. Mat<eT>&
  1881. Mat<eT>::operator/=(const subview_elem2<eT,T1,T2>& X)
  1882. {
  1883. arma_extra_debug_sigprint();
  1884. subview_elem2<eT,T1,T2>::div_inplace(*this, X);
  1885. return *this;
  1886. }
  1887. template<typename eT>
  1888. template<typename T1>
  1889. inline
  1890. Mat<eT>::Mat(const SpBase<eT, T1>& m)
  1891. : n_rows(0)
  1892. , n_cols(0)
  1893. , n_elem(0)
  1894. , vec_state(0)
  1895. , mem_state(0)
  1896. , mem()
  1897. {
  1898. arma_extra_debug_sigprint_this(this);
  1899. (*this).operator=(m);
  1900. }
  1901. template<typename eT>
  1902. template<typename T1>
  1903. inline
  1904. Mat<eT>&
  1905. Mat<eT>::operator=(const SpBase<eT, T1>& m)
  1906. {
  1907. arma_extra_debug_sigprint();
  1908. const unwrap_spmat<T1> U(m.get_ref());
  1909. const SpMat<eT>& x = U.M;
  1910. const uword x_n_cols = x.n_cols;
  1911. (*this).zeros(x.n_rows, x_n_cols);
  1912. const eT* x_values = x.values;
  1913. const uword* x_row_indices = x.row_indices;
  1914. const uword* x_col_ptrs = x.col_ptrs;
  1915. for(uword x_col = 0; x_col < x_n_cols; ++x_col)
  1916. {
  1917. const uword start = x_col_ptrs[x_col ];
  1918. const uword end = x_col_ptrs[x_col + 1];
  1919. for(uword i = start; i < end; ++i)
  1920. {
  1921. const uword x_row = x_row_indices[i];
  1922. const eT x_val = x_values[i];
  1923. at(x_row, x_col) = x_val;
  1924. }
  1925. }
  1926. return *this;
  1927. }
  1928. template<typename eT>
  1929. template<typename T1>
  1930. inline
  1931. Mat<eT>&
  1932. Mat<eT>::operator+=(const SpBase<eT, T1>& m)
  1933. {
  1934. arma_extra_debug_sigprint();
  1935. const SpProxy<T1> p(m.get_ref());
  1936. arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "addition");
  1937. typename SpProxy<T1>::const_iterator_type it = p.begin();
  1938. typename SpProxy<T1>::const_iterator_type it_end = p.end();
  1939. while(it != it_end)
  1940. {
  1941. at(it.row(), it.col()) += (*it);
  1942. ++it;
  1943. }
  1944. return *this;
  1945. }
  1946. template<typename eT>
  1947. template<typename T1>
  1948. inline
  1949. Mat<eT>&
  1950. Mat<eT>::operator-=(const SpBase<eT, T1>& m)
  1951. {
  1952. arma_extra_debug_sigprint();
  1953. const SpProxy<T1> p(m.get_ref());
  1954. arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "subtraction");
  1955. typename SpProxy<T1>::const_iterator_type it = p.begin();
  1956. typename SpProxy<T1>::const_iterator_type it_end = p.end();
  1957. while(it != it_end)
  1958. {
  1959. at(it.row(), it.col()) -= (*it);
  1960. ++it;
  1961. }
  1962. return *this;
  1963. }
  1964. template<typename eT>
  1965. template<typename T1>
  1966. inline
  1967. Mat<eT>&
  1968. Mat<eT>::operator*=(const SpBase<eT, T1>& m)
  1969. {
  1970. arma_extra_debug_sigprint();
  1971. Mat<eT> z = (*this) * m.get_ref();
  1972. steal_mem(z);
  1973. return *this;
  1974. }
  1975. template<typename eT>
  1976. template<typename T1>
  1977. inline
  1978. Mat<eT>&
  1979. Mat<eT>::operator%=(const SpBase<eT, T1>& m)
  1980. {
  1981. arma_extra_debug_sigprint();
  1982. const SpProxy<T1> p(m.get_ref());
  1983. arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "element-wise multiplication");
  1984. typename SpProxy<T1>::const_iterator_type it = p.begin();
  1985. typename SpProxy<T1>::const_iterator_type it_end = p.end();
  1986. // We have to zero everything that isn't being used.
  1987. arrayops::inplace_set(memptr(), eT(0), (it.col() * n_rows) + it.row());
  1988. while(it != it_end)
  1989. {
  1990. const uword cur_loc = (it.col() * n_rows) + it.row();
  1991. access::rw(mem[cur_loc]) *= (*it);
  1992. ++it;
  1993. const uword next_loc = (it == it_end)
  1994. ? (p.get_n_cols() * n_rows)
  1995. : (it.col() * n_rows) + it.row();
  1996. arrayops::inplace_set(memptr() + cur_loc + 1, eT(0), (next_loc - cur_loc - 1));
  1997. }
  1998. return *this;
  1999. }
  2000. template<typename eT>
  2001. template<typename T1>
  2002. inline
  2003. Mat<eT>&
  2004. Mat<eT>::operator/=(const SpBase<eT, T1>& m)
  2005. {
  2006. arma_extra_debug_sigprint();
  2007. // NOTE: use of this function is not advised; it is implemented only for completeness
  2008. const SpProxy<T1> p(m.get_ref());
  2009. arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "element-wise division");
  2010. for(uword c = 0; c < n_cols; ++c)
  2011. for(uword r = 0; r < n_rows; ++r)
  2012. {
  2013. at(r, c) /= p.at(r, c);
  2014. }
  2015. return *this;
  2016. }
  2017. template<typename eT>
  2018. inline
  2019. Mat<eT>::Mat(const SpSubview<eT>& X)
  2020. : n_rows(0)
  2021. , n_cols(0)
  2022. , n_elem(0)
  2023. , vec_state(0)
  2024. , mem_state(0)
  2025. , mem()
  2026. {
  2027. arma_extra_debug_sigprint_this(this);
  2028. (*this).operator=(X);
  2029. }
  2030. template<typename eT>
  2031. inline
  2032. Mat<eT>&
  2033. Mat<eT>::operator=(const SpSubview<eT>& X)
  2034. {
  2035. arma_extra_debug_sigprint();
  2036. (*this).zeros(X.n_rows, X.n_cols);
  2037. if(X.n_rows == X.m.n_rows)
  2038. {
  2039. const uword sv_col_start = X.aux_col1;
  2040. const uword sv_col_end = X.aux_col1 + X.n_cols - 1;
  2041. const eT* m_values = X.m.values;
  2042. const uword* m_row_indices = X.m.row_indices;
  2043. const uword* m_col_ptrs = X.m.col_ptrs;
  2044. for(uword m_col = sv_col_start; m_col <= sv_col_end; ++m_col)
  2045. {
  2046. const uword m_col_adjusted = m_col - sv_col_start;
  2047. const uword start = m_col_ptrs[m_col ];
  2048. const uword end = m_col_ptrs[m_col + 1];
  2049. for(uword ii = start; ii < end; ++ii)
  2050. {
  2051. const uword m_row = m_row_indices[ii];
  2052. const eT m_val = m_values[ii];
  2053. at(m_row, m_col_adjusted) = m_val;
  2054. }
  2055. }
  2056. }
  2057. else
  2058. {
  2059. typename SpSubview<eT>::const_iterator it = X.begin();
  2060. typename SpSubview<eT>::const_iterator it_end = X.end();
  2061. while(it != it_end)
  2062. {
  2063. at(it.row(), it.col()) = (*it);
  2064. ++it;
  2065. }
  2066. }
  2067. return *this;
  2068. }
  2069. template<typename eT>
  2070. inline
  2071. Mat<eT>::Mat(const spdiagview<eT>& X)
  2072. : n_rows(X.n_rows)
  2073. , n_cols(X.n_cols)
  2074. , n_elem(X.n_elem)
  2075. , vec_state(0)
  2076. , mem_state(0)
  2077. , mem()
  2078. {
  2079. arma_extra_debug_sigprint_this(this);
  2080. init_cold();
  2081. spdiagview<eT>::extract(*this, X);
  2082. }
  2083. template<typename eT>
  2084. inline
  2085. Mat<eT>&
  2086. Mat<eT>::operator=(const spdiagview<eT>& X)
  2087. {
  2088. arma_extra_debug_sigprint();
  2089. init_warm(X.n_rows, X.n_cols);
  2090. spdiagview<eT>::extract(*this, X);
  2091. return *this;
  2092. }
  2093. template<typename eT>
  2094. inline
  2095. Mat<eT>&
  2096. Mat<eT>::operator+=(const spdiagview<eT>& X)
  2097. {
  2098. arma_extra_debug_sigprint();
  2099. const Mat<eT> tmp(X);
  2100. (*this).operator+=(tmp);
  2101. return *this;
  2102. }
  2103. template<typename eT>
  2104. inline
  2105. Mat<eT>&
  2106. Mat<eT>::operator-=(const spdiagview<eT>& X)
  2107. {
  2108. arma_extra_debug_sigprint();
  2109. const Mat<eT> tmp(X);
  2110. (*this).operator-=(tmp);
  2111. return *this;
  2112. }
  2113. template<typename eT>
  2114. inline
  2115. Mat<eT>&
  2116. Mat<eT>::operator*=(const spdiagview<eT>& X)
  2117. {
  2118. arma_extra_debug_sigprint();
  2119. const Mat<eT> tmp(X);
  2120. (*this).operator*=(tmp);
  2121. return *this;
  2122. }
  2123. template<typename eT>
  2124. inline
  2125. Mat<eT>&
  2126. Mat<eT>::operator%=(const spdiagview<eT>& X)
  2127. {
  2128. arma_extra_debug_sigprint();
  2129. const Mat<eT> tmp(X);
  2130. (*this).operator%=(tmp);
  2131. return *this;
  2132. }
  2133. template<typename eT>
  2134. inline
  2135. Mat<eT>&
  2136. Mat<eT>::operator/=(const spdiagview<eT>& X)
  2137. {
  2138. arma_extra_debug_sigprint();
  2139. const Mat<eT> tmp(X);
  2140. (*this).operator/=(tmp);
  2141. return *this;
  2142. }
  2143. template<typename eT>
  2144. inline
  2145. mat_injector< Mat<eT> >
  2146. Mat<eT>::operator<<(const eT val)
  2147. {
  2148. return mat_injector< Mat<eT> >(*this, val);
  2149. }
  2150. template<typename eT>
  2151. inline
  2152. mat_injector< Mat<eT> >
  2153. Mat<eT>::operator<<(const injector_end_of_row<>& x)
  2154. {
  2155. return mat_injector< Mat<eT> >(*this, x);
  2156. }
  2157. //! creation of subview (row vector)
  2158. template<typename eT>
  2159. arma_inline
  2160. subview_row<eT>
  2161. Mat<eT>::row(const uword row_num)
  2162. {
  2163. arma_extra_debug_sigprint();
  2164. arma_debug_check( row_num >= n_rows, "Mat::row(): index out of bounds" );
  2165. return subview_row<eT>(*this, row_num);
  2166. }
  2167. //! creation of subview (row vector)
  2168. template<typename eT>
  2169. arma_inline
  2170. const subview_row<eT>
  2171. Mat<eT>::row(const uword row_num) const
  2172. {
  2173. arma_extra_debug_sigprint();
  2174. arma_debug_check( row_num >= n_rows, "Mat::row(): index out of bounds" );
  2175. return subview_row<eT>(*this, row_num);
  2176. }
  2177. template<typename eT>
  2178. inline
  2179. subview_row<eT>
  2180. Mat<eT>::operator()(const uword row_num, const span& col_span)
  2181. {
  2182. arma_extra_debug_sigprint();
  2183. const bool col_all = col_span.whole;
  2184. const uword local_n_cols = n_cols;
  2185. const uword in_col1 = col_all ? 0 : col_span.a;
  2186. const uword in_col2 = col_span.b;
  2187. const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
  2188. arma_debug_check
  2189. (
  2190. (row_num >= n_rows)
  2191. ||
  2192. ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
  2193. ,
  2194. "Mat::operator(): indices out of bounds or incorrectly used"
  2195. );
  2196. return subview_row<eT>(*this, row_num, in_col1, submat_n_cols);
  2197. }
  2198. template<typename eT>
  2199. inline
  2200. const subview_row<eT>
  2201. Mat<eT>::operator()(const uword row_num, const span& col_span) const
  2202. {
  2203. arma_extra_debug_sigprint();
  2204. const bool col_all = col_span.whole;
  2205. const uword local_n_cols = n_cols;
  2206. const uword in_col1 = col_all ? 0 : col_span.a;
  2207. const uword in_col2 = col_span.b;
  2208. const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
  2209. arma_debug_check
  2210. (
  2211. (row_num >= n_rows)
  2212. ||
  2213. ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
  2214. ,
  2215. "Mat::operator(): indices out of bounds or incorrectly used"
  2216. );
  2217. return subview_row<eT>(*this, row_num, in_col1, submat_n_cols);
  2218. }
  2219. //! creation of subview (column vector)
  2220. template<typename eT>
  2221. arma_inline
  2222. subview_col<eT>
  2223. Mat<eT>::col(const uword col_num)
  2224. {
  2225. arma_extra_debug_sigprint();
  2226. arma_debug_check( col_num >= n_cols, "Mat::col(): index out of bounds");
  2227. return subview_col<eT>(*this, col_num);
  2228. }
  2229. //! creation of subview (column vector)
  2230. template<typename eT>
  2231. arma_inline
  2232. const subview_col<eT>
  2233. Mat<eT>::col(const uword col_num) const
  2234. {
  2235. arma_extra_debug_sigprint();
  2236. arma_debug_check( col_num >= n_cols, "Mat::col(): index out of bounds");
  2237. return subview_col<eT>(*this, col_num);
  2238. }
  2239. template<typename eT>
  2240. inline
  2241. subview_col<eT>
  2242. Mat<eT>::operator()(const span& row_span, const uword col_num)
  2243. {
  2244. arma_extra_debug_sigprint();
  2245. const bool row_all = row_span.whole;
  2246. const uword local_n_rows = n_rows;
  2247. const uword in_row1 = row_all ? 0 : row_span.a;
  2248. const uword in_row2 = row_span.b;
  2249. const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
  2250. arma_debug_check
  2251. (
  2252. (col_num >= n_cols)
  2253. ||
  2254. ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
  2255. ,
  2256. "Mat::operator(): indices out of bounds or incorrectly used"
  2257. );
  2258. return subview_col<eT>(*this, col_num, in_row1, submat_n_rows);
  2259. }
  2260. template<typename eT>
  2261. inline
  2262. const subview_col<eT>
  2263. Mat<eT>::operator()(const span& row_span, const uword col_num) const
  2264. {
  2265. arma_extra_debug_sigprint();
  2266. const bool row_all = row_span.whole;
  2267. const uword local_n_rows = n_rows;
  2268. const uword in_row1 = row_all ? 0 : row_span.a;
  2269. const uword in_row2 = row_span.b;
  2270. const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
  2271. arma_debug_check
  2272. (
  2273. (col_num >= n_cols)
  2274. ||
  2275. ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
  2276. ,
  2277. "Mat::operator(): indices out of bounds or incorrectly used"
  2278. );
  2279. return subview_col<eT>(*this, col_num, in_row1, submat_n_rows);
  2280. }
  2281. //! create a Col object which uses memory from an existing matrix object.
  2282. //! this approach is currently not alias safe
  2283. //! and does not take into account that the parent matrix object could be deleted.
  2284. //! if deleted memory is accessed by the created Col object,
  2285. //! it will cause memory corruption and/or a crash
  2286. template<typename eT>
  2287. inline
  2288. Col<eT>
  2289. Mat<eT>::unsafe_col(const uword col_num)
  2290. {
  2291. arma_extra_debug_sigprint();
  2292. arma_debug_check( col_num >= n_cols, "Mat::unsafe_col(): index out of bounds");
  2293. return Col<eT>(colptr(col_num), n_rows, false, true);
  2294. }
  2295. //! create a Col object which uses memory from an existing matrix object.
  2296. //! this approach is currently not alias safe
  2297. //! and does not take into account that the parent matrix object could be deleted.
  2298. //! if deleted memory is accessed by the created Col object,
  2299. //! it will cause memory corruption and/or a crash
  2300. template<typename eT>
  2301. inline
  2302. const Col<eT>
  2303. Mat<eT>::unsafe_col(const uword col_num) const
  2304. {
  2305. arma_extra_debug_sigprint();
  2306. arma_debug_check( col_num >= n_cols, "Mat::unsafe_col(): index out of bounds");
  2307. typedef const Col<eT> out_type;
  2308. return out_type(const_cast<eT*>(colptr(col_num)), n_rows, false, true);
  2309. }
  2310. //! creation of subview (submatrix comprised of specified row vectors)
  2311. template<typename eT>
  2312. arma_inline
  2313. subview<eT>
  2314. Mat<eT>::rows(const uword in_row1, const uword in_row2)
  2315. {
  2316. arma_extra_debug_sigprint();
  2317. arma_debug_check
  2318. (
  2319. (in_row1 > in_row2) || (in_row2 >= n_rows),
  2320. "Mat::rows(): indices out of bounds or incorrectly used"
  2321. );
  2322. const uword subview_n_rows = in_row2 - in_row1 + 1;
  2323. return subview<eT>(*this, in_row1, 0, subview_n_rows, n_cols );
  2324. }
  2325. //! creation of subview (submatrix comprised of specified row vectors)
  2326. template<typename eT>
  2327. arma_inline
  2328. const subview<eT>
  2329. Mat<eT>::rows(const uword in_row1, const uword in_row2) const
  2330. {
  2331. arma_extra_debug_sigprint();
  2332. arma_debug_check
  2333. (
  2334. (in_row1 > in_row2) || (in_row2 >= n_rows),
  2335. "Mat::rows(): indices out of bounds or incorrectly used"
  2336. );
  2337. const uword subview_n_rows = in_row2 - in_row1 + 1;
  2338. return subview<eT>(*this, in_row1, 0, subview_n_rows, n_cols );
  2339. }
  2340. //! creation of subview (submatrix comprised of specified column vectors)
  2341. template<typename eT>
  2342. arma_inline
  2343. subview<eT>
  2344. Mat<eT>::cols(const uword in_col1, const uword in_col2)
  2345. {
  2346. arma_extra_debug_sigprint();
  2347. arma_debug_check
  2348. (
  2349. (in_col1 > in_col2) || (in_col2 >= n_cols),
  2350. "Mat::cols(): indices out of bounds or incorrectly used"
  2351. );
  2352. const uword subview_n_cols = in_col2 - in_col1 + 1;
  2353. return subview<eT>(*this, 0, in_col1, n_rows, subview_n_cols);
  2354. }
  2355. //! creation of subview (submatrix comprised of specified column vectors)
  2356. template<typename eT>
  2357. arma_inline
  2358. const subview<eT>
  2359. Mat<eT>::cols(const uword in_col1, const uword in_col2) const
  2360. {
  2361. arma_extra_debug_sigprint();
  2362. arma_debug_check
  2363. (
  2364. (in_col1 > in_col2) || (in_col2 >= n_cols),
  2365. "Mat::cols(): indices out of bounds or incorrectly used"
  2366. );
  2367. const uword subview_n_cols = in_col2 - in_col1 + 1;
  2368. return subview<eT>(*this, 0, in_col1, n_rows, subview_n_cols);
  2369. }
  2370. //! creation of subview (submatrix comprised of specified row vectors)
  2371. template<typename eT>
  2372. inline
  2373. subview<eT>
  2374. Mat<eT>::rows(const span& row_span)
  2375. {
  2376. arma_extra_debug_sigprint();
  2377. const bool row_all = row_span.whole;
  2378. const uword local_n_rows = n_rows;
  2379. const uword in_row1 = row_all ? 0 : row_span.a;
  2380. const uword in_row2 = row_span.b;
  2381. const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
  2382. arma_debug_check
  2383. (
  2384. ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
  2385. ,
  2386. "Mat::rows(): indices out of bounds or incorrectly used"
  2387. );
  2388. return subview<eT>(*this, in_row1, 0, submat_n_rows, n_cols);
  2389. }
  2390. //! creation of subview (submatrix comprised of specified row vectors)
  2391. template<typename eT>
  2392. inline
  2393. const subview<eT>
  2394. Mat<eT>::rows(const span& row_span) const
  2395. {
  2396. arma_extra_debug_sigprint();
  2397. const bool row_all = row_span.whole;
  2398. const uword local_n_rows = n_rows;
  2399. const uword in_row1 = row_all ? 0 : row_span.a;
  2400. const uword in_row2 = row_span.b;
  2401. const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
  2402. arma_debug_check
  2403. (
  2404. ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
  2405. ,
  2406. "Mat::rows(): indices out of bounds or incorrectly used"
  2407. );
  2408. return subview<eT>(*this, in_row1, 0, submat_n_rows, n_cols);
  2409. }
  2410. //! creation of subview (submatrix comprised of specified column vectors)
  2411. template<typename eT>
  2412. arma_inline
  2413. subview<eT>
  2414. Mat<eT>::cols(const span& col_span)
  2415. {
  2416. arma_extra_debug_sigprint();
  2417. const bool col_all = col_span.whole;
  2418. const uword local_n_cols = n_cols;
  2419. const uword in_col1 = col_all ? 0 : col_span.a;
  2420. const uword in_col2 = col_span.b;
  2421. const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
  2422. arma_debug_check
  2423. (
  2424. ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
  2425. ,
  2426. "Mat::cols(): indices out of bounds or incorrectly used"
  2427. );
  2428. return subview<eT>(*this, 0, in_col1, n_rows, submat_n_cols);
  2429. }
  2430. //! creation of subview (submatrix comprised of specified column vectors)
  2431. template<typename eT>
  2432. arma_inline
  2433. const subview<eT>
  2434. Mat<eT>::cols(const span& col_span) const
  2435. {
  2436. arma_extra_debug_sigprint();
  2437. const bool col_all = col_span.whole;
  2438. const uword local_n_cols = n_cols;
  2439. const uword in_col1 = col_all ? 0 : col_span.a;
  2440. const uword in_col2 = col_span.b;
  2441. const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
  2442. arma_debug_check
  2443. (
  2444. ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
  2445. ,
  2446. "Mat::cols(): indices out of bounds or incorrectly used"
  2447. );
  2448. return subview<eT>(*this, 0, in_col1, n_rows, submat_n_cols);
  2449. }
  2450. //! creation of subview (submatrix)
  2451. template<typename eT>
  2452. arma_inline
  2453. subview<eT>
  2454. Mat<eT>::submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2)
  2455. {
  2456. arma_extra_debug_sigprint();
  2457. arma_debug_check
  2458. (
  2459. (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
  2460. "Mat::submat(): indices out of bounds or incorrectly used"
  2461. );
  2462. const uword subview_n_rows = in_row2 - in_row1 + 1;
  2463. const uword subview_n_cols = in_col2 - in_col1 + 1;
  2464. return subview<eT>(*this, in_row1, in_col1, subview_n_rows, subview_n_cols);
  2465. }
  2466. //! creation of subview (generic submatrix)
  2467. template<typename eT>
  2468. arma_inline
  2469. const subview<eT>
  2470. Mat<eT>::submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const
  2471. {
  2472. arma_extra_debug_sigprint();
  2473. arma_debug_check
  2474. (
  2475. (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
  2476. "Mat::submat(): indices out of bounds or incorrectly used"
  2477. );
  2478. const uword subview_n_rows = in_row2 - in_row1 + 1;
  2479. const uword subview_n_cols = in_col2 - in_col1 + 1;
  2480. return subview<eT>(*this, in_row1, in_col1, subview_n_rows, subview_n_cols);
  2481. }
  2482. //! creation of subview (submatrix)
  2483. template<typename eT>
  2484. arma_inline
  2485. subview<eT>
  2486. Mat<eT>::submat(const uword in_row1, const uword in_col1, const SizeMat& s)
  2487. {
  2488. arma_extra_debug_sigprint();
  2489. const uword l_n_rows = n_rows;
  2490. const uword l_n_cols = n_cols;
  2491. const uword s_n_rows = s.n_rows;
  2492. const uword s_n_cols = s.n_cols;
  2493. arma_debug_check
  2494. (
  2495. ((in_row1 >= l_n_rows) || (in_col1 >= l_n_cols) || ((in_row1 + s_n_rows) > l_n_rows) || ((in_col1 + s_n_cols) > l_n_cols)),
  2496. "Mat::submat(): indices or size out of bounds"
  2497. );
  2498. return subview<eT>(*this, in_row1, in_col1, s_n_rows, s_n_cols);
  2499. }
  2500. //! creation of subview (submatrix)
  2501. template<typename eT>
  2502. arma_inline
  2503. const subview<eT>
  2504. Mat<eT>::submat(const uword in_row1, const uword in_col1, const SizeMat& s) const
  2505. {
  2506. arma_extra_debug_sigprint();
  2507. const uword l_n_rows = n_rows;
  2508. const uword l_n_cols = n_cols;
  2509. const uword s_n_rows = s.n_rows;
  2510. const uword s_n_cols = s.n_cols;
  2511. arma_debug_check
  2512. (
  2513. ((in_row1 >= l_n_rows) || (in_col1 >= l_n_cols) || ((in_row1 + s_n_rows) > l_n_rows) || ((in_col1 + s_n_cols) > l_n_cols)),
  2514. "Mat::submat(): indices or size out of bounds"
  2515. );
  2516. return subview<eT>(*this, in_row1, in_col1, s_n_rows, s_n_cols);
  2517. }
  2518. //! creation of subview (submatrix)
  2519. template<typename eT>
  2520. inline
  2521. subview<eT>
  2522. Mat<eT>::submat(const span& row_span, const span& col_span)
  2523. {
  2524. arma_extra_debug_sigprint();
  2525. const bool row_all = row_span.whole;
  2526. const bool col_all = col_span.whole;
  2527. const uword local_n_rows = n_rows;
  2528. const uword local_n_cols = n_cols;
  2529. const uword in_row1 = row_all ? 0 : row_span.a;
  2530. const uword in_row2 = row_span.b;
  2531. const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
  2532. const uword in_col1 = col_all ? 0 : col_span.a;
  2533. const uword in_col2 = col_span.b;
  2534. const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
  2535. arma_debug_check
  2536. (
  2537. ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
  2538. ||
  2539. ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
  2540. ,
  2541. "Mat::submat(): indices out of bounds or incorrectly used"
  2542. );
  2543. return subview<eT>(*this, in_row1, in_col1, submat_n_rows, submat_n_cols);
  2544. }
  2545. //! creation of subview (generic submatrix)
  2546. template<typename eT>
  2547. inline
  2548. const subview<eT>
  2549. Mat<eT>::submat(const span& row_span, const span& col_span) const
  2550. {
  2551. arma_extra_debug_sigprint();
  2552. const bool row_all = row_span.whole;
  2553. const bool col_all = col_span.whole;
  2554. const uword local_n_rows = n_rows;
  2555. const uword local_n_cols = n_cols;
  2556. const uword in_row1 = row_all ? 0 : row_span.a;
  2557. const uword in_row2 = row_span.b;
  2558. const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
  2559. const uword in_col1 = col_all ? 0 : col_span.a;
  2560. const uword in_col2 = col_span.b;
  2561. const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
  2562. arma_debug_check
  2563. (
  2564. ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
  2565. ||
  2566. ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
  2567. ,
  2568. "Mat::submat(): indices out of bounds or incorrectly used"
  2569. );
  2570. return subview<eT>(*this, in_row1, in_col1, submat_n_rows, submat_n_cols);
  2571. }
  2572. template<typename eT>
  2573. inline
  2574. subview<eT>
  2575. Mat<eT>::operator()(const span& row_span, const span& col_span)
  2576. {
  2577. arma_extra_debug_sigprint();
  2578. return (*this).submat(row_span, col_span);
  2579. }
  2580. template<typename eT>
  2581. inline
  2582. const subview<eT>
  2583. Mat<eT>::operator()(const span& row_span, const span& col_span) const
  2584. {
  2585. arma_extra_debug_sigprint();
  2586. return (*this).submat(row_span, col_span);
  2587. }
  2588. template<typename eT>
  2589. inline
  2590. subview<eT>
  2591. Mat<eT>::operator()(const uword in_row1, const uword in_col1, const SizeMat& s)
  2592. {
  2593. arma_extra_debug_sigprint();
  2594. return (*this).submat(in_row1, in_col1, s);
  2595. }
  2596. template<typename eT>
  2597. inline
  2598. const subview<eT>
  2599. Mat<eT>::operator()(const uword in_row1, const uword in_col1, const SizeMat& s) const
  2600. {
  2601. arma_extra_debug_sigprint();
  2602. return (*this).submat(in_row1, in_col1, s);
  2603. }
  2604. template<typename eT>
  2605. inline
  2606. subview<eT>
  2607. Mat<eT>::head_rows(const uword N)
  2608. {
  2609. arma_extra_debug_sigprint();
  2610. arma_debug_check( (N > n_rows), "Mat::head_rows(): size out of bounds");
  2611. return subview<eT>(*this, 0, 0, N, n_cols);
  2612. }
  2613. template<typename eT>
  2614. inline
  2615. const subview<eT>
  2616. Mat<eT>::head_rows(const uword N) const
  2617. {
  2618. arma_extra_debug_sigprint();
  2619. arma_debug_check( (N > n_rows), "Mat::head_rows(): size out of bounds");
  2620. return subview<eT>(*this, 0, 0, N, n_cols);
  2621. }
  2622. template<typename eT>
  2623. inline
  2624. subview<eT>
  2625. Mat<eT>::tail_rows(const uword N)
  2626. {
  2627. arma_extra_debug_sigprint();
  2628. arma_debug_check( (N > n_rows), "Mat::tail_rows(): size out of bounds");
  2629. const uword start_row = n_rows - N;
  2630. return subview<eT>(*this, start_row, 0, N, n_cols);
  2631. }
  2632. template<typename eT>
  2633. inline
  2634. const subview<eT>
  2635. Mat<eT>::tail_rows(const uword N) const
  2636. {
  2637. arma_extra_debug_sigprint();
  2638. arma_debug_check( (N > n_rows), "Mat::tail_rows(): size out of bounds");
  2639. const uword start_row = n_rows - N;
  2640. return subview<eT>(*this, start_row, 0, N, n_cols);
  2641. }
  2642. template<typename eT>
  2643. inline
  2644. subview<eT>
  2645. Mat<eT>::head_cols(const uword N)
  2646. {
  2647. arma_extra_debug_sigprint();
  2648. arma_debug_check( (N > n_cols), "Mat::head_cols(): size out of bounds");
  2649. return subview<eT>(*this, 0, 0, n_rows, N);
  2650. }
  2651. template<typename eT>
  2652. inline
  2653. const subview<eT>
  2654. Mat<eT>::head_cols(const uword N) const
  2655. {
  2656. arma_extra_debug_sigprint();
  2657. arma_debug_check( (N > n_cols), "Mat::head_cols(): size out of bounds");
  2658. return subview<eT>(*this, 0, 0, n_rows, N);
  2659. }
  2660. template<typename eT>
  2661. inline
  2662. subview<eT>
  2663. Mat<eT>::tail_cols(const uword N)
  2664. {
  2665. arma_extra_debug_sigprint();
  2666. arma_debug_check( (N > n_cols), "Mat::tail_cols(): size out of bounds");
  2667. const uword start_col = n_cols - N;
  2668. return subview<eT>(*this, 0, start_col, n_rows, N);
  2669. }
  2670. template<typename eT>
  2671. inline
  2672. const subview<eT>
  2673. Mat<eT>::tail_cols(const uword N) const
  2674. {
  2675. arma_extra_debug_sigprint();
  2676. arma_debug_check( (N > n_cols), "Mat::tail_cols(): size out of bounds");
  2677. const uword start_col = n_cols - N;
  2678. return subview<eT>(*this, 0, start_col, n_rows, N);
  2679. }
  2680. template<typename eT>
  2681. template<typename T1>
  2682. arma_inline
  2683. subview_elem1<eT,T1>
  2684. Mat<eT>::elem(const Base<uword,T1>& a)
  2685. {
  2686. arma_extra_debug_sigprint();
  2687. return subview_elem1<eT,T1>(*this, a);
  2688. }
  2689. template<typename eT>
  2690. template<typename T1>
  2691. arma_inline
  2692. const subview_elem1<eT,T1>
  2693. Mat<eT>::elem(const Base<uword,T1>& a) const
  2694. {
  2695. arma_extra_debug_sigprint();
  2696. return subview_elem1<eT,T1>(*this, a);
  2697. }
  2698. template<typename eT>
  2699. template<typename T1>
  2700. arma_inline
  2701. subview_elem1<eT,T1>
  2702. Mat<eT>::operator()(const Base<uword,T1>& a)
  2703. {
  2704. arma_extra_debug_sigprint();
  2705. return subview_elem1<eT,T1>(*this, a);
  2706. }
  2707. template<typename eT>
  2708. template<typename T1>
  2709. arma_inline
  2710. const subview_elem1<eT,T1>
  2711. Mat<eT>::operator()(const Base<uword,T1>& a) const
  2712. {
  2713. arma_extra_debug_sigprint();
  2714. return subview_elem1<eT,T1>(*this, a);
  2715. }
  2716. template<typename eT>
  2717. template<typename T1, typename T2>
  2718. arma_inline
  2719. subview_elem2<eT,T1,T2>
  2720. Mat<eT>::elem(const Base<uword,T1>& ri, const Base<uword,T2>& ci)
  2721. {
  2722. arma_extra_debug_sigprint();
  2723. return subview_elem2<eT,T1,T2>(*this, ri, ci, false, false);
  2724. }
  2725. template<typename eT>
  2726. template<typename T1, typename T2>
  2727. arma_inline
  2728. const subview_elem2<eT,T1,T2>
  2729. Mat<eT>::elem(const Base<uword,T1>& ri, const Base<uword,T2>& ci) const
  2730. {
  2731. arma_extra_debug_sigprint();
  2732. return subview_elem2<eT,T1,T2>(*this, ri, ci, false, false);
  2733. }
  2734. template<typename eT>
  2735. template<typename T1, typename T2>
  2736. arma_inline
  2737. subview_elem2<eT,T1,T2>
  2738. Mat<eT>::submat(const Base<uword,T1>& ri, const Base<uword,T2>& ci)
  2739. {
  2740. arma_extra_debug_sigprint();
  2741. return subview_elem2<eT,T1,T2>(*this, ri, ci, false, false);
  2742. }
  2743. template<typename eT>
  2744. template<typename T1, typename T2>
  2745. arma_inline
  2746. const subview_elem2<eT,T1,T2>
  2747. Mat<eT>::submat(const Base<uword,T1>& ri, const Base<uword,T2>& ci) const
  2748. {
  2749. arma_extra_debug_sigprint();
  2750. return subview_elem2<eT,T1,T2>(*this, ri, ci, false, false);
  2751. }
  2752. template<typename eT>
  2753. template<typename T1, typename T2>
  2754. arma_inline
  2755. subview_elem2<eT,T1,T2>
  2756. Mat<eT>::operator()(const Base<uword,T1>& ri, const Base<uword,T2>& ci)
  2757. {
  2758. arma_extra_debug_sigprint();
  2759. return subview_elem2<eT,T1,T2>(*this, ri, ci, false, false);
  2760. }
  2761. template<typename eT>
  2762. template<typename T1, typename T2>
  2763. arma_inline
  2764. const subview_elem2<eT,T1,T2>
  2765. Mat<eT>::operator()(const Base<uword,T1>& ri, const Base<uword,T2>& ci) const
  2766. {
  2767. arma_extra_debug_sigprint();
  2768. return subview_elem2<eT,T1,T2>(*this, ri, ci, false, false);
  2769. }
  2770. template<typename eT>
  2771. template<typename T1>
  2772. arma_inline
  2773. subview_elem2<eT,T1,T1>
  2774. Mat<eT>::rows(const Base<uword,T1>& ri)
  2775. {
  2776. arma_extra_debug_sigprint();
  2777. return subview_elem2<eT,T1,T1>(*this, ri, ri, false, true);
  2778. }
  2779. template<typename eT>
  2780. template<typename T1>
  2781. arma_inline
  2782. const subview_elem2<eT,T1,T1>
  2783. Mat<eT>::rows(const Base<uword,T1>& ri) const
  2784. {
  2785. arma_extra_debug_sigprint();
  2786. return subview_elem2<eT,T1,T1>(*this, ri, ri, false, true);
  2787. }
  2788. template<typename eT>
  2789. template<typename T2>
  2790. arma_inline
  2791. subview_elem2<eT,T2,T2>
  2792. Mat<eT>::cols(const Base<uword,T2>& ci)
  2793. {
  2794. arma_extra_debug_sigprint();
  2795. return subview_elem2<eT,T2,T2>(*this, ci, ci, true, false);
  2796. }
  2797. template<typename eT>
  2798. template<typename T2>
  2799. arma_inline
  2800. const subview_elem2<eT,T2,T2>
  2801. Mat<eT>::cols(const Base<uword,T2>& ci) const
  2802. {
  2803. arma_extra_debug_sigprint();
  2804. return subview_elem2<eT,T2,T2>(*this, ci, ci, true, false);
  2805. }
  2806. template<typename eT>
  2807. arma_inline
  2808. subview_each1< Mat<eT>, 0 >
  2809. Mat<eT>::each_col()
  2810. {
  2811. arma_extra_debug_sigprint();
  2812. return subview_each1< Mat<eT>, 0>(*this);
  2813. }
  2814. template<typename eT>
  2815. arma_inline
  2816. subview_each1< Mat<eT>, 1 >
  2817. Mat<eT>::each_row()
  2818. {
  2819. arma_extra_debug_sigprint();
  2820. return subview_each1< Mat<eT>, 1>(*this);
  2821. }
  2822. template<typename eT>
  2823. arma_inline
  2824. const subview_each1< Mat<eT>, 0 >
  2825. Mat<eT>::each_col() const
  2826. {
  2827. arma_extra_debug_sigprint();
  2828. return subview_each1< Mat<eT>, 0>(*this);
  2829. }
  2830. template<typename eT>
  2831. arma_inline
  2832. const subview_each1< Mat<eT>, 1 >
  2833. Mat<eT>::each_row() const
  2834. {
  2835. arma_extra_debug_sigprint();
  2836. return subview_each1< Mat<eT>, 1>(*this);
  2837. }
  2838. template<typename eT>
  2839. template<typename T1>
  2840. inline
  2841. subview_each2< Mat<eT>, 0, T1 >
  2842. Mat<eT>::each_col(const Base<uword, T1>& indices)
  2843. {
  2844. arma_extra_debug_sigprint();
  2845. return subview_each2< Mat<eT>, 0, T1 >(*this, indices);
  2846. }
  2847. template<typename eT>
  2848. template<typename T1>
  2849. inline
  2850. subview_each2< Mat<eT>, 1, T1 >
  2851. Mat<eT>::each_row(const Base<uword, T1>& indices)
  2852. {
  2853. arma_extra_debug_sigprint();
  2854. return subview_each2< Mat<eT>, 1, T1 >(*this, indices);
  2855. }
  2856. template<typename eT>
  2857. template<typename T1>
  2858. inline
  2859. const subview_each2< Mat<eT>, 0, T1 >
  2860. Mat<eT>::each_col(const Base<uword, T1>& indices) const
  2861. {
  2862. arma_extra_debug_sigprint();
  2863. return subview_each2< Mat<eT>, 0, T1 >(*this, indices);
  2864. }
  2865. template<typename eT>
  2866. template<typename T1>
  2867. inline
  2868. const subview_each2< Mat<eT>, 1, T1 >
  2869. Mat<eT>::each_row(const Base<uword, T1>& indices) const
  2870. {
  2871. arma_extra_debug_sigprint();
  2872. return subview_each2< Mat<eT>, 1, T1 >(*this, indices);
  2873. }
  2874. #if defined(ARMA_USE_CXX11)
  2875. //! apply a lambda function to each column, where each column is interpreted as a column vector
  2876. template<typename eT>
  2877. inline
  2878. const Mat<eT>&
  2879. Mat<eT>::each_col(const std::function< void(Col<eT>&) >& F)
  2880. {
  2881. arma_extra_debug_sigprint();
  2882. for(uword ii=0; ii < n_cols; ++ii)
  2883. {
  2884. Col<eT> tmp(colptr(ii), n_rows, false, true);
  2885. F(tmp);
  2886. }
  2887. return *this;
  2888. }
  2889. template<typename eT>
  2890. inline
  2891. const Mat<eT>&
  2892. Mat<eT>::each_col(const std::function< void(const Col<eT>&) >& F) const
  2893. {
  2894. arma_extra_debug_sigprint();
  2895. for(uword ii=0; ii < n_cols; ++ii)
  2896. {
  2897. const Col<eT> tmp(const_cast<eT*>(colptr(ii)), n_rows, false, true);
  2898. F(tmp);
  2899. }
  2900. return *this;
  2901. }
  2902. //! apply a lambda function to each row, where each row is interpreted as a row vector
  2903. template<typename eT>
  2904. inline
  2905. const Mat<eT>&
  2906. Mat<eT>::each_row(const std::function< void(Row<eT>&) >& F)
  2907. {
  2908. arma_extra_debug_sigprint();
  2909. podarray<eT> array1(n_cols);
  2910. podarray<eT> array2(n_cols);
  2911. Row<eT> tmp1( array1.memptr(), n_cols, false, true );
  2912. Row<eT> tmp2( array2.memptr(), n_cols, false, true );
  2913. eT* tmp1_mem = tmp1.memptr();
  2914. eT* tmp2_mem = tmp2.memptr();
  2915. uword ii, jj;
  2916. for(ii=0, jj=1; jj < n_rows; ii+=2, jj+=2)
  2917. {
  2918. for(uword col_id = 0; col_id < n_cols; ++col_id)
  2919. {
  2920. const eT* col_mem = colptr(col_id);
  2921. tmp1_mem[col_id] = col_mem[ii];
  2922. tmp2_mem[col_id] = col_mem[jj];
  2923. }
  2924. F(tmp1);
  2925. F(tmp2);
  2926. for(uword col_id = 0; col_id < n_cols; ++col_id)
  2927. {
  2928. eT* col_mem = colptr(col_id);
  2929. col_mem[ii] = tmp1_mem[col_id];
  2930. col_mem[jj] = tmp2_mem[col_id];
  2931. }
  2932. }
  2933. if(ii < n_rows)
  2934. {
  2935. tmp1 = (*this).row(ii);
  2936. F(tmp1);
  2937. (*this).row(ii) = tmp1;
  2938. }
  2939. return *this;
  2940. }
  2941. template<typename eT>
  2942. inline
  2943. const Mat<eT>&
  2944. Mat<eT>::each_row(const std::function< void(const Row<eT>&) >& F) const
  2945. {
  2946. arma_extra_debug_sigprint();
  2947. podarray<eT> array1(n_cols);
  2948. podarray<eT> array2(n_cols);
  2949. Row<eT> tmp1( array1.memptr(), n_cols, false, true );
  2950. Row<eT> tmp2( array2.memptr(), n_cols, false, true );
  2951. eT* tmp1_mem = tmp1.memptr();
  2952. eT* tmp2_mem = tmp2.memptr();
  2953. uword ii, jj;
  2954. for(ii=0, jj=1; jj < n_rows; ii+=2, jj+=2)
  2955. {
  2956. for(uword col_id = 0; col_id < n_cols; ++col_id)
  2957. {
  2958. const eT* col_mem = colptr(col_id);
  2959. tmp1_mem[col_id] = col_mem[ii];
  2960. tmp2_mem[col_id] = col_mem[jj];
  2961. }
  2962. F(tmp1);
  2963. F(tmp2);
  2964. }
  2965. if(ii < n_rows)
  2966. {
  2967. tmp1 = (*this).row(ii);
  2968. F(tmp1);
  2969. }
  2970. return *this;
  2971. }
  2972. #endif
  2973. //! creation of diagview (diagonal)
  2974. template<typename eT>
  2975. arma_inline
  2976. diagview<eT>
  2977. Mat<eT>::diag(const sword in_id)
  2978. {
  2979. arma_extra_debug_sigprint();
  2980. const uword row_offset = (in_id < 0) ? uword(-in_id) : 0;
  2981. const uword col_offset = (in_id > 0) ? uword( in_id) : 0;
  2982. arma_debug_check
  2983. (
  2984. ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)),
  2985. "Mat::diag(): requested diagonal out of bounds"
  2986. );
  2987. const uword len = (std::min)(n_rows - row_offset, n_cols - col_offset);
  2988. return diagview<eT>(*this, row_offset, col_offset, len);
  2989. }
  2990. //! creation of diagview (diagonal)
  2991. template<typename eT>
  2992. arma_inline
  2993. const diagview<eT>
  2994. Mat<eT>::diag(const sword in_id) const
  2995. {
  2996. arma_extra_debug_sigprint();
  2997. const uword row_offset = uword( (in_id < 0) ? -in_id : 0 );
  2998. const uword col_offset = uword( (in_id > 0) ? in_id : 0 );
  2999. arma_debug_check
  3000. (
  3001. ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)),
  3002. "Mat::diag(): requested diagonal out of bounds"
  3003. );
  3004. const uword len = (std::min)(n_rows - row_offset, n_cols - col_offset);
  3005. return diagview<eT>(*this, row_offset, col_offset, len);
  3006. }
  3007. template<typename eT>
  3008. inline
  3009. void
  3010. Mat<eT>::swap_rows(const uword in_row1, const uword in_row2)
  3011. {
  3012. arma_extra_debug_sigprint();
  3013. const uword local_n_rows = n_rows;
  3014. const uword local_n_cols = n_cols;
  3015. arma_debug_check
  3016. (
  3017. (in_row1 >= local_n_rows) || (in_row2 >= local_n_rows),
  3018. "Mat::swap_rows(): index out of bounds"
  3019. );
  3020. if(n_elem > 0)
  3021. {
  3022. for(uword ucol=0; ucol < local_n_cols; ++ucol)
  3023. {
  3024. const uword offset = ucol * local_n_rows;
  3025. const uword pos1 = in_row1 + offset;
  3026. const uword pos2 = in_row2 + offset;
  3027. std::swap( access::rw(mem[pos1]), access::rw(mem[pos2]) );
  3028. }
  3029. }
  3030. }
  3031. template<typename eT>
  3032. inline
  3033. void
  3034. Mat<eT>::swap_cols(const uword in_colA, const uword in_colB)
  3035. {
  3036. arma_extra_debug_sigprint();
  3037. const uword local_n_rows = n_rows;
  3038. const uword local_n_cols = n_cols;
  3039. arma_debug_check
  3040. (
  3041. (in_colA >= local_n_cols) || (in_colB >= local_n_cols),
  3042. "Mat::swap_cols(): index out of bounds"
  3043. );
  3044. if(n_elem > 0)
  3045. {
  3046. eT* ptrA = colptr(in_colA);
  3047. eT* ptrB = colptr(in_colB);
  3048. eT tmp_i;
  3049. eT tmp_j;
  3050. uword iq,jq;
  3051. for(iq=0, jq=1; jq < local_n_rows; iq+=2, jq+=2)
  3052. {
  3053. tmp_i = ptrA[iq];
  3054. tmp_j = ptrA[jq];
  3055. ptrA[iq] = ptrB[iq];
  3056. ptrA[jq] = ptrB[jq];
  3057. ptrB[iq] = tmp_i;
  3058. ptrB[jq] = tmp_j;
  3059. }
  3060. if(iq < local_n_rows)
  3061. {
  3062. std::swap( ptrA[iq], ptrB[iq] );
  3063. }
  3064. }
  3065. }
  3066. //! remove specified row
  3067. template<typename eT>
  3068. inline
  3069. void
  3070. Mat<eT>::shed_row(const uword row_num)
  3071. {
  3072. arma_extra_debug_sigprint();
  3073. arma_debug_check( row_num >= n_rows, "Mat::shed_row(): index out of bounds");
  3074. shed_rows(row_num, row_num);
  3075. }
  3076. //! remove specified column
  3077. template<typename eT>
  3078. inline
  3079. void
  3080. Mat<eT>::shed_col(const uword col_num)
  3081. {
  3082. arma_extra_debug_sigprint();
  3083. arma_debug_check( col_num >= n_cols, "Mat::shed_col(): index out of bounds");
  3084. shed_cols(col_num, col_num);
  3085. }
  3086. //! remove specified rows
  3087. template<typename eT>
  3088. inline
  3089. void
  3090. Mat<eT>::shed_rows(const uword in_row1, const uword in_row2)
  3091. {
  3092. arma_extra_debug_sigprint();
  3093. arma_debug_check
  3094. (
  3095. (in_row1 > in_row2) || (in_row2 >= n_rows),
  3096. "Mat::shed_rows(): indices out of bounds or incorrectly used"
  3097. );
  3098. const uword n_keep_front = in_row1;
  3099. const uword n_keep_back = n_rows - (in_row2 + 1);
  3100. Mat<eT> X(n_keep_front + n_keep_back, n_cols);
  3101. if(n_keep_front > 0)
  3102. {
  3103. X.rows( 0, (n_keep_front-1) ) = rows( 0, (in_row1-1) );
  3104. }
  3105. if(n_keep_back > 0)
  3106. {
  3107. X.rows( n_keep_front, (n_keep_front+n_keep_back-1) ) = rows( (in_row2+1), (n_rows-1) );
  3108. }
  3109. steal_mem(X);
  3110. }
  3111. //! remove specified columns
  3112. template<typename eT>
  3113. inline
  3114. void
  3115. Mat<eT>::shed_cols(const uword in_col1, const uword in_col2)
  3116. {
  3117. arma_extra_debug_sigprint();
  3118. arma_debug_check
  3119. (
  3120. (in_col1 > in_col2) || (in_col2 >= n_cols),
  3121. "Mat::shed_cols(): indices out of bounds or incorrectly used"
  3122. );
  3123. const uword n_keep_front = in_col1;
  3124. const uword n_keep_back = n_cols - (in_col2 + 1);
  3125. Mat<eT> X(n_rows, n_keep_front + n_keep_back);
  3126. if(n_keep_front > 0)
  3127. {
  3128. X.cols( 0, (n_keep_front-1) ) = cols( 0, (in_col1-1) );
  3129. }
  3130. if(n_keep_back > 0)
  3131. {
  3132. X.cols( n_keep_front, (n_keep_front+n_keep_back-1) ) = cols( (in_col2+1), (n_cols-1) );
  3133. }
  3134. steal_mem(X);
  3135. }
  3136. //! remove specified rows
  3137. template<typename eT>
  3138. template<typename T1>
  3139. inline
  3140. void
  3141. Mat<eT>::shed_rows(const Base<uword, T1>& indices)
  3142. {
  3143. arma_extra_debug_sigprint();
  3144. const unwrap_check_mixed<T1> U(indices.get_ref(), *this);
  3145. const Mat<uword>& tmp1 = U.M;
  3146. arma_debug_check( ((tmp1.is_vec() == false) && (tmp1.is_empty() == false)), "Mat::shed_rows(): list of indices must be a vector" );
  3147. if(tmp1.is_empty()) { return; }
  3148. const Col<uword> tmp2(const_cast<uword*>(tmp1.memptr()), tmp1.n_elem, false, false);
  3149. const Col<uword>& rows_to_shed = (tmp2.is_sorted("strictascend") == false)
  3150. ? Col<uword>(unique(tmp2))
  3151. : Col<uword>(const_cast<uword*>(tmp2.memptr()), tmp2.n_elem, false, false);
  3152. const uword* rows_to_shed_mem = rows_to_shed.memptr();
  3153. const uword N = rows_to_shed.n_elem;
  3154. if(arma_config::debug)
  3155. {
  3156. for(uword i=0; i<N; ++i)
  3157. {
  3158. arma_debug_check( (rows_to_shed_mem[i] >= n_rows), "Mat::shed_rows(): indices out of bounds" );
  3159. }
  3160. }
  3161. Col<uword> tmp3(n_rows);
  3162. uword* tmp3_mem = tmp3.memptr();
  3163. uword i = 0;
  3164. uword count = 0;
  3165. for(uword j=0; j < n_rows; ++j)
  3166. {
  3167. if(i < N)
  3168. {
  3169. if( j != rows_to_shed_mem[i] )
  3170. {
  3171. tmp3_mem[count] = j;
  3172. ++count;
  3173. }
  3174. else
  3175. {
  3176. ++i;
  3177. }
  3178. }
  3179. else
  3180. {
  3181. tmp3_mem[count] = j;
  3182. ++count;
  3183. }
  3184. }
  3185. const Col<uword> rows_to_keep(tmp3.memptr(), count, false, false);
  3186. Mat<eT> X = (*this).rows(rows_to_keep);
  3187. steal_mem(X);
  3188. }
  3189. //! remove specified columns
  3190. template<typename eT>
  3191. template<typename T1>
  3192. inline
  3193. void
  3194. Mat<eT>::shed_cols(const Base<uword, T1>& indices)
  3195. {
  3196. arma_extra_debug_sigprint();
  3197. const unwrap_check_mixed<T1> U(indices.get_ref(), *this);
  3198. const Mat<uword>& tmp1 = U.M;
  3199. arma_debug_check( ((tmp1.is_vec() == false) && (tmp1.is_empty() == false)), "Mat::shed_cols(): list of indices must be a vector" );
  3200. if(tmp1.is_empty()) { return; }
  3201. const Col<uword> tmp2(const_cast<uword*>(tmp1.memptr()), tmp1.n_elem, false, false);
  3202. const Col<uword>& cols_to_shed = (tmp2.is_sorted("strictascend") == false)
  3203. ? Col<uword>(unique(tmp2))
  3204. : Col<uword>(const_cast<uword*>(tmp2.memptr()), tmp2.n_elem, false, false);
  3205. const uword* cols_to_shed_mem = cols_to_shed.memptr();
  3206. const uword N = cols_to_shed.n_elem;
  3207. if(arma_config::debug)
  3208. {
  3209. for(uword i=0; i<N; ++i)
  3210. {
  3211. arma_debug_check( (cols_to_shed_mem[i] >= n_cols), "Mat::shed_cols(): indices out of bounds" );
  3212. }
  3213. }
  3214. Col<uword> tmp3(n_cols);
  3215. uword* tmp3_mem = tmp3.memptr();
  3216. uword i = 0;
  3217. uword count = 0;
  3218. for(uword j=0; j < n_cols; ++j)
  3219. {
  3220. if(i < N)
  3221. {
  3222. if( j != cols_to_shed_mem[i] )
  3223. {
  3224. tmp3_mem[count] = j;
  3225. ++count;
  3226. }
  3227. else
  3228. {
  3229. ++i;
  3230. }
  3231. }
  3232. else
  3233. {
  3234. tmp3_mem[count] = j;
  3235. ++count;
  3236. }
  3237. }
  3238. const Col<uword> cols_to_keep(tmp3.memptr(), count, false, false);
  3239. Mat<eT> X = (*this).cols(cols_to_keep);
  3240. steal_mem(X);
  3241. }
  3242. //! insert N rows at the specified row position,
  3243. //! optionally setting the elements of the inserted rows to zero
  3244. template<typename eT>
  3245. inline
  3246. void
  3247. Mat<eT>::insert_rows(const uword row_num, const uword N, const bool set_to_zero)
  3248. {
  3249. arma_extra_debug_sigprint();
  3250. const uword t_n_rows = n_rows;
  3251. const uword t_n_cols = n_cols;
  3252. const uword A_n_rows = row_num;
  3253. const uword B_n_rows = t_n_rows - row_num;
  3254. // insertion at row_num == n_rows is in effect an append operation
  3255. arma_debug_check( (row_num > t_n_rows), "Mat::insert_rows(): index out of bounds");
  3256. if(N > 0)
  3257. {
  3258. Mat<eT> out(t_n_rows + N, t_n_cols);
  3259. if(A_n_rows > 0)
  3260. {
  3261. out.rows(0, A_n_rows-1) = rows(0, A_n_rows-1);
  3262. }
  3263. if(B_n_rows > 0)
  3264. {
  3265. out.rows(row_num + N, t_n_rows + N - 1) = rows(row_num, t_n_rows-1);
  3266. }
  3267. if(set_to_zero)
  3268. {
  3269. out.rows(row_num, row_num + N - 1).zeros();
  3270. }
  3271. steal_mem(out);
  3272. }
  3273. }
  3274. //! insert N columns at the specified column position,
  3275. //! optionally setting the elements of the inserted columns to zero
  3276. template<typename eT>
  3277. inline
  3278. void
  3279. Mat<eT>::insert_cols(const uword col_num, const uword N, const bool set_to_zero)
  3280. {
  3281. arma_extra_debug_sigprint();
  3282. const uword t_n_rows = n_rows;
  3283. const uword t_n_cols = n_cols;
  3284. const uword A_n_cols = col_num;
  3285. const uword B_n_cols = t_n_cols - col_num;
  3286. // insertion at col_num == n_cols is in effect an append operation
  3287. arma_debug_check( (col_num > t_n_cols), "Mat::insert_cols(): index out of bounds");
  3288. if(N > 0)
  3289. {
  3290. Mat<eT> out(t_n_rows, t_n_cols + N);
  3291. if(A_n_cols > 0)
  3292. {
  3293. out.cols(0, A_n_cols-1) = cols(0, A_n_cols-1);
  3294. }
  3295. if(B_n_cols > 0)
  3296. {
  3297. out.cols(col_num + N, t_n_cols + N - 1) = cols(col_num, t_n_cols-1);
  3298. }
  3299. if(set_to_zero)
  3300. {
  3301. out.cols(col_num, col_num + N - 1).zeros();
  3302. }
  3303. steal_mem(out);
  3304. }
  3305. }
  3306. //! insert the given object at the specified row position;
  3307. //! the given object must have the same number of columns as the matrix
  3308. template<typename eT>
  3309. template<typename T1>
  3310. inline
  3311. void
  3312. Mat<eT>::insert_rows(const uword row_num, const Base<eT,T1>& X)
  3313. {
  3314. arma_extra_debug_sigprint();
  3315. const unwrap<T1> tmp(X.get_ref());
  3316. const Mat<eT>& C = tmp.M;
  3317. const uword C_n_rows = C.n_rows;
  3318. const uword C_n_cols = C.n_cols;
  3319. const uword t_n_rows = n_rows;
  3320. const uword t_n_cols = n_cols;
  3321. const uword A_n_rows = row_num;
  3322. const uword B_n_rows = t_n_rows - row_num;
  3323. bool err_state = false;
  3324. char* err_msg = 0;
  3325. // insertion at row_num == n_rows is in effect an append operation
  3326. arma_debug_set_error
  3327. (
  3328. err_state,
  3329. err_msg,
  3330. (row_num > t_n_rows),
  3331. "Mat::insert_rows(): index out of bounds"
  3332. );
  3333. arma_debug_set_error
  3334. (
  3335. err_state,
  3336. err_msg,
  3337. ( (C_n_cols != t_n_cols) && ( (t_n_rows > 0) || (t_n_cols > 0) ) && ( (C_n_rows > 0) || (C_n_cols > 0) ) ),
  3338. "Mat::insert_rows(): given object has an incompatible number of columns"
  3339. );
  3340. arma_debug_check(err_state, err_msg);
  3341. if(C_n_rows > 0)
  3342. {
  3343. Mat<eT> out( t_n_rows + C_n_rows, (std::max)(t_n_cols, C_n_cols) );
  3344. if(t_n_cols > 0)
  3345. {
  3346. if(A_n_rows > 0)
  3347. {
  3348. out.rows(0, A_n_rows-1) = rows(0, A_n_rows-1);
  3349. }
  3350. if( (t_n_cols > 0) && (B_n_rows > 0) )
  3351. {
  3352. out.rows(row_num + C_n_rows, t_n_rows + C_n_rows - 1) = rows(row_num, t_n_rows - 1);
  3353. }
  3354. }
  3355. if(C_n_cols > 0)
  3356. {
  3357. out.rows(row_num, row_num + C_n_rows - 1) = C;
  3358. }
  3359. steal_mem(out);
  3360. }
  3361. }
  3362. //! insert the given object at the specified column position;
  3363. //! the given object must have the same number of rows as the matrix
  3364. template<typename eT>
  3365. template<typename T1>
  3366. inline
  3367. void
  3368. Mat<eT>::insert_cols(const uword col_num, const Base<eT,T1>& X)
  3369. {
  3370. arma_extra_debug_sigprint();
  3371. const unwrap<T1> tmp(X.get_ref());
  3372. const Mat<eT>& C = tmp.M;
  3373. const uword C_n_rows = C.n_rows;
  3374. const uword C_n_cols = C.n_cols;
  3375. const uword t_n_rows = n_rows;
  3376. const uword t_n_cols = n_cols;
  3377. const uword A_n_cols = col_num;
  3378. const uword B_n_cols = t_n_cols - col_num;
  3379. bool err_state = false;
  3380. char* err_msg = 0;
  3381. // insertion at col_num == n_cols is in effect an append operation
  3382. arma_debug_set_error
  3383. (
  3384. err_state,
  3385. err_msg,
  3386. (col_num > t_n_cols),
  3387. "Mat::insert_cols(): index out of bounds"
  3388. );
  3389. arma_debug_set_error
  3390. (
  3391. err_state,
  3392. err_msg,
  3393. ( (C_n_rows != t_n_rows) && ( (t_n_rows > 0) || (t_n_cols > 0) ) && ( (C_n_rows > 0) || (C_n_cols > 0) ) ),
  3394. "Mat::insert_cols(): given object has an incompatible number of rows"
  3395. );
  3396. arma_debug_check(err_state, err_msg);
  3397. if(C_n_cols > 0)
  3398. {
  3399. Mat<eT> out( (std::max)(t_n_rows, C_n_rows), t_n_cols + C_n_cols );
  3400. if(t_n_rows > 0)
  3401. {
  3402. if(A_n_cols > 0)
  3403. {
  3404. out.cols(0, A_n_cols-1) = cols(0, A_n_cols-1);
  3405. }
  3406. if(B_n_cols > 0)
  3407. {
  3408. out.cols(col_num + C_n_cols, t_n_cols + C_n_cols - 1) = cols(col_num, t_n_cols - 1);
  3409. }
  3410. }
  3411. if(C_n_rows > 0)
  3412. {
  3413. out.cols(col_num, col_num + C_n_cols - 1) = C;
  3414. }
  3415. steal_mem(out);
  3416. }
  3417. }
  3418. template<typename eT>
  3419. template<typename T1, typename gen_type>
  3420. inline
  3421. Mat<eT>::Mat(const Gen<T1, gen_type>& X)
  3422. : n_rows(X.n_rows)
  3423. , n_cols(X.n_cols)
  3424. , n_elem(n_rows*n_cols)
  3425. , vec_state(0)
  3426. , mem_state(0)
  3427. , mem()
  3428. {
  3429. arma_extra_debug_sigprint_this(this);
  3430. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3431. init_cold();
  3432. X.apply(*this);
  3433. }
  3434. template<typename eT>
  3435. template<typename T1, typename gen_type>
  3436. inline
  3437. Mat<eT>&
  3438. Mat<eT>::operator=(const Gen<T1, gen_type>& X)
  3439. {
  3440. arma_extra_debug_sigprint();
  3441. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3442. init_warm(X.n_rows, X.n_cols);
  3443. X.apply(*this);
  3444. return *this;
  3445. }
  3446. template<typename eT>
  3447. template<typename T1, typename gen_type>
  3448. inline
  3449. Mat<eT>&
  3450. Mat<eT>::operator+=(const Gen<T1, gen_type>& X)
  3451. {
  3452. arma_extra_debug_sigprint();
  3453. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3454. X.apply_inplace_plus(*this);
  3455. return *this;
  3456. }
  3457. template<typename eT>
  3458. template<typename T1, typename gen_type>
  3459. inline
  3460. Mat<eT>&
  3461. Mat<eT>::operator-=(const Gen<T1, gen_type>& X)
  3462. {
  3463. arma_extra_debug_sigprint();
  3464. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3465. X.apply_inplace_minus(*this);
  3466. return *this;
  3467. }
  3468. template<typename eT>
  3469. template<typename T1, typename gen_type>
  3470. inline
  3471. Mat<eT>&
  3472. Mat<eT>::operator*=(const Gen<T1, gen_type>& X)
  3473. {
  3474. arma_extra_debug_sigprint();
  3475. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3476. const Mat<eT> tmp(X);
  3477. return (*this).operator*=(tmp);
  3478. }
  3479. template<typename eT>
  3480. template<typename T1, typename gen_type>
  3481. inline
  3482. Mat<eT>&
  3483. Mat<eT>::operator%=(const Gen<T1, gen_type>& X)
  3484. {
  3485. arma_extra_debug_sigprint();
  3486. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3487. X.apply_inplace_schur(*this);
  3488. return *this;
  3489. }
  3490. template<typename eT>
  3491. template<typename T1, typename gen_type>
  3492. inline
  3493. Mat<eT>&
  3494. Mat<eT>::operator/=(const Gen<T1, gen_type>& X)
  3495. {
  3496. arma_extra_debug_sigprint();
  3497. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3498. X.apply_inplace_div(*this);
  3499. return *this;
  3500. }
  3501. //! create a matrix from Op, i.e. run the previously delayed unary operations
  3502. template<typename eT>
  3503. template<typename T1, typename op_type>
  3504. inline
  3505. Mat<eT>::Mat(const Op<T1, op_type>& X)
  3506. : n_rows(0)
  3507. , n_cols(0)
  3508. , n_elem(0)
  3509. , vec_state(0)
  3510. , mem_state(0)
  3511. , mem()
  3512. {
  3513. arma_extra_debug_sigprint_this(this);
  3514. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3515. op_type::apply(*this, X);
  3516. }
  3517. //! create a matrix from Op, i.e. run the previously delayed unary operations
  3518. template<typename eT>
  3519. template<typename T1, typename op_type>
  3520. inline
  3521. Mat<eT>&
  3522. Mat<eT>::operator=(const Op<T1, op_type>& X)
  3523. {
  3524. arma_extra_debug_sigprint();
  3525. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3526. op_type::apply(*this, X);
  3527. return *this;
  3528. }
  3529. //! in-place matrix addition, with the right-hand-side operand having delayed operations
  3530. template<typename eT>
  3531. template<typename T1, typename op_type>
  3532. inline
  3533. Mat<eT>&
  3534. Mat<eT>::operator+=(const Op<T1, op_type>& X)
  3535. {
  3536. arma_extra_debug_sigprint();
  3537. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3538. const Mat<eT> m(X);
  3539. return (*this).operator+=(m);
  3540. }
  3541. //! in-place matrix subtraction, with the right-hand-side operand having delayed operations
  3542. template<typename eT>
  3543. template<typename T1, typename op_type>
  3544. inline
  3545. Mat<eT>&
  3546. Mat<eT>::operator-=(const Op<T1, op_type>& X)
  3547. {
  3548. arma_extra_debug_sigprint();
  3549. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3550. const Mat<eT> m(X);
  3551. return (*this).operator-=(m);
  3552. }
  3553. //! in-place matrix multiplication, with the right-hand-side operand having delayed operations
  3554. template<typename eT>
  3555. template<typename T1, typename op_type>
  3556. inline
  3557. Mat<eT>&
  3558. Mat<eT>::operator*=(const Op<T1, op_type>& X)
  3559. {
  3560. arma_extra_debug_sigprint();
  3561. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3562. glue_times::apply_inplace(*this, X);
  3563. return *this;
  3564. }
  3565. //! in-place matrix element-wise multiplication, with the right-hand-side operand having delayed operations
  3566. template<typename eT>
  3567. template<typename T1, typename op_type>
  3568. inline
  3569. Mat<eT>&
  3570. Mat<eT>::operator%=(const Op<T1, op_type>& X)
  3571. {
  3572. arma_extra_debug_sigprint();
  3573. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3574. const Mat<eT> m(X);
  3575. return (*this).operator%=(m);
  3576. }
  3577. //! in-place matrix element-wise division, with the right-hand-side operand having delayed operations
  3578. template<typename eT>
  3579. template<typename T1, typename op_type>
  3580. inline
  3581. Mat<eT>&
  3582. Mat<eT>::operator/=(const Op<T1, op_type>& X)
  3583. {
  3584. arma_extra_debug_sigprint();
  3585. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3586. const Mat<eT> m(X);
  3587. return (*this).operator/=(m);
  3588. }
  3589. //! create a matrix from eOp, i.e. run the previously delayed unary operations
  3590. template<typename eT>
  3591. template<typename T1, typename eop_type>
  3592. inline
  3593. Mat<eT>::Mat(const eOp<T1, eop_type>& X)
  3594. : n_rows(X.get_n_rows())
  3595. , n_cols(X.get_n_cols())
  3596. , n_elem(X.get_n_elem())
  3597. , vec_state(0)
  3598. , mem_state(0)
  3599. , mem()
  3600. {
  3601. arma_extra_debug_sigprint_this(this);
  3602. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3603. init_cold();
  3604. eop_type::apply(*this, X);
  3605. }
  3606. //! create a matrix from eOp, i.e. run the previously delayed unary operations
  3607. template<typename eT>
  3608. template<typename T1, typename eop_type>
  3609. inline
  3610. Mat<eT>&
  3611. Mat<eT>::operator=(const eOp<T1, eop_type>& X)
  3612. {
  3613. arma_extra_debug_sigprint();
  3614. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3615. const bool bad_alias = (eOp<T1, eop_type>::proxy_type::has_subview && X.P.is_alias(*this));
  3616. if(bad_alias == false)
  3617. {
  3618. init_warm(X.get_n_rows(), X.get_n_cols());
  3619. eop_type::apply(*this, X);
  3620. }
  3621. else
  3622. {
  3623. arma_extra_debug_print("bad_alias = true");
  3624. Mat<eT> tmp(X);
  3625. steal_mem(tmp);
  3626. }
  3627. return *this;
  3628. }
  3629. template<typename eT>
  3630. template<typename T1, typename eop_type>
  3631. inline
  3632. Mat<eT>&
  3633. Mat<eT>::operator+=(const eOp<T1, eop_type>& X)
  3634. {
  3635. arma_extra_debug_sigprint();
  3636. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3637. eop_type::apply_inplace_plus(*this, X);
  3638. return *this;
  3639. }
  3640. template<typename eT>
  3641. template<typename T1, typename eop_type>
  3642. inline
  3643. Mat<eT>&
  3644. Mat<eT>::operator-=(const eOp<T1, eop_type>& X)
  3645. {
  3646. arma_extra_debug_sigprint();
  3647. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3648. eop_type::apply_inplace_minus(*this, X);
  3649. return *this;
  3650. }
  3651. template<typename eT>
  3652. template<typename T1, typename eop_type>
  3653. inline
  3654. Mat<eT>&
  3655. Mat<eT>::operator*=(const eOp<T1, eop_type>& X)
  3656. {
  3657. arma_extra_debug_sigprint();
  3658. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3659. glue_times::apply_inplace(*this, X);
  3660. return *this;
  3661. }
  3662. template<typename eT>
  3663. template<typename T1, typename eop_type>
  3664. inline
  3665. Mat<eT>&
  3666. Mat<eT>::operator%=(const eOp<T1, eop_type>& X)
  3667. {
  3668. arma_extra_debug_sigprint();
  3669. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3670. eop_type::apply_inplace_schur(*this, X);
  3671. return *this;
  3672. }
  3673. template<typename eT>
  3674. template<typename T1, typename eop_type>
  3675. inline
  3676. Mat<eT>&
  3677. Mat<eT>::operator/=(const eOp<T1, eop_type>& X)
  3678. {
  3679. arma_extra_debug_sigprint();
  3680. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3681. eop_type::apply_inplace_div(*this, X);
  3682. return *this;
  3683. }
  3684. template<typename eT>
  3685. template<typename T1, typename op_type>
  3686. inline
  3687. Mat<eT>::Mat(const mtOp<eT, T1, op_type>& X)
  3688. : n_rows(0)
  3689. , n_cols(0)
  3690. , n_elem(0)
  3691. , vec_state(0)
  3692. , mem_state(0)
  3693. , mem()
  3694. {
  3695. arma_extra_debug_sigprint_this(this);
  3696. op_type::apply(*this, X);
  3697. }
  3698. template<typename eT>
  3699. template<typename T1, typename op_type>
  3700. inline
  3701. Mat<eT>&
  3702. Mat<eT>::operator=(const mtOp<eT, T1, op_type>& X)
  3703. {
  3704. arma_extra_debug_sigprint();
  3705. op_type::apply(*this, X);
  3706. return *this;
  3707. }
  3708. template<typename eT>
  3709. template<typename T1, typename op_type>
  3710. inline
  3711. Mat<eT>&
  3712. Mat<eT>::operator+=(const mtOp<eT, T1, op_type>& X)
  3713. {
  3714. arma_extra_debug_sigprint();
  3715. const Mat<eT> m(X);
  3716. return (*this).operator+=(m);
  3717. }
  3718. template<typename eT>
  3719. template<typename T1, typename op_type>
  3720. inline
  3721. Mat<eT>&
  3722. Mat<eT>::operator-=(const mtOp<eT, T1, op_type>& X)
  3723. {
  3724. arma_extra_debug_sigprint();
  3725. const Mat<eT> m(X);
  3726. return (*this).operator-=(m);
  3727. }
  3728. template<typename eT>
  3729. template<typename T1, typename op_type>
  3730. inline
  3731. Mat<eT>&
  3732. Mat<eT>::operator*=(const mtOp<eT, T1, op_type>& X)
  3733. {
  3734. arma_extra_debug_sigprint();
  3735. const Mat<eT> m(X);
  3736. return (*this).operator*=(m);
  3737. }
  3738. template<typename eT>
  3739. template<typename T1, typename op_type>
  3740. inline
  3741. Mat<eT>&
  3742. Mat<eT>::operator%=(const mtOp<eT, T1, op_type>& X)
  3743. {
  3744. arma_extra_debug_sigprint();
  3745. const Mat<eT> m(X);
  3746. return (*this).operator%=(m);
  3747. }
  3748. template<typename eT>
  3749. template<typename T1, typename op_type>
  3750. inline
  3751. Mat<eT>&
  3752. Mat<eT>::operator/=(const mtOp<eT, T1, op_type>& X)
  3753. {
  3754. arma_extra_debug_sigprint();
  3755. const Mat<eT> m(X);
  3756. return (*this).operator/=(m);
  3757. }
  3758. template<typename eT>
  3759. template<typename T1, typename op_type>
  3760. inline
  3761. Mat<eT>::Mat(const CubeToMatOp<T1, op_type>& X)
  3762. : n_rows(0)
  3763. , n_cols(0)
  3764. , n_elem(0)
  3765. , vec_state(0)
  3766. , mem_state(0)
  3767. , mem()
  3768. {
  3769. arma_extra_debug_sigprint_this(this);
  3770. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3771. op_type::apply(*this, X);
  3772. }
  3773. template<typename eT>
  3774. template<typename T1, typename op_type>
  3775. inline
  3776. Mat<eT>&
  3777. Mat<eT>::operator=(const CubeToMatOp<T1, op_type>& X)
  3778. {
  3779. arma_extra_debug_sigprint();
  3780. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3781. op_type::apply(*this, X);
  3782. return *this;
  3783. }
  3784. template<typename eT>
  3785. template<typename T1, typename op_type>
  3786. inline
  3787. Mat<eT>&
  3788. Mat<eT>::operator+=(const CubeToMatOp<T1, op_type>& X)
  3789. {
  3790. arma_extra_debug_sigprint();
  3791. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3792. (*this) = (*this) + X;
  3793. return (*this);
  3794. }
  3795. template<typename eT>
  3796. template<typename T1, typename op_type>
  3797. inline
  3798. Mat<eT>&
  3799. Mat<eT>::operator-=(const CubeToMatOp<T1, op_type>& X)
  3800. {
  3801. arma_extra_debug_sigprint();
  3802. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3803. (*this) = (*this) - X;
  3804. return (*this);
  3805. }
  3806. template<typename eT>
  3807. template<typename T1, typename op_type>
  3808. inline
  3809. Mat<eT>&
  3810. Mat<eT>::operator*=(const CubeToMatOp<T1, op_type>& X)
  3811. {
  3812. arma_extra_debug_sigprint();
  3813. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3814. glue_times::apply_inplace(*this, X);
  3815. return *this;
  3816. }
  3817. template<typename eT>
  3818. template<typename T1, typename op_type>
  3819. inline
  3820. Mat<eT>&
  3821. Mat<eT>::operator%=(const CubeToMatOp<T1, op_type>& X)
  3822. {
  3823. arma_extra_debug_sigprint();
  3824. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3825. (*this) = (*this) % X;
  3826. return (*this);
  3827. }
  3828. template<typename eT>
  3829. template<typename T1, typename op_type>
  3830. inline
  3831. Mat<eT>&
  3832. Mat<eT>::operator/=(const CubeToMatOp<T1, op_type>& X)
  3833. {
  3834. arma_extra_debug_sigprint();
  3835. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3836. (*this) = (*this) / X;
  3837. return (*this);
  3838. }
  3839. template<typename eT>
  3840. template<typename T1, typename op_type>
  3841. inline
  3842. Mat<eT>::Mat(const SpToDOp<T1, op_type>& X)
  3843. : n_rows(0)
  3844. , n_cols(0)
  3845. , n_elem(0)
  3846. , vec_state(0)
  3847. , mem_state(0)
  3848. , mem()
  3849. {
  3850. arma_extra_debug_sigprint_this(this);
  3851. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3852. op_type::apply(*this, X);
  3853. }
  3854. //! create a matrix from an SpToDOp, i.e. run the previously delayed unary operations
  3855. template<typename eT>
  3856. template<typename T1, typename op_type>
  3857. inline
  3858. Mat<eT>&
  3859. Mat<eT>::operator=(const SpToDOp<T1, op_type>& X)
  3860. {
  3861. arma_extra_debug_sigprint();
  3862. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3863. op_type::apply(*this, X);
  3864. return *this;
  3865. }
  3866. //! in-place matrix addition, with the right-hand-side operand having delayed operations
  3867. template<typename eT>
  3868. template<typename T1, typename op_type>
  3869. inline
  3870. Mat<eT>&
  3871. Mat<eT>::operator+=(const SpToDOp<T1, op_type>& X)
  3872. {
  3873. arma_extra_debug_sigprint();
  3874. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3875. const Mat<eT> m(X);
  3876. return (*this).operator+=(m);
  3877. }
  3878. //! in-place matrix subtraction, with the right-hand-side operand having delayed operations
  3879. template<typename eT>
  3880. template<typename T1, typename op_type>
  3881. inline
  3882. Mat<eT>&
  3883. Mat<eT>::operator-=(const SpToDOp<T1, op_type>& X)
  3884. {
  3885. arma_extra_debug_sigprint();
  3886. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3887. const Mat<eT> m(X);
  3888. return (*this).operator-=(m);
  3889. }
  3890. //! in-place matrix multiplication, with the right-hand-side operand having delayed operations
  3891. template<typename eT>
  3892. template<typename T1, typename op_type>
  3893. inline
  3894. Mat<eT>&
  3895. Mat<eT>::operator*=(const SpToDOp<T1, op_type>& X)
  3896. {
  3897. arma_extra_debug_sigprint();
  3898. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3899. glue_times::apply_inplace(*this, X);
  3900. return *this;
  3901. }
  3902. //! in-place matrix element-wise multiplication, with the right-hand-side operand having delayed operations
  3903. template<typename eT>
  3904. template<typename T1, typename op_type>
  3905. inline
  3906. Mat<eT>&
  3907. Mat<eT>::operator%=(const SpToDOp<T1, op_type>& X)
  3908. {
  3909. arma_extra_debug_sigprint();
  3910. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3911. const Mat<eT> m(X);
  3912. return (*this).operator%=(m);
  3913. }
  3914. //! in-place matrix element-wise division, with the right-hand-side operand having delayed operations
  3915. template<typename eT>
  3916. template<typename T1, typename op_type>
  3917. inline
  3918. Mat<eT>&
  3919. Mat<eT>::operator/=(const SpToDOp<T1, op_type>& X)
  3920. {
  3921. arma_extra_debug_sigprint();
  3922. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3923. const Mat<eT> m(X);
  3924. return (*this).operator/=(m);
  3925. }
  3926. //! create a matrix from Glue, i.e. run the previously delayed binary operations
  3927. template<typename eT>
  3928. template<typename T1, typename T2, typename glue_type>
  3929. inline
  3930. Mat<eT>::Mat(const Glue<T1, T2, glue_type>& X)
  3931. : n_rows(0)
  3932. , n_cols(0)
  3933. , n_elem(0)
  3934. , vec_state(0)
  3935. , mem_state(0)
  3936. , mem()
  3937. {
  3938. arma_extra_debug_sigprint_this(this);
  3939. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3940. arma_type_check(( is_same_type< eT, typename T2::elem_type >::no ));
  3941. glue_type::apply(*this, X);
  3942. }
  3943. //! create a matrix from Glue, i.e. run the previously delayed binary operations
  3944. template<typename eT>
  3945. template<typename T1, typename T2, typename glue_type>
  3946. inline
  3947. Mat<eT>&
  3948. Mat<eT>::operator=(const Glue<T1, T2, glue_type>& X)
  3949. {
  3950. arma_extra_debug_sigprint();
  3951. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3952. arma_type_check(( is_same_type< eT, typename T2::elem_type >::no ));
  3953. glue_type::apply(*this, X);
  3954. return *this;
  3955. }
  3956. //! in-place matrix addition, with the right-hand-side operands having delayed operations
  3957. template<typename eT>
  3958. template<typename T1, typename T2, typename glue_type>
  3959. inline
  3960. Mat<eT>&
  3961. Mat<eT>::operator+=(const Glue<T1, T2, glue_type>& X)
  3962. {
  3963. arma_extra_debug_sigprint();
  3964. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3965. arma_type_check(( is_same_type< eT, typename T2::elem_type >::no ));
  3966. const Mat<eT> m(X);
  3967. return (*this).operator+=(m);
  3968. }
  3969. //! in-place matrix subtraction, with the right-hand-side operands having delayed operations
  3970. template<typename eT>
  3971. template<typename T1, typename T2, typename glue_type>
  3972. inline
  3973. Mat<eT>&
  3974. Mat<eT>::operator-=(const Glue<T1, T2, glue_type>& X)
  3975. {
  3976. arma_extra_debug_sigprint();
  3977. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3978. arma_type_check(( is_same_type< eT, typename T2::elem_type >::no ));
  3979. const Mat<eT> m(X);
  3980. return (*this).operator-=(m);
  3981. }
  3982. //! in-place matrix multiplications, with the right-hand-side operands having delayed operations
  3983. template<typename eT>
  3984. template<typename T1, typename T2, typename glue_type>
  3985. inline
  3986. Mat<eT>&
  3987. Mat<eT>::operator*=(const Glue<T1, T2, glue_type>& X)
  3988. {
  3989. arma_extra_debug_sigprint();
  3990. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  3991. arma_type_check(( is_same_type< eT, typename T2::elem_type >::no ));
  3992. glue_times::apply_inplace(*this, X);
  3993. return *this;
  3994. }
  3995. //! in-place matrix element-wise multiplication, with the right-hand-side operands having delayed operations
  3996. template<typename eT>
  3997. template<typename T1, typename T2, typename glue_type>
  3998. inline
  3999. Mat<eT>&
  4000. Mat<eT>::operator%=(const Glue<T1, T2, glue_type>& X)
  4001. {
  4002. arma_extra_debug_sigprint();
  4003. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  4004. arma_type_check(( is_same_type< eT, typename T2::elem_type >::no ));
  4005. const Mat<eT> m(X);
  4006. return (*this).operator%=(m);
  4007. }
  4008. //! in-place matrix element-wise division, with the right-hand-side operands having delayed operations
  4009. template<typename eT>
  4010. template<typename T1, typename T2, typename glue_type>
  4011. inline
  4012. Mat<eT>&
  4013. Mat<eT>::operator/=(const Glue<T1, T2, glue_type>& X)
  4014. {
  4015. arma_extra_debug_sigprint();
  4016. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  4017. arma_type_check(( is_same_type< eT, typename T2::elem_type >::no ));
  4018. const Mat<eT> m(X);
  4019. return (*this).operator/=(m);
  4020. }
  4021. template<typename eT>
  4022. template<typename T1, typename T2>
  4023. inline
  4024. Mat<eT>&
  4025. Mat<eT>::operator+=(const Glue<T1, T2, glue_times>& X)
  4026. {
  4027. arma_extra_debug_sigprint();
  4028. glue_times::apply_inplace_plus(*this, X, sword(+1));
  4029. return *this;
  4030. }
  4031. template<typename eT>
  4032. template<typename T1, typename T2>
  4033. inline
  4034. Mat<eT>&
  4035. Mat<eT>::operator-=(const Glue<T1, T2, glue_times>& X)
  4036. {
  4037. arma_extra_debug_sigprint();
  4038. glue_times::apply_inplace_plus(*this, X, sword(-1));
  4039. return *this;
  4040. }
  4041. //! create a matrix from eGlue, i.e. run the previously delayed binary operations
  4042. template<typename eT>
  4043. template<typename T1, typename T2, typename eglue_type>
  4044. inline
  4045. Mat<eT>::Mat(const eGlue<T1, T2, eglue_type>& X)
  4046. : n_rows(X.get_n_rows())
  4047. , n_cols(X.get_n_cols())
  4048. , n_elem(X.get_n_elem())
  4049. , vec_state(0)
  4050. , mem_state(0)
  4051. , mem()
  4052. {
  4053. arma_extra_debug_sigprint_this(this);
  4054. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  4055. arma_type_check(( is_same_type< eT, typename T2::elem_type >::no ));
  4056. init_cold();
  4057. eglue_type::apply(*this, X);
  4058. }
  4059. //! create a matrix from eGlue, i.e. run the previously delayed binary operations
  4060. template<typename eT>
  4061. template<typename T1, typename T2, typename eglue_type>
  4062. inline
  4063. Mat<eT>&
  4064. Mat<eT>::operator=(const eGlue<T1, T2, eglue_type>& X)
  4065. {
  4066. arma_extra_debug_sigprint();
  4067. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  4068. arma_type_check(( is_same_type< eT, typename T2::elem_type >::no ));
  4069. const bool bad_alias =
  4070. (
  4071. (eGlue<T1, T2, eglue_type>::proxy1_type::has_subview && X.P1.is_alias(*this))
  4072. ||
  4073. (eGlue<T1, T2, eglue_type>::proxy2_type::has_subview && X.P2.is_alias(*this))
  4074. );
  4075. if(bad_alias == false)
  4076. {
  4077. init_warm(X.get_n_rows(), X.get_n_cols());
  4078. eglue_type::apply(*this, X);
  4079. }
  4080. else
  4081. {
  4082. arma_extra_debug_print("bad_alias = true");
  4083. Mat<eT> tmp(X);
  4084. steal_mem(tmp);
  4085. }
  4086. return *this;
  4087. }
  4088. //! in-place matrix addition, with the right-hand-side operands having delayed operations
  4089. template<typename eT>
  4090. template<typename T1, typename T2, typename eglue_type>
  4091. inline
  4092. Mat<eT>&
  4093. Mat<eT>::operator+=(const eGlue<T1, T2, eglue_type>& X)
  4094. {
  4095. arma_extra_debug_sigprint();
  4096. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  4097. arma_type_check(( is_same_type< eT, typename T2::elem_type >::no ));
  4098. eglue_type::apply_inplace_plus(*this, X);
  4099. return *this;
  4100. }
  4101. //! in-place matrix subtraction, with the right-hand-side operands having delayed operations
  4102. template<typename eT>
  4103. template<typename T1, typename T2, typename eglue_type>
  4104. inline
  4105. Mat<eT>&
  4106. Mat<eT>::operator-=(const eGlue<T1, T2, eglue_type>& X)
  4107. {
  4108. arma_extra_debug_sigprint();
  4109. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  4110. arma_type_check(( is_same_type< eT, typename T2::elem_type >::no ));
  4111. eglue_type::apply_inplace_minus(*this, X);
  4112. return *this;
  4113. }
  4114. template<typename eT>
  4115. template<typename T1, typename T2, typename eglue_type>
  4116. inline
  4117. Mat<eT>&
  4118. Mat<eT>::operator*=(const eGlue<T1, T2, eglue_type>& X)
  4119. {
  4120. arma_extra_debug_sigprint();
  4121. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  4122. arma_type_check(( is_same_type< eT, typename T2::elem_type >::no ));
  4123. glue_times::apply_inplace(*this, X);
  4124. return *this;
  4125. }
  4126. template<typename eT>
  4127. template<typename T1, typename T2, typename eglue_type>
  4128. inline
  4129. Mat<eT>&
  4130. Mat<eT>::operator%=(const eGlue<T1, T2, eglue_type>& X)
  4131. {
  4132. arma_extra_debug_sigprint();
  4133. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  4134. arma_type_check(( is_same_type< eT, typename T2::elem_type >::no ));
  4135. eglue_type::apply_inplace_schur(*this, X);
  4136. return *this;
  4137. }
  4138. template<typename eT>
  4139. template<typename T1, typename T2, typename eglue_type>
  4140. inline
  4141. Mat<eT>&
  4142. Mat<eT>::operator/=(const eGlue<T1, T2, eglue_type>& X)
  4143. {
  4144. arma_extra_debug_sigprint();
  4145. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  4146. arma_type_check(( is_same_type< eT, typename T2::elem_type >::no ));
  4147. eglue_type::apply_inplace_div(*this, X);
  4148. return *this;
  4149. }
  4150. template<typename eT>
  4151. template<typename T1, typename T2, typename glue_type>
  4152. inline
  4153. Mat<eT>::Mat(const mtGlue<eT, T1, T2, glue_type>& X)
  4154. : n_rows(0)
  4155. , n_cols(0)
  4156. , n_elem(0)
  4157. , vec_state(0)
  4158. , mem_state(0)
  4159. , mem()
  4160. {
  4161. arma_extra_debug_sigprint_this(this);
  4162. glue_type::apply(*this, X);
  4163. }
  4164. template<typename eT>
  4165. template<typename T1, typename T2, typename glue_type>
  4166. inline
  4167. Mat<eT>&
  4168. Mat<eT>::operator=(const mtGlue<eT, T1, T2, glue_type>& X)
  4169. {
  4170. arma_extra_debug_sigprint();
  4171. glue_type::apply(*this, X);
  4172. return *this;
  4173. }
  4174. template<typename eT>
  4175. template<typename T1, typename T2, typename glue_type>
  4176. inline
  4177. Mat<eT>&
  4178. Mat<eT>::operator+=(const mtGlue<eT, T1, T2, glue_type>& X)
  4179. {
  4180. arma_extra_debug_sigprint();
  4181. const Mat<eT> m(X);
  4182. return (*this).operator+=(m);
  4183. }
  4184. template<typename eT>
  4185. template<typename T1, typename T2, typename glue_type>
  4186. inline
  4187. Mat<eT>&
  4188. Mat<eT>::operator-=(const mtGlue<eT, T1, T2, glue_type>& X)
  4189. {
  4190. arma_extra_debug_sigprint();
  4191. const Mat<eT> m(X);
  4192. return (*this).operator-=(m);
  4193. }
  4194. template<typename eT>
  4195. template<typename T1, typename T2, typename glue_type>
  4196. inline
  4197. Mat<eT>&
  4198. Mat<eT>::operator*=(const mtGlue<eT, T1, T2, glue_type>& X)
  4199. {
  4200. arma_extra_debug_sigprint();
  4201. const Mat<eT> m(X);
  4202. glue_times::apply_inplace(*this, m);
  4203. return *this;
  4204. }
  4205. template<typename eT>
  4206. template<typename T1, typename T2, typename glue_type>
  4207. inline
  4208. Mat<eT>&
  4209. Mat<eT>::operator%=(const mtGlue<eT, T1, T2, glue_type>& X)
  4210. {
  4211. arma_extra_debug_sigprint();
  4212. const Mat<eT> m(X);
  4213. return (*this).operator%=(m);
  4214. }
  4215. template<typename eT>
  4216. template<typename T1, typename T2, typename glue_type>
  4217. inline
  4218. Mat<eT>&
  4219. Mat<eT>::operator/=(const mtGlue<eT, T1, T2, glue_type>& X)
  4220. {
  4221. arma_extra_debug_sigprint();
  4222. const Mat<eT> m(X);
  4223. return (*this).operator/=(m);
  4224. }
  4225. //! linear element accessor (treats the matrix as a vector); no bounds check; assumes memory is aligned
  4226. template<typename eT>
  4227. arma_inline
  4228. arma_warn_unused
  4229. const eT&
  4230. Mat<eT>::at_alt(const uword ii) const
  4231. {
  4232. const eT* mem_aligned = mem;
  4233. memory::mark_as_aligned(mem_aligned);
  4234. return mem_aligned[ii];
  4235. }
  4236. //! linear element accessor (treats the matrix as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
  4237. template<typename eT>
  4238. arma_inline
  4239. arma_warn_unused
  4240. eT&
  4241. Mat<eT>::operator() (const uword ii)
  4242. {
  4243. arma_debug_check( (ii >= n_elem), "Mat::operator(): index out of bounds");
  4244. return access::rw(mem[ii]);
  4245. }
  4246. //! linear element accessor (treats the matrix as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
  4247. template<typename eT>
  4248. arma_inline
  4249. arma_warn_unused
  4250. const eT&
  4251. Mat<eT>::operator() (const uword ii) const
  4252. {
  4253. arma_debug_check( (ii >= n_elem), "Mat::operator(): index out of bounds");
  4254. return mem[ii];
  4255. }
  4256. //! linear element accessor (treats the matrix as a vector); no bounds check.
  4257. template<typename eT>
  4258. arma_inline
  4259. arma_warn_unused
  4260. eT&
  4261. Mat<eT>::operator[] (const uword ii)
  4262. {
  4263. return access::rw(mem[ii]);
  4264. }
  4265. //! linear element accessor (treats the matrix as a vector); no bounds check
  4266. template<typename eT>
  4267. arma_inline
  4268. arma_warn_unused
  4269. const eT&
  4270. Mat<eT>::operator[] (const uword ii) const
  4271. {
  4272. return mem[ii];
  4273. }
  4274. //! linear element accessor (treats the matrix as a vector); no bounds check.
  4275. template<typename eT>
  4276. arma_inline
  4277. arma_warn_unused
  4278. eT&
  4279. Mat<eT>::at(const uword ii)
  4280. {
  4281. return access::rw(mem[ii]);
  4282. }
  4283. //! linear element accessor (treats the matrix as a vector); no bounds check
  4284. template<typename eT>
  4285. arma_inline
  4286. arma_warn_unused
  4287. const eT&
  4288. Mat<eT>::at(const uword ii) const
  4289. {
  4290. return mem[ii];
  4291. }
  4292. //! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
  4293. template<typename eT>
  4294. arma_inline
  4295. arma_warn_unused
  4296. eT&
  4297. Mat<eT>::operator() (const uword in_row, const uword in_col)
  4298. {
  4299. arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "Mat::operator(): index out of bounds");
  4300. return access::rw(mem[in_row + in_col*n_rows]);
  4301. }
  4302. //! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
  4303. template<typename eT>
  4304. arma_inline
  4305. arma_warn_unused
  4306. const eT&
  4307. Mat<eT>::operator() (const uword in_row, const uword in_col) const
  4308. {
  4309. arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "Mat::operator(): index out of bounds");
  4310. return mem[in_row + in_col*n_rows];
  4311. }
  4312. //! element accessor; no bounds check
  4313. template<typename eT>
  4314. arma_inline
  4315. arma_warn_unused
  4316. eT&
  4317. Mat<eT>::at(const uword in_row, const uword in_col)
  4318. {
  4319. return access::rw( mem[in_row + in_col*n_rows] );
  4320. }
  4321. //! element accessor; no bounds check
  4322. template<typename eT>
  4323. arma_inline
  4324. arma_warn_unused
  4325. const eT&
  4326. Mat<eT>::at(const uword in_row, const uword in_col) const
  4327. {
  4328. return mem[in_row + in_col*n_rows];
  4329. }
  4330. //! prefix ++
  4331. template<typename eT>
  4332. arma_inline
  4333. const Mat<eT>&
  4334. Mat<eT>::operator++()
  4335. {
  4336. Mat_aux::prefix_pp(*this);
  4337. return *this;
  4338. }
  4339. //! postfix ++ (must not return the object by reference)
  4340. template<typename eT>
  4341. arma_inline
  4342. void
  4343. Mat<eT>::operator++(int)
  4344. {
  4345. Mat_aux::postfix_pp(*this);
  4346. }
  4347. //! prefix --
  4348. template<typename eT>
  4349. arma_inline
  4350. const Mat<eT>&
  4351. Mat<eT>::operator--()
  4352. {
  4353. Mat_aux::prefix_mm(*this);
  4354. return *this;
  4355. }
  4356. //! postfix -- (must not return the object by reference)
  4357. template<typename eT>
  4358. arma_inline
  4359. void
  4360. Mat<eT>::operator--(int)
  4361. {
  4362. Mat_aux::postfix_mm(*this);
  4363. }
  4364. //! returns true if the matrix has no elements
  4365. template<typename eT>
  4366. arma_inline
  4367. arma_warn_unused
  4368. bool
  4369. Mat<eT>::is_empty() const
  4370. {
  4371. return (n_elem == 0);
  4372. }
  4373. //! returns true if the object can be interpreted as a column or row vector
  4374. template<typename eT>
  4375. arma_inline
  4376. arma_warn_unused
  4377. bool
  4378. Mat<eT>::is_vec() const
  4379. {
  4380. return ( (n_rows == 1) || (n_cols == 1) );
  4381. }
  4382. //! returns true if the object can be interpreted as a row vector
  4383. template<typename eT>
  4384. arma_inline
  4385. arma_warn_unused
  4386. bool
  4387. Mat<eT>::is_rowvec() const
  4388. {
  4389. return (n_rows == 1);
  4390. }
  4391. //! returns true if the object can be interpreted as a column vector
  4392. template<typename eT>
  4393. arma_inline
  4394. arma_warn_unused
  4395. bool
  4396. Mat<eT>::is_colvec() const
  4397. {
  4398. return (n_cols == 1);
  4399. }
  4400. //! returns true if the object has the same number of non-zero rows and columnns
  4401. template<typename eT>
  4402. arma_inline
  4403. arma_warn_unused
  4404. bool
  4405. Mat<eT>::is_square() const
  4406. {
  4407. return (n_rows == n_cols);
  4408. }
  4409. //! returns true if all of the elements are finite
  4410. template<typename eT>
  4411. inline
  4412. arma_warn_unused
  4413. bool
  4414. Mat<eT>::is_finite() const
  4415. {
  4416. return arrayops::is_finite( memptr(), n_elem );
  4417. }
  4418. template<typename eT>
  4419. inline
  4420. arma_warn_unused
  4421. bool
  4422. Mat<eT>::has_inf() const
  4423. {
  4424. arma_extra_debug_sigprint();
  4425. return arrayops::has_inf(memptr(), n_elem);
  4426. }
  4427. template<typename eT>
  4428. inline
  4429. arma_warn_unused
  4430. bool
  4431. Mat<eT>::has_nan() const
  4432. {
  4433. arma_extra_debug_sigprint();
  4434. return arrayops::has_nan(memptr(), n_elem);
  4435. }
  4436. template<typename eT>
  4437. inline
  4438. arma_warn_unused
  4439. bool
  4440. Mat<eT>::is_sorted(const char* direction) const
  4441. {
  4442. arma_extra_debug_sigprint();
  4443. return (*this).is_sorted(direction, (((vec_state == 2) || (n_rows == 1)) ? uword(1) : uword(0)));
  4444. }
  4445. template<typename eT>
  4446. inline
  4447. arma_warn_unused
  4448. bool
  4449. Mat<eT>::is_sorted(const char* direction, const uword dim) const
  4450. {
  4451. arma_extra_debug_sigprint();
  4452. const char sig1 = (direction != NULL) ? direction[0] : char(0);
  4453. // direction is one of:
  4454. // "ascend"
  4455. // "descend"
  4456. // "strictascend"
  4457. // "strictdescend"
  4458. arma_debug_check( ((sig1 != 'a') && (sig1 != 'd') && (sig1 != 's')), "Mat::is_sorted(): unknown sort direction" );
  4459. // "strictascend"
  4460. // "strictdescend"
  4461. // 0123456
  4462. const char sig2 = (sig1 == 's') ? direction[6] : char(0);
  4463. if(sig1 == 's') { arma_debug_check( ((sig2 != 'a') && (sig2 != 'd')), "Mat::is_sorted(): unknown sort direction" ); }
  4464. arma_debug_check( (dim > 1), "Mat::is_sorted(): parameter 'dim' must be 0 or 1" );
  4465. if(sig1 == 'a')
  4466. {
  4467. // case: ascend
  4468. // deliberately using the opposite direction comparator,
  4469. // as we need to handle the case of two elements being equal
  4470. arma_gt_comparator<eT> comparator;
  4471. return (*this).is_sorted_helper(comparator, dim);
  4472. }
  4473. else
  4474. if(sig1 == 'd')
  4475. {
  4476. // case: descend
  4477. // deliberately using the opposite direction comparator,
  4478. // as we need to handle the case of two elements being equal
  4479. arma_lt_comparator<eT> comparator;
  4480. return (*this).is_sorted_helper(comparator, dim);
  4481. }
  4482. else
  4483. if((sig1 == 's') && (sig2 == 'a'))
  4484. {
  4485. // case: strict ascend
  4486. arma_geq_comparator<eT> comparator;
  4487. return (*this).is_sorted_helper(comparator, dim);
  4488. }
  4489. else
  4490. if((sig1 == 's') && (sig2 == 'd'))
  4491. {
  4492. // case: strict descend
  4493. arma_leq_comparator<eT> comparator;
  4494. return (*this).is_sorted_helper(comparator, dim);
  4495. }
  4496. return true;
  4497. }
  4498. template<typename eT>
  4499. template<typename comparator>
  4500. inline
  4501. arma_warn_unused
  4502. bool
  4503. Mat<eT>::is_sorted_helper(const comparator& comp, const uword dim) const
  4504. {
  4505. arma_extra_debug_sigprint();
  4506. if(n_elem <= 1) { return true; }
  4507. const uword local_n_cols = n_cols;
  4508. const uword local_n_rows = n_rows;
  4509. if(dim == 0)
  4510. {
  4511. if(local_n_rows <= 1u) { return true; }
  4512. const uword local_n_rows_m1 = local_n_rows - 1;
  4513. for(uword c=0; c < local_n_cols; ++c)
  4514. {
  4515. const eT* coldata = colptr(c);
  4516. for(uword r=0; r < local_n_rows_m1; ++r)
  4517. {
  4518. const eT val1 = (*coldata); coldata++;
  4519. const eT val2 = (*coldata);
  4520. if(comp(val1,val2)) { return false; }
  4521. }
  4522. }
  4523. }
  4524. else
  4525. if(dim == 1)
  4526. {
  4527. if(local_n_cols <= 1u) { return true; }
  4528. const uword local_n_cols_m1 = local_n_cols - 1;
  4529. if(local_n_rows == 1)
  4530. {
  4531. const eT* rowdata = memptr();
  4532. for(uword c=0; c < local_n_cols_m1; ++c)
  4533. {
  4534. const eT val1 = (*rowdata); rowdata++;
  4535. const eT val2 = (*rowdata);
  4536. if(comp(val1,val2)) { return false; }
  4537. }
  4538. }
  4539. else
  4540. {
  4541. for(uword r=0; r < local_n_rows; ++r)
  4542. for(uword c=0; c < local_n_cols_m1; ++c)
  4543. {
  4544. const eT val1 = at(r,c );
  4545. const eT val2 = at(r,c+1);
  4546. if(comp(val1,val2)) { return false; }
  4547. }
  4548. }
  4549. }
  4550. return true;
  4551. }
  4552. //! returns true if the given index is currently in range
  4553. template<typename eT>
  4554. arma_inline
  4555. arma_warn_unused
  4556. bool
  4557. Mat<eT>::in_range(const uword ii) const
  4558. {
  4559. return (ii < n_elem);
  4560. }
  4561. //! returns true if the given start and end indices are currently in range
  4562. template<typename eT>
  4563. arma_inline
  4564. arma_warn_unused
  4565. bool
  4566. Mat<eT>::in_range(const span& x) const
  4567. {
  4568. arma_extra_debug_sigprint();
  4569. if(x.whole)
  4570. {
  4571. return true;
  4572. }
  4573. else
  4574. {
  4575. const uword a = x.a;
  4576. const uword b = x.b;
  4577. return ( (a <= b) && (b < n_elem) );
  4578. }
  4579. }
  4580. //! returns true if the given location is currently in range
  4581. template<typename eT>
  4582. arma_inline
  4583. arma_warn_unused
  4584. bool
  4585. Mat<eT>::in_range(const uword in_row, const uword in_col) const
  4586. {
  4587. return ( (in_row < n_rows) && (in_col < n_cols) );
  4588. }
  4589. template<typename eT>
  4590. arma_inline
  4591. arma_warn_unused
  4592. bool
  4593. Mat<eT>::in_range(const span& row_span, const uword in_col) const
  4594. {
  4595. arma_extra_debug_sigprint();
  4596. if(row_span.whole)
  4597. {
  4598. return (in_col < n_cols);
  4599. }
  4600. else
  4601. {
  4602. const uword in_row1 = row_span.a;
  4603. const uword in_row2 = row_span.b;
  4604. return ( (in_row1 <= in_row2) && (in_row2 < n_rows) && (in_col < n_cols) );
  4605. }
  4606. }
  4607. template<typename eT>
  4608. arma_inline
  4609. arma_warn_unused
  4610. bool
  4611. Mat<eT>::in_range(const uword in_row, const span& col_span) const
  4612. {
  4613. arma_extra_debug_sigprint();
  4614. if(col_span.whole)
  4615. {
  4616. return (in_row < n_rows);
  4617. }
  4618. else
  4619. {
  4620. const uword in_col1 = col_span.a;
  4621. const uword in_col2 = col_span.b;
  4622. return ( (in_row < n_rows) && (in_col1 <= in_col2) && (in_col2 < n_cols) );
  4623. }
  4624. }
  4625. template<typename eT>
  4626. arma_inline
  4627. arma_warn_unused
  4628. bool
  4629. Mat<eT>::in_range(const span& row_span, const span& col_span) const
  4630. {
  4631. arma_extra_debug_sigprint();
  4632. const uword in_row1 = row_span.a;
  4633. const uword in_row2 = row_span.b;
  4634. const uword in_col1 = col_span.a;
  4635. const uword in_col2 = col_span.b;
  4636. const bool rows_ok = row_span.whole ? true : ( (in_row1 <= in_row2) && (in_row2 < n_rows) );
  4637. const bool cols_ok = col_span.whole ? true : ( (in_col1 <= in_col2) && (in_col2 < n_cols) );
  4638. return ( rows_ok && cols_ok );
  4639. }
  4640. template<typename eT>
  4641. arma_inline
  4642. arma_warn_unused
  4643. bool
  4644. Mat<eT>::in_range(const uword in_row, const uword in_col, const SizeMat& s) const
  4645. {
  4646. const uword l_n_rows = n_rows;
  4647. const uword l_n_cols = n_cols;
  4648. if( (in_row >= l_n_rows) || (in_col >= l_n_cols) || ((in_row + s.n_rows) > l_n_rows) || ((in_col + s.n_cols) > l_n_cols) )
  4649. {
  4650. return false;
  4651. }
  4652. else
  4653. {
  4654. return true;
  4655. }
  4656. }
  4657. //! returns a pointer to array of eTs for a specified column; no bounds check
  4658. template<typename eT>
  4659. arma_inline
  4660. arma_warn_unused
  4661. eT*
  4662. Mat<eT>::colptr(const uword in_col)
  4663. {
  4664. return & access::rw(mem[in_col*n_rows]);
  4665. }
  4666. //! returns a pointer to array of eTs for a specified column; no bounds check
  4667. template<typename eT>
  4668. arma_inline
  4669. arma_warn_unused
  4670. const eT*
  4671. Mat<eT>::colptr(const uword in_col) const
  4672. {
  4673. return & mem[in_col*n_rows];
  4674. }
  4675. //! returns a pointer to array of eTs used by the matrix
  4676. template<typename eT>
  4677. arma_inline
  4678. arma_warn_unused
  4679. eT*
  4680. Mat<eT>::memptr()
  4681. {
  4682. return const_cast<eT*>(mem);
  4683. }
  4684. //! returns a pointer to array of eTs used by the matrix
  4685. template<typename eT>
  4686. arma_inline
  4687. arma_warn_unused
  4688. const eT*
  4689. Mat<eT>::memptr() const
  4690. {
  4691. return mem;
  4692. }
  4693. //! print contents of the matrix (to the cout stream),
  4694. //! optionally preceding with a user specified line of text.
  4695. //! the precision and cell width are modified.
  4696. //! on return, the stream's state are restored to their original values.
  4697. template<typename eT>
  4698. arma_cold
  4699. inline
  4700. void
  4701. Mat<eT>::impl_print(const std::string& extra_text) const
  4702. {
  4703. arma_extra_debug_sigprint();
  4704. if(extra_text.length() != 0)
  4705. {
  4706. const std::streamsize orig_width = get_cout_stream().width();
  4707. get_cout_stream() << extra_text << '\n';
  4708. get_cout_stream().width(orig_width);
  4709. }
  4710. arma_ostream::print(get_cout_stream(), *this, true);
  4711. }
  4712. //! print contents of the matrix to a user specified stream,
  4713. //! optionally preceding with a user specified line of text.
  4714. //! the precision and cell width are modified.
  4715. //! on return, the stream's state are restored to their original values.
  4716. template<typename eT>
  4717. arma_cold
  4718. inline
  4719. void
  4720. Mat<eT>::impl_print(std::ostream& user_stream, const std::string& extra_text) const
  4721. {
  4722. arma_extra_debug_sigprint();
  4723. if(extra_text.length() != 0)
  4724. {
  4725. const std::streamsize orig_width = user_stream.width();
  4726. user_stream << extra_text << '\n';
  4727. user_stream.width(orig_width);
  4728. }
  4729. arma_ostream::print(user_stream, *this, true);
  4730. }
  4731. //! print contents of the matrix (to the cout stream),
  4732. //! optionally preceding with a user specified line of text.
  4733. //! the stream's state are used as is and are not modified
  4734. //! (i.e. the precision and cell width are not modified).
  4735. template<typename eT>
  4736. arma_cold
  4737. inline
  4738. void
  4739. Mat<eT>::impl_raw_print(const std::string& extra_text) const
  4740. {
  4741. arma_extra_debug_sigprint();
  4742. if(extra_text.length() != 0)
  4743. {
  4744. const std::streamsize orig_width = get_cout_stream().width();
  4745. get_cout_stream() << extra_text << '\n';
  4746. get_cout_stream().width(orig_width);
  4747. }
  4748. arma_ostream::print(get_cout_stream(), *this, false);
  4749. }
  4750. //! print contents of the matrix to a user specified stream,
  4751. //! optionally preceding with a user specified line of text.
  4752. //! the stream's state are used as is and are not modified.
  4753. //! (i.e. the precision and cell width are not modified).
  4754. template<typename eT>
  4755. arma_cold
  4756. inline
  4757. void
  4758. Mat<eT>::impl_raw_print(std::ostream& user_stream, const std::string& extra_text) const
  4759. {
  4760. arma_extra_debug_sigprint();
  4761. if(extra_text.length() != 0)
  4762. {
  4763. const std::streamsize orig_width = user_stream.width();
  4764. user_stream << extra_text << '\n';
  4765. user_stream.width(orig_width);
  4766. }
  4767. arma_ostream::print(user_stream, *this, false);
  4768. }
  4769. //! change the matrix to have user specified dimensions (data is not preserved)
  4770. template<typename eT>
  4771. inline
  4772. void
  4773. Mat<eT>::set_size(const uword in_elem)
  4774. {
  4775. arma_extra_debug_sigprint();
  4776. switch(vec_state)
  4777. {
  4778. case 0:
  4779. // fallthrough
  4780. case 1:
  4781. init_warm(in_elem, 1);
  4782. break;
  4783. case 2:
  4784. init_warm(1, in_elem);
  4785. break;
  4786. default:
  4787. ;
  4788. }
  4789. }
  4790. //! change the matrix to have user specified dimensions (data is not preserved)
  4791. template<typename eT>
  4792. inline
  4793. void
  4794. Mat<eT>::set_size(const uword in_rows, const uword in_cols)
  4795. {
  4796. arma_extra_debug_sigprint();
  4797. init_warm(in_rows, in_cols);
  4798. }
  4799. template<typename eT>
  4800. inline
  4801. void
  4802. Mat<eT>::set_size(const SizeMat& s)
  4803. {
  4804. arma_extra_debug_sigprint();
  4805. init_warm(s.n_rows, s.n_cols);
  4806. }
  4807. //! change the matrix to have user specified dimensions (data is preserved)
  4808. template<typename eT>
  4809. inline
  4810. void
  4811. Mat<eT>::resize(const uword in_elem)
  4812. {
  4813. arma_extra_debug_sigprint();
  4814. switch(vec_state)
  4815. {
  4816. case 0:
  4817. // fallthrough
  4818. case 1:
  4819. (*this).resize(in_elem, 1);
  4820. break;
  4821. case 2:
  4822. (*this).resize(1, in_elem);
  4823. break;
  4824. default:
  4825. ;
  4826. }
  4827. }
  4828. //! change the matrix to have user specified dimensions (data is preserved)
  4829. template<typename eT>
  4830. inline
  4831. void
  4832. Mat<eT>::resize(const uword in_rows, const uword in_cols)
  4833. {
  4834. arma_extra_debug_sigprint();
  4835. *this = arma::resize(*this, in_rows, in_cols);
  4836. }
  4837. template<typename eT>
  4838. inline
  4839. void
  4840. Mat<eT>::resize(const SizeMat& s)
  4841. {
  4842. arma_extra_debug_sigprint();
  4843. *this = arma::resize(*this, s.n_rows, s.n_cols);
  4844. }
  4845. //! change the matrix to have user specified dimensions (data is preserved)
  4846. template<typename eT>
  4847. inline
  4848. void
  4849. Mat<eT>::reshape(const uword in_rows, const uword in_cols)
  4850. {
  4851. arma_extra_debug_sigprint();
  4852. *this = arma::reshape(*this, in_rows, in_cols);
  4853. }
  4854. template<typename eT>
  4855. inline
  4856. void
  4857. Mat<eT>::reshape(const SizeMat& s)
  4858. {
  4859. arma_extra_debug_sigprint();
  4860. *this = arma::reshape(*this, s.n_rows, s.n_cols);
  4861. }
  4862. //! NOTE: don't use this form; it's deprecated and will be removed
  4863. template<typename eT>
  4864. arma_deprecated
  4865. inline
  4866. void
  4867. Mat<eT>::reshape(const uword in_rows, const uword in_cols, const uword dim)
  4868. {
  4869. arma_extra_debug_sigprint();
  4870. *this = arma::reshape(*this, in_rows, in_cols, dim);
  4871. }
  4872. //! change the matrix (without preserving data) to have the same dimensions as the given expression
  4873. template<typename eT>
  4874. template<typename eT2, typename expr>
  4875. inline
  4876. void
  4877. Mat<eT>::copy_size(const Base<eT2, expr>& X)
  4878. {
  4879. arma_extra_debug_sigprint();
  4880. const Proxy<expr> P(X.get_ref());
  4881. const uword X_n_rows = P.get_n_rows();
  4882. const uword X_n_cols = P.get_n_cols();
  4883. init_warm(X_n_rows, X_n_cols);
  4884. }
  4885. //! apply a functor to each element
  4886. template<typename eT>
  4887. template<typename functor>
  4888. inline
  4889. const Mat<eT>&
  4890. Mat<eT>::for_each(functor F)
  4891. {
  4892. arma_extra_debug_sigprint();
  4893. eT* data = memptr();
  4894. const uword N = n_elem;
  4895. uword ii, jj;
  4896. for(ii=0, jj=1; jj < N; ii+=2, jj+=2)
  4897. {
  4898. F(data[ii]);
  4899. F(data[jj]);
  4900. }
  4901. if(ii < N)
  4902. {
  4903. F(data[ii]);
  4904. }
  4905. return *this;
  4906. }
  4907. template<typename eT>
  4908. template<typename functor>
  4909. inline
  4910. const Mat<eT>&
  4911. Mat<eT>::for_each(functor F) const
  4912. {
  4913. arma_extra_debug_sigprint();
  4914. const eT* data = memptr();
  4915. const uword N = n_elem;
  4916. uword ii, jj;
  4917. for(ii=0, jj=1; jj < N; ii+=2, jj+=2)
  4918. {
  4919. F(data[ii]);
  4920. F(data[jj]);
  4921. }
  4922. if(ii < N)
  4923. {
  4924. F(data[ii]);
  4925. }
  4926. return *this;
  4927. }
  4928. //! transform each element in the matrix using a functor
  4929. template<typename eT>
  4930. template<typename functor>
  4931. inline
  4932. const Mat<eT>&
  4933. Mat<eT>::transform(functor F)
  4934. {
  4935. arma_extra_debug_sigprint();
  4936. eT* out_mem = memptr();
  4937. const uword N = n_elem;
  4938. uword ii, jj;
  4939. for(ii=0, jj=1; jj < N; ii+=2, jj+=2)
  4940. {
  4941. eT tmp_ii = out_mem[ii];
  4942. eT tmp_jj = out_mem[jj];
  4943. tmp_ii = eT( F(tmp_ii) );
  4944. tmp_jj = eT( F(tmp_jj) );
  4945. out_mem[ii] = tmp_ii;
  4946. out_mem[jj] = tmp_jj;
  4947. }
  4948. if(ii < N)
  4949. {
  4950. out_mem[ii] = eT( F(out_mem[ii]) );
  4951. }
  4952. return *this;
  4953. }
  4954. //! imbue (fill) the matrix with values provided by a functor
  4955. template<typename eT>
  4956. template<typename functor>
  4957. inline
  4958. const Mat<eT>&
  4959. Mat<eT>::imbue(functor F)
  4960. {
  4961. arma_extra_debug_sigprint();
  4962. eT* out_mem = memptr();
  4963. const uword N = n_elem;
  4964. uword ii, jj;
  4965. for(ii=0, jj=1; jj < N; ii+=2, jj+=2)
  4966. {
  4967. const eT tmp_ii = eT( F() );
  4968. const eT tmp_jj = eT( F() );
  4969. out_mem[ii] = tmp_ii;
  4970. out_mem[jj] = tmp_jj;
  4971. }
  4972. if(ii < N)
  4973. {
  4974. out_mem[ii] = eT( F() );
  4975. }
  4976. return *this;
  4977. }
  4978. template<typename eT>
  4979. inline
  4980. const Mat<eT>&
  4981. Mat<eT>::replace(const eT old_val, const eT new_val)
  4982. {
  4983. arma_extra_debug_sigprint();
  4984. arrayops::replace(memptr(), n_elem, old_val, new_val);
  4985. return *this;
  4986. }
  4987. template<typename eT>
  4988. inline
  4989. const Mat<eT>&
  4990. Mat<eT>::clean(const typename get_pod_type<eT>::result threshold)
  4991. {
  4992. arma_extra_debug_sigprint();
  4993. arrayops::clean(memptr(), n_elem, threshold);
  4994. return *this;
  4995. }
  4996. //! fill the matrix with the specified value
  4997. template<typename eT>
  4998. inline
  4999. const Mat<eT>&
  5000. Mat<eT>::fill(const eT val)
  5001. {
  5002. arma_extra_debug_sigprint();
  5003. arrayops::inplace_set( memptr(), val, n_elem );
  5004. return *this;
  5005. }
  5006. //! fill the matrix with the specified pattern
  5007. template<typename eT>
  5008. template<typename fill_type>
  5009. inline
  5010. const Mat<eT>&
  5011. Mat<eT>::fill(const fill::fill_class<fill_type>&)
  5012. {
  5013. arma_extra_debug_sigprint();
  5014. if(is_same_type<fill_type, fill::fill_zeros>::yes) (*this).zeros();
  5015. if(is_same_type<fill_type, fill::fill_ones >::yes) (*this).ones();
  5016. if(is_same_type<fill_type, fill::fill_eye >::yes) (*this).eye();
  5017. if(is_same_type<fill_type, fill::fill_randu>::yes) (*this).randu();
  5018. if(is_same_type<fill_type, fill::fill_randn>::yes) (*this).randn();
  5019. return *this;
  5020. }
  5021. template<typename eT>
  5022. inline
  5023. const Mat<eT>&
  5024. Mat<eT>::zeros()
  5025. {
  5026. arma_extra_debug_sigprint();
  5027. arrayops::fill_zeros(memptr(), n_elem);
  5028. return *this;
  5029. }
  5030. template<typename eT>
  5031. inline
  5032. const Mat<eT>&
  5033. Mat<eT>::zeros(const uword in_elem)
  5034. {
  5035. arma_extra_debug_sigprint();
  5036. set_size(in_elem);
  5037. return (*this).zeros();
  5038. }
  5039. template<typename eT>
  5040. inline
  5041. const Mat<eT>&
  5042. Mat<eT>::zeros(const uword in_n_rows, const uword in_n_cols)
  5043. {
  5044. arma_extra_debug_sigprint();
  5045. set_size(in_n_rows, in_n_cols);
  5046. return (*this).zeros();
  5047. }
  5048. template<typename eT>
  5049. inline
  5050. const Mat<eT>&
  5051. Mat<eT>::zeros(const SizeMat& s)
  5052. {
  5053. arma_extra_debug_sigprint();
  5054. return (*this).zeros(s.n_rows, s.n_cols);
  5055. }
  5056. template<typename eT>
  5057. inline
  5058. const Mat<eT>&
  5059. Mat<eT>::ones()
  5060. {
  5061. arma_extra_debug_sigprint();
  5062. return fill(eT(1));
  5063. }
  5064. template<typename eT>
  5065. inline
  5066. const Mat<eT>&
  5067. Mat<eT>::ones(const uword in_elem)
  5068. {
  5069. arma_extra_debug_sigprint();
  5070. set_size(in_elem);
  5071. return fill(eT(1));
  5072. }
  5073. template<typename eT>
  5074. inline
  5075. const Mat<eT>&
  5076. Mat<eT>::ones(const uword in_rows, const uword in_cols)
  5077. {
  5078. arma_extra_debug_sigprint();
  5079. set_size(in_rows, in_cols);
  5080. return fill(eT(1));
  5081. }
  5082. template<typename eT>
  5083. inline
  5084. const Mat<eT>&
  5085. Mat<eT>::ones(const SizeMat& s)
  5086. {
  5087. arma_extra_debug_sigprint();
  5088. return (*this).ones(s.n_rows, s.n_cols);
  5089. }
  5090. template<typename eT>
  5091. inline
  5092. const Mat<eT>&
  5093. Mat<eT>::randu()
  5094. {
  5095. arma_extra_debug_sigprint();
  5096. arma_rng::randu<eT>::fill( memptr(), n_elem );
  5097. return *this;
  5098. }
  5099. template<typename eT>
  5100. inline
  5101. const Mat<eT>&
  5102. Mat<eT>::randu(const uword in_elem)
  5103. {
  5104. arma_extra_debug_sigprint();
  5105. set_size(in_elem);
  5106. return (*this).randu();
  5107. }
  5108. template<typename eT>
  5109. inline
  5110. const Mat<eT>&
  5111. Mat<eT>::randu(const uword in_rows, const uword in_cols)
  5112. {
  5113. arma_extra_debug_sigprint();
  5114. set_size(in_rows, in_cols);
  5115. return (*this).randu();
  5116. }
  5117. template<typename eT>
  5118. inline
  5119. const Mat<eT>&
  5120. Mat<eT>::randu(const SizeMat& s)
  5121. {
  5122. arma_extra_debug_sigprint();
  5123. return (*this).randu(s.n_rows, s.n_cols);
  5124. }
  5125. template<typename eT>
  5126. inline
  5127. const Mat<eT>&
  5128. Mat<eT>::randn()
  5129. {
  5130. arma_extra_debug_sigprint();
  5131. arma_rng::randn<eT>::fill( memptr(), n_elem );
  5132. return *this;
  5133. }
  5134. template<typename eT>
  5135. inline
  5136. const Mat<eT>&
  5137. Mat<eT>::randn(const uword in_elem)
  5138. {
  5139. arma_extra_debug_sigprint();
  5140. set_size(in_elem);
  5141. return (*this).randn();
  5142. }
  5143. template<typename eT>
  5144. inline
  5145. const Mat<eT>&
  5146. Mat<eT>::randn(const uword in_rows, const uword in_cols)
  5147. {
  5148. arma_extra_debug_sigprint();
  5149. set_size(in_rows, in_cols);
  5150. return (*this).randn();
  5151. }
  5152. template<typename eT>
  5153. inline
  5154. const Mat<eT>&
  5155. Mat<eT>::randn(const SizeMat& s)
  5156. {
  5157. arma_extra_debug_sigprint();
  5158. return (*this).randn(s.n_rows, s.n_cols);
  5159. }
  5160. template<typename eT>
  5161. inline
  5162. const Mat<eT>&
  5163. Mat<eT>::eye()
  5164. {
  5165. arma_extra_debug_sigprint();
  5166. (*this).zeros();
  5167. const uword N = (std::min)(n_rows, n_cols);
  5168. for(uword ii=0; ii<N; ++ii)
  5169. {
  5170. at(ii,ii) = eT(1);
  5171. }
  5172. return *this;
  5173. }
  5174. template<typename eT>
  5175. inline
  5176. const Mat<eT>&
  5177. Mat<eT>::eye(const uword in_rows, const uword in_cols)
  5178. {
  5179. arma_extra_debug_sigprint();
  5180. set_size(in_rows, in_cols);
  5181. return (*this).eye();
  5182. }
  5183. template<typename eT>
  5184. inline
  5185. const Mat<eT>&
  5186. Mat<eT>::eye(const SizeMat& s)
  5187. {
  5188. arma_extra_debug_sigprint();
  5189. return (*this).eye(s.n_rows, s.n_cols);
  5190. }
  5191. template<typename eT>
  5192. inline
  5193. arma_cold
  5194. void
  5195. Mat<eT>::reset()
  5196. {
  5197. arma_extra_debug_sigprint();
  5198. switch(vec_state)
  5199. {
  5200. default:
  5201. init_warm(0, 0);
  5202. break;
  5203. case 1:
  5204. init_warm(0, 1);
  5205. break;
  5206. case 2:
  5207. init_warm(1, 0);
  5208. break;
  5209. }
  5210. }
  5211. template<typename eT>
  5212. inline
  5213. arma_cold
  5214. void
  5215. Mat<eT>::soft_reset()
  5216. {
  5217. arma_extra_debug_sigprint();
  5218. // don't change the size if the matrix has a fixed size or is a cube slice
  5219. if(mem_state <= 1)
  5220. {
  5221. reset();
  5222. }
  5223. else
  5224. {
  5225. fill(Datum<eT>::nan);
  5226. }
  5227. }
  5228. template<typename eT>
  5229. template<typename T1>
  5230. inline
  5231. void
  5232. Mat<eT>::set_real(const Base<typename Mat<eT>::pod_type,T1>& X)
  5233. {
  5234. arma_extra_debug_sigprint();
  5235. Mat_aux::set_real(*this, X);
  5236. }
  5237. template<typename eT>
  5238. template<typename T1>
  5239. inline
  5240. void
  5241. Mat<eT>::set_imag(const Base<typename Mat<eT>::pod_type,T1>& X)
  5242. {
  5243. arma_extra_debug_sigprint();
  5244. Mat_aux::set_imag(*this, X);
  5245. }
  5246. template<typename eT>
  5247. inline
  5248. arma_warn_unused
  5249. eT
  5250. Mat<eT>::min() const
  5251. {
  5252. arma_extra_debug_sigprint();
  5253. if(n_elem == 0)
  5254. {
  5255. arma_debug_check(true, "Mat::min(): object has no elements");
  5256. return Datum<eT>::nan;
  5257. }
  5258. return op_min::direct_min(memptr(), n_elem);
  5259. }
  5260. template<typename eT>
  5261. inline
  5262. arma_warn_unused
  5263. eT
  5264. Mat<eT>::max() const
  5265. {
  5266. arma_extra_debug_sigprint();
  5267. if(n_elem == 0)
  5268. {
  5269. arma_debug_check(true, "Mat::max(): object has no elements");
  5270. return Datum<eT>::nan;
  5271. }
  5272. return op_max::direct_max(memptr(), n_elem);
  5273. }
  5274. template<typename eT>
  5275. inline
  5276. eT
  5277. Mat<eT>::min(uword& index_of_min_val) const
  5278. {
  5279. arma_extra_debug_sigprint();
  5280. if(n_elem == 0)
  5281. {
  5282. arma_debug_check(true, "Mat::min(): object has no elements");
  5283. index_of_min_val = uword(0);
  5284. return Datum<eT>::nan;
  5285. }
  5286. return op_min::direct_min(memptr(), n_elem, index_of_min_val);
  5287. }
  5288. template<typename eT>
  5289. inline
  5290. eT
  5291. Mat<eT>::max(uword& index_of_max_val) const
  5292. {
  5293. arma_extra_debug_sigprint();
  5294. if(n_elem == 0)
  5295. {
  5296. arma_debug_check(true, "Mat::max(): object has no elements");
  5297. index_of_max_val = uword(0);
  5298. return Datum<eT>::nan;
  5299. }
  5300. return op_max::direct_max(memptr(), n_elem, index_of_max_val);
  5301. }
  5302. template<typename eT>
  5303. inline
  5304. eT
  5305. Mat<eT>::min(uword& row_of_min_val, uword& col_of_min_val) const
  5306. {
  5307. arma_extra_debug_sigprint();
  5308. if(n_elem == 0)
  5309. {
  5310. arma_debug_check(true, "Mat::min(): object has no elements");
  5311. row_of_min_val = uword(0);
  5312. col_of_min_val = uword(0);
  5313. return Datum<eT>::nan;
  5314. }
  5315. uword iq;
  5316. eT val = op_min::direct_min(memptr(), n_elem, iq);
  5317. row_of_min_val = iq % n_rows;
  5318. col_of_min_val = iq / n_rows;
  5319. return val;
  5320. }
  5321. template<typename eT>
  5322. inline
  5323. eT
  5324. Mat<eT>::max(uword& row_of_max_val, uword& col_of_max_val) const
  5325. {
  5326. arma_extra_debug_sigprint();
  5327. if(n_elem == 0)
  5328. {
  5329. arma_debug_check(true, "Mat::max(): object has no elements");
  5330. row_of_max_val = uword(0);
  5331. col_of_max_val = uword(0);
  5332. return Datum<eT>::nan;
  5333. }
  5334. uword iq;
  5335. eT val = op_max::direct_max(memptr(), n_elem, iq);
  5336. row_of_max_val = iq % n_rows;
  5337. col_of_max_val = iq / n_rows;
  5338. return val;
  5339. }
  5340. //! save the matrix to a file
  5341. template<typename eT>
  5342. inline
  5343. arma_cold
  5344. bool
  5345. Mat<eT>::save(const std::string name, const file_type type, const bool print_status) const
  5346. {
  5347. arma_extra_debug_sigprint();
  5348. bool save_okay = false;
  5349. switch(type)
  5350. {
  5351. case raw_ascii:
  5352. save_okay = diskio::save_raw_ascii(*this, name);
  5353. break;
  5354. case arma_ascii:
  5355. save_okay = diskio::save_arma_ascii(*this, name);
  5356. break;
  5357. case csv_ascii:
  5358. return (*this).save(csv_name(name), type, print_status);
  5359. break;
  5360. case raw_binary:
  5361. save_okay = diskio::save_raw_binary(*this, name);
  5362. break;
  5363. case arma_binary:
  5364. save_okay = diskio::save_arma_binary(*this, name);
  5365. break;
  5366. case pgm_binary:
  5367. save_okay = diskio::save_pgm_binary(*this, name);
  5368. break;
  5369. case hdf5_binary:
  5370. return (*this).save(hdf5_name(name));
  5371. break;
  5372. case hdf5_binary_trans: // kept for compatibility with earlier versions of Armadillo
  5373. return (*this).save(hdf5_name(name, std::string(), hdf5_opts::trans));
  5374. break;
  5375. default:
  5376. if(print_status) { arma_debug_warn("Mat::save(): unsupported file type"); }
  5377. save_okay = false;
  5378. }
  5379. if(print_status && (save_okay == false)) { arma_debug_warn("Mat::save(): couldn't write to ", name); }
  5380. return save_okay;
  5381. }
  5382. template<typename eT>
  5383. inline
  5384. arma_cold
  5385. bool
  5386. Mat<eT>::save(const hdf5_name& spec, const file_type type, const bool print_status) const
  5387. {
  5388. arma_extra_debug_sigprint();
  5389. // handling of hdf5_binary_trans kept for compatibility with earlier versions of Armadillo
  5390. if( (type != hdf5_binary) && (type != hdf5_binary_trans) )
  5391. {
  5392. arma_debug_check(true, "Mat::save(): unsupported file type for hdf5_name()");
  5393. return false;
  5394. }
  5395. const bool do_trans = bool(spec.opts.flags & hdf5_opts::flag_trans ) || (type == hdf5_binary_trans);
  5396. const bool append = bool(spec.opts.flags & hdf5_opts::flag_append );
  5397. const bool replace = bool(spec.opts.flags & hdf5_opts::flag_replace);
  5398. if(append && replace)
  5399. {
  5400. arma_debug_check(true, "Mat::save(): only one of 'append' or 'replace' options can be used");
  5401. return false;
  5402. }
  5403. bool save_okay = false;
  5404. std::string err_msg;
  5405. if(do_trans)
  5406. {
  5407. Mat<eT> tmp;
  5408. op_strans::apply_mat_noalias(tmp, *this);
  5409. save_okay = diskio::save_hdf5_binary(tmp, spec, err_msg);
  5410. }
  5411. else
  5412. {
  5413. save_okay = diskio::save_hdf5_binary(*this, spec, err_msg);
  5414. }
  5415. if((print_status == true) && (save_okay == false))
  5416. {
  5417. if(err_msg.length() > 0)
  5418. {
  5419. arma_debug_warn("Mat::save(): ", err_msg, spec.filename);
  5420. }
  5421. else
  5422. {
  5423. arma_debug_warn("Mat::save(): couldn't write to ", spec.filename);
  5424. }
  5425. }
  5426. return save_okay;
  5427. }
  5428. template<typename eT>
  5429. inline
  5430. arma_cold
  5431. bool
  5432. Mat<eT>::save(const csv_name& spec, const file_type type, const bool print_status) const
  5433. {
  5434. arma_extra_debug_sigprint();
  5435. if(type != csv_ascii)
  5436. {
  5437. arma_debug_check(true, "Mat::save(): unsupported file type for csv_name()");
  5438. return false;
  5439. }
  5440. const bool do_trans = bool(spec.opts.flags & csv_opts::flag_trans );
  5441. const bool no_header = bool(spec.opts.flags & csv_opts::flag_no_header );
  5442. bool with_header = bool(spec.opts.flags & csv_opts::flag_with_header);
  5443. arma_extra_debug_print("Mat::save(csv_name): enabled flags:");
  5444. if(do_trans ) { arma_extra_debug_print("trans"); }
  5445. if(no_header ) { arma_extra_debug_print("no_header"); }
  5446. if(with_header) { arma_extra_debug_print("with_header"); }
  5447. if(no_header) { with_header = false; }
  5448. if(with_header)
  5449. {
  5450. if( (spec.header_ro.n_cols != 1) && (spec.header_ro.n_rows != 1) )
  5451. {
  5452. if(print_status) { arma_debug_warn("Mat::save(): given header must have a vector layout"); }
  5453. return false;
  5454. }
  5455. for(uword i=0; i < spec.header_ro.n_elem; ++i)
  5456. {
  5457. const std::string& token = spec.header_ro.at(i);
  5458. if(token.find(',') != std::string::npos)
  5459. {
  5460. if(print_status) { arma_debug_warn("Mat::save(): token within the header contains a comma: '", token, "'"); }
  5461. return false;
  5462. }
  5463. }
  5464. const uword save_n_cols = (do_trans) ? (*this).n_rows : (*this).n_cols;
  5465. if(spec.header_ro.n_elem != save_n_cols)
  5466. {
  5467. if(print_status) { arma_debug_warn("Mat::save(): size mistmach between header and matrix"); }
  5468. return false;
  5469. }
  5470. }
  5471. bool save_okay = false;
  5472. if(do_trans)
  5473. {
  5474. const Mat<eT> tmp = (*this).st();
  5475. save_okay = diskio::save_csv_ascii(tmp, spec.filename, spec.header_ro, with_header);
  5476. }
  5477. else
  5478. {
  5479. save_okay = diskio::save_csv_ascii(*this, spec.filename, spec.header_ro, with_header);
  5480. }
  5481. if((print_status == true) && (save_okay == false))
  5482. {
  5483. arma_debug_warn("Mat::save(): couldn't write to ", spec.filename);
  5484. }
  5485. return save_okay;
  5486. }
  5487. //! save the matrix to a stream
  5488. template<typename eT>
  5489. inline
  5490. arma_cold
  5491. bool
  5492. Mat<eT>::save(std::ostream& os, const file_type type, const bool print_status) const
  5493. {
  5494. arma_extra_debug_sigprint();
  5495. bool save_okay = false;
  5496. switch(type)
  5497. {
  5498. case raw_ascii:
  5499. save_okay = diskio::save_raw_ascii(*this, os);
  5500. break;
  5501. case arma_ascii:
  5502. save_okay = diskio::save_arma_ascii(*this, os);
  5503. break;
  5504. case csv_ascii:
  5505. save_okay = diskio::save_csv_ascii(*this, os);
  5506. break;
  5507. case raw_binary:
  5508. save_okay = diskio::save_raw_binary(*this, os);
  5509. break;
  5510. case arma_binary:
  5511. save_okay = diskio::save_arma_binary(*this, os);
  5512. break;
  5513. case pgm_binary:
  5514. save_okay = diskio::save_pgm_binary(*this, os);
  5515. break;
  5516. default:
  5517. if(print_status) { arma_debug_warn("Mat::save(): unsupported file type"); }
  5518. save_okay = false;
  5519. }
  5520. if(print_status && (save_okay == false)) { arma_debug_warn("Mat::save(): couldn't write to the given stream"); }
  5521. return save_okay;
  5522. }
  5523. //! load a matrix from a file
  5524. template<typename eT>
  5525. inline
  5526. arma_cold
  5527. bool
  5528. Mat<eT>::load(const std::string name, const file_type type, const bool print_status)
  5529. {
  5530. arma_extra_debug_sigprint();
  5531. bool load_okay = false;
  5532. std::string err_msg;
  5533. switch(type)
  5534. {
  5535. case auto_detect:
  5536. load_okay = diskio::load_auto_detect(*this, name, err_msg);
  5537. break;
  5538. case raw_ascii:
  5539. load_okay = diskio::load_raw_ascii(*this, name, err_msg);
  5540. break;
  5541. case arma_ascii:
  5542. load_okay = diskio::load_arma_ascii(*this, name, err_msg);
  5543. break;
  5544. case csv_ascii:
  5545. return (*this).load(csv_name(name), type, print_status);
  5546. break;
  5547. case raw_binary:
  5548. load_okay = diskio::load_raw_binary(*this, name, err_msg);
  5549. break;
  5550. case arma_binary:
  5551. load_okay = diskio::load_arma_binary(*this, name, err_msg);
  5552. break;
  5553. case pgm_binary:
  5554. load_okay = diskio::load_pgm_binary(*this, name, err_msg);
  5555. break;
  5556. case hdf5_binary:
  5557. return (*this).load(hdf5_name(name));
  5558. break;
  5559. case hdf5_binary_trans: // kept for compatibility with earlier versions of Armadillo
  5560. return (*this).load(hdf5_name(name, std::string(), hdf5_opts::trans));
  5561. break;
  5562. default:
  5563. if(print_status) { arma_debug_warn("Mat::load(): unsupported file type"); }
  5564. load_okay = false;
  5565. }
  5566. if( (print_status == true) && (load_okay == false) )
  5567. {
  5568. if(err_msg.length() > 0)
  5569. {
  5570. arma_debug_warn("Mat::load(): ", err_msg, name);
  5571. }
  5572. else
  5573. {
  5574. arma_debug_warn("Mat::load(): couldn't read ", name);
  5575. }
  5576. }
  5577. if(load_okay == false)
  5578. {
  5579. (*this).soft_reset();
  5580. }
  5581. return load_okay;
  5582. }
  5583. template<typename eT>
  5584. inline
  5585. arma_cold
  5586. bool
  5587. Mat<eT>::load(const hdf5_name& spec, const file_type type, const bool print_status)
  5588. {
  5589. arma_extra_debug_sigprint();
  5590. if( (type != hdf5_binary) && (type != hdf5_binary_trans) )
  5591. {
  5592. if(print_status) { arma_debug_warn("Mat::load(): unsupported file type for hdf5_name()"); }
  5593. (*this).soft_reset();
  5594. return false;
  5595. }
  5596. bool load_okay = false;
  5597. std::string err_msg;
  5598. const bool do_trans = bool(spec.opts.flags & hdf5_opts::flag_trans) || (type == hdf5_binary_trans);
  5599. if(do_trans)
  5600. {
  5601. Mat<eT> tmp;
  5602. load_okay = diskio::load_hdf5_binary(tmp, spec, err_msg);
  5603. if(load_okay) { op_strans::apply_mat_noalias(*this, tmp); }
  5604. }
  5605. else
  5606. {
  5607. load_okay = diskio::load_hdf5_binary(*this, spec, err_msg);
  5608. }
  5609. if( (print_status == true) && (load_okay == false) )
  5610. {
  5611. if(err_msg.length() > 0)
  5612. {
  5613. arma_debug_warn("Mat::load(): ", err_msg, spec.filename);
  5614. }
  5615. else
  5616. {
  5617. arma_debug_warn("Mat::load(): couldn't read ", spec.filename);
  5618. }
  5619. }
  5620. if(load_okay == false)
  5621. {
  5622. (*this).soft_reset();
  5623. }
  5624. return load_okay;
  5625. }
  5626. template<typename eT>
  5627. inline
  5628. arma_cold
  5629. bool
  5630. Mat<eT>::load(const csv_name& spec, const file_type type, const bool print_status)
  5631. {
  5632. arma_extra_debug_sigprint();
  5633. if(type != csv_ascii)
  5634. {
  5635. arma_debug_check(true, "Mat::load(): unsupported file type for csv_name()");
  5636. return false;
  5637. }
  5638. const bool do_trans = bool(spec.opts.flags & csv_opts::flag_trans );
  5639. const bool no_header = bool(spec.opts.flags & csv_opts::flag_no_header );
  5640. bool with_header = bool(spec.opts.flags & csv_opts::flag_with_header);
  5641. arma_extra_debug_print("Mat::load(csv_name): enabled flags:");
  5642. if(do_trans ) { arma_extra_debug_print("trans"); }
  5643. if(no_header ) { arma_extra_debug_print("no_header"); }
  5644. if(with_header) { arma_extra_debug_print("with_header"); }
  5645. if(no_header) { with_header = false; }
  5646. bool load_okay = false;
  5647. std::string err_msg;
  5648. if(do_trans)
  5649. {
  5650. Mat<eT> tmp_mat;
  5651. load_okay = diskio::load_csv_ascii(tmp_mat, spec.filename, err_msg, spec.header_rw, with_header);
  5652. if(load_okay)
  5653. {
  5654. (*this) = tmp_mat.st();
  5655. if(with_header)
  5656. {
  5657. // field::set_size() preserves data if the number of elements hasn't changed
  5658. spec.header_rw.set_size(spec.header_rw.n_elem, 1);
  5659. }
  5660. }
  5661. }
  5662. else
  5663. {
  5664. load_okay = diskio::load_csv_ascii(*this, spec.filename, err_msg, spec.header_rw, with_header);
  5665. }
  5666. if(print_status)
  5667. {
  5668. if(load_okay == false)
  5669. {
  5670. if(err_msg.length() > 0)
  5671. {
  5672. arma_debug_warn("Mat::load(): ", err_msg, spec.filename);
  5673. }
  5674. else
  5675. {
  5676. arma_debug_warn("Mat::load(): couldn't read ", spec.filename);
  5677. }
  5678. }
  5679. else
  5680. {
  5681. const uword load_n_cols = (do_trans) ? (*this).n_rows : (*this).n_cols;
  5682. if(with_header && (spec.header_rw.n_elem != load_n_cols))
  5683. {
  5684. arma_debug_warn("Mat::load(): size mistmach between header and matrix");
  5685. }
  5686. }
  5687. }
  5688. if(load_okay == false)
  5689. {
  5690. (*this).soft_reset();
  5691. if(with_header) { spec.header_rw.reset(); }
  5692. }
  5693. return load_okay;
  5694. }
  5695. //! load a matrix from a stream
  5696. template<typename eT>
  5697. inline
  5698. arma_cold
  5699. bool
  5700. Mat<eT>::load(std::istream& is, const file_type type, const bool print_status)
  5701. {
  5702. arma_extra_debug_sigprint();
  5703. bool load_okay = false;
  5704. std::string err_msg;
  5705. switch(type)
  5706. {
  5707. case auto_detect:
  5708. load_okay = diskio::load_auto_detect(*this, is, err_msg);
  5709. break;
  5710. case raw_ascii:
  5711. load_okay = diskio::load_raw_ascii(*this, is, err_msg);
  5712. break;
  5713. case arma_ascii:
  5714. load_okay = diskio::load_arma_ascii(*this, is, err_msg);
  5715. break;
  5716. case csv_ascii:
  5717. load_okay = diskio::load_csv_ascii(*this, is, err_msg);
  5718. break;
  5719. case raw_binary:
  5720. load_okay = diskio::load_raw_binary(*this, is, err_msg);
  5721. break;
  5722. case arma_binary:
  5723. load_okay = diskio::load_arma_binary(*this, is, err_msg);
  5724. break;
  5725. case pgm_binary:
  5726. load_okay = diskio::load_pgm_binary(*this, is, err_msg);
  5727. break;
  5728. default:
  5729. if(print_status) { arma_debug_warn("Mat::load(): unsupported file type"); }
  5730. load_okay = false;
  5731. }
  5732. if( (print_status == true) && (load_okay == false) )
  5733. {
  5734. if(err_msg.length() > 0)
  5735. {
  5736. arma_debug_warn("Mat::load(): ", err_msg, "the given stream");
  5737. }
  5738. else
  5739. {
  5740. arma_debug_warn("Mat::load(): couldn't load from the given stream");
  5741. }
  5742. }
  5743. if(load_okay == false)
  5744. {
  5745. (*this).soft_reset();
  5746. }
  5747. return load_okay;
  5748. }
  5749. //! save the matrix to a file, without printing any error messages
  5750. template<typename eT>
  5751. inline
  5752. arma_cold
  5753. bool
  5754. Mat<eT>::quiet_save(const std::string name, const file_type type) const
  5755. {
  5756. arma_extra_debug_sigprint();
  5757. return (*this).save(name, type, false);
  5758. }
  5759. template<typename eT>
  5760. inline
  5761. arma_cold
  5762. bool
  5763. Mat<eT>::quiet_save(const hdf5_name& spec, const file_type type) const
  5764. {
  5765. arma_extra_debug_sigprint();
  5766. return (*this).save(spec, type, false);
  5767. }
  5768. template<typename eT>
  5769. inline
  5770. arma_cold
  5771. bool
  5772. Mat<eT>::quiet_save(const csv_name& spec, const file_type type) const
  5773. {
  5774. arma_extra_debug_sigprint();
  5775. return (*this).save(spec, type, false);
  5776. }
  5777. //! save the matrix to a stream, without printing any error messages
  5778. template<typename eT>
  5779. inline
  5780. arma_cold
  5781. bool
  5782. Mat<eT>::quiet_save(std::ostream& os, const file_type type) const
  5783. {
  5784. arma_extra_debug_sigprint();
  5785. return (*this).save(os, type, false);
  5786. }
  5787. //! load a matrix from a file, without printing any error messages
  5788. template<typename eT>
  5789. inline
  5790. arma_cold
  5791. bool
  5792. Mat<eT>::quiet_load(const std::string name, const file_type type)
  5793. {
  5794. arma_extra_debug_sigprint();
  5795. return (*this).load(name, type, false);
  5796. }
  5797. template<typename eT>
  5798. inline
  5799. arma_cold
  5800. bool
  5801. Mat<eT>::quiet_load(const hdf5_name& spec, const file_type type)
  5802. {
  5803. arma_extra_debug_sigprint();
  5804. return (*this).load(spec, type, false);
  5805. }
  5806. template<typename eT>
  5807. inline
  5808. arma_cold
  5809. bool
  5810. Mat<eT>::quiet_load(const csv_name& spec, const file_type type)
  5811. {
  5812. arma_extra_debug_sigprint();
  5813. return (*this).load(spec, type, false);
  5814. }
  5815. //! load a matrix from a stream, without printing any error messages
  5816. template<typename eT>
  5817. inline
  5818. arma_cold
  5819. bool
  5820. Mat<eT>::quiet_load(std::istream& is, const file_type type)
  5821. {
  5822. arma_extra_debug_sigprint();
  5823. return (*this).load(is, type, false);
  5824. }
  5825. template<typename eT>
  5826. inline
  5827. Mat<eT>::row_iterator::row_iterator()
  5828. : M (NULL)
  5829. , current_row(0 )
  5830. , current_col(0 )
  5831. {
  5832. arma_extra_debug_sigprint();
  5833. // Technically this iterator is invalid (it does not point to a valid element)
  5834. }
  5835. template<typename eT>
  5836. inline
  5837. Mat<eT>::row_iterator::row_iterator(const row_iterator& X)
  5838. : M (X.M )
  5839. , current_row(X.current_row)
  5840. , current_col(X.current_col)
  5841. {
  5842. arma_extra_debug_sigprint();
  5843. }
  5844. template<typename eT>
  5845. inline
  5846. Mat<eT>::row_iterator::row_iterator(Mat<eT>& in_M, const uword in_row, const uword in_col)
  5847. : M (&in_M )
  5848. , current_row(in_row)
  5849. , current_col(in_col)
  5850. {
  5851. arma_extra_debug_sigprint();
  5852. }
  5853. template<typename eT>
  5854. inline
  5855. arma_warn_unused
  5856. eT&
  5857. Mat<eT>::row_iterator::operator*()
  5858. {
  5859. return M->at(current_row,current_col);
  5860. }
  5861. template<typename eT>
  5862. inline
  5863. typename Mat<eT>::row_iterator&
  5864. Mat<eT>::row_iterator::operator++()
  5865. {
  5866. current_col++;
  5867. if(current_col == M->n_cols)
  5868. {
  5869. current_col = 0;
  5870. current_row++;
  5871. }
  5872. return *this;
  5873. }
  5874. template<typename eT>
  5875. inline
  5876. arma_warn_unused
  5877. typename Mat<eT>::row_iterator
  5878. Mat<eT>::row_iterator::operator++(int)
  5879. {
  5880. typename Mat<eT>::row_iterator temp(*this);
  5881. ++(*this);
  5882. return temp;
  5883. }
  5884. template<typename eT>
  5885. inline
  5886. typename Mat<eT>::row_iterator&
  5887. Mat<eT>::row_iterator::operator--()
  5888. {
  5889. if(current_col > 0)
  5890. {
  5891. current_col--;
  5892. }
  5893. else
  5894. {
  5895. if(current_row > 0)
  5896. {
  5897. current_col = M->n_cols - 1;
  5898. current_row--;
  5899. }
  5900. }
  5901. return *this;
  5902. }
  5903. template<typename eT>
  5904. inline
  5905. arma_warn_unused
  5906. typename Mat<eT>::row_iterator
  5907. Mat<eT>::row_iterator::operator--(int)
  5908. {
  5909. typename Mat<eT>::row_iterator temp(*this);
  5910. --(*this);
  5911. return temp;
  5912. }
  5913. template<typename eT>
  5914. inline
  5915. arma_warn_unused
  5916. bool
  5917. Mat<eT>::row_iterator::operator!=(const typename Mat<eT>::row_iterator& X) const
  5918. {
  5919. return ( (current_row != X.current_row) || (current_col != X.current_col) );
  5920. }
  5921. template<typename eT>
  5922. inline
  5923. arma_warn_unused
  5924. bool
  5925. Mat<eT>::row_iterator::operator==(const typename Mat<eT>::row_iterator& X) const
  5926. {
  5927. return ( (current_row == X.current_row) && (current_col == X.current_col) );
  5928. }
  5929. template<typename eT>
  5930. inline
  5931. arma_warn_unused
  5932. bool
  5933. Mat<eT>::row_iterator::operator!=(const typename Mat<eT>::const_row_iterator& X) const
  5934. {
  5935. return ( (current_row != X.current_row) || (current_col != X.current_col) );
  5936. }
  5937. template<typename eT>
  5938. inline
  5939. arma_warn_unused
  5940. bool
  5941. Mat<eT>::row_iterator::operator==(const typename Mat<eT>::const_row_iterator& X) const
  5942. {
  5943. return ( (current_row == X.current_row) && (current_col == X.current_col) );
  5944. }
  5945. template<typename eT>
  5946. inline
  5947. Mat<eT>::const_row_iterator::const_row_iterator()
  5948. : M (NULL)
  5949. , current_row(0 )
  5950. , current_col(0 )
  5951. {
  5952. arma_extra_debug_sigprint();
  5953. // Technically this iterator is invalid (it does not point to a valid element)
  5954. }
  5955. template<typename eT>
  5956. inline
  5957. Mat<eT>::const_row_iterator::const_row_iterator(const typename Mat<eT>::row_iterator& X)
  5958. : M (X.M )
  5959. , current_row(X.current_row)
  5960. , current_col(X.current_col)
  5961. {
  5962. arma_extra_debug_sigprint();
  5963. }
  5964. template<typename eT>
  5965. inline
  5966. Mat<eT>::const_row_iterator::const_row_iterator(const typename Mat<eT>::const_row_iterator& X)
  5967. : M (X.M )
  5968. , current_row(X.current_row)
  5969. , current_col(X.current_col)
  5970. {
  5971. arma_extra_debug_sigprint();
  5972. }
  5973. template<typename eT>
  5974. inline
  5975. Mat<eT>::const_row_iterator::const_row_iterator(const Mat<eT>& in_M, const uword in_row, const uword in_col)
  5976. : M (&in_M )
  5977. , current_row(in_row)
  5978. , current_col(in_col)
  5979. {
  5980. arma_extra_debug_sigprint();
  5981. }
  5982. template<typename eT>
  5983. inline
  5984. arma_warn_unused
  5985. const eT&
  5986. Mat<eT>::const_row_iterator::operator*() const
  5987. {
  5988. return M->at(current_row,current_col);
  5989. }
  5990. template<typename eT>
  5991. inline
  5992. typename Mat<eT>::const_row_iterator&
  5993. Mat<eT>::const_row_iterator::operator++()
  5994. {
  5995. current_col++;
  5996. if(current_col == M->n_cols)
  5997. {
  5998. current_col = 0;
  5999. current_row++;
  6000. }
  6001. return *this;
  6002. }
  6003. template<typename eT>
  6004. inline
  6005. arma_warn_unused
  6006. typename Mat<eT>::const_row_iterator
  6007. Mat<eT>::const_row_iterator::operator++(int)
  6008. {
  6009. typename Mat<eT>::const_row_iterator temp(*this);
  6010. ++(*this);
  6011. return temp;
  6012. }
  6013. template<typename eT>
  6014. inline
  6015. typename Mat<eT>::const_row_iterator&
  6016. Mat<eT>::const_row_iterator::operator--()
  6017. {
  6018. if(current_col > 0)
  6019. {
  6020. current_col--;
  6021. }
  6022. else
  6023. {
  6024. if(current_row > 0)
  6025. {
  6026. current_col = M->n_cols - 1;
  6027. current_row--;
  6028. }
  6029. }
  6030. return *this;
  6031. }
  6032. template<typename eT>
  6033. inline
  6034. arma_warn_unused
  6035. typename Mat<eT>::const_row_iterator
  6036. Mat<eT>::const_row_iterator::operator--(int)
  6037. {
  6038. typename Mat<eT>::const_row_iterator temp(*this);
  6039. --(*this);
  6040. return temp;
  6041. }
  6042. template<typename eT>
  6043. inline
  6044. arma_warn_unused
  6045. bool
  6046. Mat<eT>::const_row_iterator::operator!=(const typename Mat<eT>::row_iterator& X) const
  6047. {
  6048. return ( (current_row != X.current_row) || (current_col != X.current_col) );
  6049. }
  6050. template<typename eT>
  6051. inline
  6052. arma_warn_unused
  6053. bool
  6054. Mat<eT>::const_row_iterator::operator==(const typename Mat<eT>::row_iterator& X) const
  6055. {
  6056. return ( (current_row == X.current_row) && (current_col == X.current_col) );
  6057. }
  6058. template<typename eT>
  6059. inline
  6060. arma_warn_unused
  6061. bool
  6062. Mat<eT>::const_row_iterator::operator!=(const typename Mat<eT>::const_row_iterator& X) const
  6063. {
  6064. return ( (current_row != X.current_row) || (current_col != X.current_col) );
  6065. }
  6066. template<typename eT>
  6067. inline
  6068. arma_warn_unused
  6069. bool
  6070. Mat<eT>::const_row_iterator::operator==(const typename Mat<eT>::const_row_iterator& X) const
  6071. {
  6072. return ( (current_row == X.current_row) && (current_col == X.current_col) );
  6073. }
  6074. template<typename eT>
  6075. inline
  6076. Mat<eT>::row_col_iterator::row_col_iterator()
  6077. : M (NULL)
  6078. , current_ptr(NULL)
  6079. , current_col(0 )
  6080. , current_row(0 )
  6081. {
  6082. arma_extra_debug_sigprint();
  6083. // Technically this iterator is invalid (it does not point to a valid element)
  6084. }
  6085. template<typename eT>
  6086. inline
  6087. Mat<eT>::row_col_iterator::row_col_iterator(const row_col_iterator& in_it)
  6088. : M (in_it.M )
  6089. , current_ptr(in_it.current_ptr)
  6090. , current_col(in_it.current_col)
  6091. , current_row(in_it.current_row)
  6092. {
  6093. arma_extra_debug_sigprint();
  6094. }
  6095. template<typename eT>
  6096. inline
  6097. Mat<eT>::row_col_iterator::row_col_iterator(Mat<eT>& in_M, const uword in_row, const uword in_col)
  6098. : M (&in_M )
  6099. , current_ptr(&in_M.at(in_row,in_col))
  6100. , current_col(in_col )
  6101. , current_row(in_row )
  6102. {
  6103. arma_extra_debug_sigprint();
  6104. }
  6105. template<typename eT>
  6106. inline
  6107. arma_warn_unused
  6108. eT&
  6109. Mat<eT>::row_col_iterator::operator*()
  6110. {
  6111. return *current_ptr;
  6112. }
  6113. template<typename eT>
  6114. inline
  6115. typename Mat<eT>::row_col_iterator&
  6116. Mat<eT>::row_col_iterator::operator++()
  6117. {
  6118. if(current_col < M->n_cols)
  6119. {
  6120. current_ptr++;
  6121. current_row++;
  6122. // Check to see if we moved a column.
  6123. if(current_row == M->n_rows)
  6124. {
  6125. current_col++;
  6126. current_row = 0;
  6127. }
  6128. }
  6129. return *this;
  6130. }
  6131. template<typename eT>
  6132. inline
  6133. arma_warn_unused
  6134. typename Mat<eT>::row_col_iterator
  6135. Mat<eT>::row_col_iterator::operator++(int)
  6136. {
  6137. typename Mat<eT>::row_col_iterator temp(*this);
  6138. ++(*this);
  6139. return temp;
  6140. }
  6141. template<typename eT>
  6142. inline typename Mat<eT>::row_col_iterator&
  6143. Mat<eT>::row_col_iterator::operator--()
  6144. {
  6145. if(current_row > 0)
  6146. {
  6147. current_ptr--;
  6148. current_row--;
  6149. }
  6150. else
  6151. if(current_col > 0)
  6152. {
  6153. current_ptr--;
  6154. current_col--;
  6155. current_row = M->n_rows - 1;
  6156. }
  6157. return *this;
  6158. }
  6159. template<typename eT>
  6160. inline
  6161. arma_warn_unused
  6162. typename Mat<eT>::row_col_iterator
  6163. Mat<eT>::row_col_iterator::operator--(int)
  6164. {
  6165. typename Mat<eT>::row_col_iterator temp(*this);
  6166. --(*this);
  6167. return temp;
  6168. }
  6169. template<typename eT>
  6170. inline
  6171. arma_warn_unused
  6172. uword
  6173. Mat<eT>::row_col_iterator::row() const
  6174. {
  6175. return current_row;
  6176. }
  6177. template<typename eT>
  6178. inline
  6179. arma_warn_unused
  6180. uword
  6181. Mat<eT>::row_col_iterator::col() const
  6182. {
  6183. return current_col;
  6184. }
  6185. template<typename eT>
  6186. inline
  6187. arma_warn_unused
  6188. bool
  6189. Mat<eT>::row_col_iterator::operator==(const row_col_iterator& rhs) const
  6190. {
  6191. return (current_ptr == rhs.current_ptr);
  6192. }
  6193. template<typename eT>
  6194. inline
  6195. arma_warn_unused
  6196. bool
  6197. Mat<eT>::row_col_iterator::operator!=(const row_col_iterator& rhs) const
  6198. {
  6199. return (current_ptr != rhs.current_ptr);
  6200. }
  6201. template<typename eT>
  6202. inline
  6203. arma_warn_unused
  6204. bool
  6205. Mat<eT>::row_col_iterator::operator==(const const_row_col_iterator& rhs) const
  6206. {
  6207. return (current_ptr == rhs.current_ptr);
  6208. }
  6209. template<typename eT>
  6210. inline
  6211. arma_warn_unused
  6212. bool
  6213. Mat<eT>::row_col_iterator::operator!=(const const_row_col_iterator& rhs) const
  6214. {
  6215. return (current_ptr != rhs.current_ptr);
  6216. }
  6217. template<typename eT>
  6218. inline
  6219. Mat<eT>::const_row_col_iterator::const_row_col_iterator()
  6220. : M (NULL)
  6221. , current_ptr(NULL)
  6222. , current_col(0 )
  6223. , current_row(0 )
  6224. {
  6225. arma_extra_debug_sigprint();
  6226. // Technically this iterator is invalid (it does not point to a valid element)
  6227. }
  6228. template<typename eT>
  6229. inline
  6230. Mat<eT>::const_row_col_iterator::const_row_col_iterator(const row_col_iterator& in_it)
  6231. : M (in_it.M )
  6232. , current_ptr(in_it.current_ptr)
  6233. , current_col(in_it.col() )
  6234. , current_row(in_it.row() )
  6235. {
  6236. arma_extra_debug_sigprint();
  6237. }
  6238. template<typename eT>
  6239. inline
  6240. Mat<eT>::const_row_col_iterator::const_row_col_iterator(const const_row_col_iterator& in_it)
  6241. : M (in_it.M )
  6242. , current_ptr(in_it.current_ptr)
  6243. , current_col(in_it.col() )
  6244. , current_row(in_it.row() )
  6245. {
  6246. arma_extra_debug_sigprint();
  6247. }
  6248. template<typename eT>
  6249. inline
  6250. Mat<eT>::const_row_col_iterator::const_row_col_iterator(const Mat<eT>& in_M, const uword in_row, const uword in_col)
  6251. : M (&in_M )
  6252. , current_ptr(&in_M.at(in_row,in_col))
  6253. , current_col(in_col )
  6254. , current_row(in_row )
  6255. {
  6256. arma_extra_debug_sigprint();
  6257. }
  6258. template<typename eT>
  6259. inline
  6260. arma_warn_unused
  6261. const eT&
  6262. Mat<eT>::const_row_col_iterator::operator*() const
  6263. {
  6264. return *current_ptr;
  6265. }
  6266. template<typename eT>
  6267. inline
  6268. typename Mat<eT>::const_row_col_iterator&
  6269. Mat<eT>::const_row_col_iterator::operator++()
  6270. {
  6271. if(current_col < M->n_cols)
  6272. {
  6273. current_ptr++;
  6274. current_row++;
  6275. // Check to see if we moved a column.
  6276. if(current_row == M->n_rows)
  6277. {
  6278. current_col++;
  6279. current_row = 0;
  6280. }
  6281. }
  6282. return *this;
  6283. }
  6284. template<typename eT>
  6285. inline
  6286. arma_warn_unused
  6287. typename Mat<eT>::const_row_col_iterator
  6288. Mat<eT>::const_row_col_iterator::operator++(int)
  6289. {
  6290. typename Mat<eT>::const_row_col_iterator temp(*this);
  6291. ++(*this);
  6292. return temp;
  6293. }
  6294. template<typename eT>
  6295. inline
  6296. typename Mat<eT>::const_row_col_iterator&
  6297. Mat<eT>::const_row_col_iterator::operator--()
  6298. {
  6299. if(current_row > 0)
  6300. {
  6301. current_ptr--;
  6302. current_row--;
  6303. }
  6304. else
  6305. if(current_col > 0)
  6306. {
  6307. current_ptr--;
  6308. current_col--;
  6309. current_row = M->n_rows - 1;
  6310. }
  6311. return *this;
  6312. }
  6313. template<typename eT>
  6314. inline
  6315. arma_warn_unused
  6316. typename Mat<eT>::const_row_col_iterator
  6317. Mat<eT>::const_row_col_iterator::operator--(int)
  6318. {
  6319. typename Mat<eT>::const_row_col_iterator temp(*this);
  6320. --(*this);
  6321. return temp;
  6322. }
  6323. template<typename eT>
  6324. inline
  6325. arma_warn_unused
  6326. uword
  6327. Mat<eT>::const_row_col_iterator::row() const
  6328. {
  6329. return current_row;
  6330. }
  6331. template<typename eT>
  6332. inline
  6333. arma_warn_unused
  6334. uword
  6335. Mat<eT>::const_row_col_iterator::col() const
  6336. {
  6337. return current_col;
  6338. }
  6339. template<typename eT>
  6340. inline
  6341. arma_warn_unused
  6342. bool
  6343. Mat<eT>::const_row_col_iterator::operator==(const const_row_col_iterator& rhs) const
  6344. {
  6345. return (current_ptr == rhs.current_ptr);
  6346. }
  6347. template<typename eT>
  6348. inline
  6349. arma_warn_unused
  6350. bool
  6351. Mat<eT>::const_row_col_iterator::operator!=(const const_row_col_iterator& rhs) const
  6352. {
  6353. return (current_ptr != rhs.current_ptr);
  6354. }
  6355. template<typename eT>
  6356. inline
  6357. arma_warn_unused
  6358. bool
  6359. Mat<eT>::const_row_col_iterator::operator==(const row_col_iterator& rhs) const
  6360. {
  6361. return (current_ptr == rhs.current_ptr);
  6362. }
  6363. template<typename eT>
  6364. inline
  6365. arma_warn_unused
  6366. bool
  6367. Mat<eT>::const_row_col_iterator::operator!=(const row_col_iterator& rhs) const
  6368. {
  6369. return (current_ptr != rhs.current_ptr);
  6370. }
  6371. template<typename eT>
  6372. inline
  6373. typename Mat<eT>::iterator
  6374. Mat<eT>::begin()
  6375. {
  6376. arma_extra_debug_sigprint();
  6377. return memptr();
  6378. }
  6379. template<typename eT>
  6380. inline
  6381. typename Mat<eT>::const_iterator
  6382. Mat<eT>::begin() const
  6383. {
  6384. arma_extra_debug_sigprint();
  6385. return memptr();
  6386. }
  6387. template<typename eT>
  6388. inline
  6389. typename Mat<eT>::const_iterator
  6390. Mat<eT>::cbegin() const
  6391. {
  6392. arma_extra_debug_sigprint();
  6393. return memptr();
  6394. }
  6395. template<typename eT>
  6396. inline
  6397. typename Mat<eT>::iterator
  6398. Mat<eT>::end()
  6399. {
  6400. arma_extra_debug_sigprint();
  6401. return memptr() + n_elem;
  6402. }
  6403. template<typename eT>
  6404. inline
  6405. typename Mat<eT>::const_iterator
  6406. Mat<eT>::end() const
  6407. {
  6408. arma_extra_debug_sigprint();
  6409. return memptr() + n_elem;
  6410. }
  6411. template<typename eT>
  6412. inline
  6413. typename Mat<eT>::const_iterator
  6414. Mat<eT>::cend() const
  6415. {
  6416. arma_extra_debug_sigprint();
  6417. return memptr() + n_elem;
  6418. }
  6419. template<typename eT>
  6420. inline
  6421. typename Mat<eT>::col_iterator
  6422. Mat<eT>::begin_col(const uword col_num)
  6423. {
  6424. arma_extra_debug_sigprint();
  6425. arma_debug_check( (col_num >= n_cols), "Mat::begin_col(): index out of bounds");
  6426. return colptr(col_num);
  6427. }
  6428. template<typename eT>
  6429. inline
  6430. typename Mat<eT>::const_col_iterator
  6431. Mat<eT>::begin_col(const uword col_num) const
  6432. {
  6433. arma_extra_debug_sigprint();
  6434. arma_debug_check( (col_num >= n_cols), "Mat::begin_col(): index out of bounds");
  6435. return colptr(col_num);
  6436. }
  6437. template<typename eT>
  6438. inline
  6439. typename Mat<eT>::col_iterator
  6440. Mat<eT>::end_col(const uword col_num)
  6441. {
  6442. arma_extra_debug_sigprint();
  6443. arma_debug_check( (col_num >= n_cols), "Mat::end_col(): index out of bounds");
  6444. return colptr(col_num) + n_rows;
  6445. }
  6446. template<typename eT>
  6447. inline
  6448. typename Mat<eT>::const_col_iterator
  6449. Mat<eT>::end_col(const uword col_num) const
  6450. {
  6451. arma_extra_debug_sigprint();
  6452. arma_debug_check( (col_num >= n_cols), "Mat::end_col(): index out of bounds");
  6453. return colptr(col_num) + n_rows;
  6454. }
  6455. template<typename eT>
  6456. inline
  6457. typename Mat<eT>::row_iterator
  6458. Mat<eT>::begin_row(const uword row_num)
  6459. {
  6460. arma_extra_debug_sigprint();
  6461. arma_debug_check( (row_num >= n_rows), "Mat::begin_row(): index out of bounds" );
  6462. return typename Mat<eT>::row_iterator(*this, row_num, uword(0));
  6463. }
  6464. template<typename eT>
  6465. inline
  6466. typename Mat<eT>::const_row_iterator
  6467. Mat<eT>::begin_row(const uword row_num) const
  6468. {
  6469. arma_extra_debug_sigprint();
  6470. arma_debug_check( (row_num >= n_rows), "Mat::begin_row(): index out of bounds" );
  6471. return typename Mat<eT>::const_row_iterator(*this, row_num, uword(0));
  6472. }
  6473. template<typename eT>
  6474. inline
  6475. typename Mat<eT>::row_iterator
  6476. Mat<eT>::end_row(const uword row_num)
  6477. {
  6478. arma_extra_debug_sigprint();
  6479. arma_debug_check( (row_num >= n_rows), "Mat::end_row(): index out of bounds" );
  6480. return typename Mat<eT>::row_iterator(*this, (row_num + uword(1)), 0);
  6481. }
  6482. template<typename eT>
  6483. inline
  6484. typename Mat<eT>::const_row_iterator
  6485. Mat<eT>::end_row(const uword row_num) const
  6486. {
  6487. arma_extra_debug_sigprint();
  6488. arma_debug_check( (row_num >= n_rows), "Mat::end_row(): index out of bounds" );
  6489. return typename Mat<eT>::const_row_iterator(*this, (row_num + uword(1)), 0);
  6490. }
  6491. template<typename eT>
  6492. inline
  6493. typename Mat<eT>::row_col_iterator
  6494. Mat<eT>::begin_row_col()
  6495. {
  6496. return row_col_iterator(*this);
  6497. }
  6498. template<typename eT>
  6499. inline
  6500. typename Mat<eT>::const_row_col_iterator
  6501. Mat<eT>::begin_row_col() const
  6502. {
  6503. return const_row_col_iterator(*this);
  6504. }
  6505. template<typename eT>
  6506. inline typename Mat<eT>::row_col_iterator
  6507. Mat<eT>::end_row_col()
  6508. {
  6509. return row_col_iterator(*this, 0, n_cols);
  6510. }
  6511. template<typename eT>
  6512. inline typename Mat<eT>::const_row_col_iterator
  6513. Mat<eT>::end_row_col() const
  6514. {
  6515. return const_row_col_iterator(*this, 0, n_cols);
  6516. }
  6517. //! resets this matrix to an empty matrix
  6518. template<typename eT>
  6519. inline
  6520. void
  6521. Mat<eT>::clear()
  6522. {
  6523. reset();
  6524. }
  6525. //! returns true if the matrix has no elements
  6526. template<typename eT>
  6527. inline
  6528. bool
  6529. Mat<eT>::empty() const
  6530. {
  6531. return (n_elem == 0);
  6532. }
  6533. //! returns the number of elements in this matrix
  6534. template<typename eT>
  6535. inline
  6536. uword
  6537. Mat<eT>::size() const
  6538. {
  6539. return n_elem;
  6540. }
  6541. template<typename eT>
  6542. inline
  6543. eT&
  6544. Mat<eT>::front()
  6545. {
  6546. arma_debug_check( (n_elem == 0), "Mat::front(): matrix is empty" );
  6547. return access::rw(mem[0]);
  6548. }
  6549. template<typename eT>
  6550. inline
  6551. const eT&
  6552. Mat<eT>::front() const
  6553. {
  6554. arma_debug_check( (n_elem == 0), "Mat::front(): matrix is empty" );
  6555. return mem[0];
  6556. }
  6557. template<typename eT>
  6558. inline
  6559. eT&
  6560. Mat<eT>::back()
  6561. {
  6562. arma_debug_check( (n_elem == 0), "Mat::back(): matrix is empty" );
  6563. return access::rw(mem[n_elem-1]);
  6564. }
  6565. template<typename eT>
  6566. inline
  6567. const eT&
  6568. Mat<eT>::back() const
  6569. {
  6570. arma_debug_check( (n_elem == 0), "Mat::back(): matrix is empty" );
  6571. return mem[n_elem-1];
  6572. }
  6573. template<typename eT>
  6574. template<uword fixed_n_rows, uword fixed_n_cols>
  6575. arma_inline
  6576. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed()
  6577. : Mat<eT>( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
  6578. {
  6579. arma_extra_debug_sigprint_this(this);
  6580. }
  6581. template<typename eT>
  6582. template<uword fixed_n_rows, uword fixed_n_cols>
  6583. arma_inline
  6584. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const fixed<fixed_n_rows, fixed_n_cols>& X)
  6585. : Mat<eT>( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
  6586. {
  6587. arma_extra_debug_sigprint_this(this);
  6588. eT* dest = (use_extra) ? mem_local_extra : mem_local;
  6589. const eT* src = (use_extra) ? X.mem_local_extra : X.mem_local;
  6590. arrayops::copy( dest, src, fixed_n_elem );
  6591. }
  6592. template<typename eT>
  6593. template<uword fixed_n_rows, uword fixed_n_cols>
  6594. template<typename fill_type>
  6595. inline
  6596. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const fill::fill_class<fill_type>&)
  6597. : Mat<eT>( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
  6598. {
  6599. arma_extra_debug_sigprint_this(this);
  6600. if(is_same_type<fill_type, fill::fill_zeros>::yes) (*this).zeros();
  6601. if(is_same_type<fill_type, fill::fill_ones >::yes) (*this).ones();
  6602. if(is_same_type<fill_type, fill::fill_eye >::yes) (*this).eye();
  6603. if(is_same_type<fill_type, fill::fill_randu>::yes) (*this).randu();
  6604. if(is_same_type<fill_type, fill::fill_randn>::yes) (*this).randn();
  6605. }
  6606. template<typename eT>
  6607. template<uword fixed_n_rows, uword fixed_n_cols>
  6608. template<typename T1>
  6609. inline
  6610. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const Base<eT,T1>& A)
  6611. : Mat<eT>( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
  6612. {
  6613. arma_extra_debug_sigprint_this(this);
  6614. Mat<eT>::operator=(A.get_ref());
  6615. }
  6616. template<typename eT>
  6617. template<uword fixed_n_rows, uword fixed_n_cols>
  6618. template<typename T1, typename T2>
  6619. inline
  6620. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const Base<pod_type,T1>& A, const Base<pod_type,T2>& B)
  6621. : Mat<eT>( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
  6622. {
  6623. arma_extra_debug_sigprint_this(this);
  6624. Mat<eT>::init(A,B);
  6625. }
  6626. template<typename eT>
  6627. template<uword fixed_n_rows, uword fixed_n_cols>
  6628. inline
  6629. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const eT* aux_mem)
  6630. : Mat<eT>( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
  6631. {
  6632. arma_extra_debug_sigprint_this(this);
  6633. eT* dest = (use_extra) ? mem_local_extra : mem_local;
  6634. arrayops::copy( dest, aux_mem, fixed_n_elem );
  6635. }
  6636. template<typename eT>
  6637. template<uword fixed_n_rows, uword fixed_n_cols>
  6638. inline
  6639. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const char* text)
  6640. : Mat<eT>( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
  6641. {
  6642. arma_extra_debug_sigprint_this(this);
  6643. Mat<eT>::operator=(text);
  6644. }
  6645. template<typename eT>
  6646. template<uword fixed_n_rows, uword fixed_n_cols>
  6647. inline
  6648. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const std::string& text)
  6649. : Mat<eT>( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
  6650. {
  6651. arma_extra_debug_sigprint_this(this);
  6652. Mat<eT>::operator=(text);
  6653. }
  6654. #if defined(ARMA_USE_CXX11)
  6655. template<typename eT>
  6656. template<uword fixed_n_rows, uword fixed_n_cols>
  6657. inline
  6658. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const std::initializer_list<eT>& list)
  6659. : Mat<eT>( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
  6660. {
  6661. arma_extra_debug_sigprint_this(this);
  6662. (*this).operator=(list);
  6663. }
  6664. template<typename eT>
  6665. template<uword fixed_n_rows, uword fixed_n_cols>
  6666. inline
  6667. Mat<eT>&
  6668. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator=(const std::initializer_list<eT>& list)
  6669. {
  6670. arma_extra_debug_sigprint();
  6671. const uword N = uword(list.size());
  6672. arma_debug_check( (N > fixed_n_elem), "Mat::fixed: initialiser list is too long" );
  6673. eT* this_mem = (*this).memptr();
  6674. arrayops::copy( this_mem, list.begin(), N );
  6675. for(uword iq=N; iq < fixed_n_elem; ++iq) { this_mem[iq] = eT(0); }
  6676. return *this;
  6677. }
  6678. template<typename eT>
  6679. template<uword fixed_n_rows, uword fixed_n_cols>
  6680. inline
  6681. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const std::initializer_list< std::initializer_list<eT> >& list)
  6682. : Mat<eT>( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
  6683. {
  6684. arma_extra_debug_sigprint_this(this);
  6685. Mat<eT>::init(list);
  6686. }
  6687. template<typename eT>
  6688. template<uword fixed_n_rows, uword fixed_n_cols>
  6689. inline
  6690. Mat<eT>&
  6691. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator=(const std::initializer_list< std::initializer_list<eT> >& list)
  6692. {
  6693. arma_extra_debug_sigprint();
  6694. Mat<eT>::init(list);
  6695. return *this;
  6696. }
  6697. #endif
  6698. template<typename eT>
  6699. template<uword fixed_n_rows, uword fixed_n_cols>
  6700. arma_inline
  6701. Mat<eT>&
  6702. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator=(const fixed<fixed_n_rows, fixed_n_cols>& X)
  6703. {
  6704. arma_extra_debug_sigprint();
  6705. if(this != &X)
  6706. {
  6707. eT* dest = (use_extra) ? mem_local_extra : mem_local;
  6708. const eT* src = (use_extra) ? X.mem_local_extra : X.mem_local;
  6709. arrayops::copy( dest, src, fixed_n_elem );
  6710. }
  6711. return *this;
  6712. }
  6713. #if defined(ARMA_GOOD_COMPILER)
  6714. template<typename eT>
  6715. template<uword fixed_n_rows, uword fixed_n_cols>
  6716. template<typename T1, typename eop_type>
  6717. inline
  6718. Mat<eT>&
  6719. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator=(const eOp<T1, eop_type>& X)
  6720. {
  6721. arma_extra_debug_sigprint();
  6722. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  6723. const bool bad_alias = (eOp<T1, eop_type>::proxy_type::has_subview && X.P.is_alias(*this));
  6724. if(bad_alias == false)
  6725. {
  6726. arma_debug_assert_same_size(fixed_n_rows, fixed_n_cols, X.get_n_rows(), X.get_n_cols(), "Mat::fixed::operator=");
  6727. eop_type::apply(*this, X);
  6728. }
  6729. else
  6730. {
  6731. arma_extra_debug_print("bad_alias = true");
  6732. Mat<eT> tmp(X);
  6733. (*this) = tmp;
  6734. }
  6735. return *this;
  6736. }
  6737. template<typename eT>
  6738. template<uword fixed_n_rows, uword fixed_n_cols>
  6739. template<typename T1, typename T2, typename eglue_type>
  6740. inline
  6741. Mat<eT>&
  6742. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator=(const eGlue<T1, T2, eglue_type>& X)
  6743. {
  6744. arma_extra_debug_sigprint();
  6745. arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
  6746. arma_type_check(( is_same_type< eT, typename T2::elem_type >::no ));
  6747. const bool bad_alias =
  6748. (
  6749. (eGlue<T1, T2, eglue_type>::proxy1_type::has_subview && X.P1.is_alias(*this))
  6750. ||
  6751. (eGlue<T1, T2, eglue_type>::proxy2_type::has_subview && X.P2.is_alias(*this))
  6752. );
  6753. if(bad_alias == false)
  6754. {
  6755. arma_debug_assert_same_size(fixed_n_rows, fixed_n_cols, X.get_n_rows(), X.get_n_cols(), "Mat::fixed::operator=");
  6756. eglue_type::apply(*this, X);
  6757. }
  6758. else
  6759. {
  6760. arma_extra_debug_print("bad_alias = true");
  6761. Mat<eT> tmp(X);
  6762. (*this) = tmp;
  6763. }
  6764. return *this;
  6765. }
  6766. #endif
  6767. template<typename eT>
  6768. template<uword fixed_n_rows, uword fixed_n_cols>
  6769. arma_inline
  6770. const Op< typename Mat<eT>::template fixed<fixed_n_rows, fixed_n_cols>::Mat_fixed_type, op_htrans >
  6771. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::t() const
  6772. {
  6773. return Op< typename Mat<eT>::template fixed<fixed_n_rows, fixed_n_cols>::Mat_fixed_type, op_htrans >(*this);
  6774. }
  6775. template<typename eT>
  6776. template<uword fixed_n_rows, uword fixed_n_cols>
  6777. arma_inline
  6778. const Op< typename Mat<eT>::template fixed<fixed_n_rows, fixed_n_cols>::Mat_fixed_type, op_htrans >
  6779. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::ht() const
  6780. {
  6781. return Op< typename Mat<eT>::template fixed<fixed_n_rows, fixed_n_cols>::Mat_fixed_type, op_htrans >(*this);
  6782. }
  6783. template<typename eT>
  6784. template<uword fixed_n_rows, uword fixed_n_cols>
  6785. arma_inline
  6786. const Op< typename Mat<eT>::template fixed<fixed_n_rows, fixed_n_cols>::Mat_fixed_type, op_strans >
  6787. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::st() const
  6788. {
  6789. return Op< typename Mat<eT>::template fixed<fixed_n_rows, fixed_n_cols>::Mat_fixed_type, op_strans >(*this);
  6790. }
  6791. template<typename eT>
  6792. template<uword fixed_n_rows, uword fixed_n_cols>
  6793. arma_inline
  6794. arma_warn_unused
  6795. const eT&
  6796. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::at_alt(const uword ii) const
  6797. {
  6798. #if defined(ARMA_HAVE_ALIGNED_ATTRIBUTE)
  6799. return (use_extra) ? mem_local_extra[ii] : mem_local[ii];
  6800. #else
  6801. const eT* mem_aligned = (use_extra) ? mem_local_extra : mem_local;
  6802. memory::mark_as_aligned(mem_aligned);
  6803. return mem_aligned[ii];
  6804. #endif
  6805. }
  6806. template<typename eT>
  6807. template<uword fixed_n_rows, uword fixed_n_cols>
  6808. arma_inline
  6809. arma_warn_unused
  6810. eT&
  6811. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator[] (const uword ii)
  6812. {
  6813. return (use_extra) ? mem_local_extra[ii] : mem_local[ii];
  6814. }
  6815. template<typename eT>
  6816. template<uword fixed_n_rows, uword fixed_n_cols>
  6817. arma_inline
  6818. arma_warn_unused
  6819. const eT&
  6820. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator[] (const uword ii) const
  6821. {
  6822. return (use_extra) ? mem_local_extra[ii] : mem_local[ii];
  6823. }
  6824. template<typename eT>
  6825. template<uword fixed_n_rows, uword fixed_n_cols>
  6826. arma_inline
  6827. arma_warn_unused
  6828. eT&
  6829. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::at(const uword ii)
  6830. {
  6831. return (use_extra) ? mem_local_extra[ii] : mem_local[ii];
  6832. }
  6833. template<typename eT>
  6834. template<uword fixed_n_rows, uword fixed_n_cols>
  6835. arma_inline
  6836. arma_warn_unused
  6837. const eT&
  6838. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::at(const uword ii) const
  6839. {
  6840. return (use_extra) ? mem_local_extra[ii] : mem_local[ii];
  6841. }
  6842. template<typename eT>
  6843. template<uword fixed_n_rows, uword fixed_n_cols>
  6844. arma_inline
  6845. arma_warn_unused
  6846. eT&
  6847. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator() (const uword ii)
  6848. {
  6849. arma_debug_check( (ii >= fixed_n_elem), "Mat::operator(): index out of bounds");
  6850. return (use_extra) ? mem_local_extra[ii] : mem_local[ii];
  6851. }
  6852. template<typename eT>
  6853. template<uword fixed_n_rows, uword fixed_n_cols>
  6854. arma_inline
  6855. arma_warn_unused
  6856. const eT&
  6857. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator() (const uword ii) const
  6858. {
  6859. arma_debug_check( (ii >= fixed_n_elem), "Mat::operator(): index out of bounds");
  6860. return (use_extra) ? mem_local_extra[ii] : mem_local[ii];
  6861. }
  6862. template<typename eT>
  6863. template<uword fixed_n_rows, uword fixed_n_cols>
  6864. arma_inline
  6865. arma_warn_unused
  6866. eT&
  6867. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::at(const uword in_row, const uword in_col)
  6868. {
  6869. const uword iq = in_row + in_col*fixed_n_rows;
  6870. return (use_extra) ? mem_local_extra[iq] : mem_local[iq];
  6871. }
  6872. template<typename eT>
  6873. template<uword fixed_n_rows, uword fixed_n_cols>
  6874. arma_inline
  6875. arma_warn_unused
  6876. const eT&
  6877. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::at(const uword in_row, const uword in_col) const
  6878. {
  6879. const uword iq = in_row + in_col*fixed_n_rows;
  6880. return (use_extra) ? mem_local_extra[iq] : mem_local[iq];
  6881. }
  6882. template<typename eT>
  6883. template<uword fixed_n_rows, uword fixed_n_cols>
  6884. arma_inline
  6885. arma_warn_unused
  6886. eT&
  6887. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator() (const uword in_row, const uword in_col)
  6888. {
  6889. arma_debug_check( ((in_row >= fixed_n_rows) || (in_col >= fixed_n_cols)), "Mat::operator(): index out of bounds");
  6890. const uword iq = in_row + in_col*fixed_n_rows;
  6891. return (use_extra) ? mem_local_extra[iq] : mem_local[iq];
  6892. }
  6893. template<typename eT>
  6894. template<uword fixed_n_rows, uword fixed_n_cols>
  6895. arma_inline
  6896. arma_warn_unused
  6897. const eT&
  6898. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator() (const uword in_row, const uword in_col) const
  6899. {
  6900. arma_debug_check( ((in_row >= fixed_n_rows) || (in_col >= fixed_n_cols)), "Mat::operator(): index out of bounds");
  6901. const uword iq = in_row + in_col*fixed_n_rows;
  6902. return (use_extra) ? mem_local_extra[iq] : mem_local[iq];
  6903. }
  6904. template<typename eT>
  6905. template<uword fixed_n_rows, uword fixed_n_cols>
  6906. arma_inline
  6907. arma_warn_unused
  6908. eT*
  6909. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::colptr(const uword in_col)
  6910. {
  6911. eT* mem_actual = (use_extra) ? mem_local_extra : mem_local;
  6912. return & access::rw(mem_actual[in_col*fixed_n_rows]);
  6913. }
  6914. template<typename eT>
  6915. template<uword fixed_n_rows, uword fixed_n_cols>
  6916. arma_inline
  6917. arma_warn_unused
  6918. const eT*
  6919. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::colptr(const uword in_col) const
  6920. {
  6921. const eT* mem_actual = (use_extra) ? mem_local_extra : mem_local;
  6922. return & mem_actual[in_col*fixed_n_rows];
  6923. }
  6924. template<typename eT>
  6925. template<uword fixed_n_rows, uword fixed_n_cols>
  6926. arma_inline
  6927. arma_warn_unused
  6928. eT*
  6929. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::memptr()
  6930. {
  6931. return (use_extra) ? mem_local_extra : mem_local;
  6932. }
  6933. template<typename eT>
  6934. template<uword fixed_n_rows, uword fixed_n_cols>
  6935. arma_inline
  6936. arma_warn_unused
  6937. const eT*
  6938. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::memptr() const
  6939. {
  6940. return (use_extra) ? mem_local_extra : mem_local;
  6941. }
  6942. template<typename eT>
  6943. template<uword fixed_n_rows, uword fixed_n_cols>
  6944. arma_inline
  6945. arma_warn_unused
  6946. bool
  6947. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::is_vec() const
  6948. {
  6949. return ( (fixed_n_rows == 1) || (fixed_n_cols == 1) );
  6950. }
  6951. template<typename eT>
  6952. template<uword fixed_n_rows, uword fixed_n_cols>
  6953. inline
  6954. const Mat<eT>&
  6955. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fill(const eT val)
  6956. {
  6957. arma_extra_debug_sigprint();
  6958. eT* mem_use = (use_extra) ? &(mem_local_extra[0]) : &(mem_local[0]);
  6959. arrayops::inplace_set_fixed<eT,fixed_n_elem>( mem_use, val );
  6960. return *this;
  6961. }
  6962. template<typename eT>
  6963. template<uword fixed_n_rows, uword fixed_n_cols>
  6964. inline
  6965. const Mat<eT>&
  6966. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::zeros()
  6967. {
  6968. arma_extra_debug_sigprint();
  6969. eT* mem_use = (use_extra) ? &(mem_local_extra[0]) : &(mem_local[0]);
  6970. arrayops::inplace_set_fixed<eT,fixed_n_elem>( mem_use, eT(0) );
  6971. return *this;
  6972. }
  6973. template<typename eT>
  6974. template<uword fixed_n_rows, uword fixed_n_cols>
  6975. inline
  6976. const Mat<eT>&
  6977. Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::ones()
  6978. {
  6979. arma_extra_debug_sigprint();
  6980. eT* mem_use = (use_extra) ? &(mem_local_extra[0]) : &(mem_local[0]);
  6981. arrayops::inplace_set_fixed<eT,fixed_n_elem>( mem_use, eT(1) );
  6982. return *this;
  6983. }
  6984. //! prefix ++
  6985. template<typename eT>
  6986. inline
  6987. void
  6988. Mat_aux::prefix_pp(Mat<eT>& x)
  6989. {
  6990. eT* memptr = x.memptr();
  6991. const uword n_elem = x.n_elem;
  6992. uword i,j;
  6993. for(i=0, j=1; j<n_elem; i+=2, j+=2)
  6994. {
  6995. ++(memptr[i]);
  6996. ++(memptr[j]);
  6997. }
  6998. if(i < n_elem)
  6999. {
  7000. ++(memptr[i]);
  7001. }
  7002. }
  7003. //! prefix ++ for complex numbers (work around for limitations of the std::complex class)
  7004. template<typename T>
  7005. inline
  7006. void
  7007. Mat_aux::prefix_pp(Mat< std::complex<T> >& x)
  7008. {
  7009. x += T(1);
  7010. }
  7011. //! postfix ++
  7012. template<typename eT>
  7013. inline
  7014. void
  7015. Mat_aux::postfix_pp(Mat<eT>& x)
  7016. {
  7017. eT* memptr = x.memptr();
  7018. const uword n_elem = x.n_elem;
  7019. uword i,j;
  7020. for(i=0, j=1; j<n_elem; i+=2, j+=2)
  7021. {
  7022. (memptr[i])++;
  7023. (memptr[j])++;
  7024. }
  7025. if(i < n_elem)
  7026. {
  7027. (memptr[i])++;
  7028. }
  7029. }
  7030. //! postfix ++ for complex numbers (work around for limitations of the std::complex class)
  7031. template<typename T>
  7032. inline
  7033. void
  7034. Mat_aux::postfix_pp(Mat< std::complex<T> >& x)
  7035. {
  7036. x += T(1);
  7037. }
  7038. //! prefix --
  7039. template<typename eT>
  7040. inline
  7041. void
  7042. Mat_aux::prefix_mm(Mat<eT>& x)
  7043. {
  7044. eT* memptr = x.memptr();
  7045. const uword n_elem = x.n_elem;
  7046. uword i,j;
  7047. for(i=0, j=1; j<n_elem; i+=2, j+=2)
  7048. {
  7049. --(memptr[i]);
  7050. --(memptr[j]);
  7051. }
  7052. if(i < n_elem)
  7053. {
  7054. --(memptr[i]);
  7055. }
  7056. }
  7057. //! prefix -- for complex numbers (work around for limitations of the std::complex class)
  7058. template<typename T>
  7059. inline
  7060. void
  7061. Mat_aux::prefix_mm(Mat< std::complex<T> >& x)
  7062. {
  7063. x -= T(1);
  7064. }
  7065. //! postfix --
  7066. template<typename eT>
  7067. inline
  7068. void
  7069. Mat_aux::postfix_mm(Mat<eT>& x)
  7070. {
  7071. eT* memptr = x.memptr();
  7072. const uword n_elem = x.n_elem;
  7073. uword i,j;
  7074. for(i=0, j=1; j<n_elem; i+=2, j+=2)
  7075. {
  7076. (memptr[i])--;
  7077. (memptr[j])--;
  7078. }
  7079. if(i < n_elem)
  7080. {
  7081. (memptr[i])--;
  7082. }
  7083. }
  7084. //! postfix ++ for complex numbers (work around for limitations of the std::complex class)
  7085. template<typename T>
  7086. inline
  7087. void
  7088. Mat_aux::postfix_mm(Mat< std::complex<T> >& x)
  7089. {
  7090. x -= T(1);
  7091. }
  7092. template<typename eT, typename T1>
  7093. inline
  7094. void
  7095. Mat_aux::set_real(Mat<eT>& out, const Base<eT,T1>& X)
  7096. {
  7097. arma_extra_debug_sigprint();
  7098. const unwrap<T1> tmp(X.get_ref());
  7099. const Mat<eT>& A = tmp.M;
  7100. arma_debug_assert_same_size( out, A, "Mat::set_real()" );
  7101. out = A;
  7102. }
  7103. template<typename eT, typename T1>
  7104. inline
  7105. void
  7106. Mat_aux::set_imag(Mat<eT>&, const Base<eT,T1>&)
  7107. {
  7108. arma_extra_debug_sigprint();
  7109. }
  7110. template<typename T, typename T1>
  7111. inline
  7112. void
  7113. Mat_aux::set_real(Mat< std::complex<T> >& out, const Base<T,T1>& X)
  7114. {
  7115. arma_extra_debug_sigprint();
  7116. typedef typename std::complex<T> eT;
  7117. const Proxy<T1> P(X.get_ref());
  7118. const uword local_n_rows = P.get_n_rows();
  7119. const uword local_n_cols = P.get_n_cols();
  7120. arma_debug_assert_same_size( out.n_rows, out.n_cols, local_n_rows, local_n_cols, "Mat::set_real()" );
  7121. eT* out_mem = out.memptr();
  7122. if(Proxy<T1>::use_at == false)
  7123. {
  7124. typedef typename Proxy<T1>::ea_type ea_type;
  7125. ea_type A = P.get_ea();
  7126. const uword N = out.n_elem;
  7127. for(uword i=0; i<N; ++i)
  7128. {
  7129. out_mem[i] = std::complex<T>( A[i], out_mem[i].imag() );
  7130. }
  7131. }
  7132. else
  7133. {
  7134. for(uword col=0; col < local_n_cols; ++col)
  7135. for(uword row=0; row < local_n_rows; ++row)
  7136. {
  7137. (*out_mem) = std::complex<T>( P.at(row,col), (*out_mem).imag() );
  7138. out_mem++;
  7139. }
  7140. }
  7141. }
  7142. template<typename T, typename T1>
  7143. inline
  7144. void
  7145. Mat_aux::set_imag(Mat< std::complex<T> >& out, const Base<T,T1>& X)
  7146. {
  7147. arma_extra_debug_sigprint();
  7148. typedef typename std::complex<T> eT;
  7149. const Proxy<T1> P(X.get_ref());
  7150. const uword local_n_rows = P.get_n_rows();
  7151. const uword local_n_cols = P.get_n_cols();
  7152. arma_debug_assert_same_size( out.n_rows, out.n_cols, local_n_rows, local_n_cols, "Mat::set_imag()" );
  7153. eT* out_mem = out.memptr();
  7154. if(Proxy<T1>::use_at == false)
  7155. {
  7156. typedef typename Proxy<T1>::ea_type ea_type;
  7157. ea_type A = P.get_ea();
  7158. const uword N = out.n_elem;
  7159. for(uword i=0; i<N; ++i)
  7160. {
  7161. out_mem[i] = std::complex<T>( out_mem[i].real(), A[i] );
  7162. }
  7163. }
  7164. else
  7165. {
  7166. for(uword col=0; col < local_n_cols; ++col)
  7167. for(uword row=0; row < local_n_rows; ++row)
  7168. {
  7169. (*out_mem) = std::complex<T>( (*out_mem).real(), P.at(row,col) );
  7170. out_mem++;
  7171. }
  7172. }
  7173. }
  7174. #ifdef ARMA_EXTRA_MAT_MEAT
  7175. #include ARMA_INCFILE_WRAP(ARMA_EXTRA_MAT_MEAT)
  7176. #endif
  7177. //! @}