MATLAB: How do features from ‘license’ correspond to names from ‘ver’

licenselicensingtoolboxtoolboxes

I'm currently struggling a bit trying to set up a proper mechanism to check for the presence and availability of a matlab toolbox.
I know that using `ver`, I can get a list of all installed toolboxes in the name field of the resulting struct, and that using `license('test',featurename)` I can check, whether this toolbox is actually license (and can thus be used).
The problem is, that the names from `ver` do not clearly correspond to the feature strings used in `license` (e.g. 'Global Optimization Toolbox' becomes 'Optimization_Toolbox'). There is a list at https://nl.mathworks.com/help/matlab/ref/license.html which details a bunch of "Corresponding" feature / Product pairs, but since whats showing up in the name field changes between matlab versions, I don't want to rely on this.
Is there any programmatic way to find the corresponding values that is valid from at least 2014b?

Best Answer

Here is the data I have available to me:
licver_info = {
'Aerospace Blockset' 'Aerospace_Blockset' 'aeroblks'
'Aerospace Toolbox' 'Aerospace_Toolbox' 'aero'
'Antenna Toolbox' 'Antenna_Toolbox' 'antenna'
'Audio System Toolbox' 'Audio_System_Toolbox' 'audio'
'Bioinformatics Toolbox' 'Bioinformatics_Toolbox' 'bioinfo'
'Communications System Toolbox' 'Communication_Toolbox' 'comm'
'Computer Vision System Toolbox' 'Video_and_Image_Blockset' 'vision'
'Control System Toolbox' 'Control_Toolbox' 'control'
'Curve Fitting Toolbox' 'Curve_Fitting_Toolbox' 'curvefit'
'DSP System Toolbox' 'Signal_Blocks' 'dsp'
'Data Acquisition Toolbox' 'Data_Acq_Toolbox' 'daq'
'Database Toolbox' 'Database_Toolbox' 'database'
'Datafeed Toolbox' 'Datafeed_Toolbox' 'datafeed'
'Deep Learning Toolbox' 'Neural_Network_Toolbox' 'nnet'
'Econometrics Toolbox' 'Econometrics_Toolbox' 'econ'
'Embedded Coder' 'RTW_Embedded_Coder' 'embeddedcoder'
'Financial Instruments Toolbox' 'Fin_Instruments_Toolbox' 'fininst'
'Financial Toolbox' 'Financial_Toolbox' 'finance'
'Fixed-Point Designer' 'Fixed_Point_Toolbox' 'fixedpoint'
'Fuzzy Logic Toolbox' 'Fuzzy_Toolbox' 'fuzzy'
'Global Optimization Toolbox' 'GADS_Toolbox' 'globaloptim'
'Image Acquisition Toolbox' 'Image_Acquisition_Toolbox' 'imaq'
'Image Processing Toolbox' 'Image_Toolbox' 'images'
'Instrument Control Toolbox' 'Instr_Control_Toolbox' 'instrument'
'MATLAB' 'MATLAB' 'general'
'MATLAB Coder' 'MATLAB_Coder' 'matlabcoder'
'MATLAB Compiler' 'Compiler' 'compiler'
'MATLAB Report Generator' 'MATLAB_Report_Gen' 'rptgen'
'Mapping Toolbox' 'MAP_Toolbox' 'map'
'Model Predictive Control Toolbox' 'MPC_Toolbox' 'mpc'
'Neural Network Toolbox' 'Neural_Network_Toolbox' 'nnet'
'Optimization Toolbox' 'Optimization_Toolbox' 'optim'
'Parallel Computing Toolbox' 'Distrib_Computing_Toolbox' 'distcomp'
'Partial Differential Equation Toolbox' 'PDE_Toolbox' 'pde'
'Phased Array System Toolbox' 'Phased_Array_System_Toolbox' 'phased'
'Polyspace Bug Finder' 'PolySpace_Bug_Finder' 'psbugfinder'
'Polyspace Bug Finder' 'PolySpace_Bug_Finder_Engine' 'psbugfinder'
'Polyspace Code Prover' 'PolySpace_Server_C_CPP' 'pscodeprover'
'RF Blockset' 'RF_Blockset' 'rfblks'
'RF Toolbox' 'RF_Toolbox' 'rf'
'Robotics System Toolbox' 'Robotics_System_Toolbox' 'robotics'
'Robust Control Toolbox' 'Robust_Toolbox' 'robust'
'Signal Processing Toolbox' 'Signal_Toolbox' 'signal'
'SimBiology' 'Simbiology' 'simbio'
'SimEvents' 'SimEvents' 'simevents'
'Simscape' 'Simscape' 'simscape'
'Simscape Driveline' 'SimDriveline' 'sdl' %possibly 'simdrive'
'Simscape Electronics' 'SimElectronics' 'elec'
'Simscape Fluids' 'SimHydraulics' 'fluids'
'Simscape Multibody' 'SimMechanics' 'mech'
'Simscape Power Systems' 'Power_System_Blocks' 'sps'
'Simulink' 'SIMULINK' 'simulink'
'Simulink 3D Animation' 'Virtual_Reality_Toolbox' 'sl3d'
'Simulink Coder' 'Real-Time_Workshop' 'simulinkcoder'
'Simulink Control Design' 'Simulink_Control_Design' 'slcontrol'
'Simulink Design Optimization' 'Simulink_Design_Optim' 'sldo'
'Simulink Desktop Real-Time' 'Real-Time_Win_Target' 'sldrt'
'Simulink Real-Time' 'XPC_Target' 'xpctarget' %probably incorrect


'Simulink Report Generator' 'SIMULINK_Report_Gen' 'rptgenext'
'Spreadsheet Link' 'Excel_Link' 'excellink'
'Stateflow' 'Stateflow' 'stateflow'
'Statistics and Machine Learning Toolbox' 'Statistics_Toolbox' 'stats'
'Symbolic Math Toolbox' 'Symbolic_Toolbox' 'symbolic'
'System Identification Toolbox' 'Identification_Toolbox' 'ident'
'Trading Toolbox' 'Trading_Toolbox' 'trading'
'Vehicle Network Toolbox' 'Vehicle_Network_Toolbox' 'vehiclenetwork' %probably incorrect
'Vision HDL Toolbox' 'Vision_HDL_Toolbox' 'vision-hdl' %probably incorrect
'Wavelet Toolbox' 'Wavelet_Toolbox' 'wavelet' };
This was derived by:
1) fileread() one of my .lic files; regexp() with 'tokens' twice, once concentrating on =product= which is followed by a single word product description, and once concentrating on ="product= which is followed by a multi-word product description until the first " . In either case, the name for license() purposes is immediately after the word INCREMENT in the file. Then the multi-word descriptions need to be filtered to remove literal \ followed by newline followed by spaces. Put everything together into N x 2 cell array.
2) hack ver.m . If you which ver you might get ver.p but it turns out that calls ver.m which you can find the location of with which -all ver . There is a routine locParseContentsFiles which uses which to look for all Contents.m files. It then reads through those files and looks for ones in a specific format. The ones that it finds, it adds to a struct. The hack is to pull apart the file name to extract the last directory before the 'Contents.m' part and to record it in the struct as well. Run ver() assigning the output to a variable, which will become a struct. Extract the Name field and the field that you saved the directory name.
3) create two tables from the two respective information sources, giving the same variable name to the product description from the first license information, and to the Name field from the result of ver(). Now innerjoin() the two tables; the common key will be used automatically. table2cell() the results of the innerjoin() to get the information as above.