jiggzson / nerdamer

a symbolic math expression evaluator for javascript
http://www.nerdamer.com
MIT License
517 stars 82 forks source link

Compute the reverse of an expression #529

Closed yboujraf closed 4 years ago

yboujraf commented 4 years ago

Dear @yosuke , @Yaffle , @DouglasdeMoura , @selairi , @jiggzson

I am looking to compute the reverse on an expression.

Use case :

$ is the output value for example of a sensor and the manufacturer gives us the expr1 as formula to convert the $ to a display value for the user

But when the user wants to interact with the sensor, he needs to translate the display value to an expr2 to be sure the sensor could interpret the value.

That's my example :

The user write the expr1 and the library compute the reverse of the expr1 to expr2 expr1 = 1 + log($, 2) expr2 = 2^($ - 1)

expr1 = sin($ / 7.43) where $ is of type INTEGER expr2 = int(7.43 * asin($))

expr1 = $ - log($ / (e^(-$) * $^sin(1 / $)), 10) expr2 = exercise left to the reader

Thanks in advance if you could help us to find a solution of our issue.

Best Regards Youssef

Happypig375 commented 4 years ago

solve(y=1+log(x,2),x) => [e^(-1+y)] (bug in solve that does not take base into account) solve(y=sin(x / 7.43),x) => [(743/100)*asin(y)] (why limit the answer to an integer?) solve(y=x- log(x / (e^(-x) * x^sin(1 / x)), 10),x) => [] (solve needs improvement)

Happypig375 commented 4 years ago

Strangely, I cannot get any math solver online to solve y=x- log(x / (e^(-x) * x^sin(1 / x)), 10), even Wolfram Alpha refuses to do it. Is this even solvable?

yboujraf commented 4 years ago

@Happypig375

6 years ago, I did it with F# but microsoft OS and each time they release the software version the code didn't work and need to be rebuild it with new framework, too much time.

