I am trying to sum each digit in the number 2^1000, for instance, the sum of each digits in 25346 = 2+5+3+4+6 = 20.
I wrote a code in Matlab looking like this:
clc, clear all, close all,
x=2^1000;
x=vpa(x,400);
sum=0;
while x>0
num=mod(x,10);
sum = sum+num;
x=floor(x/10);
end
sum % = 1349, correct answer should be 1366
For smaller numbers, this code works. I'm guessing there's something fishy with the vpa command, but I can't figure out what.
Anyone have any ideas? Is there an easier and faster way of doing this in matlab?
Merge these two lines as it is shown in the documentation:
x=2^1000;
x=vpa(x,400);
to this
x=vpa(2^1000,400);
Related
I am using a while loop with an index t starting from 1 and increasing with each loop.
I'm having problems with this index in the following bit of code within the loop:
dt = 100000^(-1);
t = 1;
equi = false;
while equi==false
***some code that populates the arrays S(t) and I(t)***
t=t+1;
if (t>2/dt)
n = [S(t) I(t)];
np = [S(t-1/dt) I(t-1/dt)];
if sum((n-np).^2)<1e-5
equi=true;
end
end
First, the code in the "if" statement is accessed at t==200000 instead of at t==200001.
Second, the expression S(t-1/dt) results in the error message "Subscript indices must either be real positive integers or logicals", even though (t-1/dt) is whole and equals 1.0000e+005 .
I guess I can solve this using "round", but this worked before and suddenly doesn't work and I'd like to figure out why.
Thanks!
the expression S(t-1/dt) results in the error message "Subscript indices must either be real positive integers or logicals", even though (t-1/dt) is whole and equals 1.0000e+005
Is it really? ;)
mod(200000 - 1/dt, 1)
%ans = 1.455191522836685e-11
Your index is not an integer. This is one of the things to be aware of when working with floating point arithmetic. I suggest reading this excellent resource: "What every computer scientist should know about floating-point Arithmetic".
You can either use round as you did, or store 1/dt as a separate variable (many options exist).
Matlab is lying to you. You're running into floating point inaccuracies and Matlab does not have an honest printing policy. Try printing the numbers with full precision:
dt = 100000^(-1);
t = 200000;
fprintf('2/dt == %.12f\n',2/dt) % 199999.999999999971
fprintf('t - 1/dt == %.12f\n',t - 1/dt) % 100000.000000000015
While powers of 10 are very nice for us to type and read, 1e-5 (your dt) cannot be represented exactly as a floating point number. That's why your resulting calculations aren't coming out as even integers.
The statement
S(t-1/dt)
can be replaced by
S(uint32(t-1/dt))
And similarly for I.
Also you might want to save 1/dt hardcoded as 100000 as suggested above.
I reckon this will improve the comparison.
I have written a function that is the beginning of a Poisson Process
function n_t = PoisProc2(t,tao,SIZE)
n_t=0;
for n=1:SIZE
if t>tao(1,n)
n_t=n_t+1;
end
end
end
tao is simply an array of random doubles of length SIZE. For simplicity we'll say [1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,20]
So this functions purpose is to count how many elements of tao that t is greater than for any given t.
This code works fine when I simply write
PoisProc2(3,tao,20);
the answer I get is 19 as expected, but if I write
x=1:.01:20;
y=PoisProc2(x,tao,20);
plot(x,y,'-')
y shows up as 0 in the workspace (I would expect an array of length 1901) and my plot also reads 0. I'm pretty new to Matlab, but this seems like a pretty simply thing I'm trying to do and I must be missing something obvious. Please help!
Your code does not work as you are giving a vector. So your if condition is not working as you expect.
First initialize n_t with a vector :
n_t=zeros(1,length(t))
instead of
if t>tao(1,n)
n_t=n_t+1;
end
Vectorize your expression :
n_t = n_t + (t>tao(1,n))
Cheers
Because x is a vector in your last example, the "if t>tao(1,n)" statement in your function behave totally different from what you think.
This function below should give you the right result.
function ret = PoisProc2(thresholds, vec)
ret = zeros(size(thresholds));
for k = 1:numel(thresholds)
ret(k) = numel(nonzeros(vec > thresholds(k)));
end
Side comments:
Your original function is quite C/Java style. You can see in my function, it's replaced by a one-liner "numel(nonzeros(vec > thresholds(k)))", which is more MATLAB style.
I think this can be done with hist() function. But this probably is easier to understand.
I have a matrix with some elements going to zero. This is a problem for me in consequent operations (taking log, etc). Is there a way to quickly replace zero elements in a matrix with a input of my choice. Quickly - meaning, without a loop.
The direct answer is:
M(M == 0) = realmin;
which does exactly what you ask for, replacing zeros with a small number. See that this does an implicit search for the zeros in a vectorized way. No loops are required. (This is a MATLAB way, avoiding those explicit and slow loops.)
Or, you could use max, since negative numbers are never an issue. So
M = max(M,realmin);
will also work. Again, this is a vectorized solution. I'm not positive which one is faster without a careful test, but either will surely be acceptable.
Note that I've used realmin here instead of eps, since it is as small as you can realistically get in a double precision number. But use whatever small number makes sense to you.
log10(realmin)
ans =
-307.6527
Compare that to eps.
log10(eps)
ans =
-15.6536
Sure--where A is your matrix,
A(A==0) = my_small_number;
Assume your matrix is called A
A(A==0) = eps;
What is the difference between hist and imhist functions in Matlab? I have a matrix of color levels values loaded from image with imread and need to count entropy value of the image using histogram.
When using imhist the resulting matrix contains zeros in all places except the last one (lower-right) which contains some high value number (few thousands or so).
Because that output seems to be wrong, I have tried to use hist instead of imhist and the resulting values are much better, the matrix is fulfilled with correct-looking values instead of zeros.
However, according to the docs, imhist should be better in this case and hist should give weird results..
Unfortunately I am not good at Matlab, so I can not provide you with better problem description. I can add some other information in the future, though.
So I will try to better explain my problem..I have an image, for which I should count entropy and few other values (how much bytes it will take to save that image,..). I wrote this function and it works pretty well
function [entropy, bytes_image, bytes_coding] = entropy_single_pixels(im)
im = double(im);
histg = hist(im);
histg(histg==0) = [];
nzhist = histg ./ numel(im);
entropy = -sum(nzhist.*log2(nzhist));
bytes_image = (entropy*(numel(im))/8);
bytes_coding = 2*numel(unique(im));
fprintf('ENTROPY_VALUE:%s\n',num2str(entropy));
fprintf('BYTES_IMAGE:%s\n',num2str(bytes_image));
fprintf('BYTES_CODING:%s\n',num2str(bytes_coding));
end
Then I have to count the same, but I have to make "pairs" from pixels which are below each other. So I have only half the rows and the same count of columns. I need to express every unique pixel pair as a different number, so I multiplied the first one by 1000 and added the second one to it... Subsequently I need to actually apply the same function as in the first example, but that is the time, when I am getting weird numbers from the imhist function. When using hist, it seems to be OK, but I really don't think that behavior is correct, so that must be my error somewhere. I actually understand pretty good, to what I want to do, or at least I hope so, but unfortunately Matlab makes all that kind of hard for me :)
hist- compute histogram(count number of occurance of each pixel) in color image.........
imhist- compute histogram in two dimensional image.
Use im2double instead of double if you want to use imhist. The imhist function expects double or single-precision data to be in the [0,1] data range, which is why you see everything in the last bin of the histogram.
Keeping simple, take a matrix of ones i.e.
U_iso = ones(72,37)
and some parameters
ThDeg = 0:5:180;
dtheta = 5*pi/180;
dphi = 5*pi/180;
Th = ThDeg*pi/180;
Now the code is
omega_iso = 0;
for i = 1:72
for j=1:37
omega_iso = omega_iso + U_iso(i,j)*sin(Th(j))*dphi*dtheta;
end
end
and
D_iso = (4 * pi)/omega_iso
This code is fine. It take a matrix with dimension 72*37. The loop is an approximation of the integral which is further divided by 4pi to get ONE value of directivity of antenna.
Now this code gives one value which will be around 1.002.
My problem is I dont need 1 value. I need a 72*37 matrix as my answer where the above integral approximation is implemented on each cell of the 72 * 37 matrix. and thus the Directviity 'D' also results in a matrix of same size with each cell giving the same value.
So all we have to do is instead of getting 1 value, we need value at each cell.
Can anyone please help.
You talk about creating a result that is a function essentially of the elements of U. However, in no place is that code dependent on the elements of U. Look carefully at what you have written. While you do use the variable U_iso, never is any element of U employed anywhere in that code as you have written it.
So while you talk about defining this for a matrix U, that definition is meaningless. So far, it appears that a call to repmat at the very end would create a matrix of the desired size, and clearly that is not what you are looking for.
Perhaps you tried to make the problem simple for ease of explanation. But what you did was to over-simplify, not leaving us with something that even made any sense. Please explain your problem more clearly and show code that is consistent with your explanation, for a better answer than I can provide so far.
(Note: One option MIGHT be to use arrayfun. Or the answer to this question might be more trivial, using simple vectorized operations. I cannot know at this point.)
EDIT:
Your question is still unanswerable. This loop creates a single scalar result, essentially summing over the entire array. You don't say what you mean for the integral to be computed for each element of U_iso, since you are already summing over the entire array. Please learn to be accurate in your questions, otherwise we are just guessing as to what you mean.
My best guess at the moment is that you might wish to compute a cumulative integral, in two dimensions. cumtrapz can help you there, IF that is your goal. But I'm not sure it is your goal, since your explanation is so incomplete.
You say that you wish to get the same value in each cell of the result. If that is what you wish, then a call to repmat at the end will do what you wish.