Translate numbers from a range to another range - math

Example range 1 (minimum and maximum):
[40 ... 480]
Example numbers from range 1:
[42, 59.4, 78.18, 120.43, 416]
Example range 2:
[10 .. 140]
How can I translate the values of the numbers from range 1 to values within the second range? 42 should be equivalent to something between 10 and 11 in the new range.
I'm using PHP but this is more like a math problem.
I know how to align them to the second range:
$diff = $range[0] - $numbers[0];
foreach($numbers as $i => $number){
$numbers[$i] = $number + $diff;
}
But that's it :(

Do you mean something like this, which scales the values linearly to fit within the new range?
var transformRange = (value, r1, r2) => {
var scale = (r2.max - r2.min) / (r1.max - r1.min)
return (value - r1.min) * scale;
}
Sample usage:
transformRange(100, {max: 150, min: 50}, {max: 1, min: 0}); => 0.5

You can transform one of the ranges into the other with this function (python)
def transfrom(x):
return (x - 40)*(130/440.0) + 10
In general the idea is that you want to rebase the ranges (make sure that they both start at zero) and then find how you need to stretch the first range to obtain the second range. So the steps would be
Convert the first range to [0-440] by subtracting 40 and the second range to [0-130] by subtracting 10. This is done to get intervals which start at zero which are easy to scale.
To convert any value from [0-440] to a corresponding value from [0-130] you need to multiply it with 130/440. You can imagine this as shrinking the first interval to a [0-1] interval by dividing with 440 and then stretching it to a [0-130] interval by multiplying.
Now you know how to go from [0-440] to [0-130] and that means that to go from [40-440] to [10-140] you first need to rebase by subtracting 40 multiply by 130/440 and then add 10
Example:
>>> transform(40)
10.0
>>> transform(42)
10.590909090909092
>>> transform(220)
63.181818181818187
>>> transform(480)
140.0

Related

Statistical probability of N contiguous true-bits in a sequence of bits?

