How to create numeric array from a string in MATLAB? - arrays

How to create numeric array from a string in Matlab?
For example I have such a string:
>> str = dec2bin(7);
s = 111
I need the array [1 1 1]. How to do it?
I see strread function strread
but I get difficulties to use it with non-space string input.

The standard solution is to use the solution posted by yuk,
a = (str == '1');
which produces a logical result. If you need a double,
a = double(str == '1');
or even just:
a = +(str == '1');
Perhaps the simplest looking solution is this one:
a = str - 48;
although I think the last is least obvious as to what it does. I prefer code that is easy to read and understand the purpose. That goal is best met by the second solution, IMHO.

Just answered another question and found a part of it might be useful here.
You can actually convert such a string to a logical vector:
a = str == '1';
You can cast it to another type, for example double(a).

I suppose, naively:
n = length(s);
myArray = zeros(1,n)
for i = 1:n
myArray(i) = double(s(i));
where "double()" is whatever the command is for changing a string element to a double precision number, if that is indeed what you want.

With strread:
a = strread('123', '%c')

The answer is using "bitget"
> x = bitget(7,1:3);
> class(bitget(7,1:3))
ans =
double
The result is double.

Related

Recursive unitless element type

I am trying to come up with a function that gives me the recursive unitless element type. So for example, to shorten it let's call it ruet, I would like to have:
A = zeros(5,5)
reut(A) == Float64
using Unitful
A = zeros(5,5)*1u"kg"
reut(A) == Float64
AA = [zeros(5,5) for i in 1:5]
reut(AA) == Array{Float64,2}
AofA = [copy(A) for i in 1:5]
reut(AofA) == Array{Float64,2}
using StaticArrays
AofSA = [#SVector [2.0,3.0] for i in 1:5]
reut(AofSA) == SVector{2,Float64}
AofuSA = [#SVector [2.0u"kg",3.0u"kg"] for i in 1:5]
reut(AofuSA) == SVector{2,Float64}
So basically strip away the units but still return the correct element type, which could be an array. It's the array part that's hard. I can recurse:
recursive_eltype(a) = recursive_eltype(eltype(a))
recursive_eltype{T<:Number}(a::Type{T}) = eltype(a)
and then get the unitless element type:
uEltype = recursive_eltype(u)
uEltypeNoUnits = typeof(one(uEltype))
but then this is always the number type, and I can't seem to find a good way to get back the array types when it's an array of arrays, i.e. this method is returning Float64 in all of the examples above. I am wondering if dispatching on static arrays and using similar_type is required here.
Note that I would like the solution to, if possible, not have a requirement on Unitful.jl. Getting the unitless type for the number can be done via one(u), so I think this should be possible.
(Somewhat related Julia issue: https://github.com/JuliaLang/julia/issues/22216)
I came up with:
Base.#pure recursive_unitless_eltype(a) = recursive_unitless_eltype(eltype(a))
Base.#pure recursive_unitless_eltype{T<:StaticArray}(a::Type{T}) = similar_type(a,recursive_unitless_eltype(eltype(a)))
Base.#pure recursive_unitless_eltype{T<:Array}(a::Type{T}) = Array{recursive_unitless_eltype(eltype(a)),ndims(a)}
Base.#pure recursive_unitless_eltype{T<:Number}(a::Type{T}) = typeof(one(eltype(a)))
This still isn't fully generic, but works on quite a broad range of things.
Using Julia version 0.6.2-something (code surely not very portable):
function _reut(T)
try
T.name == Quantity.body.body.body.name && return _reut(T.parameters[1])
getfield(T.name.module, T.name.name){_reut.(collect(T.parameters))...}
catch
T
end
end
reut(T) = _reut(eltype(T))
And the tests in the question pass. Still not inferrable, but replaced eval with getfield(Module,Symbol). Where do you get these questions?

MATLAB - Equivalent logical indexing leading to two different results

I'm writing a piece of code for submission through an online grader, as showcased below. B is some given array filled any/all integers 1 through K, and I want to extract the corresponding logical indices of matrix X and perform some operations on those elements, to be put into a return array:
for i = 1:K
A = X(B == i, :);
returnArr(i, :) = sum(A) / length(A);
end
This did not pass the grader at all, and so I looked to change my approach, instead indexing array X indirectly via first using the "find" function, as below:
for i = 1:K
C = find(B == i);
returnArr(i,:) = sum(X(C,:)) / length(C);
end
To my surprise, this code passed the grader without any issues. I know there are a plethora of variations between graders, and one might handle a particular function differently than another, but from a MATLAB functionality/coding perspective, what am I missing in terms of discrepancies between the two approaches? Thanks!
I think the problem is that:
length(C) == sum(B == i)
while
length(A) == max([sum(B == i) , size(X , 2)])
In other words, to obtain the same result of the second example with the first one, you should modify it like this:
A = X(B == i , :);
returnArr(i, :) = sum(A) / size(A,1);
The function length returns the length of largest array dimension

how to check in matlab if a 3D array has at least one non zero element?

I tried to check if a 3D array is not all zeros using the next code:
notAll_n0_GreaterThan_ni=1;
while notAll_n0_GreaterThan_ni
notAll_n0_GreaterThan_ni=0;
mask=(n0<ni);
numDimensions=ndims(mask);
for dim_ind=1:numDimensions
if any(mask,dim_ind)
notAll_n0_GreaterThan_ni=1;
break;
end
end
if notAll_n0_GreaterThan_ni
n0(mask)=n0(mask)+1;
end
end
It seems I have error in the code because at the end I get for example: n_0(11,3,69)=21 while ni(11,3,69)=21.1556.
I can't find the error. I'll appreciate if someone shows me where I'm wrong and also if there is a simpler way to check existence of nonzero elements in a 3D array.
Let x denote an n-dimensional array. To check if it contains at least one non-zero element, just use
any(x(:))
For example:
>> x = zeros(2,3,4);
>> any(x(:))
ans =
0
>> x(1,2,2) = 5;
>> any(x(:))
ans =
1
Other, more exotic possibilities include:
sum(abs(x(:)))>0
and
nnz(x)>0
This is what you looking for
B = any(your_Array_name_here(:) ==0); no need for loops
the (:) turns the elements of your_Array into a single column vector, so you can use this type of statement on an array of any size
I 've tested this and it works
A = rand(3,7,5) * 5;
B = any(A(:) ==0);

Access structure array whose index is stored in a string

I want to get a value from a structure array by code, and I'll have the index stored in a string.
I've tried to run this code:
function M = getdata(matrix,field,varargin)
exp = [];
for i = 1:nargin-3
exp = [exp num2str(varargin{i}) ','];
end
exp = [exp num2str(varargin{nargin-2})];
M = eval('matrix(exp).(Field)');
end
However, it fails.
For example, suppose I have a structure array with 2 fields, A and B. So, I could write
MyStruct(1,1).A
A possible use would be:
M = getdata(MyStruct,A,1,1)
and I want the program to do:
M = MyStruct(1,1).A
How could I do that?
Thanks!
You can use the getfield function:
M = getfield(MyStruct, {1,1} ,'A');
Or if you wanted, say, MyStruct(1,1).A(3).B:
M = getfield(MyStruct, {1,1}, 'A', {3},'B');
For the example you give, this will suffice:
function M = getdata(matrix,field,varargin)
M = matrix(varargin{:}).(field);
which you call like
getdata(myStruct, 'A', 1,1)
which makes that function pretty useless.
But, in general, when you have indices given as strings, you can follow roughly the same approach:
%// Your indices
str = {'1', '2'};
%// convert to numbers
str = cellfun(#str2double, str, 'UniformOutput', false);
%// use them as indices into structure
M = myStruct(str{:}).(field)
And if you really insist, your call to eval is just wrong:
M = eval(['matrix(' exp ').(' field ')']);
And, as a general remark, please refrain from using exp as the name of a variable; it is also the name of a built-in function (the natural exponential function).

How to slice a struct array?

How can I extract a specific field from each element of a Matlab struct array?
>> clear x
>> x(1).a = 6;
>> x(2).a = 7;
I'd like an array containing 6 and 7. Neither x(:).a nor x.a do what I want.
>> x(:).a
ans =
6
ans =
7
No problem - just use :
arr = [x.a];
It will concat all of the values that you need.
If you have a more complex data, you can use the curly bracers:
b(1).x = 'John';
b(2).x = 'Doe';
arr = {b.x};
For a multi-dimensional array, you need
reshape([x.a], size(x))
If elements of the struct are strings, the accepted solution concatenates all cells.
The more general
vertcat(x.a)
works in all cases.
Ref
Sadly, I am almost sure that MATLAB has no nice way of doing what you want. You will have to either use a for loop to construct a new array, or else go back and redesign your data structures. For example you might be able to use a struct-of-arrays rather than an array-of-structs.

Resources