Difference between 12Log2 and Log[2,12]? - math

My math is pretty weak, and I'm having confusion over the differences. I'm trying to find out the midi formula, to output frequency when I have midi value
MidiNumber = 69+12* Log2(440/Frequency)
So I derived
Frequency = (-69 + 5280 Log2 + MidiNumber)/(12 Log2)
If I plugin things this works correctly
440 = (-69 + 5280 Log2 + 69)/(12 Log2)
If I do this though things do not work correctly
(-69 + Log[2, 5280.] + 69)/Log[2, 12.]
This is the output I get in my programming, I don't know exactly the difference between the two equations. Maybe it's 12*Log2, but is that 12*Log2[1] or, ...? No idea.

Part of your confusion seems to be treating Log2(n) as Log2 * n. Log2 is actually a function, the inverse of which is 2^x.
So your derivation should go something as follows:
MidiNumber = 69 + 12 * Log2(440 / Frequency)
MidiNumber - 69 = 12 * Log2(440 / Frequency)
(MidiNumber - 69) / 12 = Log2(440 / Frequency)
2^((MidiNumber - 69) / 12) = 440 / Frequency
Frequency = 440 / 2^((MidiNumber - 69) / 12)

Related

Get formula from series of numbers

I have a series of numbers but need to get the formula to calculate the number at position x.
The starting number is always -1396 and every value is a multiplication of 1396. So it starts with -1396 then goes up by (3 * 1396), stays the same for 3 times and then goes up for (3 * 1396) again. This will always be the same pattern, how can I find a formula for it?
The only formula I could get from an online formula creator was:
x = 1396(z^3 + 3z - 1) / (z-1)^2 (z^2 + z + 1)
but this does not seem to get the right answer.
-1396
2792
2792
2792
6980
6980
6980
11168
11168
11168
You can use Math.floor to make it jump each 3 steps.
z = (Math.floor((x - 1) / 3) * 3 + 2) * 1396

I modelled the sun in R, but can't do the same in Simulink

I'm very new in modeling systems. With a friend's help, We created this model in R
hours <- seq(6+20/60, 18+31/60, 0.01)
h_radians <- (pi/12) * (hours - (12+26/60))
doy <- 268
decl_radians <- 23.45 * sin(2*pi*(284+doy)/365) * pi / 180
lat_radians <- 23.45 * pi / 180
sin_gamma <- sin(lat_radians)*sin(decl_radians) + cos(lat_radians)*cos(decl_radians)*cos(h_radians)
m <- 1/sin_gamma
irradiance[is.na(irradiance)] <- 0
irradiance <- 1353 * sin_gamma * 0.687 ^ (m ^ 0.678)
the output is like that;
When I try to move this mathematical model to simulink, cannot do it. That is what I tried to do
Actually, I cant imagine how the time is used in Simulink. Would you help me to fix my issue ?
You could simply use a Matlab function block to make the calculation exactly as you did it in R:
function irr = irradiance(h,day,lat)
h_radians = (pi/12) * (h - (12+26/60));
decl_radians = lat * sin(2*pi*(284+day)/365) * pi / 180;
lat_radians = lat * pi / 180;
sin_gamma = sin(lat_radians)*sin(decl_radians) + cos(lat_radians)*cos(decl_radians)*cos(h_radians);
m = 1./sin_gamma;
pow = m .^ 0.678;
pow(imag(pow)~=0)=NaN;
irr = 1353 .* sin_gamma .* 0.687 .^pow;
end
Then you should configure the solver to define simulation duration / step :
The simulation will run 12 hours with a step of 0.01 hour.
As you want to simulate between 6h and 18h, I added 6 hours to the simulation clock block.
Without surprise, the result is similar to what you got in R : Simulink can also "model the sun"!

Analog to Digital input scaling equation works in codeblocks but not on Microcontroller

