I want to know whether it is possible?
Let Suppose:
var a = 2592;
var b = 2584;
if(a nearly equal to b) {
// do something
}
Like so.
var diff = Math.abs( a - b );
if( diff > 50 ) {
console.log('diff greater than 50');
}
That would compare if the absolute difference is greater than 50 using Math.abs and simple comparison.
Here's the old school way to do it...
approxeq = function(v1, v2, epsilon) {
if (epsilon == null) {
epsilon = 0.001;
}
return Math.abs(v1 - v2) < epsilon;
};
so,
approxeq(5,5.000001)
is true, while
approxeq(5,5.1)
is false.
You can adjust pass in epsilons explicitly to suit your needs. One part in a thousand usually covers my javascript roundoff issues.
var ratio = 0;
if ( a > b) {
ratio = b / a;
}
else {
ratio = a / b;
}
if (ratio > 0.90) {
//do something
}
One line Es6 way version of The Software Barbarian:
const approxeq = (v1, v2, epsilon = 0.001) => Math.abs(v1 - v2) <= epsilon;
console.log(approxeq(3.33333, 3.33322)); // true
console.log(approxeq(2.3, 2.33322)); // false
console.log(approxeq(3, 4, 1)); // true
I changed it to include the number in the margin. So with an epsilon margin of 1 approxeq between 1 and 2 is true
Floating point comparison gets complicated in a hurry. It's not as simple as diff less than epsilon in a lot of cases.
Here's an article about the subject, though not javascript specific.
https://floating-point-gui.de/errors/comparison/
TLDR:
When one of the numbers being compared is very close to zero, subtracting the smaller from the larger can lose digits of precision, making the diff appear smaller than it is (or zero).
Very small numbers with different signs work in a weird way.
Dividing by zero will cause problems.
In the article is a function (java) which solves better for these cases:
public static boolean nearlyEqual(float a, float b, float epsilon) {
final float absA = Math.abs(a);
final float absB = Math.abs(b);
final float diff = Math.abs(a - b);
if (a == b) { // shortcut, handles infinities
return true;
} else if (a == 0 || b == 0 || (absA + absB < Float.MIN_NORMAL)) {
// a or b is zero or both are extremely close to it
// relative error is less meaningful here
return diff < (epsilon * Float.MIN_NORMAL);
} else { // use relative error
return diff / Math.min((absA + absB), Float.MAX_VALUE) < epsilon;
}
}
Before you complain: Yes, that's Java, so you'd have to rewrite it in Javascript. It's just to illustrate the algorithm and it's just copied from the article.
I'm still looking for a thorough solution to this problem, ideally with an NPM package so I don't have to figure this out again every time I need it.
Edit: I've found a package which implements the solution from the article linked above (which has the same link in their readme).
https://www.npmjs.com/package/#intocode-io/nearly-equal
This will be a less error-prone solution than others shown in other answers. There are several npm packages which implement the naive solutions which have error cases near zero as described above. Make sure you look at the source before you use them.
Related
I have an lcm function that is failing for very large numbers, but not smaller numbers. For example, on an input of (6, 8), it returns 24 as the lcm. But if I do something such as (2000000000,1999999999), my while loop will infinitely loop, and not return anything.
I am using a big integer library to handle big numbers, but it doesn't seem to be working. Here is the code:
function lcm(n1, n2) {
n1 = bigInt(n1).value; //bigInt comes from the big-integer library
n2 = bigInt(n2).value;
let smaller = bigInt.min(n1, n2);
let bigger = bigInt.max(n1, n2);
let s1 = smaller;
if (smaller === 1) {
return bigger;
} else if (bigger === 1) {
return smaller;
}
while (s1 % bigger !== 0) { //once s1 % bigger is 0, we found the lcm in s1's variable
s1 = bigInt(s1).add(smaller);
console.log(s1);
}
return s1;
}
Any ideas?
Your algorithm is too slow. With n1=2000000000 and n2=1999999999 it is doing 2 billion add calls. You can use this formula:
lcm(a, b) = a * b / gcd(a, b)
To calculate gcd(a, b) (greatest common divisor) you need to implement division-based version of Euclidian algorithm. Recursive implementation:
function gcd(a, b) {
return b == 0 ? a : gcd(b, a % b);
}
Other implementations (if you want to avoid recursion) can be found here: JS how to find the greatest common divisor
If you are using this package, then you are in luck - it has a built in lcm method for you: link to the docs
If you want to see the implementation of it, check out the source over at the Github repository.
Implementation of the method inside the above library: Source
Hope this helps you out :)
I am not sure my issue is related to programming or related to concept of LLL algorithm and what has been mentioned on Wikipedia.
I decided to implement LLL algorithm as it has been written on Wikipedia (step-by-step / line-by-line) to actually learn the algorithm and make sure it is truly working but I am getting unexpected or invalid results.
So, I used JavaScript (programming language) and node.js (JavaScript engine) to implement it and this is the git repository to get the complete code.
Long story short, value of K gets out of range, for example when we have only 3 vectors (array size is 3, thus maximum value of index would be 2), but k becomes 3 and it is nonsense.
My code is step-by-step (line-by-line) implementation of the algorithm mentioned on Wikipedia and what I did was only implementing it. So I don't what is the issue.
// ** important
// {b} set of vectors are denoted by this.matrix_before
// {b*} set of vectors are denoted by this.matrix_after
calculate_LLL() {
this.matrix_after = new gs(this.matrix_before, false).matrix; // initialize after vectors: perform Gram-Schmidt, but do not normalize
var flag = false; // invariant
var k = 1;
while (k <= this.dimensions && !flag) {
for (var j = k - 1; j >= 0; j--) {
if (Math.abs(this.mu(k, j)) > 0.5) {
var to_subtract = tools.multiply(Math.round(this.mu(k, j)), this.matrix_before[j], this.dimensions);
this.matrix_before[k] = tools.subtract(this.matrix_before[k], to_subtract, this.dimensions);
this.matrix_after = new gs(this.matrix_before, false).matrix; // update after vectors: perform Gram-Schmidt, but do not normalize
}
}
if (tools.dot_product(this.matrix_after[k], this.matrix_after[k], this.dimensions) >= (this.delta - Math.pow(this.mu(k, k - 1), 2)) * tools.dot_product(this.matrix_after[k - 1], this.matrix_after[k - 1], this.dimensions)) {
if (k + 1 >= this.dimensions) { // invariant: there is some issue, something is wrong
flag = true; // invariant is broken
console.log("something bad happened ! (1)");
}
k++;
// console.log("if; k, j");
// console.log(k + ", " + j);
} else {
var temp_matrix = this.matrix_before[k];
this.matrix_before[k] = this.matrix_before[k - 1];
this.matrix_before[k - 1] = temp_matrix;
this.matrix_after = new gs(this.matrix_before, false).matrix; // update after vectors: perform Gram-Schmidt, but do not normalize
if (k === Math.max(k - 1, 1) || k >= this.dimensions || Math.max(k - 1, 1) >= this.dimensions) { // invariant: there is some issue, something is wrong
flag = true; // invariant is broken
console.log("something bad happened ! (2)");
}
k = Math.max(k - 1, 1);
// console.log("else; k, j");
// console.log(k + ", " + j);
}
console.log(this.matrix_before);
console.log("\n");
} // I added this flag variable to prevent getting exceptions and terminate the loop gracefully
console.log("final: ");
console.log(this.matrix_before);
}
// calculated mu as been mentioned on Wikipedia
// mu(i, j) = <b_i, b*_j> / <b*_j, b*_j>
mu(i, j) {
var top = tools.dot_product(this.matrix_before[i], this.matrix_after[j], this.dimensions);
var bottom = tools.dot_product(this.matrix_after[j], this.matrix_after[j], this.dimensions);
return top / bottom;
}
Here is the screenshot of the algorithm that is on Wikipedia:
Update #1: I added more comments to the code to clarify the question hoping that someone would help.
Just in case you are wondering about the already available implementation of the code, you can type: LatticeReduce[{{0,1},{2,0}}] wolfram alpha to see how this code suppose to behave.
Update #2: I cleaned up the code more and added a validate function to make Gram Schmidt code is working correctly, but still code fails and value of k exceeds number of dimensions (or number of vectors) which doesn't make sense.
The algorithm description in Wikipedia uses rather odd notation -- the vectors are numbered 0..n (rather than, say, 0..n-1 or 1..n), so the total number of vectors is n+1.
The code you've posted here treats this.dimensions as if it corresponds to n in the Wikipedia description. Nothing wrong with that so far.
However, the constructor in the full source file on GitHub sets this.dimensions = matrix[0].length. Two things about this look wrong. The first is that surely matrix[0].length is more like m (the dimension of the space) than n (the number of vectors, minus 1 for unclear reasons). The second is that if it's meant to be n then you need to subtract 1 because the number of vectors is n+1, not n.
So if you want to use this.dimensions to mean n, I think you need to initialize it as matrix.length-1. With the square matrix in your test case, using matrix[0].length-1 would work, but I think the code will then break when you feed in a non-square matrix. The name dimensions is kinda misleading, too; maybe just n to match the Wikipedia description?
Or you could call it something like nVectors, let it equal matrix.length, and change the rest of the code appropriately, which just means an adjustment in the termination condition for the main loop.
I am developing a JavaScript application and I needed a recursive algorithm for the longest common subsequence, so I went here and tried this one out.
It goes like this:
function lcs(a, b) {
var aSub = a.substr(0, a.length - 1);
var bSub = b.substr(0, b.length - 1);
if (a.length === 0 || b.length === 0) {
return '';
} else if (a.charAt(a.length - 1) === b.charAt(b.length - 1)) {
return lcs(aSub, bSub) + a.charAt(a.length - 1);
} else {
var x = lcs(a, bSub);
var y = lcs(aSub, b);
return (x.length > y.length) ? x : y;
}
}
It worked fine with the few test cases i tried until now, but I found that it loops on the following test case:
a: This entity works ok
b: This didn't work ok but should after
It also loops with:
a: This entity works ok
b: This didn't work as well
which at some point should get in the middle branch.
I have noticed that it is a translation of a Java version (here) of the same algorithm. It goes like this:
public static String lcs(String a, String b){
int aLen = a.length();
int bLen = b.length();
if(aLen == 0 || bLen == 0){
return "";
}else if(a.charAt(aLen-1) == b.charAt(bLen-1)){
return lcs(a.substring(0,aLen-1),b.substring(0,bLen-1))
+ a.charAt(aLen-1);
}else{
String x = lcs(a, b.substring(0,bLen-1));
String y = lcs(a.substring(0,aLen-1), b);
return (x.length() > y.length()) ? x : y;
}
}
I supposed that the JavaScript translation was wrong assuming that String.substr() and String.substring() were the same (which they aren't).
To be sure that it wasn't the case, I tried the Java one on the same test case here.
Guess what? Also the java version does not end.
I am struggling to debug it, as it is recursive.
Anyone has any idea on what is going wrong with it?
As others have pointed out in the comments, the program itself is correct. The issue you are experiencing is due that, in this implementation, the code has an exponential time complexity, and therefore takes A LONG time to run with your example input. If you let it run for a LONG time, it will return the correct result.
As others have also pointed out in the comments, LCS between two Strings is solvable with a lower time complexity using dynamic programming, which will solve it much quicker. Refer to the internet for more help (wikipedia ) or, better, try to solve it yourself thinking about the fact that there are, for each String of length n, exactly N^2 substrings. You can trivially solve it in N^2*M^2 (n m are the lengths of the two strings) by just checking if any substring of a is present in b. Ask yourself if you can do better for exercise? If yes how, if no, why.
When I try to do 8067 % 80.67 I get 80.66999999999983, instead of 0 beacuse of known floating point javascript behaviour.
So I went and made a function for this, to avoid floating point javascript errors.
function math(a, b) {
var left = Math.abs(a),
times = 1,
abs = a >= 0 ? 1 : -1;
while (Math.abs(a) >= b * times) {
left -= b;
times++;
}
return (a - (b * (times - 1))) * abs;
}
http://jsfiddle.net/s5w3C/
So my question is: is this usefull, ie a good tool to use instead of %? is there cases where this will also give falsy results like the modulus % oprator.
I am looking for a tools to calculate % consistently.
I didn't really inspect the algorithm for correctness, but if you care about efficiency, this is a bad idea. Basically, the larger the input, the slower your code will execute.
I think any fix will only work to a certain level of accuracy and for certain sized numbers. Perhaps something like the following will be sufficient:
function nearlyMod(a, b) {
var precision = ('' + b).split('.').length;
var estimate = (a % b).toFixed(precision);
return estimate == b ? 0 : +estimate;
}
console.log(nearlyMod(8067, 80.66)); // 1
console.log(nearlyMod(8067, 80.67)); // 0
console.log(nearlyMod(8067, 80.68)); // 79.68
It tests if the result is an even divisor within the precision of the original number. If so, it returns 0, otherwise it returns a number to the same precision (which may or may not be what you want).
The result is always a number (the value returned from toFixed is a string, hence +estimate).
A better name might be "roundedMod" or similar.
What is the best way to prevent divide by 0 in javascript that is accepting user inputs.
If there is no particular way to achieve this what would be the best way to handle such a situation so as to not prevent other scripts from executing?
Any insights are much appreciated.
There is no way to do that with the normal / and /= operators.
The best way to do what you want is with guards:
function notZero(n) {
n = +n; // Coerce to number.
if (!n) { // Matches +0, -0, NaN
throw new Error('Invalid dividend ' + n);
}
return n;
}
and then do division like
numerator / notZero(denominator)
Alternatively you can always guard the output
function dividend(numerator, denominator) {
var quotient = numerator / denominator;
if (quotient !== quotient) { throw new Error(numerator + " / " + denominator); }
return quotient;
}
but that loses the readability and expressiveness of /=.
Off the top of my head you could:
Check the user input to see if the denominator is zero (or evaluates to zero, depending on what your script actually does).
Check if the result of the action isFinite() and if not then handle appropriately.
what would be the best way to handle such a situation so as to not prevent other scripts from executing
Division by zero doesn't seem to prevent other scripts from execution in JavaScript:
var a = 20;
var b = 0;
var result = a/b;
console.log(result); // returns Infinity
If you want something different to happen in case of division by zero, you could use
function divideIfNotZero(numerator, denominator) {
if (denominator === 0 || isNaN(denominator)) {
return null;
}
else {
return numerator / denominator;
}
}
Hope this is useful
(denominator != 0 ? numerator/denominator : Infinity)
or whatever value you want to put at the end.
Greetings.
To prevent (unwanted) execution
Always verify critical user input and/or results
Use logic and/or callbacks you can prevent to execute
On HTML forms etc. you can use i.e. return false; as value to stop submission.
Why not just check if the denominator is zero?
if(x != 0) z = y / x;
You can also check if the result is Infinity:
3 / 0 == Infinity
Results in true;
(Only tested in chrome.)
A bit different than stopping execution, but the ternary operator is a pretty slick way to customize variable assignment.
var one = 1,
zero = 0,
customValue = 1;
var quotient = zero===0 ? customValue : one / zero;
This way, by setting the customVariable to the integer of your choice, you can expect a predictable result when division by zero occurs.
The best way is contextual. But here's the easiest:
function myFunction( input ){
input = 0 ? 0.0001 : input; // same as if( input == 0 ){ input = 0.0001; }
return 1 / input;
}
Basically if the input is zero, turn it into a very small number before using as a denominator. Works great for integers, since after your division you can round them back down.
A couple caveats prevent this from being universal:
It could cause false positives if your input accepts really small numbers
It won't trigger any error-handling code, if you need to do something special if zero is entered
So it's best for general-purpose, non-critical cases. For example, if you need to return the result of a complex calculation and don't care if the answer is accurate to N digits (determined by 0.0001 vs. 0.00000001, etc.); you just don't want it to break on a divide-by-zero.
As another answer suggested, you could also create a reusable global function.
function divisor( n ){ return ( n = 0 ? 0.0001 : n ); }
function myFunction( input ){ return 1 / divisor( input ); }
Possible improvements:
function divisor( n, orError ){
if( typeof n == 'undefined' || isNaN( n ) || !n ){
if( orError ){ throw new Error( 'Divide by zero.' ); }
return 0.000000000000001;
}else{ return 0 + n; }
}
This would take any value (null, number, string, object) and if invalid or zero, return the failsafe zero-like value. It would also coerce the output to a number just in case it was a string and you were doing something odd. All this would ensure that your divisor function always worked. Finally, for cases where you wanted to handle such errors yourself, you could set the second parameter to true and use a try/catch.
Set a cap on what the value for the numerator can be and set the numerator to that value when the denominator equals 0.
This is a faster approach yet is confusing
let divisor;
let dividend;
let result =(dividend/divisor) || 0
if the result for instance if you are calculating percentage is infinite you can give it 0 as value;
const progress = goal == 0 ? 0 : total/goal