brute force polynomial evaluation algorithm javascript - javascript

what is required is a brute force algorithm, and not some other!
I'm trying to implement the brute force method for a polynomial in javascript, but an error occurs, the answer is different from the other method above (horner method) - this method is checked and it gives the correct answer
but here is the second brut force- method that gives an excellent result, which is not correct.
What is the error in my code?
input :
_x = 6 _n = 5 polyEval = [2,3,5,-6,2]
output Horner method:
3386 // good. correct answer
output Bruforce method:
1496 // bad. incorrect answer
class Programm {
constructor(x:number, n:number) {
this._x = 4;
this._n = 5;
this.polyEval = [2,3,5,-6,2] //this.RandomArray(this._n);
}
private _x:number;
private _n:number;
private polyEval:number[] = [];
//working method
private Horner(poly:number[], n:number, x:number){
let time = performance.now();
let result = poly[0];
for (let i = 1; i < n; i++){
result = result * x + poly[i];
}
time = performance.now() - time;
console.log("Method: Horner |" ,`Result: ${result}, array: ${this.polyEval} |` ,`time: ${time.toFixed(5)}`);
}
// method with an error that I can't find
private BruteForce(poly:number[], n:number, x:number){
let time = performance.now();
let p: number = 0;
for(let i = n - 1; i >= 0; i--){
let coefficient = 1;
for(let j = 1; j <= i; j++){
coefficient = coefficient * x;
}
p = p + poly[i] * coefficient;
}
time = performance.now() - time;
console.log("Method: Brute Force |" ,`Result: ${p}, array: ${this.polyEval} |` ,`time: ${time.toFixed(5)}`);
}
// generate random array
private RandomArray(n: number):number[]{
let result:number[] = new Array(n);
for (let i = 0; i < n; i++){
if(Math.round(Math.random() * 1) > 0){
result[i] = Math.floor(Math.random() * (10 - 1)) + 1;
}else{
result[i] = Math.floor(((Math.random() * (10 - 1)) + 1) * -1);
}
}
return result;
}
public Main() {
console.log(`n - array length: ${this._n} | x - coefficient: ${this._x}`);
this.Horner(this.polyEval, this._n, this._x);
this.BruteForce(this.polyEval, this._n, this._x);
}
}
const random_N:number = Math.floor(Math.random() * (5 - 1)) + 3;
const random_X:number = Math.floor(Math.random() * (5 - 1)) + 2;
const poly = new Programm(random_N, random_X);
poly.Main();

The Horner's scheme works like this:
// initially
result = poly[0] == p_0;
// iteration 1
result = result * x + poly[1] == p_0 * x + p_1
// iteration 2
result = result * x + poly[2] == (p_0 * x + p_1) * x + p_2
== p_0 * x^2 + p_1 * x + p_2
Thus, the polynomial coefficients in the array poly are in order of highest to lowest. Then to replicate that in the brute force solution, one needs to apply the formula as
result = sum(poly[i] * pow(x, n-1-i)) ==
result = sum(poly[n-1-i] * pow(x, i))

Related

Trigonometric Interpolation returns NaN

I'm a musician, who's new to programming. I use JavaScript inside Max Msp (hence the bang() and post() functions) to create a trigonometric interpolation, interpolating between given equidistant points (for testing, only values of sine from [0, 2π) and returning values from the same points). When I run the code, it returns NaN, except for x = 0, as my tau() function returns only 1 in this special case. Could it be, that it has something to do with summing Math.sin results?
var f = new Array(9);
var TWO_PI = 2*Math.PI;
bang();
function bang() {
for(var i = 0; i < f.length; i++) {
f[i] = Math.sin(i/f.length*TWO_PI);
//post("f[" + i + "]: " + Math.round(f[i]*1000)/1000 + "\n");
}
var points = new Array(f.length);
for(var i = 0; i < points.length; i++) {
var idx = i/points.length*TWO_PI;
points[i] = [i, p(idx)];
//post("p[" + points[i][0] + "]: " + Math.round(points[i][1]*1000)/1000 + "\n");
}
console.log("p(2): " + p(2/points.length*TWO_PI) + "\n");
}
function p(x) {
var result = 0;
for(var k = 0; k < f.length; k++) {
result += f[k]*tau(k, x);
}
return result;
}
function tau(k, x) {
var dividend = sinc(1/2*f.length*(x-k/f.length*TWO_PI));
var divisor = sinc(1/2*(x-k/f.length*TWO_PI));
var result = dividend/divisor;
if(f.length%2 == 0) result *= Math.cos(1/2*(x-k/f.length*TWO_PI));
if(x == 0) return 1;
return result;
}
function sinc(x) {
return Math.sin(x)/x;
}
In your tau function, if x equals k / f.length * TWO_PI (which it will since x is multiples of 1 / points.length * TWO_PI) your sinc function divides by 0, making divisor equal to NaN, which then propagates.
You have to be a bit careful in implementing sinc to avoid dividing by 0. One way is to say that if x is small enough we can replace sin(x) by the first few terms of its taylor series, and all the terms are divisible by x.
I don't know javascript but here is the function in C in case it is of use
#define SINC_EPS (1e-6)
// for small x,
// missing sinc terms start with pow(x,4)/120, and value close to 1
// so the error too small to be seen in a double
double sinc( double x)
{ if ( fabs(x) < SINC_EPS)
{ return 1.0 - x*x/6.0;
}
else
{ return sin(x)/x;
}
}

