1 doesn't equal 1? Matrix entry comparison in MATLAB - matlab

I'm trying to test an inversion of a matrix by multiplying it to get 1. I check if it equals 1, and if not, then print a message and the value of the matrix entry.
The problem is that the printed matrix entry is 1. I even use a rounding function I know works to make sure there's nothing wrong with floating point inaccuracies.
Here's my code:
function [D1,f]=stiff(D,y)
n = size(D,2);
D1 = inv(D);
f = D1 * y;
for i = 1:n
for j = 1:n
if j == i % checking for diagonal entry
yTempVar = D * D1 (1:n, i);
if truncateFunction (yTempVar(j), 1) ~= 1
fprintf ("something's wrong")
truncateFunction (yTempVar(j), 1)
return
end
end
end
end
function B=truncateFunction(A,pow)
A(abs(A)<10^-pow)=0;
B=A;
The corresponding output is this:
something's wrong
ans = 1.0000
I've also tried it without the rounding function, and I've tried it against 1.0000
Here's what I have in my live script to test with
D=rand(4)*0.1;
y=randi([10 20], 4,1);
stiff(D,y)

truncateFunction doesn't do what you think it does. It only rounds values below the given power of ten down to zero - it doesn't round to the nearest integer at all, unless that integer is zero.
In general, it's better with floating point issues (which this is) to check that values are within a small value rather than being equal.
epsilon = .00001
if abs(yTempVar(j)-1) > epsilon
fprintf ("something's wrong")
truncateFunction (yTempVar(j), 1)
return

Related

Explanation for a function within xcorr in MATLAB

Looking within the xcorr function, most of it is pretty straightforward, except for one function within xcorr called "findTransformLength".
function m = findTransformLength(m)
m = 2*m;
while true
r = m;
for p = [2 3 5 7]
while (r > 1) && (mod(r, p) == 0)
r = r / p;
end
end
if r == 1
break;
end
m = m + 1;
end
With no comments, i fail to understand what this function is meant to acheive and what is the significance of p = [2 3 5 7]. Why those numbers specifically? Why not take a fixed FFT size instead? Is there a disadvantage(cause errors) to taking a fixed FFT size?
This part is used to get the integer closest to 2*m that can be written in the form:
Either:
m is already of this form, then the loop
for p = [2 3 5 7]
while (r > 1) && (mod(r, p) == 0)
r = r / p;
end
end
Will decrease r down to 1 and the break will be reached.
Or m has at least one other prime factor, and r will not reach 1. You go back to the look with m+1 and so on until you reach a number of the right form.
As per why they do this, you can see on the fft doc, in the Input arguments section:
n — Transform length [] (default) | nonnegative integer scalar
Transform length, specified as [] or a nonnegative integer scalar.
Specifying a positive integer scalar for the transform length can
increase the performance of fft. The length is typically specified as
a power of 2 or a value that can be factored into a product of small
prime numbers. If n is less than the length of the signal, then fft
ignores the remaining signal values past the nth entry and returns the
truncated result. If n is 0, then fft returns an empty matrix.
Example: n = 2^nextpow2(size(X,1))

How to apply a function on every pair of rows of a Matrix in Matlab?

I'm new to matlab and working with matrix and I'm kinda confused.
I'm supposed to make a m x n matrix called M and it's elements are -1, 1 and 0.
I need to write a function called d(x,y) which returns 1 if x = -1 and y = 1. And returns 0 otherwise.
and another function which calculates the sum of d(m(i,j),m(k,j)) in every column:
Please read the comment for an example.
How to find the sum?
I know basic programming but I don't know how to do this.
You can use nchoosek for selction:
comb = nchoosek(1:size(m,1), 2);
result = zeros(1, length(comb)); % allocate the memory
% you can run some techniques to run a function on each row of comb
% which is mentinoned in other posts instead of the following code
for i = 1:length(comb)
result(i) = sum(abs(m(comb(i,1), :) - m(comb(i,2), :)) == 2);
end

Matlab : Help in modulus operation

I am trying to implement a map / function which has the equation Bernoulli Shift Map
x_n+1 = 2* x_n mod 1
The output of this map will be a binary number which will be either 0/1.
So, I generated the first sample x_1 using rand. The following is the code. The problem is I am getting real numbers. When using a digital calculator, I can get binary, whereas when using Matlab, I am getting real numbers. Please help where I am going wrong. Thank you.
>> x = rand();
>> x
x =
0.1647
>> y = mod(2* x,1)
y =
0.3295
The dyadic transformation seems to be a transformation from [0,1) continuous to [0,1) continuous. I see nothing wrong with your test code if you are trying to implement the dyadic mapping. You should be expecting output in the [0,1)
I misunderstood your question because I focused on the assumption you had that the output should be binary [0 or 1], which is wrong.
To reproduce the output of the dyadic transformation as in the link you provided, your code works fine (for 1 value), and you can use this function to calculate N terms (assuming a starting term x0) :
function x = dyadic(x0,n)
x = zeros(n,1) ; %// preallocate output vector
x(1) = x0 ; %// assign first term
for k=2:n
x(k) = mod( 2*x(k-1) , 1) ; %// calculate all terms of the serie
end
Note that the output does not have to be binary, it has to be between 0 and 1.
In the case of integers, the result of mod(WhateverInteger,1) is always 0, but in the case of Real numbers (which is what you use here), the result of mod(AnyRealNumber,1) will be the fractional part, so a number between 0 and 1. (1 is mathematically excluded, 0 is possible by the mod(x,1) operation, but in the case of your serie it means all the successive term will be zero too).

