Javascript: Solve a system of equations - javascript

I'm making a dew point calculator using the "closer approximation" on wikipedia.
I want to be able to calculate the dew point if the user enters any two variables.
Is there an easy way to do this rather than having a lot of if-statements?
More specifically: What if I wanted to use the wet-bulb temperature instead of the relative humidity? Would I have to make a new function or use an if-statement to exclude a set of variables?
Currently I'm using the temperature and relative humidity:
$('#calculate').click(function(){
//Get Temp
var T = parseInt($('#val1').val());
//Get RH
var RH = parseInt($('#val2').val());
//Get es and ex
var es = 6.112*Math.exp(17.76*T/(T+243.5));
var ex = (RH*es)/100;
//Calculate Dew Point
var Tdp = (243.5*Math.log(ex/6.112))/(17.67-Math.log(ex/6.112));
$('#output').append("<p>Dew Point"+Tdp+"</p>");
});

FYI solving systems of nonlinear equations is generally a hard problem. Do whatever you can to avoid that.
My usual approach if multiple pairs of values can be used to calculate an answer is to use the pair of values I'm given to calculate a canonical pair of values, which then is used to do the real calculation. Furthermore since it gets messy to have to sort through input to figure out what you have been given so you can DWIM, it might make sense to have separate functions for each pair of inputs that I'll accept. (Or it might not depending on the flow of control in your program, you know that better than I do.)

Related

What is faster for storing and manipulating a grid: 2D array, 1D array or a hash table?

For my Node.js application I need to choose the best performing structure to represent a grid.
My requirements/limitations are:
The grid to store is two-dimensional by nature (x, y) and not very large (100-300 cells)
Some cells in the grid contain nothing, i.e. the grid will be empty for up to 25%
I will have to address the grid very often. I'll need to do some heavy
algorithms to the grid, like flood-fill, A* pathfinding and some more
This will be a repetitive simulation process of changing the grid and applying the algorithms again
I aim at hundreds of simulations in a limited time, so every millisecond matters
I do not care about readability of the code
Amount of memory used is also a minor concern
Switch to another programming language is not possible
I've been choosing between three options:
var grid = [height][width];
grid[y][x] = {};
var grid = [height * width];
grid[y * height + x] = {};
var y = ~~(index % height);
var x = index - height * y;
var grid = [];
var key = x + ',' + y;
grid[key] = {};
The first one is the most comfortable as I will manipulate the coordinates a lot, meaning x and y will be handy all the time. Possible disadvantage - I've read it could be much slower when holding objects in comparison to 1D array.
The second is fine and probably very fast. But I will need to convert index to x and y and vice versa which is extra calculations involving modulo for index to coords conversion. Still I see this approach in many good sources.
The third way is new to me but I've seen it in some robust code examples and I've read that retrieving an object from hash table can be faster in comparison to 2D array as well.
I do not trust synthetic benchmarks too much so I do not wish to set up a code competition with almost empty logic so far. But I'm afraid it will be a very long way back if I pick a wrong way now and then will have to revert.
I've seen similar questions asking about different pairs of these methods, but none of them reflects my requirements close enough.
Thank you for your considerations with code samples.

Numbers from inside a string without regex?

I'm making a bot for a gaming chatroom with some friends, but I've hit an impasse. Is there a reliable way to get numbers from inside a string of text that won't completely break an inexperienced script kiddy's brain? Here's the best I've been able to come up with so far, variables simplified slightly for illustration's sake:
var k = [0];
function dieRoll(m,n) {
for(i = 0; i < m; i++) {
k[i] = Math.floor(Math.random()*n)+1;
}
}
var m = text[5];
var n = text[7];
if (text === 'roll '+m+'d'+n) {
dieRoll(m,n)
console.log(k);
}
The biggest problem as-is is that it's limited to single-digit input.
EDIT: Looping through the text looking for integers is exactly the kind of thing I'm looking for. I don't have much experience with programming, so I probably tend to end up with overly complicated and confusing messes of spaghetti code that would embarrass anyone remotely professional. As for the format of the input I'm looking for, "roll [number of dice]d[highest number on the dice]". For anyone who doesn't know, it's the notation most tabletop rpgs use. For example, "roll 2d6" for two normal six-sided dice.
EDIT: It's not that I'm necessarily against regex, I just want to be able to understand what's going on, so that if and when I need to edit or reuse the code it I can do so without going completely insane.
EDIT: Thank you all very much! split() seems to be exactly what I was looking for! It'll probably take some trial and error, but I think I'll be able to get her working how she's supposed to this weekend (Yes I call my bots 'she').
Basically, you need to look at the format of the input you're using, and identify certain facts about it. Here are the assumptions I've taken based on your question.
1) The "roll" command comes first followed by a space, and
2) After the command, you are provided with dice information in the form xdy.
Here's something that should work given those constraints:
function getRollParameters(inputCommand) {
var inputWords = inputCommand.split(' '); //Split our input around the space, into an array containing the text before and after the space as two separate elements.
var diceInfo = inputWords[1]; //Store the second element as "diceInfo"
var diceDetails = diceInfo.split('d'); //Split this diceInfo into two sections, that before and after the "d" - ie, the number of dice, and the sides.
//assign each part of the dicedetails to an appropriate variable
var dice = diceDetails[0];
var sides = diceDetails[1];
//return our two pieces of information as a convenient object.
return {
"dice": dice,
"sides": sides
};
}
//a couple of demonstrations
console.log(getRollParameters("roll 5d8"));
console.log(getRollParameters("roll 126d2"));
Effectively, we're first splitting the string into the "command", and the "arguments" - the information we want. Then, we split our arguments up using the "d" as a midpoint. That gives us two numbers - the one before and the one after the d. Then we assign those values to variables, and can use them however we like.
This obviously won't deal with more creative or flexible inputs, and isn't tested beyond the examples shown but it should be a decent starting point.

