How to remove line from m file in MATLAB after its execution - matlab

I'm stuck in one case related to matlab.
I create a file through script by using these commands:
delete output
delete f.m
clc;
% This is a Cell Array!
prompt={'Enter Function f(x) Here :'};...
% Name of the Dialog Box
name='Trapezoidal Rule Input Screen';...
numlines=1; % Number of lines visible for User Input
% Default Answer
defaultanswer={'1 + exp(-x).*sin(4*x)'};...
% Creating the Dialog box where the User Input is stored into a Cell Array
answer=inputdlg(prompt,name,numlines,defaultanswer);...
global y1
y1=answer{1};...
diary f.m;
disp('function y = f(x)');...
%disp('y = '),disp(y),disp(';');...
%disp('y = ((1+(x^2))^-1);');...
fprintf('y=%s;\n',y1);
diary off;
f(0);
when the click on RUN CHECK button then f.m file had been created because it is part of script and generate the following code in f.m file
function y = f(x)
%disp('y = '),disp(y),disp(';');...
%disp('y = ((1+(x^2))^-1);');...
fprintf('y=%s;\n',y1);
y=1 + exp(-x).*sin(4*x);
diary off;
but it stop and highlight error that y1 is apparently use before it is define.
fprintf('y=%s;\n',y1);
so if any 1 have some solution regarding this problem please help me out.