indices must either be real positive integers or logicals. && Attempted to access f(0,0); index must be a positive integer or logical

I am new in matlab coming from c++ and trying to do 2d convolution. I have done dry run but nothing seems to go wrong but i dont know why this coming
My simple logic if value is lesser equal to zero then place zero. I am using this expression for solving that problem
i am facing 2 errors at
1)at f(q,p)=zeros(q,p);
2) at output_args(x,y)=output_args(x,y) + (W(s, t)* f(q,p));
function output_args = convo(img,k )
//skipped the portion of code---
z=s;i=t;
for x=1:row
for y=1:col
for s=s:a+2
% disp(s);
for t= t:b+2
q=z-s;
p=i-t;
if q<=0
if p <=0
f(q,p)=0; %// trying to place zero at index so help needed which is 1st error i have said
end
end
% disp(f(q,p));
output_args(x,y)=output_args(x,y) + (W(s, t)* f(q,p)); %//2nd error is comin (as i have told you above.
end
end
w=w+1;
end
z=z+1;
end
end
at console:(error occur when i apply
1) Subscript indices must either be real positive integers or logicals at f(q,p)=0
2) Attempted to access f(0,0); index must be a positive integer or logical. output_args(x,y)=output_args(x,y) + (W(s, t)* f(q,p));
so any idea?
if q<=0
if p <=0
f(q,p)=0; % p and q will always be invalid!
end
end
Well, that is begging for that error. In MATLAB, Indices must be greater than zero. While you can invert the if-condition to ensure that the index is positive, that will change the mending of your code.
if q > 0
if p > 0
f(q,p)=0; % p and q will always be valid.
end
end
If you need to index from -5 to 5 (for example) you could instead index from 1 to 11 instead. Just remember that you subtract 6 every time you display values. Alternatively, store the "real" indices in another vector.

How to compute values closest to or equal to 0.5?

how to pick values from matrix closest to or equal to K = 0.5? I know I could obtain values from the matrix, by taking the absolute values and its min. However, I want to be able to loop through the matrix, check if the the first element is equal K, if it is equal,take its index and break. But if the first element is not equal to K, loop until you find value equal to K. Continue until all values equal to K is exhausted. Can anybody point me in the right direction? Thanks in advance.
Here is my code:
data = rand(10,2);k =0.5;
indr = find(data(:,1));
cNum = data(1,1);
if cNum < k
old_distance = abs(k - cNum);
else
old_distance = abs(cNum - k);
end
Xdata = data(2:end,:);
indeX = find(Xdata(:,1));
for i = 1:size(Xdata,1)
if Xdata(i,1) < k
min_Val = abs(k-Xdata(i,1));
new_distance = min(min_Val);
else
min_Val = abs(Xdata(i,1) -k);
new_distance = min(min_Val);
end
if (new_distance < old_distance)
old_distance = new_distance;
cNum = Xdata(i,1);
end
end
cNum_indeX = indr(indeXm);
Y = cNum;
X = indr(cNum_indeX);'
To find the closest value in a vector to a particular value you can do this:
>> data = rand(10, 1)
data =
0.7060
0.0318
0.2769
0.0462
0.0971
0.8235
0.6948
0.3171
0.9502
0.0344
>> k = 0.5;
>> [~, index] = min(abs(data - k));
>> closestValue = data(index)
closestValue =
0.3171
For loops are rarely the answer in MATLAB. Let's say you want to check if your array elements are within K ± tol, where tol is some tolerance that you've set. You can do that by simple logical indexing.
K=0.5;
tol=0.001; %# set your tolerance here
boolIndex=xVector<=K+tol & xVector>=K-tol; %# xVector is your vector
Now boolIndex is just a logical index array of 0's and 1's. It gives a 1 wherever your array element has satisfied this criteria. You can use this directly in indexing your vector for further manipulation. If, for some reason, you need the exact index, you can get them by doing find(boolIndex==1).
The constraints of the problem aren't clear enough (and I don't have enough points to make this a comment rather than an answer.)
Is speed critical here? If so, then you should avoid any sort of explicit loop. It's usually better to use builtin functions unless the matrix is really huge and you want to break when you find something close enough. If it's millions of entries long, I'd break it into chunks of 10000 or so and let MATLAB use the min function on chunks. Or rows. Or columns. Depends on what you want to do.
How close is close enough? You demonstrate with a random matrix, but are you expecting something within rounding error of 0.5?
Are you aware that [value,index]=min(x) will give the value and index of minimum?
I assume the matrix must be large, otherwise there would be no downside to letting MATLAB do the vectorized:
[colminval,colminind]=min(abs(x-0.5));
[minval,rowminind]=min(colminval);
That's the best I can do for direction without more... direction.