Bitget working with large inputs? - matlab

The default type is uint64 but the below apparently requires larger support where you can see that the number 536870915 (100000000000000000000000000011 in binary, 30 bits' length) is not supported by the above bitget command. So
How to get bitget command working with large inputs like the below?
Input
hhhh=sparse([],[],[],2^40+1,1);
hhhh(536870915)=1;
bitget(str2num(dec2bin(find(hhhh)-1)),2,'uint64')
Output
Error using bitget
Double inputs must have integer values in the range of ASSUMEDTYPE.

You pass the output of dec2bin(find(hhhh)-1) to str2num. This directly converts the string of ones and zeros into a double: 9.999999999999999e+28. I'm guessing that's not what you want.
If you're just trying to get the second bit of 536870915, why not use:
bitget(find(hhhh)-1,2,'uint64')
On the other hand, I think that you could also use this (probably slower, but maybe it'll work with the rest of your code if you're already converting to string representation):
b = dec2bin(find(hhhh)-1);
str2double(b(end-1))
It seems like you're trying to combine two approaches.

Related

MATLAB - literally convert decimal to string

I hope I have a simple question, I just couldn't figure it out.
I have several numbers which I want to be converted to string quite literally:
12.000 -> '12.000'
4.0 -> '4.0'
34.760000 -> '34.760000'
As you can see, I cannot simply pad zeros, since that highly depends on how many zero are given with the number.
Does anyone know how to do this?
Ahh, yes, this is easily accomplished with MATLAB's num2str function, like so:
num2str(12.000 ,'%.3f')
num2str(4.0, '%.1f')
num2str(34.760000,'%.6f')
WRT " %x.f ", where x equals 3,1, and 6 in the examples above, this is called the formSpec, which I would encourage you to read about more, here. In this case, we are saying that the variable is a floating point number, and we want to preserve x digits after the decimal place. It is useful to know about format specification for parsing text, and to efficiently read from and write to files.
Edit: A point of clarification, and as I'm sure you already know, single quotes (' ') in MATLAB yield a character array rather than a string. These are different data types. If you're really after a string, just add string to the num2str argument, i.e.,
string(num2str(12.000 ,'%.3f'))
string(num2str(4.0, '%.1f'))
string(num2str(34.760000,'%.6f'))

Octave / Matlab - Reading fixed width file

I have a fixed width file format (original was input for a Fortran routine). Several lines of the file look like the below:
1078.0711005.481 932.978 861.159 788.103 716.076
How this actually should read:
1078.071 1005.481 932.978 861.159 788.103 716.076
I have tried various methods, textscan, fgetl, fscanf etc, however the problem I have is, as seen above, sometimes because of the fixed width of the original files there is no whitespace between some of the numbers. I cant seem to find a way to read them directly and I cant change the original format.
The best I have come up with so far is to use fgetl which reads the whole line in, then I reshape the result into an 8,6 array
A=fgetl
A=reshape(A,8,6)
which generates the following result
11
009877
703681
852186
......
049110
787507
118936
So now I have the above and thought I might be able to concatenate the rows of that array together to form each number, although that is seeming difficult as well having tried strcat, vertcat etc.
All of that seems a long way round so was hoping for some better suggestions.
Thanks.
If you can rely on three decimal numbers you can use a simple regular expression to generate the missing blanks:
s = '1078.0711005.481 932.978 861.159 788.103 716.076';
s = regexprep(s, '(\.\d\d\d)', '$1 ');
c = textscan(s, '%f');
Now c{1} contains your numbers. This will also work if s is in fact the whole file instead of one line.
You haven't mentioned which class of output you needed, but I guess you need to read doubles from the file to do some calculations. I assume you are able to read your file since you have results of reshape() function already. However, using reshape() function will not be efficient for your case since your variables are not fixed sized (i.e 1078.071 and 932.978).
If I did't misunderstand your problem:
Your data is squashed in some parts (i.e 1078.0711005.481 instead
of 1078.071 1005.481).
Fractional part of variables have 3 digits.
First of all we need to get rid of spaces from the string array:
A = A(~ismember(A,' '));
Then using the information that fractional parts are 3 digits:
iter = length(strfind(A, '.'));
for k=1:iter
[stat,ind] = ismember('.', A);
B(k)=str2double(A(1:ind+3));
A = A(ind+4:end);
end
B will be an array of doubles as a result.

uint64 is not exact for vectors in Matlab

I have discovered an inconsistency for uint64 when using vectors in Matlab. It seems as an array of uint64 is not exact for all 64 bits. This did not give the output I expected,
p=uint64([0;0]);
p(1)=13286492335502040542
p =
13286492335502041088
0
However
q = uint64(13286492335502040542)
q =
13286492335502040542
does. It is also working with
p(1)=uint64(13286492335502040542)
p =
13286492335502040542
0
Working with unsigned integers one expect a special behaviour and usually also perfect precision. This seems weird and even a bit uncanny. I do not see this problem with smaller numbers. Maybe anyone knows more? I do not expect this to be an unknown problem, so I guess there must be some explanation to it. I would be good to know why this happen and when, to be able to avoid it. As usual this kind of issues is mentioned nowhere in the documentation.
Matlab 2014a, windows 7.
EDIT
It is worth mentioning that I can see the same behaviour when defining arrays directly.
p=uint64([13286492335502040542;13286492335502040543])
p =
13286492335502041088
13286492335502041088
This is the root to why I ask this question. I have hard to see workaround for this case.
While it might be surprising, this is a floating point precision issue. :-)
The thing is, all numeric literals are by default of type double in MATLAB; that's why:
13286492335502040542 == 13286492335502041088
will return true; the floating point representation in double precision of 13286492335502040542 is 13286492335502041088. Since p has the class uint64, all assignments done to it will cast the right-hand-side to its class.
On another hand, the uint64(13286492335502040542) "call" will be optimized by the MATLAB interpreter to avoid the overhead of calling the uint64 function for the double argument, and will convert the literal directly to its unsigned integer representation (which is exact).
On a third hand [sic], the function call optimization doesn't apply to
p = uint64([13286492335502040542;13286492335502040543])
because the argument of uint64 is not a literal, but the result of an expression, i.e. the result of the vertcat operator applied to two double operands. In this case the MATLAB interpreter is not smart enough to figure out that the two function calls should "commute" (concatenation of uint should be the same as uint of concatenation), so it evaluates the concatenation (which gives an array of equal double because FP precision), then converts the two similar double values to uint64.
TLDR: the difference between
p = uint64(13286492335502040542);
and
u = 13286492335502040542; p = uint64(u);
is a side effect of function call optimization.
Matlab, unless told otherwise reads numbers as double, then casts to the relevant datatype. The Matlab double datatype allows for 51 bits for the floating point fraction, giving the possibility to store 52 bit integers without loss of prepossession (mantissa). Notice that 13286492335502041088 is just 13286492335502040543 with the last 12 bits set to zero.
the solution as you said, is to convert the literals directly uint64(13286492335502040543).
p=uint64([13286492335502040542;13286492335502040543]) does not work because it creates a double array and then converts it to uint64
This issue is mentioned in the uint64 documentation, under 'More About', although it doesn't mention that laterals are read as doubles unless otherwise specified.
I agree this seems weird and I don't have an explanation. I do have a workaround:
p=[uint64(13286492335502040542);uint64(13286492335502040543)]
i.e., cast the separate values to uint64s.

