Adding time slice in a matlab output using fprintf - matlab

I have matlab output of a complex number, where 'modTrace' contains the complex numbers. to write my output in a file called '3pt.txt' I write the following:
modTrace
fileID = fopen('3pt.txt','w');
fprintf ( fileID,'%e+%ei\n',real ( traces ), imag ( traces ) );
fclose(fileID);
The output looks like this:
2.355387e-13+3.263411e-12i
3.037095e-12+1.848502e-12i
2.264321e-12+1.408536e-12i
3.808791e-13-1.647224e-14i
-3.249665e-14+7.954636e-15i
7.026766e-14+1.056313e-13i
and so on. Now if I want the output with time slice numbers to the left, something like:
0 2.355387e-13+3.263411e-12i
1 3.037095e-12+1.848502e-12i
2 2.264321e-12+1.408536e-12i
3 3.808791e-13-1.647224e-14i
4 -3.249665e-14+7.954636e-15i
5 7.026766e-14+1.056313e-13i
and so on, how to I edit the code?
Thank you in advance for help.

Your fprintf statement is not working the way you are intending. It prints out all the values in real(traces) before getting to imag(traces). For example,
>> v = [1 2; 3 4; 5 6]
v =
1 2
3 4
5 6
>> fprintf('%d %d\n',v(:,1),v(:,2))
1 3
5 2
4 6
To pair values the way intended, you need to transpose the matrix:
>> fprintf('%d %d\n',v.')
1 2
3 4
5 6
Following this example, you can prepend slice numbers as follows:
v = [(1:numel(traces)).' real(traces(:)) imag(traces(:))].';
fprintf(fileID,'%d %e+%ei\n',v)

Related

how to reverse the element of matrix?

I am trying to reverse the elements of the matrix such that for given matrix order of the elements get reversed.
my code is as shown for the 3x3 matrix is working.
X = [ 1 2 3 ; 4 5 6 ; 7 8 9 ];
B = [fliplr(X(3,:));fliplr(X(2,:));fliplr(X(1,:))];
input X =
1 2 3
4 5 6
7 8 9
output:
B =
9 8 7
6 5 4
3 2 1
the above code I am trying to generalize for any matrix with the following code
[a,b]=size(X);
for i=0:a-1
A = [fliplr(X(a-i,:))];
end
but get only last row as output.
output A =
3 2 1
please help me to concatenate all the rows of the matrix one above to each other after it got reversed.
rot90 is the function made for this purpose.
B = rot90(A,2);
Your code doesn't work because you overwrite A in every loop iteration. Instead, you should index into A to save each of your rows.
However, fliplr can flip a whole matrix. You want to flip left/right and up/down:
B = flipud(fliplr(X));
This is the same as rotating the matrix (as Sardar posted while I was writing this):
B = rot90(X,2);
A totally different approach would work for arrays of any dimensionality:
X(:) = flipud(X(:));

Formatting cell to double

I have text file in which the data is like (1,2),(3,4),1 (4,5),(6,7),1
I am reading the file in the matlab as:
A= textread('abc.txt', '%s');
the output is
A: 2x1 cell
(1,2),(3,4),1
(4,5),(6,7),1
Anyone please help to convert this cell to double with the output
New_A= 5x2 double
1 2 3 4 1
4 5 6 7 1
For your particular example, once you read the file, you can use textscan.
A = {'(1,2),(3,4),1'
'(4,5),(6,7),1'};
New_A = cell2mat(cellfun(#(line) cell2mat(textscan(line,'(%f,%f),(%f,%f),%f')), A, 'UniformOutput', 0));
New_A =
1 2 3 4 1
4 5 6 7 1
You can also do similar, line by line, as they are read from the file.
This can be done using regexprep, cell2mat and str2num as follows:
A = {'(1,2),(3,4),1'
'(4,5),(6,7),1'}; % This is what you get after this: A= textread('abc.txt', '%s');
New_A = regexprep(A,'(\(|\))',''); %Removing the brackets ()
New_A = str2num(cell2mat(New_A)) %Converting char cell to numeric matrix

visualizing 2D-graphs of n-dim. array via surf() in matlab

I want to show 2dim. Surface plots for different combinations of 2 parameters of a 3- or higher-dimensional array in matlab. The data for the non-shown dimensions are integrated (i.e. summed in the remaining dimensions). I am using surf(), and for parameter combinations other than (1,2) (eg. (1,3), (2,3) ...) I have to rearrange the data matrices in order to make it work.
I am looking for an alternative command (or shorter code) which does this work.
Here's the code:
a=zeros(3,3,2);
a(:,:,1) = [1 2 3 ;4 5 6; 7 8 9; 10 11 12]; % // data matrix
a(:,:,2) = -[1 2 3 ;4 5 6; 7 8 9; 10 11 12]*2; % // data matrix
ai=[[1 2 3 4]' [5 6 7 0]' [8 9 0 0]']; % // parameter vector
mat12 = sum(a,3);
surf(ai(1:3,2),ai(1:4,1),mat12)
aux13 = sum(a,2);
for i = 1:2; mat13(:,i) = aux13(:,:,i);
surf(ai(1:2,3),ai(1:4,1),mat13)
aux23 = sum(a,1);
for i = 1:2; mat23(i,:) = aux23(:,:,i);
surf(ai(1:3,2),ai(1:2,3),mat23)
In other words, I am looking for a way to use surf for matrices mat13 and mat23 without the aux13, aux23 variables and the for loop.
First your example doesn't run because you declare a=zeros(3,3,2); as a matrix [3x3x2] but you immediately try to populate it as a [4x3x2] matrix, so I had to adjust your first line to: a=zeros(4,3,2);
If I run your code with that adjustment, your auxiliary variable and for loops are to reform/reshape a matrix stripped of it's singleton dimension. Matlab provide a handy function for that : squeeze.
For example, your variable aux13 is of dimension [4x1x2], then mat13=squeeze(aux13); achieve the same thing than your for loop. Your matrix mat13 is now of dimension [4x2].
Since no for loop is needed, you can completely bypass your auxiliary variable by calling squeeze directly on the result of your summation: mat13=squeeze( sum(a,2) );
Full example, the code below does exactly the same than your code sample:
mat12 = sum(a,3);
surf(ai(1:3,2),ai(1:4,1),mat12)
mat13 = squeeze( sum(a,2) ) ;
surf(ai(1:2,3),ai(1:4,1),mat13)
mat23 = squeeze( sum(a,1) ) ;
mat23 = mat23.' ; %'// <= note the "transpose" operation here
surf(ai(1:3,2),ai(1:2,3),mat23)
Note that I had to transpose mat23 to make it match the one in your example.
sum(a,1) is [1x3x2] => squeeze that and you obtain a [3x2] matrix but your code arrange the same values in a [2x3] matrix, so the use of the transpose. The transpose operator has a shorthand notation .'.
I used it in the example in a separate line just to highlight it. Once understood you can simply write the full operation in one line:
mat23 = squeeze(sum(a,1)).' ;
The way you write your loops isn't exactly MATLAB syntax. Below is the correct loop syntax shown.
On line 2 and 3, you are trying to load (4x3)-matrices into (3x3)-matrices. That is why you get a subscript error. You could resolve it by making the zeros-matrix bigger. Here's some Syntax fixed:
a=zeros(4,3,2);
a(:,:,1) = [1 2 3 ;4 5 6; 7 8 9; 10 11 12]; % // data matrix
a(:,:,2) = -[1 2 3 ;4 5 6; 7 8 9; 10 11 12]*2; % // data matrix
ai=[[1 2 3 4]' [5 6 7 0]' [8 9 0 0]']; % // parameter vector
mat12 = sum(a,3);
surf(ai(1:3,2),ai(1:4,1),mat12)
aux13 = sum(a,2);
for i = 1:2 mat13(:,i) = aux13(:,:,i);
surf(ai(1:2,3),ai(1:4,1),mat13)
end
aux23 = sum(a,1);
for i = 1:2 mat23(i,:) = aux23(:,:,i);
surf(ai(1:3,2),ai(1:2,3),mat23)
end
Now, what are you exactly trying to do inside those loops?

Filtering sequences in MATLAB

Is it possible to do something like regular expressions with MATLAB to filter things out? Basically I'm looking for something that will let me take a vector like:
[1 2 1 1 1 2 1 3 3 3 3 1 1 4 4 4 1 1]
and will return:
[3 3 3 3 4 4 4]
These are the uninterrupted sequences (where there's no interspersion).
Is this possible?
Using regular expressions
Use MATLAB's built-in regexp function for regular expression matching. However, you have to convert the input array to a string first, and only then feed it to regexp:
C = regexp(sprintf('%d ', x), '(.+ )(\1)+', 'match')
Note that I separated the values with spaces so that regexp can match multiple digit numbers as well. Then convert the result back to a numerical array:
res = str2num([C{:}])
The dot (.) in the pattern string represents any character. To find sequences of certain digits only, specify them in brackets ([]). For instance, the pattern to find only sequences of 3 and 4 would be:
([34]+ )(\1)+
A simpler approach
You can filter out successively repeating values by checking the similarity between adjacent elements using diff:
res = x((diff([NaN; x(:)])' == 0) | (diff([x(:); NaN])' == 0))
Optionally, you can keep only certain values from the result, for example:
res(res == 3 | res == 4)
You can do it like this:
v=[1 2 1 1 1 2 1 3 3 3 3 1 1 4 4 4 1 1];
vals=unique(v); % find all unique values in the vector
mask=[]; % mask of values to retain
for i=1:length(vals)
indices=find(v==vals(i)); % find indices of each unique value
% if the maximum difference between indices containing
% a given value is 1, it is contiguous
% --> add this value to the mask
if max(indices(2:end)-indices(1:end-1))==1
mask=[mask vals(i)];
end
end
% filter out what's necessary
vproc=v(ismember(v,mask))
Result:
vproc =
3 3 3 3 4 4 4
This can be another approach, although a little bit too elaborated.
If you see the plot of your array, you want to retain its level sets (i.e. a == const) which are topologically connected (i.e. made by one piece).
Coherently, such level sets are exactly the ones corresponding to a==3 and a==4.
Here is a possible implementation
a = [1 2 1 1 1 2 1 3 3 3 3 1 1 4 4 4 1 1]
r = []; % result
b = a; % b will contain the union of the level sets not parsed yet
while ~isempty(b)
m = a == b(1); % m is the current level set
connected = sum(diff([0 m 0]).^2) == 2; % a condition for being a connected set:
% the derivative must have 1 positive and 1
% negative jump
if connected == true % if the level set is connected we add it to the result
r = [r a(m)];
end
b = b(b~=b(1));
end
If you try something like
a = [1 2 1 1 1 2 1 3 3 3 3 1 1 4 4 4 1 1] %initial vector
b = a>=3 %apply filter condition
a = a(b) %keep values that satisfy filter
a will output
a = [3 3 3 3 4 4 4]

How to display sequence numbers in Matlab in a better way?

For example, I have an array:
a=[1:5 8:10];
If I display it using:
disp(['a = ' num2str(a)]);
The result would be something like
a = 1 2 3 4 5 8 9 10
It's quite too long than I need. How can I let Matlab to display as same as the way I defined it or as close as is?
Be more specific, if I defined the variable in an "informal" way like:
a=[1:3 4:6 8:10]
(should be normally 1:6 instead of 1:3 4:6)
I just want Matlab to display in either way:
1:3 4:6 8:10 or 1:6 8:10
I also not care about whether it displays the variable name or square brackets.
Searched but didn't find anything useful. Considered to manually parse it but doesn't sounds like a clever way.
Any suggestion would be great helpful, thanks a lot.
The only way to do this would be to create your own function to display the arrays in the format you want. For example, if you want to display monotonically-increasing portions of your array in a condensed fashion, you could use a function like this:
function display_array(array)
str = cellfun(#(n) {num2str(n)}, num2cell(array));
index = (diff(array) == 1) & ([1 diff(array, 2)] == 0);
str(index) = {':'};
str = regexprep(sprintf(' %s', str{:}), '( :)+\s*', ':');
disp([inputname(1) ' = [' str(2:end) ']']);
end
And you would use it like so:
>> a = [1:5 7 9:11] %# Define a sample array
a =
1 2 3 4 5 7 9 10 11 %# Default display
>> display_array(a)
a = [1:5 7 9:11] %# Condensed display
>> b = [1 2 3 4 4 4 3 2 1]; %# Another sample array
>> display_array(b)
b = [1:4 4 4 3 2 1] %# Note only the monotonically increasing part is replaced
For this, I use vec2str from the Matlab file exchange. For example:
str = vec2str([1 3 5 5 9 8 7 6 5])
ans =
[1:2:5,5,9:-1:5]
>> eval(str)
ans =
1 3 5 5 9 8 7 6 5
Impossible. Matlab throws away your definition very quickly. The "object" a has no knowledge of that definition at all.