I would not abuse the diary command for this.
Why not just:
fid = fopen('f.m','w');
fprintf(fid,'function y=f(x)\n');
fprintf(fid,'y=%s;\n';
fclose(fid);

Related

Get name of code section in Matlab script

I have a script (actually a test script used for script based unit tests) which is divided into sections of the type
%% test foo
code
%% test bar
more code
How do I retrieve the name of a section (in any form, e.g. foo, test foo, TestFoo or whatever Matlab makes out of a section name) from inside my script (i.e. the place where I have written code).
Sorry, I have no Matlab on this computer. So the code is untested. But I guess with the code snippet below you should be able to do what you are trying.
It's a little bit hacky, but it's Matlab.
function section_name = get_current_section_name()
ds = dbstack();
execution_file = ds(2).file;
execution_line = ds(2).line;
fid = fopen(execution_file);
section_name = "";
current_line_number = 1;
tline = fgetl(fid);
while ischar(tline)
if startsWith(tline, "%%")
section_name = tline;
end
if execution_line == current_line_number
return
end
tline = fgetl(fid);
current_line = current_line + 1;
end
fclose(fid)
% case: not found
section_name = "";
end
And on your desired position you should be fine if you just call
section_name = get_current_section_name()
Here's a possible solution.
Given the following code:
%% test foo
code
%% test bar
more code
%% test baz
other code
You can obtain the comment of the active live script as follows:
>> X = matlab.desktop.editor.getActive; % Get MATLAB editor
>> editorText = X.Text; % Get editor text
>> n = X.Selection(1); % Get line number on which cursor is
>> all_lines = regexp(editorText,'\n','split'); % Get all lines of editor
>> for line = all_lines(n:-1:1) % Iterate backwards from starting lne
>> if contains(line,'%%') % If the line contains a comment, extract string and exit loop
>> match = regexp(line,'%% (.+)$','tokens','once')
>> break
>> end
>> end
match is a cell with the desired content. If your cursor is in the first code section, match{1} contains test foo. If the cursor is in the second block, test bar and finally test baz for the last block.
How it works:
First we get the active MATLAB editor and the position of the cursor. Then, we split on newline \n to obtain all of the lines in the editor. From the current line, we iterate backwards to identify the first line which has the comment, which contains the desired string.

Running Matlab script many times

So I have a matlab.m file script. When the file runs. It generates a vector. I want to save that vector and rerun the script all over again. How do I put a loop on the entire script file and create a vector_{i}, where the index enters the name of the file? I would post the code but it wont work without the data on my desktop.
[data,labels]=xlsread('C:\Users\Hilbert\Desktop\matlab\matlabdata_abe.xlsx');
gdp=log(data(:,1)./lagmatrix(data(:,1),1)) %GDP
ip=log(data(:,2)./lagmatrix(data(:,2),1)) %IP
tnx=data(:,3) %TNX
m2=log(data(:,4)./lagmatrix(data(:,4),1)) %M2
cpi=log(data(:,5)./lagmatrix(data(:,5),1)) %CPI
ffed=log(data(:,6)./lagmatrix(data(:,6),1)) %FedFund
Dgdp=gdp
inflation=cpi
Dm2=m2
ffr_=ffed
data=[Dgdp(54:length(cpi)), inflation(54:length(cpi)), Dm2(54:length(cpi)), ffr_(54:length(cpi)) ];
data_L1=lagmatrix(data,1)
data_L2=lagmatrix(data,2)
data_L3=lagmatrix(data,3)
data_L4=lagmatrix(data,4)
mat=[ones(1,size(data_L1',2));data_L1';data_L2';data_L3';data_L4']
mat=mat(:,5:end)
X=[data';data_L1';data_L2';data_L3']
X=X(:,5:end)
mat=mat';
X=X'
Fhat=(inv(mat'*mat) * mat'*X)';
nobs=size(data,1)
p=4
yhat= mat*Fhat'
yhat=yhat(:,1:4)
data_sample=data(5:nobs,:)
res=data_sample - yhat
res_{loopindexnumber}=res %saves the vector and re-runs the entire cost again the idea is to bootstrap the data by running many simulations and saving the residual vector
Make the script a function. And then execute the function in a loop how many times you want. For example:
function res = my_function(k)
% your script goes here.
% the function is saved in my_function.m file
% some calucations producing return_vector using k parmeter
res = return_vector
Later on, just run a for loop over the function and store the results to a cell array:
for k = 1:10
A{k} = my_function(k)
end
Make the script a function. And then execute the function in a loop how many times you want. For example:
function res = my_function(k)
% your script goes here.
% the function is saved in my_function.m file
% some calucations producing return_vector using k parmeter
res = return_vector
Later on, just run a for loop over the function.
for k = 1:10
assignin('base', ['A_', num2str(k)], my_function(k))
end

Matlab, textscan error

I get an error when I run a Matlab code (attached), that continuosly check and opens two .txt files at a given time interval, (2 seconds) and depending on the result a value comparison between those two files, chose one or another and use it....
Those two files are constantly saved and updated by a Java script at the same time interval of 2 seconds.
All the files are located in the same path.
The error I get is: "invalid file identifier. use fopen to generate a valid file identifier
Error in KinectDEMelevation_with_filecomparison2 (line 36)
DEM1 =
textscan(fid2,formatSpec,'HeaderLines',6,'Delimiter','\b'); "
The code is:
DEM = GRIDobj('kinectDEM0.txt');
clims = [-30 140];
imagesc(DEM,clims);
colormap(jet);
hold on
while(1)
tic
% clear all
% clf
% load('MyColormaps','mycmap');
%% Get kinectDEM0 data
% Open 'kinectDEM0.txt'
fid1 = fopen('kinectDEM0.txt', 'r+');
% Read data in from the .txt file
formatSpec = '%n';
DEM0 = textscan(fid1,formatSpec,'HeaderLines',6,'Delimiter','\b');
% Extract data from DEM0
DEM0Data = DEM0{1,1}(200:100:287800,1);
% Close 'kinectDEM0.txt'
fclose(fid1);
%% Get kinectDEM1 data
% Open 'kinectDEM1.txt'
fid2 = fopen('kinectDEM1.txt', 'r+');
% Read data in from the .txt file
formatSpec = '%n';
DEM1 = textscan(fid2,formatSpec,'HeaderLines',6,'Delimiter','\b');
% Extract data from DEM1
DEM1Data = DEM1{1,1}(200:100:287800,1);
% Close 'kinectDEM1.txt'
fclose(fid2);
%% Compare data, a logical array return 1 for true (points that has been changed), 0 for false
test = eq(DEM0Data,DEM1Data);
num = sum(test); % numbers of point in the scene that has been changed
threshold = 2900; % after this threshold update the image
if num > threshold
DEM = GRIDobj('kinectDEM1.txt');
clf
clims = [-30 140];
imagesc(DEM,clims);
colormap(jet);
hold on
end
T = toc;
pause(2 - T);
end
How can I fix it?
Thanks
You should add some error checking to make sure the file:
exists
has been successfully opened
For the first, you can use exist:
r = exist('kinectDEM0.txt','file');
% will return 2 if file exists
For the second, you need to check fid is valid. If fopen cannot open the file, this will be -1. You may also use the second output for fopen, errmsg, for additional checking; errmsg should be an empty string if the file was opened successfully, otherwise it will return the system error message, such as "No such file or directory".
A simple example:
fid = -1
while fid == -1
fid = fopen('myfile.txt'); % attempt to open until success
end

plot automatically titled with plot object in matlab

I would like to know if some of you know of a way to automatically title plots with the name of the object plotted
so that for intance when I plot supermatrix(5:10,:,2:3)
the title (or the legend ..) on the plot says "supermatrix(5:10,:,2:3)"
thanks
Is this for debugging purposes? If not then I suggest you tell us your overall motivation because someone might be able to suggest a more robust method, but this might get you started:
vname = #(x)inputname(1); %//from here: https://www.mathworks.com/matlabcentral/newsreader/view_thread/251347
plot(supermatrix(5:10,:,2:3))
title(vname(supermatrix))
Although to be honest I cannot imagine why this would ever be useful
I think this does what you want and remains pretty flexible:
function h = plotwithtitle( plotstring, varargin )
argstoplot = evalin('caller', ['{', plotstring, '}']);
h = plot( argstoplot{:}, varargin{:} );
title(plotstring);
end
The following examples all work for me:
supermatrix=rand(10,10);
x=1:10;
y=rand(1,10);
plotwithtitle('supermatrix');
plotwithtitle('supermatrix(5:10,:)');
plotwithtitle('x, y');
plotwithtitle('x, y', '--r');
plotwithtitle('1:10', 'r');
plotwithtitle('rand(1,10)');
I've modified the function dfig originally created by F.Moisy for creating docked figures in order to have the command used for plotting show up in the figure name.
The idea is to read the last command in the command history and use that to generate the figure title.
function hh = dfig(varargin)
%DFIG Create docked figure window
% DFIG, by itself, creates a new docked figure window, and returns its
% handle.
%
% DFIG(H) makes H the current figure and docks it. If Figure H does not
% exist, and H is an integer, a new figure is created with handle H.
%
% DFIG(H, name, value,...) reads additional name-value pairs. See
% doc(figure) for available otions.
%
% DFIG will parse the command line input and use the text following dfig
% as figure name. E.g. calling dfig,plot(x(1:3),y(2:2:end)) results in
% the name "plot(x(1:3),y(2:2:end))"
% F. Moisy, moisy_at_fast.u-psud.fr
% Revision: 1.00, Date: 2007/09/11
% Modified (a lot) by Jonas
if nargin==0
h=figure; % create a new figure
else
% call figure with varargin
figure(varargin{:})
h = gcf;
end
if ~any(strcmp('name',varargin(1:2:end)))
% if no name has been supplied: try to use function call
javaHistory=com.mathworks.mlservices.MLCommandHistoryServices.getSessionHistory;
if ~isempty(javaHistory)
lastCommand = javaHistory(end).toCharArray';
funCall = regexp(lastCommand,'dfig\s*[,;]\s*(.*)$','tokens','once');
else
funCall = [];
end
if ~isempty(funCall)
if isnumeric(h)
set(h,'Name',[num2str(h),': ',funCall{1}],'NumberTitle','off')
else % HG2
h.Name = sprintf('%i: %s',h.Number,funCall{1});
h.NumberTitle = 'off';
end
end
end
set(h,'WindowStyle','docked'); % dock the figure
if nargout~=0 % returns the handle if requested
hh=h;
end

Saving GUI data from matlab in a 3D matrix

I'd like to save matrices which are input via GUI pushbuttons in a 3D matrix. for example: I click button 1 a 2-2 matrix is put in the first slice of the 3D matrix. I than click button 3 and a different 2-2 matrix is put in the second slice. SO on and so on. I hope this is clear enough. The problem I have is that I'm not an experienced programmer. I currently initialize a zeros matrix as follows in the opening func:
storageMatrix = ones(2,2,100);
setappdata(0, 'storageMatrix', storageMatrix);
I have put a function updateStorageMatrix in the main script like this, mind you this isn't finished yet.
function updateStorageMatrix
storageMatrix = getappdata(0, 'storageMatrix');
and than when I look at my code of pushbutton 1 for example it looks like this:
% --- Executes on button press in Add_Straightduct.
function Add_Straightduct_Callback(hObject, eventdata, handles)
%prompt command for k number and length
prompt = {'k0:','Length:'};
dlg_title = 'Straight Duct specs';
num_lines = 1;
SDelements = {'0','0'};
Straightduct = inputdlg(prompt,dlg_title,num_lines,SDelements)
%insert values in function
sizeStorageMatrix = size(getappdata(0,'storageMatrix')); %get size of the storage matrix
dimT = sizeStorageMatrix(1,3); %take the number of matrices
if dimT==1
straightDuct = straight_duct(str2num(SDelements{1}), str2num(SDelements{2}), Mach_Frange(1,1))
setappdata(handles.updateStorageMatrix,'storageMatrix', storageMatrix(1:2, 1:2, 1))=straight_duct(str2num(SDelements{1}), str2num(answer{2}), Mach_Frange(1,1))
dimT+1
else
setappdata(0,'storageMatrix', storageMatrix(1:2, 1:2, dimT+1))=straight_duct(str2num(SDelements{1}), str2num(answer{2}), Mach_Frange(1,1))
dimT+1
end
the straight_duct() is a function I used in the script when calculating the mufflers, I have several of those functions, I am not sure if that's the way to work when using GUI. I just hope you get the idea of what I'm trying to achieve and help me on my way. So I can actually make a UI for my script :)
This assumes you've initialized the storageMatrix elsewhere in the GUI like this...
handles.storageMatrix = zeros(2,2,100);
guidata(hObject,handles); % Must call this to save handles so other callbacks can access the new element "storageMatrix"
Then in your first button's callback...
% --- Executes on button press in Add_Straightduct.
function Add_Straightduct_Callback(hObject, eventdata, handles)
.
. % Whatever initializations you need to do
.
localStorageMatrix = handles.storageMatrix; %load the storageMatrix being used by other callbacks/functions
.
. % Whatever you need to do to generate the new 2x2 matrix "slice"
.
localStorageMatrix(:,:,end+1) = newSlice; % appends the new slice to the end of the, indexing using colons assumes newSlice is of the same first and second dimension as other slices in localStorageMatrix
handles.storageMatrix = localStorageMatrix; % overwrite the storageMatrix in handles with the contents of the new localStorageMatrix
guidata(hObject,handles); % save the handles struct again now that you've changed it
Alternatively, you could have just used the handles.storageMatrix throughout, without including a localStorageMatrix but I've included it for emphasis.