I'm trying to write a simple code to give the output of sum of a harmonic series of n terms. While I wrote and executed the code as follows
for(i=1;i<=n;i++)
sum = sum + (1/i);
I'm not able to get the desired output. The output is displayed for me as sum = 1.000000 while the same peace of code is working if it is as follows:
for(i=1;i<=n;i++)
sum = sum + (1/(float)i);
actual output: sum = 2.283334
Can anyone please explain how the type conversion here is impacting the output?
The computer thinks that (1/i) should be an integer. When 1 is divided by i the decimal part is dropped to get an integer value. Since 1/i results in 0.xxxx, when the decimal part is dropped you are left with 0. Changing i to a float tells it that the number should be a float. You could get a similar result by using sum = sum + (1.0/i); if you wanted to.
Related
I'm new to Matlab.
I have these simple lines. The problem is that the sum variable does not take negative values. All variables are double.
Inp_pixel = Inp_padded(x, y);
Filter_pixel = Filter(f_row, f_col);
sum = sum + (Inp_pixel * Filter_pixel);
for example: if Filter_pixel = -1 and Inp_pixel = 150 and sum = 0. the expected result should be -150 but I get sum = 0
The problem was in Inp_pixel. This variable assigned from an uint8 2D array.
that's why this variable didn't take the negative value of the multiplication. I used cast() function to solve this problem.
for more details about this function please check this link.
MATLAB documentation page
I currently have the following code:
count = 20;
n = zeros(count, 1);
P = zeros(count, 1);
for i = 1:count
n(i) = i;
P(i) = sym(i)^i + (sym(1-i))^(i-1);
if i == (count)
T = table(n,P)
end
end
This gives me a table with a set of values. However, some of the values are losing precision because they have too many digits.
I am aware that MATLAB allows for up to 536870913 digits of precision. How do I make my table values not lose precision?
Note: if I were to just do the following operation (for example): sym(200)^2010, I would get the full precision value, which has 4626 digits. Doing this for table values doesn't seem to work, though, for some strange reason.
If someone could please help me with this I would be extremely grateful as I have been struggling with this for several hours now.
As #Daniel commented, the problem is that you are casting to double when storing it in P. MATLAB only has the precision you mention when using symbolic variables, but when you get into the numerical world, you can only store a finite amount of precision.
To be exact, once you define P as a double (zeros returns a double vector), the biggest integer you can store such that all of its smaller integers are precise is 2^53, way smaller than your P(20). This means that any integer bigger than 2^53 is not ensured to be precise on a double valued vector.
Your solution is thus to avoid casting, to store the variable on a sym type P. Note that the above also applies to later maths. If you plan to use this variable in some equation, remember that when you pass it to numerical form, you will lose precision. Often this does not matter, as the precision lost is very small, but you should know it.
If you want to learn more about how numerical precision work on computers, I suggest reading the following Q&A: Why is 24.0000 not equal to 24.0000 in MATLAB?
Sym solution:
count = 20;
n = zeros(count, 1);
P = sym('integer',[count, 1]);
for i = 1:count
n(i) = i;
P(i) = sym(i)^i + (sym(1-i))^(i-1);
if i == (count)
T = table(n,P)
end
end
returns
>> T.P(20)
ans =
102879180344339686410876021
I have a function that converts a decimal number to binary but i need to make the function recursive. I don't know how to make this function call itself. Any help will be very appreciated.
This is my function :
function bin = myBinary (dec_nr)
i = 1;
q = floor(dec_nr/2); %this is the quotient, the "floor" function is used to round down
r = rem(dec_nr, 2); % the "rem" function is used to get the remainder which will become the first binary value
bin(i) = num2str(r(i)); % the remainder is converted and stored as a string
while 2 <= q
dec_nr = q;
i = i + 1;
q = floor(dec_nr/2);
r = rem(dec_nr, 2);
bin(i) = num2str(r);
end
bin(i + 1) = num2str(q);
bin = fliplr(bin);
save myBinary
Thank you in advance!
That's pretty simple to do. I would implement this using something called tail recursion. Remember the algorithm for converting a decimal number (assuming unsigned) into binary.
Declare a number you want to convert.
Initially declare an output to be empty.
Until the number is 0...
a. Take the number and divide this by 2
b. If there is a remainder, then attach a bit of 1 from the left, so output <- [1 output]. Else, attach a 0, so output <- [0 output].
output will contain the binary representation of your number.
With recursion, there are two cases you must consider: The base case, where the algorithm stops and gives you a known output, and a recursive case that tells you that you need to keep going, and you call the function again with modified inputs.
As such, you can very easily achieve what you want above by tail recursion by providing a helper function that takes in the input number at a given state (basically the number after being divided by 2 for a number of times) and a binary string that gives you the current state of binary string construction as you're going through and determining each bit.
You would repeatedly call this function and taking the input number and dividing it by 2 until you get a result of 0. You would start by calling the function with the original input number, and an empty string. Make sure that when you send the input number back into the function for the recursive case, you need to truncate any decimal values that result, so you would take the floor.
Therefore, a possible function is very simply:
function bin = bin2dec_recursive(in)
%// Recursive helper
function [out] = recursive_helper(in_number, binstr)
%// Base case
if in_number == 0
out = binstr; %// Just return the current binary string
%// Recursive case
else
%// Recurse - Integer divide input number and concatenate string
out = recursive_helper(floor(in_number/2), [num2str(mod(in_number,2)) binstr]);
end
end
%// call recursive helper
bin = recursive_helper(in, '');
end
What's key is this statement right here:
out = recursive_helper(floor(in_number/2), [num2str(mod(in_number,2)) binstr]);
When we hit the recursive case, we need to call the function again by dividing the input number by 2 and the input binary string is the current string, but we add either a 0 or 1 to the left of the string. We convert the number to a string by num2str.
If you desire to have a double array of single digits, simply remove the num2str call inside the recursive case, and replace '' with [] when you're calling the recursive helper function for the first time at the last line of code above.
With this, here are some examples of it working:
>> bin2dec_recursive(3)
ans =
11
>> bin2dec_recursive(5)
ans =
101
>> bin2dec_recursive(9)
ans =
1001
>> bin2dec_recursive(127)
ans =
1111111
>> bin2dec_recursive(200)
ans =
11001000
Minor Note
Be advised that the recursion limit for MATLAB is 500 calls. Therefore, with recursion, you can only compute binary numbers that are up to a maximum of 500 bits, so this means that the maximum decimal number you can put into the above function is approximately 2500 - 1. Anything more will give you an error saying that MATLAB has reached its recursion limit.
How can one find the last two digits of a decimal number using MATLAB?
Example:
59 for 1.23000659
35 for 56368.35
12 for 548695412
There will always be issues when you have a decimal number with many integer digits and fractional digits. In this case, the number of integer and decimal digits decide if we are correct or not in estimating the last two digits. Let's take at the code and the comments thereafter.
Code
%// num is the input decimal number
t1 = num2str(num,'%1.15e') %// Convert number to exponential notation
t1 = t1(1:strfind(t1,'e')-1)
lastind = find(t1-'0',1,'last')
out = str2num(t1(lastind-1:lastind)) %// desired output
Results and Conclusions
For num = 1.23000659, it prints the output as 59, which is correct thanks
to the fact that the number of integer and decimal digits don't add upto
more than 16.
For num = 56368.35, we get output as 35, which is correct again and the
reason is the same as before.
For num = 548695412, we are getting the correct output of 12 because of the
same good reason.
For an out of the question sample of num = 2736232.3927327329236576
(deliberately chosen a number with many integer and fractional digits),
the code run gives output as 33 which is wrong and the reason could be
inferred from the fact that integer and decimal digits add upto a much
bigger number than the code could handle.
One can look into MATLAB command vpa for getting more precision, if extreme cases like the 4th one are to dealt with.
Convert to string and then extract the last two characters:
x = 1.23; % x = 1.23
s = num2str(x); % s = "1.23"
t = s(end-1:end); % t = "23"
u = str2num(t); % u = 23
Note: depending on your specific needs you might want to supply a precision or formatSpec to num2str.
The other two answers are nice and straight forward, but here you have a mathematical way of doing it ;)
Assuming a as your number,
ashift=0.01*a; %shift the last two digits
afloor=floor(ashift); %crop the last two digits
LastDecimals=a-100*afloor; %substract the cropped number form the original, only the last two digits left.
Of course if you have non-natural numbers, you can figure those out too with the same "floor and subtract technique as above.
I've got a huge array of values, all or which are much smaller than 1, so using a round up/down function is useless. Is there anyway I can use/make the 'find' function on these non-integer values?
e.g.
ind=find(x,9.5201e-007)
FWIW all the values are in acceding sequential order in the array.
Much appreciated!
The syntax you're using isn't correct.
find(X,k)
returns k non-zero values, which is why k must be an integer. You want
find(x==9.5021e-007);
%# ______________<-- logical index: ones where condition is true, else zeros
%# the single-argument of find returns all non-zero elements, which happens
%# at the locations of your value of interest.
Note that this needs to be an exact representation of the floating point number, otherwise it will fail. If you need tolerance, try the following example:
tol = 1e-9; %# or some other value
val = 9.5021e-007;
find(abs(x-val)<tol);
When I want to find real numbers in some range of tolerance, I usually round them all to that level of toleranace and then do my finding, sorting, whatever.
If x is my real numbers, I do something like
xr = 0.01 * round(x/0.01);
then xr are all multiples of .01, i.e., rounded to the nearest .01. I can then do
t = find(xr=9.22)
and then x(t) will be every value of x between 9.2144444444449 and 9.225.
It sounds from your comments what you want is
`[b,m,n] = unique(x,'first');
then b will be a sorted version of the elements in x with no repeats, and
x = b(n);
So if there are 4 '1's in n, it means the value b(1) shows up in x 4 times, and its locations in x are at find(n==1).