Save mat file from MATLAB - matlab

I want to save variables in a loop with different image names, like
for i = 1:length(imagefile)
name = imagefile{i};
var = rand(100); % Just for example
save name var
end
It will save var as name, but how do I save it with a value of name, for example Canon101?

Sayyad, you don't have to use eval. You can simply use the function form of save, i.e., save(filename,variables). This will use the value of filename. Remember that the variables need to be entered as strings. So, in your example, it would be
save(name,'var')

Related

How I can i audioread all files in a folder

I have a folder with files named like this: "speaker1_001.wav". It goes From 001 to speaker1_020. How can I do a for loop to "audioread" all the files and storing the value in variables with different names?
This is what I got, but I only obtain one variable instead of 20.
mypath = fullfile('TrainVoices', 'speaker1');
for idx = 1:20
filename = fullfile(mypath, sprintf('speaker1_%d.wav', idx));
nameSpeaker = sprintf('speaker1_%d', idx);
[nameSpeaker, fs] = audioread(filename);
end
In your code, you try to dinamically create the name of the output variable nameSpeaker with the instruction nameSpeaker = sprintf('speaker1_%d', idx); in order to use it as output variable in the call to audioread.
This is not correct since you actually assign the string created with sprintf to the variable nameSpeaker rather then "change" the name of it.
Also, you have to manage the "zeros" included in the filename.
A part from this error (which can be fixed), in general it is not a good practice to use dinamically created variable.
A possible solution could be to store the wav data in a struct which allows to dinamically create the name of the field.
Moreover, since according to the code you've posted you know in advance the path and the root name of the inout files, you can create the complete filename by simply appending the different strings rather than using fullfile
In the following you can find a possible implementaton of the proposed solution.
The output will be a struct named nameSpeaker with a set of fields named speaker1_1, speaker1_2, speaker1_3 ... etc after the name of the input file in which, for semplicity the "zeros"have been removed.
Each of this fields is a struct with the field: data and fs containing the data of the wav file.
For example:
the data of speaker1_001.wav arfe stored in the struct
nameSpeaker.speaker1_1.data
nameSpeaker.speaker1_1.fa
the data of speaker1_002.wav arfe stored in the struct
nameSpeaker.speaker1_2.data
nameSpeaker.speaker1_2.fs
and so on.
% Defina the path
mypath='TrainVoices\speaker1'
% Define the file root name
f_root_name='speaker1_'
% Define the extension of the input file\
ext='.wav'
% Loop over the input filess
for idx = 1:20
%& add the proper number of "0" to tjhe filename
if(idx <= 9)
f_name=[f_root_name '00' num2str(idx)]
else
f_name=[f_root_name '0' num2str(idx)]
end
% Build the filename
filename=fullfile(mypath,[f_name ext])
% Read the wav file
[data,fs] = audioread(filename);
% Store the wav file data in a struct
nameSpeaker.([f_root_name num2str(idx)]).data=data;
nameSpeaker.([f_root_name num2str(idx)]).fs=fs;
end
You can make access to the data by simply specify the "idx" of the file.
For example, to make access to the data of speaker1_001.wav, you can simply define the file "idx" and then build the names of the fields accordingly:
file_idx=3
data=nameSpeaker.([f_root_name num2str(file_idx)]).data
fs=nameSpeaker.([f_root_name num2str(file_idx)]).fs

assignment of structure field values in loop - matlab

