Matlab exercise: i just don't get it [closed] - matlab

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Given the signals:
f1[n] = sinc[n] {1[n+5]-1[n-5]}
f2[n] = 1-rect[n]
f3[n] = 1[n]-1[n-5]
write a programm in matlab in which you will check the following proprieties:
1)sinc[n]:=sin(phi*n)/phi*n;
2)(f1*f2)[n] = (f2*f1)[n];
3)f1[n]*{ f2[n] + f3[n] } = f1[n]*f2[n] + f1[n]*f3[n];
4)(f1*delta)[n] = (delta*f1)[n] = f1[n];
I'm really really grateful for any tips/ideal on how to solve this problem. :)

sinc[n]:=sin(phi*n)/phi*n;
That certainly isn't Matlab syntax, and the ; at the end makes it not look much like a question either. Anyway, you have two options. Either plot the functions to visually assess equivalence or else check the vectors. I'll demonstrate with this one, then you can try for all the others.
Firstly you need to make a sample n vector which will be your domain over which to test equivalence (i.e. the x values of your plot). I'm going to arbitrarily choose:
n = -10:0.01:10;
Also I'm going to assuming by phi you actually meant pi based on the Matlab definition of sinc: http://www.mathworks.com/help/signal/ref/sinc.html
So now we have to functions:
a = sinc(n);
b = sin(n)./n;
a and b are now vectors with a corresponding "y" value for each element of n. You'll also notice I used a . before the /, this means element wise divide i.e. divide each element by each corresponding element rather than matrix division which is inversion followed by matrix multiplication.
Now lets plot them:
plot(n, a, n, b, 'r')
and finally to check numerical equivalence we could do this:
all(a == b)
But (and this is probably a bit out of scope for your question but important to know) you should actually never check for absolute equivalence of floating point numbers like that as you get precision errors due to different truncations in the inner calculations (because of how your computer stores floating point numbers). So instead it is good practice to rather check that the difference between the two numbers is less than some tiny threshold.
all((a - b) < 0.000001)
I'll leave the rest up to you

Related

