How to reciprocate? - matlab

Actually I am coding a Matlab simulation where the AnchorID and SourceID will report to eachother. For example if I take an anchor 30 and source 50 it will collect all the agc values between these anchor and source and calculate rssi_dB and display them.Below mentioned is an example of anchor 30 and source id 50
Note: list of anchors ID's and source ID's are same. for e.g. 30 50 55 58 . These ID are both same for anchor and source.
function A30(BlinkSet)
for i=1:length(BlinkSet)
xAnchorID=30;
xSourceID=50;
a=BlinkSet{i}.AnchorID;
b=BlinkSet{i}.SourceID;
if xAnchorID==a && xSourceID==b
xagc=BlinkSet{i}.agc;
rssi_dB(i)=-(33+xagc*(89-33)/(29-1));
end
end
rssi_dB(rssi_dB==0)=[];
rssi_dBm=sum(rssi_dB(:))/length(rssi_dB);
disp([sprintf('The rssi value is %0.0f',rssi_dBm)]);
When I call the function in Matlab command window I get the rssi value of the above function.
Also my task is when I reciprocate the Anchor ID and source ID say Anchor as 50 and source as 30 like the function I have mentioned below I get an error which is mentioned after the function below.
function A50(BlinkSet)
for i=1:length(BlinkSet)
xAnchorID=50;
xSourceID=30;
a=BlinkSet{i}.AnchorID;
b=BlinkSet{i}.SourceID;
if xAnchorID==a && xSourceID==b
xagc=BlinkSet{i}.agc;
rssi_dB(i)=-(33+xagc*(89-33)/(29-1));
end
end
rssi_dB(rssi_dB==0)=[];
rssi_dBm=sum(rssi_dB(:))/length(rssi_dB);
disp([sprintf('The rssi value is %0.0f',rssi_dBm)]);
When I call this function I get an error as
??? Undefined function or variable "rssi_dB".
Error in ==> A50 at 14
rssi_dB(rssi_dB==0)=[];
Error in ==> main_reduced at 26
A50(BlinkSet);
In main function I have coded like this,
%A30(BlinkSet);
A50(BlinkSet);
Any help is highly appreciated.

In both of these functions, you only create the variable rssi_dB if execution enters the if statement within the loop (i.e., if xAnchorID==a && xSourceID==b is at some point true). Clearly, this code is never executed in your A50 function. Without knowing what is in BlinkSet it's a bit difficult to diagnose the exact problem, but this is the cause at least.
As a side note: it's not a good idea to create two separate functions to do this job when their code is almost identical. You should add an input argument to your function that allows it to do the job of both. In this particular case, all that changes is the value of xAnchorID and xSourceID, so you could just pass these in:
function srcToAnchorRssi(BlinkSet, xSourceID, xAnchorID)
% The rest of the function stays the same!
If you want to provide some defaults for these arguments, you can do, e.g.:
if nargin < 3 || isempty(xAnchorID), xAnchorID = 50; end
if nargin < 2 || isempty(xSourceID), xSourceID = 30; end
It's always a good idea to include an isempty in statements of this sort, so that your function supports syntax like myFunction(myArg1, [], myArg3). Also note that the order of the operands to || is crucial; if you did if isempty(theArgument) || nargin < theArgumentNumber and the user did not pass theArgument, then it would error in the isempty because theArgument would not exist as a local variable. We can get around this by swapping the operands' order because MATLAB is smart enough to know it doesn't have to evaluate the right operand if the left operand is true (note that this is also the case in many other programming languages).

Related

How can I return true in COBOL

