How to deal with error 'Undefined function 'times' for input arguments of type 'struct'.' - matlab

A matlab program which was previously working for fine for about 6 months has starting giving the error
'Undefined function 'times' for input arguments of type 'struct'.' The line where this appears is
sampleData.allDiameters= sampleData.allDiameters* pixelToMicron;
When I try methods such as a loop or saving as another variable from one of the structure fields it saves the new variable as a structure, which previously it did not do. Some examples of this:
for n=1:length(measurements)
x=measurements(n); %saves x as 1x1 struct
measurements(n)=x*pixelToMicron;
end
%%%
measurements=sampleData.allDiameters; %saves measurements as a 276x1 struct
This was triggered after a small loop was added which has since been deleted. This was a while loop and hadn't even been included in the main program. Nothing else was edited. For clarity this is the loop (as far as I got with it)
function [sampleData]=sphereCheck(sampleData)
%for each object check how spherical each object is
%Measurement2: use regionprops to measure and record the x and y position
%of the corner of the smallest box which bounds the object [xpos ypos xwidth ywidth]
measurements2=regionprops(sampleData.binImage, 'BoundingBox');
sampleData.allDiameters
counter=1
while counter<length(measurements2)
%[~ ~ a b]=measurements2(counter);
end
I would like know how I can get the structures multiplying again or how I can access the data from the structure to perform operations on it.

Related

Array indices must be positive integers or logical value when read images in matlab

trying to read multi images in matlab in loop so error Array indices must be positive integers or logical values is appear
for i=1:12 % we have 16 images we have in or folder
clc;clear;
images ='/home/mohamed/Downloads/Lab6-20200415/Lab6-20200421/Lab6/Lab6/';
jpgfiles=dir(fullfile(images,'\*.jpg*'));
n=numel(jpgfiles(i));
im=jpgfiles(i).name;
im1=imread(fullfile(images,im));
d1 = rg2gray(iml);
imshow(im1);
end
Here is a minimal example demonstrating your problem:
for i=1:10
clear
jpgfiles=rand(10,1); %some dummy data to replace your actual code
jpgfiles(i);
end
the clear deletes the variable i which means i is the imaginary unit, not a valid index. Avoid the variable name i, it leads to difficult to debug problems. With other variable names, the much clearer error message would have been:
Unrecognized function or variable 'ix'.
Error in foo (line 4)
jpgfiles(ix);

MATLAB struct conversion error

I have 5 different structure and I want to calculate some variables for all of them. To do that, I wrote the following code:
for i=1:5
[StructureI(i), ReqTab(i), jt(i), B(i)]=Checkall(E);
end
The values StructureI, ReqTab, jt and B are calculated in another function and they are
StructureI= 1X4 matrix,
ReqTab= 4X2 matrix,
jt=2x1 matrix,
B=4x4 matrix
When I run the code it calculates all the varibles in the function Checkall. However, when it turns to the parent code, it gives and error "Conversion to double from struct is not possible."
How can I solve this problem?
Thanks in advance.
You cannot assign directly from double to struct, instead you have to write the specific field field_name to assign to:
[StructureI(i).field_name, ReqTab(i), jt(i), B(i)] = Checkall(E);
If all of these variables (i.e. also ReqTab, jt, B) are structures, then off course you need to specify the field in each one of them, using the . notation.
However, as mentioned in the comments, all iterations of your loop are just the same (no usage of i within it), so why do you need this loop? just to make 5 copies?

pass an array of structure through function using matlab

I'm working on MATLAB for image processing.I have a problem where we search the 3x3 neighbours of a pixel. If there are 2 or more neighbours then we store the number of neighbours and the pixel coordinates in a structure. The problem is I'm not able to pass this structure to the calling function.my structure is like this:
pixel=struct('count',{},'x',{},'y',{});
struct pixel p[]={};
for x=2:size(PEI,1)-1
for y=2:size(PEI,2)-1
if(PEI(x,y)==1)
p=windowmod(x,y);
end
end
end
Then I declare a function:
function [p]=windowmod(x1,y1)
When I run the code I get the following error:
??? Output argument "p" (and maybe others) not assigned during call to
"C:\Users\Prajnya\Desktop\IP programs\windowmod.m>windowmod".
Error in ==> step5modified at 17
p=windowmod(x,y);
I don't understand what this error means. I would be extremely grateful if someone could help me with this function.