I'm so lost on how to fix this, it should be so simple. I'm using a pic16F1526 and trying to scale the analog to digital reading from 0-255 to 50-100 roughly. I am using this equation
result = ((user_input + 200) * 200) / 800;
In code blocks and on my calculator it works at all numbers from 0-255 and it works perfectly whether I use 8 bit, 16 bit variables in code bloacks.
I've already verified that the AtoD input is working correctly sending the data to the UART. Even if I enter static numbers in place of the sample I get weird results.
When the acd reads a 255 or I enter a 255 the equation gives me a 31 in decimal instead of 100 like it's supposed to. The only thing I can think of is something is getting messed up in the way an 8 bit PIC does it's math since it's an a bit micro.
Sounds like you are getting the correct results on in codeblack because of integer promotion and getting the incorrect results in the hardware because of variable overflow.
uint8_t Can contain 0 to 255
int8_t Can contain -126 125
uint16_t Can contain 0 to 65635
...
Assuming you have uint16_t, the micro's math will go as follows:
((255 + 200) * 200) / 800
(455 * 200) / 800 : 455 * 200 Overflows the 16 bit variable!
( 25464 ) / 800: Note that 91000 & 0xFFFF == 25464
31
You can work around this issue by simplifying your equation :
(user_input + 200) / 4 is equivalent to ((user_input + 200) * 200) / 800 and will not overflow at 16 bits although your accuracy is not very high as ImaginaryHuman072889 pointed out.
If I understand your question correctly, you want to linearly map the numbers 0-255 to the numbers 50-100.
Back to good old y = mx + b algebra.
When x = 0, y = 50. Therefore:
y = mx + b
50 = m*0 + b
b = 50
When x = 255, y = 100. Therefore:
y = mx + 50
100 = m*255 +50
m*255 = 50
m = 50/255 = 10/51
Therefore, the precise answer is:
y = (10/51)*x + 50
On a side note, I have no idea how you got the result of 31 when plugging in 100 into your formula. See below.
(255+200)*200/800 = 113.75

Avoid round off error in exponential calculation

Due to rounding error cannot get ratio between two numbers:
Ratio=exp(x)/(exp(x)+exp(y)) such that x=-1.11e4 and y=-1.12e4.
Any mathematical or computational trick to do?
You can simplify it like this:
R = exp(x) / (exp(x) + exp(y))
= exp(x) / (exp(x) * (1 + exp(y) / exp(x)))
= 1 / (1 + exp(y) / exp(x))
= 1 / (1 + exp(y - x))
(This is the same result as derived by DiltihiumMatrix, but obtained without going into the log domain and back again.)
How about some mathematical manipulation in log-space...
R = exp(x)/[exp(x)+exp(y)]
log(R) = log[exp(x)] - log[exp(x)+exp(y)]
= log[exp(x)] - log[exp(x)*(1+exp(y)/exp(x))]
= log[exp(x)] - log[exp(x)*(1+exp(y-x)]
= log[exp(x)] - log[exp(x)] - log[(1+exp(y-x))]
= - log[(1+exp(y-x))]
Now, exp(y-x) should be a reasonable number, so you can calculate that easily. Then convert back to normal space using R = exp(log(R)).
If that still doesn't work, you can actually taylor expand the last line:
log[(1+z)] ~ 1 + z^2/2 - z^3/3 ...
for small z, in this case z = exp(y-x).

WolframAlpha: Solve Multiple Functions

I'm trying to use WolframAlpha to solve for a variable.
I have
u(k, r) = (900-3k)r^(k-1)
and
s(n, r) = sum u(k, r), k=1 to n
and I want to solve for r with
s(5000, r) = -600000000000
I've tried various incantations, but can't seem to get it working. I can't even get s defined to evaluate it.
If you care, it is to solve this problem : http://projecteuler.net/index.php?section=problems&id=235
WARNING: Spoiler below!
You should ask WA to FullSimplify the expression of s(n,r) after you substitute u(k,r) into it. It should give
(3 (299 - 300 r + r^n (-299 + n + 300 r - n r)))/(-1 + r)^2
Solving the final equality is then just finding the root of a (high degree) polynomial:
299 + 200000000000 (-1 + r)^2 + (4701 - 4700 r) r^5000 == 300 r
where r != 1 since that was a pole of the original expression. Note that r must be positive so that the positive quadratic gets negated by the high-degree term. Plotting the function shows that It is positive for r < 1, and negative for r >~ 1, so the solution is somewhere past r=1. Now change variables so that x = r-1 and look near x=0:
200000000000 x^2 + (1 + x)^5000 (1 - 4700 x) - 1 - 300 x == 0
This should be enlightnening:
Plot[200000000000 x^2 + (1 + x)^5000 (1 - 4700 x) - 1 - 300 x, {x, 0, 0.003}]
Using FindRoot with a good guess gives x=0.002322108633 or r=1.002322108633.
The WA commands follow.
First I used
FullSimplify[Sum[(900-3k)r^(k-1),{k,1,n]]
Then you would have to retype the expression it spits out:
Plot[(3 (299 - 300 r + r^5000 (-299 + 5000 + 300 r - 5000 r)))/(-1 + r)^2 + 6000000000,{r,-2,2}]
At this point I manually replaced r with x+1:
Plot[200000000000 x^2 + (1 + x)^5000 (1 - 4700 x) - 1 - 300 x, {x, 0, 0.003}]
And solving for the root:
FindRoot[200000000000 x^2 + (1 + x)^5000 (1 - 4700 x) - 1 - 300 x, {x, 0.0023}]
Which doesn't give enough precision, and this is as far as you can go using only WA. You can try to subtract off the first few digits that WA gives you, and do another substitution with y = x + 0.00232211 to get the next few digits, but that is too tedious for me to try.

Resources