maanantai 25. elokuuta 2008

memmapfile-funktion käyttö MATLABissa

MATLABissa on jo muutaman version ajan ollut memmapfile-funktio, joka hyödyntää käyttöjärjestelmien tarjoamaa tiedostojen muistiinkuvauspalvelua. Tiedosto voidaan siis kuvata prosessin muistiin ikään kuin se olisi muistissa, vaikka se tosiasiassa onkin vain massamuistissa. Palvelua hyödyntävän ohjelmoijan ei tarvitse itse ladata osia tiedoston sisällöstä muistiin käsittelyä varten, vaan käyttöjärjestelmä hoitaa tämän tylsän ja virhealttiin tehtävän. Palvelu on oikeastaan todella tärkeä ajatellen nykyistä massamuistin ja keskusmuistin suhdetta: massamuistia voi olla tavallisissa mikrokoneissakin teratavu tai useampia, mutta fyysistä muistia on usein vain gigatavu. tai pari. Lisäksi MATLAB tuo vielä oman rajoitteensa muistinkäyttöön, sillä sille ei riitä, että muistia on yhteensä jokin määrä. MATLAB pystyy nimittäin tallentamaan matriiseja vain yhtenäiselle muistialueelle. Lisäksi ainakin Windowsissa MATLABin käytössä oleva muistialue pirstoutuu käytön aikana, jolloin kahden gigatavunkin muistilla varustetussa koneessa pystyy käsittelemään vain muutamaa sadan megan matriisia yhtä aikaa. MATLAB-ohjelmia on myös helppo kirjoittaa niin, että tarvitaan useita kopioita samasta matriisista.

memmapfilen käyttö on onneksi melko yksinkertaista. Oletetaan, että on olemassa 500 megatavun Level 4 MAT-tiedosto aikasarja.mat, jossa matriisi y sisältää jonkin systeemin syötteen rivillä kaksi, vasteen rivillä kolme ja ajan rivillä yksi. Seuraavalla koodilla 

   s = whos('-file', 'aikasarja.mat');
map=memmapfile('aikasarja.mat',...
'Format', {'double' s(1,1).size 'y'},...
'Repeat', 1,...
'Offset', 22);
syntyy objekti map, jossa itse aikasarjoihin pääsee käsiksi notaatiolla map.Data.y. Tässä on ensin whos-funktiolla otettu tiedoston sisältämän matriisin ominaisuudet talteen rakenteeseen s. Matriisin koko on syötetty suoraan memmapfilen Format-argumenttiin, joka tarvitsee lisäksi ohjeen datan tulkitsemiseksi (double) ja nimeämiseksi (y). Tämän jälkeen voi vaikkapa laskea varsin siedettävällä muistinkäytöllä taajuusvaste-estimaatin:
[FRF, frequency] = tfestimate(map.Data.y(2,:), map.Data.y(3,:));
Oleellista on tietää, missä muodossa data on tiedostossa. memmapfile on sen verran matalalla tasolla, että helposti joutuu lukemaan MAT-tiedostoformaatin dokumentaatiota pystyäkseen antamaan oikean arvon Offset-argumentille. Tässä tapauksessa oikea offset on 22, koska matriisin nimen pituus on kaksi tavua (y-kirjain ja null-merkki). Tiedostojen tarkastelussa tarvitaan hyvä tiedostonmuokkain. Paras löytämäni on KHexEdit, joka tosin toimii vain Linuxissa. Ehkäpä samat toiminnot tarjoava ohjelma on olemassa myös Windowsille.

Ei kommentteja: