Save Complex vector from Matlab to text file - matlab

I generate a vector of complex numbers with Matlab and I want to save that vector into text file (.txt) to use it as input in my C code so the complex vectors looks like :
y = zeros(1,N);
for n = 1:N
y(n) = exp(-1i*(n-1)*k*d*sind(Qtgt));
end
picture
So I tried the functon dlmwrite to save the vector into text file :
dlmwrite('data.txt', y, 'delimiter','\n','newline', 'pc')
the vector stored like this :
picture 2
but I want it to be stored in this way : picture3
every complex number should stored in new line and the real part, the imaginary part should be separated with coma Any idea please ?

lifay:
This has a very simple fix: In your callout to dlmwrite, replace the y input for [real(y'),imag(y')]
Here's my attempt:
N = 10;
y = zeros(1,N);
for n = 1:N
y(n) = exp(-1i*(n-1));
re = real(y(n));
im = imag(y(n));
fprintf('%6.10f,%6.10f\n',re,im)
end
filename = 'output';
dlmwrite(filename,[real(y)',imag(y')],'precision',16)
Output to the above (granted I have a slightly different formula) on my end is:
The reason the output is given as shown by your "Picture 2" is that y is a row vector. Unless explicitly "told" otherwise by the programmer, MATLAB assumes arrays to be row vectors. MATLAB's dlmwrite output emulates the shape of the input array, in this case, a row vector, therefore, picture 2 is what you get. To get the output of picture 3, you must input a rectangular matrix. I achieve this above by concatenating two(2) row vectors that were transposed into column vectors. To perform the transposition use the ' operator as shown. Notice that I transpose the output of the real function and then the input to the imag function. These functions also emulate the shape of their respective input arrays into their respective output arrays. So, [real(y)',imag(y')] has the same effect as [real(y'),imag(y')].
Also, don't forget to specify the "precision" parameter to ensure that dlmwrite stores all the digits possible, if unspecified, dlmwrite will truncate the numbers and introduce truncation error into your further calculations in C.

Related

One hot encode column vectors in matrix without iterating