I am trying to assign the field values of structure in loop.
Structure declaration with empty values:
result_struct = struct('a',{},'b',{},'c',{},'d',{})
I am assigning values in loop like that:
% assume a, b, c, d are variables in my workspace
% field names match with the variable names
for index=1:n
% some computation and store results in variables (a-d)
result_struct(index).a = a;
result_struct(index).b = b;
result_struct(index).c = c;
result_struct(index).d = d;
end
How can I assign the values to the fields using another loop? Like that:
for fname = fieldnames(result_struct)'
result_struct(index).fname = fname; % field names and variable names match
end
You need to use dynamic field names to assign to the struct (the leff-hand side). For the right hand side you could use eval but that is dangerous, so it's better to save your variable fname to a file and then load it back in as a struct prior to accessing fname, again using dynamic field names.
names = fieldnames(result_struct);
for k = 1:numel(names)
% Save variable to a file
save('tmp.mat', names{k});
% Load it back into a struct
tmp = load('tmp.mat', names{k});
result_struct(index).(names{k}) = tmp.(names{k});
end
Alternately, you can use the save and load to just transform the entire thing into a struct without having to loop through the fields.
fields = fieldnames(result_struct);
% Save all relevant variables to a file
save('tmp.mat', fields{:});
% Load it back into the result_struct
result_struct(index) = orderfields(load('tmp.mat'), fields);

Matlab load mat into variable

When loading data from a .Mat file directly into a variable, it stores an struct instead of the variable itself.
Example:
myData.mat contains var1, var2, var3
if I do:
load myData.mat
it will create the variables var1, var2 and var3 in my workspace. OK.
If I assign what load returns to a variable, it stores an struct. This is normal since I'm loading several variables.
foo = load('myData.mat')
foo =
struct with fields:
var1
var2
var3
However suppose that I'm only interested in var1 and I want to directly store into a variable foo.
Load has an option of loading only specific variables from a .mat file, however it still stores an struct
foo = load('myData.mat', 'var1')
foo =
struct with fields:
var1
I want var1 to be directly assigned to foo.
Of course I can do:
foo = load('myData.mat', 'var1')
foo = foo.var1;
But it should be a way of doing this automatically in one line right?
If the MAT-file contains one variable, use
x = importdata(mat_file_name)
load does not behave this way otherwise load would behave inconsistently depending upon the number of variables that you have requested which would lead to an extremely confusing behavior.
To illustrate this, imagine that you wrote a general program that wanted to load all variables from a .mat file, make some modification to them, and then save them again. You want this program to work with any file so some files may have one variable and some may have multiple variables stored in them.
If load used the behavior you've specified, then you'd have to add in all sorts of logic to check how many variables were stored in a file before loading and modifying it.
Here is what this program would look like with the current behavior of load
function modifymyfile(filename)
data = load(filename);
fields = fieldnames(data);
for k = 1:numel(fields)
data.(fields{k}) = modify(data.(fields{k}));
end
save(filename, '-struct', 'data')
end
If the behavior was the way that you think you want
function modifymyfile(filename)
% Use a matfile to determine the number of variables
vars = whos(matfile(filename));
% If there is only one variable
if numel(vars) == 1
% Assign that variable (have to use eval)
tmp = load(filename, vars(1).name);
tmp = modify(tmp);
% Now to save it again, you have to use eval to reassign
eval([vars(1).name, '= tmp;']);
% Now resave
save(filename, vars(1).name);
else
data = load(filename);
fields = fieldnames(data);
for k = 1:numel(fields)
data.(fields{k}) = modify(data.(fields{k}));
end
save(filename, '-struct', 'data');
end
end
I'll leave it to the reader to decide which of these is more legible and robust.
The best way to do what you're trying to do is exactly what you've shown in your question. Simply reassign the value after loading
data = load('myfile.mat', 'var1');
data = data.var1;
Update
Even if you only wanted the variable to not be assigned to a struct when a variable was explicitly specified, you'd still end up with inconsistent behavior which would make it difficult if my program accepted a list of variables to change as a cell array
variables = {'var1', 'var2'}
data = load(filename, variables{:}); % Would yield a struct
variables = {'var1'};
data = load(filename, variables{:}); % Would not yield a struct
#Suever is right, but in case you wish for a one-line workaround this will do it:
foo = getfield(load('myData.mat'), 'var1');
It looks ugly but does what you want:
foo = subsref(matfile('myData.mat'),struct('type','.','subs','var1'))
Use matfile allows partial loading of variables into memory i.e. it only loads what is necessary. The function subsref does the job of the indexing operator "." in this case.

