I have an embedded application that generates half precision (fp16) output that I would like to import and use in MATLAB. Would someone please advise me the easiest way to do that?
MATLAB: Using FP16 data in MATLAB
fp16halfhalf precisionMATLAB
Related Solutions
You have a integer data type in an operation with a double precision data type (t1 = 14 is double precision.) MATLAB defines an operation combining an integer data type and double precision as being carried out in double precision and then converted to the integer data type. Your code is currently equivalent to
y = int16( double(t2) / t1 );
If that is not what you want, then you should either not make t2 into int16, or else you should convert it before the division:
y = double(t2) / t1;
I don't have R2019b installed so I don't know how half precision numbers are stored, but can you use typecast:
h = your half precision variableu16 = typecast(h,'uint16');
Another option is a mex routine, but I would need to know how the half precision values are stored first.
EDIT
I just checked, and unfortunately the new half precision type is not a fundamental numeric type like double or uint16 ... it is an opaque type like OOP classdef objects. So even though isnumeric(half) returns true, half precision variables are not stored the same as the native numeric variables are. The data areas are hidden.
I have no idea why TMW would choose to implement a basic numeric type this way, but they must have their reasons. The half precision type is fundamentally different from all of the other numeric types. Not suprisingly, the typecast( ) function does not work since the storage scheme is fundamentally different. This also makes a mex option out of the question since the data area is hidden. What a pain ... why couldn't they have just made it compatible with all the other numeric types??? THERE WILL BE NO WAY TO EFFICIENTLY WORK WITH HALF VARIBLES IN A MEX ROUTINE BECAUSE OF THIS! (yes I am shouting)
SOLUTION
For your purpose, you only need the hex patterns or equivalent bit patterns to write out. So I can offer my C-mex code for this, which can be found here:
You would convert your half precision variable to single, then call my C-mex routine to turn it into the uint16 half precision bit pattern. Then you can write that uint16 variable directly to a file in binary with fwrite( ). I just need to check to see if it still works in later versions of MATLAB. I will get back to you ...
UPDATE
I downloaded my halfprecision C-mex file and it seems to compile and run OK. Just don't use the -R2018a mex option because the code isn't updated yet for R2018a+. My halfprecision C code will also handle the inf, nan, and denorm patterns just fine. You would compile it as follows:
mex halfprecision.c
Sample run:
>> versionans = '9.7.0.1190202 (R2019b)'>> halfpi = half(pi) % The MATLAB half class
halfpi = half 3.1406250 % MATLAB is apparently using the single display code for this
>> hp = halfprecision(pi) % my C-mex routine ...
hp = uint16 % ... returns a uint16 variable that contains the half precision bit pattern
16968>> halfprecision(hp,'disp') % my C-mex routine has a display option
3.1406>> halfprecision(hp,'single') % my C-mex routine can convert it back into other classes
ans = single 3.1406250>> sprintf('%04x',hp) % If you want the hex values as ASCII text, do this
ans = '4248'>> >> halfinf = half(inf)halfinf = half Inf>> hinf = halfprecision(inf)hinf = uint16 31744>> halfprecision(hinf,'disp') Inf>> halfprecision(hinf,'single')ans = single Inf>> sprintf('%04x',hinf)ans = '7c00'>> >> halfnan = half(nan)halfnan = half NaN>> hnan = halfprecision(nan)hnan = uint16 65024>> halfprecision(hnan,'disp') NaN>> halfprecision(hnan,'single')ans = single NaN>> sprintf('%04x',hnan)ans = 'fe00'>> format hex>> halfpihalfpi = half 4248>> halfinfhalfinf = half 7c00>> halfnanhalfnan = half fe00
Best Answer