MATLAB cell array of function handles - How does it work?

I am trying to understand the following commands of a MATLAB script :
global operatorObj
calcEVR_handles = operatorObj.calcEVR_handles;
m = operatorObj.nInputs
E = zeros(m,1);
V = zeros(m,1);
R = zeros(m,m);
for i=1:m
[E(i), V(i), R(i,i)] = calcEVR_handles{i}(t,x);
end
What can calcEVR_handles be, if t is a float and x is a vector?
calcEVR_handles (to me) looks like a cell array where each element is a handle to a function. Each element in calcEVR_handles is an anonymous function that takes in a single value t and a single vector x. As such, by doing calcEVR_handles{i}, you would access the corresponding function stored at the ith element in the cell array. Once you have access, you then pass your parameters to this function and it gives you those three outputs.
To show you an example of this working, consider the following cell array that works similarly to calcEVR_handles.
calcCellFunc = {#sin, #cos, #tan};
This is a three element cell array, where each element is a handle to a function. The # is a special character in MATLAB that denotes that you are creating a handle to a function. It's also used to create anonymous functions, but let's shelve that for this answer. You can read more about it here if you want to delve into more detail regarding this.
Back to our cell array of handles, we will make handles for sin, cos and tan. You can then iterate over your cell array by accessing the function you want by calcCellFunc{idx} where idx is the element you want in the cell array. This will ultimately give you the function stored at index idx. Once you do that, you can then call the function and specify whatever inputs you want (or none if it doesn't take any inputs). Here's a quick example for you. Let's create a random 5 x 5 matrix, and run through each function with this matrix serving as the input. We then take each of these outputs and store them into a corresponding slot in an output cell array. As such:
rng(123); %// Set seed for reproducibility
M = rand(5);
calcCellFunc = {#sin, #cos, #tan};
out = cell(1, numel(calcCellFunc)); %// To store the results for each function
for idx = 1 : numel(calcCellFunc)
out{idx} = calcCellFunc{idx}(M); %// Get the function, then pass
%// the matrix M to it
end
If you want to make things clear, you could split up the out statement to this instead:
func = calcCellFunc{idx}; %// Get access to the function
out{idx} = func(M); %// Pass M to this function
If you're new to handles / anonymous functions, you should probably use the above code first to make it explicitly clear on what MATLAB is doing. You are first getting access to the function you want that is stored in the cell array, and then you pass your arguments to this function.
If we display the output, we get:
>> celldisp(out)
out{1} =
0.6415 0.4106 0.3365 0.6728 0.5927
0.2823 0.8309 0.6662 0.1815 0.7509
0.2249 0.6325 0.4246 0.1746 0.6627
0.5238 0.4626 0.0596 0.5069 0.5737
0.6590 0.3821 0.3876 0.5071 0.6612
out{2} =
0.7671 0.9118 0.9417 0.7398 0.8054
0.9593 0.5564 0.7458 0.9834 0.6604
0.9744 0.7745 0.9054 0.9846 0.7489
0.8518 0.8866 0.9982 0.8620 0.8191
0.7522 0.9241 0.9218 0.8619 0.7502
out{3} =
0.8363 0.4503 0.3573 0.9094 0.7359
0.2942 1.4934 0.8932 0.1845 1.1370
0.2308 0.8167 0.4690 0.1773 0.8850
0.6149 0.5218 0.0597 0.5880 0.7004
0.8761 0.4135 0.4205 0.5884 0.8814
The first element of the output cell array has the output when you pass M to sin, the second when you pass M to cos, and the third when you pass M to tan.
So the next question you're asking... why is this useful?
Point #1 - Nix the copying and pasting
This kind of code writing is very useful because if you want to use the same inputs and supply them to many different functions, we would naturally be inclined to do some copying and pasting. Take each of your function names, and create a single line for each. Each line would call the corresponding function you want, followed by the input arguments. This can become quite tedious, and so one smart way to do it would be to place your function name as a handle into a cell array, and to write one for loop that goes over all of the functions dynamically. You could even explore cellfun and escape using the for loop to iterate over all of the function handles too, but I'll leave that for you to read up on.
In this way, you have very maintainable code and if you want to remove functions that don't need to be run, just remove the handles from the cell array rather than scrolling down to where the line that invokes this function is located and removing that.
This is actually a very common technique in computer science / software engineering in general. In fact, this is actually quite close to what are known as function pointers. This is MATLAB's cheap way of doing it, but the logic behind this is essentially the same.
Point #2 - Higher Order Functions
Another way this is useful is if you have a function where one (or more than one!) of the inputs is a function, and you also specify inputs into this function as additional parameters to this function. This is what is known as a higher order function. The outputs would be based on using this input function, and the additional inputs you specify to it and the outputs are based on using this input function and the inputs you specify for this function.
One very good example is the fzero function in MATLAB. The goal is to find the root of a non-linear function, and the first parameter is a handle to a function that you specify. The base behaviour behind how fzero works is the same no matter what the function is. All you have to do is specify the function you want to solve and the initial guess of where you think this root is.
All in all, anonymous functions are very useful.

Error: Attempt to reference field of non-structure array. (using global vars)

I'm trying to modify someone else's code that uses global variables and keep getting an error that I can't figure out. This is my first time using global variables, so I suspect it has to do with that. I'm getting this error:
Attempt to reference field of non-structure array.
Error in likelihood (line 35)
X=ModelInfo.X;
This is the code I run:
clearvars -global
clearvars
global ModelInfo
%Pull in data from MySQL database
ModelInfo.X=..... %76x2 double type
ModelInfo.y=..... %76x1 double type
addpath('C:/.../Sampling Plans');
addpath('C:/.../Constructing a Surrogate');
%Number of variables
k=size(ModelInfo.X,2);
%Number of sample points
n=size(ModelInfo.X,1);
%Set upper and lower bounds for search of log theta
UpperTheta=ones(1,k).*2;
LowerTheta=ones(1,k).*-3;
%Run GA search of likelihood
[ModelInfo.Theta,MinNegLnLikelihood]=ga(#likelihood,k,[],[],[],[],LowerTheta,UpperTheta);
...which references an outside function likelihood (written by someone else):
function [NegLnLike,Psi,U]=likelihood(x)
global ModelInfo
X=ModelInfo.X;
y=ModelInfo.y;
theta=10.^x;
p=2;
n=size(X,1);
one=ones(n,1);
% Pre-allocate memory
Psi=zeros(n,n);
% Build upper half of correlation matrix
for i=1:n
for j=i+1:n
Psi(i,j)=exp(-sum(theta.*abs(X(i,:)-X(j,:)).^p));
end
end
% Add upper and lower halves and diagonal of ones plus
% small number to reduce ill-conditioning
Psi=Psi+Psi'+eye(n)+eye(n).*eps;
% Cholesky factorisation
[U,p]=chol(Psi);
% Use penalty if ill-conditioned
if p>0
NegLnLike=1e4;
else
% Sum lns of diagonal to find ln(abs(det(Psi)))
LnDetPsi=2*sum(log(abs(diag(U))));
% Use back-substitution of Cholesky instead of inverse
mu=(one'*(U\(U'\y)))/(one'*(U\(U'\one)));
SigmaSqr=((y-one*mu)'*(U\(U'\(y-one*mu))))/n;
NegLnLike=-1*(-(n/2)*log(SigmaSqr) - 0.5*LnDetPsi);
end
UPDATE:
Figured out the problem. I declared ModelInfo as a global variable at the beginning, and then within the %Pull in data from MySQL database section I created a database connection and then cleared some variables we wouldn't need anymore using the clearvars -except command, but I didn't include ModelInfo in that list. After that I put data into ModelInfo. Since it's global, I guess that deleted either the local copy or the global copy (not quite sure), but it still appeared in the list of variables in the workspace and isstruct(ModelInfo) still returned 1...so visibly there was nothing to indicate an issue other than the error.
If that is indeed the code you run:
%Pull in data from MySQL database
ModelInfo.X=..... %76x2 double type
ModelInfo.y=..... %76x1 double type
I doubt it has anything to do with global variables. You should have some data of some sort instead of the 5 dots ..... in order to make any code work (as the comment that is placed above indicate "pull data from..."). I'd also try to make this data in the form that the comments suggest if it isn't of the same class, i.e. make it double and of the size mentioned.
For example, try to see if replacing these lines with this makes your code work
ModelInfo.X=rand(76,2) %76x2 double type
ModelInfo.y=rand(76,1) %76x1 double type