Any trim functions in matlab? - matlab

If I have an input like [1 2 3; 4.0 c] and I want it to output it like 1234.0c in matlab. What function can I use ? I am looking for something like trim in php.
Any idea ?
Thanks

You can use this to remove any number of spaces from inside of a string:
>> a = char(' he llo wor ld ');
>> a(isspace(a)) = [] %replaces all of the space with nothing
a =
helloworld

You can use isstrprop function with approppriate categories. For your case,
>> str = '1 2 3; 4.0 c';
>> str(isstrprop(str, 'alphanum') | str == '.')
ans =
1234.0c
You can use functions like isletter, isnumeric, etc. if you like.
Besides, you can create your own function in one line as follows
>> myTrim = #(x)(x(isstrprop(x, 'alphanum') | x == '.'));
>> myTrim(str)
ans =
1234.0c
Note that you ask [1 2 3; 4.0 c] as an input which is not a proper syntax for MATLAB. I assumed you wanted to ask for a string. In addition, trim actually implies removing leading and trailing white space from a string and there is strtrim for this in MATLAB.

It is not a valid MATLAB argument.
But if you have something like
a = ['1', '2' ,'3'; '4', '.','c'];
you can use
a(:)'
to get
142.3c
or
a = a';
a(:)'
to get
123.4c

Related

Is there an Octave equivalent of Matlab's `contains` function?

Is there an equivalent of MATLAB's contains function in Octave? Or, is there a simpler solution than writing my own function in Octave to replicate this functionality? I am in the process of switching to Octave from MATLAB and I use contains throughout my MATLAB scripts.
Let's stick to the example from the documentation on contains: In Octave, there are no (double-quoted) strings as introduced in MATLAB R2017a. So, we need to switch to plain, old (single-quoted) char arrays. In the see also section, we get a link to strfind. We'll use this function, which is also implemented in Octave to create an anonymous function mimicking the behaviour of contains. Also, we will need cellfun, which is available in Octave, too. Please see the following code snippet:
% Example adapted from https://www.mathworks.com/help/matlab/ref/contains.html
% Names; char arrays ("strings") in cell array
str = {'Mary Ann Jones', 'Paul Jay Burns', 'John Paul Smith'}
% Search pattern; char array ("string")
pattern = 'Paul';
% Anonymous function mimicking contains
contains = #(str, pattern) ~cellfun('isempty', strfind(str, pattern));
% contains = #(str, pattern) ~cellfun(#isempty, strfind(str, pattern));
TF = contains(str, pattern)
The output is as follows:
str =
{
[1,1] = Mary Ann Jones
[1,2] = Paul Jay Burns
[1,3] = John Paul Smith
}
TF =
0 1 1
That should resemble the output of MATLAB's contains.
So, in the end - yes, you need to replicate the functionality by yourself, since strfind is no exact replacement.
Hope that helps!
EDIT: Use 'isempty' instead of #isempty in the cellfun call to get a faster in-built implementation (see carandraug's comment below).
I'm not too familiar with MuPad functions, but it looks like this is reinventing the ismember function (which exists in both Matlab and Octave).
E.g.
ismember( {'jim', 'stan'}, {'greta', 'george', 'jim', 'jenny'} )
% ans = 1 0
i.e. 'jim' is a member of {'greta', 'george', 'jim', 'jenny'}, whereas 'stan' is not.
Furthermore, ismember also supports finding the index of the matched element:
[BoolVal, Idx] = ismember( {'jim', 'stan'}, {'greta', 'george', 'jim', 'jenny'} )
% BoolVal = 1 0
% Idx = 3 0
Personally I use my own implementation, which returns 1 if a string str contains entire substring sub:
function res = containsStr(str, sub)
res = 0;
strCharsCount = length(str);
subCharsCount = length(sub);
startCharSub = sub(1);
% loop over character of main straing
for ic = 1:strCharsCount
currentChar = str(ic);
% if a substring starts from current character
if (currentChar == startCharSub)
%fprintf('Match! %s = %s\n', currentChar, startCharSub);
matchedCharsCount = 1;
% loop over characters of substring
for ics = 2:subCharsCount
nextCharIndex = ic + (ics - 1);
% if there's enough chars in the main string
if (nextCharIndex <= strCharsCount)
nextChar = str(nextCharIndex);
nextCharSub = sub(ics);
if (nextChar == nextCharSub)
matchedCharsCount = matchedCharsCount + 1;
end
end
end
%fprintf('Matched chars = %d / %d\n', matchedCharsCount, subCharsCount);
% the substring is inside the main one
if (matchedCharsCount == subCharsCount)
res = 1;
end
end
end
end