MATLAB: Loop through the values of a list from 'who' function

I have a long list of variables in my workspace.
First, I'm finding the potential variables I could be interested in using the who function. Next, I'd like to loop through this list to find the size of each variable, however who outputs only the name of the variables as a string.
How could I use this list to refer to the values of the variables, rather than just the name?
Thank you,
list = who('*time*')
list =
'time'
'time_1'
'time_2'
for i = 1:size(list,1);
len(i,1) = length(list(i))
end
len =
1
1
1
If you want details about the variables, you can use whos instead which will return a struct that contains (among other things) the dimensions (size) and storage size (bytes).
As far as getting the value, you could use eval but this is not recommended and you should instead consider using cell arrays or structs with dynamic field names rather than dynamic variable names.
S = whos('*time*');
for k = 1:numel(S)
disp(S(k).name)
disp(S(k).bytes)
disp(S(k).size)
% The number of elements
len(k) = prod(S(k).size);
% You CAN get the value this way (not recommended)
value = eval(S(k).name);
end
#Suever nicely explained the straightforward way to get this information. As I noted in a comment, I suggest that you take a step back, and don't generate those dynamically named variables to begin with.
You can access structs dynamically, without having to resort to the slow and unsafe eval:
timestruc.field = time;
timestruc.('field1') = time_1;
fname = 'field2';
timestruc.(fname) = time_2;
The above three assignments are all valid for a struct, and so you can address the fields of a single data struct by generating the field strings dynamically. The only constraint is that field names have to be valid variable names, so the first character of the field has to be a letter.
But here's a quick way out of the trap you got yourself into: save your workspace (well, the relevant part) in a .mat file, and read it back in. You can do this in a way that will give you a struct with fields that are exactly your variable names:
time = 1;
time_1 = 2;
time_2 = rand(4);
save('tmp.mat','time*'); % or just save('tmp.mat')
S = load('tmp.mat');
afterwards S will be a struct, each field will correspond to a variable you saved into 'tmp.mat':
>> S
S =
time: 1
time_1: 2
time_2: [4x4 double]
An example writing variables from workspace to csv files:
clear;
% Writing variables of myfile.mat to csv files
load('myfile.mat');
allvars = who;
for i=1:length(allvars)
varname = strjoin(allvars(i));
evalstr = strcat('csvwrite(', char(39), varname, '.csv', char(39), ', ', varname, ')');
eval(evalstr);
end

passing a filename as argument in matlab

In matlab I have a function which should take in a file name.
This file has a struct in it, later this file should be executed with in the function so that the struct will be loaded to the work space.
For example:
My function is hello(a), where 'a' is a file name, this file has a struct.
On executing the file in command window this struct will be loaded in the workspace.
Same way I want the struct to be loaded in to the workspace when I call the function.
I tried eval(a), but this is not loading the struct in the file to the workspace.
From the file name how will I obtain the struct name, even though I know that there is a struct in the file, but this is going to vary dynamically.
So how should I return the structure in function?
I am not sure whether you want the struct (or structs) inside the file to be copied automatically to the workspace, or if you want to assign the data yourself.
The following solution copies all variables from file a to the "base"-workspace automatically using the assignin() function. The solution also assumes that you give it a file for a .mat file.
function hello(a)
all_structs = load('-mat', a);
var_names = fieldnames(all_structs);
for k = 1:length(var_names)
assignin('base', var_names{k}, all_structs.(var_names{k}));
end
end
Try eval:
function mystruct = readstruct(filename)
% ... read in text from file here ...
eval(text)
For example, assume your file contains text 'mystruct.myval = 1', then after reading the file contents into string text, eval(text) returns
mystruct =
myval: 1
To load the structure into the workspace, the function should return the structure.
If the file contains arbitrary data (presumably but not necessarily in ascii format) then you can simply assign it to a structure after the file is read:
function mystruct = readstruct(filename)
% ... read in text from file here ...
% ... perform conversion of data type ...
mystruct.value = values