Efficiently sorting large arrays of people by their proximity to the user

So I'm trying to create a list of the 15 closest people in an array of varying sizes. The array will almost always be ~100 objects in size, but for the sake of testing, I'm trying to make it work with 10,000 (there may be need for the project to be scaled up to these numbers further down the line).
Currently, the method in place is to loop through the array of people, and calculate their proximity to the user based on both the person in question's and the user's latitude and longitude (the former of which is stored in the array). This is done using the haversine formulae and works well (though it does take ~500 milliseconds).
The problem however is that when run on a mobile device (a Samsung Galaxy S5 for the sake of this example), performance really suffers. The time taken for the S5 to sort through 10,000 records in order of how close they are to a pre-determined latitude and longitude is a staggering 1,500-1,600 milliseconds, an unacceptable delay for an app that will be doing many things either side of this process.
So my question is, am I missing some fundamentally more efficient means of sorting this list? Is there an alternative formulae available that is more efficient? Could I simply calculate the combined difference in Latitude and Longitude in .000001s and sort based on that?
Notes:
The user's location is variable, so proximities cannot be stored
I am aware that I'm asking a mobile CPU to perform 100,000,000 calculations in a short space of time and so this may be unavoidable
The method of sorting is the native JavaScript sort method, below is a simplified version of what I am doing to test these timings:
patientArray.sort(function(a, b)
{
return GetDistanceToPoint(a["Lat"], a["Lng"]) - GetDistanceToPoint(b["Lat"], b["Lng"]);
});
// Function to get the User's distance to a point
function GetDistanceToPoint(Latitude, Longitude)
{
// Check if the User's current Latitude and Longitude are available
if(currentLat && currentLng)
{
// Convert degrees to a radius
function degreeToRadius(degree)
{
return degree * (Math.PI/180)
}
// Variable to store radius of the Earth in Km
var earthRadius = 6371;
// Calculate the distance between the two points
var dLat = degreeToRadius(Latitude-currentLat);
var dLon = degreeToRadius(Longitude-currentLng);
var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(degreeToRadius(currentLat)) * Math.cos(degreeToRadius(Latitude)) * Math.sin(dLon/2) * Math.sin(dLon/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = earthRadius * c;
return d;
}
return "-1";
}
It all has to be tested but here are some ideas that I would try.
For heavy use of trigonometric functions you can use lookup tables. This is always a good idea. For example precompute 360 (or more) values of sin() and for every sin(radians) in your code use sinTable[degrees].
(I say 360 values as an example because with that your index is an angle in degrees but any value will do and it all depends on what precision you need - it can have thousands of values if needed.)
Avoid unnecessary calculations. May seem obvious but people often write something like x/(2*Math.PI) instead of x*A where A (a better name of course) is computed once as 1/(2*Math.PI).
Memoize every value that you can, if it makes sense.
If your data have some specific qualities, like for example never spanning half of the planet, then you can try to cheat a little bit and use coordinates on a flat plane - then you only have to compute square roots (which could also be precomputed to use lookup tables).
Those are the first things that crossed my mind. Hope it helps.
UPDATE:
You made an edit so I know a little bit more now. Here are my tips:
Don't convert degrees to radians. Keep degrees and use them as indexes in lookup tables of precomputed values of trigonometric functions. If you need more precision then multiply the degrees by 10 or something and use a scale from 0 to 3600 instead of 0 to 360. Find a good size/precision compromise that works for you.
You can eliminate all sin() and cos() calls that way and if you're lucky you can eliminate atan2(). I wouldn't worry so much about sqrt() but you can eliminate it too if you know what the values are typically going to be. If values of functions like sqrt() or atan2() are not known up fron then you can fall back to real functions for values that are out of range of your lookup tables.
Avoid to many function calls. Instead of an anonymous function that you pass to patientArray.sort(), that calls GetDistanceToPoint(), that calls degreeToRadius() - you need only one function that can be passed directly as an argument to .sort() and that function doesn't need to return d - it can return just c (in your example).
You don't need to multiply everything by earthRadius if you only use that value for sorting.
Another quick ideas: using typed arrays (for lookup tables), and asm.js and SIMD.js for additional optimization if possible.
Those are the first things that come to mind. I'd love to hear how much faster your code can get. Good luck.
UPDATE 2:
Another idea - instead of (or in addition to) optimizing the GetDistanceToPoint() you can also make sure that it isn't called more than once for every object.
Instead of:
patientArray.sort(function(a, b)
{
return GetDistanceToPoint(a["Lat"], a["Lng"]) - GetDistanceToPoint(b["Lat"], b["Lng"]);
});
You can try doing something like:
patientArray.forEach(function (element) {
element.distance = GetDistanceToPoint(element["Lat"], element["Lng"]);
});
or maybe for loop will be faster:
for (var i = 0; i < patientArray.length; i++) {
var element = patientArray[i];
element.distance = GetDistanceToPoint(element["Lat"], element["Lng"]);
}
to store the value for the entire patientArray array.
And then in the sort function:
patientArray.sort(function(a, b)
{
return a.distance - b.distance;
});
It may hopefully save you a lot of calls to GetDistanceToPoint.

simplifying the contents of an input using the javascript math system

This obviuosly works perfectly:<script>alert(5*8-4)</script>
but i need to solve whatever someone puts inside an input box.
Heres what I thought of doing: I would get the value of the input, into a variable. then I would use
document.write("<script>alert("+theinputvalue+")<script>");
or do this:
var string="<script>alert("+theinputvalue+")<script>";document.write(string);
but nothing works.
Is it even possible to do this? if not, tell my what simple other system I could use.
eventually, I will use it to graph lines like this:
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d")
for(var x=-100; x<100; x=x+.2){
y = .1*(x*x)
ctx.fillRect(x+50, -1*y+50, 2, 2);
}
http://jsfiddle.net/KGgq4/
eval('5*8-4')
will result in 36
I'm not aware of any library that is doing that (this doesn't mean that there are no such it simply means I never actually needed that) but what you should end up doing is to build an automata that will parse input string and transform it to a proper graph with proper transformations. This is not very easy topic and if you want to go this route you should start reading on arithmetic expressions parsing algorithms (sorry I do not have any solution in place).
Or you can cheat and define types of equations that will be selected by user. Once user selects type of equation you should be able show user inputs where user will be able to select coefficients. You can read those coefficients into different variables and apply transformations in your draw procedure (For example if user will select type sin(x) you know that general equation has following formula: y = k*sin(a*x + b) + c. So once it is selected you can allow user to enter k, a, b, c and based on that input calculate appropriate locations of points for your graph.)
Well, third solution could involve "eval ", but usually you should avoid eval at any cost (B/c it is straight forward JavaScript injection which may be an OK for this case but may get you in trouble later in your life. ).
You can use math.js, which comes with an advanced expression parser. It supports definition of variables and functions.
// create an instance of math.js
var math = mathjs();
// evaluate an expression
math.eval('5*8-4'); // 36
// user defined function (returns a native JavaScript function)
var f = math.eval('f(x) = 2*x^2 + 6');
// use the function (for graphing or something)
f(2); // 14

