Generate prime numbers recursively, Matlab - matlab

I am trying to generate prime numbers recursively using the previous primes. 2 is a prime by default and each time I keep adding 1 to the next number and divide by the previous primes, eg 2+1=3 so i check that 2 does not divide 3 so 3 is prime so i store 2 and 3 so far, next would be 3+1=4, i would use my current prime list 2 and 3, and see that 2 divides 4 so it does not go into the list then i continue with 4+1 and so forth all the way up to n. The key thing is dividing by the previous primes each time and if you reach a prime the list is updated. Please check my program to see what i am doing wrong.
this is my program so far but I am just getting 3 and 962, i want it update the list and refer back to it each time for the loop so i can use mod(2+numba,primlist) each time:
n=960;
primlist=[];
for numba=2:n
if mod(2+1,2)~=0
primlist=2+1;
end
if mod(2+numba,primlist)~=0
primlist=[primlist;2+numba];
end
end
primlist

You are initializing your primlist again and again. Do not do that. I am making as less modifications to your code to make it run correctly. The logic is essentially correct. You just need to initialize primlist outside.
n=960;
primlist=2;
for numba=1:n %Changed 2 to 1
if mod(2+numba,primlist)~=0
primlist=[primlist;2+numba];
end
end
primlist

Related

Double for loop in MATLAB, storing the information

I have two for loops in MATLAB.
One of the for loops leads to different variables being inserted into the model, which are 43 and then I have 5 horizons.
So I estimate the model 215 times.
My problem is I want to store this in 215x5 matrix, the reason I have x5 is that I am estimating 5 variables, 4 are fixed and the other one comes from the for loop.
I have tried to do this in two ways,
Firstly, I create a variable called out,
out=zeros(215,5);
The first for loop is,
for i=[1,2,3,4,5];
The second for loop is,
for ii=18:60;
The 18:60 is how I define my variables using XLS read, e.g. they are inserted into the model as (data:,ii).
I have tried to store the data in two ways, I want to store OLS which contains the five estimates
First,
out(i,:)=OLS;
This method creates a 5 x 5 matrix, with the estimates for one of the (18:60), at each of the horizons.
Second,
out(ii,:)=OLS;
This stores the variables for each of the variables (18:60), at just one horizon.
I want to have a matrix which stores all of the estimates OLS, at each of the horizons, for each of my (18:60).
Minimal example
clear;
for i=[1,2,3,4,5];
K=i;
for ii=18:60
x=[1,2,3,i,ii];
out(i,:)=x;
end
end
So the variable out will store 1 2 3 5 60
I want the variable out to store all of the combinations
i.e.
1 2 3 1 1
1 2 3 1 2
...
1 2 3 5 60
Thanks
The simplest solution is to use a 3D matrix:
for jj=[1,2,3,4,5];
K=jj;
for ii=18:60
x=[1,2,3,jj,ii];
out(ii-17,jj,:)=x;
end
end
If you now reshape the out matrix you get the same result as the first block in etmuse's answer:
out = reshape(out,[],size(out,3));
(Note I replaced i by jj. i and ii are too similar to use both, it leads to confusion. It is better to use different letters for loop indices. Also, i is OK to use, but it also is the built-in imaginary number sqrt(-1). So I prefer to use ii over i.)
As you've discovered, using just one of your loop variables to index the output results in most of the results being overwritten, leaving only the results from the final iteration of the relevant loop.
There are 2 ways to create an indexing variable.
1- You can use an independent variable, initialised before the loops and incremented at the end of the internal loop.
kk=1;
for i=1:5
for ii=18:60
%calculate OLC
out(kk,:)=OLC;
kk = kk+1;
end
end
2- Use a calculation of i and ii
kk = i + 5*(ii-18)
(Use in loop as before, without increment)

Generate matrix of random number with constraints in matlab

I want to generate a matrix of random numbers (normrnd with mean == 0) that satisfy the following constraints using MATLAB (or any other language)
The sum of the absolute values in the matrix must equal X
The largest abs(single number) must equal Y
The difference between the number and its 8 neighbors (3 if in corner, 5 if on edge) must be less than Z
It would be relatively easy to satisfy one of the constraints, but I can't think of an algorithm that satisfies all of them...
Any ideas?
I am not sure whether to edit my post or to reply here, so I am editing... #MZimmerman6, you have a point. Though these constraints won't produce a unique solution, how would I obtain multiple solutions without using rand?
A very simply 3 x 3 where 5 is the max element value, 30 is the sum, and 2 is the difference
5 4 3
4 4 2
3 2 3
Rody, that actually may help...I need to think more :)
Luis ...Hmmm...why not? I can add up the absolute value of a normally distributed sample...right?
Here is an algorithm to get the 'random' numbers that you need.
Generate a valid number (for example in the middle)
Determine the feasible range for one of the numbers next to it
If there is no range, you go to step 1, otherwise generate a number and continue
Depending on your constraints it may take a while of course. You could add an other step to see if changing the existing numbers would help before going back to step 1.

find discretization steps