Matlab mnrfit error "Inputs must be floats, namely single or double."

I have training data, that are train_input (194x11 matrix) and train_output (194x1 ordinal).
class(train_input) gives the result double and class(train_output) gives the result ordinal. I run them using mnrfit in Matlab. The command is basically
[B,dev,stats] = mnrfit(train_output, train_input)
I get the error message:
Inputs must be floats, namely single or double.
I converted the ordinal output into double and this time the error is
If Y is a column vector, it must contain positive integer category numbers
I tried to make them categorical, bu this time I get
Creating an instance of the Abstract class 'categorical' is not allowed
The Matlab tutorial says that I keep them ordinal or categorical in order to apply mnrfit.
I also tried to run the examples myself, I get the last "categorical" error.
What might the problem be?
The problem is that you are not inputting floats. That's exactly what the error says. An ordinal is not a double or single, therefore it does not work.
This page on the documentation shows examples and as far as I can see you need doubles for both X and Y. Try running the examples yourself and check the classes of their inputs.

'exact' numerical value after numerical optimization MATLAB

I'm having the following issue with my code. I've been trying to use some other posts that I found on line, like this one. But they didn't what I'm looking for.
My code uses a MATLAB Exchange function which optimize a numerical value that is important to be with 32 digits after the dot such as
0.59329669191989231613604260928696
The optimization function can be found here and it is called fminsearchbnd
The optimization function calculate this and store the value in a variable that I use all over my code. In order not to perform the optimization everytime I want to store the variable (I tried either on a *.mat and on a label in the string form.
But when I retrieve it, MATLAB transforms it in a double precision variable 'cutting' all the numbers after the 14th. However I need all of them because they are important!
Is it possible to read a number like that w/o using vpa() because with a symbolic value I can't do anything.
Any help is really appreciated.
Thanks
EDIT:
fminsearchbnd gives me this class(bb) -> double and when I want to see it on the workspace it is 0.586675392365899. But when I set formatSpec = '%.32f\n'; because I want to see all the numbers that the optimization gives me, typing set(editLabel,'String',num2str(bb,formatSpec))
You're trying to store/use a number that cannot be represented exactly in an IEEE754 64-bit double-precision floating point number.
I'm not sure how you got that number without using vpa() in the first place, since 64-bit double is Matlab's maximum of precision...
You could use the multiple precision toolbox by Ben Barrowes, or HPF by John d'Errico, also from the FEX. You'll have to convert/construct to/from string if you want to store/load it to/from file.
But I have to agree with John's comment there:
The fact is, most of the time, if you can't do it with a double, you
are doing something wrong
so...why exactly are those 32-or-more digits important?