I am wondering if its possible to have conditional statements in a function argument.
for ex,
testarray = [1,5,8,5,7,23,61,16]
psum = sum(testarray>2 & testarray<10)
will it possible to implement something like this in matlab.
I would really appreciate an example.
Yes, please see the example below using your data.
testarray = [1,5,8,5,7,23,61,16]; % your array
Find sum of all numbers greater than 2 and less than 10 in testarray
psum = sum(testarray(testarray>2 & testarray<10));
The idea is that you find the indices of the numbers that meet the condition (i.e., testarray>2 & testarray<10 in this case), extract the numbers by indexing into testarray, and then sum them.
Related
Consider the arbitrary function:
function myFunc_ = myFunc(firstInput, secondInput)
myFunc_ = firstInput * secondInput;
end
Now imagine I want to map the above function to an array for the first input firstInput, while the second input secondInput is constant. For example, something like:
firstVariable = linspace(0., 1.);
plot(firstVariable, map(myFunc, [firstVariable , 0.1]))
where 0.1 is an arbitrary scalar value for the secondInput and firstVariable array is an arbitrary array for the firstInput.
I have looked into the arrayfun() function. However, I don't know how to include the constant variable. Plus it seems like the syntax between MATLAB and Octave are different, or maybe I'm mistaken. It is important for me to have a cross-compatible code that I can share with colleagues.
Assuming in the original function you were multiplying two scalars and you want to vectorise, then
function myFunc_ = myFunc(firstInput, secondInput)
myFunc_ = firstInput .* secondInput;
end
should work just fine.
Then plot it directly:
plot( firstVariable, myFunc(firstVariable , 0.1) )
I'm afraid the arbitrary examples given in the original question were too simplified and as a result, they do not represent the actual issue I'm facing with my code. But I did manage to find the right syntax that works inside Octave:
plot(firstVariable, arrayfun(#(tempVariable) myFunc(tempVariable, 0.1), firstVariable))
basically the
#(tempVariable) myFunc(tempVariable, 0.1)
creates what is so-called an anonymous function and the
arrayfun(<function>, <array>)
maps the function over the given array.
I would be happy to hear somebody explain me the meaning of 1: before the function below please.
yActual = data2_test.Response;
x = 1:numel(yActual)';
A single colon operator in the context of your snippet is a short-hand way of creating a vector:
start_number:end_number
equivalent to
[start_number, start_number+1, start_number+2, ... end_number-1,end_number]
In your specific case, the variable x is a vector from 1,2,3... up to the number of elements in data2_test.Response.
I have an excel file and I need to read it based on string values in the 4th column. I have written the following but it does not work properly:
[num,txt,raw] = xlsread('Coordinates','Centerville');
zn={};
ctr=0;
for i = 3:size(raw,1)
tf = strcmp(char(raw{i,4}),char(raw{i-1,4}));
if tf == 0
ctr = ctr+1;
end
zn{ctr}=raw{i,4};
end
data=zeros(1,10); % 10 corresponds to the number of columns I want to read (herein, columns 'J' to 'S')
ctr=0;
for j = 1:length(zn)
for i=3:size(raw,1)
tf=strcmp(char(raw{i,4}),char(zn{j}));
if tf==1
ctr=ctr+1;
data(ctr,:,j)=num(i-2,10:19);
end
end
end
It gives me a "15129x10x22 double" thing and when I try to open it I get the message "Cannot display summaries of variables with more than 524288 elements". It might be obvious but what I am trying to get as the output is 'N = length(zn)' number of matrices which represent the data for different strings in the 4th column (so I probably need a struct; I just don't know how to make it work). Any ideas on how I could fix this? Thanks!
Did not test it, but this should help you get going:
EDIT: corrected wrong indexing into raw vector. Also, depending on the format you might want to restrict also the rows of the raw matrix. From your question, I assume something like selector = raw(3:end,4); and data = raw(3:end,10:19); should be correct.
[~,~,raw] = xlsread('Coordinates','Centerville');
selector = raw(:,4);
data = raw(:,10:19);
[selector,~,grpidx] = unique(selector);
nGrp = numel(selector);
out = cell(nGrp,1);
for i=1:nGrp
idx = grpidx==i;
out{i} = cell2mat(data(idx,:));
end
out is the output variable. The key here is the variable grpidx that is an output of the unique function and allows you to trace back the unique values to their position in the original vector. Note that unique as I used it may change the order of the string values. If that is an issue for you, use the setOrderparameter of the unique function and set it to 'stable'
This is NOT a question where I need to know how to add A+B in MATLAB. This is more of a code design question.
I have few function files that return a numeric matrix and index info on the matrix. For example
function [Mat1, IdxID, IdxDate, IdxVal, IdxMarker, IdxOpen, ...] = First ()
....
.... % where IdxId = 1 ; IdxDate = 2 ; ...
end
function [Mat1, IdxUid, IdxName, IdxVal, Mat2, IdxUid2, IdxSalary2, ...] = Second ()
....
.... % where IdxUid= 1 ; IdxName= 2 ; ...
end
As you can see the code becomes clunky and when I call these functions, I have to declare an equal number of outputs to catch all the indices. The advantage is if I suddenly swap ID & Date columns, the calling functions do not change as I simply make ID=2, Date=1. I also have the advantage of renaming these variables inside the function.
Is there a better way to do this? I'm testing whether struct or cell can be used for indices. I can't use datasets or cell for returning numeric matrix. Too much time is lost in translating it into numbers. Thanks.
Yes, you can return arrays/cells/structs instead. For instance, id can be a struct with multiple variables. Your function definition could be as follows.
function [Mat, Id] = Second ()
...
end
In your function, have the following set:
Id.Name
Id.Val
Id.Salary
...
If you find that you have multiple structs with the same exact structure, you can even consider objects.
Please clarify with more details on the structure if you want a more detailed answer.
I want to replace the value of the fields in a structure array. For example, I want to replace all 1's with 3's in the following construction.
a(1).b = 1;
a(2).b = 2;
a(3).b = 1;
a([a.b] == 1).b = 3; % This doesn't work and spits out:
% "Insufficient outputs from right hand side to satisfy comma separated
% list expansion on left hand side. Missing [] are the most likely cause."
Is there an easy syntax for this? I want to avoid ugly for loops for such simple operation.
Credits go to #Slayton, but you actually can do the same thing for assigning values too, using deal:
[a([a.b]==1).b]=deal(3)
So breakdown:
[a.b]
retrieves all b fields of the array a and puts this comma-separated-list in an array.
a([a.b]==1)
uses logical indexing to index only the elements of a that satisfy the constraint. Subsequently the full command above assigns the value 3 to all elements of the resulting comma-separated-list according to this.
You can retrieve that the value of a field for each struct in an array using cell notation.
bVals = {a.b};
bVals = cell2mat( bVals );
AFAIK, you can't do the same thing for inserting values into an array of structs. You'll have to use a loop.