How to best print output to command window during a loop in Matlab? - matlab

I have a loop which iterates through a list of ID numbers paired with a given stress value. The code works fine, except there is no guarantee that the lists have identical lengths. I currently have an if isempty(stress_value) loop with a continue statement if an ID number doesn't have corresponding stress value. All of this takes place in a for id = 1:num_ids loop.
I am now trying to print this id value (class 'double') to the command line, if it doesn't have an assigned stress value, so if the isempty statement is True, prior to continuing out of the loop. As an example, if I set num_ids equal to 101, but the list I'm iterating through only has ID values 1-100, I want to output this 101 ID to the command line.
I've tried printing as an error like this:
error(['The following ID does not have an assigned stress value: ',id])
Here id simply prints as e however when I try this in the command window, which I don't quite understand. When I run it in the script nothing is printed to the command window.
I have also tried simply adding a display command for the id to the loop as follows, however when I run the code nothing shows up again:
disp(id)
Sorry for the simple question, but I have not found an effective way to do this yet, and would appreciate your feedback!

Check the fprintf. You can format your output just like you want.
for id=1:num_ids
% do something
if isempty(stress_value)
fprintf('The following ID does not have an assigned stress value: %d\n',id)
continue
end
% do something
end
The error function will stop code execution.
The display function only prints the value of the variable, without printing the variable name.

Related

I am trying get three parameters of x, y, and z from this script but all it does is return one value that is not the dimensions I am looking for?

I am new to perl and i am trying to get the dimensions which i think are given from the GeometricCenter method in this perl script. I used this script and it ran and returned only one value which i believe is a value called the gyration which is a paramter that helps determine the xyz dimensions. I thought this script would of returned the dimensions but it did not. Anyone know?
so i tried printing the values in the array xyz which i thought they were in. I tried this by using say but it said i cannot use say on an undefined value
This is the actual problem.
https://github.com/michal-brylinski/eboxsize/blob/master/eBoxSize-1.1.pl
As far as I can tell, your question boils down to "how do I print the values of an array?".
The answer depends on how you want the results formatted, but in the simple case of space-separated numbers, you can just do
print "#geo_center\n";

Check code as a string instead of parsing a file

Is it possible to use checkcode or matlab.internal.codeanalyzer to parse a string of code, for example:
for i=1:100 a*b(i); end
without first putting that in a file and then calling checkcode or the internal parser.parse on that file. I want to check thousands of strings of code but dynamically without putting them in a file before each check. Ideally, I would like to be able to parse a string with the code in and have that parsed.
To be more clear incase there are other functions that could be useful, I actually want to parse a string and count the number of syntax errors, and find their location etc.
Seems mlintmex has a -text option which one can use to pass a string. It needs a string and a filename, however, it seems not to even use the filename, so not sure why. Furthermore, I can't figure out why, but when using -text there needs to be at least one parseable command. Therefore instead of calling
fid = fopen('tmp.m','wt');
fprintf(fid, '-mean[1:10)');
fclose(fid);
info = checkcode('tmp.m', '-fullpath');
one can use the following which has a great increase in performance:
% Get the errors with text mode
info = checkcode(['1;','-mean[1:10)'], 'tmp.m', '-fullpath', '-text');
% Reduce the columns to take in to account the '1;' in the checkcode call above.
for i=1:numel(info)
info(i).column = info(i).column - 2;
end
Using tic and toc in a loop for 1000 times, I get ~9 seconds for the file version and ~3-4 seconds for the -text version.

How to get a script to give a value to an input prompt?

I have a collection of smaller scripts foo1, foo2, etc. and a script master.m that runs them all, like this:
% master.m
run foo1
run foo2
Let's say foo1 calls for input somewhere by saying a = input('Gimme a number\n');.
I thought that if I put the value(s) I wanted on new lines after the run command that they would be entered as input, but they don't. I've also tried enclosing them as a string, i.e. '5'. That doesn't work either.
Is their another function I should use? I looked at the help file for input, but there's no output function. Presumably there's something like write or writetostdio somewhere.
How do I give user input to a script that is being called by another script without touching the keyboard? Can I put the values I want to input in the master.m file?
EDIT:
Because there's some confusion, I'll try to clear it up.
The scripts foo1 and foo2 will NOT be passing values back and forth. Every script will be run independently. Instead, I'm trying to test a program for a range of user behaviours (which are responses to prompts via input in foo1). These are normally typed on the keyboard, but I want my master.m file to tell foo1 what the user inputs are.
Sorry if this is confusing, but hopefully that clears it up.
Modifying existing code to accommodate both manual input and testing inputs is trivial:
function foo1(niterations)
if nargin == 0
niterations = round(input('How many iterations? '));
end
for ii = 1:numel(niterations)
% Run the thing
fprintf('Running some random program with %d iterations! Yay!\n', niterations(ii));
end
end
Using this approach we can do:
>> foo1
How many iterations? 2
Running some random program with 2 iterations! Yay!
or
>> foo1(2)
Running some random program with 2 iterations! Yay!
or
>> foo1([1, 3, 5, 7, 9])
Running some random program with 1 iterations! Yay!
Running some random program with 3 iterations! Yay!
Running some random program with 5 iterations! Yay!
Running some random program with 7 iterations! Yay!
Running some random program with 9 iterations! Yay!
This is far more logical than trying to pipe things from text files, use evalin to poof things into workspaces, or whatever automagical approach is required to accommodate using scripts in this fashion.
Ok, this is a bit ugly... but might be a work-around if for some reason foo1.m etc. have to remain as scripts.
The idea is to replace each instance of input with a newly defined function myInput which checks if a variable PROMPT_VALUE has been set in the base work-space; and returns that if so, and otherwise passes through to the built-in input. For example:
% myInput.m
function [ valueOut ] = myInput( promptString )
W = evalin('caller','whos'); %or 'base'
doesPVexist = ismember('PROMPT_VALUE',[W(:).name]);
if doesPVexist
valueOut = evalin('caller', 'PROMPT_VALUE');
else
valueOut = input(promptString);
end
end
Assuming we have the following sub-scripts:
% foo1.m
a = myInput('Number to double: ');
disp(2*a);
% foo2.m
b = myInput('Number to halve: ');
disp(b/2);
We can test the approach as follows:
% master.m
clearvars;
PROMPT_VALUE=5;
run foo1.m;
PROMPT_VALUE=3;
run foo2.m
If you run this as-is it will take the PROMPT_VALUE as inputs to each of the subscripts (returning 10, and 1.5). If those lines are commented out it will look for input from the user.

