Jump to content

Porter

Members
  • Posts

    227
  • Joined

  • Last visited

  • Days Won

    26

Posts posted by Porter

  1. 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\".

  2. 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.

  3. 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.

  4. 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

  5. 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\". 

  6. 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

  7. 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

  8. 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.

  9. On 9/10/2017 at 2:58 AM, ensegre said:

    mupEvalMulti.vi dies on DSDisposePtr. Shouldn't there be a DSNewPtr somewhere, like in other VIs using LabVIEW:MoveBlock?

    mupEvalMulti returns a pointer to an array of doubles. I'm using that as the source for MoveBlock. Then I initialize an array of doubles to the correct size and pass its array data pointer as the destination for MoveBlock. The destination pointer, I'm assuming, is allocated and disposed of internally by LabVIEW. The source pointer should be allocated and disposed of by muParser. So I should not use the DSDisposePtr at all in this case... ?

    On 9/10/2017 at 2:58 AM, ensegre said:

    Besides, your .so doesn't load on my system, and I have to use the one I compiled locally, but that is expected, as said above. Only confirming that it is vane to target all possible linux distros at once.

    The .so files included in the zip are the ones that you posted earlier. Maybe I messed them up when I renamed them? Or perhaps they break if loaded from "<LabVIEW>/resource" directory? Sorry I can't test any of this; I don't have access to LabVIEW for Linux.

  10. V0.0.4 is up. I've named the muparser shared libraries as "libmuparser-[bitness]-lv.dll". For now, you need to manually copy them over to your "<LabVIEW>\resource" directory (or somewhere else in the search path).

    Now to concentrate on features...

    - Bulk mode
    - Multiple return values
    - Multiple type support (MUP_BASETYPE)?

  11. Quote

    MUP_STRING_TYPE

    This definition determines the string type used by muParser. This can either be std::string or std::wstring. This definition shouldn't be set directly. It is defined to std::wstring if there is a preprocessor macro _UNICODE present. (This definition is set by VS2008 accoring to the project settings.

    But it sounds like your "/usr/lib/x86_64-linux-gnu/libmuparser.so.2" is using std::string.

  12. How about these names:

    libmuparser-x32-ascii-lv.dll
    libmuparser-x64-ascii-lv.dll
    libmuparser-x32-ascii-lv.so.2.2.5
    libmuparser-x64-ascii-lv.so.2.2.5

    I will assume that they will be located in the "<LabVIEW>\resource" directory.

    Note that a major difference between the modified version and a possible standard version of libmuparser is the character encoding. By default, Visual studio 2013 compiles muparser with _UNICODE preprocessor macro. This does not play nice with LabVIEW's strings.

  13. I also prefer the statically linked dll because I can imagine that no one will remember to include the correct DLL or even know where to find the DLL when they build their exe.

    However, since this library is under development, I think that it is wise to stick with the in-lined mupLibPath vi for now.

    When we get closer to V1.0 perhaps it will be worth putting in the extra effort to setup a conditional disable structure around each CLN.

    • Like 1
  14. To simplify the path logic to a constant, we could reference the shared library by name rather than full path. To do this, we need to place the library in the search path. For LV windows, linux and OSX development environment the search path includes "<LabVIEW>\resource". For a LV-built application in windows, the directory of the executable seems to also be included in the search path. Not sure about LV-built applications for Linux though.

    See: http://digital.ni.com/public.nsf/websearch/EBAE870D564CBBE78625788B004E76D3

    Benchmark shows very little difference (<100ns) in performance between static, constant (full path) and in-line VI (providing library name).

    Benchmark_CLN.zip

  15. How about statically linking (not specifying path on diagram) and putting a conditional disable structure around each CLN? It is a pain to maintain but I think that it would give us the best performance. Also, when built to exe, the correct OS & bitness dll/so will be included automatically.

  16. 7 hours ago, ensegre said:

    In any case, have you noted the shift register for that pointer? This should keep the case of N=0 exprs from crashing.

    Good catch. I missed that one. I was too distracted by my struggles with the getValueByPointer xnode (which does not work properly when built into an executable).

    7 hours ago, ensegre said:

    mupGetExprVars still crashes if called with Parser in=0, that should perhaps be trapped in a production version.

    Indeed, LabVIEW does not like an uninitialized parser reference. Now is it worth checking for hParser=0 in every mup vi? My plan was to create a wrapper for the mup VIs (muExpr class) to protect the end user from inadvertently crashing LabVIEW. Within that wrapper I make sure that the parser handle is properly initialized and pointers to variables are properly created/released.

×
×
  • Create New...

Important Information

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