Jump to content

Recommended Posts

Thanks for pointing out that typo.

I will definitely add the multi-variable multi-expression evaluation function to the mupExpr class. I am also planning to add bulk mode eval.

The last thing I was working on was to put the mupExpr inside a DVR. I did this because I was worried about the case of splitting the mupExpr wire, calling destruct on one of them, then continuing to use the other. This could cause labview to crash because its variable pointers and muparser handle have been released. Of course, putting everything inside a DVR slows things down a bit but I think that it might be worth it to avoid a crash. The other option is single element queue(s) to store the variable pointers and muparser handle. Not sure if this would reduce the performance hit though. Haven't tried yet.

Unfortunately I've been sidetracked by home renovations. I'm going to continue development on this project soon though.

Link to comment
29 minutes ago, Porter said:

I did this because I was worried about the case of splitting the mupExpr wire, calling destruct on one of them

well, a disciplined programmer shouldn't do that. I think the same could be said for anything else living on some other handle wire. Camera sessions i.e....

Link to comment

My intention for the mupExpr class is to abstract away the details of interfacing with the muparser dll. The developer shouldn't have to worry (too much) about the handle and variable pointers.

I think that I can just obtain a queue or notifier reference in construct and release it in destruct. I will check if the reference is valid before trying to use the muparser handle or variable pointers. It is like an "is initialized" flag. That way I can generate an error instead of risk crashing labview if the muparser handle is not initialized or has been released somewhere.

Splitting the mupExpr wire could be useful if you want to, for example, update variable values in one loop and evaluate in another loop

Link to comment

I see. Yes, the difference with e.g. a camera is that you can think at scenari where multiple access could make sense. Discipline would be required nevertheless to handle races, even if a lock mechanism is built in, for instance I wouldn't see the sense of updating variables and evaluating completely asynchronously.

Edited by ensegre
Link to comment

I don't really see the point of evaluating asynchronously either. But I do sleep better knowing that the muparser handle and variable pointers are wrapped in something that is also passed around by reference. If the muExpr DVR is valid, I can assume that its variable pointers and muparser handle are also valid. If the DVR is not valid, most likely the variable pointers and muparser handle are also not valid. An error will be generated. No harm done.

I've added two polymorphic VIs to the class to aggregate the set variable value and eval functions. So finally, the top level api will look like:

construct
select single variable
set variable value
eval
destruct

Through these you are able to access all combinations of single variable, multi variable, multi expression, bulk mode. Note that bulk mode doesn't support multi expression. It just evaluates the last expression in the list.

Latest version here: muParser_byRef2.zip

Link to comment
On 10/20/2017 at 0:06 AM, Porter said:

If the DVR is not valid, most likely the variable pointers and muparser handle are also not valid

Indeed the other day I spent some time debugging an elusive crash-LV-second-time-button-is-clicked, which turned out nothing but a mistake attempting to destroy a stale muparser handle.

A trivial issue: some of your VIs are broken because of the input varValue moved to position 3 of the conpane on Eval_SglVar_SglRef, I imagine a last minute change for uniformity.

 

Edited by ensegre
Link to comment
On 10/22/2017 at 3:53 AM, ensegre said:

No big deal, they are all very simple. The full message from mupGetErrorMsg() is already more informative, beyond that I can't imagine. See my go at it:

mupCheckError.vi

Thanks. That saves me some time. I will try to take a look at it this evening. I will also try to fix up the examples and make a vip package to install the mupLib and mupExpr into "<LabVIEW>\vi.lib\LAVA\" and the dlls to "<LabVIEW>\resource\". 

Link to comment

Version 1.0.0 is available for download. It is a vip package.

It will install muParser dlls to "<LabVIEW>\resource\" and mupLib, mupExpr to "<LabVIEW>\vi.lib\LAVA\muParser\".

mupExpr VIs are located on the function palette under "Addons > LAVA > muParser"

Documentation and examples have not been included yet. But you should be able to figure it out for now.

