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>
Related
I am learning Javascript currently.I was wondering if there is any difference between:
var factor=0.1;
var limit=10;
var x;
var y;
x= limit*factor;
y= limit*factor;
//or
var limit=10;
var x;
var y;
x=limit *0.1;
y=limit*0.1;
Does it make any difference (when looking at performance for example)? If so, why it is different? The second example looks less promising to me, because I keep thinking that I am declaring the variable 0.1 twice. Thanks for your help in advance.
There is a very small difference. When you use factor in the two multiplications, the JavaScript engine has to go look up the value of factor in the current lexical environment object each time — in theory, anyway; optimization may well be able to get rid of that, if and when the code is chosen for optimization by the JavaScript engine.
But regardless: Worry about performance problems when you have a performance problem to worry about. Instead, concentrate on readability and maintainability. If x and y are meant to be multiplied by the same value, put that value in something (a var, or perhaps a const with ES2015+), and use it in both places.
I would suggest you go ahead with the first example, but with a modification. Variables are meant to hold dynamic data, it is better to hold 0.1 in a variable, so you can change it over time if required.
// have a function so that you don't repeat the code
function getFactor(factor, limit) {
return limit * factor;
}
//declare the variables and set the required default values
var factor = 0.1,
limit = 10,
x, y;
//assign getFactor to x and y variables
x = y = getFactor(factor, limit);
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'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)
I have created a Chrome extension that can draw the graph of the math equation user has inputted. To get the value of y easily, I used eval() (Yes I know it is bad) because the easiest way to achieve it.
var equ = $("#equ1").val(); //some element
//let's say equ = "2(2^x) + 3x"
//some magic code
//equ becomes "2*(pow(2,x))+3*x"
for(var x = -10; x < 10; x++){
var y = eval(equ.replace(/x/ig, x)); //calculate y value
drawPoint(x, y);
}
console.log("Graphing done.");
However, because of the new manifest version 2, I can't use eval anymore. I can't think of any way to manipulate the string. Any idea?
The clean way: You could try parsing the expression using Jison and building an AST from the input string. Then, associate functions with the AST node that apply the operations that the nodes represent to data given to them. This would mean that you have to explicitly put every math expression that you want to support in your grammar and your node code, but on the other hand, this would also make it easier to support mathematical operators that JS doesn't support. If you're willing to invest some time, this probably is the way to go.
The dirty way: If your extension is used on normal websites, you might be able to do some kind of indirect eval by injecting a <script> element into the website or so – however, that would likely be insecure.
Did you try New Function() ... ??
var some_logic = "2*(Math.pow(2,x))+3*x";
args = ['x', 'return (' + some_logic + ');'];
myFunc = Function.apply(null, args);
for (var x = -10; x < 10; x++) {
var y = myFunc(x);
console.log(x, y);
}
console.log("Graphing done.");
Fiddle - http://jsfiddle.net/atif089/sVPAH/
Is there a JavaScript library or function that will solve equations for variables?
Such as 9 = 3 + x and solve for x. But it should also solve more advanced equations that include sine, cosine, and tangent.
I'd like to propose nerdamer. It can algebraically solve up to quartic functions and it can numerically solve a range of functions. Another library to consider is Algebrite.
//solve linear equations
var x = nerdamer.solve('(x+1)*3=x-6', 'x');
console.log(x.toString());
//quadratic
var x2 = nerdamer.solve('x^2-8x+15', 'x');
console.log(x2.toString());
//quadratic algebraically
var x3 = nerdamer.solve('x^2-ax+3*b', 'x');
console.log(x3.toString());
//multiple roots
var x4 = nerdamer.solve('x^6+41*x^5+652*x^4+5102*x^3+20581*x^2+40361*x+30030', 'x');
console.log(x4.toString());
//functions - numerically around to zero up to a predefined range
var x5 = nerdamer.solve('cos(x)^2+sin(x-1)', 'x');
console.log(x5.toString());
//solve a system of linear equations
var x6 = nerdamer.solveEquations(['2x+y=7', 'x-y+3z=11', 'y-z=-1']);
console.log(x6.toString());
//solve a system of nonlinear equations
var x7 = nerdamer.solveEquations(['3*x^2/y=2', 'z*x*y-1=35', '5*z^2+7=52']);
console.log(x7.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/Solve.js"></script>
You can approximate the solution by doing what excel calls "Goal Seek" - testing values for x until both sides of the equation approximately match. You can do this by splitting the equation by the "=" sign, replacing each occurence of x with a value, evaling both sides, and determining if the difference falls below a certain threshold. While relatively simple, there are flaws to this method though (other than the fact that it is an approximation), for example the algorithm may think the two sides are converging when in fact it is just a local min/max and will diverge after the difference falls just below your threshold. You'll also need to test multiple start points to solve equations with more than one solution.
For a program to actually solve an equation as a human would (by rearranging the two sides of the equation and applying inverse functions, derivatives/integrals and whatnot) is far more complex, and somehow feels entirely proprietary ;)
A quick search turns up algebra.js and js-solver. I don't know anything about them, but they seem legit. algebra.js has a nice OOP API, but doesn't appear to handle trigonometric functions.
Look at the script at Newton's Method Program for f(x)=0. It solves the equation using Newton's tangent method.
Ceres.js can find the solution to an array of equations of the form f(x) = 0. It is ported from C++ to JavaScript with Emscripten. The file is a bit large but if you need a really high performance solver this is your best bet. It runs in web-assembly so the speed is high.
Here is an example:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
<h2>Powell Function</h2>
<p>This is an example of the solution of the powell function using Ceres.js</p>
<textarea id="demo" rows="40" cols="170">
</textarea>
<script type="module">
import {Ceres} from 'https://cdn.jsdelivr.net/gh/Pterodactylus/Ceres.js#master/Ceres-v1.5.3.js'
var fn1 = function f1(x){
return (x[0]+10*x[1]);
}
var fn2 = function f2(x){
return (Math.sqrt(5)*(x[2]-x[3]));
}
var fn3 = function f3(x){
return Math.pow(x[1]-2*x[2],2);
}
var fn4 = function f4(x){
return Math.sqrt(10)*Math.pow(x[0]-x[3],2);
}
let solver = new Ceres()
solver.add_function(fn1) //Add the first equation to the solver.
solver.add_function(fn2) //Add the second equation to the solver.
solver.add_function(fn3) //Add the third equation to the solver.
solver.add_function(fn4) //Add the forth equation to the solver.
//solver.add_callback(c1) //Add the callback to the solver.
//solver.add_lowerbound(0,1.6) //Add a lower bound to the x[0] variable
//solver.add_upperbound(1,1.7) //Add a upper bound to the x[1] variable
solver.promise.then(function(result) {
var x_guess = [1,2,3,4] //Guess the initial values of the solution.
var s = solver.solve(x_guess) //Solve the equation
var x = s.x //assign the calculated solution array to the variable x
document.getElementById("demo").value = s.report //Print solver report
solver.remove() //required to free the memory in C++
})
</script>
</body>
</html>