I have data files F_j, each containing a list of numbers with an unknown number of decimal places. Each file contains discretized measurements of some continuous variable and
I want to find the discretization step d_j for file F_j
A solution I could come up with: for each F_j,
find the number (n_j) of decimal places;
multiply each number in F_j with 10^{n_j} to obtain integers;
find the greatest common divisor of the entire list.
I'm looking for an elegant way to find n_j with Matlab.
Also, finding the gcd of a long list of integers seems hard — do you have any better idea?
Finding the gcd of a long list of numbers isn't too hard. You can do it in time linear in the size of the list. If you get lucky, you can do it in time a lot less than linear. Essentially this is because:
gcd(a,b,c) = gcd(gcd(a,b),c)
and if either a=1 or b=1 then gcd(a,b)=1 regardless of the size of the other number.
So if you have a list of numbers xs you can do
g = xs(1);
for i = 2:length(xs)
g = gcd(x(i),g);
if g == 1
break
end
end
The variable g will now store the gcd of the list.
Here is some sample code that I believe will help you get the GCD once you have the numbers you want to look at.
A = [15 30 20];
A_min = min(A);
GCD = 1;
for n = A_min:-1:1
temp = A / n;
if (max(mod(temp,1))==0)
% yay GCD found
GCD = n;
break;
end
end
The basic concept here is that the default GCD will always be 1 since every number is divisible by itself and 1 of course =). The GCD also can't be greater than the smallest number in the list, thus I start with the smallest number and then decriment by 1. This is assuming that you have already converted the numbers to a whole number form at this point. Decimals will throw this off!
By using the modulus of 1 you are testing to see if the number is a whole number, if it isn't you will have a decmial remainder left which is greater than 0. If you anticipate having to deal with negative you will have to tweak this test!
Other than that, the first time you find a number where the modulus of the list (mod 1) is all zeros you've found the GCD.
Enjoy!

matlab percentage change between cells

