What is a cell array?[]
A cell is a flexible type of variable that can hold any type of variable. A cell array is simply an array of those cells. It's somewhat confusing so let's make an analogy. A cell is like a bucket. You can throw anything you want into the bucket: a string, an integer, a double, an array, a structure, even another cell array. Now let's say you have an array of buckets - an array of cells or a "Cell Array". Each bucket can contain something different, or they might all contain the same type of variable. Bucket 1 could contain a string, while bucket 2 could contain an image (array of uint8's), while bucket 3 could be a int32. Or all buckets could contain strings of various lengths. It's totally flexible.
ca{1} = myString; ca{2} = myInteger; ca{3} = myDoubleArray; ca{4} = rgbImage; ca{5} = myStructure;
The braces should be read as "contents of", so if you say ca{4} = rgbImage, you are saying that "the content of" cell #4 is the variable rgbImage.
Another way to use the cell is to refer to the cell itself, rather than the contents of it, and for that you use parentheses. The item it refers to must be a cell. For example ca(1) is a cell, ca(2) is a cell, and ca(3) is a cell, even though those cells contain variables of arbitrary, and possibly different, types. To make something a cell, you enclose it in braces, like this:
ca(1) = {myString}; ca(2) = {myInteger}; ca(3) = {myDoubleArray}; ca(4) = {rgbImage}; ca(5) = {myStructure};
This set of code is entirely equivalent to the first set of code. For the first line, it's basically like saying "Let's get a bucket (a cell) and put the string into it - that's what {myString} by itself is. myString is the character variable and {} is the bucket so {myString} is the variable inside a bucket. Then let's take that bucket and make it bucket #1, replacing any bucket that was already there." In other words, take the cell {myString} and make it be element #1 (bucket #1) of the cell array called "ca." It uses parentheses which means it refers to the whole single bucket (the bucket plus the contents) while the first set of code used braces which refers to only the contents of the bucket. So ca(1) equals the cell "{myString}", while ca{1} equals the string "myString" because the braces said to get the contents of the cell. In other words, ca{1} says don't give me the bucket with the string inside, just give me the string alone, without the bucket. It's just a slight difference - a slightly different way of considering it. Saying
ca(1) = {myString}; % or saying ca{1} = myString;
are equivalent for the most part. You can use either way and I don't really think one way or the other is really preferred. You can use whatever way is easier for you to think about it. Maybe one way will be more intuitive for you than the other way, but again, they are equivalent.
Cell arrays are similar to structures, which you probably are more familiar with, in that both are containers that can hold variables of a variety of different types (arrays, strings, scalars, even other structures or cells). The difference is that with structures you refer to the different "members" or "fields" by their name after a dot (e.g. UserSettings.myString), while with cells you refer to them by their index number inside braces (e.g. ca{1}).
Here is some demo code that may help explain cell arrays, and the type of classes you get when you use braces or parentheses:
% Initialize a cell array with three different types of contents. % First cell contains an int32, second cell contains a string, % and the third cell contains a double array. ca = {int32(123), 'abcdef', pi*ones(3)} % Let's see what's in cell #1 and the difference between % using ( ) and using { }. ca1cell = ca(1) fprintf('\nThe class of ca1cell is %s\n', class(ca1cell)) ca1contents = ca{1} fprintf('The class of ca1contents is %s\n\n', class(ca1contents)) % Let's see what's in cell #2 and the difference between % using ( ) and using { }. ca2cell = ca(2) fprintf('The class of ca2cell is %s\n', class(ca2cell)) ca2contents = ca{2} fprintf('The class of ca2contents is %s\n\n', class(ca2contents)) % Let's see what's in cell #3 and the difference between % using ( ) and using { }. ca3cell = ca(3) fprintf('\nThe class of ca3cell is %s\n', class(ca3cell)) ca3contents = ca{3} fprintf('The class of ca3contents is %s\n\n', class(ca3contents)) % Now let's see what gets displayed when we use the % celldisp() function specially made for displaying cells: fprintf('\nHere is what celldisp returns:\n') celldisp(ca);
One use of cell arrays is to hold lists of strings of different lengths. Since arrays are rectangular, you can't have an character array of strings unless each string was the same length (or padded with blanks to be as long as the longest string). To get around that, you can use a cell array instead of a character array. Each cell in the cell array would hold a string of a different length - they don't have to all be the same length like with a character array. For example:
ca = {'Short'; 'A little longer'; 'A really really long string'}
If you get strange error messages while working with cells or cell arrays, one easy thing to try is to change your braces into parentheses, or your parentheses into braces, and see if that eliminates the errors.
It's also possible to mix indexing of the row and column of the cell array with the indexing of the contents of the single cell at that row and column of the cell array. For example, let's create a cell array of 2 rows and 3 columns, and in every cell of that let's put a 4 element integer array. Then we'll access the second element of the integer array at the cell in row 1, column 2 of the cell array.
% Create an empty cell array of 2 rows and 3 columns. % Each element in the array is a single cell. rows = 2; columns = 3; c = cell(rows, columns); % Now, for each cell in the cell array, % put an array of 4 random integers (in the range 1-99). for column = 1: columns for row = 1 : rows randomNumberArray = randi(99, [1, 4]); c{row, column} = randomNumberArray; % An alternate way of specifying is given on the next line. %c(row, column) = {randomNumberArray}; % Note changes in braces and parentheses. fprintf('The integer array in row #%d, column #%d of the cell array = [%d, %d, %d, %d]\n',... row, column, randomNumberArray(1), randomNumberArray(2), randomNumberArray(3), randomNumberArray(4)); end end % Print out the second element of the 4-element integer array % from the cell at the (1,2) position of your 2D array of cells. ourValue = c{1,2}(2) fprintf('The second element of the integer array in cell row %d, column %d is %d\n',... row, column, ourValue);
To visualize, imagine you had an array of buckets arranged in 2 rows and 3 columns (this is our cell array), and in each bucket are 4 billiard balls arranged in a line. The above example goes to the bucket in the first row and second column, and reads off the number of the second billiard ball in that bucket.
For further discussion see Loren Shure's blog: [1]
For more information, this link gives good examples about accessing cell data: http://www.mathworks.com/help/matlab/matlab_prog/access-data-in-a-cell-array.html
Does MATLAB only calculate to 4 significant digits?[]
It doesn't. Don't worry - your number is not truncated. It uses full double-precision floating point numbers to calculate everything. However, by default it only prints a few decimal places to the screen in the command window. You can change this, to print out more decimal places, using the command:
>> format long
Type:
>> help format
for more information.
Why does the transpose operator take the complex conjugate?[]
When performing linear algebra operations on complex matrices, it is almost always the complex conjugate transpose (also called the Hermitian transpose) that is needed (see Gilbert Strang's linear algebra book for discussion- page 293 in edition 3). The bare apostrophe is an operator that takes the complex conjugate transpose. The non-conjugating transpose operator is a period followed by an apostrophe. Type help punct for more info.
>> A' % complex conjugate transpose >> A.' % transpose
How can I detect NaN values in a matrix or vector?[]
By definition, NaN
is not equal to any number, not even NaN
itself. Therefore there are two ways to detect NaN
values:
% Generate sample data x = rand(1, 10); x(x > 0.5) = NaN; % Find NaN values in two different ways y1 = isnan(x) ; y2 = (x ~= x) ;
For speed purposes the use of isnan()
tends to be 20%-30% faster. Here's a test snippet if you want to see the comparison:
A = rand(1000); %Random 1000x1000 matrix A(rand(size(A))>.75) = nan; %Populate with NaNs t1 = 0; %time of isnan t2 = 0; %time of ~= for ii = 1:100 tic idx1 = isnan(A); t1 = t1+toc; tic idx2 = A~=A; t2 = t2 + toc; end ratio = t2/t1; %ratio of ~= to isnan isequal(idx1,idx2) %Insure same results %{ ratio = 1.2179 ans = 1 %}
How can I make MATLAB use the full window width for displaying matrices?[]
In R12 (MATLAB 6.0), this can be controlled via a preference. Select the File | Preferences... menu item, and select Command Window in the Preferences dialog that appears. In the Display section, there's a checkbox labeled Limit matrix display width to eighty columns. Unchecking that box allows matrix displays to make full use of the Command Window's width. [Unchecked is the default.]
Starting with MATLAB R12.1, users can access the current command window size using the root property CommandWindowSize. That is, sz=get(0, 'CommandWindowSize');
. In R12.0, there is no way to do this unless you call undocumented C functions from a MEX file.
How do I comment out a large block of code?[]
Starting in MATLAB 7 (R14), the syntax is:
%{ Stuff to be commented out %}
You can also highlight a section of code and type control-r to comment out the code -- this will place a percent symbol (%) at the beginning of the line. Typing control-t will uncomment the lines by removing any percent symbol that is the first non-blank character on the line.
If you have an older version, the built-in editor in MATLAB 6.0 has a block-comment feature, which will simply put a comment character on each line. Or you can use matlab-mode for Emacs, which supports this as well.
If you are using an even older version, use this:
if 0 commented out code end
This is not the best solution, since parse errors inside that block will cause an error.
How do I save default settings across sessions?[]
The key is to create a startup.m file. Look at the online helpfor more detailed instructions specific to your operating system.
How can I find local maxima in a vector array?[]
You can use the following one-line function to determine the indices of the local maxima.
function index = localmax(x) index = find( diff( sign( diff([0; x(:); 0]) ) ) < 0 );
If you have the Image Processing Toolbox, you can use the imregionalmax() function. If you have the Signal Processing Toolbox you can use the findpeaks() function.
Why is 6*i not a complex number in my program?[]
You may have used a variable called "i" earlier in your program or session, thus overwriting the imaginary constant i with your own number. In this case, MATLAB will use your new value for i instead of treating i as sqrt(-1). Five ways to ensure that you receive a complex result are:
- Use the syntax 6i; MATLAB always interprets this as 6*sqrt(-1)
y = 6i;
- Redefine i back to sqrt(-1)
i=sqrt(-1) y = 6*i;
- Clear your redefinition of i
clear i y = 6*i;
- Use j instead of i (assuming you haven't used a variable called "j" earlier in you program or session)
Note: these are very good reasons for not using i & j as indexes (in FOR loops, for example)
y = 6*j;
- Use the COMPLEX function
y = complex(0, 6);
How can I modify the MATLAB path?[]
Easiest solution: use the PATHTOOL GUI. Or if you want command line access:
Suggested by Joshua Stiff: You can use addpath to add directories from the command line, and path2rc to write the current path back to `pathdef.m'. If you do not have write permissions for `pathdef.m', path2rc can write to a different file, which you can execute from your 'startup.m'.
What are the versions of MATLAB and associated runtime files?[]
These are documented in some technical solutions Solution 1-4GSNCF Solution 1-1IW46N
R14 - Matlab 7.0 - MCR 7.0 - compiler 4.0 - mclmcrrt70.dll R14SP1 - Matlab 7.0.1 - MCR 7.1 - compiler 4.1 - mclmcrrt71.dll R14SP2 - Matlab 7.0.4 - MCR 7.2 - compiler 4.2 - mclmcrrt72.dll R14SP3 - Matlab 7.1 - MCR 7.3 - compiler 4.3 - mclmcrrt73.dll R2006a - Matlab 7.2 - MCR 7.4 - compiler 4.4 - mclmcrrt74.dll R2006b - Matlab 7.3 - MCR 7.5 - compiler 4.5 - mclmcrrt75.dll R2007a - Matlab 7.4 - MCR 7.6 - compiler 4.6 - mclmcrrt76.dll R2007b - Matlab 7.5 - MCR 7.7 - compiler 4.7 - mclmcrrt77.dll R2008a - Matlab 7.6 - MCR 7.8 - compiler 4.8 - mclmcrrt78.dll R2008b - Matlab 7.7 - MCR 7.9 - compiler 4.9 - mclmcrrt79.dll R2009a - Matlab 7.8 - MCR 7.10 - compiler 4.10 - mclmcrrt710.dll R2009b - Matlab 7.9 - MCR 7.11 - compiler 4.11 - mclmcrrt711.dll R2009bSP1 - Matlab 7.9.1 - MCR 7.12 - compiler 4.12 - mclmcrrt712.dll R2010a - Matlab 7.10 - MCR 7.13 - compiler 4.13 - mclmcrrt713.dll R2010b - Matlab 7.11 - MCR 7.14 - compiler 4.14 - mclmcrrt714.dll R2011a - Matlab 7.12 - MCR 7.15 - compiler 4.15 - mclmcrrt715.dll R2011b - Matlab 7.13 - MCR 7.16 - compiler 4.16 - mclmcrrt716.dll R2012a - Matlab 7.14 - MCR 7.17 - compiler 4.17 - mclmcrrt717.dll
Error Messages[]
"Subscript indices must either be real positive integers or logicals."[]
In MATLAB all array indices must be logical or positive numeric integers. This means that the following is permitted:
>> A = [123,456,789];
>> A(2) % 2 is an integer ans = 456
>> logicalIndexes = A > 400 % Produces a logical (boolean) array of true (1) and false (0) logicalIndexes = 0 1 1 >> A(logicalIndexes) ans = 456 789
But the following produces an error:
>> A(3.14159) % 3.14159 is not an integer Subscript indices must either be real positive integers or logicals.
>> A(0) Subscript indices must either be real positive integers or logicals.
>> A(-1) Index exceeds matrix dimensions.
Note that fractional numbers, negative integers, zero, and complex/imaginary numbers are not permitted indices. Note that zero is only permitted as an index if it's not really an integer or double zero, but really "false" - a logical data type. When MATLAB displays logical values it uses 0 and 1 rather than "false" and "true".
The reason is that the indexes refer to rows and columns in the array. So while you can have row #1 or column #3, you can't have row #3.14159, nor can you have the 0th row or column, or the (-1)th row or column.
To fix the error you must make sure that your indexes are real, positive integer numbers, or logicals. They can be scalars (single numbers) or vectors or arrays of many numbers. You might take the expression for your index and make it into a single variable, like myIndexes, and then examine that in the variable editor or use code like this to figure out it's real data type and value:
myIndexes = (some complicated expression) format long myIndexes % No semicolon so will print directly to the command line. whos myIndexes % Displays data type, e.g. int32, double, logical, structure, etc.
The official Mathworks answer to this question can be found here: [2]
The most common reason this message arises is because people come to MATLAB from other programming languages and are not aware of the fact that MATLAB indexing begins at 1. A(1) is the first element in a vector, and A(1, 1) is the first element in a matrix, not A(0) or A(0,0) like in other programming languages!
A = magic(3) A = 8 1 6 3 5 7 4 9 2 A(0) Subscript indices must either be real positive integers or logicals.
There are a number of theories for why MATLAB uses 1-based indexing, but ultimately the answer is pretty simple. 1-based indexing is the language of Mathematics, as confirmed by Cleve Moler himself in a comment on this April Fools blog post.
We have always had BOTH 0-based indexing and 1-based indexing. In order to distinguish between the two, 0-based indices are followed by “+1″. The 1-based indices are preferred becaused they are the language of mathematics. — Cleve
If you’re interested in this, a quick Google search will turn up many results, as it has a long and contentious history! This error message can also arise if you use a noninteger (or negative) value to index. What is MATLAB supposed to do with A(1.5) or A(-3)? In this context, you should check the bounds of any loop statements in your code to make sure they aren’t producing decimal or negative values for indexing.
A = randi(9, 4, 1); % A is a 4 element long vector from A(1) to A(4)
for k = -1 : 6
if k < 1 || k > length(A)
message = sprintf('%d is outside the acceptable range is 1 - %d', k, length(A));
uiwait(warndlg(message));
continue;
end
fprintf('A(%d) = %f.\n', k, A(k));
end
Another common reason for this error is that you defined a variable and a function with the same name and then tried to use it and MATLAB is confused as to whether you want the function context or the variable context. For example, in a script you have
function MyScript() f = 5; y = f(-3.9); % Double the input argument of -3.9 by calling the function f end %-------------------------------------------------------------------------- function outputValue = f(inputValue) outputValue = inputValue * 2; end
When it goes to assign y and you want it to call f, MATLAB at that point thinks that f is a variable, specifically a vector variable because you used parentheses. Since it thinks it's a vector, it assumes you're trying to access index -20. Well, you defined f as a scalar, not a vector, so there is only one index, and regardless, vectors do not have an index of -20 or any indexes less than one, or any indexes that are not an integer. In a vector there is no -3.9'th element of the vector. You could estimate one by interpolating to get a new variable, but with the original vector variable there is no such index.
"In an assignment A(I) = B, the number of elements in B and I must be the same"[]
This error is encountered when you try to place more elements into A that are specified by the I variable. For example if A is a simple vector, and I is a simple index, like 3, then trying to put 100 numbers into A(3) will obviously not work.
"Error using horzcat. Dimensions of arrays being concatenated are not consistent."[]
This error is encountered when you try to horizontally concatenate arrays that do not have the same number of rows. Matrices with a ragged bottom edge are not allowed, unless you use a cell array. For example, this code will demonstrate the error:
% Define 1-D row vectors and 2-D matrix. v1 = [1,2,3] % One row vector. v2 = [4,5,6] % Another one-row vector. m = [1,2,3; 7,8,9] % A two-row matrix.
% Now try to horizontally concatenate them. % These lines will work: v12a = horzcat(v1, v2) % This will work because both have one row. v12b = [v1, v2] % This will work because both have one row.
% Neither of these will work because you can't have different number of rows in each column. % In other words you can't have a ragged bottom edge like: % 1 2 3 1 2 3 % 7 8 9 % Because columns 1-3 have only 1 row while columns 4-6 would have two rows. badMatrix = horzcat(v1, m) % Throws error badMatrix = [v1, m] % Throws error % Running either of those two lines would throw this error: % Error using horzcat % Dimensions of arrays being concatenated are not consistent.
"Error using vertcat. Dimensions of arrays being concatenated are not consistent."[]
This error is encountered when you try to vertically concatenate arrays that do not have the same number of columns. Matrices with a ragged right edge are not allowed, unless you use a cell array. For example, this code will demonstrate the error:
% Define 1-D column vectors and 2-D matrix. v1 = [1;2;3] % One column vector. v2 = [4;5;6] % Another one-column vector. m = [1,2,3; 7,8,9] % A two-row matrix.
% Now try to vertically concatenate them. % These lines will work: v12a = vertcat(v1, v2) % This will work because both have one column. v12b = [v1; v2] % This will work because both have one column.
% Neither of these will work because you can't have different number of columns in each column. % In other words you can't have a ragged right edge like: % 1 % 2 % 3 % 1 2 3 % 7 8 9 % Because rows 1-3 have only 1 column while rows 4-5 would have three columns. badMatrix = vertcat(v1, m) % Throws error badMatrix = [v1; m] % Throws error % Running either of those two lines would throw this error: % Error using vertcat % Dimensions of arrays being concatenated are not consistent.
“Dimensions of arrays being concatenated are not consistent.”[]
This error is encountered when you try to vertically concatenate arrays that do not have compatible sizes. For example, to vertically concatenate two matrices A and B, they must have the same number of columns:
A = ones(2,3) B = ones(5,3) C = [A; B] % Works!
A and B both have 5 columns so this is OK - they can be stitched together vertically. C is a matrix with 7 (= 2 + 5) rows and 3 columns.
However, if B has 4 columns instead of 3, you will get the error if you try to stitch them vertically. For example,
B = ones(5,4) C = [A; B] % Throws error!
For an example in the other direction, to horizontally concatenate two matrices A and B, they must have the same number of rows:
A = ones(5,3) B = ones(5,7) C = [A; B]
A and B both have 5 rows so this is OK - they can be stitched together horizontally. C is a matrix with 5 rows and 10 (= 3 + 7) columns.
For more information on concatenation in general, see https://www.mathworks.com/help/matlab/math/creating-and-concatenating-matrices.html.
"Function definitions are not permitted in this context."[]
You can have multiple functions defined in one m-file, but before Matlab R2016b you can't have a script followed by one or more functions in the same m-file. For example, this m-file:
% This is the m-file called test.m, composed of a script followed by a function. % It will generate an error. clc; % Clear the command window. m = magic(7); MyCustomFunction(m) % Define a custom function in the m-file function MyCustomFunction(m) disp(m);
will generate an error in R2016a and earlier versions:
Error: File: test.m Line: 8 Column: 1 Function definitions are not permitted in this context
because lines 1-5 are a script, and 7-9 are a function. To fix, add a "function" line as the first line in your code (after any comments) and it will work. See below:
% This is the m-file called test.m composed of two functions. function test() clc; % Clear the command window. m = magic(7); MyCustomFunction(m) % Define a custom function in the m-file function MyCustomFunction(m) disp(m);
If you don't have that function line, it's a script, and you can't then define functions later (further down) in your code. By adding that line, you'll be making a function out of the first few script lines in your m-file, and when all code is contained in functions, there is no error.
If you have a version BEFORE R2016b (i.e. R2016a and before), then read below. It does NOT apply to version R2016b and later.[]
You cannot mix a script and function(s) in the same m-file. You can have a script, and that script can call functions in other m-files, or you can have all functions with no script at all. Most likely you have forgotten to include the "function" keyword and the name of your m-file as the first executable line of your m-file. If you do that, it will probably work. See the following examples:
Example 1 : script and function = not allowed:
% This test.m contains a script and a function, SomeFunction(). % You can not do this. It does not work because you % cannot mix a script with a function in the same m-file. % You will get the error "Function definitions are not permitted in this context." % If SomeFunction() were in a separate m-file, SomeFunction.m, % instead of in the same m-file, test.m, then it would work. % Here is the script: clc; % Clear the command window. workspace; % Make sure the workspace panel is showing. format compact; m = randi(9, 2, 3) output = SomeFunction(m) % Here is the function: function output = SomeFunction(m) output = 2 * m; % Multiply m by 2.
Example 2 : two functions = allowed:
% This test.m contains two functions: test() and SomeFunction() % You can do this. Because it has only functions, % and does not have a script, it works. % Because the first executable line of code is "function test" % that turns it from a script into a function and allows it to work. % Here is the first function, that has the name of the m-file: function test % <----- Key function definition keyword! clc; % Clear the command window. workspace; % Make sure the workspace panel is showing. format compact; m = randi(9, 2, 3) % Define sample data. output = SomeFunction(m) % Call SomeFunction() % Here is the second function. It should not take on the name % of any built-in MATLAB function to avoid conflict. function output = SomeFunction(m) output = 2 * m; % Multiply m by 2.
Note: if the name of the first function declared in the m-file does not match the file name, it will execute when called by the file name, not the name after the function keyword. For example, in the second example above, if we had improperly called the function TestFunction
function TestFunction
then the code would execute by issuing the command "test" because that's the name of the m-file. Issuing the command "TestFunction" would give the error "Undefined function or variable 'testFunction'."
"Subscripted assignment dimension mismatch"[]
For the official Mathworks answer, please see http://www.mathworks.com/matlabcentral/answers/93586-why-do-i-get-the-subscripted-assignment-dimension-mismatch-error-message
This error message arises because of an attempt to assign a vector or matrix into a compartment that it does not fit in. The dimension of the subscripted elements does not match the dimension of the assignment. For example, you cannot assign the first element in a matrix to be a vector, because there is only room for 1 element:
A = magic(3) A = 8 1 6 3 5 7 4 9 2 A(1) = [4 5 6] Subscripted assignment dimension mismatch.
This error can be much more subtle when you’re working with large matrices or loops, and it can occur because of a mismatch on either side of the equals sign. Sometimes the size of a vector or matrix can grow in an unexpected way in a loop, and you’ll receive this message and wonder what went wrong. The best way to debug this error is to double check that all of your assignments are the sizes you expect them to be, and that your matrices are growing (or not) as you expect them to. If you don’t have any loops, just break the statement apart and check the size of each side. You won’t get this error if the sizes match exactly:
size(A(1:3)) ans = 1 3 size([4 5 6]) ans = 1 3 A(1:3) = [4 5 6] A = 4 1 6 5 5 7 6 9 2
"Output argument "y" (and maybe others) not assigned during call to MyFunction"?[]
This will happen if your code is supposed to return a variable but in the function you never assign that variable. For example if the code is:
function y = MyFunction(x) if x >= 1 y = x; % Only executes if x >= 1. end
then MyFunction(2) would first test if 2 >= 1 and a value would be assigned to y in that case. However if you passed in 0, MyFunction(0), then the if block would not be entered and the function would finish without a value ever being assign to y. The programmer must account for all possibilities. Often this means assigning default values immediately upon entering the function:
function y = MyFunction(x) y = 0; % Assign something to y so it will have a value no matter what. if x >= 1 y = x; end
Above we immediately assign a value of 0 to y so that even if a value of x is entered such that the if block never gets entered, y will still have a value.
Why do I receive an error about an undefined variable or the recursion limit when calling ODE45?[]
One common cause of an "Undefined function or variable" error or an error about the RecursionLimit being exceeded when using an ODE solver like ODE45 is that the function being called by the ODE solver itself contains the call to the ODE solver. For instance, if your code is:
function dy = myodefunction(t, y) dy = [y(2); 2*t]; y0 = [0; 1]; tspan = [0 10]; [t, y] = ode45(@myodefunction, y0, tspan);
If you call myodefunction with no inputs, you will receive an error on the second line, where MATLAB tries to use t and y to define dy. If you call myodefunction with two inputs, it will proceed without error to the ODE45 call. ODE45 will call myodefunction with two inputs, and that call will proceed without error to the ODE45 call. This process will repeat until ODE45 has recursively call myodefunction a number of times equal to the root RecursionLimit property, at which point MATLAB will throw an error.
To avoid these errors, do not include the call to the ODE solver inside your ODE function (the function you pass to the ODE solver as the first input argument.) Instead, define the ODE function in a subfunction or as a separate function file and use that in your ODE45 call.
The subfunction approach requires one function file:
% begin myodefunction.m function [t, y] = myodefunction y0 = [0; 1]; tspan = [0 10]; [t, y] = ode45(@myodesubfun, y0, tspan); function dy = myodesubfun(t, y) dy = [y(2); 2*t]; % end myodefunction.m
The separate file approach requires one function or script file that calls ODE45:
% begin myodefunction.m function [t, y] = myodefunction y0 = [0; 1]; tspan = [0 10]; [t, y] = ode45(@myodeseparatefun, y0, tspan); % end myodefunction.m
and a function file that ODE45 will call:
% begin myodeseparatefun.m function dy = myodeseparatefun(t, y) dy = [y(2); 2*t]; % end myodeseparatefun.m
"Inner matrix dimensions must agree."[]
One of the most common error messages weI see posted about by new users is this one. They create a few matrices or vectors, and just go to multiply them with A*B, and this message is returned. Some example code that produces this message is:
A = [1 2 3]; B = [4 5 6]; A*B
And get the error using "Inner matrix dimensions must agree." The key to this error message is usually that people are not aware of the elementwise operators in MATLAB. The * operator performs matrix multiplication, where an NxM matrix is multiplied by an MxP matrix, resulting in an NxP matrix. Notice how those matrices have the common dimension “M”? That’s where this message comes from; it’s a common inner dimension. Most often, you simply need to use .* instead of * to perform the elementwise multiplication, where corresponding elements are multiplied and the result is the same size as the inputs.
A.*B ans = 4 10 18
For more information about the different MATLAB operators, see Array vs. Matrix Operations. Note that even though this error message is the most common in this situation (since, well, multiplication is pretty popular) there are similar messages for the misuse of ^ , / , and \ as opposed to .^ , ./ , and .\ .
"Index exceeds matrix dimensions."[]
Quite simply, this error arises when you try to reference an element that doesn’t exist. For example, if the matrix has N elements, and you try to index into the N+1 element:
A = magic(5) A = 17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 9 A(26) Index exceeds matrix dimensions.
To fix this error, double check that the matrix is the size you were expecting it to be, and that the index you’re using is also what you expect. For example, if the index is the result of a calculation or is part of a loop, then you might need to adjust the calculation, or the number of loop iterations. Some useful functions to check sizes and number of elements are numel(), size(), and length().
"The expression to the left of the equals sign is not a valid target for an assignment."[]
This error can occur because of a mismatched or missing closing brace, bracket, or parenthesis.
myFunction = @(a,b)a+b;
str = 'myFunction (a,b);';
vec = {1,2,; % !!! unmatched curly brace !!!
foo = str2func(strcat('@(a,b)',str));
foo(2,3)
This error seems to occur with older versions of MATLAB. Newer versions will give the "Incorrect use of '=' operator."
"Incorrect use of '=' operator."[]
This error message arises because of misuse of the = and == operators. The = operator does an assignment, and the == operator does a logical test for equality. In the context of an if statement, for example, the if operator is expecting to see a logical expression, that can be evaluated to a single true or false value, to determine whether to continue executing the code inside the if block. So the following example code produces this error:
n = 5; if n = 4 n = n.^2; end
You get the error "Incorrect use of '=' operator. To assign a value to a variable, use '='. To compare values for equality, use '=='." To fix this all you need to do is use == instead:
n = 5; if n == 4 n = n.^2; end
This code outlines the differences between the two operators more clearly:
A = 1:5 A = 1 2 3 4 5 B = 5; A == B ans = 0 0 0 0 1 C = A == B C = 0 0 0 0 1
In short: when you need to compare values, use ==. When you want to assign a value, use =.
Why do I receive an error when using the AVIREAD function?[]
Please see Why do I receive an error when using the AVIREAD function?
Programming[]
How can I create variables A1, A2,..., A10 in a loop?[]
Please don't do this! You will find that MATLAB arrays (either numeric or cell) will let you do the same thing in a much faster, much more readable way. For example, if A1 through A10 contain scalars, use:
A = zeros(1, 10); % Not necessary, but it's faster to preallocate space for k = 1 : 10 A(k) = % some value, variable, or function ... end
Now refer to A(i) whenever you mean Ai. In case each Ai contains a vector or matrix, each with a different size, you want to use cell arrays, which are intended exactly for this:
for k = 1 : 10 A{k} = 1 : k; end
Note that each A{i} contains a different size matrix. And be sure to use the curly braces for the subscript, not parentheses! Remember (from the "What is a cell array" FAQ entry above) that A(k) is the cell itself, while A{k} refers to the contents of the cell. So in our above example A(k) is a cell while A{k} is an integer. See the FAQ entry on cells if this is still unclear to you.
Another approach is to use structures with dynamic field names instead of cell arrays. The fields of the structure can be the variable names you want. And you can index into them with dynamic field references. For example:
names = {'fred' 'sam' 'al'}; for index = 1 : length(names) s.(names{index}) = index; % Assign index to s.fred, s.sam, and s.al end
In this case, you end up with the variable s, a structure, containing fields specified by the names in the strings that are stored in the cells of the cell array. You can assign anything to the field such as a scalar, an array, a string, another structure, a cell array, or whatever you want. In this example we just assigned the integer in the index variable.
Now, if you still really want to go against our advice and create variables with dynamically generated names, you need to use the eval() function. With eval(), you use MATLAB commands to generate the string that will perform the operation you intend. For example, eval('A=10') has the same effect as A=10, and eval(['A' 'B' '=10']) has the same effect as AB=10, only the eval() function executes much more slowly. So in a loop, you could use:
for i=1:10 eval(sprintf('A%d = [1:i]', i)); end
Notice how much more obfuscated this is. It could be made possibly clearer to split it up into multiple lines:
for i=1:10 lineOfCode = sprintf('A%d = [1:i]', i); % Now, execute lineOfCode just as if you'd typed % >> Ai=[i:i]' into the command window eval(lineOfCode); end
In addition, this can cause difficult-to-troubleshoot problems in your code, particularly if you try to dynamically create a variable with the same name as a function:
function y = mysin(x) eval('sin = 5;'); y = sin(x);
Calling this function with "y = mysin(1)" will not return y = 5 (the first element of the sin variable created by EVAL) -- it will return the sine of 1, because when the function was parsed there was no variable named sin and so the usage of sin on the last line was parsed as a call to the built-in SIN function. The fact that a variable named sin existed at runtime is irrelevant; the parsetime "decision" takes precedence.
Repeat: don't create variables at runtime using eval() unless you have a very good reason, such as someone gives you a MAT file with 2000 variables named A1428, for example. Even in that case, you can avoid eval() by using dynamic field names of a structure:
% Assume the MAT-file example1.mat contains 2000 variables, A1 through A2000 S = load('example1.mat'); % S is now a structure array with 2000 fields, S.A1 through S.A2000. % To access A1428, use: x1 = S.A1428; % If the "index" of the variable you want to access is stored in a variable: k = 1428; x2 = S.(sprintf('A%d', k)); x3 = S.(['A', num2str(k)]);
How can I process a sequence of files?[]
We present three ways of doing this. The first uses dir() to get existing filenames, the second uses sprintf() to create filenames that may or may not exist yet, and the third method uses imageDatastore() or fileDatastore() to get existing filenames.
The first method is if you want to process all the files whose name matches a pattern in a directory. You can use the DIR function to return a list of all file names matching the pattern, for example all .txt files or all .csv files, or all files named myFilennnn.dat (where nnnn is some number). Note that while this example uses *.png as the pattern and IMREAD to read in the data, as with the previous example you could use whatever pattern and file reading function suits your application's needs:
% Specify the folder where the files live. myFolder = 'C:\Users\yourUserName\Documents\My Pictures'; % Check to make sure that folder actually exists. Warn user if it doesn't. if ~isfolder(myFolder) errorMessage = sprintf('Error: The following folder does not exist:\n%s\nPlease specify a new folder.', myFolder); uiwait(warndlg(errorMessage)); myFolder = uigetdir(); % Ask for a new one. if myFolder == 0 % User clicked Cancel return; end end % Get a list of all files in the folder with the desired file name pattern. filePattern = fullfile(myFolder, '*.png'); % Change to whatever pattern you need. theFiles = dir(filePattern); for k = 1 : length(theFiles) baseFileName = theFiles(k).name; fullFileName = fullfile(theFiles(k).folder, baseFileName); fprintf(1, 'Now reading %s\n', fullFileName); % Now do whatever you want with this file name, % such as reading it in as an image array with imread() imageArray = imread(fullFileName); imshow(imageArray); % Display image. drawnow; % Force display to update immediately. end
If you want to get all files in that folder PLUS subfolders, you can use two extra stars in the file pattern, like this:
% Get a list of all files in the folder, and its subfolders, with the desired file name pattern. filePattern = fullfile(myFolder, '**/*.png'); % Change to whatever pattern you need.
Or you can use the simpler, though not as robust, code inspired by this StackOverflow question:
csvfiles = dir('*.csv') for file = csvfiles' fprintf(1, 'Doing something with %s.\n', file.name) end
The uncommented, simplistic code above assumes that all files will be in the current folder. It's recommended to use the more robust first version instead of this version. Or you can try a "File Exchange Pick of the Week": FileFun.
The second method is if the files that you want to process are sequentially numbered, like "file1.txt", "file2.txt", "file3.txt", etc. then you can use sprintf() or num2str() to create the filename and load(), imread(), fopen(), etc. to retrieve the data from the file. Also note the three different ways of building the file name (for mat files, image files, or text files) - you can use your favorite way. Typically you'd use just one of the options, not all of them, so delete the two you don't need.
% Read files mat1.mat through mat20.mat, file1.txt through file20.txt, % and image1.jpg through image20.jpg. Files are in the current directory. % Use fullfile() if you need to prepend some other folder to the base file name. % Adapt to use which ever cases you need. for k = 1 : 20 % OPTION 1: Create a mat filename, and load it into a structure called matData. matFileName = sprintf('mat%d.mat', k); if isfile(matFileName) matData = load(matFileName); else fprintf('File %s does not exist.\n', matFileName); end % OPTION 2: Create an image filename, and read it in to a variable called imageData. jpgFileName = strcat('image', num2str(k), '.jpg'); if isfile(jpgFileName) imageData = imread(jpgFileName); else fprintf('File %s does not exist.\n', jpgFileName); end % OPTION 3: Create a text file name, and read the file. textFileName = ['file' num2str(k) '.txt']; if isfile(textFileName) fid = fopen(textFileName, 'rt'); textData = fread(fid); fclose(fid); else fprintf('File %s does not exist.\n', textFileName); end end
In the above code, matData, imageData, and textData will get overwritten each time. You should save them to an array or cell array if you need to use them outside the loop, otherwise use them immediately inside the loop.
A third, newer method to process a sequence of files is to use the fileDatastore() function, introduced in R2016a. This function has the advantage of being able to automatically get a list of your file pattern in subfolders, as well as the main folder.
% Get a list of all txt files in the current folder, or subfolders of it.
fds = fileDatastore('*.txt', 'ReadFcn', @importdata)
fullFileNames = fds.Files
numFiles = length(fullFileNames)
% Loop over all files reading them in and plotting them.
for k = 1 : numFiles
fprintf('Now reading file %s\n', fullFileNames{k});
% Now have code to read in the data using whatever function you want.
% Now put code to plot the data or process it however you want...
end
How do I sort file names numerically?[]
If you call the dir() function to get file information (including file names), like this:
fileList = dir('*.*');
and get files sorted like this file1.dat, file10.dat, file11.dat, file2.dat, file20.dat, file21.dat, file3.dat, etc. and what you really wanted was them to be sorted like this: file1.dat, file2.dat, file3.dat, file10.dat, file11.dat, file20.dat, file21.dat, then see Natural Order Sorting, a File Exchange Pick of the Week.
Can I read a text file with a certain format?[]
Yes. If the file has nothing but numbers separated by whitespace, and has a constant number of columns through the entire file, you can just type load myfile.txt.
The function DLMREAD is more flexible and allows you to read files with fields delimited by any character.
If you have mixed data, such as columns of text and numbers, you can use READTABLE. The first line is the column headers line and says what the fields of the table will be called.
t = readtable('file.txt');
The function TEXTREAD is more flexible still and allows you to skip lines at the beginning, ignore certain comment lines, read text as well as numbers, and more. Type help textread for more info.
If you are dealing with a more complicated file try XLSREAD, for example when opening a csv file with only partially numerical content.
If none of these suit your needs, you can always use the low-level file I/O functions FOPEN, FREAD, FSCANF, FGETL, FSEEK and FCLOSE to read the data however you would like.
Are global variables bad?[]
1) Using globals is perfectly okay (that's why they are there in first place), just like for's and while's and other intelligent 2nd generation computer language constructs (that MATLAB is built on), as long as you are careful about where, why, and how you use them.
2) However, using globals is not recommended by many programmers because it shows that she/he didn't think ahead but was rather sloppy... and just kept adding on those never-ending "important set up" parameters that she/he needed to use by all the axes - or whatever - of a one single project.
3) Using globals can be a problem in terms of bookkeeping if you end up having dozens of them hovering around in your workspace. If you are not careful and use the same names for global variables that represent different things, then you may start having problems if the global <myParameter> from function1 is mixed up with the global <myParameter> from function2. You can do <whos global> to show you all the global variables.
4) A nice way to reduce the number of global variables is to collect all your globals into a single structure (thereby uncluttering your workspace). For example
% Declare UserSettings (or whatever name you want) as global in this function. global UserSettings; % Get the user folder of the user who logged in to the computer. userFolder = getenv('USERPROFILE') % 'C:\Users\YourName % Set up global variable, UserSettings, for use in any other function that % declares UserSettings as global, but in ONLY those functions. UserSettings.dataFolder = fullfile(userFolder, '\Documents') UserSettings.resultsFolder = fullfile(UserSettings.dataFolder, '\Results') UserSettings.someVariable = 42*pi;
Just attach any variables that you want to make global to the UserSettings structure. Now, any other function that declares UserSettings as global will have access to all of the member fields of UserSettings. Other functions that do not have the "global UserSettings" line in them will not be able to see the UserSettings global variable. It is not global unless the global line is included in the function.
5) Alternatively you can not have UserSettings as global and instead pass it as an input argument to only those functions that need it. This is one preferred way of sharing variables in MATLAB ... and it shows your intelligence, to boot.
If you're using global variables because you want to share variables between functions, look at the section on How can I share data between callback functions in my GUI. That section of this FAQ lists some alternatives to using global variables.
How does logical indexing work?[]
From the Getting Started book:
The logical vectors created from logical and relational operations can be used to reference subarrays. Suppose X is an ordinary matrix and L is a matrix of the same size that is the result of some logical operation. Then X(L) specifies the elements of X where the elements of L are nonzero.
Here's a short example of logical indexing to specify certain array elements:
m = magic(5) % Get the logical matrix which is zero where % m <= 20 and 1 where m >= 21 bigNumbersLocations = m > 20 % Extract those big numbers into an array % Method #1: bigNumbers = zeros(size(m)); bigNumbers(bigNumbersLocations) = m(bigNumbersLocations) % Method #2: bigNumbers2 = m; bigNumbers2(~bigNumbersLocations) = 0 % Display the big numbers. It will be a 1D vector. m(bigNumbersLocations) m = 17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 9 bigNumbersLocations = 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 bigNumbers = 0 24 0 0 0 23 0 0 0 0 0 0 0 0 22 0 0 0 21 0 0 0 25 0 0 bigNumbers2 = 0 24 0 0 0 23 0 0 0 0 0 0 0 0 22 0 0 0 21 0 0 0 25 0 0 ans = 23 24 25 21 22
Huge memory waste using array of structs?[]
The following example was posted to the newsgroup:
I've discovered to my horror that structs take up an obscene amount of overhead (I'm running version 5.3.1.29215a (R11.1) on a Dec ALPHA). I have a set of 10,242 observations, each consisting of 3+13=16 fields, which have 3*27 + 1*13 = 94 values. So the total size in bytes should be 10,242 * 94 * 8 bytes/double = 7,701,984.
I have this stored in a 1 x 10242 data structure, and when I issue the whos command, it tells me that the data now takes up 27,367,136 bytes!
Professor Cris Luengo answers:
My guess would be that a structure contains MATLAB arrays. Each array has some overhead, like data type, array sizes, etc. In your second implementation (index using data.latitude(observation)), there are 10,242 times less arrays allocated. Note that in your data, for each observation, you have 13 arrays with one value. I don't know how large the matrix header exactly is, but it is a waste putting only a single value in it!
I think Cris has hit it exactly. Every MATLAB matrix has an overhead of ~100 bytes, even matrices with a single element. In this example, there are 16 fields * 10242 elements = 163872 matrices. Each one of these matrices adds an additional 100 bytes, for 16.4Mbytes in pure overhead. This still comes up a little short of the amount reported, but it is fairly close.
It is much more efficient, both for storage and computation, to use a struct of arrays rather than an array of structs.
Why is my MEX file crashing?[]
Memory errors are one likely reason. Greg Wolodkin suggests the debug memory manager:
The platform-independent way to use the debug memory manager is to set the environment variable MATLAB_MEM_MGR to contain the string "debug".
On Windows:
C:\> set MATLAB_MEM_MGR=debug C:\> matlab
On Unix with csh or tcsh:
% setenv MATLAB_MEM_MGR debug % matlab
On Unix with sh or bash:
$ MATLAB_MEM_MGR=debug matlab
The debug memory manager cannot catch your code the instant it writes out of bounds (tools like Purify can do this but the performance hit they induce is quite painful). What it will catch is that in general, when you write outside of one memory block you end up writing into another, corrupting it or (in the case of the debug memory manager) hopefully corrupting only a guard band. When you later free the memory, we can tell you that you walked off the end of the block and corrupted the guard band.
Do boolean operators short-circuit?[]
In many programming languages, boolean operators like AND and OR will stop evaluating as soon as the result is known. For instance,
1 | error('Short-circuit')
would never get to the error part, since the 1 is always true.
MATLAB versions >= 6.5 include the new short-circuiting logical operators || and &&. Use these for all condition tests in loops and similar, and use the old | and & for element-by-element logical operations. You can find details here (http://www.mathworks.com/help/techdoc/ref/logicaloperatorsshortcircuit.html).
In older versions of MATLAB, the boolean operators | and & are only short-circuit evaluated inside the conditions of IF and WHILE statements. In all other contexts, all parts of the conditional are evaluated.
How do I fix "Out of Memory" problems?[]
A frequent variant of this question is: "I have 3 GB of RAM, and 2 GB of swap space. Why can't I create this 600 MB matrix?"
First of all, issue the command "memory" in the command window to see how much memory is available on your computer. It should return something like this:
>> memory
Maximum possible array: 520 MB (5.457e+008 bytes) *
Memory available for all arrays: 1343 MB (1.409e+009 bytes) **
Memory used by MATLAB: 447 MB (4.690e+008 bytes)
Physical Memory (RAM): 3036 MB (3.184e+009 bytes)
- Limited by contiguous virtual address space available.
** Limited by virtual address space available.
Remember that double precision floats take up 8 bytes. So a million element vector takes up 8Mbytes. Be sure you're estimating properly.
Many operations need to create duplicate matrices. For example, B = inv(A.') must create a tempory variable the same size as A to hold the transpose, and B is the same size as A.
If you're sure your matrices are reasonably sized, then read these Mathworks Technical Notes: Tech Note 1106: Memory Management Guide and Tech Note 1107: Avoiding Out of Memory Errors
Another variant of this question is: "How do I pre-allocate memory when using MATLAB?"
If the matrix size is not defined prior to populating it with data through a FOR loop, memory fragmentation problems may happen since MATLAB is not aware of the final matrix size upon the conclusion of the FOR loop. In order to work around this issue, one solution is to pre-allocate memory by creating an initial matrix of zeros with the final size of the matrix being populated in the FOR loop. You should read the following Mathworks article: Technical Solution 1-18150 for a more complete discussion of this problem.
How do I dynamically generate a filename for SAVE?[]
You're probably trying
fname = 'foobag'; save fname variable;
To do this correctly, you need to use the "functional" form of save:
fname = 'foobar'; save(fname, 'variable');
In fact, it is true in general that the following two lines are equivalent:
command str1 str2 str3 command('str1', 'str2', 'str3')
This allows one replace any or all of the parameters with dynamically generated strings. This is also useful in commands like PRINT, LOAD, CLEAR, etc.
What's the difference between M-files, Pcode, and MEX files?[]
- M-files are plain ASCII text that is interpreted at run time. Actually it is parsed once and "just-in-time" compiled, but this is transparent to the user. Use M-files for most of your MATLAB development, and for platform independence and maintainability.
- Pcode is a preparsed and encoded version of the M-file. Since it is preparsed, it saves on the load time of the function. This is most likely not an issue except for very large M-files, since most are parsed only once anyway. Pcode also lets you hide the source code from others. Careful, there is no way to convert Pcode back to the M-file source. Pcode is platform independent.
- MEX files are native C or C++ files that are dynamically linked directly into the MATLAB application at runtime. They must be compiled for each hardware architecture on which they are to be run. MEX files have the potential to crash the MATLAB application, but rather large speed gains are possible, depending on the algorithm.
Can MATLAB pass by reference?[]
If you are attempting to use pass-by-reference to modify the input argument passed into a function, the answer to the question depends on whether the input is a handle object or a value object. The two types of objects are described in the Object-Oriented Programming (http://www.mathworks.com/access/helpdesk/help/techdoc/matlab_oop/brfylq3.html) and Programming Fundamentals (http://www.mathworks.com/access/helpdesk/help/techdoc/matlab_prog/brtm8si.html) sections of the documentation. By default, objects (including matrices, arrays, etc. of the built-in data types) are value objects.
Handle objects do exhibit reference behavior when passed as function arguments; value objects do not. When you pass a handle object to a function, MATLAB still copies the value of the argument to the parameter variable in the function (with one bit of subtlety; see below.) However, all copies of a handle object refer to the same underlying object.
If a function modifies a handle object passed as an input argument, the modification affects the object referenced by both the original and copied handles. In this case, the function does not need to return the result to be reassigned.
If instead you are attempting to use pass-by-reference to avoid unnecessary copying of data into the workspace of the function you're calling, you should be aware that MATLAB uses a system commonly called "copy-on-write" to avoid making a copy of the input argument inside the function workspace until or unless you modify the input argument. If you do not modify the input argument, MATLAB will avoid making a copy. For instance, in this code:
function y = functionOfLargeMatrix(x) y = x(1);
MATLAB will not make a copy of the input in the workspace of functionOfLargeMatrix, as x is not being changed in that function. If on the other hand, you called this function:
function y = functionOfLargeMatrix2(x) x(2) = 2; y = x(1);
then x is being modified inside the workspace of functionOfLargeMatrix2, and so a copy must be made.
For more information on this behavior, read this posting (http://blogs.mathworks.com/loren/2006/05/10/memory-management-for-functions-and-variables/) on Loren Shure's blog.
How can I pass additional parameters into a "function function" like ODE45, QUAD, FSOLVE, FMINCON, GA, etc?[]
The term "function functions" refers to functions in MATLAB and the toolboxes that accept a function (usually a function handle) and evaluate that function repeatedly during the course of their work. Some examples of "function functions" are:
- the ordinary differential equation solvers like ODE45, ODE23, etc.
- the integration functions like QUAD and QUADL
- the optimization functions in the funfun directory in MATLAB, like FMINSEARCH and LSQNONLIN
- the optimization functions in the Optimization Toolbox, like FMINCON, FSOLVE, and LSQCURVEFIT
- the optimization functions in the Genetic Algorithm and Direct Search Toolbox, like GA and PATTERNSEARCH
There are several documents on The MathWorks support website that shows examples of how to pass additional parameters to the functions used by the "function functions".
- ODE solvers like ODE45 and integration functions like QUAD or QUADL (http://www.mathworks.com/support/solutions/data/1-1AIJF.html?solution=1-1AIJF)
- Optimization functions in toolbox/matlab/funfun and toolbox/optim (FMINCON, FSOLVE, FZERO, LSQCURVEFIT, etc.) (http://www.mathworks.com/support/solutions/data/1-19HM6.html?solution=1-19HM6)
- Genetic Algorithm and Direct Search Toolbox functions (GA, PATTERNSEARCH) (http://www.mathworks.com/support/solutions/data/1-1BZ6V.html?solution=1-1BZ6V)
This information has also been incorporated into the documentation in recent versions of MATLAB and the toolboxes:
- MATLAB (http://www.mathworks.com/access/helpdesk/help/techdoc/math/f2-941087.html)
- Optimization Toolbox (http://www.mathworks.com/access/helpdesk/help/toolbox/optim/ug/f67947.html)
- GA function, Genetic Algorithm and Direct Search Toolbox (http://www.mathworks.com/access/helpdesk/help/toolbox/gads/bqlex3b-1.html)
- PATTERNSEARCH function, Genetic Algorithm and Direct Search Toolbox (http://www.mathworks.com/access/helpdesk/help//gads/f12810.html)
Why does MATLAB clear the breakpoints I've set in my M-file?[]
When a function is cleared from memory using the CLEAR function, breakpoints in that file are also cleared. That means that if you execute code including the statement "clear functions", "clear <the name of your function>", or "clear all", your breakpoints will be cleared.
If you want to have your program stop execution and enter debug mode regardless of whether or not you have cleared it, insert a call to the KEYBOARD function into the code at the location where you want to enter debug mode. This will not be cleared by the CLEAR function and will cause MATLAB to enter debug mode when the KEYBOARD function is called.
Alternately, you can use the "Stop if Errors/Warnings" item under the Debug menu in the MATLAB Editor to cause MATLAB to enter debug mode whenever the code you're running throws an error that is not caught by a TRY/CATCH block, whenever it throws an error that is caught by a TRY/CATCH block, whenever it throws a warning, or whenever the value of a variable becomes Inf or NaN. You can find more information on this item in the documentation (http://www.mathworks.com/access/helpdesk/help/techdoc/matlab_env/bq4hw4g-1.html).
Why is it advised to avoid using the "eval" function?[]
The EVAL function is one of the most powerful, flexible, and potentially dangerous functions in MATLAB. Since EVAL is so powerful, it is easy to misuse the function. In a way, the EVAL function is a lot like global variables; both are tools that are so easy to use that it might be easier to use them rather than to search for a more elegant, safer, and appropriate solution. There is a major drawback to the EVAL function, although it can be avoided if you use EVAL carefully. EVAL can be used to alter arbitrary variables. In addition, two related functions, evalin and assignin, can be used to alter variables in different function workspaces. These functions can create bugs which are difficult to reproduce and nearly impossible to eliminate. Further explanation, and The Mathworks official warning against using eval, can be found in Mathworks Tech Note 1103.
Where did my file go? The risks of using the cd function.[]
Sometimes if you're writing code that does file input/output without specifying the full path (folder + base file name) you may not find your file. It may not be there to read in or may not be written out to the folder that you expected. For example
storedStruct = load('mySavedParameters.mat'); imwrite('myOutputImage.png')
If another function call used the cd() function to change the current folder, then you would be looking to that folder when you tried to read in a file or write out a file. If you thought that you were looking at a different folder, then you'll get a "file not found" error upon trying to read in a file, or else not find the file in that folder that you thought you wrote out to. It would be best if any code that used cd() saved and restored the original folder:
originalFolder = pwd; % Do stuff. Then restore the original folder cd(originalFolder);
but you cannot always rely upon that. It's much, much better to not use cd() and instead create the full-blown explicit filename with functions such as sprintf(), fileparts(), and fullfile(). Because if you have the full path name of the file, you'll know for certain where it will get saved to or read from. See the following code for guidance:
% Code to ask user for a folder. startingFolder = pwd; returnValue = uigetdir(startingFolder,'Select folder'); % returnValue will be 0 (a double) if they click cancel. % returnValue will be the path (a string) if they clicked OK. if returnValue ~= 0 % Assign the value if they didn't click cancel. folder = returnValue; else folder = startingFolder; end % Example 1: Write out a .mat file with some variables. % Create the full file name. baseFileName = 'myFile.mat'; fullFileName = fullFile(folder, baseFileName); % Save out the variable into the mat file. stringToSave = 'It is risky to use cd().'; % Some sample variable. integerToSave = 42; save(fullFileName, 'stringToSave', 'integerToSave'); % Example 2: Read in a mat file baseFileName = 'myFile.mat'; fullFileName = fullFile(folder, baseFileName); if exist(fullFileName, 'file') % It exists. storedVariablesStructure = load(fullFileName); else % It doesn't exist. warningMessage = sprintf('Error reading mat file\n%s.\n\nFile not found', ... fullFileName); uiwait(warndlg(warningMessage)); end
Graphics[]
[]
Unlike custom functions that you write, the callback functions take the predetermined input variables (hObject, eventdata, handles) so it's not clear how you can pass in other variables that you need to. There are several techniques you can use to share data between callback functions in your GUI. Which approach is easiest depends on whether you are creating your GUI using GUIDE to design the layout (GUIDE-based GUIs) or whether you are calling FIGURE, AXES, UICONTROL, etc. directly (programmatic GUIs.)
The main techniques are:
- Using the handles structure. You can dynamically add on new members to the handles structure that contain your variables that you want to pass in. Unlike global variables, which expose the variables only where you put the global statement, attaching to the handles structure and passing handles will share all the variables you have attached to the handles structure. This could expose variables to your function that you did not need or want exposed. Since variables passed in to MATLAB functions are "pass by value" and not "pass by reference" if you change any of the variables, you are only changing the local copy. If you change any of the variables attached as members of the handle structure, and you want to retain these changed values in the calling function, you will have to return the handles structure as an output of your function, and accept it in your calling function, or else use the guidata() function. Otherwise changes you make to the handles structure variables are only local and will not survive once the function has returned.
% Add a brand new variable on to the handles structure. handles.myNewVariable = 42;
- Creating your callback functions as nested functions inside the main GUI function. The function must be truly nested with the main function's "end" statement and not merely listed as another separate, independent function just defined in the m-file. (There is a difference.)
- Storing data in a property [often the UserData property] of a component in the GUI and retrieving it when needed. For example
set(handles.button1, 'UserData', myString).
- Storing data in the application workspace using the SETAPPDATA and GETAPPDATA functions.
% Do this to save variables to your figure's workspace. % handles.GUIHandle is the "Tag" property of your main GUI figure. % Double-click the figure to bring up the "Property Inspector" in GUIDE % to see what your figure is named. You may have called it something different % than GUIHandle. You can call it whatever you want but the name in the "tag" % field of the Property Inspector must match the name in setappdata(). setappdata(handles.GUIHandle, 'yourVariable', yourVariable) % Do this to retrieve variables from your figure's workspace. yourVariable = getappdata(handles.GUIHandle , 'yourVariable') % Do this to remove what you saved from your figure's workspace. rmappdata(handles.GUIHandle, 'yourVariable')
- Declaring the variable(s) global. For example, if you have this inside a function:
global myVariable; % Declare global. Any function with this line it it can see this variable.
then any other function that also has the "global myVariable" declaration in it will be able to see the variable called "myVariable". Functions that do not have the "global myVariable" line in them will not be able to see the variable. So it's actually more like a "friend" variable (if you're familiar with C++ programming) than a truly global variable because not every function or workspace sees it. The "myVariable" variable will not be seen in the "base" workspace - it will be seen only inside functions with the "global myVariable" declaration in them.
- Writing the data out to a file, such as a mat file with the save function, and then having the called function read in that mat file.
% Do this to save variables to your figure's workspace. % yourVariable could be a single variable that is a structure % with a bunch of variables as members of the structure % if you wish. That can be convenient because then there % is only one variable to save. save(fullMATFileName, 'yourVariable') % Do this to retrieve the variable. storedStructure = load(fullMATFileName); yourVariable = storedStructure.yourVariable;
- Use the assignin() function.
% Send the variable myGUIVariable from the GUIs workspace % to a variable called myBaseVariable in the "base" workspace. assignin('base', 'myBaseVariable', myGUIVariable); % They could both be the same name if you wish. assignin('base', 'myVariable', myVariable);
Sharing between multiple GUIs. If the "main" GUI calls other GUIs, then the best way to do it is by passing variables in via the input argument list, and accepting output variables via the output argument list. The output argument of GUI2 can then be sent into GUI3. So someplace in GUI1 (like the callback function of the "Go!" button of GUI1), you'd have this
[out2a out2b out2c] = gui2(in2a, in2b, in2c, in2d); [out3a out3b] = gui3(out2a, out2b);
or something along those lines. The arguments can be extracted out of the varargin cell array of your opening code for the GUI, for example in the GUI's "OpeningFcn" function if you used GUIDE. Once they are in your opening function, then they can be shared amongst the other functions in the GUI with the methods mentioned earlier in this section. This method will not let GUI1 control GUI2 and GUI3's parameters "live" - they can be changed only when calling the GUIs. To have GUI1 control GUI2 when GUI2 is already running, you can use the assignin() function.
This answer from Geoff Hayes in the Answers forum may also help you in the multiple GUI situation: [3]
Official Documentation. The documentation contains instructions for using these techniques to share data between callbacks in these Mathworks web pages:
- GUIDE-based GUI (http://www.mathworks.com/access/helpdesk/help/techdoc/creating_guis/f5-998197.html)
- Doug Hull's video tutorial Passing data between GUIDE callbacks without globals in MATLAB
- Doug Hull's Video Tutorial How to pass data from one GUI to another
- programmatic GUIs (http://www.mathworks.com/access/helpdesk/help/techdoc/creating_guis/f13-998197.html)
- Share data among callbacks: https://www.mathworks.com/help/matlab/creating_guis/share-data-among-callbacks.html
How do I shade the region between two curves?[]
To shade between an upper and lower curve, you can use the patch() function. Here is an example::
% Shades region between two curves with light green.
numPoints = 600;
x = 1 : numPoints;
% Make and plot y1.
period1 = 300;
y1 = cos(2 * pi * x / period1);
% plot(x, y1, 'r-', 'LineWidth', 3);
% Make and plot y2.
period2 = 100;
y2 = cos(2 * pi * x / period2);
hold on;
% plot(x, y2, 'b-', 'LineWidth', 3);
grid on;
% Shade the area between in light green using the patch() function.
lightGreen = [0.85, 1, 0.85];
% Create the boundaries of the upper points and the lower points.
% Assume y1 and y2 have the same number of elements located at the same x values.
upperBoundary = max(y1, y2);
lowerBoundary = min(y1, y2);
% Now do the actual display of the shaded region.
patch([x fliplr(x)], [upperBoundary fliplr(lowerBoundary)], lightGreen);
% Plot y1 and y2 AFTER the patch so the patch does not cover any of those curves.
hold on;
plot(x, y1, 'r-', 'LineWidth', 2); % Plot curve 1 in red.
plot(x, y2, 'b-', 'LineWidth', 2); % Plot curve 2 in blue.
xlabel('X', 'FontSize', 24);
ylabel('Y', 'FontSize', 24); legend('Patch', 'y1', 'y2');
% Maximize the figure window
g = gcf; % Setting the WindowState on gcf directly doesn't work for some reason.
g.WindowState = 'maximized'
It can be modified to shade
- only the region between y1 and y2 if y1 is higher than y2, or
- only the region between y1 and y2 only if y2 is higher, or to
- shade the region below either curve and the x axis,
or however you want to do it.
How do I create a circle?[]
To create a 2D logical image of a solid circle (a disc), you can use code like this:
% Create a logical image of a circle with specified % diameter, center, and image size. % First create the image. imageSizeX = 640; imageSizeY = 480; [columnsInImage rowsInImage] = meshgrid(1:imageSizeX, 1:imageSizeY); % Next create the circle in the image. centerX = 320; centerY = 240; radius = 100; circlePixels = (rowsInImage - centerY).^2 ... + (columnsInImage - centerX).^2 <= radius.^2; % circlePixels is a 2D "logical" array. % Now, display it. image(circlePixels) ; colormap([0 0 0; 1 1 1]); title('Binary image of a circle');
It can be extended to handle ellipses by putting in factors inside the sqrt() in the obvious places. If you want, this circle mask can be used to assign image values either inside or outside the circle to a new gray level:
% Assign values inside the circle. newGrayLevelInside = 50; grayImage(circlePixels) = newGrayLevelInside; % Or, assign values outside the circle. newGrayLevelOutside = 150; grayImage(~circlePixels) = newGrayLevelOutside ;
If you would like the circle to be only a single pixel wide circumference in the digital image, rather than a solid disc, then you can use this code:
% Code to burn a white circle into a black digital image. % Write white pixels along the circumference of the circle into an image. % Create image of size 1200 rows by 2200 columns. myImage = zeros(1200, 2200, 'uint8'); % Let's specify the center at (x, y) = (1600, 600) and the radius = 350. xCenter = 1600; yCenter = 600; radius = 350; % Circumference for a circle of radius 350 should be 2*pi*r = 2199 pixels. % To ensure that we have no gaps in the circle % we need to make sure we have at least as many coordinates in vectors x and y % as there are around the circumference of the circle. % Make it double that just to make extra sure there are no gaps in the circle % by going all 360 degrees (0 - 2*pi) with 4398 points. theta = linspace(0, 2*pi, round(4 * pi * radius)); % Define angles % Get x and y vectors for each point along the circumference. x = radius * cos(theta) + xCenter; y = radius * sin(theta) + yCenter; plot(x, y); axis square; grid on;
% Write those (x,y) into the image with gray level 255. for k = 1 : length(x) row = round(y(k)); col = round(x(k)); myImage(row, col) = 255; end % Display the image. It may appear as though there are gaps in the circle % due to subsampling for display but examine the image in the variable inspector % and you'll see there are no gaps/breaks in the circle. imshow(myImage); axis('on', 'image'); % Plot crosshairs in the overlay at the center hold on; plot(xCenter, yCenter, 'r+', 'MarkerSize', 100);
If you want to plot a circle, you can use the rectangle() function:
radius = 5; centerX = 20; centerY = 30; rectangle('Position',[centerX - radius, centerY - radius, radius*2, radius*2],... 'Curvature',[1,1],... 'FaceColor','r'); axis square;
Newer versions of the Image Processing Toolbox have the viscircles() function for plotting multiple circles simultaneously in the overlay above the digital image.
radius = 5; centerX = 20; centerY = 30; viscircles([centerX, centerY], radius); axis square;
Or, if you want a list of x and y coordinates of the perimeter of the circle, or of an arc, you can do this:
xCenter = 12; yCenter = 10; theta = 0 : 0.01 : 2*pi; radius = 5; x = radius * cos(theta) + xCenter; y = radius * sin(theta) + yCenter; plot(x, y); axis square; xlim([0 20]); ylim([0 20]); grid on;
Note that it will be a circle according to the tick marks on the axes, but whether it appears perfectly circular on your computer monitor depends on your video adapter settings, and whether you use, or don't use, the 'square' and 'equal' options for the axis command. The above code can also be used to create an arc - a portion of a circle. Just change the line that assigns theta to start and stop at the desired angles of the arc.
If you want this to be in the overlay of an existing plot or image, issue the "hold on" command prior to issuing the rectangle command, or else the circle will destroy the existing plot or image.
The use of meshgrid (or ndgrid) can be easily extended to 3D to create a logical mask for a sphere.
% Create a logical image volume of a sphere with specified % diameter, center, and image size. % First create the image. imageSizeX = 100; imageSizeY = 100; imageSizeZ = 100; [columnsInImage rowsInImage pagesInImage] = meshgrid(1:imageSizeX, 1:imageSizeY,1:imageSizeZ); % Next create the sphere in the image. centerX = 40; centerY = 60; centerZ = 50; radius = 36; sphereVoxels = (rowsInImage - centerY).^2 ... + (columnsInImage - centerX).^2 + (pagesInImage - centerZ).^2 <= radius.^2; % sphereVoxels is a 3D "logical" array. % Now, display it using an isosurface and a patch fv = isosurface(sphereVoxels,0); patch(fv,'FaceColor',[0 0 .7],'EdgeColor',[0 0 1]); view(45,45); axis equal; title('Binary volume of a sphere');
How do I create an arc?[]
Creating an arc is very similar to creating a circle. Simply specify a starting and ending angle for theta.
% Define parameters of the arc. xCenter = 2; yCenter = 1; radius = 5; % Define the angle theta as going from 30 to 150 degrees in 100 steps. theta = linspace(30, 150, 100); % Define x and y using "Degrees" version of sin and cos. x = radius * cosd(theta) + xCenter; y = radius * sind(theta) + yCenter; % Now plot the points. plot(x, y, 'b-', 'LineWidth', 2); axis equal; grid on;
How do I create an ellipse?[]
The code is very similar to the code to create a circle from above.
% Create a logical image of an ellipse with specified % semi-major and semi-minor axes, center, and image size. % First create the image. imageSizeX = 640; imageSizeY = 480; [columnsInImage rowsInImage] = meshgrid(1:imageSizeX, 1:imageSizeY); % Next create the ellipse in the image. centerX = 320; centerY = 240; radiusX = 250; radiusY = 150; ellipsePixels = (rowsInImage - centerY).^2 ./ radiusY^2 ... + (columnsInImage - centerX).^2 ./ radiusX^2 <= 1; % ellipsePixels is a 2D "logical" array. % Now, display it. image(ellipsePixels) ; colormap([0 0 0; 1 1 1]); title('Binary image of a ellipse', 'FontSize', 20);
Or you can create an ellipse in the overlay of a plot or image:
xCenter = 12.5; yCenter = 10; xRadius = 2.5; yRadius = 8; theta = 0 : 0.01 : 2*pi; x = xRadius * cos(theta) + xCenter; y = yRadius * sin(theta) + yCenter; plot(x, y, 'LineWidth', 3); axis square; xlim([0 20]); ylim([0 20]); grid on;
How do I create a ring?[]
The code is very similar to the code to create a circle from above - just specify an inner and outer radius.
% Create a logical image of a ring with specified % inner diameter, outer diameter center, and image size. % First create the image. imageSizeX = 640; imageSizeY = 480; [columnsInImage, rowsInImage] = meshgrid(1:imageSizeX, 1:imageSizeY); % Next create the circle in the image. centerX = 320; centerY = 240; innerRadius = 100; outerRadius = 140; array2D = (rowsInImage - centerY).^2 ... + (columnsInImage - centerX).^2; ringPixels = array2D >= innerRadius.^2 & array2D <= outerRadius.^2; % ringPixels is a 2D "logical" array. % Now, display it. image(ringPixels) ; colormap([0 0 0; 1 1 1]); title('Binary Image of a Ring', 'FontSize', 25);
How do I create a spiral?[]
The code is very similar to the code to create a circle from above - just specify an inner and outer angle, and an inner and outer radius that changes for each angle. The ending angle can be as high as you want. The larger it is, the more times the spiral will wrap around the center.
xCenter = 12;
yCenter = 10;
% Define starting and ending angles.
startingAngle = 25; % Degrees
endingAngle = 850; % Degrees
angleIncrement = 15;
theta = startingAngle : angleIncrement : endingAngle; % Or could also use linspace()
% Define starting and ending radii. One radius for every angle, so must use linspace().
startingRadius = 45;
endingRadius = 100;
radius = linspace(startingRadius, endingRadius, length(theta));
x = radius .* cosd(theta) + xCenter;
y = radius .* sind(theta) + yCenter;
% Plot the spiral.
plot(x, y, 'b.-', 'MarkerSize', 30, 'LineWidth', 2);
% Plot a crosshairs at the center.
hold on;
plot(xCenter, yCenter, 'r+', 'MarkerSize', 125, 'LineWidth', 2);
axis equal;
xlabel('x', 'FontSize', 20);
ylabel('y', 'FontSize', 20);
grid on
How do I create a set of random locations within a circle?[]
To create a set of (x,y) coordinates within the perimeter of a solid circle (a disc), you can use code like this from Roger Stafford in his Answers posting:
% Create a random set of coordinates in a circle. % First define parameters that define the number of points and the circle. n = 5000; R = 20; x0 = 50; % Center of the circle in the x direction. y0 = 90; % Center of the circle in the y direction. % Now create the set of points. % For a full circle, use 0 and 2*pi. angle1 = 0; angle2 = 2*pi; % For a sector, use partial angles. % angle1 = pi/4; % angle2 = 3*pi/4; t = (angle2 - angle1) * rand(n,1) + angle1; r = R*sqrt(rand(n,1)); x = x0 + r.*cos(t); y = y0 + r.*sin(t); % Now display our random set of points in a figure. plot(x,y, '.', 'MarkerSize', 5) axis square; grid on; % Enlarge figure to full screen. set(gcf, 'units','normalized','outerposition',[0 0 1 1]); fontSize = 30; xlabel('X', 'FontSize', fontSize); ylabel('Y', 'FontSize', fontSize); title('Random Locations Within a Circle', 'FontSize', fontSize);
How do I create a set of random locations on the surface of a sphere?[]
To create a set of (x, y, z) coordinates uniformly and randomly distributed over the surface of a hollow sphere (a round shell), you can use code like this from Roger Stafford in his Answers Forum posting [4]
% Define the radius of the shell of points, the surface of the sphere. radius = 10; % Define the number of points to place on the surface of the sphere. numPoints = 1000; % Use a large value. % Get a 3-by-numPoints list of (x, y, z) coordinates. r = randn(3, numPoints); % At this point the points can be anywhere in 3D space, % not just on the surface of a sphere, a shell of constant radius. % Divide by the distance of each point from the origin. % This will place each point out at a definite radius of 1, not scattered throughout the volume. r = bsxfun(@rdivide, r, sqrt(sum(r.^2,1))); % Now multiply by radius to make the shell out % at a specified radius instead of a radius of exactly 1 r = radius * r; % Extract the x, y, and z coordinates from the array. x = r(1,:); % Extract x from row #1. y = r(2,:); % Extract y from row #2. z = r(3,:); % Extract z from row #3. % Display the shell of points scatter3(x, y, z); axis square; % Make sure the aspect ratio is maintained as it's displayed and rotated. xlabel('X', 'FontSize', 20); ylabel('Y', 'FontSize', 20); zlabel('Z', 'FontSize', 20); % Enlarge figure to full screen. set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]); msgbox('Now use the circular arrow icon on the toolbar to rotate the sphere.');
How do I adjust the font size of a tick label?[]
The ticklabel gets its properties from the axis to which it is attached. So set(gca, 'fontsize', 14) should do the trick. Type get(gca) to see what else you can set.
Can I create a pi/sigma/superscript in my ticklabels?[]
Not directly... MATLAB does not interpret TeX strings in ticklabels. You can play games with placing text by hand. See the MathWorks solution for some ideas of how to work around this.
There are also some free third-party software packages you can use to accomplish this. One community-generated solution in the MATLAB File Exchange is Format Tick Labels (http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=15986) as an example. It will replace axes tick labels with formatted text objects that can include both Tex and LaTex interpreted strings.
Doug Schwarz has written a Styled Text Toolbox that does this. It is freely available at: http://www.frontiernet.net/~dmschwarz/stextfun/index.html
At least from 2014 this is supported via MATLAB. See here: Change Axis Tick Values and Labels
Can I open multiple files using uigetfile?[]
As of MATLAB 7.0 (R14), you can use the 'MultiSelect' parameter with UIGETFILE to allow the selection of multiple files. If you are using a version of MATLAB prior to version 7.0, you can use the `uigetfiles.dll' submission on the MATLAB Central File Exchange to do this on a Windows platform. This file is located here (http://www.mathworks.com/matlabcentral/fileexchange/Files.jsp?type=category&id=&fileId=331).
I want to use a scrollbar to scroll my edit boxes/buttons[]
Sorry, there's no easy solution. MATLAB does not support hierarchical figures, so you can't have a container control holding your controls. If you really need this you'll have to create your own, using the callbacks from the scrollbar to modify the position properties of your controls.
Ghassan Hamarneh writes:
What I would do is to add 2 pushbuttons to the figure: one at the top right and another at the bottom right and use these buttons to control the vertical scroll of the content of the figure. (surely you can add another 2 horizontal pushbuttons, lower left and lower right).
Whenever any of these buttons is pressed, you loop over all the controls except the two pushbuttons, and increment/decrement the vertical/horizontal postition value of each control. Something like this:
% fig_handle is the handle of the figure containing the UI controls % pushb1_handle, pushb2_handle are the handles of the pushbuttons % described above % find handles of all the controls all_handles=findobj(fig_handle); % exclude the handles of the 2 pushbuttons and the figure itself move_handles=setdiff(all_handles, ... [fig_handle, pushb1_handle, pushb2_handle]); % loop over the remaining handles and change their positions for k=1:length(move_handles) set(move_handles(k),'position', ... (get(move_handles(k),'position'))-[0 0 0 10]); end
How can I rotate ticklabels?[]
As of release R2014b, set the axes XTickLabelRotation, YTickLabelRotation, or ZTickLabelRotation properties. See the "Tick Values and Labels" section of the documentation for axes properties for more information.
For earlier releases, you cannot rotate tick labels directly but there are some community-generated solutions to simulate this in the MATLAB Central File Exchange. See Format Tick Labels (http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=15986) as an example.
How can I display data in a grid like Excel?[]
If you simply want to edit the matrix as if it were an Excel spreadsheet, you can use the builtin Array Editor. Type openvar(my_var) at the command prompt, or double click on the variable in the Workspace Browser. Or you can use the uitable control. See the help for uitable.
How can I write a title or text with multiple lines?[]
This can be done using a cell array of strings:
title({'First line','Second Line'}) text(0.5, 0.5, {'First line','Second Line'})
Or can be done with sprintf():
filename = 'cameraman.tif'; variableValue = 1234; % Note the \n in the format string to cause a new line: axesCaption = sprintf('The file is %s\nThe value is %d',... filename, variableValue); title(axesCaption, 'FontSize', 18);
For more sophisticated titles, including those with special characters or even images in them, or to put titles on other things than axes (like legends), see Steve Eddins's blog: [5]
How can I use a common colormap among several images?[]
One way to do this is to insert a CAXIS command in your plotting function/script. For this to work well, you first need to have a first look at all of your data to determine what are the minimum and maximum values over the entire set of images. For example, if the overall minimum value amongst all images is 40 and the overall maximum is 256, you may issue the command "caxis([40 260])" for each image.
Tech note 1215, at http://www.mathworks.com/support/tech-notes/1200/1215.shtml, addresses a related question, namely "How can I use multiple colormaps in a single figure". As a bonus, it includes a thorough discussion of colormaps in general.
How can I set default handle graphics properties?[]
There are probably several hundred of these default handle graphics options. Rather than trying to remember any particular one, the best thing is to learn the general principle behind all of these default handle graphics properties. The basic call to insert into your startup.m file is :
set(0,'DefaultObjectnamePropertyName',Value)
For line objects, here are a few examples:
set(0,'DefaultLineMarkerSize',12); set(0,'DefaultLineMarker','d'); set(0,'DefaultLineLineWidth', 2);
Similarly, you can use these statements for axes objects:
set(0,'DefaultAxesLineWidth', 2); set(0,'DefaultAxesXGrid','on'); set(0,'DefaultAxesTickDir','out'); set(0,'DefaultAxesTickLength',[0.015 0.015]); set(0,'DefaultAxesFontName','Arial')
For more details, do a full text search for 'Defining Default Values' in the R12 online help, and click on the very first hit. Also see the following entries in the R12 online help:
- Graphics Object Hierarchy
- Types of Graphics Objects
How can I modify the default bar color used for histograms?[]
A histogram is made up of patch objects. The trick is to modify the FaceColor property of these patches. A short example follows:
x=rand(400,1); hist(x); % Default facecolor is blue h=get(gca,'Children'); set(h,'FaceColor', 'm'); % magenta facecolor % Draw only the edges of the bars making up the histogram set(h,'FaceColor', 'none');
How can I draw more than two lines with plotyy?[]
You can use the axes' handles to plot additional lines, as follows:
x1 = (1:10)'; x2 = x1; y1 = x1; y2 = x1.^2; %Plot one line against each of the left and right y-axis [ax, h1, h2] = plotyy(x1,y1,x2,y2); %Plot additional line against the left y-axis x3= x1; y3 = y1 + 3; h3 = line(x3,y3,'Parent', ax(1), 'Color',get(h1,'Color')); %Plot additional line against the right y-axis x4= x1; y4 = y2+3; h4 = line(x4,y4,'Parent', ax(2), 'Color',get(h2,'Color')); set(ax,'YLimMode','auto','YTickMode','auto')
Is there a command available for plotting an arrow on a graph?[]
A user-contributed m-file (arrow.m) is available at http://www.mathworks.com/matlabcentral/fileexchange/Files.jsp?type=category&id=&fileId=278
Also look at arrow3.m at http://www.mathworks.com/matlabcentral/fileexchange/Files.jsp?type=category&id=36&fileId=1430
Why does movie(M,1) display the movie M twice?[]
This behavior, where MOVIE displayed the movie one time more than was requested, was eliminated in MATLAB 7.4 (R2007a), as mentioned in the release notes (http://www.mathworks.com/access/helpdesk/help/techdoc/rn/bq08z9s-1.html#bq08z9s-3).
In older releases, the movie function displayed each frame as it loaded the data into memory, and then played the movie the requested number of times all the data was loaded. This eliminated long delays with a blank screen when you loaded a memory-intensive movie. The movie's load cycle was not considered one of the movie repetitions.
How can I set the focus in my GUI?[]
You can't. One hopes that The MathWorks will include this often-requested feature in a future, but there is no guarantee.
Related to this, changing the stacking order of your GUI elements might allow you to set the tab order, but this seems to not always work. GUIDE in MATLAB version >= 6.5 includes a Tab Order Editor, which does a better job at this.
How can I add text labels to data points?[]
The text command can be used in a vectorized form to automatically add text labels wherever needed. Say you have a matrix D, where the first column contains X coordinates and the second column contains Y coordinates. Then us illustrates:
plot(D(:,1),D(:,2),'+-'); n=num2str(D,'%5.3f/'); n=n(:,1:end-1); % Just to remove the trailing slash text(D(:,1),D(:,2),n);
How can I create a movie from my MATLAB figures?[]
Try searching the File Exchange:
http://www.mathworks.com/matlabcentral/linkexchange/?term=movie
where you'll find entries such as these:
"How to combine MATLAB figures into a movie"
By Sandeep Somani, Center for Advanced Research in Biotechnology, U MD Biotechnology Inst
"How to Make a Movie from MATLAB"
I receive with a certain regularity the question: ``How do I make movies with Matlab? In fact, ...
Contributed by: MATLAB Central Team
http://www.mathworks.com/help/techdoc/creating_plots/f10-1460.html
You might want to use code similar to this:
% Make an avi movie from a collection of PNG images in a folder. % Specify the folder. myFolder = 'C:\Users\yourUserName\Documents'; if ~isdir(myFolder) errorMessage = sprintf('Error: The following folder does not exist:\n%s', myFolder); uiwait(warndlg(errorMessage)); return; end % Get a directory listing. filePattern = fullfile(myFolder, '*.PNG'); pngFiles = dir(filePattern); % Open the video writer object. writerObj = VideoWriter('YourAVI.avi'); open(writerObj); % Go through image by image writing it out to the AVI file. for frameNumber = 1 : length(pngFiles) % Construct the full filename. baseFileName = pngFiles(frameNumber).name; fullFileName = fullfile(myFolder, baseFileName); % Display image name in the command window. fprintf(1, 'Now reading %s\n', fullFileName); % Display image in an axes control. thisimage = imread(fullFileName); imshow(thisimage); % Display image. drawnow; % Force display to update immediately. % Write this frame out to the AVI file. writeVideo(writerObj, thisimage); end % Close down the video writer object to finish the file. close(writerObj);
How do I save my figure, axes, or image? I'm having trouble with the built in MATLAB functions.[]
Many people encounter trouble when they try to use the various built in MATLAB functions (such as print, saveas, hgsave, etc.) for saving figures, axes, or images. For example, the colors may be different than expected, there may be undesired spacing around it, it may be all black or all white, the overlay graphics don't get saved along with the underlying image, the resolution is not correct, the wrong part of the window is being saved, etc. Try using export_fig in the File Exchange. This may solve your problems. Does this work?
How can I get Greek letters and other symbols on my GUI?[]
Please visit this Answer: Answers Forum Tutorial on Greek Letters
Math/Algorithms[]
Why is 0.3 - 0.2 - 0.1 (or similar) not equal to zero?[]
(The above example returns -2.7756e-17.)
As is mentioned frequently in the newsgroup, some floating point numbers can not be represented exactly in binary form. So that's why you see the very small but not zero result. See EPS.
The difference is that 0:0.1:0.4 increments by a number very close to but not exactly 0.1 for the reasons mentioned below. So after a few steps it will be off whereas [0 0.1 0.2 0.3 0.4] is forcing the the numbers to their proper value, as accurately as they can be represented anyway.
a=[0 0.1 0.2 0.3 0.4]; b=[0:.1:.4]; as=sprintf('%20.18f\n',a) as = 0.000000000000000000 % == 0.100000000000000010 % == 0.200000000000000010 % == 0.299999999999999990 % ~= bs ! 0.400000000000000020 % == bs=sprintf('%20.18f\n',b) bs = 0.000000000000000000 % == 0.100000000000000010 % == 0.200000000000000010 % == 0.300000000000000040 % ~= as ! 0.400000000000000020 % == -and- format hex; hd=[a.',b.'] hd = 0000000000000000 0000000000000000 % == 3fb999999999999a 3fb999999999999a % == 3fc999999999999a 3fc999999999999a % == 3fd3333333333333 3fd3333333333334 % ~= ! 3fd999999999999a 3fd999999999999a % ==
If you're trying to compare two floating-point numbers, be very careful about using == to do so.
An alternate comparison method is to check if the two numbers you're comparing are "close enough" (within a tolerance value of each other). For example:
% Instead of a == b % If you have MATLAB release R2015a or later, use: a = 0.3; b = 0.1 + 0.2; tol = 5 * eps(a) % A very small value. areEssentiallyEqual = ismembertol(a, b, tol) % areEssentiallyEqual is a logical (a true or false value).
For older MATLAB releases:
% Instead of a == b % with releases R2014b and earlier, use: a = 0.3; b = 0.1 + 0.2; tol = 5 * eps(a) areEssentiallyEqual = abs(a-b) < tol % for some small value of tol relative to a and b
You can see this same sort of behavior outside MATLAB. Using pencil and paper (or a chalkboard, or a whiteboard, etc.) compute x = 1/3 to as many decimal places as you want. The number of decimal places must be finite, however. Now compute y = 3*x. In exact arithmetic, y would be exactly 1; however, since x is not exactly one third but is a rounded approximation to one third, y will not be exactly 1.
For a readable introduction to floating point arithmetic, look at Cleve's Corner article from 1996: Floating Points (PDF) (http://www.mathworks.com/company/newsletters/news_notes/pdf/Fall96Cleve.pdf)
For an official "Answer" by the Mathworks in the Answers forum, read Why-does-mat2str-0-005-90-return-0-0050000000000000001-in-matlab
For more rigorous and detailed information on floating point arithmetic, read the following paper: What Every Computer Scientist Should Know About Floating Point Arithmetic (http://docs.sun.com/source/806-3568/ncg_goldberg.html)
Another resource is Technical Note 1108 (http://www.mathworks.com/support/tech-notes/1100/1108.html) on the Support section of The MathWorks website.
And yet another is Loren's blog A Glimpse into Floating-Point Accuracy
How do I compute the mean of a vector in blocks?[]
Let's say you have a column vector or row vector and want to compute the mean of vector values in a window of length N that moves in jumps of N elements. In other words,you want to compute the mean in each block, with the blocks not overlapping. The window of length N will "jump" by N elements each time. Below is sample code that does this for both a column vector and a row vector.
% Take the means of elements in blocks of 3.
% Compute the means of elements 1-3, then of 4-6, then of 7-9, etc.
% Create sample data. First a column vector.
columnVector = (1 : 15)'
% Reshape into a 2-D matrix with 3 rows and 5 columns.
% Tip: one argument (either rows or columns) can be null [].
m2d = reshape(columnVector, 3, [])
% Get the means of the 5 columns.
means3 = mean(m2d, 1)
% Next create a row vector.
rowVector = (1 : 15)
% Reshape into a 2-D matrix with 3 rows and 5 columns.
% Tip: one argument (either rows or columns) can be null [].
m2d = reshape(rowVector, 3, [])
means3 = mean(m2d, 1)
What you'll see is
m2d =
1 4 7 10 13
2 5 8 11 14
3 6 9 12 15
means3 =
2 5 8 11 14
It's better to use a loop for to avoid problems with reshape due to vector and window length.
How do I compute a vector [1/1, 1/2, 1/3, 1/4, 1/5, 1/6, 1/7]?[]
Create a vector [1,2,3,4,5,6,7] and then use dot slash to divide 1 (in the numerator) by that vector (in the denominator):
>> v = 1 ./ (1 : 7)
v =
1.0000 0.5000 0.3333 0.2500 0.2000 0.1667 0.1429
If you want to use the Symbolic Toolbox and get ratios, you can do this:
>> sym( 1 ./ (1:7) )
ans =
[ 1, 1/2, 1/3, 1/4, 1/5, 1/6, 1/7]
How can I fit a circle to a set of XY data?[]
An elegant snippet of MATLAB code to perform least-squares circle fitting was written by Bucher Izhak in 1991. The first reference to it that we can find is in msgid:<3A13371D.A732886D%40skm.com.au>:
function [xCenter, yCenter, radius, a] = circlefit(x, y) % circlefit(): Fits a circle through a set of points in the x - y plane. % USAGE : % [xCenter, yCenter, radius, a] = circlefit(X, Y) % The output is the center point (xCenter, yCenter) and the radius of the fitted circle. % "a" is an optional output vector describing the coefficients in the circle's equation: % x ^ 2 + y ^ 2 + a(1) * x + a(2) * y + a(3) = 0 % by Bucher Izhak 25 - Oct - 1991 numPoints = numel(x); xx = x .* x; yy = y .* y; xy = x .* y; A = [sum(x), sum(y), numPoints; sum(xy), sum(yy), sum(y); sum(xx), sum(xy), sum(x)]; B = [-sum(xx + yy) ; -sum(xx .* y + yy .* y); -sum(xx .* x + xy .* y)]; a = A \ B; xCenter = -.5 * a(1); yCenter = -.5 * a(2); radius = sqrt((a(1) ^ 2 + a(2) ^ 2) / 4 - a(3));
Tom Davis provided a more sophisticated approach that works for more cases in
msgid:<3C76E5AA.350DA497@eng.usf.edu> and msgid:<3C785735.F7F192BC@eng.usf.edu>. Code is included.
How can I fit a circle to a set of XYZ data?[]
To fit a circle to a set of 3-D (x, y, z) data points, see this link: https://de.mathworks.com/matlabcentral/answers/475212-circle-least-squares-fit-for-3d-data
How can I fit an ellipse or other shape to a set of XY data?[]
See this paper Least-squares orthogonal distances fitting of circle, sphere, ellipse, hyperbola, and parabola
You can also see this MATLAB Answers post: https://www.mathworks.com/matlabcentral/answers/461127-using-inbuilt-ransac-function-for-circle-fit-in-2d-data#answer_622322
How do I find the area of a polygon?[]
You can use the built-in function polyarea. If you wish to avoid using 'polyarea', one method is this (offered by Roger Stafford). Let x and y be vectors of the corresponding coordinates of the polygon's vertices taken in counterclockwise order around the polygon.
area = 1/2*sum(x.*y([2:end,1])-y.*x([2:end,1]));
How do I find the areas of contours?[]
You can find the areas of closed contours you generated with the contour function with the following code:
[x, y, z] = peaks; % Generate sample data. [C, h] = contour(x, y, z, 20); % Find contours. ch = get(h, 'children'); areas = zeros(numel(ch), 1); for k = 1 : numel(ch) % Get the x and y coordinates of this contour. x = get(ch(k), 'xdata'); y = get(ch(k), 'ydata'); [x, y] = poly2cw(x, y); % Compute area of this contour. areas(k) = polyarea(x, y); end
How does the backslash operator work? What does it do?[]
For full matrices, pseudocode describing the algorithm can be found in the MathWorks Technical Solution How does the backslash operator work when A is full? (http://www.mathworks.com/support/solutions/data/1-172BD.html?solution=1-172BD) or Operating on Sparse Matrices (http://www.mathworks.com/access/helpdesk/help/techdoc/index.html?/access/helpdesk/help/techdoc/math/f6-8856.html).
Also for sparse matrices, you can turn on monitoring routines that show you some of the steps. Use spparms('spumoni', 1), or spparms('spumoni', 2)
How does one compute a factorial?[]
After MATLAB5.3, there is a factorial function, but it is not vectorized. Why this is so we will never know. Instead, you can use the gamma function, which is vectorized. Careful, factorial(n) = gamma(n+1). If you are trying to compute a ratio of factorials, see the next question.
How can one accurately compute ratios of factorials?[]
If you are trying to compute "n choose k", just use the function nchoosek. Otherwise, Paul Skoczylas suggests in msgid:<bzAM5.2437$pQ4.21981@jekyl.ab.tac.net>
If I wanted to evaluate n!/(n-j)! for large values of n and/or j (but still assuming n>j), I would use the gammaln function.
gamma(m+1)=m! gammaln(m+1)=log(m!)
Rewrite and manipulate the equation:
A=n!/(n-j)! log(A)=log(n!/(n-j)!) log(A)=log(n!)-log((n-j)!) A=exp(log(n!)-log((n-j)!))
so,
A=exp(gammaln(n+1)-gammaln(n-j+1))
Why does MATLAB return a complex number for (-8)^(1/3)[]
In the same way there are two solutions (plus and minus) for the square root of a positive number, there are multiple solutions for roots of negative (and complex) numbers. If you express the number in magnitude*exp(i*theta) form, the cube root (for instance) takes the form (magnitude^(1/3))*exp(i*(theta+2k*pi)/3), for k=0:2 or 1:3.
-8 is 8*exp(i*pi), so theta=pi and the cube roots are 2*exp(i*pi/3), 2*exp(-i*pi/3), and 2*exp(i*pi). The last one simplifies to -2.
MATLAB always returns the first solution counter-clockwise from the positive real axis, i.e. 2*exp(i*pi/3) or: 1 + 1.732i. Armed with this knowledge, you can compute all or some particular root. For instance, if you want the negative real cube root, simply take the cube root of the absolute value of the number, and negate it.
For a different wording and more information, see the related [MathWorks Tech Solution http://www.mathworks.com/support/solutions/data/1-15M1N.html?solution=1-15M1N].
Finally, Joe Sababa suggests in msgid:<eeada27.1@WebX.raydaftYaTP> a method to find all the roots at once:
Find the roots of a polynomial:
P=[1 0 0 27]; roots(P)
An alternate method to obtain -2 as a cube root of -8 is to use the NTHROOT function:
x = nthroot(-8, 3)
x =
-2
Can I compute the DFT of an irregularly-sampled signal?[]
The easiest way to find the spectrum of irregularly sampled data is to resample it to uniform samples. You can do this with MATLAB's interp1
function. The accuracy of your spectrum will depend on the accuracy of the interpolation. You will want to experiment with several of the interpolation methods that are available in interp1
. I believe that for interpolation with a limited window (i.e. interpolating a sample value from N nearest neighbors), the Lagrange interpolation is optimal, but Lagrange is not one of the choices in interp1
.
If interpolation doesn't work there are other schemes available. The Lomb-Scargle periodogram is often mentioned in relation to this question and may be more appropriate if your data has very uneven spacing (e.g. very large or very small spacings). I know that this algorithm is listed in Numerical Recipes, but I don't have a good on-line reference (with MATLAB code) to point you to.
In general, the problem is that the spacing between points determines the "importance" of a particular point. For example, if several points are very close together, then small amounts of noise on those measurements will tend to have a greater effect on inferring the slope of the function (and with it, the high frequency energy) than the same amounts of noise on measurements that are further apart.
How can I efficiently do row-wise vector-matrix multiplication?[]
Elaborating on the question, the for-loop implementation looks like:
for row = 1:N output(row, :) = vector(row) * matrix(row, :); end
In recent MATLAB versions (>= 6.5), this is actually not such a bad idea, as the accelerator will do a good job on a loop like this.
The "old-style" vectorized version of this uses repmat.
output = matrix .* repmat(vector, 1, M);
This is a fine solution, except that having to replicate vector uses memory unnecessarily, and is less cache-efficient. The accelerated single loop may run faster in some cases, dujjkke to the better cache-usage.
In newer versions of MATLAB you can use bsxfun. BSX stands for Binary Singleton eXpansion. It accomplishes the same thing without the memory footprint of repmat and is more compact than a for-loop.
output = bsxfun(@times,matrix,vector);
Finally, there is a solution using sparse. Ken Davis writes:
If A is MxN and B is Nx1 or 1xN, then A*sparse(1:N, 1:N, B) multiplies the columns of A by the elements of B. Similarly, sparse(1:M, 1:M, B)*A multiplies the rows of A by the corresponding elements of B. For division, use 1./B in place of B as the argument to sparse.
This solution requires the conversion of the full vector to a sparse format, but the actual computation will be very fast. The fastest solution depends on the sizes involved, so try them all!
How do I find "kinks" in a curve?[]
If you have a set of (x,y) points that define a curve, and you want to find discontinuities in the slope, or "kinks" in the curve, you can check the radius of curvature between 3 points along the curve. Please see this reference: Posting by Roger Stafford in the Answers forum
Installation, Crashes, Platform-Specific Issues[]
How do I release or deactivate a MATLAB license?[]
Follow the instructions in technical support solution document. Follow this link: Deactivate MATLAB. It has instructions for both when you have MATLAB still installed and still have the computer, and for when MATLAB has been uninstalled or you do not have the computer.
When MATLAB automatically activates, it registers the volume serial number and the MAC addresses of the machine to your license.
If you cannot access the computer you want to deactivate MATLAB on, you can deactivate the "old computer" that MATLAB registered to by deactivating manually from your MathWorks License Center, since technically it is no longer accessible and can't be deactivated from that specific machine with the specific MAC address.
To deactivate MATLAB from the MathWorks License Center
- Select the license you want to deactivate.
- Select the "Install and Activate" tab
- Under the last column, "Deactivate," click the blue X in the row of the activation you want to deactivate.
- Click the "Manual Deactivation agreement" above the buttons near the bottom of the form.
- Answer the two questions on the page.
- Type your name to confirm you that cannot retrieve the deactivation string.
- Click "Submit Agreement to Deactivate Software" to complete the deactivation process.
During installation, the installer crashes, hangs, gives an error message, does not authenticate your license, or otherwise does finish installing correctly.[]
There are so many ways that you could have problems during installation and volunteers in the Answers forum can't possibly know the solutions to all of them or even some of them. Asking in the Answers forum or the Newsgroup will only delay you from getting the issue solved. The Mathworks gives free support for all installation problems, even by telephone and even for the Student Edition. This is the fastest way to solve your installation problem: call The Mathworks at (508)647-7000. Although the Student Edition normally does not get technical support, it does get support for installation issues.
After installation, MATLAB crashes or gives an error message when I try to run MATLAB.[]
The causes for crashes are many and complex, and complicated to figure out, especially if you don't have access to the source code. This is why it's best for The Mathworks to work on your crash issue. Asking other users in the Answers forum may provide an answer but the chances are slim. Your best bet is to call The Mathworks at (508)647-7000 and explain to them the circumstances for your crash. The Mathworks gives free support for all installation problems, even by telephone and even for Student, Home, or Trial versions. Note, this is just if MATLAB itself crashes, not if it's your m-file throwing an error (red text in the command window) or a DLL or mex file causing the crash.
How do I release or return a toolbox license key back to the pool of available keys without restarting the license manager or exiting MATLAB?[]
Follow the instructions in technical support solution document 1-15HLG (http://www.mathworks.com/support/solutions/data/1-15HLG.html?solution=1-15HLG).
How can I make MATLAB open without the GUI?[]
Start MATLAB using the command matlab -nodesktop
. A related switch is -nojvm
, which starts MATLAB without the Java Virtual Machine, making it take much less memory. However many of the editor and browser features will not work.
Why doesn't Ctrl-C interrupt execution of my m-file?[]
This is likely to be a problem only under Windows, where MATLAB must poll for Ctrl-C events. If it is deep within matrix computation, it will simply not respond. If this occurs inside a loop construct, you can force MATLAB to poll more often by inserting drawnow or pause (0) into the loop. This will also update your figures and make GUIs more responsive.
Image Processing Toolbox[]
How do I split an image into non-overlapping blocks?[]
See this link for demo code: Split_image_into_blocks
How do I mask an image?[]
To set an image to some contant value either inside or outside some defined regions, you first need to make a binary image. See this page for demo code: Mask an image.
How do I segment and measure objects in an image?[]
Please refer to this demo: Image Analyst's "Image Segmentation Tutorial"
How do I find objects of a certain color?[]
To find objects or regions in a certain color range, please refer to: Image Analyst's Color Segmentation Demos
How do I extract frames from a video file?[]
To see how to extract individual frames from a video file and save them to disk, see this demo: Extract Frames From Movie. The demo also shows how to do image processing and analysis on the individual frames and displays the results as a function of frame number.
How do I build a movie from individual frames?[]
To see how to take individual frames from image files on disk and create and play a movie from them, see the bottom part of this demo: Extract Frames From Movie
How do I measure a distance or area in real world units instead of in pixels?[]
You need to measure an object of known length so that you can get a spatial calibration factor. Put a ruler, a tape measure, a standard sheet of paper, or anything else of known length into the scene. Then snap a picture of it and use imdistline() to find the length in pixels. For example, let's say you laid down a sheet of A4 paper and measured it's distance as 2100 pixels. Knowing that it is 21 cm long, you get a spatial calibration factor of 21/2100, which you multiply your distances in pixels by to get the distance in cm. Multiply by that calibration factor squared to convert the area in pixels to the area in square centimeters.
calibrationFactor = 21/2200; distanceInCm = distanceInPixels * calibrationFactor; areaInSquareCm = areaInPixels * calibrationFactor ^ 2;
MATLAB Compiler Toolbox[]
How can I make a standalone executable from my MATLAB code?[]
To generate a standalone executable that you can execute outside MATLAB or on a computer without MATLAB, you will need to use the MATLAB Compiler.
http://www.mathworks.com/products/compiler/
The section titled "Deployment Process" in the documentation for this product gives instructions on what steps you need to perform to run the executable on a machine that does not have MATLAB installed.
If something doesn't compile as expected, please refer to MATLAB's page:
Limitations About What May Be Compiled
My standalone executable won't run on the target computer. What can I try?[]
If you've deployed (installed) your standalone executable application on the end-user's computer and it won't run, there are various things you can try to fix the situation:
1) Make sure that you have installed the MCR (MATLAB Compiler Runtime) on the target computer that is the same version that you have on the system that compiled the program. A different version will not work. For example, a program compiled with version 8.1 will not work on a computer that does not have that exact 8.1 version installed on it. Earlier or later versions will not work. If this is the problem, then you should see an error message notifying you of this in the console window that appears as the application tries to launch. You can have multiple, even older, versions of MCR on the target computer without any conflict, but you must at least have the same version it was compiled with.
2) Run the Dependency Report to see what functions and files are called. On MATLAB since R2013b, click the down arrow on the title bar of the "Current Folder" panel and select "Reports/Dependency Report". On older versions, use the "Tools/Show dependency report" pull down menu item. See what files are called. Pay particular attention to those that are labeled "other."
3) Try fdep in the File Exchange. It's like a souped up version of the dependency report tool that's built into MATLAB. Look at all the modules that are listed. It sometimes finds modules that the Dependency Report tool doesn't.
4) Run DependencyWalker on the executable and look for any missing components. This must be run on the target computer, not the computer that compiled it, unless it won't run on that computer either.
5) Make sure any ancillary files that are needed at run time are shipped with the installation package. This includes DLL's, OCX's, initialization/configuration/mat files, sample data files, documentation, Excel templates, etc.
6) Call the Mathworks and let them figure it out. Sometimes the mistake is on their side. For example, one time they figured out that there was something missing in the image processing toolbox or the compiler so that compiled versions didn't run. They made a patch for it.
7) Also be aware that the MCR installer may claim that it will install the Microsoft Visual C redistributable. However that never seems to work for me and Dependence Walker will show that it can't find msvcr80.dll and msvcr90.dll. In this case, go to the Microsoft web site and download and install the redistributable yourself. You can also try here: Latest Supported Visual C++ Downloads. After doing that it seems to work most of the time. Sometimes the installer just quits after installing the Visual C++ redistributable and never installs the actual MATLAB run time library software. Some have found that rebooting after that first installation where it quits will allow you to rerun the MCRInstaller.exe and it will then finish.
8) Check your startup.m code for commands that should not be run in a deployed executable. When your compiled app runs, it also executes the startup.m file that you had when you compiled the code. So whatever code you had in your startup.m file will also get run on the target computer. It is not obvious to people that their startup.m code gets run before the actual code that they wanted to run gets run, but it does. So make sure that everything that's in there makes sense when run on the target computer. For example if your startup.m code changes directory to a particular directory, or reads a specific file, and that file does not exist on the target computer, it will throw an error or warning. You can have code in your startup.m file that runs only on your computer while in development mode, and other code that is run only in deployed code on the target computer if you check the isdeployed variable. It is a built-in variable that is true if the code is compiled and false if it's source code running in the normal MATLAB development environment. For example:
if isdeployed % Code that gets run only by compiled applications uiwait(msgbox('This is a compiled application')); else % Code that gets run only in development environment uiwait(helpdlg('You are in development mode.')); % For example, set current folder to your main working code folder. cd('C:/SomeFolderOfYours'); end
9) Have the startup code for your application print out ctfroot to the console window to see where the executable actually unpacks the executable to.
fprintf(1, '%s', ctfroot);
If you refer to subfolders in your application, they will actually be under this folder, which is usually in a temporary, hidden folder (in Windows, it's under C:\Documents and Settings\username\Local Settings\Temp) and not where you installed your executable.
10) If your application tries to call a DLL with a different number of bits, you will have trouble - it may not launch. For example, you cannot compile a 64 bit m-file that tries to call a 32 bit DLL. This is a common problem with users trying to call old DLLs from third party manufacturers (e.g. manufacturers of cameras or other peripherals). If you're calling a 32 bit DLL, you MUST use the 32 bit version of MATLAB to compile it, and install the 32 bit version of the MCR from the matching MATLAB Release on the target computer. The target computer can be either a 32 bit computer or a 64 bit computer. You can install both the 32 bit and 64 bit versions of MATLAB on your computer and they will live happily together with no conflicts.
11) If you're running the executable by double-clicking the icon in Windows Explorer, and it encounters an unhandled error (an error that you don't catch in a try/catch block), then the application may just exit before you ever see any error messages. To make sure you see the error messages before they vanish, run the program from a console window (an MS-DOS command prompt). From the start menu, type cmd in the run box to get a console window. Then use cd to navigate to the folder where you have your executable. Then type in the name of the executable. When it runs, any errors will go to the console window but the console window will not close and you'll have the ability to see the errors. You might also be able to do this from the MATLAB command window prompt if you type an exclamation point (bang) followed by the name of the executable.
12) Some Simulink blocks implement portions of their functionality using shared libraries (DLL files on Windows). Additionally, in some cases EXEs generated from models using these blocks are dependent on these shared libraries as well. In this case it seems like the Simulink UDP Send block has some of these dependencies.
The PACKNGO function can be used to locate the needed shared libraries. Go into your modelname_target_rtw folder and load the 'buildInfo' object into the workspace from the "buildInfo.mat" file. Then you can execute the command
>> packNGo(buildInfo);
This will create compressed folder in the same directory containing the generated EXE. This compressed folder should contain any DLLs that the generated EXE is dependent on. When running the EXE outside of the MATLAB/Simulink environment these DLLs need to be on the system path or within the same directory as the EXE. This information came from the Answers forum
Why can't my standalone compiled executable find my files?[]
The folder where you installed your compiled executable is not the actual folder that your application runs out of. For example, it's not really in C:\Program Files\MyApp (or wherever), it's really in some secret hidden folder - for example, in C:\Users\MyUserName\AppData\Local\Temp\MyUserName\mcrCache7.16\MyApp\. So if you put any files in the folder where you think the exe is (C:\Program Files\MyApp), it won't find them because the exe is not really there. The exe in that folder is actually a self-extracting archive that unzips the real executable to the secret folder. So your file would have to be located there in that secret folder for your executable to see it (that is, if you neglected to include the full path and just assume it would find your file in the current working directory, which is bad practice). The ways around this are to ship the files with the -a option of mcc, or include it in deploytool if you're using deploytool to create your executable. Or better yet, specify the full path of any files you use and make sure they're there. Use fullfile() to create full file names, and isfile(filename) to check for them before you use them. Alert the user with uiwait(warndlg(yourWarningMessage)) if the file does not exist. Create yourWarningMessage with sprintf() explaining the missing file to your user.
If you don't want your exe to unpack the archive to a secret hidden folder, then (in Windows) you can set the MCR_CACHE_ROOT environment variable to "." (dot). Then it will unpack a bunch of stuff (subfolders, etc.) to the current folder (where at least you can see it and know it's there).
How can I suppress the black console window (DOS command window) when I run my standalone executable?[]
See the Compiler Documentation. You have to use the -e option.
"Suppress appearance of the MS-DOS command window when generating a standalone application. Use -e in place of the -m option. This option is available for Windows only. Use with -R option to generate error logging as such:
mcc -e -R -logfile -R filename -v function_name
or:
mcc -e -R '-logfile logfilename' -v function_name
You can also suppress the MS-DOS command window when using deploytool by creating a Windows Standalone Application."
What is the path in my deployed application?[]
Please read Loren's discussion here: Path management in deployed applications.
Toolboxes, Blogs, Software Archives, Books, and Other Resources[]
What toolboxes or other m-files does my m-file use?[]
First of all, you can find out what toolboxes are installed on your computer by issuing the "ver" command in the MATLAB command window. To find out what toolboxes are required by any specific m-file, you can:
- Select "Tools->Show Dependency Report" from the main MATLAB pulldown menu. To get the Tools menu to show up, you must have focus in the Editor window (not the Command window). In other words, you must have clicked last in the Editor window to make it the active window.
- You can use "fdep" from the File Exchange. This sometimes finds dependent files that the dependency report doesn't find.
- You can use "depfun" from the File Exchange.
Where can I find the release notes for all the versions?[]
The Release Notestell you what new features were introduced, or what bugs were fixed, in versions since the year 2004. Other than the direct link just given, here's a way to navigate to the release notes for current and older versions of MATLAB.
- Start at The MathWorks home page.
- Click on Support.
- Click on Product Documentation.
- Click on MATLAB.
- Click on MATLAB Release Notes.
Note that release notes are available there for releases back to R14 in 2004. The release notes summarize new features, compatibility considerations, and fixed and known bugs.
Similarly, you can find release notes for the Image Processing Toolbox going back to version 2.2.2 in 2000.
[]
Official Mathworks blogs:
Other users' blogs:
http://www.cb.uu.se/~cris/blog/
http://imageprocessingblog.com/
Where can I find an archive of user-contributed MATLAB software?[]
The MathWorks has a website for user-contributed MATLAB files:
http://www.mathworks.com/matlabcentral/fileexchange/ .
Where can I find a package to perform a specific task?[]
First, check the File Exchange for free, user-contributed code submissions:
http://www.mathworks.com/matlabcentral/fileexchange/
Next, look to the Mathworks web site's product listing:
http://www.mathworks.com/products/product_listing/index.html
Finally, you can look to other specific user-written toolboxes, such as:
Styled Text Toolbox: written by Doug Schwarz, this toolbox allows extremely flexible formatting of text strings, including symbols, math formulae, etc. Its TeX interpreter is much more complete than the builtin MATLAB interpreter. http://www.frontiernet.net/~dmschwarz/stextfun/index.html
MATLAB and LaTeX: Arno Linnemann has written an M-file to simplify the inclusion of MATLAB graphics into LaTeX documents, along with a nice document of tips and tricks. http://www.uni-kassel.de/~linne/matlab/WelcomeEng.html
Genetic Algorithm Optimization Toolbox: GAOT implements simulated evolution in the MATLAB environment. Written by the Meta-Heuristic Research and Applications Group at the North Carolina State University Department of Industrial Engineering: http://www.ise.ncsu.edu/mirage/GAToolBox/gaot/ (WARNING: as of Nov. 10, 2010 that link is defunct).
What textbook would you recommend for learning MATLAB?[]
One choice is the image processing book written by Steve Eddins. Steve Eddins is a software development manager in the MATLAB and image processing areas at MathWorks. Steve coauthored Digital Image Processing Using MATLAB. He writes about image processing concepts, algorithm implementations, and MATLAB, both in the book and on his Steve on Image Processing blog.
Where can I find MATLAB Style Guides or Coding Standards?[]
Richie Cotton's guide: http://4dpiecharts.com/matlab-code-style-guide/
Richard Johnson's guide: http://www.mathworks.com/matlabcentral/fileexchange/2529
David Schwartz's guide: http://www.cs.cornell.edu/courses/cs99/2002fa/matlabstyle.html
Where are the official Mathworks Tech Notes for MATLAB and Simulink?[]
There aren't many of them but they can be found off the Mathworks Support web page here: Tech Notes and How-to Guides
Where are the official Mathworks Bug Reports for MATLAB and Simulink?[]
They can be found off the Mathworks Support web page
What toolboxes or other m-files does my m-file use?[]
First of all, you can find out what toolboxes are installed on your computer by issuing the "ver" command in the MATLAB command window. To find out what toolboxes are required by any specific m-file, you can:
- Select "Tools->Show Dependency Report" from the main MATLAB pulldown menu. To get the Tools menu to show up, you must have focus in the Editor window (not the Command window). In other words, you must have clicked last in the Editor window to make it the active window.
- You can use "fdep" from the File Exchange. This sometimes finds dependent files that the dependency report doesn't find.
- You can use "depfun" from the File Exchange.
List of external MATLAB toolboxes[]
- FEATool Multiphysics - An easy to use finite element FEM physics simulation toolbox.
- Geometry Processing Toolbox
- Multiprecision Computing Toolbox - MATLAB extension for computing with arbitrary precision
Simulink[]
How do I insert a Simulink model into an MS Office Document?[]
What are best practices for modeling communications systems with Simulink?[]
Miscellaneous[]
Can you program up the algorithm in this article for me and explain it to me?[]
You may find that the algorithm in the scientific article is interesting and may be useful to you, but you may not understand it, or you may not know how to program it up in MATLAB, so you ask if anyone in the Answers forum or newsgroup will program it up for you. Unfortunately, the volunteers who participate in the Answers forum generally don't have the time to read your scientific article, understand it themselves, then code it up for you, explain both the algorithm and code to you, and finally hand over the code to you.There are just too many papers - we can't even find the time to read the papers that we already have that we find interesting, much less other ones. If you really need it done, here are some options for you:
- Write it yourself.
- Ask the authors of the paper for the source code. They may give it to you for free, or they may sell it to you.
- Hire The Mathworks to write it for you [6] They will charge you for their time of course.
- Hire a consultant or university to write it for you. They will charge you for their time of course.
How do I run MATLAB in batch mode?[]
On the PC, you can use the /r
flag to start your m-file immediately upon starting MATLAB. Using this in combination with the Windows Task Manager, you can set a MATLAB job to run when you want it to run, even if you are not at the computer. Please note that you will need to exit MATLAB at the end of the m-file. Alternately, if you only want a single file to run, you can name it startup.m and place it in your MATLAB directory.
For UNIX, you can use the at
or cron
commands to execute a script which runs MATLAB. In the script, use this general syntax:
matlab < MyMFile
If you want to record output, either use the SAVE command inside your m-file or redirect the output of the MATLAB session to a file using this syntax:
matlab < MyMFile > MyOutputFile
This syntax only works for scripts. If you need to run a function, create a wrapper script that calls the function.