Link to home
Start Free TrialLog in
Avatar of jakeyo
jakeyo

asked on

Unexpected Matlab operator

I am trying to call a Matlab script from a Perl script. I believe that I have the syntax correct, but I get the error: "??? error: unexpected Matlab operator." I believe I have the syntax right because the call launches Matlab, but that's about all it does except for posting an error message.
    My syntax is  `matlab -r "try,myprog(ar1, arg2, ...,arg10), end; quit"`;
I've tried this by replacing myprog with plot(1:10) - a Matlab function, and it works well!
 
So how can I trace what in my program is causing Matlab to have problems? BTW, I run my Matlab script from a small test script in Matlab and it works fine. But I don't know why I can't call it from Perl.
    Any help would be greatly appreciated. Thank you.
Regads,
jakeyo
Avatar of yuk99
yuk99
Flag of United States of America image

If you show the exact command you are using then the syntax is incorrect. You cannot use "..." between arguments. This symbol(s) only used in MATLAB to separate long statement to several lines. In your case you have to list all the arguments.

If you put "..." just to shorten the command, but actually you list all the arguments, then the problem in inside the myprog function. MATLAB should show that. Show us the complete error message you've got.
Avatar of jakeyo
jakeyo

ASKER

I'm sorry, I didn't quite understand all that you said. But here is my exact code:

$cmd = `matlab -r "try,plotA2modnew($batch, $dirs, $buoynum, $plots,
               $temps, $pres, $sal, $dens, $extn, $sfreq), end; quit"`;
print $cmd;

Please note that I have done the following as a test and it works:
    $cmd = `matlab -r "try,plot(1:10), end; quit"`;
      print $cmd;

The exact error message that I get is:
             ??? error: unexpected Matlab operator
Also please note that I constructed a small script to call plotA2modnew in Matlab and it works fine. However, there are some prompts in the code that requests user input. I avoided the prompts by hardcoding an answer in the code - just in case the program was requesting information and I couldn't see the request and, thus, might think that it's hanging up.
     I'd be happy to get a reasonable Matlab error that I can trace. But the error that I have has no line number associated with it. Hence, my dilemma.
jakeyo
It looks like the problem is in the command line you run. It's syntax error and it comes from the arguments.

I believe you define all the arguments for plotA2modnew in the perl script. What are they? All strings or some other classes? Can you show an example with all arguments defined?

Do you split the line with "$cmd =" into 2 lines on your code?

With the current command line you will not see any error messages that comes from the function plotA2modnew. They are hidden by try-end block. To show them you need to make the command longer with try-catch-end block:

$cmd = `matlab -nosplash -nodesktop -nodisplay -nojvm -r "try, plotA2modnew(...), catch ME, disp(ME.message), end; exit"`;

Open in new window

Avatar of jakeyo

ASKER

Thanks for the idea on the use of "Catch." I'll give it a try and let you know what happens. As far as the actual variables being passed, they are all strings except for $sfreq which is 6 (samples per hour) and $batch which is 1 and indicates that batch processing is turned on. So the other variables look like $plots = 'n', $temps = 'y', $dens = 'y', etc. The only variable which is not a 'y' or 'n' string is $dir which is just another string indicating a directory (e.g. '/2s125w/pm946a/'.

I'll try your coding and get back to you. Thanks.
jakeyo
Avatar of jakeyo

ASKER

P.S. I forgot to tell you that my matlab line of code is split in the coding of the command. I assume that the command continues logically to the next line as there is no ; at the end of the first line. I'm unaware of any line continuation character(s) at the end of a line in Perl.
jakeyo
Although splitting command line is allowed in perl, in this case this is matlab command, where simple splitting by end-of-line is not allowed. When this string is passed to matlab, end-of-line character is still there, and this might give you the error.

In MATLAB a single statement can be splitted with three dots (...) at the end of line. You can try to put ... at the end of line (not sure if it will work), but first try just to put the command in one line.

To test for this, take the command that is works and try to split it.
Avatar of jakeyo

ASKER

It would be nice if the problem is that simple. I'm still coding the other command. I have to jump back and forth between Linux (implement code changes) and Windows (read E-E mail with changes/suggestions). So it takes me a little while to effect a change.
jakeyo
I think I understand what's going on. When you pass string arguments they will substitute corresponding variables before the command will be passed to MATLAB. But the quotes will not be passed. So MATLAB will not see the arguments as strings, but as variables. Let's see the code:

$cmd = `matlab -r "try,plotA2modnew($batch, $dirs, $buoynum, $plots,
               $temps, $pres, $sal, $dens, $extn, $sfreq), end; quit"`;

