ram6ler / function-tree

A simple dart library for parsing strings into callable function-trees.
MIT License
23 stars 11 forks source link

The "log" function, is not log in base 10 #4

Closed titoworlddev closed 3 years ago

titoworlddev commented 3 years ago

I think that '' log '' does not work well, because when I use it it does the same as "ln" that is; ln (6) = 1.791759469228055 log (6) = 1.791759469228055

This should not be the case, if ln is logarithm to base e that is fine, but log I understand that it is logarithm to base 10 and therefore it should be; ln (6) = 1.791759469228055 log (6) = 0.77815125038364363250876679797961

Therefore "ln" works perfectly but "log" does not.

Maybe I do not use it well but I am using it as I put in the example and that way it works well for me in all calculators.

If I am not using it well I would like you to explain how to do it.

ram6ler commented 3 years ago

Thanks for your interest in this library!

I am aware of (and personally like) the convention to use log for base-10 logarithms and ln for base-e logarithms that you're referring to, but the more general convention is to use log to mean base-e logarithms. Many math libraries — including dart:math — use log to mean the base-e logarithm, which is why I stuck to this convention. I only included support for ln because it is a common alias for log.

If you'd like to create a base-10 log function-tree, use the two-parameter function log(base, x) pattern. For example:

final myLog10 = 'log(10, x)'.toSingleVariableFunction();

I hope that helps!

titoworlddev commented 3 years ago

Thanks, that helps a lot. The problem I see is that I am Spanish and from what I see in other countries it is said differently, because here "log" generally refers to a logarithm in base 10 and "ln" to a logarithm in base e, they are not the same. Also tell you thanks for the example, but the problem I have is that I want to use it that way inside a string and then use the .interpret () function, would that be possible in any way?

titoworlddev commented 3 years ago

I have tried that example, which you tell me and it does not let me put the variable x, that is, if I put:

final myLog10 = 'log (10, x)'. toSingleVariableFunction ();
print (myLog10 (10));

the result of print is:

Exception caught by gesture ═══════════════════════════════════════════
The following _Exception was thrown while handling a gesture:
Exception: Bad expression: '10x' ...

When the exception was thrown, this was the stack
# 0 _parseString
package: calculateme_app /… / src / interpreter.dart: 198
# 1 _parseString
package: calculateme_app /… / src / interpreter.dart: 92
# 2 _parseString
package: calculateme_app /… / src / interpreter.dart: 106
# 3 new SingleVariableFunction
package: calculateme_app /… / src / trees.dart: 54
# 4 StringMethods.toSingleVariableFunction
package: calculateme_app /… / src / extensions.dart: 22
...
Handler: "onTap"
Recognizer: TapGestureRecognizer # 7a53a
    debugOwner: GestureDetector
    state: possible
    won sand
    finalPosition: Offset (250.0, 763.0)
    finalLocalPosition: Offset (45.8, 33.5)
    button: 1
    sent tap down
══════════════════════════════════════════════════ ════════════════

And if instead of that I put:

final myLog10 = 'log (10, 10)'. toSingleVariableFunction ();
print(myLog10(10));

or

final myLog10 = 'log (10, x)'. toSingleVariableFunction ();
print(myLog10(10));

or

final myLog10 = 'log (10, x)'. toSingleVariableFunction ('x');
print(myLog10(10));

or

final myLog10 = 'log (10, 10)'. interpret ();
print (myLog10);

It still does not give a good result like log in base 10, since its result is: 6.917705609835305 and it should be 1, since if the result of the logarithm in base 10 is the number of times we should raise 10 to give us the value of x 10 ^ 10 = 1. Or put another way, log (10) = 1. Or even, log10 (10) = 1

titoworlddev commented 3 years ago

Hello again, I've been looking at your package, and I've found the _functionMap, if I'm not mistaken that's where you say what "log" refers to within the string when using the .interpret () function. I mean this map:

final Map <String, Function> _functionMap = {
  'abs': (num x) => x.abs (),
  'accos': accos
  'asin': asin,
  'atan': atan,
  'ceil': (num x) => x.ceil (),
  'cos': cos,
  'cosh': (num x) => (pow (e, x) + pow (e, -x)) / 2,
  'cot': (num x) => 1 / tan (x),
  'coth': (num x) => (pow (e, x) + pow (e, -x)) / (pow (e, x) - pow (e, -x)),
  'csc': (num x) => 1 / sin (x),
  'csch': (num x) => 2 / (pow (e, x) - pow (e, -x)),
  'exp': exp,
  'floor': (num x) => x.floor (),
  'ln': log,
  'log': log,
  'round': (num x) => x.round (),
  'sec': (num x) => 1 / cos (x),
  'sech': (num x) => 2 / (pow (e, x) + pow (e, -x)),
  'sin': sin,
  'sinh': (num x) => (pow (e, x) - pow (e, -x)) / 2,
  'sqrt': sqrt,
  'so so,
  'tanh': (num x) => (pow (e, x) - pow (e, -x)) / (pow (e, x) + pow (e, -x))
};

I know that to get the logarithm in any base it can be done like this;

log (x) / log (y)

where x = the number of which you want to take the logarithm and y = the base of the logarithm, in this case 10 which is what I want.

I have tried changing the map where "log" is defined on my own like this:

'ln': log,
  'log': (num x) => log (x) / log (10),
  'round': (num x) => x.round (),

but it has not worked for me, the result is the same as if I put print ('log (6)'. interpret ()); // 1.791759469228055

I have even tried this:

'ln': log,
  'log': log,
  'log10': (num x) => log (x) / log (10),
  'round': (num x) => x.round (),

but it doesn't work either.

I know that something like this could be added to make it work well, but since I don't know exactly how the package is created I can't help with that. Even so I wish you could add it, that would be very helpful for me, as well as make the package even more complete than it already is.

ram6ler commented 3 years ago

Hi Hekhy,

I won't say anything about your style choice to put spaces before function parentheses. :)

It's strange: I can't reproduce your error. When I copy-and-paste your code,

final myLog10 = 'log (10, x)'. toSingleVariableFunction ();
print (myLog10 (10));

my output is:

1.0

Also, you're right about the organization of the function-mapping in defs.dart. If I change the map in defs.dart to:

.
.
.
  'ln': log,
  'log': (num x) => log (x) / log (10),
  'round': (num x) => x.round (),
.
.
.

then log behaves like a base-10 log function, as you expected. For example,

print('log(10)'.interpret());

outputs

1.0

It must be something on your end. From the error messages, it looks as though the comma is possibly being lost somehow: is your app manipulating the string before feeding it to the function-tree interpreter maybe?

titoworlddev commented 3 years ago

Hi @ram6ler ,

Do not take into account the spaces before the parentheses, I do not do that like that, but when I translate my answer in the google translator automatically he adds spaces, but I need to translate it because I don't know much English.

Beyond that, I have already solved it, I had a problem with the installation of the packages, I don't know what could have happened but I decided to try to create a new project and migrate my code there and then magically it worked.