Matlab vector Printing

How do i print a vector in matlab with also something before the values. For example i have a vector with the following values A' = [1 2 3]. I want to print it out in such a way that the output will be
w0 = 1
w1 = 2
w2 = 3
How do i do this?
Can i do this using a loop?
I am using the following code and i am not getting the right output
for qux = 1:3
fprintf('w%i=%.4lf\n',qux-1,answ);
end
Output:
w0=w1=w2
Your format string is not formed properly. Specifically '%.4lf' should be '%.4f'. Additionally, the third input to fprintf should be A(qux) to access the value in A.
for qux = 1:3
fprintf('w%i=%.4f\n', qux-1, A(qux));
end
I would, however, recommend using '%g' to use a format that optimizes the display of each number. Additionally, you could remove the for loop and do something like
A = [1, 2, 3];
fprintf('w%i = %g\n', [0:numel(A)-1; A])
If I have understand the question correctly, I think that you could do that with the following code:
for i = 1:3
disp(['w' num2str(A(i)-1) '=' num2str(A(i))]);
end
Using disp and num2str you could get the following output:
w0=1
w1=2
w2=3

How to output matrix dimensions together with its content?

Is it possible to make GNU Octave to output matrix dimensions together with its content? For example, it should produce smth. like this:
octave:1> X = [1 2; 3 4]
X [2x2] =
1 2
3 4
octave:2> X(1,:)
ans [1x2] =
1 2
In MATLAB, create display.m in a folder called #double somewhere in your path with this content:
function display(v)
name = inputname(1);
if isempty(name)
name = 'ans';
end
s = num2cell(size(v));
fprintf('\n%s [%d%s] =\n\n', name, s{1}, sprintf('x%d', s{2:end}));
builtin('disp', v);
end
This way you override the display method for class double, and get exactly what you have described. However, this will not work for other classes like int8, logical or cell. You have to override the method for all classes you are interested in. Example:
>> A=ones(2,2,2)
A [2x2x2] =
(:,:,1) =
1 1
1 1
(:,:,2) =
1 1
1 1
While Mohsen's answer does the job indeed, I felt that a separate m-file is somewhat an overkill for this purpose (especially if you don't want to clutter your directory with additional m-files). I suggest using a local anonymous function one-liner instead (let's name it dispf), so here are its evolution phases :)
The basic anonymous function I came up with is:
dispf = #(x)fprintf('%s =\n\n%s\n', inputname(1), disp(x));
which is essentially equivalent to the output in the command window after entering statements (that do not end with a semicolon, of course). Well, almost... because if inputname returns an empty string, it doesn't print 'ans' (and it should). But this can be corrected:
dispf = #(x)fprintf('%s=\n\n%s\n', ...
regexprep([inputname(1), ' '], '^ $', 'ans '), ...
disp(x));
This is basically using regexprep to match an empty string and replace it with 'ans'. Finally, we append the dimensions after the variable name:
dispf = #(x)fprintf('%s%s =\n\n%s\n', ...
regexprep([inputname(1), ' '], '^ $', 'ans '), ...
strrep(mat2str(size(x)), ' ', 'x'), ...
disp(x));
Now you can plug this one-liner is into any script without the need for an additional m-file!
Example
Just a proof that it's working:
dispf = #(x)fprintf('%s%s =\n\n%s\n', ...
regexprep([inputname(1), ' '], '^ $', 'ans '), ...
strrep(mat2str(size(x)), ' ', 'x'), ...
disp(x));
A = [1 2; 3 4];
dispf(A)
dispf(A(1, :))
The result is as expected:
A [2x2] =
1 2
3 4
ans [1x2] =
1 2
I don't know if it works in Octave, but in MATLAB you can use format debug command and get the dimensions of the array and a bit more:
>> format debug
>> X = [1 2; 3 4]
X =
Structure address = 7d19498
m = 2
n = 2
pr = 373bafa0
pi = 0
1 2
3 4
Here is another way to do it. The advantage of this method is that it can deal with more complicated inputs than the mentioned alternatives.
function show(s)
t = regexp(s,'=');
if any(t)
evalin('caller',['disp(size(' s(t+1:end) ')),' s])
else
evalin('caller',['disp(size(' s ')),' s])
end
To use it, save the function and try this:
show x = rand(3)
show('y = {uint8(8);[6 7 8]}')
Note that it can take the convenient command syntax for simple inputs and that you need the function form with the command in string form for complicated inputs (containing semicolons or apostrophes).
Here is another one. You could either use it to overload #double/display as others have explained, or name it something else and use it as your own custom display function:
function display(x)
% determine whether format is loose or compect
loose = strcmp(get(0,'FormatSpacing'), 'loose');
% print name or ans
name = inputname(1);
if isempty(name), name = 'ans'; end
if loose, disp(' '); end
disp([name ' =']);
if loose, disp(' '); end
% print size
sz = size(x);
if length(sz) == 2
fprintf(' %s: %d-by-%d\n', class(x), sz(1), sz(2));
elseif length(sz) == 3
fprintf(' %s: %d-by-%d-by-%d\n', class(x), sz(1), sz(2), sz(3));
else
fprintf(' %s: %d-D\n', class(x), numel(sz));
end
if loose, disp(' '); end
% print array
disp(x);
end
Note that I changed the format of the output a little bit from what you had:
>> format compact;
>> x = magic(5);
>> display(x)
x =
double: 5-by-5
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

