Filling arrays with random int number - arrays

I am pretty new to Matlab and am trying to create an m-by-n matrix containing numbers within a specified range (ie. between 0 and 250) with a specified step (ie. [0:10:250]).
Is there an equivalent function, or a workaround, to:
r = randi ( [a b], m , n )
where I can specify the step myself?

claudiop definitely had a good suggestion, but an alternative to this, in case you have a set of numbers that you want to randomly select from, is to chose random indices of a vector containing your desired numbers
nums = 0:10:250;
randIdxs = randi([1,numel(nums)],m,n);
nums(randIdxs);
It is randomly selecting numbers from the nums vector that will contains the numbers you want to randomly switch between. This solution becomes more useful when there is no clear pattern between all of the numbers, such as [3,5,7,13,23,37]. This is no clear spacing or function between primes, so if you wanted to randomly choose prime numbers, this solution would be good.
Updated
Edited the code above to use numel instead of length in case the numbers were in a multidimensional array. Not a huge change at all

Think about a transformation from a set of random integers over a fixed range ([a b]) to another set with a skip. Multiplication should take care of the skip... then just be careful of the end condition:
r = 10*randi([0 25], m, n);
I leave the general formula to you... if you want, you can wrap this in another function randi_skip().

You can use the randi function with the numbers between 0 and 25 and then multiplicate the result by 10.
r = mystep * randi ( [a b] , m , n )

Related

Minimum Complexity of two lists element summation comparison

I have a question in algorithm design about arrays, which should be implement in C language.
Suppose that we have an array which has n elements. For simplicity n is power of '2' like 1, 2, 4, 8, 16 , etc. I want to separate this to 2 parts with (n/2) elements. Condition of separating is lowest absolute difference between sum of all elements in two arrays for example if I have this array (9,2,5,3,6,1,4,7) it will be separate to these arrays (9,5,1,3) and (6,7,4,2) . summation of first array's elements is 18 and the summation of second array's elements is 19 and the difference is 1 and these two arrays are the answer but two arrays like (9,5,4,2) and (7,6,3,1) isn't the answer because the difference of element summation is 4 and we have found 1 . so 4 isn't the minimum difference. How to solve this?
Thank you.
This is the Partition Problem, which is unfortunately NP-Hard.
However, since your numbers are integers, if they are relatively low, there is a pseudo polynomial O(W*n^2) solution using Dynamic Programming (where W is sum of all elements).
The idea is to create the DP matrix of size (W/2+1)*(n+1)*(n/2+1), based on the following recursive formula:
D(0,i,0) = true
D(0,i,k) = false k != 0
D(x,i,k) = false x < 0
D(x,0,k) = false x > 0
D(x,i,0) = false x > 0
D(x,i,k) = D(x,i-1,k) OR D(x-arr[i], i-1,k-1)
The above gives a 3d matrix, where each entry D(x,i,k) says if there is a subset containing exactly k elements, that sums to x, and uses the first i elements as candidates.
Once you have this matrix, you just need to find the highest x (that is smaller than SUM/2) such that D(x,n,n/2) = true
Later, you can get the relevant subset by going back on the table and "retracing" your choices at each step. This thread deals with how it is done on a very similar problem.
For small sets, there is also the alternative of a naive brute force solution, which basically splits the array to all possible halves ((2n)!/(n!*n!) of those), and picks the best one out of them.

How to find the maximum of multiple arrays in MATLAB?

Let's say we have an array x. We can find the maximum value of this array as follows:
maximum = max(x);
If I have two arrays, let's say x and y, I can find the array that contains the maximum value by using the command
maximum_array = max(x, y);
Let's say that this array is y. Then, I can find the maximum value by using the max command with argument y, as before with x:
maximum_value = max(y);
This two-step procedure could be performed with the following compact, one-liner command:
maximum_value = max(max(x, y));
But what happens when we have more than 2 arrays? As far as I know, the max function does not allow to compare more than two arrays. Therefore, I have to use max for pairs of arrays, and then find the max among the intermediate results (which involves also the use of additional variables). Of course, if I have, let's say, 50 arrays, this would be - and it really is - a tedius process.
Is there a more efficient approach?
Approach #1
Concatenate column vector versions of them along dim-2 with cat and then use maximium values with max along dim-2 to get the max.
Thus, assuming x, y and z to be the input arrays, do something like this -
%// Reshape all arrays to column vectors with (:) and then use cat
M = cat(2,x(:),y(:),z(:))
%// Use max along dim-2 with `max(..,[],2)` to get column vector
%// version and then reshape back to the shape of input arrays
max_array = reshape(max(M,[],2),size(x))
Approach #2
You can use ndims to find the number of dimensions in the input arrays and then concatenate along the dimension that is plus 1 of that dimension and finally find max along it to get the maximum values array. This would avoid all of that reshaping back and forth and thus could be more efficient and a more compact code as well -
ndimsp1 = ndims(x)+1 %// no. of dimensions plus 1
maxarr = max(cat(ndimsp1,x,y,z),[],ndimsp1) %// concatenate and find max
I think the easiest approach for a small set of arrays is to column-ify and concatenate:
maxValue = max([x(:);y(:)]);
For a large number of arrays in some data structure (e.g. a cell array or a struct), I simple loop would be best:
maxValue = max(cellOfMats{1}(:));
for k = 2:length(cellOfMats)
maxValue = max([maxValue;cellOfMats{k}(:)]);
end
For the pathological case of a large number of separate arrays with differing names, I say "don't do that" and put them in a data structure or use eval with a loop.

