Mandelbrot set defined by a specific function - javascript

I'm experimenting with canvas and I'm trying to modify this piece of code, but unfortunately I don't understand some parts of it.
My question is - how to customize the above code to be defined for example by
f(z) = c^e(-z)
(the formula is taken from a book with fractal examples)?
I know that I need to change this part of code:
function computeRow(task) {
var iter = 0;
var c_i = task.i;
var max_iter = task.max_iter;
var escape = task.escape * task.escape;
task.values = [];
for (var i = 0; i < task.width; i++) {
var c_r = task.r_min + (task.r_max - task.r_min) * i / task.width;
var z_r = 0, z_i = 0;
for (iter = 0; z_r*z_r + z_i*z_i < escape && iter < max_iter; iter++) {
// z -> z^2 + c
var tmp = z_r*z_r - z_i*z_i + c_r;
z_i = 2 * z_r * z_i + c_i;
z_r = tmp;
}
if (iter == max_iter) {
iter = -1;
}
task.values.push(iter);
}
return task;
}
But can't what z_i, z_r, c_i, c_r really means and how I could bind them to the above formula.
Any help would be greatly appreciated.

Complex number have a two part: real, imaginary.
So z = a + b*i, where a is real part, and b*i is imaginary.
In provided sample for z=z^2+c, where z=z_r+z_i*i
NOTE: i*i = -1
So z^2 = (z_r+z_i*i)*(z_r+z_i*i) = z_r*z_r+2*z_r*z_i*i + z_i*i*z_i*i = z_r*z_r+2*z_r*z_i*i - z_i*z_i
now add c: z_r*z_r+2*z_r*z_i*i - z_i*z_i + c_r + c_i*i group it
z_r*z_r+2*z_r*z_i*i - z_i*z_i + c_r + c_i*i = (z_r*z_r - z_i*z_i + c_r) + (2*z_r*z_i + c_i)*i
So we get tmp var from code - is real part of new z
tmp = z_r*z_r - z_i*z_i + c_r
and imaginary part
2*z_r*z_i + c_i
Since z = z_r + z_i * i, we need assign
z_r = z_r*z_r - z_i*z_i + c_r
z_i = 2*z_r*z_i + c_i
UPDATE: for f(z) = e^z - c
first, few complex form: x = a+b*i = |x|(cos(p)+i*sin(p)) = |x|*e^(i*p)
where |x| = sqrt(a*a + b*b) and p = b/a
in our case: p=z_i/z_r, |z| = sqrt(z_r*z_r+z_i*z_i)
e^z = e^(z_r+z_i*i) = e^z_r * (e^z_i*i) = e^z_r * (cos(p)+i*sin(p)) = (e^z_r * cos(p)) + i * (e^z_r * sin(p))
subtract c:
(e^z_r * cos(p)) + i * (e^z_r * sin(p)) - c_r - c_i*i = (e^z_r * cos(p) - c_r) + i * (e^z_r * sin(p) - c_i)
so new z
z_r = (e^z_r * cos(p) - c_r) = (e^z_r * cos(z_i/z_r) - c_r)
z_i = (e^z_r * sin(p) - c_i) = (e^z_r * sin(z_i/z_r) - c_i)

Related

brute force polynomial evaluation algorithm 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))

How to improve this code, transforming string