I am implementing a neural network and am trying to one hot encode a matrix of column vectors based on the max value in each column. Previously, I had been iterating through the matrix vector by vector, but I've been told that this is unnecessary and that I can actually one hot encode every column vector in the matrix at the same time. Unfortunately, after perusing SO, GitHub, and MathWorks, nothing seems to be getting the job done. I've listed my previous code below. Please help! Thanks :)
UPDATE:
This is what I am trying to accomplish...except this only changed the max value in the entire matrix to 1. I want to change the max value in each COLUMN to 1.
one_hots = bsxfun(#eq, mini_batch_activations, max(mini_batch_activations(:)))
UPDATE 2:
This is what I am looking for, but it only works for rows. I need columns.
V = max(mini_batch_activations,[],2);
idx = mini_batch_activations == V;
Iterative code:
% This is the matrix I want to one hot encode
mini_batch_activations = activations{length(layers)};
%For each vector in the mini_batch:
for m = 1:size(mini_batch_activations, 2)
% Isolate column vector for mini_batch
vector = mini_batch_activations(:,m);
% One hot encode vector to compare to target vector
one_hot = zeros(size(mini_batch_activations, 1),1);
[max_val,ind] = max(vector);
one_hot(ind) = 1;
% Isolate corresponding column vector in targets
mini_batch = mini_batch_y{k};
target_vector = mini_batch(:,m);
% Compare one_hot to target vector , and increment result if they match
if isequal(one_hot, target_vector)
num_correct = num_correct + 1;
endif
...
endfor
You’ve got the maxima for each column:
V = max(mini_batch_activations,[],1); % note 1, not 2!
Now all you need to do is equality comparison, the output is a logical array that readily converts to 0s and 1s. Note that MATLAB and Octave do implicit singleton expansion:
one_hot = mini_batch_activations==V;

Vectorize code to create a 3-dimensional array consisting of coordinate windows from a coordinate vector

I have a coordinate vector comp_points holding an image-coordinate-pair in each row. Now I want to create an array comp_windows holding nxm-windows of an image around the coordinates of comp_points. These windows shall be aligned along the 3rd dimension of comp_windows.
I solved the task like this:
I2=randi([0 255],[500 500]);
comp_points=randi([10 490],[20 2]);
delta_u_window=5;
delta_v_window=5;
for ii=1:size(comp_points,1)
comp_windows(:,:,ii)=I2(...
comp_points(ii,1)-delta_u_window:...
comp_points(ii,1)+delta_u_window,...
comp_points(ii,2)-delta_v_window:...
comp_points(ii,2)+delta_v_window);
end
Now I feel like I could do this without the for-loop using a concatenation or indexing expression or something, but I can't figure it out.
You already have the operations as slicing without any compute. So, I am not sure if it's worth to vectorize it, but let's put it out anyway with big help from bsxfun -
% Get range arrays
r1 = [-delta_u_window : delta_u_window];
r2 = [-delta_v_window : delta_v_window];
% Get row and column indices for all points in comp_points
r = bsxfun(#plus,r1(:),comp_points(:,1).');
c = bsxfun(#plus,r2(:),comp_points(:,2).');
% Next up, the work is to combine those row and column indices in a meshed-way
% Get 3D version of r and c - Keeping their last dim aligned and "spreading
% out" their first dims against each others. Then, perform elementwise
% summations to give us a summed up array of indices, indexing into which
% would give us the desired output.
r3D = reshape(r,size(r,1),1,[]);
c3D = reshape((c-1)*size(I2,1),1,size(c,1),[]);
out = I2(bsxfun(#plus, r3D, c3D));
For permute lovers, we can replace the last three steps with a single one, like so -
I2(bsxfun(#plus, permute(r,[1,3,2]), permute((c-1)* size(I2,1),[3,1,2])))

Importing text file into matrix form with indexes as strings?

I'm new to Matlab so bear with me. I have a text file in this form :
b0002 b0003 999
b0002 b0004 999
b0002 b0261 800
I need to read this file and convert it into a matrix. The first and second column in the text file are analogous to row and column of a matrix(the indices). I have another text file with a list of all values of 'indices'. So it should be possible to create an empty matrix beforehand.
b0002
b0003
b0004
b0005
b0006
b0007
b0008
Is there anyway to access matrix elements using custom string indices(I doubt it but just wondering)? If not, I'm guessing the only way to do this is to assign the first row and first column the index string values and then assign the third column values based on the first text file. Can anyone help me with that?
You can easily convert those strings to numbers and then use those as indices. For a given string, b0002:
s = 'b0002'
str2num(s(2:end); % output = 2
Furthermore, you can also do this with a char matrix:
t = ['b0002';'b0003';'b0004']
t =
b0002
b0003
b0004
str2num(t(:,2:end))
ans =
2
3
4
First, we use textscan to read the data in as two strings and a float (could use other numerical formats. We have to open the file for reading first.
fid = fopen('myfile.txt');
A = textscan(fid,'%s%s%f');
textscan returns a cell array, so we have to extract your three variables. x and y are converted to single char arrays using cell2mat (works only if all the strings inside are the same length), n is a list of numbers.
x = cell2mat(A{1});
y = cell2mat(A{2});
n = A{3};
We can now convert x and y to numbers by telling it to take every row : but only the second to final part of the row 2:end, e.g 002, 003 , not b002, b003.
x = str2num(x(:,2:end));
y = str2num(y(:,2:end));
Slight problem with indexing - if I have a matrix A and I do this:
A = magic(8);
A([1,5],[3,8])
Then it returns four elements - [1,3],[5,3],[1,8],[5,8] - not two. But what you want is the location in your matrix equivalent to x(1),y(1) to be set to n(1) and so on. To do this, we need to 1) work out the final size of matrix. 2) use sub2ind to calculate the right locations.
% find the size
% if you have a specified size you want the output to be use that instead
xsize = max(x);
ysize = max(y);
% initialise the output matrix - not always necessary but good practice
out = zeros(xsize,ysize);
% turn our x,y into linear indices
ind = sub2ind([xsize,ysize],x,y);
% put our numbers in our output matrix
out(ind) = n;

Converting a scipy.sparse.csr.csr_matrix into a form readable by MATLAB

I have a scipy.sparse.csr.csr_matrix which is the output from TfidfVectorizer() class. I know I can access the individual components of this matrix in this manner:
So if I have this matrix here:
tf_idf_matrix = vectorizer.fit_transform(lines)
I can access the individual components here:
tf_idf_matrix.data
tf_idf_matrix.indices
tf_idf_matrix.indptr
How do I save this from Python- such that I can load it into a MATLAB sparse matrix? OR how do I change it into a dense array, and save it as one numpy.ndarray text file - such that I can just simply load it into MATLAB as a matrix. The size of this matrix is not VERY large - its (5000, 68k)
Please help. Thanks
The MATLAB sparse constructor:
S = sparse(i,j,s,m,n,nzmax) uses vectors i, j, and s to generate an m-by-n sparse matrix such that S(i(k),j(k)) = s(k), with space allocated for nzmax nonzeros
is the same as the scipy sparse (including the step of adding values with ij are same).
csr_matrix((data, ij), [shape=(M, N)])
where data and ij satisfy the relationship a[ij[0, k], ij[1, k]] = data[k]
data and ij the attributes of the coo_matrix format. So for a start I'd suggest converting tocoo and writing the three arrays to a .mat file (scipy.io).
Assuming you have those components in matlab
then
x = accumarray(indptr+1, ones(size(indptr)),[1,N]);
% N being the number of rows >= max indptr+1
colind = cumsum(x);
res = sparse(colind,indices,data);
should do it.
The first part just converts the indptr vector into a vector to match each index with the right column number.
(note that indptr may have repititions and this is why the accumarray is necessary )

Indexing must appear last in an index expression

I have a vector CD1 (120-by-1) and I separate CD1 into 6 parts. For example, the first part is extracted from row 1 to row 20 in CD1, and second part is extracted from row 21 to row 40 in CD1, etc. For each part, I need to compute the means of the absolute values of second differences of the data.
for PartNo = 1:6
% extract data
Y(PartNo) = CD1(1 + 20*(PartNo-1):20*(PartNo),:);
% find the second difference
Z(PartNo) = Y(PartNo)(3:end) - Y(PartNo)(1:end-2);
% mean of absolute value
MEAN_ABS_2ND_DIFF_RESULT(PartNo) = mean(abs(Z));
end
However, the commands above produce the error:
()-indexing must appear last in an index expression for Line:2
Any ideas to change the code to have it do what I want?
This error is often encountered when Y is a cell-array. For cell arrays,
Y{1}(1:3)
is legal. Curly braces ({}) mean data extraction, so this means you are extracting the array stored in location 1 in the cell array, and then referencing the elements 1 through 3 of that array.
The notation
Y(1)(1:3)
is different in that it does not extract data, but it references the cell's location 1. This means the first part (Y(1)) returns a cell-array which, in your case, contains a single array. So you won't have direct access to the regular array as before.
It is an infamous limitation in Matlab that you cannot do indirect or double-referencing, which is in effect what you are doing here.
Hence the error.
Now, to resolve: I suspect replacing a few normal braces with curly ones will do the trick:
Y{PartNo} = CD1(1+20*(PartNo-1):20*PartNo,:); % extract data
Z{PartNo} = Y{PartNo}(3:end)-Y{PartNo}(1:end-2); % find the second difference
MEAN_ABS_2ND_DIFF_RESULT{PartNo} = mean(abs(Z{PartNo})); % mean of absolute value
I might suggest a different approach
Y = reshape(CD1, 20, 6);
Z = diff(y(1:2:end,:));
MEAN_ABS_2ND_DIFF_RESULT = mean(abs(Z));
This is not a valid statement in matlab:
Y(PartNo)(3:end)
You should either make Y two-dimensional and use this indexing
Y(PartNo, 3:end)
or extract vector parts and use them directly, if you use a loop like you have shown
for PartNo = 1:6
% extract data
Y = CD1(1 + 20*(PartNo-1):20*(PartNo),:);
% find the second difference
Z = Y(3:end) - Y(1:end-2);
% mean of absolute value
MEAN_ABS_2ND_DIFF_RESULT(PartNo) = mean(abs(Z));
end
Also, since CD1 is a vector, you do not need to index the second dimension. Drop the :
Y = CD1(1 + 20*(PartNo-1):20*(PartNo));
Finally, you do not need a loop. You can reshape the CD1 vector to a two-dimensional array Y of size 20x6, in which the columns are your parts, and work directly on the resulting matrix:
Y = reshape(CD1, 20, 6);
Z = Y(3:end,:)-Y(1:end-1,:);
MEAN_ABS_2ND_DIFF_RESULT = mean(abs(Z));