Memory issues in recursion

I'm trying to solve this leetcode problem here: https://leetcode.com/problems/next-closest-time/description/.
Simply my solution is to try every combination that is valid and then set my ans variable to the one that is closest to the original time. It does print out all the combinations however the diff variable never changes. In the for loop after (if cur.length ==4) it prints every possible combination because it still thinks that diff is 9007199254740991. Also when I assign ans to cur.slice(), I receive a blank array. Even when I uncomment it in the nextClosestTime function I still have the same issue.
/**
* #param {string} time
* #return {string}
*/
var diff = 9007199254740991;
function calcSeconds(digits) {
var hours = (digits[0] * 10) + digits[1];
var seconds = (digits[2] * 10) + digits[3];
return (hours * 3600) + (seconds * 60);
}
function nextClosestTime(time) {
var digits = [];
// diff = 9007199254740991;
var cur = [];
var ans = [];
for (var i = 0; i < time.length; i++) {
if (isFinite(time.charAt(i))) {
digits.push(parseInt(time.charAt(i)));
}
}
var target = calcSeconds(digits);
nch(digits, cur, diff, target, ans);
return ans;
};
function nch(digits, cur, diff, target, ans) {
if (cur.length == 4) {
var curSec = calcSeconds(cur);
if (Math.abs(curSec - target) < diff) {
console.log(cur);
diff = Math.abs(calcSeconds(digits) - calcSeconds(cur));
//ans = cur.slice();
}
return;
}
for (var i = 0; i < digits.length; i++) {
if ((((cur[0] * 10) + cur[1]) >= 24) || (((cur[2] * 10) + cur[3]) >= 60)) {
return;
}
cur.push(digits[i]);
nch(digits, cur, diff, target, ans);
cur.pop()
}
}

Calculate the nearest value on a circular variable

I have an problem where i have 3 times of the 24 hour day. To keep it simple i can use the decimal representation:
a) 23:45 (23.75)
b) 11:30 (11.50)
c) 00:15 (00.25)
I'd like to know , for each time, which other time is closest.
var closestTime = 24
var closestActualTime = 0;
for (var i = 0; i < times.length; i++) {
if (times[i].time == this.time) continue;
var temp = Math.abs(this.time - times[i].time)
if (temp < closestTime) {
closestTime = temp;
closestActualTime = times[i].time;
}
}
My issue is that 23:45 and 00:25 are actually really close but i don't know how process a variable with a modulo type
I suggest to build a list with the pairs and then calculate the difference.
The difference is the third element in the pairs array.
Basically you need to check the delta and if it greater than 12 hours, take the difference from 24 and delta.
delta = Math.abs(aa - bb);
if (delta > 12) {
delta = 24 - delta;
}
function combination(array, size) {
function c(part, start) {
var i, l, p;
for (i = start, l = array.length + part.length + 1 - size; i < l; i++) {
p = part.slice();
p.push(array[i]);
p.length < size ? c(p, i + 1) : result.push(p);
}
}
var result = [];
c([], 0);
return result;
}
function timeDelta(a, b) {
function decimalTime(s) {
var p = s.split(':');
return +p[0] + p[1] / 60;
}
function padZero(v) {
return (v < 10) ? '0' + v : String(v);
}
var aa = decimalTime(a),
bb = decimalTime(b),
delta = Math.abs(aa - bb);
if (delta > 12) {
delta = 24 - delta;
}
return padZero(Math.floor(delta)) + ':' + padZero(Math.round(60 * (delta - Math.floor(delta))));
}
var times = ['23:45', '11:30', '00:15'],
pairs = combination(times, 2);
pairs.forEach(function (a, i, aa) {
aa[i][2] = timeDelta(a[0], a[1]);
});
console.log(pairs);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Loop over times.
Try combinations of delta time, offset by 24 hours.
Pick smallest delta time.
var times = [23.75, 11.50, 3, 6, 7];
/**
* timeClosestTo
*
* #param {number} time
* #returns {number}
*/
function timeClosestTo(time) {
//Distance variable to compare against
var distance = 100;
//Hours in a day
var day = 24;
//Current best
var best = null;
//Test against all times
for (var i = 0; i < times.length; i++) {
//Find best score based upon day
var d = Math.min(Math.abs((times[i]) - (time)), Math.abs((times[i] + day) - time), Math.abs((times[i]) - (time + day)), Math.abs((times[i] + day) - (time + day)));
//If best found distance yet, set best to current
if (d < distance) {
best = times[i];
distance = d;
}
}
//Return best
return best;
}
console.log("times to deal with:",times.join(", "));
console.log("closest to 1:", timeClosestTo(1), "closest to 11:", timeClosestTo(11), "closest to 5:", timeClosestTo(5));
Quite functionally i would do this job as follows
var times = [23.75,11.50,0.25],
diffs = times.reduce((d,t1,i,a) => a[i+1] ? d.concat(a.slice(i+1)
.map(t2 => [t1,t2,[Math.min(Math.abs(t1-t2),24-Math.abs(t1-t2))]
.map(n => ~~n + ":" + (n%1)*60)[0]]))
: d,[]);
console.log(diffs);

