Matlab: regexp usage - matlab

I am going to start illustration using a code:
A = 'G1(General G1Airlines american G1Fungus )';
Using regexp (or any other function) in Matlab I want to distinctively locate: G1, G1A and G1F.
Currently if I try to do something as:
B = regexp( A, 'G1')
It is not able to distinguish G1 with the G1A and G1F i.e. I need to force the comparison to find me only case with G1 and ignore G1A and G1F.
However, when I am searching for G1A then it should still find me the location of G1A.
Can someone please help ?
Edit: Another case for A is:
A = 'R1George Service SmalR1Al C&I)';
And the expression this time I need to find is R1 and R1A instead.
Edit:
I have a giant array containing A's and another big vector containing G1, R1, etc I need to search for.

If you want to find 'G1' but not 'G1A' or 'G1F' you can use
>> B = regexp(A, 'G1[^AF]')
B =
1
This will find 'G1' and the ^ is used to specify that it should not match any characters contained with []. Then you could use
>> B = regexp(A, 'G1[AF]')
B =
12 32
to find both 'G1A' and 'G1F'.

Related

Matlab: read multiple files

my matlab script read several wav files contained in a folder.
Each read signal is saved in cell "mat" and each signal is saved in array. For example,
I have 3 wav files, I read these files and these signals are saved in arrays "a,b and c".
I want apply another function that has as input each signal (a, b and c) and the name of corresponding
file.
dirMask = '\myfolder\*.wav';
fileRoot = fileparts(dirMask);
Files=dir(dirMask);
N = natsortfiles({Files.name});
C = cell(size(N));
D = cell(size(N));
for k = 1:numel(N)
str =fullfile(fileRoot, Files(k).name);
[C{k},D{k}] = audioread(str);
mat = [C(:)];
fs = [D(:)];
a=mat{1};
b=mat{2};
c=mat{3};
myfunction(a,Files(1).name);
myfunction(b,Files(2).name);
myfunction(c,Files(3).name);
end
My script doesn't work because myfunction considers only the last Wav file contained in the folder, although
arrays a, b and c cointain the three different signal.
If I read only one wav file, the script works well. What's wrong in the for loop?
Like Cris noticed, you have some issues with how you structured your for loop. You are trying to use 'b', and 'c' before they are even given any data (in the second and third times through the loop). Assuming that you have a reason for structuring your program the way you do (I would rewrite the loop so that you do not use 'a','b', or 'c'. And just send 'myfunction' the appropriate index of 'mat') The following should work:
dirMask = '\myfolder\*.wav';
fileRoot = fileparts(dirMask);
Files=dir(dirMask);
N = natsortfiles({Files.name});
C = cell(size(N));
D = cell(size(N));
a = {};
b = {};
c = {};
for k = 1:numel(N)
str =fullfile(fileRoot, Files(k).name);
[C{k},D{k}] = audioread(str);
mat = [C(:)];
fs = [D(:)];
a=mat{1};
b=mat{2};
c=mat{3};
end
myfunction(a,Files(1).name);
myfunction(b,Files(2).name);
myfunction(c,Files(3).name);
EDIT
I wanted to take a moment to clarify what I meant by saying that I would not use the a, b, or c variables. Please note that I could be missing something in what you were asking so I might be explaining things you already know.
In a certain scenarios like this it is possible to articulate exactly how many variables you will be using. In your case, you know that you have exactly 3 audio files that you are going to process. So, variables a, b, and c can come out. Great, but what if you have to throw another audio file in? Now you need to go back in and add a 'd' variable and another call to 'myfunction'. There is a better way, that not only reduces complexity but also extends functionality to the program. See the following code:
%same as your code
dirMask = '\myfolder\*.wav';
fileRoot = fileparts(dirMask);
Files = dir(dirMask);
%slight variable name change, k->idx, slightly more meaningful.
%also removed N, simplifying things a little.
for idx = 1:numel(Files)
%meaningful variable name change str -> filepath.
filepath = fullfile(fileRoot, Files(idx).name);
%It was unclear if you were actually using the Fs component returned
%from the 'audioread' call. I wanted to make sure that we kept access
%to that data. Note that we have removed 'mat' and 'fs'. We can hold
%all of that data inside one variable, 'audio', which simplifies the
%program.
[audio{idx}.('data'), audio{idx}.('rate')] = audioread(filepath);
%this function call sends exactly the same data that your version did
%but note that we have to unpack it a little by adding the .('data').
myfunction(audio{idx}.('data'), Files(idx).name);
end

How to format print statements with two vector variables?

