Return " i " value when if-statement is true - matlab

I have created a matrix with row 1 full of strings and 4 other rows with numbers. They are created in a handle class with the object "Projekter".
So in the object "Projekter" row 1, the first value is blank, but the second value is 'Ole'. So I know that 'Ole' is in (1,2). x is the name/string I want to search for, which in this case is 'Ole'.
As you see below it should search row 1 from column 2 untill the last name/string and if i = 'Ole', it should bring me the value 2 because " i " should be equal 2.
A is just a controller if the function works, but at this point it doesn't.
The error it gives is "Undefined function 'eq' for input arguments of type 'cell'."
How do I fix this so it return the " i " value when the statement is correct?
Thank you in advance!
function number(obj,x)
A = [];
for i = 2:size(obj.Projekter,2)
if obj.Projekter(1,i)==x
A = A + 1;
end
end
disp(A)
end

Maybe you have to index the cell content:
your_cell = {'a_string'};
your_string = your_cell{1};

function [returnValue] = number(obj,x)
for i = 2:size(obj.Projekter,2)
if obj.Projekter{1,i}==x
returnValue = i;
return;
end
end
end
Note the change from obj.Projekter(1,i)==x to obj.Projekter{1,i}==x (use curly braces instead of parens). I have then specified that returnValue will hold the value that should be returned by doing function [returnValue] = number(obj,x). We then set returnValue equal to i and return from the function when the condition of the if statement is true.
As suggested in the comments, it is probably better to do:
function [returnValue] = number(obj, x)
returnValue = find(strcmp(x, obj.Projekter) == 1);
strcmp(x, obj.Projektor) will give you an array the length of obj.Projekter with 1's wherever the strings match, and 0's where they don't, you can then find the indices that are set to 1. This has the added benefit of
not using a loop so it's faster
Giving you every occurrence of a match, not just the first one.

Related

How to use for loop to add the previous values in an array in MATLAB?

I have an array like t. It contains the numbers and I would like to add to each number the previous ones. For example: t=[0,2,3,5] and I would like to get tnew=[0,2,5,10]. I tried out this code but it is wrong for sure. (There are 5292 values)
for i=0:5292
t(i)=t(i)+t(i+1)
end
For some array t = [0,2,3,5];, you can just do tnew = cumsum(t).
If you really want to do this in a loop, you need to start from the 2nd index, and keep adding to the value from the previous index
t = [0,2,3,5];
tnew = t;
for ii = 2:numel(t)
tnew(ii) = t(ii) + tnew(ii-1);
end

Lua: set every new element in table to a default value

I want to get the most frequent k-sized substring in a string. To achieve this, I'm using a table to store the number of occurrences for each substring. Here's the code:
function frequentWords(seq, k)
local subs = ""
local counter = {}
for i = 1,(seq:len()-k+1) do
subs = seq:sub(i, i+k-1)
counter[subs] = (counter[subs] and counter[subs] + 1 or 1)
--print(subs .. ": " .. counter[subs])
end
end
The line counter[subs] = (counter[subs] and counter[subs] + 1 or 1) has the same mean of counter[subs] = (counter[subs] ? counter[subs]+1 : 1). This line would be only counter[subs] = counter[subs] + 1 if we could set every new counter element with 0. Is this possible in Lua? If not, what's the best way of doing something similar?
For instance, in Ruby, this is done by declaring a Hash like this:
counter = Hash.new(0)
You can set an __index metamethod in counter to return 0:
setmetatable(counter,{__index=function () return 0 end})
but this is easier and clearer:
counter[subs] = (counter[subs] or 0) + 1
For your case, lhf's solution is sufficient. Just for completeness, I would like to mention there is a more complex way, that enables some slightly more complex functionality. Specifically, it acts "as you would expect" when you use it with mutable values, such as table: it both creates the item, and assigns it to the key when created.
function defaultTable(constructor)
local new = {}
local function initIndex(key)
local value = constructor()
new[key] = value
return value
end
setmetatable(new, {__index=initIndex})
return new
end

'Undefined function' error, but I don't even use it

I am trying to write a function that can return a function which adjusts if an input value is in array. Here is the code:
function in = getArray(varargin)
%varargin must contain some 2D-arrays that define the border of range
%say,[0,1] [100,102]
narginchk(1,inf);
function result = isIn(value)
len = size(varargin);
for k = 1:len(1)
arr = varargin(k);
if (value >= arr(1)) && (value <= arr(2))
result = 1;
return;
else
result = 0;
end
end
end
in = #isIn;
end
It's so odd that when I call it by in = getArray([0,1]);in(10) the error is as follows:
??? Undefined function 'ge' for input arguments of type 'cell'.
Error in getArray/isIn (line 10)
if (value >= arr(1)) && (value <= arr(2))
Can someone find something?
The function ge is called when performing the >= operation. The error tries to tell you that you are not allowed to do a >= operation with a cell array as first operand.
As Marc already mentions, this problem stems from the fact that you access your varargin array - which is a cell array - using (), which makes the result be a cell array as well.
Instead, use {} as this will pick the contents out of the cell array and have the correct data type.
Try indexing varargin using curly brackets, it's a cell array: arr = varargin{k};.