So I am making a program that checks if a number is divisible by another number or not. If it is its supposed to return true, otherwise false. Here's what I have so far.
P.S : I'm using IBM (GnuCOBOL v2.2 -std=ibm-strict -O2) to run this.
IDENTIFICATION DIVISION.
PROGRAM-ID. CHECKER.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 BASE PIC 9(5).
01 FACTOR PIC 9(2).
01 RESULT PIC 9(5).
88 TRU VALUE 0 .
88 FAL VALUE 1 THRU 99 .
PROCEDURE DIVISION.
CHECK-FOR-FACTOR SECTION.
IF FUNCTION MOD(BASE, FACTOR) = 0 THEN
SET TRU TO TRUE
ELSE
SET FAL TO TRUE
END-IF.
END PROGRAM CHECKER.
It gives me error saying invalid use of level 88. I'm sure I'm making a mistake, and I've searched for couple of days and I can't seem to find anything that can help me with it. Any ideas if it is possible in COBOL or does COBOL handle all the boolean stuff some other way ?
(Kindly do not reply with look up level 88 or some other stuff like that, I have already looked them up and they haven't been helping)
To return TRUE from a program you'd need an implementation that has boolean USAGE, define that in LINKAGE and specify it in PROCEDURE-DIVISION RETURNING true-item and also use CALL 'yourprog' RETURNING true-item.
Your specified environment GnuCOBOL doesn't have a boolean USAGE in 2021 and can't handle RETURNING phrase of PROCEDURE DIVISION in programs.
But you can use a very common extension to COBOL which is available in both IBM and GnuCOBOL:
Before the program ends MOVE RESULT TO RETURN-CODE (which is a global register) and in the calling program check its value (and reset it to zero).
Then it is only up to you what value means "true" (in your program it is 0).
As an alternative you could create a user-define function (FUNCTION-ID instead of PROGRAM-ID and use the RETURNING phrase to pass your result) - but that would mean you need to use IF FUNCTION instead of CALL + IF RETURN-CODE in each caller.

Find variables and the dependencies between them in code

I am trying to write a function that finds all the variables in a function which contains computing operations. I do this to find out which variables this block of calculations requires as input arguments to perform the calculations.
A calculation function always gets a table with different parameters as input, accesses certain parameters of that table to calculate certain metrics.
For example my data table T contains the double arrays Power and Time. This table is passed to the function calc_energy which then calculates Energy:
function [ T ] = calc_energy( T )
T.Energy = T.Power .* T.Time;
end
Say whenever a new data table is generated, different calculations as the above one are run automatically. Now if Power itself is calculated by the function calc_power, but calc_energy is run before or parallel to calc_power, then I have a problem because calc_energy doesn't find the required variables in T.
In order to prevent such an error, I want my function check_required_variables to be called inside the calc_energy and check beforehand whether T.Power exists. The thing is that check_required_variables should be a general function that is called in every single calculation function and therefore doesn't know the required variables. It has to find them in the function that it is called by.
function [ T ] = calc_energy( T )
OK = check_required_variables( T, 'calc_energy.m' );
if OK == 1
T.Energy = T.Power .* T.Time;
else
error('Required fields not found');
end
end
Are there any functions that spot the variables Energy, Power and Time used in my code? And are there functions that maybe analyse the dependencies between these variables (Energy dependent on Power and Time)? What are generally clever ways to figure out the ocurring variables just from the code? Any ideas?
I know this is a tough one so I'm thankful for any suggestions.
use isfield
function [ T ] = calc_energy( T )
if all(isfield(T,{'Power','Time'}))
T.Energy = T.Power .* T.Time;
else
error('Nooooope')
end
end
However, knowing which ones are required seems a bit harder.... You can always try to read the .m file, and regexp for T.____, then put the input of that to isfield.
This however, just hints of bad software design. A function should know what it requires to run. What happens if OK is false? It just skips the computation? You can then cascade to hundreds of calls (depend on the application) because the original structure failed to have a variable, or had a typo. I'd take the radically opposite approach to software design:
function [ T ] = calc_energy( T )
assert(all(isfield(T,{'Power','Time'}))); %error if there are not.
T.Energy = T.Power .* T.Time;
end

Using `exist` with structure array

The assignment is
You are testing a functional near infrared (fNIR) device and
measuring how well each subject is able to control the computer mouse using
it. Write a function getcogdata that returns the requested category for
the requested user id. If the requested user does not exist, return an empty
matrix. If no user is requested, return a
cell array of values for all users.
My code is as follows
function output=getcogdata(cat,id)
info=struct('id',{'33','10','48','41'},'name',{'Joe','Sally','Harry','Ann'},...
'age',{'27','25','23','19'},...
'height',{'5.9','6.1','5.8','6.0'},'score',{'9,5','9.3','9.7','9.4'});
if id=='33'
id=1;
elseif id=='10'
id=2;
elseif id=='48'
id=3;
else id=='41'
id=4;
end
output=info(id).(cat)
end
My code works for when measurement and user are specified but I can't figure out how to code for if the user doesn't exist or if no user is requested. I tried not exist(id) I get an error. Is there a way I can use not exist?
Matlab's exist function will tell you if something is known to the current Matlab instance. It won't tell you if a particular value is present.
Your task is probably a little bit more complex than you originally thought but you can accomplish it with a mixture of strcmp, and any.
First, we convert the ids in info to a cell array with
{info.id}
now we can use strcmp to compare them against id
strcmp(id, {info.id})
Finally, we can use any to tell us if any of the values in {info.id} are equal to id. So putting this all together we get
>> info = struct('id',{'33','10','48','41'});
>> id = '33';
>> any(strcmp(id, {info.id}))
ans =
1
We can also this to find the index of id in {info.id} and do away with the if statements in your question by using find instead of any
>> id = '10'; % Present in index 2 - Output should be 2
>> find(strcmp(id, {info.id}))
ans =
2
To answer your final question about not passing the id to getcogdata you can do this using nargin
function output = getcogdata(cat,id)
if (nargin < 2)
fprintf(1, 'No id passed to getcogdata()\n');
end
end
nargin will tell you how many arguments were passed to the function getcogdata.
Thanks to #AndrasDeak for teaching me Matlab's strcmp is much better than the C version I had been assuming it was similar to!
Note: Always read the manual!

set threshold as a function of autoThreshold

I have written a macro for ImageJ/FIJI to deconvolve my confocal microscopy images and run the "3D Object Counter" plugin. The macro successfully runs all required commands and saves all required data in the specified places.
However, I have found that the 3D-OC autothreshold (as shown in the plugin dialog box) is to stringent resulting in objects being lost or divided.
To remedy this I would like to reduce the autothreshold by a predetermined function something similar to what was done here (from:How to get threshold value used by auto threshold Plugin) which resulted in this code:
setAutoThreshold();
getThreshold(lower,upper);
v=setThreshold(lower,upper*0.5);
run("3D Objects Counter", "threshold="v" slice=10 min.=400 max.=20971520 objects statistics summary");
The idea was to call the AutoThreshold values, modify them and set them to a variable. However when these lines are run the following error is returned:
Number or numeric function expected in line 3.
v=<setThreshold>(lower,upper*0.5);
And if the variable is inserted directly into the threshold key for run(3D-OC) the following msg is encountered:
Numeric value expected in run() function
Key:"threshold"
Value or variable name:"setThreshold(lower,upper*0.5"
Any suggestions or help on how to designate the 3D-OC threshold value as a variable as described would be greatly appreciated (as would any work arounds of course :) ).
Cheers
Edit: After testing Jan's response below (which works perfectly), it appears I need to call the threshold set by the 3D-OC plugin. Anyone know how to do this?
The getThreshold(lower, upper) function returns the lower and upper threshold levels in the provided variables. There is no need to assign any value to a new variable, and as you observed, setThreshold does not have any return value.
Instead, you can use the value(s) returned from getThreshold and use them as parameters in the run method (in the correct way, by string concatenation, see here):
setAutoThreshold();
getThreshold(lower, v);
run("3D Objects Counter", "threshold=" + v + " slice=10 min.=400 max.=20971520 objects statistics summary");
Alternatively, you can use &v in the second parameter to avoid string concatenation in the last line (see the documentation for the run() macro function):
run("3D Objects Counter", "threshold=&v slice=10 min.=400 max.=20971520 objects statistics summary");
You might have to use the lower instead of the upper threshold value, depending on whether you count bright or dark objects.

I need a function that will return the existence (or not) of a given index of a matrix

I'm trying to filter noise out of an image in matlab and I've hit an issue. I need to be able ask some function whether or not if the index -1,-3 or -1,4 or 5,-1 exists, and I need it to return some integer or a false so that I can put it in an if statement. so far, with islogical() exist() and just ARRAYNAME(-1,4) I've gotten an error saying that index position doesn't exist (duh, but that's not what I want) is there a function that can return 1 if there's an error? I really just need this one thing. let me know if the question is too vague.
You can use try-catch statement as follows.
function element=neverReturnIndexingError(array1)
%array1=[1 2 3 4];
try
element=array1(-1,2);
catch
fprintf('Index is invalid\n');
element=1; %returning 1 as you said
end