B-V to Kelvin formula - javascript

Whilst looking for a "B-V color index to temperature conversion formula"
I found this javascript:
var C1 = 3.979145;
var C2 = -0.654499;
var C3 = 1.74069;
var C4 = -4.608815;
var C5 = 6.7926;
var C6 = -5.39691;
var C7 = 2.19297;
var C8 = -.359496;
bmv = parseFloat(BV);
with (Math) {
logt=
C1
+C2*bmv
+C3*pow(bmv,2)
+C4*pow(bmv,3)
+C5*pow(bmv,4)
+C6*pow(bmv,5)
+C7*pow(bmv,6)
+C8*pow(bmv,7);
t=pow(10,logt);
}
Which is supposed to convert B-V color index to temperature.
Does anyone understand how this is working and if the output value is an approximation for temperature in celcius or kelvin?
Is it something to do with products of logarithms?

The B-V index is basically a function that transforms the difference between the intensity of the light passing through a 'blue' resp. a 'visible' filter into a temperature.
This function can be approached as 109th degree polynomial, where the polynomial is basically C1*bv0 + C2*bv1 + ... + C8*bv7.
Since we're talking stellar temperatures, the output will be in Kelvin.
Note that a Horner algorithm for polynomial functions is often more precise...

I think temperatures are in Kelvin because its very common for astronomers to use Kelvin rather than Celcius.
Look here.
And,
if logbaseX = Y then X = baseY
log10(t)= C1 +C2*bmv +C3*pow(bmv,2) +C4*pow(bmv,3)
+C5*pow(bmv,4) +C6*pow(bmv,5) +C7*pow(bmv,6)
+C8*pow(bmv,7);
t = pow(10,log10(t));
Also, this formula is very much related to Taylor Series.
// Horners algorithm for polynomials
function Horner(a,n,x)
{
var result = a[n];
var i = n - 1;
while( i >= 0)
{
result = result*x + a[i];
i-=1;
}
return result;
}
In your case,
Array Cs = {C1,C2,C3,C4,C5,C6,C7,C8};
var temperature = Horner(Cs,8,bmv);

Related

Function that doubles value by various rates

I'm trying to make a line chart like the New York Times Coronavirus Deaths by U.S. State and Country Over Time: Daily Tracker.
NYT has some clever lines in the chart showing the doubling rate, every day, every 2 days, every 3 days, every week, and so on.
I'm wondering how to write a function that returns an array of values that represent these lines given a start value of 10 and a maxX-value of 36 (total number of days as of today).
This is where I'm at right now, I'm afraid it does not calculate the values correctly but it might explain what I want to achieve.
How can I do this in a correct way? My math is too rusty for this.
var maxX = 36;
var start = 10;
function double(factor) {
var f = start;
var arr = [f];
for (var i = 1; i < maxX; i++) {
f = f + (f / factor)
arr.push(f)
}
return arr
}
var lines = [1, 2, 3, 7, 30].map(f => {
return {
days: f,
arr: double(f)
}
})
console.log(lines)
You first need to figure out what to multiply each daily value by, given a doubling rate. For example, with a doubling rate of every 2 days, you'd want each day count to be multiplied by 1.412 (square root of 2); after 1 day, it'd be 1.412x, after 2 days, it'd be 2x, after 4 days, it'd be 4x, etc.
For the general solution, the equation to solve is:
orig * (dayFactor ** daysToDouble) = 2 * orig
where orig is the original number of infections (here, 10), and dayFactor is the value you want to solve for, since that's the number the infections should be multiplied each day.
orig * (dayFactor ** daysToDouble) = 2 * orig
(dayFactor ** daysToDouble) = 2
dayFactor = 2 ** (1 / daysToDouble)
In the function, identify the dayFactor given the doubling rate, then multiply the count by that each day:
var maxX = 36;
var start = 10;
function double (daysToDouble) {
const dayFactor = 2 ** (1 / daysToDouble);
let currentInfected = start;
const arr = [currentInfected];
for (var i = 1; i < maxX; i++){
currentInfected *= dayFactor;
arr.push(currentInfected);
}
return arr;
}
var lines = [1,2,3,7,30].map(f => {
return {days: f, arr: double(f)}
});
console.log(lines[2]); // double every 3rd day

Swapping imputed values. Z axis optimization. Making smallest value the Z axis