Let's assume I have an N-bit stream of generated bits. (In my case 64kilobits.)
Whats the probability of finding a sequence of X "all true" bits, contained within a stream of N bits. Where X = (2 to 16), and N = (16 to 1000000), and X < N.
For example:
If N=16 and X=5, whats the likelyhood of finding 11111 within a 16-bit number.
Like this pseudo-code:
int N = 1<<16; // (64KB)
int X = 5;
int Count = 0;
for (int i = 0; i < N; i++) {
int ThisCount = ContiguousBitsDiscovered(i, X);
Count += ThisCount;
}
return Count;
That is, if we ran an integer in a loop from 0 to 64K-1... how many times would 11111 appear within those numbers.
Extra rule: 1111110000000000 doesn't count, because it has 6 true values in a row, not 5. So:
1111110000000000 = 0x // because its 6 contiguous true bits, not 5.
1111100000000000 = 1x
0111110000000000 = 1x
0011111000000000 = 1x
1111101111100000 = 2x
I'm trying to do some work involving physically-based random-number generation, and detecting "how random" the numbers are. Thats what this is for.
...
This would be easy to solve if N were less than 32 or so, I could just "run a loop" from 0 to 4GB, then count how many contiguous bits were detected once the loop was completed. Then I could store the number and use it later.
Considering that X ranges from 2 to 16, I'd literally only need to store 15 numbers, each less than 32 bits! (if N=32)!
BUT in my case N = 65,536. So I'd need to run a loop, for 2^65,536 iterations. Basically impossible :)
No way to "experimentally calculate the values for a given X, if N = 65,536". So I need maths, basically.
Fix X and N, obiously with X < N. You have 2^N possible values of combinations of 0 and 1 in your bit number, and you have N-X +1 possible sequences of 1*X (in this part I'm only looking for 1's together) contained in you bit number. Consider for example N = 5 and X = 2, this is a possible valid bit number 01011, so fixed the last two characteres (the last two 1's) you have 2^2 possible combinations for that 1*Xsequence. Then you have two cases:
Border case: Your 1*X is in the border, then you have (2^(N -X -1))*2 possible combinations
Inner case: You have (2^(N -X -2))*(N-X-1) possible combinations.
So, the probability is (border + inner )/2^N
Examples:
1)N = 3, X =2, then the proability is 2/2^3
2) N = 4, X = 2, then the probaility is 5/16
A bit brute force, but I'd do something like this to avoid getting mired in statistics theory:
Multiply the probabilities (1 bit = 0.5, 2 bits = 0.5*0.5, etc) while looping
Keep track of each X and when you have the product of X bits, flip it and continue
Start with small example (N = 5, X=1 - 5) to make sure you get edge cases right, compare to brute force approach.
This can probably be expressed as something like Sum (Sum 0.5^x (x = 1 -> 16) (for n = 1 - 65536) , but edge cases need to be taken into account (i.e. 7 bits doesn't fit, discard probability), which gives me a bit of a headache. :-)
#Andrex answer is plain wrong as it counts some combinations several times.
For example consider the case N=3, X=1. Then the combination 101 happens only 1/2^3 times but the border calculation counts it two times: one as the sequence starting with 10 and another time as the sequence ending with 01.
His calculations gives a (1+4)/8 probability whereas there are only 4 unique sequences that have at least a single contiguous 1 (as opposed to cases such as 011):
001
010
100
101
and so the probability is 4/8.
To count the number of unique sequences you need to account for sequences that can appear multiple times. As long as X is smaller than N/2 this will happens. Not sure how you can count them tho.

How can I get a random multiple of 50 using Microsoft Small Basic?

How can I get a random multiple of 50 between 0 and 800?
So I would need numbers:
0,50,100,150,200,250,300,350,400,450,500,550,600,650,700,750,800.
I've tried using math.getrandomnumber(800) but that gives me any number.
Get a random number between 0 and 16, then multiply it with 50.
Firstly You Should get a random number under 16. Then multiply the random number under 16 x 50. Like that you will get always a random multiple of 50 under 800. Because 50 x 16 = 800. And 16 is the maximal number that you can multiply with 50.
RandomNumber_under16 = Math.GetRandomNumber(16)
random_multiple_of_50_under_800 = RandomNumber_under16*50
TextWindow.WriteLine(random_multiple_of_50_under_800)
So I would need numbers, 0,50,100,150,200,250,300,350,400,450,500,550,600,650,700,750,800
You can build these numbers by scaling the numbers in the range [0,16] by a factor of 50.
Given the definition of the Math.GetRandomNumber function
Math.GetRandomNumber(maxNumber)
Gets a random number between 1 and the specified maxNumber (inclusive).
Parameters
maxNumber: The maximum number for the requested random value.
Returns
A Random number that is less than or equal to the specified max.
your solution will have to account for the fact that the returned random integer starts at 1 whereas you need to include 0 in your list.
Next code snippet produces the desired result:
For i = 1 To 20
TextWindow.WriteLine((Math.GetRandomNumber(17) - 1) * 50)
EndFor
' Math.GetRandomNumber(17) -> [1,17]
' Math.GetRandomNumber(17) - 1 -> [0,16]
' (Math.GetRandomNumber(17) - 1) * 50 -> {0,50,100,150, ... ,800}

Find max value of X that satisfies both 9x < 10 && 7.5x < 8

I am writing a program that needs to find the maximum value of X that satisfies the 2 following equations:
9x < 10
7.5x < 8
Can anyone advise on the best way to go about this? I am writing the program in Dart but would appreciate examples/advice in any language.
This is what I have done currently but I am not 100% sure this is correct:
double Xval = 10/9;
if(7.5 * Xval > 8)
Xval = 8 / 7.5;
Please note the program would have to work if we changed any or all of the numbers (e.g. the 9, 10, 7.5 or the 8).
It needs some mathematical logic.
1)First find value of x by replacing < to =. Eg. Find x in 9x=10.
2)Find minimum of both the solution x.
3)This minimum value will satisfy both the equation its obvious but we have replaced < with = so we need to subtract a smallest value by which we can find maximum x which satisfy the original equation.
4)So subtract the value 0.0001 from minimum if you want 4 decimal point precision. Generally subtract (10)^(-DecimalPointPrecision) value ,so here DecimalPointPrecision is equal to 4.
5)This value you get will satisfy both the equation and it will be the maximum value of x.
I have written a code in java implementing this logic.
import java.util.Scanner;
class SolveEquation
{
public static void main(String [] args)
{
float ip1_left;
float ip1_right;
float ip2_left;
float ip2_right;
Scanner sc=new Scanner(System.in);
System.out.print("\nEnter the multiplier of x of 1st equation:");
ip1_left=sc.nextFloat();
System.out.print("Enter the constant of 1st equation:");
ip1_right=sc.nextFloat();
System.out.print("Enter the multiplier of x of 2nd equation:");
ip2_left=sc.nextFloat();
System.out.print("Enter the constant of x of 2nd equation:");
ip2_right=sc.nextFloat();
float ans1=ip1_right/ip1_left;
float ans2=ip2_right/ip2_left;
float min=ans1;
if(ans2<ans1)
min=ans2;
//If you want 4 decimal precision then print 4 digits after point and subtract 0.0001 (where 1 is placed on 4th place after decimal point).
System.out.printf("\nMaximum value of x is %.4f",min-0.0001);
}
}
Sample output for input as per your question:

