Is there a similar concept to Unix 'alias' within Matlab?
This question Is there a way to do command aliasing in matlab R2011b? suggests defining anonymous functions, and extending the answer these could be sourced at startup, but this results in the function handles appearing in the Workspace, which will disappear when cleared.
Is there a more robust and Unix analogous solution? Seems like a pretty useful thing to be able to do...
I am not sure why you would want to do this, but...
Assuming you are willing to have a directory on the path dedicated to aliases you can create m files in that directory to run the aliases. In this case the aliases will not exist in the workspace. You could of course just write the alias files your self, but the following function will create aliases for you automatically. The function can get confused if the function/script you are trying to alias is not currently on the search path. The function is not "perfect" in the sense that you do not write
alias myAlias = run('full/path/to/some/script')
but rather
alias myAlias full/path/to/some/script
function alias(aliasName, functionName)
% alias myfoo foo
aliasPath = './alias';
isscript = false;
try
nargin(functionName);
catch %#ok<CTCH>
isscript = true;
end
if isscript
fileID = fopen([aliasPath, aliasName, '.m'],'w');
fprintf(fileID, '%s\n', ['run(', functionName, ')']);
fclose(fileID);
else
fileID = fopen([aliasPath, aliasName, '.m'],'w');
fprintf(fileID, '%s\n', ['function varargout = ', aliasName, '(varargin)']);
fprintf(fileID, '\t%s\n', ['varargout{1:nargout} = ', functionName, '(varargin{:});']);
fprintf(fileID, '%s\n', 'end');
fclose(fileID);
end
end
Yes there is a way. It's called a function. You just write a function to do whatever you want the alias to do. For example:
function cdhome
cd(getenv('MATLABUSERPATH'))
Then just type cdhome at the command line, exactly like an alias in a unix shell. Note that MATLABUSERPATH is an environment variable I define in startup.m. It can be easier, just save a script called cdhome.m with the following content:
cd(getenv(<ENVIRONMENT_VARIABLE_THAT_DEFINES_MY_FAVORITE_PATH>))
Or how about:
clc; clear; close all;
Save that in a script file called clean.m and then simply put clean at the top of your scripts instead of clc; clear; close all;
No, it doesn't exactly follow the unix idea of having a bunch of alias's in a single configuration file that executes on startup.
But you can do that too. Put all your aliases in a switch block, in one function, call it alias:
function alias(thecalledalias)
switch thecalledalias
case somealias
% ... define some alias
case someotheralias
% ... define some other alias
end
For autocomplete, which you would get with your shell, put a functionSignatures.json file in the same folder as the alias.m function file and populate it with your aliases:
{
"_schemaVersion": "1.0.0",
"alias":
{
"inputs":
[
{"name":"thecalledalias", "kind":"required",
"type":["char", "choices={'somealias','someotheralias'}"]}
]
}
}
Then you will get autocomplete when you type alias(...) at the command line.
But to me it is easier to have one folder, call it myaliases with one script or function for each alias, and you get autocomplete at the command line just like when you call any function (i.e., no need to type alias(<somealias>)).
Related
I am writing a script to access a function that has been written in another script.
When I run the second script the error is that the function is undefined.
I have been working backwards and am currently trying to get the function to work in the command window.
The function file has appeared in the current folder window. When it is highlighted all functions and parameters are displayed in the window below (displays the file name on top then the file contents).
I am still getting a function is undefined when I copy and paste the functions call from the script into the command window.
I tried rebuilding the functions individually in separate scripts, but I am still receiving an error message.
I have made sure the are in the same folder, and are spelled exactly the same, what am I doing wrong?
'''
%file name Lab_5_functions.m
function[vel] = velocity (g,m,co_d,t)
vel= ((g*m)/co_d)^(1/2)*tanh(((g*co_d)/m)^(1/2)*t);
end
function [dvel]= dvelocity (g,m,co_d,t)
dvel=(((.5*(g*m)/co_d)^(1/2)*tanh(((g*co_d)/m).^(1/2)*t_sec))-(((g*t)/(2*m))*(sech(((g*co_d)./m).^(1/2)*t))));
end
'''
v=velocity(1,2,3,4)
%error message below:
Undefined function or variable 'velocity'.
'''
Thanks
-MK
Matlab is searching for functions using filenames. So you define a single public function myfunc in a file myfunc.m.
You can define additional functions in that file, but they will not be accessible outside that .m file.
MATLAB looks for filenames to find the functions and expects the first line of that file to be a function definition.
For example: myfunc.m
function output = myfunc(input)
If you do want many functions in one file (like a module/library), I have used a work-around before: write all your functions in the file, then include an if-else block to call the correct function. Multiple arguments can be parsed with some simple checks (see nargin function). It is a less elegant solution; I only use it if I have many simple functions and it would be plain annoying to have heaps of .m files.
Here is a simple example:
Call the file: myfunc.m
function output = myfunc(fn, arg1, arg2, ...)
function out = func1(arg1, arg2, ...)
out = 0
if strcmp(fn, 'func1')
if nargin == 2
output = func1(arg1)
end
elseif strcmp(fn, 'func2')
...
end
This is a simple Matlab code that I'm trying to execute.
function result = scale(img, value)
result = value .* img;
end
dolphin = imread('dolphin.png')
imshow(scale(dolphin, 1.5));
The error says:
Error: File: scale.m Line: 5 Column: 1
This statement is not inside any function.
(It follows the END that terminates the definition of the function "scale".)
What am I doing wrong here?
scale.m is a function M-file because it begins with the keyword function. The part up to end is the definition of the function. When you call scale at the MATLAB command line, it executes the code in the function. The stuff that comes after end is not part of the function, and hence cannot be executed.
If you intended to write a script with a private function scale that you want to use only within this script, then put the lines of code that read and display dolphin at the top of the file. The private functions should come after the script part. This syntax is supported since MATLAB R2016b.
Otherwise, move the dolphin code to a different M-file, which would be a simple script M-file without any function definitions. This script can then use scale, which would call the function in the file scale.m.
A third alternative, keeping all code in the same file, is to not use a script at all, and put the script code inside a function:
function f % just a random name
dolphin = imread('dolphin.png')
imshow(scale(dolphin, 1.5));
end
function result = scale(img, value)
result = value .* img;
end
(The function name doesn't need to match the file name, although the MATLAB editor will warn you if these names don't match.)
This is probably too easy, but I cannot google the answer for this: how can I get command line arguments in matlab script.
I run matlab as matlab -nodisplay -r "run('script.m')" and I want to return all arguments as a list. Something similar to python sys.argv. How can I do this?
I'm using Linux Mint and MATLAB 2015a.
I came up with a simple function that works on both Windows and Linux (Ubuntu):
function args = GetCommandLineArgs()
if isunix
fid = fopen(['/proc/' num2str(feature('getpid')) '/cmdline'], 'r');
args = textscan(fid, '%s', 'Delimiter', char(0));
fclose(fid);
else
kernel32WasAlreadyLoaded = libisloaded('kernel32');
if ~kernel32WasAlreadyLoaded
temporaryHeaderName = [gettempfolder '\GetCommandLineA.h'];
dlmwrite(temporaryHeaderName, 'char* __stdcall GetCommandLineA(void);', '');
loadlibrary('kernel32', temporaryHeaderName);
delete(temporaryHeaderName);
end
args = textscan(calllib('kernel32', 'GetCommandLineA'), '%q');
if ~kernel32WasAlreadyLoaded
unloadlibrary kernel32;
end
end
args = args{1};
On your sample call, it would return this:
>> GetCommandLineArgs
args =
'/[path-to-matlab-home-folder]/'
'-nodisplay'
'-r'
'run('script.m')'
It returns a cell array of strings, where the first string is the path to MATLAB home folder (on Linux) or the full path to MATLAB executable (on Windows) and the others are the program arguments (if any).
How it works:
On Linux: the function gets the current Matlab process ID using the feature function (be aware it's an undocumented feature). And reads the /proc/[PID]/cmdline file, which on Linux gives the command line arguments of any process. The values are separated by the null character \0, hence the textscan with delimiter = char(0).
On Windows: the function calls GetCommandLineA, which returns the command line arguments on a string. Then it uses textscan to split the arguments on individual strings. The GetCommandLineA function is called using MATLAB's calllib. It requires a header file. Since we only want to use one function, it creates the header file on the fly on the temporary folder and deletes it after it's no longer needed. Also the function takes care not to unload the library in case it was already loaded (for example, if the calling script already loads it for some other purpose).
I am not aware of a direction solution (like an inbuilt function).
However, you can use one of the following workarounds:
1. method
This only works in Linux:
Create a file pid_wrapper.m with the following contents:
function [] = pid_wrapper( parent_pid )
[~, matlab_pid] = system(['pgrep -P' num2str(parent_pid)]);
matlab_pid = strtrim(matlab_pid);
[~, matlab_args] = system(['ps -h -ocommand ' num2str(matlab_pid)]);
matlab_args = strsplit(strtrim(matlab_args));
disp(matlab_args);
% call your script with the extracted arguments in matlab_args
% ...
end
Invoke MATLAB like this:
matlab -nodisplay -r "pid_wrapper($$)"
This will pass the process id of MATLAB's parent process (i.e. the shell which launches MATLAB) to wrapper. This can then be used to find out the child MATLAB process and its command line arguments which you then can access in matlab_args.
2. method
This method is OS independent and does not really find out the command line arguments, but since your goal is to pass additional parameters to a script, it might work for you.
Create a file vararg_wrapper.m with the following contents:
function [] = wrapper( varargin )
% all parameters can be accessed in varargin
for i=1:nargin
disp(varargin{i});
end
% call your script with the supplied parameters
% ...
end
Invoke MATLAB like this:
matlab -nodisplay -r "vararg_wrapper('first_param', 'second_param')"
This will pass {'first_param', 'second_param'} to vararg_wrapper which you can then forward to your script.
I want to run a function "folder/test.m". This path stands in a variable "var_path". How do I run the function with parameters?
You can use system command.
For example:
sys_com = ['C:\path\to\matlab.exe ', var_path, ' ', parameter1, ' ', parameter2];
system(sys_com);
First line creates a command as a string (parameters should be strings). Second line executes that string.
you can either change dir to var_path and then run test as a regular funciton.
Alternatively, you can add var_path to your path and run test.
Matlab does not allow including function files (like in C/C++, for example). There are two possbilities to achieve something similar:
Change the folder during script execution
Change the search path to make the function file visible to the Matlab interpreter
Example for 1:
cur_dir = pwd; % save current directory
cd(var_path); % change to directory containing the function
test(a, b);
cd(pwd); % change back to original directory
This can have unwanted side effects of course, e.g. if your script relies on other files in the current directory or if you write to files.
Example for 2:
cur_path = path(); % save current path variable
addpath(var_path); % add function path to Matlab path
test(a, b);
setpath(cur_path); % restore original path variable
I'm quite new to Matlab. I've defined a function inside a .m file, I want to use that function in that .m file inside another .m file, and I want to run the contents of that last .m file from the command window.
How should I go about accomplishing this?
EDIT- for clarification, I have one function a inside a.m, and a script inside b.m that uses the function a inside a.m. I would like to run this script inside b.m from the command window, but am not sure how to do so. (as a side note, I can totally convert the script in b.m into a function if need be)
EDIT- right now I just need to know how to import/load a matlab file and that is it!!!
If I understand your situation correctly, you have something like this:
A file (`A.m'):
function results = A(parameters)
% some code
A file (`B.m'):
function results = B(parameters)
% some code
You want to use function A inside B, you can just call that function from inside function B:
function results = B(parameters)
% some code
otherResults = A(otherParameters)
If your situation is something like what nimrodm described, your A.m file is something like:
function results = A(paramters)
% some code
function results = C(parameters)
% code of function C
end
end
function results = D(parameters)
% code of function D
end
There is no way of directly accessing C and D from outside A. If you need to use subfunction D outside of A, just make a file D.m containing
function results = D(parameters)
% code of function D
end
And preferably, removed the same code from function A.
For a nested function C, the same can be done in some (but not all) cases, as nested functions also have access to the variables of function A. In recent versions of MATLAB (I guess R2010b or R2011a), the editor highlights variables that are shared between a function and nested functions in teal. If you don't make use of the variables of function A inside of function C, just do the same as for function D. If you do, pass these variables as parameters and/or return values and adjust the rest of your code to reflect this. Test your code and afterwards, do the same as for D.
Most likely, you will not have case C, as this is an advanced feature in MATLAB.
There is however another case, if you are not using MATLAB functions, but MATLAB scripts in different files. You can call a script (both from command line and another function or script, just by its (file) name.
contents of file E.m:
% code for script E
contents of file F.m:
% some code
E;
Using that code, you execute all commands in E from inside script F. Beware that E and F will share all their variables, so if you begin your scripts by something like clear all; close all; clc;, you cannot pass any variables from F into E (and you will lose all results from F calculated before calling E.
In most cases it is better to use functions instead of scripts, so that's also the way to solve such a situation: make everything into functions with decent parameters and return values.
edit:
After you 'changed' your question, it's quite easy.
Let's consider you have the function, I will use different names, as that is more intuitive to understand. You have the function ackermann inside the file ackermann.m which you want to call from the script bigScript.m.
The file ackermann.m contains the Ackermann-Péter function (as an example):
function result = ackermann(m,n)
if m == 0
result = n + 1;
elseif m > 0
if n == 0
result = ackermann(m-1,1);
elseif n > 0
result = ackermann(m-1,ackermann(m,n-1));
else
error('n has to be positive');
end
else
error('m has to be positive');
end
end
From inside your big script, you can call the function ackermann as follows (if you want m = 1 and n = 1):
A = ackermann(1,1)
It's that simple, no need to load anything. But you need to remember to have the function 'available in your path', the easiest way to do this, is just keep the script and function files in the same directory.
Anyhow, I sense you are a starting MATLAB user: if you don't know what a function does, just type help functionname (substituting functionname of course) into the command window. You will notice that the function load is there to load data files, not for m-files (as the m-files in your path are used automatically).
In principle, MATLAB advocates the use of one function per .m file. You can call such a function from another .m file and from the MATLAB command line.
You can define multiple functions in one .m file, but only the first (or 'outermost') function can be accessed from other .m files or the command line. The other functions are treated as 'helper' functions that may be called only inside this particular .m file.
For anyone else searching for this question, as I did, just type:
addpath('[Path name of mat file]');
This will tell Matlab how to find the function. To verify, just type:
which [function name]
If successful, it should list the path name that you just added.