Detecting if a Number is within a Certain Range - java

I have a portion of code which generates a random number, and then attempts to find out where the number falls, between zero and some probability, stored in an array as a percentage. I understand that this may sound much more confusing than it actually is, so here is my code, essentially, in Java:
Random rand = new Random();
double currentProbability = rand.nextDouble();
// these are the "percentages" I refer to above
// note that they will not necessarily be in least-to-greatest/greatest-to-least
// order
double[] probabilities = new double[]{0.49, 0.49, 0.02};
// the objects in the array below correspond to the probabilities at the same
// index in the "probabilities" array above
Object[] correspondingObjects = new Object[]{new Object(), new Object(), new Object()};
// here, I would find between which percentage the random number lies, and choose
// the corresponding object from the array of Objects
Therefore, my issue is mainly how to select in which index the random number lies, if the probability is given as a percentage. Perhaps I am over-complicating this, and I would ask that any user who believes that this is the case leave a comment below instead of down-voting this question.

Here is the code for finding index:
int index = 0;
while (true) {
currentProbability -= probabilities[index];
if (currentProbability <= 0) {
break;
}
index++;
}

D.E. Knuth describes a method that is beneficial if the number of cases to choose from is large. If you have to choose among n cases, you distribute them into n-1 buckets of equal sizes, such that there are no more than 2 cases in each bucket. It can be shown that this is always possible. To select a case is then a two step process that can be performed in constant time: first select a bucket, then decide which of the two cases in this bucket applies.
For example if the distribution for A, B, C is [0.49, 0.49, 0.02] we would come up with two buckets of size 0.5 each. The first contains 0.02 C and 0.48 A; the second 0.01 A and 0.49 B. In sum, you get the original probabilities.
If the generated random number r is below 0.5 we choose the first bucket, if r is below 0.02 the case C is selected, otherwise A. If r is above 0.5, the second bucket is selected and if (r-0.5) is below 0.01 we select case A otherwise case B.

It sounds like you want to do a weighted shuffle. depending on the size of your set, it may be easier to just load a List with objects multiple times then use the static shuffle(List) method in java.util.Collection and pop an object off the top of the List.
For instance,
for [.49,.49,.02] this would be normalized.
for [.10, .10, .80] this would normalize to [.1, .1, .8] so if this is [A, B, C] you would load 1 A, 1 B and 8 C objects into a list then use shuffle.
Obviously, if you have a very fine precision on your List and lots of objects then this solution would not be optimal.

Related

Java - how to divide an integer into 5 random parts

I'm working on an android graphics app, and at some point in the code, I need to divide lets say, a rectangle's width into 5 random sizes.
I have my randomintegerfunction(int min, int max) in my activity, but that can help me divide it into 2 parts.
How do I go about dividing an integer, lets say 100, into 5 random parts, so that the first one or two parts arent always the biggest, then I subdivide for the third, fourth and fifth parts?
Right now, I am know I can try to implememt it using my random integer generator,but the issue, I think is that I'd have to use some forced divisions, like dividing the first 70% of the integer into 2 parts, then dividing the remaining 20% into two parts, to make a total of 5 parts, but such a method would always make the first part be bigger than the fifth part, which I'd like to avoid...to make it truly random.
What I'd like, for example...
the first part to potentially be 7,
second part 25,
third part 5,
fourth part 40,
fifth/last/remaining part 23. To add up to 100 (or any integer).
I am not sure about how to write the logic of such a function...so please if you have any ideas of how to implement a function that randomly divides an integer into 3 or 4 or 5 or 6 truly random sizes/parts, please enlighten me!
Thanks for your time!
You could randomly select from the amount remaining.
int[] nums = new int[5];
int total = 100;
Random rand = new Random();
for (int i = 0; i < nums.length-1; i++) {
nums[i] = rand.nextInt(total);
total -= nums[i];
}
nums[nums.length-1] = total;
Arrays.sort(nums);
This will select a random number and ensure the sum is always the same. The last sort ensures they are in ascending order.
A simple algorithm is to put the numbers 1-99 into a list, shuffle them, and take the first 4 elements as your "split points", i.e. positions at which to divide the number range.
List<Integer> splitPoints =
IntStream.rangeClosed(1, 99)
.boxed().collect(Collectors.toList());
Collections.shuffle(splitPoints);
splitPoints.subList(4, splitPoints.size()).clear();
Collections.sort(splitPoints);
Now, you have 4 randomly-placed split points. The ranges go from:
0 -> splitPoints.get(0)
splitPoints.get(0) -> splitPoints.get(1)
...
splitPoints.get(3) -> 100.
Take four numbers from below range:
4 to n-1
And then divide each number by four .
And fifth number to be n - (sum of other four).
Where n is 100 in the given case..
Again this is one way of implementation and there are hundred of ways to implement it
Hope that helps.
The most efficient way to do this and to keep proper distribution - looks like this.
1) In general cases. You need divide line into N parts.
generate N-1 doubles [0,1], add 0 and 1, and sort them -> x[i] = {0, ..., 1}
N-1 point divide line into N parts -> 0=x[0]..x[1]; x[1]...x[2]; ... x[N]..x[N+1]=1
scale each part to proper size -> len[i] = (x[i+1]-x[i])*total_length
cast to int if needed
2) In case when you need large Objects and small gaps - split you length with desirable proportion, like 70% for objects and 30% for gaps. Or generate it nextDouble(0.2)+0.2 for [0.2,0.4) range for gaps. Then use proposed algorithm twice.

