I'm looking for a Computer Algebra System to run in a browser, with a particular interest in finding roots to systems of equations.
I'm currently evaluating Coffeequate.
The simplest non-trivial system I came up with that wasn't on the demo page was a system of two simultaneous linear equations:
var exp1 = CQ('x = 2 * y + 6');
var exp2 = CQ('x - y = 10');
exp2.sub({x: exp1.solve('x')})
.solve('y');
Unfortunately, this hangs at the sub call.
What I would like to obtain is the value for all unknowns (i.e. x and y) that are knowable – there is guaranteed to be a solution in this case.
What am I doing wrong here?
CQ().solve returns an array of solutions (in case there are multiple solutions). However, things that you want to substitute in using CQ().sub have to be integers or CQ() objects themselves. The following code works:
var exp1 = CQ('x = 2 * y + 6');
var exp2 = CQ('x - y = 10');
exp2.sub({x: exp1.solve('x')[0]}).solve('y'); // 4
The fact that it actually hangs instead of erroring when you pass in an array is a bug; I'll patch that.
(Disclaimer: I wrote Coffeequate)
Related
I've been working with the algebra.js JavaScript library for a while and I can't find an answer to my problem.
I have a number of equations that varies in type;
(Linear, Radical, Quadratic, and Exponential)
And I need to switch the sides of two or more variables.
An example to the solution would be in a linear equation as follows:
x = 2y - 6 ----> y = (x/2) + 3
This simple example works because the x is in the simplest form and the equation is linear. However, when the equation looks like this:
7a + 4b = 9c + 5d
and I want to move the 9c to the left in order for it to look like this:
9c = 7a + 4b - 5d
It can't be done.
Moreover, these are all linear examples which makes them simple to process without using the library. But when it comes to an equation that looks like this:
y = z*(a^x)*b^(1-x)
and I want the left side to be (a^x), it doesn't seem that there is a way to do it.
So, is there any way to transfer a variable or a term to be alone in one side of the equation regardless to solving an equation?
It doesn't have to be algebra.js. It can be any library or code using JavaScript.
Have you read thru algebra.js documentation already? There is a direct statement how to do this -- see solve linear equation chapter, multiple variables subchapter, and its example:
var eq = new Equation(...)
var xAnswer = eq.solveFor("x");
var yAnswer = eq.solveFor("y");
Same solveFor() applies to other equation types as well.
I'm trying to adapt some equations (implicit f(x,y)) in order to be able list the Y for corresponding X-Value.
The equations could be e.g. as follows:
y^2 = x^3 + 2x - 3xy
(X^2+y^2-1)^3-x^2y^3=0
X^3+y^3=3xy^2-x-1
X^3+y^2=6xy/sqrt(y/x)
cos(PI*Y) = cos(PI.X)
Below you can see the plotted equations:
Hint, I don't know, but maybe this can be helpful, the following applies:
Y^2 + X^2 =1 ==> Y= sqrt(1-X^2)
The equations are to be adapt (substitution), so that they are expressed by X (not Y).
For y^2=x^3+2x-3xy by means of substitution results:
y1 = (-(-3x) - sqr((-3x)^2 - 4(-1)(x^3+2x)))/2*(-1)
y2 = (-(-3x) + sqr((-3x)^2 - 4(-1)(x^3+2x)))/2*(-1)
By means of adapted equations I will be able to vary X and get the corresponding Y.
See here the solution of Arkadiusz Raszeja-Solution for the equation y^2=x^3+2x-3xyThe solution of "Arkadiusz Raszeja" is for Quadratic equation, but I need an algorithm, so that e.g. all above equations can be solved.
var x,y;
for(var n=0; n<=10; n++) {
x=n;
y = (-(-3*x)-Math.sqrt(((-3*x)*(-3*x)) - 4*(-1)*((x*x*x)+2*x)))/(2*(-1));
alert(y);
}
The above alert(y); will show for Y something like below list:
X= 1 ; Y=0.79
X=2 ; Y=1.58
X=3 ; Y=2.79
X=4 ; Y=4.39
X=5 ; Y=6.33
X=6 ; Y=8.57
X=7 ; Y=11.12
X=8 ; Y=13.92
X=9 ; Y=16.98
X=10 ; Y= 20.29
My question is how can I program an algorithm, which will adapt (solve) the equations like in above example?
(You can also use a JS library like math.js, but not a plot or graph library. The solution should be in javascript)
Thanks in advance.
Hopefully I'm understanding your question correctly. Would nerdamer help? It can help solve algebraically up to a 3rd degree polynomial. The buildFunction method can be called to get a JS function which can be used for graphing. I use it in a somewhat similar manner on the project website in combination with function-plot.js
var solutions = nerdamer('y^2=x^3+2x-3x*y').solveFor('y');
//You'll get back two solutions since it's quadratic wrt to y
console.log(solutions.toString());
//You can then parse the solutions to native javascript function
var f = nerdamer(solutions[0]).buildFunction();
console.log(f.toString());
/* Evaluate */
var solutions = nerdamer('y^3*x^2=(x^2+y^2-1)').solveFor('y');
console.log(solutions.toString());
//You can then parse the solutions again to native javascript function
var f = nerdamer(solutions[0]);
var points = {};
for(var i=1; i<10; i++)
points[i] = f.evaluate({x: i}).text();
console.log(points)
<script src="http://nerdamer.com/js/nerdamer.core.js"></script>
<script src="http://nerdamer.com/js/Algebra.js"></script>
<script src="http://nerdamer.com/js/Calculus.js"></script>
<script src="http://nerdamer.com/js/Solve.js"></script>
You could always just evaluate. This is slower than a pure JS function but it might be what you need. You'll have to probably use a try catch block for division by zero.
I'd like to point out that this problem cannot be solved exactly in general. The cited solution for the quadratic case (y^2) can be extended to the cubic case and quartic case (there are a general complicated solutions). But there is a math theorem (from Galois theory) that states that there is no general solution for the quintic equation (and so on). In your case, maximum degree is 3, so you can use the cubic equation from wikipedia. For the heart graphic write: x^2*y^3 - y^2 -(x^2-1) = 0 and treat x as constant. For the sqrt case, get rid of it. Square both sides of equation, isolate y and you end up with a quartic equation on y, that you can solve using wikipedia's quartic equation knowledge.
Anyway, if you don't have a very strong reason to do this, don't do it, as the computer can solve this numerically for you. Standard approach is to calculate this implicitly, as in the plots you made.
I hope this helps.
There ia a possible solution for the general quintic equation, when you addapt the solutionmethod from Cardano for the general cubic equation and the solutionmethod from Ferrari for the general quartic equation.
I have this code to calculate whether this circle intersections with another circle. I want a faster version, is that possible?
this.CheckIntersection = function(another){
var xC = this.x;
var yC = this.y;
var GxC = another.x;
var GyC = another.y;
var distSq = (xC - GxC) * (xC - GxC) + (yC - GyC) * (yC - GyC);
return distSq < (this.r + another.r) * (this.r + another.r);
}
Well you can try to improve this a little bit as follows:
this.CheckIntersection = function(another){
var dx = this.x-another.x;
var dy = this.y-another.y;
dx = dx*dx+dy*dy;
dy = this.r+another.r;
return dx < dy*dy;
}
This will be a bit faster since you save some subtractions, and you use less variables so the runtime environment will have an easier job with register allocation/caching.
But in terms of time complexity there is not much you can do. So you are limited to peephole optimization like for instance looking for duplicated computation and try to compute them only once.
If you have many such checks, it might make sense to offload them to the GPU. The GPU should be able to do more of them in parallel, but you pay a bit more because you need to copy data to/from GPU. There's not much to do complexity wise.
Nvidia's cuda is a good starting point, but there are other libraries.
If you ask for a faster test, you probably identified a bottleneck there, meaning that you must be using this function intensively.
For a test of a single circle against a single other, there is about nothing that you can reduce. The test essentially takes 3+/2* to compute a squared Euclidean distance and a comparison to a term obtained with 1+/1*. There is nothing you can remove, and the code is so tiny that you probably pay more for the interpreter overhead than for the operations themselves.
Things can become more interesting, and potential gains much higher, if you have to test a moving circle against N fixed circles, or, better, N circles against each other.
I have a formula with several components, let's say w = x * y / z^2 + c. Now I have an input-field for each variable. My goal is, to calculate the missing one as soon, as all the others were entered. Difficulty is, that you can choose which fields you fill and which you want to leave free.
The easy (naive) way would of course be to resolve it for each variable by hand, detect the missing var, and have seperate js functions for each case. But I even have linked formulas (like x in the above formula is x = a + b, too) as well and the options are almost infinitive. Is there any option in JS to solve a formula by a specified variable? I could then replace each variable string with the assigned value and then eval the string.
First I thought Nerdamer would be the thing, but it turned out that it can only evaluate expressions and can't handle equations.
Is this possible? Any better idea?
Thanks in advance!
P.S.: My actual set of formula is:
dR = c * I^2 / A
R = L * dR
P = I * U
DV = R * I
DW = DV * I
It's for calculating losses in a cable due to ohm's resistance. Each Variable has a corresponding input field.
The following solution can be built for finding "R" using nerdamer. The logic can be extended to solve for the remaining variables. Do keep in mind that the current limitation is that nerdamer can currently only solve up to cubic functions algebraically. Higher order functions will be solved numerically.
//You can then take care of the non linear containing I. I is quadratic
var dR = nerdamer('R=L*dR').solveFor('dR');
var I = nerdamer('dR=c*I^2/A').sub('dR', dR).solveFor('I');
//You can first start by reducing the first few equations since they are linear and you can solve them as a linear system
var solutions = nerdamer.solveEquations(['P = I * U', 'DV = R * I', 'DW = DV * I'], ['I', 'DW', 'P']);
//the solutions come back as an array arrays in the form of [variable, value]
//you can see what they look like. In your case all your solutions will be in terns of DV & U since these are the only actual knowns
//You can see what the solutions look like
solutions.map(function(x) {
console.log('-'+x[0]+' = '+x[1]);
});
console.log('------------------ R ----------------');
var R = nerdamer.setEquation(I[0], solutions[0][1]).solveFor('R');
//I will have 3 solutions since it's cubic. You can console.log them below
R.map(function(x) {
console.log('R = '+x.toString());
});
<script src="https://cdn.jsdelivr.net/npm/nerdamer#latest/nerdamer.core.js"></script>
<script src="https://cdn.jsdelivr.net/npm/nerdamer#latest/Algebra.js"></script>
<script src="https://cdn.jsdelivr.net/npm/nerdamer#latest/Calculus.js"></script>
<script src="https://cdn.jsdelivr.net/npm/nerdamer#latest/Extra.js"></script>
<script src="https://cdn.jsdelivr.net/npm/nerdamer#latest/Solve.js"></script>
I’m having problems generating normally distributed random numbers (mu=0 sigma=1)
using JavaScript.
I’ve tried Box-Muller's method and ziggurat, but the mean of the generated series of numbers comes out as 0.0015 or -0.0018 — very far from zero!! Over 500,000 randomly generated numbers this is a big issue. It should be close to zero, something like 0.000000000001.
I cannot figure out whether it’s a method problem, or whether JavaScript’s built-in Math.random() generates not exactly uniformly distributed numbers.
Has someone found similar problems?
Here you can find the ziggurat function:
http://www.filosophy.org/post/35/normaldistributed_random_values_in_javascript_using_the_ziggurat_algorithm/
And below is the code for the Box-Muller:
function rnd_bmt() {
var x = 0, y = 0, rds, c;
// Get two random numbers from -1 to 1.
// If the radius is zero or greater than 1, throw them out and pick two
// new ones. Rejection sampling throws away about 20% of the pairs.
do {
x = Math.random()*2-1;
y = Math.random()*2-1;
rds = x*x + y*y;
}
while (rds === 0 || rds > 1)
// This magic is the Box-Muller Transform
c = Math.sqrt(-2*Math.log(rds)/rds);
// It always creates a pair of numbers. I'll return them in an array.
// This function is quite efficient so don't be afraid to throw one away
// if you don't need both.
return [x*c, y*c];
}
If you generate n independent normal random variables, the standard deviation of the mean will be sigma / sqrt(n).
In your case n = 500000 and sigma = 1 so the standard error of the mean is approximately 1 / 707 = 0.0014. The 95% confidence interval, given 0 mean, would be around twice this or (-0.0028, 0.0028). Your sample means are well within this range.
Your expectation of obtaining 0.000000000001 (1e-12) is not mathematically grounded. To get within that range of accuracy, you would need to generate about 10^24 samples. At 10,000 samples per second that would still take 3 quadrillon years to do...this is precisely why it's good to avoid computing things by simulation if possible.
On the other hand, your algorithm does seem to be implemented correctly :)