Generating also non-unique (duplicated) permutations

I've written a basic permutation program in C.
The user types a number, and it prints all the permutations of that number.
Basically, this is how it works (the main algorithm is the one used to find the next higher permutation):
int currentPerm = toAscending(num);
int lastPerm = toDescending(num);
int counter = 1;
printf("%d", currentPerm);
while (currentPerm != lastPerm)
{
counter++;
currentPerm = nextHigherPerm(currentPerm);
printf("%d", currentPerm);
}
However, when the number input includes repeated digits - duplicates - some permutations are not being generated, since they're duplicates. The counter shows a different number than it's supposed to - Instead of showing the factorial of the number of digits in the number, it shows a smaller number, of only unique permutations.
For example:
num = 1234567
counter = 5040 (!7 - all unique)
num = 1123456
counter = 2520
num = 1112345
counter = 840
I want to it to treat repeated/duplicated digits as if they were different - I don't want to generate only unique permutations - but rather generate all the permutations, regardless of whether they're repeated and duplicates of others.
Uhm... why not just calculate the factorial of the length of the input string then? ;)
I want to it to treat repeated/duplicated digits as if they were
different - I don't want to calculate only the number of unique
permutations.
If the only information that nextHigherPerm() uses is the number that's passed in, you're out of luck. Consider nextHigherPerm(122). How can the function know how many versions of 122 it has already seen? Should nextHigherPerm(122) return 122 or 212? There's no way to know unless you keep track of the current state of the generator separately.
When you have 3 letters for example ABC, you can make: ABC, ACB, BAC, BCA, CAB, CBA, 6 combinations (6!). If 2 of those letters repeat like AAB, you can make: AAB, ABA, BAA, IT IS NOT 3! so What is it? From where does it comes from? The real way to calculate it when a digit or letter is repeated is with combinations -> ( n k ) = n! / ( n! * ( n! - k! ) )
Let's make another illustrative example: AAAB, then the possible combinations are AAAB, AABA, ABAA, BAAA only four combinations, and if you calcualte them by the formula 4C3 = 4.
How is the correct procedure to generate all these lists:
Store the digits in an array. Example ABCD.
Set the 0 element of the array as the pivot element, and exclude it from the temp array. A {BCD}
Then as you want all the combinations (Even the repeated), move the elements of the temporal array to the right or left (However you like) until you reach the n element.
A{BCD}------------A{CDB}------------A{DBC}
Do the second step again but with the temp array.
A{B{CD}}------------A{C{DB}}------------A{D{BC}}
Do the third step again but inside the second temp array.
A{B{CD}}------------A{C{DB}}------------A{D{BC}}
A{B{DC}}------------A{C{BD}}------------A{D{CB}}
Go to the first array and move the array, BCDA, set B as pivot, and do this until you find all combinations.
Why not convert it to a string then treat your program like an anagram generator?

NumPy change elements of an array with a given probability

I have an array of random numbers. I want to change only some of the elements based on a probability of say 0.07. Currently I am doing this using a for loop to iterate over every element. Is there a better way of doing this?
If the array in question is called a, you can select an average proportion of 0.07 of its values by
a[numpy.random.rand(*a.shape) < 0.07]
I don't know how you want to change these values. To multiply them by two, just do
a[numpy.random.rand(*a.shape) < 0.07] *= 2.0
Sven's answer is elegant. However, it is much faster to pick the elements you want to change with
n = numpy.random.binomial(len(a), 0.07)
a[numpy.random.randint(0, len(a), size=n)] *= 2.0
The first expression determines how many elements you want to sample (n is an integer between 0 and len(a), but on average 0.07), the second generates exactly the number of indices you want to retrieve. (Note, however, that you might get the same index several times.)
The difference to
a[numpy.random.rand(len(a)) < p]
becomes small as p approaches 1, but for small p, it might be a factor of 10 or more.

MATLAB: Defining n subsets of a matrix

I have a 1974x1 vector, Upper, and I am trying to break the information up into individual arrays of 36 items each. So, I used length to find that there are 1974 items and then divided by 36 and used the floor function. I cannot figure out how to do it all with n.
Here is my logic: I am defining n in an attempt to find the number of subsets that need to be defined. Then, I am trying to have subsetn become subset1, subset2,...,subset36. However, MATLAB only definies the matrix subsetn as a 1x36 matrix. However, this matrix contains what subset1 is supposed to contain(1...36). Do you guys have any advice for a newbie? What am I doing wrong?
binSize = 36;
nData = length(Upper);
nBins = floor(nData/36);
nDiscarded = nData - binSize*nBins;
n=1:binSize;
subsetn= [(n-1)*binSize+1:n*binSize];
You can create a 54x36 array where the nth column is your nth subset.
subsetArray=reshape(x(1:binSize*nBins),[],nBins);
You can access the nth subset as subsetArray(:,n)
Sorry in advance if I misunderstood what you want to do.
I think the following little trick might do what you want (it's hacky, but I'm no Matlab expert):
[a, b] = meshgrid(0:nBins-1, 0:binSize-1)
inds = a*binSize + b + 1
Now inds is a nBins*binSize matrix of indices. You can index Upper with it like
Upper(inds)
which should give you the subsets as the columns in the resulting matrix.
Edit: on seeing Yoda's answer, his is better ;)

Resources