I am currently working on a project where I need to convert string in specific way. So, the idea is that string like this:
r[10,55]r will be converted to (Math.floor(Math.random() * (55 - 10 + 1)) + 10) - making it js value that is random from 10 to 55 (including).
and string like this: %[50;w]% will be be converted to (canvas.width / 100 * 50) - making it 50% of canvas width (w; stands for width, h; stands for height).
You can also combine these two 'functions' like this: %[r[0,50]r;h]% making it (canvas.height / 100 * (Math.floor(Math.random() * (50 - 0 + 1)) + 0)), meaning you will get from 0% to 50% of canvas height.
So, they way I'm doing it right now looks like this:
transform = function(i){
var i = i;
while(i.indexOf('r[') > -1){
var part1 = i.substring(i.indexOf('r['));
var part2 = i.substring(i.indexOf(']r') + 2);
var r = part1.substring(0,part1.length - part2.length);
var partBefore = i.substring(0,i.indexOf('r['));
var firstNumber = r.substring(r.indexOf('r[') + 2);
var comma = r.substring(r.indexOf(','));
var secondNumber = r.substring(r.indexOf(',') + 1);
firstNumber = firstNumber.substring(0,r.length - comma.length - 2);
secondNumber = secondNumber.substring(0,secondNumber.length - 2);
while(firstNumber.indexOf('%[') > -1){
var part1A = firstNumber.substring(firstNumber.indexOf('%['));
var part2A = firstNumber.substring(firstNumber.indexOf(']%') + 2);
var p = part1A.substring(0,part1A.length - part2A.length);
var partBeforeA = firstNumber.substring(0,firstNumber.indexOf('%['));
var firstNumberA = p.substring(p.indexOf('%[') + 2);
var commaA = p.substring(p.indexOf(';'));
var secondNumberA = p.substring(p.indexOf(';') + 1);
firstNumberA = firstNumberA.substring(0,p.length - commaA.length - 2);
secondNumberA = secondNumberA.substring(0,secondNumberA.length - 2);
if(secondNumberA == 'w'){ secondNumberA = 'canvas.width'; }
else if(secondNumberA == 'h'){ secondNumberA = 'canvas.height'; }
var partAfterA = firstNumber.substring(firstNumber.indexOf('%[') + p.length,firstNumber.length);
firstNumber = partBeforeA + '(' + secondNumberA + ' / 100 * ' + firstNumberA + ')' + partAfterA;
}
var partAfter = i.substring(i.indexOf('r[') + r.length,i.length);
i = partBefore + '(Math.floor(Math.random() * (' + secondNumber + ' - ' + firstNumber + ' + 1)) + ' + firstNumber + ')' + partAfter;
}
while(i.indexOf('%[') > -1){
var part1 = i.substring(i.indexOf('%['));
var part2 = i.substring(i.indexOf(']%') + 2);
var p = part1.substring(0,part1.length - part2.length);
var partBefore = i.substring(0,i.indexOf('%['));
var firstNumber = p.substring(p.indexOf('%[') + 2);
var comma = p.substring(p.indexOf(';'));
var secondNumber = p.substring(p.indexOf(';') + 1);
firstNumber = firstNumber.substring(0,p.length - comma.length - 2);
secondNumber = secondNumber.substring(0,secondNumber.length - 2);
if(secondNumber == 'w'){ secondNumber = 'canvas.width'; }
else if(secondNumber == 'h'){ secondNumber = 'canvas.height'; }
while(firstNumber.indexOf('r[') > -1){
var part1A = firstNumber.substring(firstNumber.indexOf('r['));
var part2A = firstNumber.substring(firstNumber.indexOf(']r') + 2);
var r = part1A.substring(0,part1A.length - part2A.length);
var partBeforeA = firstNumber.substring(0,firstNumber.indexOf('r['));
var firstNumberA = r.substring(r.indexOf('r[') + 2);
var commaA = r.substring(r.indexOf(','));
var secondNumberA = r.substring(r.indexOf(',') + 1);
firstNumberA = firstNumberA.substring(0,r.length - commaA.length - 2);
secondNumberA = secondNumberA.substring(0,secondNumberA.length - 2);
var partAfterA = firstNumber.substring(firstNumber.indexOf('r[') + r.length,firstNumber.length);
firstNumber = partBeforeA + '(Math.floor(Math.random() * (' + secondNumberA + ' - ' + firstNumberA + ' + 1)) + ' + firstNumberA + ')' + partAfterA;
}
var partAfter = i.substring(i.indexOf('%[') + p.length,i.length);
i = partBefore + '(' + secondNumber + ' / 100 * ' + firstNumber + ')' + partAfter;
}
return i;
};
and it has some problems..
I don't know how to identify where the , ends so I'm using ; in the %[...;...]% function instead, but that's not really a good solution, because I want to add more functions like these in the future. And I can't think of a new 'divider' every time like , ; . : obviously.
Is there a better way to do it?
let conversion = 'r[10,55]r'
let reg = /r\[([0-9]{0,3}),([0-9]{0,3})]r/
let format = (string, match1, match2) => {
return `(Math.floor(Math.random() * (${match2} - ${match1} + 1)) + ${match2})`
}
let res = conversion.replace(reg, format)
console.log(res)
let conversion = '%[50;w]%'
let reg = /%\[([0-9]{0,3});([a-z])]%/
let format = (string, match1, match2) => {
let dimension = match2 === 'w' ? 'width' : 'height'
return `(canvas.${dimension} / 100 * ${match1})`
}
let res = conversion.replace(reg, format)
console.log(res)
Here is my work around the two individual scenarios, currently working on a combined conversion scenario.
As chrisz mentions in the comments regular expressions can help out a lot. Here's how you might approach the first two (uncombined) strings using template literals to produce the output from the matched elements.
const regex1 = /r\[(\d+),(\d+)\]r/;
const str = 'r[10,55]r';
const match = str.match(regex1).slice(-2);
const out = `(Math.floor(Math.random() * (${match[1]} - ${match[0]} + 1)) + ${match[0]})`;
console.log(out);
const regex2 = /%\[(\d+);(h|w)\]%/;
const str2 = '%[50;w]%';
const match2 = str2.match(regex2).slice(-2);
const out2 = `(canvas${match[1] === 'h' ? '.height' : '.width'} / 100 * ${match2[0]})`;
console.log(out2);