The development version is available on github: https://github.com/rfporter/LV-muParser

Edited by Porter
Link to comment

quick test, seems to work ok in my project on windows.

Noob question about vipm: I can't install the vip on linux, as it was build with vipm-2017. How can I build the package from the sources with vipm-2014, which is the latest available for linux (jki said no schedule for a new release). "Open Package Build Spec" LV_muParser.vipb gives me a blunt "VI Package Builder was unable to open the build spec due to an error".

Edited by ensegre
Link to comment
On 10/29/2017 at 3:42 AM, ensegre said:

Noob question about vipm: I can't install the vip on linux, as it was build with vipm-2017. How can I build the package from the sources with vipm-2014, which is the latest available for linux (jki said no schedule for a new release). "Open Package Build Spec" LV_muParser.vipb gives me a blunt "VI Package Builder was unable to open the build spec due to an error".

I didn't realize that there was no vipm 2017 for linux. I will need to re-do the vipb file with vipm 2014. Have to find a computer that hasn't upgraded to vipm 2017 yet.

Link to comment
  • 3 weeks later...

In testing I noticed that muParser's log() function is base e, while excel's log() function is base 10.

I usually expect log() to be base 10 because ln() is base e.

Any opinions on this? Is it an engineering vs physics/mathematics convention issue?

This behavior can be changed in muParser.cpp, line 297. I'm very tempted to change log() to refer to log10() instead of ln() and add an additional function lg() as an unambiguous log10() shorthand.

Link to comment

Different packages have different names. For instance Matlab has log and log10, LV formula and mathscript has ln, lnp1, log10 and log2.

Imho you shouldn't change. You're releasing a package which is essentially muparser, and can even work happily with the unpatched muparser, so users could expect a high compatibility with it. Besides you're already at version 1.0. You're going to irk your user basis...

  • Like 1
Link to comment
  • 2 weeks later...

V1.1.0 released.

I've decided to add get variable value to mupExpr. This allows you to retrieve the value of a variable that may have been modified by evaluation of the expression (the assignment operator "=" is supported).

Examples for mupExpr and mupLib have been included in "<LabVIEW>\examples\LAVA\muParser\".

Link to comment

FYI

LabVIEW's formula parsing VIs are located within "NI_Gmath.lvlib". This means that even if you just use formula parsing, you need to load the entire Gmath library. This is a very big library!

This becomes particularly noticeable when building a stand-alone executable. Here are the results from my application:

With NI_Gmath as dependency
- Exe size: 40.6 Mb
- Build time: 22 minutes :throwpc:

With muParser instead of NI_Gmath:
- Exe size: 29.4 Mb
- Build time: 8 minutes :thumbup1:

 

  • Like 1
Link to comment
On 12/6/2017 at 5:37 AM, Porter said:

FYI

LabVIEW's formula parsing VIs are located within "NI_Gmath.lvlib". This means that even if you just use formula parsing, you need to load the entire Gmath library. This is a very big library!

This becomes particularly noticeable when building a stand-alone executable. Here are the results from my application:

With NI_Gmath as dependency
- Exe size: 40.6 Mb
- Build time: 22 minutes :throwpc:

With muParser instead of NI_Gmath:
- Exe size: 29.4 Mb
- Build time: 8 minutes :thumbup1:

 

How about 64 bit support :-)

Link to comment

Still about:

On 10/22/2017 at 10:53 AM, ensegre said:

 

On 10/17/2017 at 9:28 PM, Porter said:

Yup. I have a few more functions to implement for error handling

No big deal, they are all very simple. The full message from mupGetErrorMsg() is already more informative, beyond that I can't imagine. See my go at it:

 

While designing an interface which should highlight syntax errors in typed formulas, I realize that I miss a VI returning directly the strings of mupGetExpr() and mupGetErrorToken() together with the number mupGetErrorPos() [when applicable], instead of tediously parsing them from the full error message. Do you envision adding it to the toolbox? I may have a go at getting them from the encapsulated form, it later.

Edited by ensegre
Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.