How to read data into array in MATLAB? - arrays

I'm writing a code to solve Ax=b using MATLAB's x=A\B. I believe my problem lies within getting the data from the files into the array. Right now, the solution vector is coming out to be a load of 0's
The matrices I'm using have 10 rows respectively. They are aligned correctly in the text files.
% solve a linear system Ax = b by reading A and b from input file
% and then writing x on output file.
clear;
clc;
input_filename = 'my_input.txt';
output_filename = 'my_output.txt';
% read data from file
fileID = fopen('a_matrix.txt', 'r');
formatSpec = '%d %f';
sizeA = [10 Inf];
A = load('b_matrix.txt');
A = A'
file2ID = fopen('b_matrix.txt','r');
formatSpec2 = '%d %f';
sizeB = [10 Inf];
b = load('b_matrix.txt');
fclose(file2ID);
b = b'
% solve the linear system
x = A\b;
% write output data on file
dlmwrite('my_output.txt',x,'delimiter',',','precision',4);
% print screen
fprintf('Solution vector is: \n');
fprintf('%4.2f \n', x);

I answered my own question but I felt the need to share in case anyone else has similar troubles.
% solve a linear system Ax = b by reading A and b from input file
% and then writing x on output file.
clear;
clc;
input_filename = 'my_input.txt';
output_filename = 'my_output.txt';
% read data from file
f = textread('a_matrix.txt', '%f');
vals = reshape(f, 11, []).';
A = vals(:,1:10);
b = vals(:,11);
% solve the linear system
x = A\b;
% write output data on file
dlmwrite('my_output.txt',x,'delimiter',',','precision',4);
% print screen
fprintf('Solution vector is: \n');
fprintf('%4.2f \n', x);
I ended up combining the 'a' and 'b' matrix into a single text file for simplicity. Now, MATLAB reads data in by columns, so it is necessary to use 'reshape' in order to fit the data within the array correctly. Then, I filtered out the information from the single matrix by columns, using the 'vals' function as seen in my code. The 'A' matrix is essentially all numbers in columns 1 through 10, while the 'B' matrix is the 11th (and final) column.
Using MATLAB's x=A\b function, I was able to solve the linear system of equations.

Related

Filtering of fourier transforms of audio signals

I have an array containing the Fourier transform of an input audio signal (the amplitudes corresponding to various frequencies). I wish to select specific ranges of the signal without using the inbuilt functions. I have performed the following simple operations for the same :
[audio_in,audio_freq_sampl]=audioread('F:\Signals and Systems\Take Me Home Country Roads (John Denver Cover).wav');
Length_audio=length(audio_in);
df=audio_freq_sampl/Length_audio;
frequency_audio=-audio_freq_sampl/2:df:audio_freq_sampl/2-df;
figure
FFT_audio_in=fft(audio_in);
n = length(FFT_audio_in);
init = 30000;
fin = 40000;
conji= mod((n-init+2),n) ;
conjf= mod((n-fin+2),n) ;
fs_1(1:n) = 0.0 ;
fs_1(init:fin) = FFT_audio_in(init:fin);
fs_1(conji:conjf) = FFT_audio_in(conji:conjf);
plot(frequency_audio,abs(fs_1));
As we can see here, there is only one peak. the other one should be visible at the other end of the plot in the range.
The song can be found here - https://www.youtube.com/watch?v=WF046Z5tPJE
The song must be converted to a .wav file before reading it.
The above code should give me a plot containing two small peaks corresponding to the ranges of frequencies - (init , fin) and (conji , conjf). However, I am getting a peak only corresponding to the 1st range. Both these ranges are within the size of the array - FFT_audio_in.
The error lies in the following lines of code :
n = length(FFT_audio_in);
init = 30000;
fin = 40000;
conji= mod((n-init+2),n) ;
conjf= mod((n-fin+2),n) ;
fs_1(1:n) = 0.0 ;
fs_1(init:fin) = FFT_audio_in(init:fin);
fs_1(conji:conjf) = FFT_audio_in(conji:conjf);
Turns out that in the above lines of code, conji < conjf. So in the last line of the code, I am spanning through the vector with the initial point being larger than the final point. However, with the following lines of code, this issue is resolved :
n = length(FFT_audio_in);
init = n/4;
fin = n/4 + 10000;
conji= mod((n-init+2),n) ;
conjf= mod((n-fin+2),n) ;
init_2 = min(conji , conjf);
fin_2 = max(conji , conjf);
fs_1(1:n) = 0.0 ;
fs_1(init:fin) = FFT_audio_in(init:fin);
fs_1(init_2:fin_2) = FFT_audio_in(init_2:fin_2);