How to return NaN or empty matrix if a condition is false

I have a question based on the below function. How to return a NaN or empty matrix if a condition is false.
Below function actually check if the Anchor ID and Source ID are present and if such a combination exists it goes further inside the loop to check if Anchor Channel and Source Channel exists if it exists then it will calculate "y" and goes on. But what if the Anchor Channel and source Channel does not exist for this condition ? and also consider what if Anchor ID and source ID does not exist !!! If it does not exist then I want it to return to NaN or simply nil.
How to modify this function to my requirements ??
function [rssi_dBm1]= sampletrue(BlinkSetList,AnchorID,SourceID)
for i=1:length(BlinkSetList)
S=cell2mat(BlinkSetList(i));
for j=1:length(S)
if S(j).AnchorID==AnchorID && S(j).SourceID==SourceID
if S(j).AnchorChan==0 && S(j).SourceChan==0
y=S(j).agc;
rssi_dB1(i)= -(33+y*(89-33)/(29-1));
else
rssi_dB1(i)=NaN;
end
end
end
end
rssi_dB1(rssi_dB1==0)=[];
rssi_dBm1=sum(rssi_dB1(:))/length(rssi_dB1);
disp([sprintf('The rssi value with A-Chan 0 and S-Chan 0 is %0.0f',rssi_dBm1)]);
Note: This is just a one part of the conditions, there are still three more combinations for anchor channel and source channel to evaluate.
If the question is still not clear post your doubts and I will try to explain it more precisely.
Your help is highly appreciated . Thanks in advance.
An example of function returning Nan
function ret = retNan( value )
if value == true
ret = 1;
else
ret = NaN; % set returned value to Nan
end
A function that returns an empty matrix
function ret = retEmpty( value )
if value == true
ret = 1;
else
ret = []; % set returned value to an empty matrix
end
EDIT:
Bottom line, whatever the value of variable ret (or in your case, rssi_dBm1) is at the end of the function - this value is returned. So, if ret is empty or NaN the function simply returns an empty/NaN value.
You may set rssi_dBm1 to be an empty matrix at the beginning of the function and only change it if conditions are satisfied. In that case if all conditions fails the function will return the default value - an empty matrix.
PS,
1. It is best not to use i and j as variable names in Matlab.
2. You can use mean instead of sum()/length().
3. instead of disp( sprintf(...) ) you may use fprintf(1, ... )

MATLAB: Using the If statement with a string to return values from other arrays

I have a matlab program where I am importing some arrays from excel. I am trying to write an if statement that looks in the first array, say:
Thing-1 Thing-1 Thing-3 Thing-5
If a column is a "Thing-1", then it goes to a different array, and calculates 3 values that are to be given different variable names...any guidance would be much appreciated! Thanks!
You need a function like vlookup as in Excel.
I have written one. Here is the source code:
function [content, index] = vlookup(m, e, column, lookcolumn)
if isempty(m) || isempty(e), return; end
if nargin <= 3, lookcolumn = 1; end
isechar = ischar(e);
assert(isechar || isnumeric(e), 'the second parameter must be a string or numeric');
if iscell(m)
content = {}; index = [];
if isechar
index = find(strcmp(e, m(:, lookcolumn)));
content = m(index, column);
else
for i = 1:size(m, 1)
if isnumeric(m{i, lookcolumn}) && m{i, lookcolumn} == e
content = [content; m(i, column)]; %#ok<*AGROW>
index = [index; i];
end
end
end
else
assert(~isechar, 'When the first para is a matrix, the second para must be numeric');
index = find(m(:, lookcolumn) == e);
content = m(index, column);
end
The question is... not very clear, but let me try and give you some suggestions.
Say you read some data from an Excel workbook in which the first row is headers, followed by lots of rows with numbers.
[num,txt] = xlsread(excelFileName);
so that num contains the numeric data and txt the string column headers.
Then you can check for the string Thing-1 in the column headers. thingOneIdx is an array with indices into the columns of the header. In your example, it would be [1 2], since the first two columns are Thing-1.
thingOneIdx = find(strcmp('Thing-1',txt));
You can create three cell arrays, firstValue, secondValue, and thirdValue that will store the results of the three calculations. If you need to keep the Thing-1 data around in an additional array, you can do that analogously.
%# define cell arrays (do it in one go using deal)
[firstValue,secondValue,thirdValue] = deal(cell(length(thingOneIdx),1));
%# for simplicity and readability, loop through isThingOneIdx to assign data
for ct = 1:length(thingOneIdx)
myIdx = thingOneIdx(ct);
firstValue{ct} = someCalculation(num(myIdx,:));
secondValue{ct} = someOtherCalculation(num(myIdx,:));
%# etc
end