Loop vectorization [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I'm applying the filtering function in the frequency domain. Because I am working with large amounts of data, I want to vectorize the for loop shown below. Any help would be appreciated.
N = 2^nextpow2(length(signal));
Y = fft(signal,N);
df=1/(N*dt);
freq=0:df:N/2*df-df;
ff=freq./fccutlow;
H=zeros(1,length(N));
for i=2:length(ff)
H(i)= sqrt((ff(i).^(2*nOrder)))./sqrt(((1+ff(i).^(2*nOrder))));
Y(i)= Y(i).*H(i);
Y(length(Y)-i+2)=Y(length(Y)-i+2).*H(i);
end
Y1= (real(ifft(Y,N)))';
Y1=Y1(1:length(signal));
filt_signal(1,:)=Y1;
For vector arithmetic on whole matrix you do not need any indexing, only use array operators, .*, ./, .^. But when only a part of array is used as operand, you need to use one of indexing methods. Keep in mind that all input and output ranges of arrays should be of compatible sizes.
Check parentheses again, but it is something like this:
H = sqrt((ff.^(2*nOrder)))./sqrt(((1+ff.^(2*nOrder))));
Y= Y.*H;
Y(end-((1:length(ff))+2))=Y(end-((1:length(ff))+2)).*H;
An example: Note that it does not matter if the matrices themselves do not have same sizes, but the operands must have compatible sizes:
A = 1:4; % 1x4
B = magic(3); % 3x3
C = zeros(3, 1); % 3x1
C([1 3]) = A(3:end).*B(1:2, 2)';
Although in this example A, B and C have different sizes, but A(3:end) and B(1:2, 2)' are both 1 by 2 and the code runs with no problem. Try to run it and evaluate different parts of code to see how indexing works.

MATLAB - singularity warning [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
when my matlab code gets to the line:
vE(:,:,i)=(mY(:,:,i))\(-mA*(vIs-mG(:,:,i)*vVs));
The following warning comes up:
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate.
RCOND = 1.682710e-16.
Whats wrong?
Full code:
function [ vE, vV_node, vI_node ] = ...
node_analysis( vIs, vVs, mA, mG, mY )
[A,B,N]=size(mY);
vE=zeros(4,1,N);
for i=1:N
vE(:,:,i)=(mY(:,:,i))\(-mA*(vIs-mG(:,:,i)*vVs));
vV_node(:,:,i)=mA'*vE(:,:,i);
vI_node(:,:,i)=mG(:,:,i)*vV_node(:,:,i)+(vIs-mG(:,:,i)*vVs);
end
end
vE=mY^-1 * (-mA*(cIs-mG*vVs))
vE is (4x1xN) size
mY(4x4xN)
mA(4x9)
vIs(9x1)
mG(9x9xN)
vVs(9x1)
When you use the \ operator with a matrix, MATLAB will try and solve the least squares problem to estimate x given y in the equation y = A*x. Depending on the size and shape of A, solving this equation might be easy, hard, or impossible without additional information. It just depends on your particular problem.
As Oli mentioned the comments, this is because your matrix is close to singular or its singular values are close to zero. MATLAB is properly informing you that the MATRIX likely has either unknown information that is going to screw up the answer or that some of the information in the MATRIX is so small compared to other pieces that the small part is going to make solving for x almost impossible and error prone.
Depending on your math background, you might consider the following cod where I create create a matrix with one value very small. This will reproduce your error:
%% Make some data:
randn('seed', 1982);
n = 3;
A = zeros(n);
for ind = 1:n-1
v = randn(n,1);
A = A + v*v';
end
% Last bit is very tiny compared to the others:
A = A + 1e-14*randn(n,1)*randn(1,n);
%% Try and solve Ax=y for x= 1,2,3...
x = (1:n)';
y = A*x
x_est = A \ y
There are various ways to start trying to fix this, usually by reformulating the problem and/or adding some kind of regularization term. A good first try, though, is so add a simple Tikhonov regularization which bumps up all the small values to something reasonable that MATLAB can work with. This may mess up your data but you can plat with it.
Roughly, try this:
tikk = 1e-12;
x_est2 = (A + tikk * eye(n)) \ y
For larger or smaller values of tikk and you will see the error goes away but the solution is to some degree wrong. You might find this acceptable or not.
Note that in my example the answer is quite wrong because I used n=3. As you increase the problem size n you will be better results.
Finally, to begin exploring what is wrong with your matrix A ((-mA*(vIs-mG(:,:,i)*vVs))), you might consider seeing how fast the values s in s=svd(A) decay. Some of them should be quite close to zero. Also, you might look at Tihkonov regularization and what you can do by actually decomposing the matrix into the SVD and scaling things better.

Matlab cosine mistake [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I've got some problem while equaling such function as:
function czeb()
k = 1:1:5;
Xk = cos( (pi*(k-0.5))/5);
CN(5,Xk)
end
function c = CN(N,x)
a=N*acos(x); % a is equal correct
c = cos(a); % buc c not, why?
return
end
If I view variable a inside CN function I receive
a=[1.5708, 4.7124, 7.8540, 10.9956, 14.1372]
which is correct bun next step in CN function is to calculate cos(a).
In this step I receive incorrect value of cos(a).
It should be
cos(a) = 1.0e-04 *[-0.0367,0.1102,-0.1837,0.2571,-0.3306]
but it is 1.0e-15 * [-0.8269,-0.1837,0.3062,-0.4286,0.5511] and I don't know why...
There is a very simple explanation, and you function is not wrong.
a=[1.5708, 4.7124, 7.8540, 10.9956, 14.1372]
is equal to pi/2 + k * pi. When you take the cosine of a, you will just get zeros. 1.0e-15 * 0.8269 is essentially zero (floating point arithmetic, and rounding errors).
I think, I understand your. Have you have create expected values manual, like cos(1.5708)? If yes, then you will always receive different results with results made by your computer. So, I think, your expected values of array a are incorrect.
First, enable long number format in the MATLAB/Octave:
format long;
After that, if you display your a array, you will see the similar output:
> a
a =
1.57079632679490 4.71238898038469 7.85398163397448 10.99557428756428 14.13716694115407
As you see at this step, your expected values and computed values by MATLAB/Octave are different. Than, if you do cos(1.57079632679490) the result will like -3.49148336110938e-15 and, as you see, this is near to the result of cos(a(1)): -8.26948102009006e-16. This means, that your stored number is different with that you see in the output.
To instead receive the same results as you expect - round your a to the fourth number after comma:
a = round(a*10000)/10000;
With this the computed results should be near to your expected results.

Matlab: how to redefine indexing to begin from zero? `Subscript indices must either be real positive integers or logicals.` [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have a mathematical data where it would be very convenient to have the index to start from zero like
a=sparse([],[],[],30,1);
>> a(0)=someValueHere
Subscript indices must either be real positive integers or logicals.
but Matlab by default offers only the index to start from 1. Is there some easy hack or trick by which I could still assign a(0) so that I don't need to create a dummyVar a0 for the value or append the value at the end?
So how to get assignment such as a(0) in Matlab? Every time zero-index called catch the error and return someValueHere instead of the warning?
To get MATLAB's index to start from 0 you'll need to make an large set of object classes that emulate regular numeric classes, but behave differently with functions such as subsassgn(), subsref() etc.
Maybe someone was crazy enough to do it somewhere, I'd expect this to take weeks to months of work to actually work properly.
There is a discussion on the matlab index issue: http://www.mathworks.cn/matlabcentral/newsreader/view_thread/285566
Maybe you can write a function like
function t=C_index(x)
t = x + 1;
Then you can write something like y(C_index(0)) to get the first value in vector y.
In Addition,
t=#(x) x+1
y(t(0))
should work.

Find Audio Peaks in MATLAB [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have an audio signal of about the size 7000000 x 1. I have used the peakfinder m file in MATLAB to find the location of all of the peaks in the audio file above a specific threshold. I am now trying to find a frame sized 1000000 x 1 that contains the greatest amount of peaks. I am completely lost on how to do this and any help would be greatly appreciated. Thank you!
Well, all the peak finder function is doing is taking the second derivative and looking for any place where the resulting value is negative. This indicates a local maximum. So you can do something very similar to find any local maximum.
Once you have these indices, you can window the array containing a logical representation of the locations, and count how many peaks are there.
The code below will do what I am saying. It will window across and count the number of peaks found, and return a a vector of the counts, which you can then just find the max of, and then you have the starting index.
clc; close all; clear all;
A = randi(10,[1,100])
plot(A)
hold on
C = diff(diff(A))
indices = find(C < 0)+1;
scatter(indices,A(indices),'r')
temp = zeros(size(A));
temp(indices) = 1;
window = ones(1,5);
results = conv(temp,window,'same');
max(results)
This is of course a pet example, A would be your matrix, and window would be a matrix the length of the range you want to examine, in your case 1000000
Edit
As Try Hard has made note of in the comments below, this method will be fairly susceptible to noise, so what you can do first is run a smoothing filter over the signal before doing any derivatives, something like as follows.
filt = (1/filtLength) * ones(1,filtLength);
A = conv(A,filt,'same')
This is a simple averaging filter which will help smooth out some of the noise