I am making a simple cost estimator. It takes 3 imputed values X,Y,Z and displays a price which is a simple calculation of a value by the z axis (the third of 3 collected values).
You can view the estimator here: http://codepen.io/FredHair/pen/FgJAd
What I would like to add is a checkbox that when clicked would check that the smallest value is stored as the Z axis. So if the user imputed 3 values and the X or Y value was the smallest then that value would be swapped with with the z axis value.
How would I go about writing a function for this?
Any help would be greatly appreciated even in pseudo code, which I could then write myself.
I have made a checkbox:
<input type="checkbox" id="zAxis">Z Axis Optimization<br>
This is my function for the Estimator:
//Calc with Switch//
function calculator(){
var x = Number(document.getElementById("x").value);
var y = Number(document.getElementById("y").value);
var z = Number(document.getElementById("z").value);
var p = Number(3);
var result;
var calc = document.getElementById("choice").value
switch(calc){
case"1" : result = z * p;
break;
case"2" : result = (z * p) + 50;
break;
case"3" : result = (z * p) + 30;
break;
}
//Display Result//
document.getElementById("result").innerHTML = " = £ " + result;
I know I will need to write a function like:
IF (x<=y && <=z) then do something
OR (y<=y && <=x) then do something
But any help will be greatly appreciated.
Here is Codepen again: http://codepen.io/FredHair/pen/FgJAd
Thanks in advance.

Using Heron's formula to calculate area - JavaScript

My code:
function calculate(sides) {
var sides = prompt("Triangle side lengths in cm
(number,number,number)"); //String will be size of 4
var nsides = sides.split(" "); //Splits content into array format
//Convert Array instances to integer values a,b,c
for(var loop=0;loop<=nsides.length;loop++) {
if(nsides[loop]!=",")
a = nsides[loop];
if(nsides[loop]!=",")
b = nsides[loop];
if(nsides[loop]!=",")
c= nsides[loop];
} //End for
//Area Calculation
var s = (a+b+c)*0.5 ; //represents the semiperimeter
var area = Math.sqrt(s*(s-a)*s(s-b)*(s-c)) //area calculation
//Result
sides = alert("The triangle's area is " + area + " square cm");
} //End function
//Main calculate(length);
I'm looking to set side a, b, and c to integers; however in order to do that I have to go through the array (I first converted it to an array from a string)
I'm going to add in some standard validation later; as of now I can't seem to place the values from the string entered into 3 separate integers being a b and c.
Other than that, is there a better way i can go about this?
Thanks.
Maybe I misunderstand your question, but is this what you're looking for?
var sides = prompt("Triangle side lengths in cm (number,number,number)");
var nsides = sides.split(",");
var a = +nsides[0];
var b = +nsides[1];
var c = +nsides[2];
//Area Calculation
//...
Note the use of + to force the strings from the array into numbers.
function calculate() {
var sides = prompt("Triangle side lengths in cm (number,number,number)"),
nsides = sides.split(","),
a = parseFloat(nsides[0]),
b = parseFloat(nsides[1]),
c = parseFloat(nsides[2]),
s = (a + b + c) / 2,
area = Math.sqrt(s * (s - a) * (s - b) * (s - c));
alert("The triangle's area is " + area + " square cm");
return area; // return the area
}
First of all I removed your parameter, it was totally unnecessary and was overwritten by the declaration of sides in the first line. Then I changed the split to , so it follows your instructions. Then you need to parse the string to integers using parseInt and specifiying the radix 10, then you can go on with your calculations. Just a last thing, you wrote Math.sqrt(s*(s-a)*s(s-b)*(s-c)), see that s(s-b) causes an exception because you are using a number to be called as a function.

Cumulative distribution function in Javascript

I am searching for a way to calculate the Cumulative distribution function in Javascript. Are there classes which have implemented this? Do you have an idea to get this to work? It does not need to be 100% percent accurate but I need a good idea of the value.
http://en.wikipedia.org/wiki/Cumulative_distribution_function
I was able to write my own function with the help of Is there an easily available implementation of erf() for Python? and the knowledge from wikipedia.
The calculation is not 100% correct as it is just a approximation.
function normalcdf(mean, sigma, to)
{
var z = (to-mean)/Math.sqrt(2*sigma*sigma);
var t = 1/(1+0.3275911*Math.abs(z));
var a1 = 0.254829592;
var a2 = -0.284496736;
var a3 = 1.421413741;
var a4 = -1.453152027;
var a5 = 1.061405429;
var erf = 1-(((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*Math.exp(-z*z);
var sign = 1;
if(z < 0)
{
sign = -1;
}
return (1/2)*(1+sign*erf);
}
normalcdf(30, 25, 1.4241); //-> 0.12651187738346226
//wolframalpha.com 0.12651200000000000
The math.js library provides an erf function. Based on a definition found at Wolfram Alpha , the cdfNormalfunction can be implemented like this in Javascript:
const mathjs = require('mathjs')
function cdfNormal (x, mean, standardDeviation) {
return (1 - mathjs.erf((mean - x ) / (Math.sqrt(2) * standardDeviation))) / 2
}
In the node.js console:
> console.log(cdfNormal(5, 30, 25))
> 0.15865525393145707 // Equal to Wolfram Alpha's result at: https://sandbox.open.wolframcloud.com/app/objects/4935c1cb-c245-4d8d-9668-4d353ad714ec#sidebar=compute
This formula will give the correct normal CDF unlike the currently accepted answer
function ncdf(x, mean, std) {
var x = (x - mean) / std
var t = 1 / (1 + .2315419 * Math.abs(x))
var d =.3989423 * Math.exp( -x * x / 2)
var prob = d * t * (.3193815 + t * ( -.3565638 + t * (1.781478 + t * (-1.821256 + t * 1.330274))))
if( x > 0 ) prob = 1 - prob
return prob
}
This answer comes from math.ucla.edu
Due to some needs in the past, i put together an implementation of distribution function in javascript. my library is available at github. You can take a look at https://github.com/chen0040/js-stats
it provides javascript implementation of CDF and inverse CDF for Normal distribution, Student's T distribution, F distribution and Chi-Square Distribution
To use the js lib for obtaining CDF and inverse CDF:
jsstats = require('js-stats');
//====================NORMAL DISTRIBUTION====================//
var mu = 0.0; // mean
var sd = 1.0; // standard deviation
var normal_distribution = new jsstats.NormalDistribution(mu, sd);
var X = 10.0; // point estimate value
var p = normal_distribution.cumulativeProbability(X); // cumulative probability
var p = 0.7; // cumulative probability
var X = normal_distribution.invCumulativeProbability(p); // point estimate value
//====================T DISTRIBUTION====================//
var df = 10; // degrees of freedom for t-distribution
var t_distribution = new jsstats.TDistribution(df);
var t_df = 10.0; // point estimate or test statistic
var p = t_distribution.cumulativeProbability(t_df); // cumulative probability
var p = 0.7;
var t_df = t_distribution.invCumulativeProbability(p); // point estimate or test statistic
//====================F DISTRIBUTION====================//
var df1 = 10; // degrees of freedom for f-distribution
var df2 = 20; // degrees of freedom for f-distribution
var f_distribution = new jsstats.FDistribution(df1, df2);
var F = 10.0; // point estimate or test statistic
var p = f_distribution.cumulativeProbability(F); // cumulative probability
//====================Chi Square DISTRIBUTION====================//
var df = 10; // degrees of freedom for cs-distribution
var cs_distribution = new jsstats.ChiSquareDistribution(df);
var X = 10.0; // point estimate or test statistic
var p = cs_distribution.cumulativeProbability(X); // cumulative probability
This is a brute force implementation, but accurate to more digits of precision. The approximation above is accurate within 10^-7. My implementation runs slower (700 nano-sec) but is accurate within 10^-14. normal(25,30,1.4241) === 0.00022322110257305683, vs wolfram's 0.000223221102572082.
It takes the power series of the standard normal pdf, i.e. the bell-curve, and then integrates the series.
I originally wrote this in C, so I concede some of the optimizations might seem silly in Javascript.
function normal(x, mu, sigma) {
return stdNormal((x-mu)/sigma);
}
function stdNormal(z) {
var j, k, kMax, m, values, total, subtotal, item, z2, z4, a, b;
// Power series is not stable at these extreme tail scenarios
if (z < -6) { return 0; }
if (z > 6) { return 1; }
m = 1; // m(k) == (2**k)/factorial(k)
b = z; // b(k) == z ** (2*k + 1)
z2 = z * z; // cache of z squared
z4 = z2 * z2; // cache of z to the 4th
values = [];
// Compute the power series in groups of two terms.
// This reduces floating point errors because the series
// alternates between positive and negative.
for (k=0; k<100; k+=2) {
a = 2*k + 1;
item = b / (a*m);
item *= (1 - (a*z2)/((a+1)*(a+2)));
values.push(item);
m *= (4*(k+1)*(k+2));
b *= z4;
}
// Add the smallest terms to the total first that
// way we minimize the floating point errors.
total = 0;
for (k=49; k>=0; k--) {
total += values[k];
}
// Multiply total by 1/sqrt(2*PI)
// Then add 0.5 so that stdNormal(0) === 0.5
return 0.5 + 0.3989422804014327 * total;
}
You can also take a look here, it's a scientific calculator implemented in javascript, it includes erf and its author claims no copyright on the implementation.

Javascript - "One shade darker"

Is it possible to use javascript to determine what color is one shade darker than the current background? Maybe some hexadecimal addition/subtraction?
I have a menu that can be any color and if it wasn't too difficult it would be great if the submenu could be one shade darker. Does anyone know how to achieve this effect?
Something like this:
function shadeColor(color, shade) {
var colorInt = parseInt(color.substring(1),16);
var R = (colorInt & 0xFF0000) >> 16;
var G = (colorInt & 0x00FF00) >> 8;
var B = (colorInt & 0x0000FF) >> 0;
R = R + Math.floor((shade/255)*R);
G = G + Math.floor((shade/255)*G);
B = B + Math.floor((shade/255)*B);
var newColorInt = (R<<16) + (G<<8) + (B);
var newColorStr = "#"+newColorInt.toString(16);
return newColorStr;
}
Usage:
var newColor = shadeColor("#AA2222", -10);
alert(newColor); //Results in #a32020
Here is an example code to test it: http://pastebin.com/g6phySEv
as AB comments, 'shade' isn't very well defined. nonetheless, it might be easier to think of this in some other colour representation, such as 'V' in hsv.
you could either convert, decrease v and convert back, or figure out what decreasing v maps to in rgb hex

Categories