I'm writing a script in MATLAB that displays Before and After images of a given original image and an image gone through the logarithm operator point transformation. I've tried debugging the program to see what's wrong with it, but for some reason, it isn't running in MATLAB. I keep getting the error on the command line (logarithm-operator is the name of the script):
Here is the script:
a = imread('cells.png');
ad = im2double(a);
x = ad;
[r, c] = size(ad);
factor = 1;
for i = 1:r
for j = 1:c
x(i, j) = factor *log(1+ ad(i,j));
end
end
subplot(1,2,1);imshow(ad);title('Before');
subplot(1,2,2);imshow(x);title('After');
Matlab script or function names cannot contain a hyphen; only letters, numbers, or underscores are allowed, and must begin with a letter. The hyphen in your script's name confuses Matlab and leads it into thinking that logarithm is the name of the function/script it's supposed to be calling.
These are the same requirements as those for variable names. You can have a look at the documentation for isvarname:
A valid variable name is a character string of letters, digits, and
underscores, totaling not more than namelengthmax characters and
beginning with a letter.
You have to change the name of your script from logarithm-operator to logarithm_operator. Because the names of variables, scripts, functions, etc in matlab does not contain the symbol : hyphen -.
Related
I have three m files using the same variables and carrying out calculations on these variables. I have made an index m file in which i have declared all the variables and I can share the variables to the remaining m files using the variable names. My problem is that the variable names change too often and then I have to change the variable names in all these files manually. How can I make a Matlab script which can automatically get the variable names and value from the index m file and put these to the remaining m files.
I feel like you just need a little example from where you could go on so here we go:
First calling each value with a different variable name. if you have a lot of values of the same type a array is easier like:
A0=0; A1=6; A2=12 %each one with its own name
B=zeros(16,1); %create an array of 16 numbers
B(1)= 0; %1 is the first element of an array so care for A0
B(2)= 6;
B(8)= 12;
disp(B); % a lot of numbers and you can each address individually
disp(B(8)); %-> 12
you can put all that in your script and try it. Now to the function part. Your function can have input, output, neither or both. If you just want to create data you wont need an input but an output.
save this as myfile1.m:
function output = myfile1()
number=[3;5;6]; %same as number(1)=3;number(2)=5;number(3)=6
%all the names just stay in this function and the variable name is chosen in the script
output = number; %output is what the file will be
end
and this as myfile2.m
function output = myfile2(input)
input=input*2;%double all the numbers
%This will make an error if "input" is not an array with at least 3
%elements
input(3)=input(3)+2; %only input(3) + 2;
output = input;
end
and now try
B=myfile1() %B will become the output of myfile1
C=myfile2(B) %B is the input of myfile2 and C will become the output
save('exp.mat','C')
I hope this will get you started.
Considering the following code
x = input('Input an array: ');
If the user types [1 2 3], variable x will be assigned that numeric vector. Similarly, if they type {1, [2 3], 'abc'}, variable x will be a cell array containing those values. Fine.
Now, if the user types [sqrt(2) sin(pi/3)], variable x will be assigned the resulting values: [1.414213562373095 0.866025403784439]. That's because the provided data is evaluated by input:
input Prompt for user input.
result = input(prompt) displays the prompt string on the screen, waits
for input from the keyboard, evaluates any expressions in the input,
and returns the value in result. [...]
This can cause problems. For example, what happens if the user types addpath('c:\path\to\folder') as input? Since the input is evaluated, it's actually a
command which will be executed by Matlab. So the user can get to add a folder to the path. Worse yet, if they input path(''), the path will be effectively changed to nothing, and Matlab will stop working properly.
Another potential source of problems is that
[...] To evaluate expressions, input accesses variables in the current workspace.
For example, if the user inputs fprintf(1,'%f', varname) and varname is an existing numeric array, the user will know its current value.
This behaviour is probably by design. Users of a Matlab program are trusted when inputting data, much like they are trusted not to press Control-C to halt the program (and then issue all commands or inspect all variables they like!).
But in certain cases the programmer may want to have a more "secure" input function, by which I mean
prevent any function calls when evaluating user
input; and
prevent the input from accessing variables of the program.
So [1 2] would be valid input, but [sqrt(2) sin(pi/3)] or path('') would not because of item 1; and [1 2 3 varname(1)] would be invalid too because of item 2.
I have found a not very satisfactory solution (and I'd love to read about a better one). It uses a semi-documented function and implies saving the user input to a temporary file. The function, referred to in Yair Altman's blog, is getcallinfo. According to help getcallinfo:
getcallinfo
Returns called functions and their first and last lines
This function is unsupported and might change or be removed without
notice in a future version.
This function solves issue 1 (prevent function calls). As for issue 2 (prevent access to variables), it would suffice to evaluate the input within a function, so that it can't see other variables. Apparently (see example 2 below), getcallinfo detects not only called functions, but variables too. Anyway, it's probably a good idea to do the evaluation in the isolated scope of a function.
The procedure is then:
Use the string version of input to prevent evaluation:
x = input('Input an array: ', 's');
Save the string to a file:
filename = 'tmp.m';
fid = fopen(filename,'w');
fprintf(fid, '%s',x);
fclose(fid);
Check the input string with getcallinfo to detect possible function calls:
gci = getcallinfo(filename);
if ~isempty(gci.calls.fcnCalls.names)
%// Input includes function calls: ignore / ask again / ...
else
x = evalinput(x); %// evaluate input in a function
end
where evalinput is the following function
function x = evalinput(x)
x = eval(x);
Example 1
Consider
x = input('Input an array: ', 's');
with user input
[sqrt(2) sin(pi/3)]
Then
filename = 'tmp.m';
fid = fopen(filename,'w');
fprintf(fid, '%s',x);
fclose(fid);
gci = getcallinfo(filename);
produces a non-empty gci.calls.fcnCalls.names,
>> gci.calls.fcnCalls.names
ans =
'sqrt' 'sin' 'pi'
which tells us that the user input would call functions sqrt, sin and pi if evaluated. Note that operators such as / are not detected as functions.
Example 2
y = [10 20 30];
x = input('Input an array: ', 's');
User enters
[1 y y.^2]
Then
filename = 'tmp.m';
fid = fopen(filename,'w');
fprintf(fid, '%s',x);
fclose(fid);
gci = getcallinfo(filename);
produces
>> gci.calls.fcnCalls.names
ans =
'y' 'y'
So variables are detected by getcallinfo as if they were functions.
If I understand your question correctly, it is possible to use regular expressions to accomplish what you are trying to do.
No function or variable calls
At its simplest, this checks to making sure there are no alphabetical characters in the input string. The expression would then be, for x containing input:
expr = '[a-zA-Z]';
x = input('Input an array: ', 's');
valid = isempty(regexp(x,expr));
This alone works for the few examples you give above.
Allowing some functions or variables
Suppose you want to allow the user to access some variables or functions, maybe simple trig functions, or pi or what have you, then it's no longer so simple. I've been playing around with an expression like below:
expr = '(?!cos\(|pi|sin\()[a-zA-Z]+
But it doesn't quite do what is expected. It will match in( in sin. If you know regex better than I, you can massage that to work properly.
Otherwise, an alternative would be to do this:
isempty(regexp(regexprep(x,'(sin\(|cos\(|pi|x)',''),expr))
so that you remove the strings you are interested in.
Hope this helps.
Update: In order to allow imaginary/exp values, and paths
The new expression to match becomes
expr = '[iIeE][a-zA-Z]+';
This ignores i/I and e/E (you can augment this as you see fit). You can also do a two character limit by switching to \{2,}, though I people can still have one character anonymous functions..
The other part, to check for input becomes:
isempty(regexp(regexprep(x,'(sin\(|cos\(|pi|x|''(.*?)'')',''),expr))
now you can exclude custom functions (you can always have this as an array and join them together by a |) and paths.
Here are a few examples tested along with the usual:
Passes
'[1+2i, 34e12]'
'''this is a path'''
'[cos(5), sin(3+2i)]'
Fails
'[1+2ii, 34e12]'
'this is not a path'
'''this is a path'' this is not'
kinda new to matlab here, searching the csvwrite tutorial and some of the existing webportals regarding my question couldn't find a way to pass my variables by value to the output file names while exporting in csv; providing my bellow scripts, i would like to have the output files something like output_$aa_$dd.csv which aa and dd are respectively the first and second for counters of the scripts.
for aa=1:27
for dd=1:5
M_Normal=bench(aa,dd).Y;
for j=1:300
randRand=M_Normal(randperm(12000,12000));
for jj = 1:numel(randMin(:,1)); % loops over the rand numbers
vv= randMin(jj,1); % gets the value
randMin(jj,j+1)=min(randRand(1:vv)); % get and store the min of the selction in the matix
end
end
csvwrite('/home/amir/amir_matlab/sprintf(''%d%d',aa, bb).csv',randMin);
end
end
String concatenation in MATLAB is done like a matrix concatenation. For example
a='app';
b='le';
c=[a,b] % returns 'apple'
Hence, in your problem, the full path can be formed this way.
['/home/amir/amir_matlab/',sprintf('%d_%d',aa,bb),'.csv']
Furthermore, it is usually best not to specify the file separator explicitly, so that your code can be implemented in other operating systems. I suggest you write the full path as
fullfile('home','amir','amir_matlab',sprintf('%d_%d.csv',aa,bb))
Cheers.
I have 11x11 matrices and I saved them as .mat files from F01_01 to F11_11.
I have to run a function Func on each file. Since it takes a long time, I want to write a script to run the function automatically:
for i=01:11
for j=01:11
filename=['F',num2str(i), '_', num2str(j),'.mat'];
load(filename);
Func(Fi_j); % run the function for each file Fi_j
end
end
But it doesn't work, Matlab cannot find the mat-files.
Could somebody please help ?
The problem
i=01;
j=01;
['F',num2str(i), '_', num2str(j),'.mat']
evaluates to
F1_1.mat
and not to
F01_01.mat
as expected.
The reason for this is that i=01 is a double type assignment and i equals to 1 - there are no leading zeros for these types of variables.
A solution
a possible solution for the problem would be
for ii = 1:11
for jj= 1:11
filename = sprintf('F_%02d_%02d.mat', ii, jj );
load(filename);
Func(Fi_j); % run the function for each file Fi_j
end
end
Several comments:
Note the use of sprintf to format the double ii and jj with leading zero using %02d.
You can use the second argument of num2str to format its output, e.g.: num2str(ii,'%02d').
It is a good practice to use string formatting tools when dealing with strings.
It is a better practice in matlab not to use i and j as loop counters, since their default value in matlab is sqrt(-1).
Here is an alternate solution, note that the solution by #Shai is more easily expanded to multiple digits but this one requires less understanding of string formatting.
for i=1:11
for j=1:11
filename=['F',num2str(floor(i/10)),num2str(mod(i,10)) '_', num2str(floor(j/10)),num2str(mod(j,10)),'.mat'];
load(filename);
Func(Fi_j); % run the function for each file Fi_j
end
end
The num2str can do zeropadding to fill the field. In the example below 4 is the desired field width+1.
num2str(1,'% 04.f')
Ans = 001
Is it possible using Greek alphabet to represent variables in MATLAB?
For example, I'd like to use the Greek character epsilon as a variable in MATLAB. I tried to insert \epsilon but I received an error.
It is not possible.
I refer to the following part of Matlab documentation:
Valid Names
A valid variable name starts with a letter, followed by letters,
digits, or underscores. MATLAB is case sensitive, so A and a are not
the same variable. The maximum length of a variable name is the value
that the namelengthmax command returns.
Letter is defined as ANSI character between a-z and A-Z.
For example, the following hebrew letter Aleph returns false (in Matlab R2018a returns true):
isletter('א')
By the way, you can always check whether your variable name is fine by using genvarname.
genvarname('א')
ans =
x0x1A
While Andrey's answer is true for variable names it's a different story for figures.
title('\epsilon\omega') will actually work and generate an epsilon and an omega as title (although the matlab font replaces them with different symbols). If you export the figure as an eps or pdf file you will see that the title really is epsilon omega. Actually any LaTeX control sequence will work!
Same is true for all the figure text objects such as legends and axis labels.