Related
I am writing a program about computing geometry.
In this program, I need to identify unit vectors. (The word identify maybe not accurate)
i.e., writing a program to check whether a unit vector already exists.
This procedure is used when checking whether two polygons are on one plane. The first step is to check whether normal of two polygons are very close (angle < 1.0 degree).
So, we can assume that
all vectors are unit vectors
vectors are random
For example, set the angle threshold to 1.0 degree. And we have 6 vectors.
(1,0,0)
(0,1,0)
(1,0,1e-8) // in program, this will be normalized
(1,0,0)
(sin(45), cos(45),0)
(sin(44.9), cos(44.9),0)
then, the index of each vector is
0 1 0 0 2 2
i.e., the 1st / 3rd / 4th vectors are the same one because their angle is within 1.0 degree or just the same direction. angle between the 5th/6th vector is smaller than 1.0 degree.
Now, the problem comes, I have hundreds of thousands unit vectors to identify in different stages. This procedure costs about half of total time.
example code
std::vector<Vector3d> unitVecs; // all unit vectors
// more than 100,000 unit vectors in real case
int getVectorID(const Vector3d& vec)
{
for(int i=0; i<unitVecs.size(); ++i) {
if(calcAngle(unitVecs[i], vec) <1.0) // 1.0 is angle degree threshold
return i;
/// alternatively, check with cos value
if(unitVecs[i].dot(vec)>cos(1.0*RADIAN))
return i;
}
return -1;
}
int insertVector(const Vector3d& vec)
{
int idx = getVectorID(vec);
if(idx!=-1) return idx;
unitVecs.push_back(vec);
return unitVecs.size()-1;
}
Does anyone have good ideas to accelerate this process ?
If you are able to accept vectors which are merely "very close to being unit vectors", as opposed to vectors which are strictly less than or equal to 1 degree from being a unit vector, you can simply check that for a given vector 3 values are very close to 0, and one value is very close to 1:
int valueCloseTo(float value, float trg, float epsilon=0.0001) {
return abs(value) - trg <= epsilon;
}
int isRoughlyUnitVector(float x, float y, float z, float epsilon=0.0001) {
// We can quickly return false if units don't add near 1
// Could also consider multiplying `epsilon` x 3 here to account for accumulated error
if (!valueCloseTo(x + y + z, 1, epsilon)) return false;
// Now ensure that of x, y, and z, two are ~0 and one is ~1
int numZero = 0;
int numOne = 0;
std::vector<float> vec{ x, y, z };
for (float v : vec) {
// Count another ~0 value
if (valueCloseTo(v, 0, epsilon)) numZero++;
// Count another ~1 value
else if (valueCloseTo(v, 1, epsilon)) numOne++;
// If any value isn't close to 0 or 1, (x,y,z) is not a unit vector
else return false;
// False if we exceed 2 values near 0, and one value near 1
if (numZero > 2 || numOne > 1) return false;
}
return true;
}
Note that this method does not give any way to define a "maximum offset angle" (like 1deg in your question) - instead it lets us work with an epsilon value, which isn't an angle but rather a simple linear value. As epsilon increases vectors that are further from being unit vectors get accepted, but epsilon doesn't have an "angular" nature to it.
my code snippet is:
int bs_greaterthan_or_equal(int *a, int key, int low, int high) {
while(low<high) {
int mid = low +(high-low)/2.0;
if(a[mid]<key) {
low = mid + 1;
}
else high = mid;
}
return high;
}
But even when i search a number greater than last element in the array it returns the last index
e.g a[] = {1,3,10,15,20,25,27}
key = 28
It returns 7
But even when i search a number greater than last element in the array it returns the last index
Because that is what it has been designed to do. Technically speaking, it returns the last index + 1.
Notice the condition:
if(a[mid]<key) {
low = mid + 1;
}
When looking for an element that's larger than (or equal to) the last element of the array, the above condition will always evaluate to true. The loop terminates when you reach the last element itself, where low is set to one more than the last index.
When you search for the key 28 in your example, low is repeatedly updated because the above condition always evaluates to true. When mid equals 6, then a[mid] is still lesser than 28, so low is set to mid + 1, i.e 7. At this point, low and high become equal (notice that high was never modified) and the loop terminates. The function returns 7.
If there's something specific that you wish to return (say, -1) upon searching for a number that's greater than or equal to the last element in the array, you can modify your code as follows.
int bs_greaterthan_or_equal(int *a, int key, int low, int high) {
int max_limit = high;
while(low<high) {
int mid = low +(high-low)/2.0;
if(a[mid]<key) {
low = mid + 1;
}
else high = mid;
}
return high == max_limit ? -1 : high;
}
If the array contains a larger or equal element for the given key, high will store its index. Otherwise, at the end, high will remain equal to max_limit, meaning that the search procedure couldn't find such an element, and hence, will return -1.
I have a 14-bit data that is fed from FPGA in vhdl, The NIos II processor reads the 14-bit data from FPGA and do some processing tasks, where Nios II system is programmed in C code
The 14-bit data can be positive, zero or negative. In Altera compiler, I can only define the data to be 8,16 or 32. So I define this to be 16 bit data.
First, I need to check if the data is negative, if it is negative, I need to pad the first two MSB to be bit '1' so the system detects it as negative value instead of positive value.
Second, I need to compute the real value of this binary representation into a decimal value of BOTH integer and fraction.
I learned from this link (Correct algorithm to convert binary floating point "1101.11" into decimal (13.75)?) that I could convert a binary (consists of both integer and fraction) to decimal values.
To be specified, I am able to use this code quoted from this link (Correct algorithm to convert binary floating point "1101.11" into decimal (13.75)?) , reproduced as below:
#include <stdio.h>
#include <math.h>
double convert(const char binary[]){
int bi,i;
int len = 0;
int dot = -1;
double result = 0;
for(bi = 0; binary[bi] != '\0'; bi++){
if(binary[bi] == '.'){
dot = bi;
}
len++;
}
if(dot == -1)
dot=len;
for(i = dot; i >= 0 ; i--){
if (binary[i] == '1'){
result += (double) pow(2,(dot-i-1));
}
}
for(i=dot; binary[i] != '\0'; i++){
if (binary[i] == '1'){
result += 1.0/(double) pow(2.0,(double)(i-dot));
}
}
return result;
}
int main()
{
char bin[] = "1101.11";
char bin1[] = "1101";
char bin2[] = "1101.";
char bin3[] = ".11";
printf("%s -> %f\n",bin, convert(bin));
printf("%s -> %f\n",bin1, convert(bin1));
printf("%s -> %f\n",bin2, convert(bin2));
printf("%s -> %f\n",bin3, convert(bin3));
return 0;
}
I am wondering if this code can be used to check for negative value? I did try with a binary string of 11111101.11 and it gives the output of 253.75...
I have two questions:
What are the modifications I need to do in order to read a negative value?
I know that I can do the bit shift (as below) to check if the msb is 1, if it is 1, I know it is negative value...
if (14bit_data & 0x2000) //if true, it is negative value
The issue is, since it involves fraction part (but not only integer), it confused me a bit if the method still works...
If the binary number is originally not in string format, is there any way I could convert it to string? The binary number is originally fed from a fpga block written in VHDL say, 14 bits, with msb as the sign bit, the following 6 bits are the magnitude for integer and the last 6 bits are the magnitude for fractional part. I need the decimal value in C code for Altera Nios II processor.
OK so I m focusing on the fact that you want to reuse the algorithm you mention at the beginning of your question and assume that the binary representation you have for your signed number is Two's complement but I`m not really sure according to your comments that the input you have is the same than the one used by the algorithm
First pad the 2 MSB to have a 16 bit representation
16bit_data = (14_bit_data & 0x2000) ? ( 14_bit_data | 0xC000) : 14_bit_data ;
In case value is positive then value will remained unchanged and if negative this will be the correct two`s complement representation on 16bits.
For fractionnal part everything is the same compared to algorithm you mentionned in your question.
For integer part everything is the same except the treatment of MSB.
For unsigned number MSB (ie bit[15]) represents pow(2,15-6) ( 6 is the width of frationnal part ) whereas for signed number in Two`s complement representation it represents -pow(2,15-6) meaning that algorithm become
/* integer part operation */
while(p >= 1)
{
rem = (int)fmod(p, 10);
p = (int)(p / 10);
dec = dec + rem * pow(2, t) * (9 != t ? 1 : -1);
++t;
}
or said differently if you don`t want * operator
/* integer part operation */
while(p >= 1)
{
rem = (int)fmod(p, 10);
p = (int)(p / 10);
if( 9 != t)
{
dec = dec + rem * pow(2, t);
}
else
{
dec = dec - rem * pow(2, t);
}
++t;
}
For the second algorithm that you mention, considering you format if dot == 11 and i == 0 we are at MSB ( 10 integer bits followed by dot) so the code become
for(i = dot - 1; i >= 0 ; i--)
{
if (binary[i] == '1')
{
if(11 != dot || i)
{
result += (double) pow(2,(dot-i-1));
}
else
{
// result -= (double) pow(2,(dot-i-1));
// Due to your number format i == 0 and dot == 11 so
result -= 512
}
}
}
WARNING : in brice algorithm the input is character string like "11011.101" whereas according to your description you have an integer input so I`m not sure that this algorithm is suited to your case
I think this should work:
float convert14BitsToFloat(int16_t in)
{
/* Sign-extend in, since it is 14 bits */
if (in & 0x2000) in |= 0xC000;
/* convert to float with 6 decimal places (64 = 2^6) */
return (float)in / 64.0f;
}
To convert any number to string, I would use sprintf. Be aware it may significantly increase the size of your application. If you don't need the float and what to keep a small application, you should make your own conversion function.
I was implementing quicksort and I wished to set the pivot to be the median or three numbers. The three numbers being the first element, the middle element, and the last element.
Could I possibly find the median in less no. of comparisons?
median(int a[], int p, int r)
{
int m = (p+r)/2;
if(a[p] < a[m])
{
if(a[p] >= a[r])
return a[p];
else if(a[m] < a[r])
return a[m];
}
else
{
if(a[p] < a[r])
return a[p];
else if(a[m] >= a[r])
return a[m];
}
return a[r];
}
If the concern is only comparisons, then this should be used.
int getMedian(int a, int b , int c) {
int x = a-b;
int y = b-c;
int z = a-c;
if(x*y > 0) return b;
if(x*z > 0) return c;
return a;
}
int32_t FindMedian(const int n1, const int n2, const int n3) {
auto _min = min(n1, min(n2, n3));
auto _max = max(n1, max(n2, n3));
return (n1 + n2 + n3) - _min - _max;
}
You can't do it in one, and you're only using two or three, so I'd say you've got the minimum number of comparisons already.
Rather than just computing the median, you might as well put them in place. Then you can get away with just 3 comparisons all the time, and you've got your pivot closer to being in place.
T median(T a[], int low, int high)
{
int middle = ( low + high ) / 2;
if( a[ middle ].compareTo( a[ low ] ) < 0 )
swap( a, low, middle );
if( a[ high ].compareTo( a[ low ] ) < 0 )
swap( a, low, high );
if( a[ high ].compareTo( a[ middle ] ) < 0 )
swap( a, middle, high );
return a[middle];
}
I know that this is an old thread, but I had to solve exactly this problem on a microcontroller that has very little RAM and does not have a h/w multiplication unit (:)). In the end I found the following works well:
static char medianIndex[] = { 1, 1, 2, 0, 0, 2, 1, 1 };
signed short getMedian(const signed short num[])
{
return num[medianIndex[(num[0] > num[1]) << 2 | (num[1] > num[2]) << 1 | (num[0] > num[2])]];
}
If you're not afraid to get your hands a little dirty with compiler intrinsics you can do it with exactly 0 branches.
The same question was discussed before on:
Fastest way of finding the middle value of a triple?
Though, I have to add that in the context of naive implementation of quicksort, with a lot of elements, reducing the amount of branches when finding the median is not so important because the branch predictor will choke either way when you'll start tossing elements around the the pivot. More sophisticated implementations (which don't branch on the partition operation, and avoid WAW hazards) will benefit from this greatly.
remove max and min value from total sum
int med3(int a, int b, int c)
{
int tot_v = a + b + c ;
int max_v = max(a, max(b, c));
int min_v = min(a, min(b, c));
return tot_v - max_v - min_v
}
There is actually a clever way to isolate the median element from three using a careful analysis of the 6 possible permutations (of low, median, high). In python:
def med(a, start, mid, last):
# put the median of a[start], a[mid], a[last] in the a[start] position
SM = a[start] < a[mid]
SL = a[start] < a[last]
if SM != SL:
return
ML = a[mid] < a[last]
m = mid if SM == ML else last
a[start], a[m] = a[m], a[start]
Half the time you have two comparisons otherwise you have 3 (avg 2.5). And you only swap the median element once when needed (2/3 of the time).
Full python quicksort using this at:
https://github.com/mckoss/labs/blob/master/qs.py
You can write up all the permutations:
1 0 2
1 2 0
0 1 2
2 1 0
0 2 1
2 0 1
Then we want to find the position of the 1. We could do this with two comparisons, if our first comparison could split out a group of equal positions, such as the first two lines.
The issue seems to be that the first two lines are different on any comparison we have available: a<b, a<c, b<c. Hence we have to fully identify the permutation, which requires 3 comparisons in the worst case.
Using a Bitwise XOR operator, the median of three numbers can be found.
def median(a,b,c):
m = max(a,b,c)
n = min(a,b,c)
ans = m^n^a^b^c
return ans
I'm trying to code a simple, sufficiently accurate filter for validating a piece of hardware in an RTL simulation. We're simulating the randomness inherent in a chip's flip-flops, by randomly initializing all the flip-flops in the design to either 0 or 1. This corresponds to the chip's flip-flops getting some random value during power-up. We're also randomizing the flops in the reset tree ( where reset tree has no feedback loops ), which means that you can get false glitching on your reset lines.
e.g.
|||
VVV Nth reset-tree flop
+----+ +----+ +----+ / / +----+
reset_in | | 0 | | 1 | | 0 / / | | reset_out
-------->D Q>----->D Q>----->D Q>---- / ... / -->D Q>----
| | | | | | \ \ | |
| | | | | | \ \ | |
+^---+ +^---+ +^---+ / / +^---+
| | | / / |
clk ------+------------+------------+---------/ / ---+
You'll see a 0->1->0 which looks like a reset, but is really a glitch.
I want to build a filter that looks for a certain number of consecutive 1 values to determine whether the reset I just saw was the reset coming from the reset controller or a spurious reset.
I know this is statistics and maybe related to the Poisson distribution, but how do I determine the probability that any X consecutive bits in a set of N bits are 1?
P.S. Yes. I am aware of 4-val RTL simulation. We're doing that also, but some Verilog constructs don't have sufficient pessimism when propagating X's and Z's.
EDIT: The below doesn't answer the question, sorry... Comment clarified that the real problem is about the probability of x consecutive 1s out of n bits, not just the simple thing I assumed.
Had a quick look at this: http://www.mathhelpforum.com/math-help/probability-statistics/64519-probability-consecutive-wins.html which may be what you are looking for - it seems to deal with working out the probability of a run of toin cosses out of a larger population of toin cosses, so sounds similar. But its late and I am tired so I haven't decoded the math :)
OBSOLETE:
It sounds like you are basically dealing with binominal probability - see http://en.wikipedia.org/wiki/Binomial_probability.
I have to admit I haven't done the calculations for about 20 years, so somewhat rusty...
Basically, binominal allows you to "add together" the probability of an event occuring multiple times, where there is only two possible outcomes each time.
Order is significant in your case so it should be as simple as multiplying the probabilites;
For 1 bit it is 50%
For 2 bits it is 50%^2 = 25%
For 3 bits it is 50%^3 = 12.5%
Look at it another way;
1 bit only has 2 possible combinations, one of which is all 1s = 50%
2 bits have 4 possible combinations (10, 01, 11, 00), only one of which is all 1s - so 25%
3 bit have 2^3 = 8 possible combinations, only one of which is all 1s, so 1/8 = 12.5%
So... probability of n bits all being 1 = 1/(2^n).
If you want a quick test to see if a sequence of bits is random based on the longest streak of 1's, you can use the fact that the expected longest streak of 1's in N bits is Θ(log(N)).
Furthermore, the probability that the longest streak exceeds r*log₂(N) bits is at most 1/N^(r-1), and similarly the probability that the longest streak is less than log₂(N)/r bits is at most 1/N^(r-1).
These results are derived in the section on "Streaks" in the chapter on "Counting and Probability" in Introduction to Algorithms
OK, here's what I found:
P = 1 - Q(X)
where
Q(X) = [1 - 1/2(Z)]/[(X + 1 - XZ) x 1/2 x Z^(X+1)]
where
Z = 1 + (1/2)(1/2)^X + (X+1)[(1/2)(1/2)^X]^2 + ...
The link with some of the math is here:
Math Forum
you can do a recursive program (python):
prob (x,n) gives your desired result
import math
def prob(x,n,i=0):
if i == x: return 1
if (x+i) > n: return 0
t = .5 * prob(x,n-1,i+1) + .5 * prob(x,n-1,i)
return t
My approach to this would be to define a FSA that accepts bit patterns of the correct type, and then simulate the pattern for each number of bits. i.e.
State state_map[] = {
0 => { 0 -> 0; 1 -> 1; accepts = false },
1 => { 0 -> 0; 1 -> 2; accepts = false },
2 => { 0 -> 0; 1 -> 3; accepts = false },
3 => { 0 -> 3; 1 -> 3; accepts = true }
};
state[t: 0, s: 0] = 1.0;
state[t: 0, s: 1] = 0.0;
state[t: 0, s: 2] = 0.0;
state[t: 0, s: 3] = 0.0;
for (t = 0; t < N; t++)
for (s = 0; s<NUM_STATES; s++)
state[t: t+1, s: state_map[s].0] += state[t, s] * .5
state[t: t+1, s: state_map[s].1] += state[t, s] * .5
print "Probability: {0}", state[t: N, s: 3],