I'd like to write several messages and tables on the same .txt file.
For example:
x=[23.9,10.9,8.9,14.2]
y=[9.83,8.04,7.47,8.32]
file=fopen('Results.txt','wt');
fprintf(file,'Results1\n');
fprintf(file,'%.2f %.2f\r\n',x,y);
fprintf(file,'Results2\n');
fclose(file);
I get this result as .txt:
Results1
23.90 10.90
8.90 14.20
9.83 8.04
7.47 8.32
Results2
But I should get this one:
Results1
23.90 9.83
10.90 8.04
8.90 7.47
14.20 8.32
Results2
Instead of fprintf(file,'%.2f %.2f\r\n',x,y);), I was trying to use:
ResultsTable2 = table(x,y);
writetable(file,ResultsTable2);
but didn't succeed. How to write the required .txt file?
Careful examination of your output shows that all the elements of x were printed before all the elements of y.
The documentation confirms that this is the expected behavior. Check out this example
A1 = [9.9, 9900];
A2 = [8.8, 7.7 ; ...
8800, 7700];
formatSpec = 'X is %4.2f meters or %8.3f mm\n';
fprintf(formatSpec,A1,A2)
X is 9.90 meters or 9900.000 mm
X is 8.80 meters or 8800.000 mm
X is 7.70 meters or 7700.000 mm
Even though the arguments to fprintf are in the order A1, A2. It first prints all the values from A1, and then it prints all the values from A2 going in single index order.
Therefore, if you want to alternate values from x and y during printing, you need to interleave them in a new variable. There are several possible ways to do so.
One example,
XY = reshape([x;y], 1, []);
Then everything should print as expected
fprintf(file, '%.2f %.2f\r\n', XY);
% or if you want to print to command window
% fprintf('%.2f %.2f\r\n', XY);
23.90 9.83
10.90 8.04
8.90 7.47
14.20 8.32
The correct answer for how to output data with fprintf is given by Cecilia: each argument will be iterated completely through in the order it appears in the argument list, so you have to combine the data into one matrix argument that will be iterated through column-wise to generate the desired output.
You also mentioned trying to use a table and the writetable function, so I though I'd add the correct way to do that in case you were curious:
ResultsTable2 = table(x(:), y(:)); % Pass data as column vectors
writetable(ResultsTable2, 'Results.txt', 'WriteVariableNames', false);

How can I get the Methodlist while iterating?

I want to iterate through all classes and packages in a special path.
After that, I want to get the MethodList.
In the command window I can use following and it’s working fine:
a = ?ClassName;
a.MethodList(X);
Now I separate this into a function:
function s = befehlsreferenz(path)
s = what(path); % list MATLAB files in folder
for idx = 1:numel(s.classes)
c = s.classes(idx);
b = ?c;
b.MethodList(0);
end
end
I get an error:
Too many outputs requested. Most likely cause is missing [] around left hand side that has a comma separated list
expansion. Error in (line 7) b.MethodList(0);
While debugging I can see:
c: 1x1 cell = ‘Chapter’
b: empty 0x0 meta.class
Why is b empty? How can I get the methodlist?
1 Edit:
Here is an example class, also not working with it.
classdef TestClass
%TESTCLASS Summary of this class goes here
% Detailed explanation goes here
properties
end
methods
function [c] = hallo(a)
c = 1;
end
end
end
When struggling with operators in Matlab, it's typically the best choice to use the underlying function instead, which is meta.class.fromname(c)
Relevant documentation: http://de.mathworks.com/help/matlab/ref/metaclass.html
Further it seems s.classes(idx); is a cell, use cell indexing: s.classes{idx} ;

How to replace/modify something in a call to function 1 from within function 2 (both in their separate files)

The given task is to call a function from within another function, where both functions are handling matrices.
Now lets call this function 1 which is in its own file:
A = (1/dot(v,v))*(Ps'*Ps);
Function 1 is called with the command:
bpt = matok(P);
Now in another file in the same folder where function 1 is located (matok.m) we make another file containing function 2 that calls function 1:
bpt = matok(P);
What I wish B to do technically, is to return the result of the following (where D is a diagonal matrix):
IGNORE THIS LINE: B = (1/dot(v,v))*(Ps'*inv(D)*Ps*inv(D);
EDIT: this is the correct B = (1/dot(v,v))*(Ps*inv(D))'*Ps*inv(D);
But B should not "re-code" what has allready been written in function 1, the challenge/task is to call function 1 within function 2, and within function 2 we use the output of function 1 to end up with the result that B gives us. Also cause in the matrix world, AB is not equal to BA, then I can't simply multiply with inv(D) twice in the end. Now since Im not allowed to write B as is shown above, I was thinking of replacing (without altering function 1, doing the manipulation within function 2):
(Ps'*Ps)
with
(Ps'*inv(D)*Ps*inv(D)
which in some way I imagine should be possible, but since Im new to Matlab have no idea how to do or where even to start. Any ideas on how to achieve the desired result?
A small detail I missed:
The transpose shouldn't be of Ps in this:
B = (1/dot(v,v))*(Ps'*inv(D))*Ps*inv(D);
But rather the transpose of Ps and inv(D):
B = (1/dot(v,v))*(Ps*inv(D))'*Ps*inv(D);
I found this solution, but it might not be as compressed as it could've been and it seems a bit unelegant in my eyes, maybe there is an even shorter way?:
C = pinv(Ps') * A
E = (Ps*inv(D))' * C
Since (A*B)' = B'*A', you probably just need to call
matok(inv(D) * Ps)

Matlab - Inserting an element in a set

I'm planning to do the following in matlab:
Create an empty set
Insert an element which specifies a certain criterion in it
So, as a quick run on the matlab command line I did the following:
>> e=78
e =
78
>> Ck=[]
Ck =
[]
>> Cn=Ck+e
Cn =
[]
But, I was expecting to get the following:
Cn = [78]
Why didn't I get the expected result? And, how can I solve this out?
Thanks.
The #plus operator is defined as an arithmetic operation, but not as a set operation.
To add to an existing (1D) set at specified locations, you perform catenation and/or indexing. For example, to add at the end of a set, you can write
Cn = [Ck,e];
or
Cn = Ck;
Cn(end+1) = e;
Probably I'll be wrong, but I would initialize an empty array by means of zeros, like:
C = zeros(m,n)
with m,n = 1,2,...,N
Then, you input your second array/matrix and treat it according to whichever algorithm you have in mind.
I hope this helps.