Otherwise there is mathjs ( https://github.com/josdejong/mathjs ) could parse expr1 and compute it but not reverse the expr1. The owner of the repo said it could be done easily but no time ;-)

Best regards, Youssef

Yaffle commented 4 years ago

solve(y=1+log(x,2),x) => [e^(-1+y)] (bug in solve that does not take base into account)

https://github.com/jiggzson/nerdamer/blob/master/Solve.js#L1334

-                                rhs = _.divide(_.subtract(_.pow(new Symbol('e'), _.divide(rhs, _.parse(lhs.multiplier))), parts[3]), parts[0]);
+                                rhs = _.divide(_.subtract(_.pow(lhs.args.length > 1 ? lhs.args[1] : new Symbol('e'), _.divide(rhs, _.parse(lhs.multiplier))), parts[3]), parts[0]);
jiggzson commented 4 years ago

@Yaffle, thanks for the fix!

solve(y=sin(x / 7.43),x) => [(743/100)*asin(y)] (why limit the answer to an integer?)

@Happypig375, you're right. The only problem with periodic solutions is that we have a to have a clear way of notifying the user that the solutions is in this form. Or a breaking change where the solution is returned as an object with additional information about the solution?

Strangely, I cannot get any math solver online to solve y=x- log(x / (e^(-x) * x^sin(1 / x)), 10), even Wolfram Alpha refuses to do it. Is this even solvable?

I don't think this equation is solvable. Take a look at the graph.

6 years ago, I did it with F# but microsoft OS and each time they release the software version the code didn't work and need to be rebuild it with new framework, too much time.

@yboujraf, are you talking about the other equations are the one depicted in the graph? Additionally, is the assumption that is being made here, which is that the reverse of the equation is the solutions to equation correct?

yboujraf commented 4 years ago

Dear @jiggzson

A Glow formula is a tuple of two mathematical expressions, each of which applies a projection to one input value (referred to as $ in the syntax).

The two expressions must have the following mathematical relationship:

expr2(expr1($)) = $ = expr1(expr2($))

The user write the expr1 and the library compute the reverse of the expr1 to expr2 expr1 = 1 + log($, 2) expr2 = 2^($ - 1)

expr1 = sin($ / 7.43) where $ is of type INTEGER expr2 = int(7.43 * asin($))

expr1 = $ - log($ / (e^(-$) * $^sin(1 / $)), 10) expr2 = exercise left to the reader

I will send the use case

Best Regards, Youssef

yboujraf commented 4 years ago

Dear @jiggzson , @Happypig375 , @Yaffle

This is my use case :

Formulas ( Rx / Tx)

INPUT RANGE

• I have an Analog to Digital convert 12 bits (4096 positions) • The manufacturer of the A/D converter infor you for 0 = -128dB and for 4095 = +15 dB

Knowing two coordinates, I can calculate the line : y = m.x +b where m is the slope and b could be calculate by replacing x, y by one of the point of the line and reverse is easy.

=> But if I need in logarithmic, I forgot how to calculate it?

I am looking to create as above "Formula" with possibility to select linear or log the Rx and Tx formula.

image

Manually introduce expression received by the manufacturer of a sensor:

image

To follow the ifSpeed example, let’s display the speed of the interface in megabytes per second instead of bits per second:

image

Data model of my parameter

{
                    "identifier": "ParameTypeStream",
                    "description": "Stream PPM MAIN",
                    "value": 0,
                    "minimum": -4096,
                    "maximum": 480,
                    "access": "read",
                    "format": "%8.2f°",
                    "enumeration": "",
                    "factor": 1,
                    "isOnline": true,
                    "default": -1024,
                    "type": "integer",
                     "formula": "32/\n32*"
                }

Properties

"formula": "32/\n32*"

That means when the client receives this properties the "/n" is the separation from RX formula and TX formula then no needs two properties

Here :

RX = $ /32 TX = $ *32

If $ = -4096 RX = -128

if $ = -128 Tx = -4096

Conclusion

A Glow formula is a tuple of two mathematical expressions, each of which applies a projection to one input value (referred to as $ in the syntax).

The two expressions must have the following mathematical relationship:

Tx(Rx($)) = $ = Rx(Tx($))

The user write the RX and the library compute the reverse of the RX to Tx or vice-versa Rx = 1 + log($, 2) Tx = 2^($ - 1)

Rx = sin($ / 7.43) where $ is of type INTEGER (because define in the properties but if could double this is not an issue) Tx = int(7.43 * asin($))

Rx = $ - log($ / (e^(-$) * $^sin(1 / $)), 10) Tx = exercise left to the reader

I hope this is clear.

I am sure gent you will be to solve it and help for this use case where I lost my black hair to white.

Best Regards, Youssef

Happypig375 commented 4 years ago

@yboujraf You cannot assume that any formula can be inverted and give a single answer. For example, when RX($) = $^2, TX($) = {sqrt($), -sqrt($)}.

There are even instances where the equation is straight-up non-invertible. When RX($) = 0, TX($) = (any number).

How will you deal with these cases?

yboujraf commented 4 years ago

Dear @Happypig375

Good point.

When RX($) = 0, TX($) = (any number).

This use case will never happen where Rx($)=0.

As written above,

Two use cases :

  1. I got two points and I need to calculate the line

    • Need to define is it is linear or log
  2. I receive from the manufacturer (Rx($) or Tx($).

That's all.

I hope it will help you.

Best Regards Youssef

Happypig375 commented 4 years ago

So solve is what you are looking for. Just replace $ with x, set the formula to equal y, use solve to find x, and then replace x with $.

yboujraf commented 4 years ago

@Happypig375

Sorry I have not understood what you mention in you last message.

May I ask you to share an example of code ?

It will be great

Best Regards, Youssef

Happypig375 commented 4 years ago

-> https://nerdamer.com/functions/solve.html

@jiggzson The Usage section of the three solve functions have an unneeded nerdamer("") around the intended usage.

yboujraf commented 4 years ago

@Happypig375

To be honest I am lost.

Do you have any sample code then I will install the repository on my laptop to test it?

Best Regards, Youssef

Happypig375 commented 4 years ago

https://nerdamer.com/demo.html image