Array Duplicate Efficiency Riddle

Recently in AP Computer Science A, our class recently learned about arrays. Our teacher posed to us a riddle.
Say you have 20 numbers, 10 through 100 inclusive, right? (these numbers are gathered from another file using Scanners)
As each number is read, we must print the number if and only if it is not a duplicate of a number already read. Now, here's the catch. We must use the smallest array possible to solve the problem.
That's the real problem I'm having. All of my solutions require a pretty big array that has 20 slots in it.
I am required to use an array. What would be the smallest array that we could use to solve the problem efficiently?
If anyone could explain the method with pseudocode (or in words) that would be awesome.
In the worst case we have to use an array of length 19.
Why 19? Each unique number has to be remembered in order to sort out duplicates from the following numbers. Since you know that there are 20 numbers incoming, but not more, you don't have to store the last number. Either the 20th number already appeared (then don't do anything), or the 20th number is unique (then print it and exit – no need to save it).
By the way: I wouldn't call an array of length 20 big :)
If your numbers are integers: You have a range from 10 to 100. So you need 91 Bits to store which values have already been read. A Java Long has 64 Bits. So you will need an array of two Longs. Let every Bit (except for the superfluous ones) stand for a number from 10 to 100. Initialize both longs with 0. When a number is read, check if the corresponding bit mapped to the read value is set to 1. If yes, the read number is a duplicate, if no set the bit to 1.
This is the idea behind the BitSet class.
Agree with Socowi. If number of numbers is known and it is equal to N , it is always possible to use N-1 array to store duplicates. Once the last element from the input is received and it is already known that this is the last element, it is not really needed to store this last value in the duplicates array.
Another idea. If your numbers are small and really located in [10:100] diapason, you can use 1 Long number for storing at least 2 small Integers and extract them from Long number using binary AND to extract small integers values back. In this case it is possible to use N/2 array. But it will make searching in this array more complicated and does not save much memory, only number of items in the array will be decreased.
You technically don't need an array, since the input size is fixed, you can just declare 20 variables. But let's say it wasn't fixed.
As other answer says, worst case is indeed 19 slots in the array. But, assuming we are talking about integers here, there is a better case scenario where some numbers form a contiguous interval. In that case, you only have to remember the highest and lowest number, since anything in between is also a duplicate. You can use an array of intervals.
With the range of 10 to 100, the numbers can be spaced apart and you still need an array of 19 intervals, in the worst case. But let's say, that the best case occurs, and all numbers form a contiguous interval, then you only need 1 array slot.
The problem you'd still have to solve is to create an abstraction over an array, that expands itself by 1 when an element is added, so it will use the minimal size necessary. (Similar to ArrayList, but it doubles in size when capacity is reached).
Since an array cannot change size at run time You need a companion variable to count the numbers that are not duplicates and fill the array partially with only those numbers.
Here is a simple code that use companion variable currentsize and fill the array partially.
Alternative you can use arrayList which change size during run time
final int LENGTH = 20;
double[] numbers = new double[LENGTH];
int currentSize = 0;
Scanner in = new Scanner(System.in);
while (in.hasNextDouble()){
if (currentSize < numbers.length){
numbers[currentSize] = in.nextDouble();
currentSize++;
}
}
Edit
Now the currentSize contains those actual numbers that are not duplicates and you did not fill all 20 elements in case you had some duplicates. Of course you need some code to determine whither a numbers is duplicate or not.
My last answer misunderstood what you were needing, but I turned this thing up that does it an int array of 5 elements using bit shifting. Since we know the max number is 100 we can store (Quite messily) four numbers into each index.
Random rand = new Random();
int[] numbers = new int[5];
int curNum;
for (int i = 0; i < 20; i++) {
curNum = rand.nextInt(100);
System.out.println(curNum);
boolean print = true;
for (int x = 0; x < i; x++) {
byte numberToCheck = ((byte) (numbers[(x - (x % 4)) / 4] >>> ((x%4) * 8)));
if (numberToCheck == curNum) {
print = false;
}
}
if (print) {
System.out.println("No Match: " + curNum);
}
int index = ((i - (i % 4)) / 4);
numbers[index] = numbers[index] | (curNum << (((i % 4)) * 8));
}
I use rand to get my ints but you could easily change this to a scanner.