Javascript Loop with adding same value

I hope you guys can help me!
I'm trying the following:
1000 + 100 = 1100 * 2 = 2200;
2200 + 100 = 2300 * 2 = 4600;
4600 + 100 = 4700 * 2 = 9400;
9400 + 100 = 9500 * 2 = 19000;
...
But I'm getting the flowing result.
1000 + 100 = 1100 * 2 = 2200;
2200 * 2 = 4400
4400 * 2 = 8800
...
The values are inputed by the user, but I used static values for the example.
I have te following code:
var generate = function generate(rate){
var array = [];
s=0;
for (var i = 0; i < 10; i++){
s =+ 100;
array.push([
(parseInt(1000) + 100) * Math.pow(2, i),
]);
}
return array;
}
Sounds to me like you want a function that adds 100, doubles and then calls itself recursively a fixed number of times.
This function will run 10 times and output the final answer:
function add100andDouble(num, runTimes){
if(runTimes == 0) return num;
return add100andDouble( (num + 100 ) * 2, runTimes - 1 );
}
$(function(){
var number = parseFloat(prompt("Enter a number"));
alert( add100andDouble(number, 10) );
});
var generate = function generate(rate){
var array = [];
s=0;
for (var i = 0; i < 10; i++){
s = rate + (array[i-1] ? array[i-1] :1000);
array.push(s*2);
}
return array;
}
console.log(generate(100));
I suggest to use a function f(x) for calculating the new value. It makes the code more clearly arranged.
function f(x) {
return (x + 100) * 2;
}
var i = 0,
x = 1000,
array = [];
for (i = 0; i < 10; i++) {
array.push(x);
x = f(x);
}
document.write('<pre>' + JSON.stringify(array, 0, 4) + '</pre>');
Recursion has its merits on other solutions but I would go with plain old for loop for this situation.
Assuming rate is the starting number, and the return is a fixed 10 value series:
function generate(rate) {
var series = [];
for(var i = 0; i < 10; i++) {
series.push(rate = ((rate + 100) * 2));
};
return series;
}
It can be easily modified to send the series length if needed.

How to write multidimensional array in JS in a loop?

I have the following code:
var marketReturns = [1];
var marketReturnsVol = [1];
var marketVolatility = [1];
var yearlyReturns = [];
var yearlyReturns2 = [];
for (y = 0; y < 50000; y++) {
for (x = 1; x <= 251; x++) {
do {
var rand1 = Math.random();
var rand2 = Math.random();
var x1 = 2.0 * rand1 - 1.0;
var x2 = 2.0 * rand2 - 1.0;
var w = Math.pow(x1, 2) + Math.pow(x2, 2);
} while (w === 0 || w > 1);
multiplier = Math.sqrt((-2 * Math.log(w)) / w);
var volVol = 1 + (((x2 * multiplier) / 100) * 5.98); // real ^VIX is 5.98.
marketVolatility[x] = volVol * marketVolatility[x - 1];
var y1 = 1 + (((x1 * multiplier) / 100) * 1.07); // 1.07 is the daily vol of ^GSPC
var y12 = 1 + (((x1 * multiplier) / 100) * 1.07 * marketVolatility[x]) + 0.00038; // 1.07 is the daily vol of ^GSPC
marketReturns[x] = y1 * marketReturns[x - 1];
marketReturnsVol[x] = y12 * marketReturnsVol[x - 1];
}
yearlyReturns[y] = marketReturns[251];
yearlyReturns2[y] = marketReturnsVol[251];
}
yearlyReturns.sort(function (a, b) {
return (a - b);
})
yearlyReturns2.sort(function (a, b) {
return (a - b);
})
for (x = 0; x < yearlyReturns.length; x++) {
document.write(yearlyReturns2[x] + ", ");
}
So essentially I am calculating marketReturns, which is marketReturns[x-1] * daily change. I want however to make this into subarrays where I can preserve all the individual marketReturns for each iteration of y instead of just preserving the last day like I am in yearlyReturns[y].
I thought I could do it as such:
marketReturns[y][x] = y1 * marketReturns[y][x - 1];
marketReturnsVol[y][x] = y12 * marketReturnsVol[y][x - 1];
But this doesn't work. Is there any way for me to start writing the marketReturns figures into subarrays? Thanks.
You can mimic the multidimensional array using nested array/nested object in javascript:
e.g.
var arr = [];
//Initialize a 10x10 "multidimensional" array
for(var i = 0; i < 10; i++) {
arr[i] = [];
for(var j = 0; j < 10; j++) {
arr[i][j] = 0;
}
}
//Store
arr[5][5] = 10;

Categories

Resources