I'm a newbie to Matlab and just stumped how to do a simple task that can be easily performed in excel. I'm simply trying to get the percent change between cells in a matrix. I would like to create a for loop for this task. The data is setup in the following format:
DAY1 DAY2 DAY3...DAY 100
SUBJECT RESULTS
I could only perform getting the percent change between two data points. How would I conduct it if across multiple days and multiple subjects? And please provide explanation
Thanks a bunch
FOR EXAMPLE, FOR DAY 1 SUBJECT1(RESULT=1), SUBJECT2(RESULT=4), SUBJECT3(RESULT=5), DAY 2 SUBJECT1(RESULT=2), SUBJECT2(RESULT=8), SUBJECT3(RESULT=10), DAY 3 SUBJECT1(RESULT=1), SUBJECT2(RESULT=4), SUBJECT3(RESULT=5).
I WANT THE PERCENT CHANGE SO OUTPUT WILL BE DAY 2 SUBJECT1(RESULT=100%), SUBJECT2(RESULT=100%), SUBJECT3(RESULT=100%). DAY3 SUBJECT1(RESULT=50%), SUBJECT2(RESULT=50%), SUBJECT3(RESULT=50%)
updated:
Hi thanks for responding guys. sorry for the confusion. zebediah49 is pretty close to what I'm looking for. My data is for example a 10 x 10 double. I merely wanted to get the percentage change from column to column. For example, if I want the percentage change from rows 1 through 10 on all columns (from columns 2:10). I would like the code to function for any matrix dimension (e.g., 1000 x 1000 double) zebediah49 could you explain the code you posted? thanks
updated2:
zebediah49,
(data(1:end,100)- data(1:end,99))./data(1:end,99)
output=[data(:,2:end)-data(:,1:end-1)]./data(:,1:end-1)*100;
Observing the code above, How would I go about modifying it so that column 100 is used as the index against all of the other columns(1-99)? If I change the code to the following:
(data(1:end,100)- data(1:end,:))./data(1:end,:)
matlab is unable because of exceeding matrix dimensions. How would I go about implementing that?
UPDATE 3
zebediah49,
Worked perfectly!!! Originally I created a new variable for the index and repmat the index to match the matrices which was not a good idea. It took forever to replicate when dealing with large numbers.
Thanks for you contribution once again.
Thanks Chris for your contribution too!!! I was looking more on how to address and manipulate arrays within a matrix.
It's matlab; you don't actually want a loop.
output=input(2:end,:)./input(1:end-1,:)*100;
will probably do roughly what you want. Since you didn't give anything about your matlab structure, you may have to change index order, etc. in order to make it work.
If it's not obvious, that line defines output as a matrix consisting of the input matrix, divided by the input matrix shifted right by one element. The ./ operator is important, because it means that you will divide each element by its corresponding one, as opposed to doing matrix division.
EDIT: further explanation was requested:
I assumed you wanted % change of the form 1->1->2->3->1 to be 100%, 200%, 150%, 33%.
The other form can be obtained by subtracting 100%.
input(2:end,:) will grab a sub-matrix, where the first row is cut off. (I put the time along the first dimension... if you want it the other way it would be input(:,2:end).
Matlab is 1-indexed, and lets you use the special value end to refer to the las element.
Thus, end-1 is the second-last.
The point here is that element (i) of this matrix is element (i+1) of the original.
input(1:end-1,:), like the above, will also grab a sub-matrix, except that that it's missing the last column.
I then divide element (i) by element (i+1). Because of how I picked out the sub-matrices, they now line up.
As a semi-graphical demonstration, using my above numbers:
input: [1 1 2 3 1]
input(2,end): [1 2 3 1]
input(1,end-1): [1 1 2 3]
When I do the division, it's first/first, second/second, etc.
input(2:end,:)./input(1:end-1,:):
[1 2 3 1 ]
./ [1 1 2 3 ]
---------------------
== [1.0 2.0 1.5 0.3]
The extra index set to (:) means that it will do that procedure across all of the other dimension.
EDIT2: Revised question: How do I exclude a row, and keep it as an index.
You say you tried something to the effect of (data(1:end,100)- data(1:end,:))./data(1:end,:). Matlab will not like this, because the element-by-element operators need them to be the same size. If you wanted it to only work on the 100th column, setting the second index to be 100 instead of : would do that.
I would, instead, suggest setting the first to be the index, and the rest to be data.
Thus, the data is processed by cutting off the first:
output=[data(2:end,2:end)-data(2:end,1:end-1)]./data(2:end,1:end-1)*100;
OR, (if you neglect the start, matlab assumes 1; neglect the end and it assumes end, making (:) shorthand for (1:end).
output=[data(2:,2:end)-data(2:,1:end-1)]./data(2:,1:end-1)*100;
However, you will probably still want the indices back, in which case you will need to append that subarray back:
output=[data(1,1:end-1) data(2:,2:end)-data(2:,1:end-1)]./data(2:,1:end-1)*100];
This is probably not how you should be doing it though-- keep data in one matrix, and time or whatever else in a separate array. That makes it much easier to do stuff like this to data, without having to worry about excluding time. It's especially nice when graphing.
Oh, and one more thing:
(data(:,2:end)-data(:,1:end-1))./data(:,1:end-1)*100;
is identically equivalent to
data(:,2:end)./data(:,1:end-1)*100-100;
Assuming zebediah49 guessed right in the comment above and you want
1 4 5
2 8 10
1 4 5
to turn into
1 1 1
-.5 -.5 -.5
then try this:
data = [1,4,5; 2,8,10; 1,4,5];
changes_absolute = diff(data);
changes_absolute./data(1:end-1,:)
ans =
1.0000 1.0000 1.0000
-0.5000 -0.5000 -0.5000
You don't need the intermediate variable, you can directly write diff(data)./data(1:end,:). I just thought the above might be easier to read. Getting from that result to percentage numbers is left as an exercise to the reader. :-)
Oh, and if you really want 50%, not -50%, just use abs around the final line.

Finding 5 consecutive successes using Matlab?

I have a function which for 10 cycles finds the difference between individual sensor values and the average sensor value. The test will be done 100 times using this function. So every time cycle>10 I am forcing it to be zero so that in the 11th repetition it will restart counting from zero. Here is the code:
cycle=cycle +1;
if cycle>10
cycle=0;
end
for i=1: TotalnoOfGrids
for j=1: noOfNodes
if abs(char(Allquants{i}(j))-char(mostCommonLetters {i}))>0
if cycle>0
wrong{i}(j)=wrong{i}(j)+1;
else
wrong{i}(j)=0;
end
end
end
end
Now I need to know if the sensor performed 5 consecutive successes in the period of 10 cycles. How can I do that?
I thought of a loop but I read that it takes too much time.
Doing a search on the net I have found this SO question.
The problem is that the above function will be repeated for 100 cycles.I want for every 10 cycles see if there is consecutive successes so it is beeing done dynamically and I am not saving the success or failure status of the sensor for the cycles. So i do not have a vector containing 1 or 0 to use the function used in the above reference or as Jonas suggested
If a loop is the easiest thing, give it a try! Just because you've read it "takes too much time" doesn't mean it really makes a difference for your case! It is true that in Matlab it often makes sense to avoid loops; but in your case, 100*20*9 (if I understand you correctly) loop iterations doesn't seem so bad yet (depending on your speed requirement).
Edit (corrected answer)
I now understand from your comments that the code you show us is surrounded by a while or for loop which is being run ~100 times, and that Allquants and mostCommonLetters probably change inside that loop. In this case my previous answer didn't work for you, since it counted successes on different sensors; this should be better now.
If I read your code correctly, the condition abs(char(Allquants{i}(j))-char(mostCommonLetters {i}))>0 tells you that a result was "wrong"; consequently,
for i=1:TotalnoOfGrids
this_cycle_successes(i,:)=char(Allquants{i})==char(mostCommonLetters{i});
end
consecutive_successes=(consecutive_successes+1).*this_cycle_successes;
would calculate how many successes you had in a row. Note you need to initialize consecutive_successes before starting your cycle loop, e.g.
consecutive_successes = zeros(9,20);
After the 10 cycles, you can check which sensors had 5 successes like this:
has5successes = consecutive_successes>=5;
Note that this is a matrix operation, so now you will get 9*20 values, as you requested in your comment. This solution wouldn't require a loop over j.