trig functions with imaginary numbers in javascript

I am trying to write some code in javascript to calculate trig functions, inverse trig functions, and hyperbolic trig functions with imaginary numbers. I have the sin, cos, sinh, and cosh working well. However, I am having some trouble getting my solutions for others to match the only verification that I can find at this site.
For example, below is the code for asin(x+yi). I am using the formula located here along with the definitions for modulus and argument found there as well. It has no errors, but doesn't match the results from the site I cited. What am I doing wrong?
asin(z)=-i*ln(iz+sqrt(1-z^2))
var id1=SquareComplex (window[id].Solution_real, window[id].Solution_imag);
var real=1-window[id1].Solution_real;
var imag=window[id1].Solution_imag;
var id2=SquareRoot(real, imag);
imag=window[id].Solution_real+window[id2].Solution_imag;
real=-window[id].Solution_imag+window[id2].Solution_real;
var modulus=Math.sqrt(real^2+imag^2);
var argument=Math.atan2(imag,real);
var Solution_imag=-Math.log(modulus);
var Solution_real=argument;
This code is intended to work in several steps. The first line calls a function that squares the complex number z. The second and third lines subtract the result from the number 1. The fourth line calls a function to take the square root of the complex number. The fifth and sixth lines add the results of the previous actions to the result of multiplying the complex number by i. The remaining lines get the modulus and argument of those results, take the natural logarithm, and multiply it by a negative i.
Your first three lines are:
var id1=SquareComplex (window[id].Solution_real, window[id].Solution_imag);
var real=1-window[id1].Solution_real;
var imag=window[id1].Solution_imag;
assuming that id is your initial z then this is not calculating the real and imaginary parts of 1-z^2 as I believe it is indtended to. The reason being that the imaginary part isn't being subtracted.
Try it with
var imag = -window[id1].Solution_imag;
and see if that helps. I can't guarantee there aren't any more errors in it but I'd suggest just going through and being really careful about making sure each line does what it should.
You may be interested in math.js, which comes with support for complex numbers for all functions including trigonometry:
var value = math.complex(2, 3);
var ans = math.asin(value);
Or using the expression parser:
var ans = math.eval('asin(2 + 3i)');

Categories