Number of Zero-crossings - Equation

I have written an algorithm that calculates the number of zero-crossings within a signal. By this, I mean the number of times a value changes from + to - and vice-versa.
The algorithm is explained like this:
If there are the following elements:
v1 = {90, -4, -3, 1, 3}
Then you multiply the value by the value next to it. (i * i+1)
Then taking the sign value sign(val) determine if this is positive or negative. Example:
e1 = {90 * -4} = -360 -> sigum(e1) = -1
e2 = {-4 * -3} = 12 -> signum(e2) = 1
e3 = {-3 * 1} = -3 -> signum(e3) = -1
e4 = {1 * 3} = 3 -> signum(e4) = 1
Therefore the total number of values changed from negative to positive is = 2 ..
Now I want to put this forumular, algorithm into an equation so that I can present it.
I have asked a simular question, but got really confused so went away and thought about it and came up with (what I think the equation should look like).. It's probably wrong, well, laughably wrong. But here it is:
Now the logic behind it:
I pass in a V (val)
I get the absolute value of the summation of the signum from calculating (Vi * Vi+1) .. The signum(Vi * Vi+1) should produce -1, 1, ..., values
If and only if the value is -1 (Because I'm only interested in the number of times zero is crossed, therefore, the zero values.
Does this look correct, if not, can anyone suggest improvements?
Thank you :)!
EDIT:
Is this correct now?
You are doing the right thing here but your equation is wrong simply because you only want to count the sign of the product of adjacent elements when it is negative. Dont sum the sign of products since positive sign products should be neglected. For this reason, an explicit mathematical formula is tricky as positive products between adjacent elements should be ignored. What you want is a function that takes 2 arguments and evaluates to 1 when their product is negative and zero when non-negative
f(x,y) = 1 if xy < 0
= 0 otherwise
then your number of crossing points is simply given by
sum(f(v1[i],v1[i+1])) for i = 0 to i = n-1
where n is the length of your vector/array v1 (using C style array access notation based on zero indexing). You also have to consider edge conditions such as 4 consecutive points {-1,0,0,1} - do you want to consider this as simply one zero crossing or 2??? Only you can answer this based on the specifics of your problem, but whatever your answer adjust your algorithm accordingly.

Maths Range To Percentage

i need a bit of help with some maths.
I have a range 0 - 127 and i want to convert it into percentage.
So 0% = 0 and 100% = 127 and every number inbetween.
How would i do this?
Edit:
Thanks to what jon posted, i came up with:
$percent * 127 / 100
While Jon's answer was not incorrect, the answer given by belisarius was more complete, in that it allowed for a range of numbers beginning and ending with any number, and not necessarily starting with 0.
Here's a little better way to represent the formula:
percentage = (value - min) / (max - min)
If you want to represent the percentage as a whole number instead of a decimal, simply multiply the result by 100.
And here's the reverse (going from a percentage to a value):
value = ((max - min) * percentage) + min
The percentage here is a decimal. If your percentage is a whole number, simply divide it by 100 before inserting in this formula.
Generally, if you have numbers in the interval [a,b], to get the percentage inside your interval, the formula is:
percentage = 100 * (x-a) / (b-a)
Where x is your value
If you want to go from a value to a percentage, eg from 63.5 to 50%, divide your value by 127 & multiply by 100.
If you want to go the other way, eg from 50% to 63.5, it's the reverse: divide your percentage by 100 & multiply by 127.

Resources