Writing a 3D Matlab matrix to a file as 1D and read it back in C

I have a three-dimensional Matlab matrix, with the shape 3x4x5 . Now I want to write this Matrix to a .txt file 1-dimensional and read it back out in C.
However, the numbers written should be the x and the y dimension first (so 4x5) followed by z-dimension (3).
Sample code for filling the matrix:
duneven = 1:3*4*5
duneven = reshape(duneven,[3 4 5]);
I hoped to get this effect by permuting the matrix like this:
duneven = permute(duneven,[3 1 2]);
And writing it out like this:
fp = fopen('testuneven.txt','w');
fprintf(fp,'%f ',duneven);
fclose(fp);
However, reading it in C - like this:
FILE* fp;
fp = fopen("testuneven.txt","r");
for(int i = 0; i < 3*4*5;i++){
float var;
fscanf(fp,"%f ",&var);
printf("%f ",var);
}
fclose(fp);
Reading it out in Matlab gives the same output. Furthermore, cat-ing out the file in the shell gives back the same results. So the issue is located in the Matlab code
Does not give back the desired output. Instead it prints out the first cols. How can I fix this issue?
I guess you mixed up the order in your permute() call. Your inital discription of the desired Dimension order stats 4x5 and then 3
your code
duneven = 1:3*4*5
duneven = reshape(duneven,[3 4 5]);
duneven = permute(duneven,[3 1 2])
produces 5x3x4.
consider using duneven = permute(duneven,[2 3 1])
The problem was, that matlab writes out the matrix column wise, while C reads it in row wise. To be sure, that it is written correctly, I have done the following:
duneven = 1:3*4*5
duneven = reshape(duneven,[3 4 5]);
%in case that the shape is not known
duneven_shape = size(duneven);
fileID = fopen('testunven.txt','w')
for i=1:duneven_shape(1)
v = reshape(squeeze(duneven (i,:,:))',[1 duneven_shape(2)*duneven_shape(3)]);
fprintf(fileID,"%f ",v);
end
fclose(fileID);

Converting code from Matlab to C?

I need to write a code that will:
Read a file that is a source and it is "emitting" 8-bytes signs (letters, numbers). The code needs to add +1 in the accumulator that is the size of 2^8^n every time a sign occurs. After I can calculate the entropy. The input parameters are the file and "n" that is 8 bytes * n (from 3 to 5).
Example:
if we read from file 10001110|11110000|11111111|00001011|10101010, for n = 3, we put +1 in the accumulator at 100011101111000011111111 and proceed with +1 at 111100001111111100001011 and so on...
The main problem is speed of this process. I need to read files that are max 50MB. Programming language can be anything from C, Matlab or Java.
Code so far in Matlab for n = 1. I need a good implementation for accumulator, so its not ful size from the very beginning...
load B.mat; %just some small part of file
file = dec2bin(B);
file = str2num(file);
[fileSize, ~] = size(file);
%Choose n
n = 1;
%Make accumulator
acu10 = linspace(0, 2^8^n-1, 2^8^n);
acu = dec2bin(acu10);
acu = str2num(acu);
index = zeros(size(acu10))';
%go through file and add +1 in accumulator
for i = 1:n:fileSize
for j = 1:size(acu)
if acu(j,:) == file(i);
index(j) = index(j) + 1;
end
end
end

2D Deconvolution using FFT in Matlab Problems

I have convoluted an image I created in matlab with a 2D Gaussian function which I have also defined in matlab and now I am trying to deconvolve the resultant matrix to see if I get the 2D Gaussian function back using the fft2 and ifft2 commands. However the matrix I get as a result is incorrect (to my knowledge). Here is the code for what I have done thus far:
% Code for input image (img) [300x300 array]
N = 100;
t = linspace(0,2*pi,50);
r = (N-10)/2;
circle = poly2mask(r*cos(t)+N/2+0.5, r*sin(t)+N/2+0.5,N,N);
img = repmat(circle,3,3);
% Code for 2D Gaussian Function with c = 0 sig = 1/64 (Z) [300x300 array]
x = linspace(-3,3,300);
y = x';
[X Y] = meshgrid(x,y);
Z = exp(-((X.^2)+(Y.^2))/(2*1/64));
% Code for 2D Convolution of img with Z (C) [599x599 array]
C = conv2(img,Z);
% I have tested that this convolution is correct using cross section profile vectors for img and C and the resulting x-y plots are what i expect from the convolution.
% From my knowledge of convolution, the algorithm works as a multiplier in Fourier space, therefore by dividing the Fourier transform of my output (convoluted image) by my input (img) I should get back the point spread function (Z - 2D Gaussian function) after the inverse Fourier transform is applied to this result by division.
% Code for attempted 2D deconvolution
Fimg = fft2(img,599,599);
% zero padding added to increase result to 599x599 array
FC = fft2(C);
R = FC/Fimg;
% I now get this error prompt: Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = 2.551432e-22
iFR = ifft2(R);
I'm expecting iFR to be close to Z but I'm getting something completely different. It may be an approximation of Z with complex values but I can't seem to check it since I don't know how to plot a 3D complex matrix in matlab. So if anyone can tell me whether my answer is correct or incorrect and how to get this deconvolution to work? I'd be much appreciated.
R = FC/Fimg needs to be R = FC./Fimg; You need to do division element-wise.
Here are some Octave (version 3.6.2) plots of that deconvolved Gaussian.
% deconvolve in frequency domain
Fimg = fft2(img,599,599);
FC = fft2(C);
R = FC ./ Fimg;
r = ifft2(R);
% show deconvolved Gaussian
figure(1);
subplot(2,3,1), imshow(img), title('image');
subplot(2,3,2), imshow(Z), title('Gaussian');
subplot(2,3,3), imshow(C), title('image blurred by Gaussian');
subplot(2,3,4), mesh(X,Y,Z), title('initial Gaussian');
subplot(2,3,5), imagesc(real(r(1:300,1:300))), colormap gray, title('deconvolved Gaussian');
subplot(2,3,6), mesh(X,Y,real(r(1:300,1:300))), title('deconvolved Gaussian');
% show difference between Gaussian and deconvolved Gaussian
figure(2);
gdiff = Z - real(r(1:300,1:300));
imagesc(gdiff), colorbar, colormap gray, title('difference between initial Gaussian and deconvolved Guassian');

Understanding Matlab code

I've got some code, and I've been trying to make some minor tweaks to it. It used to use fgets to load in a single character from a line, and use it to colour points in a 3D plot. So it would read
a
p
p
n
c
and then use other data files to assign what x, y, z points to give these. The result is a really pretty 3D plot.
I've edited the input file so it reads
0
1
1
0
2
2
0
and I want it to colour numbers the same colour.
This is where I've gotten so far with the code:
function PlotCluster(mcStep)
clear all
filename = input('Please enter filename: ', 's');
disp('Loading hopping site coordinates ...')
load x.dat
load y.dat
load z.dat
temp = z;
z = x;
x = temp;
n_sites = length(x);
disp('Loading hopping site types ...')
fp = fopen([filename]);
data = load(filename); %# Load the data
% Plot the devices
% ----------------
disp('Plotting the sample surface ...')
figure
disp('Hello world!')
ia = data == 0;
in = data == 1;
ip = data == 2;
disp('Hello Again')
plot3(x(ia),y(ia),z(ia),'b.') %,'MarkerSize',4)
hold on
plot3(x(ic),y(ic),z(ic),'b.') %,'MarkerSize',4)
plot3(x(in),y(in),z(in),'g.') %,'MarkerSize',4)
plot3(x(ip),y(ip),z(ip),'r.') %,'MarkerSize',4)
daspect([1 1 1])
set(gca,'Projection','Perspective')
set(gca,'FontSize',16)
axis tight
xlabel('z (nm)','FontSize',18)
ylabel('y (nm)','FontSize',18)
zlabel('x (nm)','FontSize',18)
%title(['Metropolis Monte Carlo step ' num2str(mcStep)])
view([126.5 23])
My issue is I'm getting this error
Index exceeds matrix dimensions.
Error in PlotCluster (line 34)
plot3(x(ia),y(ia),z(ia),'b.') %,'MarkerSize',4)
And I don't see why ia would go out of bounds of the x array. Is it to do with changing the fgets to a load statement? It was the only way to get it read the correct numbers in (not 49s and 50s which was very odd.)
The main bits that are sticking me are these lines (where the number used to correspond to 'a','n','p' etc)
ia = data == 0;
in = data == 1;
ip = data == 2;
They look like implied if statements with assignment from data to ia etc. where ia becomes an array. But I'm not sure.
Any help understanding this would be greatly appreciated.
I've fixed the issue, I hadn't updated my input correctly. To clear this up for anyone who comes to this question: ia = data ==0 means 'Make an array the same size as data, and fill it with 1 or 0 depending on if the logic (data == 0) is true or false'

Resources