matlab: converting a vector to a cell array of strings

I'm sure there's a way to do this but I don't know what it is.
Suppose I have a vector
v = [1.02 2.03 3.04];
and I want to convert this to a cell array using a format string for each element:
' %.3f'
(3 spaces before the %.3f)
How can I do this? I tried the following approach, but I get an error:
>> f1 = #(x) sprintf(' %.3f',x);
>> cellfun(f1, num2cell(v))
??? Error using ==> cellfun
Non-scalar in Uniform output, at index 1, output 1.
Set 'UniformOutput' to false.
As stated in the error, just provide the parameter of UniformOutput as false
cellfun(f1, num2cell(v), 'UniformOutput', false)
ans =
' 1.020' ' 2.030' ' 3.040'
Here is another solution:
>> v = [1.02 2.03 3.04];
>> strcat({' '}, num2str(v(:),'%.3f'))
ans =
' 1.020'
' 2.030'
' 3.040'
Obviously you can transpose the result if you want a row vector.
You can also use the {} syntax:
cellfun(#(x){f1(x)}, num2cell(v))
Also check out : Applying a function on array that returns outputs with different size in a vectorized manner

Matlab sprintf formatting

EDIT: I've reworded the question to be clearer.
Does anyone know a clever way to get sprintf to print "%.6f with trailing zeros elminated"? This is what I'm looking for:
sprintf('%somemagic ', [12345678 123.45])
ans = 1234578 123.45
where %somemagic is some magical specifier. None of the formats seem to work.
% no trailing zeros, but scientific for big nums
sprintf('%g ', [12345678 123.45])
ans = 1.23457e+007 123.45
% not approp for floats
sprintf('%d ', [12345678 123.45])
ans = 12345678 1.234500e+002
% trailing zeros
sprintf('%f ', [12345678 123.45])
ans = 12345678.000000 123.450000
% cannot specify sig figs after decimal (combo of gnovice's approaches)
mat = [12345678 123.45 123.456789012345];
for j = 1:length(mat)
fprintf('%s ', strrep(num2str(mat(j),20), ' ', ''));
end
I don't think there is a way to do it other than looping through each element and changing the specifier based off of mod(x,1)==0 or using regexp to remove trailing zeros. But you never know, the crowd is more clever than I.
My actual application is to print out the array elements in an html table. This is my current clunky solution:
for j = 1:length(mat)
if mod(mat(j),1) == 0
fprintf('<td>%d</td>', mat(j));
else
fprintf('<td>%g</td>', mat(j));
end
end
EDIT: Updated to address the edited question...
I don't think there's any way to do it with a particular format string for SPRINTF, but you could instead try this non-loop approach using the functions NUM2STR and REGEXPREP:
>> mat = [12345678 123.45 123.456789012345]; %# Sample data
>> str = num2str(mat,'<td>%.6f</td>'); %# Create the string
>> str = regexprep(str,{'\.?0+<','\s'},{'<',''}); %# Remove trailing zeroes
%# and whitespace
>> fprintf(str); %# Output the string
<td>12345678</td><td>123.45</td><td>123.456789</td> %# Output
The problem is that you're mixing an int with a float in an array. Matlab doesn't like that so it will convert your int to a float so that all elements in the array are of the same type. Look at doc sprintf: you're now forced to use %f, %e or %g on floats
Although I admit I like the STRREP method above (or below)