Puzzling error with script run in function

I'm experiencing a puzzling error in Matlab R2012b. It seems that variable names that are also data types exhibit strange behavior. Please see this small example:
function [] = test1()
dataset = 1;
if dataset ~= 0
disp hello
end
end
A call to test1() produces output hello, as expected.
Now, rather than set the value of dataset in my function, I run a script instead.
function [] = test2()
myscript;
if dataset ~= 0
disp hello
end
end
where myscript.m has one line:
dataset=1;
Now, when I call test2() I get this error:
Undefined function 'ne' for input arguments of type 'dataset'.
Error in test2 (line 4)
if dataset ~= 0
(Forgive the variable named dataset - I know that it is also the name of a data type, and it came in the code I was running.) So it seems as if in test2, Matlab creates an empty dataset object rather than using the variable named dataset. Furthermore, this behavior only appears when I set the value in a script rather than in the function body. Even more weird, is that I can do:
>> dbstop in test2 at 4 % line of if statement
>> test2()
K>> dataset
dataset =
1.00
K>> dataset ~= 0
ans =
1
K>> if dataset ~= 0, disp hello; end
hello
K>> dbcont
and I get the same error! The error is not displayed in debugging mode but it is in normal execution.
Can anyone reproduce this? What is going on here?
The MATLAB online help has some pages dealing with this issue; Variables Names and Loading Variables within a Function seem to be the most relevant.
There is no explicit page that discusses how MATLAB resolves names at compilation time, but there is one little tidbit at the bottom of the Variables Names page: "In some cases, load or eval add variables that have the same names as functions. Unless these variables are in the function workspace before the call to load or eval, the MATLAB parser interprets the variable names as function names."
In other words, if the parser finds an explicit assignment to a variable whose name is the same as another existent object, the local definition takes precedence.
In your test2(), there is no explicit assignment to a variable dataset; therefore, when the file is compiled, the parser interprets dataset to be a class constructor (since the parser will not run or inline myscript into the function).
Then at run-time, even though a variable named dataset has been poofed1 into the function's workspace, the interpreted code that is running still has the dataset symbol in the if-statement associated with the class constructor.
If you need to, you can still use the dataset variable name and load from an external file, but it should be done with an explicit assignment via a function call. For example:
dataset = initialize();
Now the parser will notice that dataset is some arbitrary output of the function initialize and all will be well. In fact, you can have even have initialize return a dataset constructor to the dataset variable if you wanted.
1 When variables are defined without explicit assignment, MATLAB people (at least on some of their blogs I've read) called this 'poofing'. Using load without any output arguments, using eval, and simply running scripts (not functions) can all poof variables into the workspace. This can work fine as long as the variable names do not conflict with other in-use symbols at compile time.

SPSS Macro: compute by variable name

I don't think SPSS macros can return values, so instead of assigning a value like VIXL3 = !getLastAvail target=VIX level=3 I figured I need to do something like this:
/* computes last available entry of target at given level */
define !compLastAvail(name !Tokens(1) /target !Tokens(1) /level !Tokens(1))
compute tmpid= $casenum.
dataset copy tmpset1.
select if not miss(!target).
compute !name= lag(!target, !level).
match files /file= * /file= tmpset1 /by tmpid.
exec.
delete variables tmpid.
dataset close tmpset1.
!enddefine.
/* compute last values */
!compLastAvail name="VIXCL3" target=VIXC level=3.
The compute !name = ...is where the problem is.
How should this be done properly? The above returns:
>Error # 4285 in column 9. Text: VIXCL3
>Incorrect variable name: either the name is more than 64 characters, or it is
>not defined by a previous command.
>Execution of this command stops.
When you pass tokens to the macro, they get interpreted literally. So when you specify
!compLastAvail name="VIXCL3"
It gets passed to the corresponding compute statement as "VIXCL3", instead of just a variable name without quotation marks (e.g. VIXCL3).
Two other general pieces of advice;
If you do the command set mprint on before you execute your macro, you will see how your tokens are passed to the macro. In this instance, if you had taken that step, you would have seen that the offending compute statement and error message.
Sometimes you do what to use quotation marks in tokens, and when that is the case the string commands !QUOTE and !UNQUOTE come in handy.