Pick a number randomly from two numbers

I have two integers, let them be
int a = 35:
int b = 70;
I want to pick one of them randomly at runtime and assign to another variable. I.e.
int c = a or b:
One of the ways that come into my mind is to create an array with these two integers and find a random integer between 0 and 1 and use it as the index of the array to get the number..
Or randomize boolean and use it in if-else.
My question is that is there a better and more efficient way to achieve this? I.e. pick a number from two previously defined integers?
Is there a specific reason you are asking for a more efficient solution? Unless this functionality sits in a very tight inner loop somewhere (e.g. in a ray tracer), you might be trying to prematurely optimize your code.
If you would like to avoid the array, and if you don't like the "bloat" of an if-statement, you can use the ternary choice operator to pick between the two:
int a = 35;
int b = 70;
int c = random.nextBoolean() ? a : b;
where random is an instance of java.util.Random. You can store this instance as a final static field in your class to reuse it.
If you don't require true randomness, but just want to switch between the two numbers in each invocation of the given block of code, you can get away with just storing a boolean and toggling it:
...
int c = toggle ? a : b;
toggle = !toggle;
Since I can't comment on other answers, I'd like to point out an issue with some of the other answers that suggest generating a random integer in a bigger range and making a decision based on whether the result is odd or even, or if it's lower or greater than the middle value. This is in effect the exact same thing as generating a random integer between 0 and 1, except overly complicated. The nextInt(n) method uses the modulo operator on a randomly generated integer between -2^31 and (2^31)-1, which is essentially what you will be doing in the end anyway, just with n = 2.
If you are using the standard library methods like Collections.shuffle(), you will again be overcomplicating things, because the standard library uses the random number generator of the standard library.
Note that all of the suggestions (so far) are less efficient than my simple nextBoolean() suggestion, because they require unnecessary method calls and arithmetic.
Another way to do this is, store the numbers into a list, shuffle, and take the first element.
ArrayList<Integer> numbers=new ArrayList<Integer>();
numbers.add(35);
numbers.add(70);
Collections.shuffle(numbers);
numbers.get(0);
In my opinion, main problem here is entropy for two numbers rather than making use of that entropy. Indexed array or boolean are essentially the same thing. What else you can do (and, hopefully, it will be more random) is to make Java give you a random number between limits say 0 to 100. Now, if the chosen random number is odd, you pick int c = a. Pick b otherwise. I could be wrong, but picking random between 0 to 100 seems more random as compared to picking random between two numbers.
You can simply use secure random generator(java.security.SecureRandom ).
try {
r = SecureRandom.getInstance("SHA1PRNG");
boolean b1 = r.nextBoolean();
if (b1) {
c = a;
} else {
c = b;
}
} catch (NoSuchAlgorithmException nsae) {
// Process the exception in some way or the other
}
Refer this link for more information
Randomize an integer between 1 and 10, if it's more than 5 then take the value of b other wise go with a. As far as I know there are no other ways to select from integers.
int a=1;
int b=2;
int get = new Random().nextBoolean()? a : b;

How to efficiently generate a set of unique random numbers with a predefined distribution?