Unique in generated random number (no duplicate)

I want only the generated random number will hava no duplicate, whenever i try to put the number, the generated random number has duplicate, any other idea. what should i change here?
See the fiddle
var arr = hello.toString(10).replace(/\D/g, '0').split('').map(Number);
for(i=0;i<arr.length;i++) arr[i] = +arr[i]|0;
//initialize variables
var z = arr[3];
var y = arr[2];
var x = arr[1];
var w = arr[0];
while((((a2 <= 0) || (a2 > 49)) || ((b <= 0) || (b > 49)) || ((c <= 0) || (c > 49)) || ((d <= 0) || (d > 49)) || ((e2 <= 0) || (e2 > 49)) || ((f <= 0) || (f > 49)) || ((g <= 0) || (g > 49) ))){
//loop ulit kapag hindi match yung random number sa value nung z
while( zRandomString != z){
zRandom = Math.floor(Math.random() * (109 - 100 + 1)) + 100;
zRandomRound = zRandom % 10;
zRandomString = zRandomRound.toString();
}
var zNew = zRandom; //new value ng z
document.getElementById("zebra").innerHTML = "Z = " + zNew + "<br />";// udsadsadsad
h = zNew;
while( yRandomString != y){
yRandom = Math.floor(Math.random() * (49 - 1 + 1)) + 1;
yRandomRound = yRandom % 10;
yRandomString = yRandomRound.toString();
}
var yNew = yRandom; //new value ng z
document.getElementById("yeah").innerHTML = "Y = " + yNew + "<br />";// udsadsadsad
h = h - yNew;
while( xRandomString != x){
xRandom = Math.floor(Math.random() * (h - 1 + 1)) + 1;
xRandomRound = xRandom % 10;
xRandomString = xRandomRound.toString();
}
var xNew = xRandom; //new value ng z
document.getElementById("ex").innerHTML = "X = " + xNew + "<br />";// udsadsadsad
h = h - xNew;
while( wRandomString != w){
wRandom = Math.floor(Math.random() * (h - 1 + 1)) + 1;
wRandomRound = wRandom % 10;
wRandomString = wRandomRound.toString();
}
var wNew = wRandom; //new value ng z
document.getElementById("weh").innerHTML = "W = " + wNew + "<br />";// udsadsadsad
//h = Math.abs(h - wNew); // new value of h
h = h - wNew;
a = Math.floor(Math.random() * (wNew - 1 + 1)) + 1;
a2 = wNew - a;
b = Math.floor(Math.random() * (a2 - 1 + 1)) + 1;
c = a - b;
d = yNew;
e = Math.floor(Math.random() * (xNew - 1 + 1)) + 1;
e2 = xNew - e;
f = Math.floor(Math.random() * (e2 - 1 + 1)) + 1;
g = e - f;
}
var combo = a2.toString() + ', ' + b.toString() + ', ' + c.toString() + ', ' + d.toString() + ', ' + e2.toString() + ', ' + f.toString() + ', ' + g.toString() + ', ' + h.toString();
document.getElementById("combo").innerHTML = combo;
Try to use this scheme:
var r;
do {
r = Math.floor(Math.random() * 10);
} while (r == 6);
It is not quite clear what you want, but one way to create a sequence on unique random numbers is to create a pool of numbers and sucessively pick and remove items from it:
function pick(pool) {
if (pool.length == 0) return undefined;
// pick an element from the pool
var k = (Math.random() * pool.length) | 0;
var res = pool[k];
// adjust array
pool[k] = pool[pool.length - 1];
pool.pop();
return res;
}
// example
var pool = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
while (pool.length) {
console.log(pick(pool));
}
Another method is to shoffle the pool first and then pop off elements:
function shuffle(arr) {
var n = arr.length;
while (n) {
// pick element
var k = (Math.random() * n--) | 0;
// swap last and picked elements
var swap = arr[k];
arr[k] = arr[n];
arr[n] = swap;
}
}
var pool = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
shuffle(pool);
while (pool.length) {
console.log(pool.pop());
}
These two methods aren't very different if you look at the pick and shuffle functions. Of course, eventually you will exhaust the pool. You can then decide to recreate or reshuffle the array. Also note that these methods will produce repeated elements if the pool has repeated entries.

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;