MATLAB will see it as

try,plotA2modnew(1, /2s125w/pm946a/, 2, n, y, etc.

Out of strings "/" is incorrect symbol in matlab, that gives "Unexpected Matlab operator" error.

Try to include quote symbol inside the strings. Like $plots = '\'n\'';
I've tested the line splitting. It always gives another error:

??? Error: At least one END is missing: the statement may begin here.

it just seems the "Unexpected Matlab operator" error comes first.
Avatar of jakeyo

ASKER

I coded the Perl call to Matlab as you suggested above. This time there was no startup display of the Matlab logo or any other text output to the screen. The only thing that was output to the screen was the same error message: "??? error: Unexpected Matlab operator." Also I had to enter <CTRL>-C to get back to the Linux command line!

I did try coding the examples with and without the ellipses (...) for the Matlab line continuation character. However, I still get the same error as above (previous paragraph).

This is getting frustrating. If there was a way for Matlab to tell me what line the error was on, it would be a tremendous help. But apparently Perl doesn't let any messages through other than what we're getting.
jakeyo
Avatar of jakeyo

ASKER

Previously, I've tried
   `matlab -r "try,plot(1:10),end; quit"`;
and it worked. Then I tried
    $a = 1; $b = 10;
   `matlab -r "try,plot($a:$b), end; quit"`;
 and it worked.

I'm not sure if this addresses your comment about how the arguments are passed to Matlab. But it does seem to be able to accept a variable ($a,$b) and pass the correct value.
Does this help explain anything?
jakeyo
Avatar of jakeyo

ASKER

I'm sorry, I don't understand your comment about putting quotes inside the string. Could you give me an example? e.g 'y' becomes '"y"'?
jakeyo
Numeric arguments inserted without problems. In your case
`matlab -r "try,plot($a:$b), end; quit"`;
will be passed as
`matlab -r "try,plot(1:10), end; quit"`;
that is correct.

But in case of strings you need to pass quote characters.
In Matlab it's only single-quotes. Use escape character \ for this.

So  your argument should be $arg='\'y\'';
All quotes are single.
Avatar of jakeyo

ASKER

Ok, I'll give it a try.
jakeyo
To answer you comment 37924824.

if you include catch statement you will get error line number. But this will work for errors in script/function. In your case the error is from command line itself, this is why you get no line number.
Avatar of jakeyo

ASKER

"???error: At least one end is missing. Your statement may begin here."

The above is the new error message that I get. However, the message doesn't say where here is! Nevertheless, this may be progress.

I've been using a test script in my testing of this problem. I'll try your substitutions in the original program which calls plotA2modnew and see what I get. Hopefully, I'll get a useful error message.
jakeyo
This is the error I mentioned before in one of my comments. It's due to line splitting.

When you edit your script make sure the editor does not wrap the lines.
Avatar of jakeyo

ASKER

I tried changing the statement (as mentioned above) in my original code and I got the new error message: "At least one END is missing...."

I also tried passing just integer values for the string variables that I'm passing and got the same message.

My next step is to look at the code and see if I can find an END that's missing in one of the new conditional statements that created to be able to run my program in batch mode (i.e. no required input from the terminal). However, I doubt if there's a coding error since the program runs in stand-alone mode from the command line.

 Other than that check I don't know what else to try.
jakeyo
Try to remove try-catch-end block. The reason to use it is to reach exit statement in case of error in the script/function. If this happens just exit from matlab manually.

So your line should look like:

$cmd = `matlab -r "plotA2modnew($batch, $dirs, $buoynum, $plots,$temps, $pres, $sal, $dens, $extn, $sfreq); quit"`;

Open in new window


Include other parameters for matlab (-nosplach etc) if you need.
Avatar of jakeyo

ASKER

I think I've found the solution. I've been talking with the Matlab people and between them and you, I think I have something that works.

First, you're correct in the way that you pass strings.
Second, here's what I have from Matlab:

    For testing purposes, define the test function in Matlab as:
             function test(x)
              plot(1:x)
    This plots a straight line from values 1 to 10.

To test a Matlab call from the command line, simply do: >>matlab -r "test(10)"

But to call this from a Perl script, you must code (and don't ask why this funky format):
               $val = 10:  <=== Perl code assigning integer 10 to $val.
              system('matlab -r "test(' . ${val} . ')"');

This code works. I made up a small test function which calls 2 variables in Perl and it works properly. However, as per your remarks, one must be very careful in how one passes a string. For a string, it's exactly as you had said: '\'n\''.
              I have to leave work early today so I don't have time to make the changes to my script. I'll code it tomorrow and let you know if it works out. But, based on the simple test that I made, it looks very promising. Thanks.
jakeyo
Avatar of jakeyo

ASKER

Didn't work.

I have all 10 inputs to plotA2modnew coded as characters like: '\'y\''
and in the call to plotA2..., I have plotA2modnew(' . ${batch} . ',' . ${dirs} . ', ... etc.

I tried using the ellipses (...) and a hard CR-LF for the terminations of parts of the mult-line input and I get the same result.
The new error is: ??? error: unexpected MATLAB expression.
Now I have an unexpected expression instead of operator. Am I getting warmer?? I don't know.
jakeyo
ASKER CERTIFIED SOLUTION
Avatar of yuk99
yuk99
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of jakeyo

ASKER

I'm not concerned about security. It's just that I have to go between Windows and Linux. The copy and paste doesn't work between these 2 so I have to retype everything. I'll get started and send you what I have. I'll also include the small sample program first so you can see how it works. I'll get started with sending you this stuff.
Thanks for your continued interest.
jakeyo
Avatar of jakeyo

ASKER

Ok, I was able to find the web browser on the Linux VM box which made uploading files much easier.

1. Phase1 is a Perl file which I'm trying to get to run. It all works except the Matlab call which is the one giving all of the problems. It's at the end of Phase1.
2. testmod.txt is a Matlab file which calls plotA2modnew.m from Matlab to insure that it is working properly.
3. perlmatest is a short test Perl file which works properly with the program test (to be sent in next email).
4. testperl3 is a short Perl program which calls plotA2modnew.m. I used this to test the various permutations of syntaxes for getting Phase1 to work. Both the call in Phase1 to plotA2... and the call in testperl3 produce the same error message:
??? error: unexpected Matlab expression.
5. I sent Phase1 to you so you could see how I'm exactly coding the call to plotA2...
6. There is an immediate exit after the function definition in plotA2... I thought this might help me with troubleshooting by varying where I place the exit in the function. But it doesn't help.

I had to add .txt endings to the above files in order for it to make it through the upload filter. The web browser didn't allow .m extensions. I hope that this is not too confusing. Thanks again for looking at this.
jakeyo
plotA2modnew.txt
perlmatest.txt
Phase1.txt
testmod.txt
testperl3.txt
Avatar of jakeyo

ASKER

Here is test file.
test.txt
Avatar of jakeyo

ASKER

Finally got it to work. That is, at least it's getting into the function. I tried coding the call with one continuous line and with broken lines using Matlab continuation characters. The former one worked, the latter gave an error.

I don't know if you're still looking into this or not. I do appreciate all of the discourse going back and forth. Thanks again for your persistence.
jakeyo
Avatar of jakeyo

ASKER

ok, thanks.
Avatar of jakeyo

ASKER

One last problem: How do I pass a character string between Perl and Matlab?
For example, in the Matlab program I'm using, Matlab is expecting y or n answers to various prompts.

To pass those, I need to pass a variable coded like $yes = '\'y\''. This appears to Matlab as 'y' which works. Now I need to pass a variable with a string in it and get the same result.

For example, suppose $yes = y. Then I need something like '.$yes.' to produce 'y' for Matlab.

Any suggestions? Thanks in advance.

jakeyo
Great, I glad you fixed it. Sorry, i was not able to have a look at it earlier. Please don't forget to choose the best comment as the answer.

As for your last problem, I'm not clear what you want to do. Do you want to define a variable in MATLAB and pass it to a function? Or you define a variable in Perl and want to pass it to MATLAB? The last one is what this question was about, isn't it? And I thought you already solved it. Please explain in more details. Show what works and what doesn't.
Avatar of jakeyo

ASKER

I want to define a variable in Perl and pass it to Matlab.

When I was testing the calling of a Matlab program from a Perl script, I was passing all variables as constants just until I got the call figured out. For example, I passed a directory string constant as '\'mydir1/mydir2\''. This actually passed the string as 'mydir1/mydir2'. The single quotes are very important to Matlab in passing these strings correctly.

Now, I'd like to put my directory in a variable and make up the equivalently passed string.
So I may have a Perl variable called $directory='/mydir1/mydir2'. Now I need to concatenate the single quotes to the variable and pass the new variable string which will have the single quotes embedded in it. So I might try (and this doesn't work) something like:
         $tick eq '\''  
          final string eq $tick.$directory.$tick
So I'm trying to think of various ways that I can code a single quote in a variable and then use the concatenation operator (.) to put the string together.
      Any ideas would be appreciated. Thanks.
jakeyo