I have a map of items with some probability distribution:
Map<SingleObjectiveItem, Double> itemsDistribution;
Given a certain m I have to generate a Set of m elements sampled from the above distribution.
As of now I was using the naive way of doing it:
while(mySet.size < m)
mySet.add(getNextSample(itemsDistribution));
The getNextSample(...) method fetches an object from the distribution as per its probability. Now, as m increases the performance severely suffers. For m = 500 and itemsDistribution.size() = 1000 elements, there is too much thrashing and the function remains in the while loop for too long. Generate 1000 such sets and you have an application that crawls.
Is there a more efficient way to generate a unique set of random numbers with a "predefined" distribution? Most collection shuffling techniques and the like are uniformly random. What would be a good way to address this?
UPDATE: The loop will call getNextSample(...) "at least" 1 + 2 + 3 + ... + m = m(m+1)/2 times. That is in the first run we'll definitely get a sample for the set. The 2nd iteration, it may be called at least twice and so on. If getNextSample is sequential in nature, i.e., goes through the entire cumulative distribution to find the sample, then the run time complexity of the loop is at least: n*m(m+1)/2, 'n' is the number of elements in the distribution. If m = cn; 0<c<=1 then the loop is at least Sigma(n^3). And that too is the lower bound!
If we replace sequential search by binary search, the complexity would be at least Sigma(log n * n^2). Efficient but may not be by a large margin.
Also, removing from the distribution is not possible since I call the above loop k times, to generate k such sets. These sets are part of a randomized 'schedule' of items. Hence a 'set' of items.
Start out by generating a number of random points in two dimentions.
Then apply your distribution
Now find all entries within the distribution and pick the x coordinates, and you have your random numbers with the requested distribution like this:
The problem is unlikely to be the loop you show:
Let n be the size of the distribution, and I be the number of invocations to getNextSample. We have I = sum_i(C_i), where C_i is the number of invocations to getNextSample while the set has size i. To find E[C_i], observe that C_i is the inter-arrival time of a poisson process with λ = 1 - i / n, and therefore exponentially distributed with λ. Therefore, E[C_i] = 1 / λ = therefore E[C_i] = 1 / (1 - i / n) <= 1 / (1 - m / n). Therefore, E[I] < m / (1 - m / n).
That is, sampling a set of size m = n/2 will take, on average, less than 2m = n invocations of getNextSample. If that is "slow" and "crawls", it is likely because getNextSample is slow. This is actually unsurprising, given the unsuitable way the distrubution is passed to the method (because the method will, of necessity, have to iterate over the entire distribution to find a random element).
The following should be faster (if m < 0.8 n)
class Distribution<T> {
private double[] cummulativeWeight;
private T[] item;
private double totalWeight;
Distribution(Map<T, Double> probabilityMap) {
int i = 0;
cummulativeWeight = new double[probabilityMap.size()];
item = (T[]) new Object[probabilityMap.size()];
for (Map.Entry<T, Double> entry : probabilityMap.entrySet()) {
item[i] = entry.getKey();
totalWeight += entry.getValue();
cummulativeWeight[i] = totalWeight;
i++;
}
}
T randomItem() {
double weight = Math.random() * totalWeight;
int index = Arrays.binarySearch(cummulativeWeight, weight);
if (index < 0) {
index = -index - 1;
}
return item[index];
}
Set<T> randomSubset(int size) {
Set<T> set = new HashSet<>();
while(set.size() < size) {
set.add(randomItem());
}
return set;
}
}
public class Test {
public static void main(String[] args) {
int max = 1_000_000;
HashMap<Integer, Double> probabilities = new HashMap<>();
for (int i = 0; i < max; i++) {
probabilities.put(i, (double) i);
}
Distribution<Integer> d = new Distribution<>(probabilities);
Set<Integer> set = d.randomSubset(max / 2);
//System.out.println(set);
}
}
The expected runtime is O(m / (1 - m / n) * log n). On my computer, a subset of size 500_000 of a set of 1_000_000 is computed in about 3 seconds.
As we can see, the expected runtime approaches infinity as m approaches n. If that is a problem (i.e. m > 0.9 n), the following more complex approach should work better:
Set<T> randomSubset(int size) {
Set<T> set = new HashSet<>();
while(set.size() < size) {
T randomItem = randomItem();
remove(randomItem); // removes the item from the distribution
set.add(randomItem);
}
return set;
}
To efficiently implement remove requires a different representation for the distribution, for instance a binary tree where each node stores the total weight of the subtree whose root it is.
But that is rather complicated, so I wouldn't go that route if m is known to be significantly smaller than n.
If you are not concerning with randomness properties too much then I do it like this:
create buffer for pseudo-random numbers
double buff[MAX]; // [edit1] double pseudo random numbers
MAX is size should be big enough ... 1024*128 for example
type can be any (float,int,DWORD...)
fill buffer with numbers
you have range of numbers x = < x0,x1 > and probability function probability(x) defined by your probability distribution so do this:
for (i=0,x=x0;x<=x1;x+=stepx)
for (j=0,n=probability(x)*MAX,q=0.1*stepx/n;j<n;j++,i++) // [edit1] unique pseudo-random numbers
buff[i]=x+(double(i)*q); // [edit1] ...
The stepx is your accuracy for items (for integral types = 1) now the buff[] array has the same distribution as you need but it is not pseudo-random. Also you should add check if j is not >= MAX to avoid array overruns and also at the end the real size of buff[] is j (can be less than MAX due to rounding)
shuffle buff[]
do just few loops of swap buff[i] and buff[j] where i is the loop variable and j is pseudo-random <0-MAX)
write your pseudo-random function
it just return number from the buffer. At first call returns the buff[0] at second buff[1] and so on ... For standard generators When you hit the end of buff[] then shuffle buff[] again and start from buff[0] again. But as you need unique numbers then you can not reach the end of buffer so so set MAX to be big enough for your task otherwise uniqueness will not be assured.
[Notes]
MAX should be big enough to store the whole distribution you want. If it is not big enough then items with low probability can be missing completely.
[edit1] - tweaked answer a little to match the question needs (pointed by meriton thanks)
PS. complexity of initialization is O(N) and for get number is O(1).
You should implement your own random number generator (using a MonteCarlo methode or any good uniform generator like mersen twister) and basing on the inversion method (here).
For example : exponential law: generate a uniform random number u in [0,1] then your random variable of the exponential law would be : ln(1-u)/(-lambda) lambda being the exponential law parameter and ln the natural logarithm.
Hope it'll help ;).
I think you have two problems:
Your itemDistribution doesn't know you need a set, so when the set you are building gets
large you will pick a lot of elements that are already in the set. If you start with the
set all full and remove elements you will run into the same problem for very small sets.
Is there a reason why you don't remove the element from the itemDistribution after you
picked it? Then you wouldn't pick the same element twice?
The choice of datastructure for itemDistribution looks suspicious to me. You want the
getNextSample operation to be fast. Doesn't the map from values to probability force you
to iterate through large parts of the map for each getNextSample. I'm no good at
statistics but couldn't you represent the itemDistribution the other way, like a map from
probability, or maybe the sum of all smaller probabilities + probability to a element
of the set?
Your performance depends on how your getNextSample function works. If you have to iterate over all probabilities when you pick the next item, it might be slow.
A good way to pick several unique random items from a list is to first shuffle the list and then pop items off the list. You can shuffle the list once with the given distribution. From then on, picking your m items ist just popping the list.
Here's an implementation of a probabilistic shuffle:
List<Item> prob_shuffle(Map<Item, int> dist)
{
int n = dist.length;
List<Item> a = dist.keys();
int psum = 0;
int i, j;
for (i in dist) psum += dist[i];
for (i = 0; i < n; i++) {
int ip = rand(psum); // 0 <= ip < psum
int jp = 0;
for (j = i; j < n; j++) {
jp += dist[a[j]];
if (ip < jp) break;
}
psum -= dist[a[j]];
Item tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
return a;
}
This in not Java, but pseudocude after an implementation in C, so please take it with a grain of salt. The idea is to append items to the shuffled area by continuously picking items from the unshuffled area.
Here, I used integer probabilities. (The proabilities don't have to add to a special value, it's just "bigger is better".) You can use floating-point numbers but because of inaccuracies, you might end up going beyond the array when picking an item. You should use item n - 1 then. If you add that saftey net, you could even have items with zero probability that always get picked last.
There might be a method to speed up the picking loop, but I don't really see how. The swapping renders any precalculations useless.
Accumulate your probabilities in a table
Probability
Item Actual Accumulated
Item1 0.10 0.10
Item2 0.30 0.40
Item3 0.15 0.55
Item4 0.20 0.75
Item5 0.25 1.00
Make a random number between 0.0 and 1.0 and do a binary search for the first item with a sum that is greater than your generated number. This item would have been chosen with the desired probability.
Ebbe's method is called rejection sampling.
I sometimes use a simple method, using an inverse cumulative distribution function, which is a function that maps a number X between 0 and 1 onto the Y axis.
Then you just generate a uniformly distributed random number between 0 and 1, and apply the function to it.
That function is also called the "quantile function".
For example, suppose you want to generate a normally distributed random number.
It's cumulative distribution function is called Phi.
The inverse of that is called probit.
There are many ways to generate normal variates, and this is just one example.
You can easily construct an approximate cumulative distribution function for any univariate distribution you like, in the form of a table.
Then you can just invert it by table-lookup and interpolation.

Creating an even amount of randomness in an array

Let's say that you have an arbitrarily large sized two-dimensional array with an even amount of items in it. Let's also assume for clarity that you can only choose between two things to put as a given item in the array. How would you go about putting a random choice at a given index in the array but once the array is filled you have an even split among the two choices?
If there are any answers with code, Java is preferred but other languages are fine as well.
You could basically think about it in the opposite way. Rather than deciding for a given index, which value to put in it, you could select n/2 elements from the array and place the first value in them. Then place the 2nd value in the other n/2.
A 2-D A[M,N] array can be mapped to a vector V[M*N] (you can use a row-major or a column-major order to do the mapping).
Start with a vector V[M*N]. Fill its first half with the first choice, and the second half of the array with the second choice object. Run a Fisher-Yates shuffle, and convert the shuffled array to a 2-D array. The array is now filled with elements that are evenly split among the two choices, and the choices at each particular index are random.
The below creates a List<T> the size of the area of the matrix, and fills it half with the first choice (spaces[0]) and half with the second (spaces[1]). Afterward, it applies a shuffle (namely Fisher-Yates, via Collections.shuffle) and begins to fill the matrix with these values.
static <T> void fill(final T[][] matrix, final T... space) {
final int w = matrix.length;
final int h = matrix[0].length;
final int area = w * h;
final List<T> sample = new ArrayList<T>(area);
final int half = area >> 1;
sample.addAll(Collections.nCopies(half, space[0]));
sample.addAll(Collections.nCopies(half, space[1]));
Collections.shuffle(sample);
final Iterator<T> cursor = sample.iterator();
for (int x = w - 1; x >= 0; --x) {
final T[] column = matrix[x];
for (int y = h - 1; y >= 0; --y) {
column[y] = cursor.next();
}
}
}
Pseudo-code:
int trues_remaining = size / 2;
int falses_remaining = size / 2;
while (trues_remaining + falses_remaining > 0)
{
if (trues_remaining > 0)
{
if (falses_remaining > 0)
array.push(getRandomBool());
else
array.push(true);
}
else
array.push(false);
}
Doesn't really scale to more than two values, though. How about:
assoc_array = { 1 = 4, 2 = 4, 3 = 4, 4 = 4 };
while (! assoc_array.isEmpty())
{
int index = rand(assoc_array.getNumberOfKeys());
int n = assoc_array.getKeyAtIndex(index);
array.push(n);
assoc_array[n]--;
if (assoc_array[n] <= 0) assoc_array.deleteKey(n);
}
EDIT: just noticed you asked for a two-dimensional array. Well it should be easy to adapt this approach to n-dimensional.
EDIT2: from your comment above, "school yard pick" is a great name for this.
It doesn't sound like your requirements for randomness are very strict, but I thought I'd contribute some more thoughts for anyone who may benefit from them.
You're basically asking for a pseudorandom binary sequence, and the most popular one I know of is the maximum length sequence. This uses a register of n bits along with a linear feedback shift register to define a periodic series of 1's and 0's that has a perfectly flat frequency spectrum. At least it is perfectly flat within certain bounds, determined by the sequence's period (2^n-1 bits).
What does that mean? Basically it means that the sequence is guaranteed to be maximally random across all shifts (and therefore frequencies) if its full length is used. When compared to an equal length sequence of numbers generated from a random number generator, it will contain MORE randomness per length than your typical randomly generated sequence.
It is for this reason that it is used to determine impulse functions in white noise analysis of systems, especially when experiment time is valuable and higher order cross effects are less important. Because the sequence is random relative to all shifts of itself, its auto-correlation is a perfect delta function (aside from qualifiers indicated above) so the stimulus does not contaminate the cross correlation between stimulus and response.
I don't really know what your application for this matrix is, but if it simply needs to "appear" random then this would do that very effectively. In terms of being balanced, 1's vs 0's, the sequence is guaranteed to have exactly one more 1 than 0. Therefore if you're trying to create a grid of 2^n, you would be guaranteed to get the correct result by tacking a 0 onto the end.
So an m-sequence is more random than anything you'll generate using a random number generator and it has a defined number of 0's and 1's. However, it doesn't allow for unqualified generation of 2d matrices of arbitrary size - only those where the total number of elements in the grid is a power of 2.

Categories