I have a function to generate some random-ish numbers and inside that function I make a call to setInterval() because I need those numbers to refresh every 2 seconds.
function genSine(val1, val2) {
var freq = 0.1; // angular frequency
var coords = function(x, y) {
var amplitude = Math.floor((Math.random()*10)+1);
var phase = Math.floor((Math.random()*20)+1);
return {
x : Math.sin(freq * (val1 + phase) * amplitude) + Math.floor((Math.random()*100)+1),
y : Math.sin(freq * (val2 + phase) * amplitude) + Math.floor((Math.random()*100)+1)
};
}
setInterval(function() {
current = coords(50, 50);
console.log('Val 1: ' + current.x);
console.log('Val 2: ' + current.y);
}, 2000);
}
genSine(10, 20);
This is all well and good, the values update as expected but my goal is to have two global variables (let's call them val1/val2) update within that setInterval() function. It appears I have a scoping issue because those variables are not accessible within the function and I can not access the 'current' variable from outside that function. I know I am missing something here, what is it?
Fiddle: http://jsfiddle.net/niczak/4uNen/1/
You just need to define var current = {}; in the global scope, and be sure not to define var current in any other scope. current=[whatever]; is fine, as long as there's no var.
Edit: I'm not sure what you did, but I fixed your fiddle with this code:
var current;
function genSine(val1, val2) {
var freq = 0.1; // angular frequency
var coords = function(x, y) {
var amplitude = Math.floor((Math.random()*10)+10);
var phase = Math.floor((Math.random()*20)+10);
return {
x : Math.sin(freq * (val1 + phase) * amplitude) + Math.floor((Math.random()*100)+1),
y : Math.sin(freq * (val2 + phase) * amplitude) + Math.floor((Math.random()*100)+1)
};
}
setInterval(function() {
current = coords(50, 50);
console.log(current);
$(".display").html(JSON.stringify(current));
}, 500);
}
genSine(10, 20);
setInterval(function() {
$(".display2").html("d2:"+JSON.stringify(current));
}, 200);
Your current is fine in that scope, it is your coords function that is not in the right scope. Put that in the global scope together with the freq variable:
var freq = 0.1; // angular frequency
var coords = function (x, y) {
var amplitude = Math.floor((Math.random() * 10) + 1);
var phase = Math.floor((Math.random() * 20) + 1);
return {
x: Math.sin(freq * (val1 + phase) * amplitude) + Math.floor((Math.random() * 100) + 1),
y: Math.sin(freq * (val2 + phase) * amplitude) + Math.floor((Math.random() * 100) + 1)
};
}
function genSine(val1, val2) {
setInterval(function () {
current = coords(50, 50);
console.log('Val 1: ' + current.x);
console.log('Val 2: ' + current.y);
}, 2000);
}
genSine(10, 20);
in typescript i did following code. in the below code i assign _this with the value of this
export class HomeComponent implements OnInit {
lat: number = 22.008515;
setMarker(){
console.log('Inside setMarker Lat : '+this.lat); // 22.008515
var _this = this;
setInterval(function() {
console.log('Inside setInterval this.lat : '+this.lat); // undefined
console.log('Inside setInterval _this.lat : '+_this.lat); // 22.008515
}, 8000)
}
}
Related
I'm trying to write a JavaScript fractal generation algorithm from first principles. I'm aware that there are many examples out there but I wanted to incorporate additional functionality to support both Mandelbrot and 'spinning' Julia with variants such as 'Burning Ship' and 'Tricorn'. With this in mind I implemented a lightweight Complex maths library (again, I'm aware there are standard Complex js libraries out there but I wanted to build one from scratch as a learning exercise).
I tested two alternate functions, one fractal using standard maths functions and the other fractalComplex using my Complex library methods. They both work fine, but I was surprised to find that the standard version is almost twice as fast as the Complex version. I was expecting some additional overhead but not that much!
Can anyone explain why? The Complex library is using the same maths constructs 'under the covers'. Is the additional overhead purely down to object creation?
The code is reproduced below (the input parms z and c are objects of the form {re, im}).
function fractal(z, c, maxiter) {
var i, za, re, im, re2, im2;
c = (settype === JULIA ? c : z);
// Iterate until abs(z) exceeds escape radius
for (i = 0; i < maxiter; i += 1) {
if (setvar === BURNING_SHIP) {
re = Math.abs(z.re);
im = -Math.abs(z.im);
}
else if (setvar === TRICORN) {
re = z.re
im = -z.im; // conjugate z
}
else { // Mandelbrot
re = z.re;
im = z.im;
}
re2 = re * re;
im2 = im * im;
z = { // z = z² + c
re: re2 - im2 + c.re,
im: 2 * im * re + c.im
};
za = re2 + im2 // abs(z)²
if (za > 4) { // abs(z)² > radius²
break;
}
}
za = Math.sqrt(za); // abs(z)
return { i, za };
}
function fractalComplex(z, c, maxiter, n, radius) {
var i, za;
c = (settype === JULIA ? c : z);
// Iterate until abs(z) exceeds escape radius
for (i = 0; i < maxiter; i += 1) {
if (setvar === BURNING_SHIP) {
z = new Complex(Math.abs(z.re), -Math.abs(z.im))
}
if (setvar === TRICORN) {
z = z.conjugate()
}
z = z.quad(n, c); // z = zⁿ + c
za = z.abs();
if (za > radius) {
break;
}
}
return { i, za };
}
My "Complex lite" library is as follows:
// ------------------------------------------------------------------------
// A basic complex number library which implements the methods used for
// Mandelbrot and Julia Set generation.
// ------------------------------------------------------------------------
'use strict';
// Instantiate complex number object.
function Complex(re, im) {
this.re = re; // real
this.im = im; // imaginary
}
Complex.prototype = {
're': 0,
'im': 0,
// Set value.
'set': function (re, im) {
this.re = re;
this.im = im;
},
// Get magnitude.
'abs': function () {
return Math.sqrt(this.re * this.re + this.im * this.im);
},
// Get polar representation (r, θ); angle in radians.
'polar': function () {
return { r: this.abs(), θ: Math.atan2(this.im, this.re) };
},
// Get square.
'sqr': function () {
var re2 = this.re * this.re - this.im * this.im;
var im2 = 2 * this.im * this.re;
return new Complex(re2, im2);
},
// Get complex number to the real power n.
'pow': function (n) {
if (n === 0) { return new Complex(1, 0); }
if (n === 1) { return this; }
if (n === 2) { return this.sqr(); }
var pol = this.polar();
var rn = Math.pow(pol.r, n);
var θn = n * pol.θ;
return cart(rn, θn);
},
// Get conjugate.
'conjugate': function () {
return new Complex(this.re, -this.im);
},
// Get quadratic zⁿ + c.
'quad': function (n, c) {
var zn = this.pow(n);
return new Complex(zn.re + c.re, zn.im + c.im);
},
// Rotate by angle in radians.
'rotate': function (angle) {
var pol = this.polar();
angle += pol.θ;
return new Complex(pol.r * Math.cos(angle), pol.r * Math.sin(angle));
},
// String in exponent format to specified significant figures.
'toString': function (sig = 9) {
return this.re.toExponential(sig) + " + " + this.im.toExponential(sig) + "i";
},
}
// Convert polar (r, θ) to cartesian representation (re, im).
function cart(r, θ) {
var re = r * Math.cos(θ);
var im = r * Math.sin(θ);
return new Complex(re, im);
}
Additional edit 22/12/2021 11:52:
For what it's worth, this is what I eventually settled on...
function fractal(p, c, n, maxiter, radius) {
var i, za, zre, zim, tre, cre, cim, r, θ;
var lastre = 0;
var lastim = 0;
var per = 0;
if (setmode === JULIA) {
cre = c.re;
cim = c.im;
zre = p.re;
zim = p.im;
}
else { // Mandelbrot mode
cre = p.re;
cim = p.im;
zre = 0;
zim = 0;
}
// Iterate until abs(z) exceeds escape radius
for (i = 0; i < maxiter; i += 1) {
if (setvar === BURNING_SHIP) {
zre = Math.abs(zre);
zim = -Math.abs(zim);
}
else if (setvar === TRICORN) {
zim = -zim; // conjugate z
}
// z = z² + c
if (n == 2) {
tre = zre * zre - zim * zim + cre;
zim = 2 * zre * zim + cim;
zre = tre;
}
else { // z = zⁿ + c, where n is integer > 2
r = powi(Math.sqrt(zre * zre + zim * zim), n); // radiusⁿ
//r = Math.pow(Math.sqrt(zre * zre + zim * zim), n); // radiusⁿ
θ = n * Math.atan2(zim, zre); // angleⁿ
zre = r * Math.cos(θ) + cre;
zim = r * Math.sin(θ) + cim;
}
// Optimisation - periodicity check speeds
// up processing of points within set
if (PERIODCHECK) {
if (zre === lastre && zim === lastim) {
i = maxiter;
break;
}
per += 1;
if (per > 20) {
per = 0;
lastre = zre;
lastim = zim;
}
}
// ... end of optimisation
za = zre * zre + zim * zim // abs(z)²
if (za > radius) { // abs(z)² > radius²
break;
}
}
return { i, za };
}
// Optimised pow() function for integer exponents
// using 'halving and squaring'.
function powi(base, n) {
var res = 1;
while (n) {
if (n & 1) { // if n is odd
res *= base;
}
n >>= 1; // n * 2
base *= base;
}
return res;
}
The following class might satisfy both performance concerns and proper encapsulation of the Complex object...
Notables:
Where applicable, always return the this Complex object (ie, the instantiated object), which facilitates chaining. Eg,
x = new Complex( 10, 5 ).sqrThis().powThis( 1 );
For every Complex method that returns a Complex object, configure two (2) methods:
A method, dubbed <method>This that operates directly on the this object and contains the function logic.
A method, dubbed <method> that clones a new Complex object from the this object, and then calls <method>This to execute the function logic on the clone.
This provides the developer the choice of methods that either updates the existing object or returns a new object.
Internal calls to other Complex methods generally should use the <method>This version, as the initial call establishes whether to use the existing this object in-place, or to clone it. From there, all internal calls to the other Complex methods will either continue to operate on the this object or the clone.
// ------------------------------------------------------------------------
// A basic complex number library which implements the methods used for
// Mandelbrot and Julia Set generation.
// ------------------------------------------------------------------------
'use strict';
class Complex {
constructor( reOrComplex, im ) {
this.set( reOrComplex, im );
}
set( reOrComplex, im ) {
if ( reOrComplex instanceof Complex ) {
this.re = reOrComplex.re;
this.im = reOrComplex.im;
} else {
this.re = reOrComplex;
this.im = im;
}
return this;
}
abs() {
return Math.sqrt(this.re * this.re + this.im * this.im);
}
toPolar() {
return { r: this.abs(), θ: Math.atan2(this.im, this.re) };
}
sqrThis() {
return this.set( this.re * this.re - this.im * this.im, 2 * this.im * this.re );
}
sqr() {
return new Complex( this ).sqrThis();
}
powThis( n ) {
if ( n === 0 ) { return this.set( 1, 0 ) };
if ( n === 1 ) { return this; }
if ( n === 2 ) { return this.sqrThis(); }
let polar = this.toPolar();
return this.toCartesianThis( Math.pow(polar.r, n), n * polar.θ );
}
pow( n ) {
return new Complex( this ).powThis( n );
}
conjugateThis() {
return this.set( this.re, -this.im);
}
conjugate() {
return new Complex( this ).conjugateThis();
}
quadraticThis( n, c ) {
let zn = this.powThis( n );
return this.set( zn.re + c.re, zn.im + c.im );
}
quadratic( n, c ) {
return new Complex( this ).quadraticThis( n, c );
}
rotateThis( deltaAngle ) {
let polar = this.toPolar();
let angle = polar.θ + deltaAngle;
return this.set( polar.r * Math.cos(angle), polar.r * Math.sin(angle) );
}
rotate( deltaAngle ) {
return new Complex( this ).rotateThis( deltaAngle );
}
toString( sig = 9 ) {
return this.re.toExponential( sig ) + " + " + this.im.toExponential( sig ) + "i";
}
toCartesianThis( r, θ ) {
return this.set( r * Math.cos( θ ), r * Math.sin( θ ) );
}
}
// Convert polar (r, θ) to cartesian representation (re, im).
Complex.toCartesian = function ( r, θ ) {
return new Complex().toCartesianThis( r, θ );
}
let x = new Complex( 10, 5 ).sqrThis();
console.log( 'x = new Complex( 10, 5 ).sqrThis()' );
console.log( 'x is ', x );
let y = x.pow( 3 );
console.log ( 'y = x.pow( 3 )' );
console.log ( 'y is ', y );
x.sqr();
console.log ( 'x.sqr()' );
console.log ( 'x is still', x );
x.sqrThis();
console.log ( 'x.sqrThis()' );
console.log ( 'x is now', x );
In short, structuring a class this way provides two versions of the same method:
One method which embodies the function logic and directly mutates the instantiated this object.
And the other method which simply clones the instantiated this object, and then calls the associated method containing the function logic.
I am not familiar with ES6 arrow functions and I received the code below from a vendor:
Highcharts.seriesType('linearregression', 'pareto', {
name: 'Linear Regression'
}, {
setDerivedData: function() {
if (this.baseSeries.yData.length > 1) {
var xValues = this.baseSeries.xData,
yData = this.baseSeries.yData,
mainData = this.baseSeries.data;
var sum = [0, 0, 0, 0, 0],
len = xValues.length,
data, rise, gradient, intercept;
Highcharts.each(xValues, function(x, i) {
sum[0] += x;
sum[1] += yData[i];
sum[2] += x * x;
sum[3] += x * yData[i];
sum[4] += yData[i] * yData[i];
});
run = ((len * sum[2]) - (sum[0] * sum[0]));
rise = ((len * sum[3]) - (sum[0] * sum[1]));
gradient = run === 0 ? 0 : (rise / run);
intercept = (sum[1] / len) - ((gradient * sum[0]) / len);
function round(value, decimals) {
return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals);
};
function predict(x) {
return [mainData[x].name, round((gradient * x) + intercept, 5)];
};
points = xValues.map(p => predict(p));
this.setData(points, false);
}
}
});
I wanted to put this into production today but just found out that ES6 is not supported in IE. How can this be rewritten to remove the arrow function (the line below)?
points = xValues.map(p => predict(p));
How about
points = xValues.map(function(p) { return predict(p); });
I have an animation of SVG paths and I would like to eg. addClass after last of element in paths is done with animation. I tried to add a callback for animate() but it doesnt work, it started when the first loop ended. then I tried .when(startAnimeDude()).then(doStuff()) but also it started at the beginning. Last thing what I tried is i == i.length -1 and also it started at the beginning( while the animation is still going). What I am missing ?
Thanks for reading.
DEMO: http://jsfiddle.net/18yunbhk/
JS
var anim = function () {
$.extend(jQuery.easing, {
easeInOutQuad: function (x, t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t + b;
return -c / 2 * ((--t) * (t - 2) - 1) + b;
}
});
var animeDude = function (parent, min, max, delayAnim) {
var paths = $('svg').find('path');
$.each(paths, function (i) {
var totalLength = this.getTotalLength();
$(this).css({
'stroke-dashoffset': totalLength,
'stroke-dasharray': totalLength + ' ' + totalLength
});
$(this).delay(delayAnim * i).animate({
'stroke-dashoffset': 0
}, {
duration: Math.floor(Math.random() * max) + min,
easing: 'easeInOutQuad'
});
if (i == 12) { //12 is last element
console.log('sad');
}
});
};
var startAnimeDude = function (parent) {
animeDude(parent, 0, 1000, 40);
};
startAnimeDude($('svg'));
};
anim();
Something like
if (i === (paths.length - 1)) {
console.log("sad");
}
JSFIDDLE
If you want the condition to be checked only when the animation is complete, then you can write that piece of code in the callback function for animation.
$(this).delay(delayAnim * i).animate({
'stroke-dashoffset': 0
}, {
duration: Math.floor(Math.random() * max) + min,
easing: 'easeInOutQuad',
complete: function() {
if (i === (paths.length - 1)) { //12 is last element
console.log('sad');
}
}
});
Hello I have found a javascript class for some excel functions but i dont know how to use it. I need to use XIRR function but i dont know the type and format of parameters and the syntax.
Here is the code:
/* Based on
* - EGM Mathematical Finance class by Enrique Garcia M. <egarcia#egm.co>
* - A Guide to the PMT, FV, IPMT and PPMT Functions by Kevin (aka MWVisa1)
*/
var ExcelFormulas = {
PVIF: function(rate, nper) {
return Math.pow(1 + rate, nper);
},
FVIFA: function(rate, nper) {
return rate == 0? nper: (this.PVIF(rate, nper) - 1) / rate;
},
PMT: function(rate, nper, pv, fv, type) {
if (!fv) fv = 0;
if (!type) type = 0;
if (rate == 0) return -(pv + fv)/nper;
var pvif = Math.pow(1 + rate, nper);
var pmt = rate / (pvif - 1) * -(pv * pvif + fv);
if (type == 1) {
pmt /= (1 + rate);
};
return pmt;
},
IPMT: function(pv, pmt, rate, per) {
var tmp = Math.pow(1 + rate, per);
return 0 - (pv * tmp * rate + pmt * (tmp - 1));
},
PPMT: function(rate, per, nper, pv, fv, type) {
if (per < 1 || (per >= nper + 1)) return null;
var pmt = this.PMT(rate, nper, pv, fv, type);
var ipmt = this.IPMT(pv, pmt, rate, per - 1);
return pmt - ipmt;
},
DaysBetween: function(date1, date2) {
var oneDay = 24*60*60*1000;
return Math.round(Math.abs((date1.getTime() - date2.getTime())/oneDay));
},
// Change Date and Flow to date and value fields you use
XNPV: function(rate, values) {
var xnpv = 0.0;
var firstDate = new Date(values[0].Date);
for (var key in values) {
var tmp = values[key];
var value = tmp.Flow;
var date = new Date(tmp.Date);
xnpv += value / Math.pow(1 + rate, this.DaysBetween(firstDate, date)/365);
};
return xnpv;
},
XIRR: function(values, guess) {
if (!guess) guess = 0.1;
var x1 = 0.0;
var x2 = guess;
var f1 = this.XNPV(x1, values);
var f2 = this.XNPV(x2, values);
for (var i = 0; i < 100; i++) {
if ((f1 * f2) < 0.0) break;
if (Math.abs(f1) < Math.abs(f2)) {
f1 = this.XNPV(x1 += 1.6 * (x1 - x2), values);
}
else {
f2 = this.XNPV(x2 += 1.6 * (x2 - x1), values);
}
};
if ((f1 * f2) > 0.0) return null;
var f = this.XNPV(x1, values);
if (f < 0.0) {
var rtb = x1;
var dx = x2 - x1;
}
else {
var rtb = x2;
var dx = x1 - x2;
};
for (var i = 0; i < 100; i++) {
dx *= 0.5;
var x_mid = rtb + dx;
var f_mid = this.XNPV(x_mid, values);
if (f_mid <= 0.0) rtb = x_mid;
if ((Math.abs(f_mid) < 1.0e-6) || (Math.abs(dx) < 1.0e-6)) return x_mid;
};
return null;
}
};
You want to use XIRR, so let's look at its signature:
XIRR: function(values, guess)
What does it do with values?
var f1 = this.XNPV(x1, values);
So values must be whatever XNPV is expecting. It has this chunk at its core:
for (var key in values) {
var tmp = values[key];
var value = tmp.Flow;
var date = new Date(tmp.Date);
xnpv += value / Math.pow(1 + rate, this.DaysBetween(firstDate, date)/365);
};
So it is expecting values to be a dictionary (associative array), where the value part of the key-value pair has members .Flow and .Date. I assume .Flow is the cashflow, and from the DaysBetween method I can see that .Date is a javascript Date. The key is ignored, so it can be a numeric if we want. So let's make one of those:
var myInstrument = { 0: {Flow: 5, Date: new Date(2015, 7, 6)},
1: {Flow: 105, Date: new Date(2016, 7, 6)} };
(That is a dictionary (or array) declaration).
The other input to XIRR is guess, which it will use to solve something, but it will default to using 0.1 (10% !) if given a falsy input value. So we can call it with our myInstrument thus:
var myInternalReturn = XIRR(myInstrument, false);
NB: The XIRR function is implementing the Actual/365 Fixed day count convention for Annual payment frequency, which may not be appropriate for the instrument you are valuing. Maybe it won't make much difference, but it will be incorrect for semi-annual or 30/360, with particular problems around month-end dates, simple interest instruments and so on
I got 2 functions:
var number1 = 9
var number2 = 17;
//Get Percent of a the number1
function getPercent(x, y) {
return x * 100 / y;
}
var percentOfNumber1 = getPercent(number1, number2);
//Get rid of remainder
function getRemain(t) {
var remainder = t % 2;
t = t - remainder;
return t;
}
alert(getRemain(percentOfNumber1));
That works..but I want to close the getRemain function in the first function.
so What I did and I dont' get result with:
function getPercent(x, y) {
return x * 100 / y;
function getRemain(t) {
var remainder = t % 2;
t = t - remainder;
return t;
}
var numberClear = getRemain(result);
}
var result = getPercent(number1, number2);
alert(numberClear);
Can anyone explain the wrong approach to this?
"this is the first time I try closures I read couple of good explanations but didin't get the calling functions part really good I guess.."
Thnx.
You need to declare numberClear outside if you want to access it outside:
var numberClear;
function getPercent(x, y) {
function getRemain(t) {
return t - t % 2;
}
var result = x * 100 / y;
numberClear = getRemain(result);
return result;
}
var result = getPercent(number1, number2);
alert(numberClear);
Why not this?
Return both the values at once
function getPercentage(a, b){
function getRemain(t)
{
var remainder = t % 2;
t = t - remainder;
return t;
}
return {
percentage: a / b * 100,
remain: getRemain(a / b * 100)
}
};
var result = getPercentage(9, 17);
alert(result.percentage);
alert(result.remain);
You simply didn't return the result properly:
function getPercent(x,y)
{
function getRemain(t)
{
var remainder = t % 2;
t = t - remainder;
return t;
}
return getRemain(x * 100 / y); // <-- return what getRemain() gives you!
}
var result = getPercent(number1, number2);
There is no way to access a variable declared inside a function from outside it.
You could try this:
var getPercent = (function() {
function getRemain(t)
{
var remainder = t % 2;
t = t - remainder;
return t;
}
return function (x,y)
{
var percent = x * 100 / y;
return {
percent: percent,
remainder: getRemain(percent)
};
}
})();
In this way the getRemain function is not accessible and the getPercent function will return both the percent and remainder values.
try this
var numberClear;
function getPercent(x, y) {
var percentange = x * 100 / y;
numberClear = getRemain(result); // set your numberClear Variable here
return percentange;
}
function getRemain(t) {
return t - t % 2;
}
var result = getPercent(number1, number2);
alert(numberClear);