Refactor a for() loop using Math.pow()?

Here's a question that I'm hoping will improve my programming chops. I have this loop that is calculating a future sum based on annual payments, increased by interest and devalued by inflation (it's derived from the PV function in Excel):
var pmt = 66,449.75 // annual payment
var ip = 0.03 // interest rate
var fv = 0 // future value, not require here
var k = 1 // interest is applied at beginning / end of period
var n = 25 // number of periods (years in this case)
var ri = 0.025 // rate of inflation
var pv = 0;
for (var i = n - 1; i >= 0; i -= 1) {
pv = (pv + (pmt * k - fv) * Math.pow(1 + ri, i)) / (1 + ip);
}
Is it possible to use Math.pow() to reproduce what this loop is doing?
To simplify, I rename some expressions
a = pmt * k - fv;
b = 1 + ri;
c = 1 + ip;
x = pv;
So your code becomes
for (var i = n - 1; i >= 0; --i) {
x = x / c + a * Math.pow(b, i) / c;
}
Then
x_0
x_1 = x_0 / c + a b^{n-1} / c
x_2 = x_1 / c + a b^{n-2} / c = x_0 / c^2 + a b^{n-1} / c^2 + a b^{n-2} / c
...
x_i = x_{i-1} / c + a b^{n-i} / c = x_0 / c^i + \sum_{k=1}^i a b^{n-k} / c^{i-k+1}
...
x_n = x_0 / c^n + \sum_{k=1}^n a * b^{n-k} / c^{n-k+1}
According to WolframAlpha,
x_n = x_0 / c^n + a (b^n-c^n) / (c^n (b-c))
Therefore, instead of your loop you can use
var foo = Math.pow(1 + ip, n); // c^n
pv = pv / foo + (pmt*k-fv) * (Math.pow(1+ri,n) - foo) / foo / (ri-ip);

Categories

Resources