Function output produces double array while only a single value is expected

1 回表示 (過去 30 日間)
Matt Sprague
Matt Sprague 2021 年 7 月 15 日
コメント済み: Matt Sprague 2021 年 7 月 15 日
Hello,
I created a fairly straightforward function that accepts lat and lon values in a particular format and converts them into decimal format. Specifically, the input format is a character/string of the style "DDmm.mm ..." where D is degrees and m is minutes. It simply takes the sum of the first two digits (DD) and the minutes (mm.mm ....) divided by 60 to get the lat/lon values in decimals:
function [lat, lon] = latlon_decimal(lat, lon, varargin)
lat = char(string(lat));
lon = char(string(lon));
lat_deg = str2double(lat(:,1:2));
lon_deg = str2double(lon(:,1:2));
lat_min = str2double(lat(:,3:end));
lon_min = str2double(lon(:,3:end));
lat_nans = lat_deg + lat_min/60;
lon_nans = lon_deg + lon_min/60;
if varargin == "omitnan"
lat = lat_nans(~isnan(lat));
lon = lon_nans(~isnan(lon));
else
lat = lat_nans;
lon = lon_nans;
end
end
When I use this function with array inputs, it works perfectly. However when I use it with a single-value input, it outputs an array of values I don't understand, but I'm expecting just a single-value output. To give an example:
[lat, lon] = latlon_decimal('1234.5678', '8765.4321')
lat =
Columns 1 through 7
0.8167 0.8333 0.8500 0.8667 0.7667 0.8833 0.9000
Columns 8 through 9
0.9167 0.9333
lon =
Columns 1 through 7
0.9333 0.9167 0.9000 0.8833 0.7667 0.8667 0.8500
Columns 8 through 9
0.8333 0.8167
What's really strange about this is that if I just copy/paste all the lines within the function into the command window and run them with the same values, it works perfectly fine:
lat = '1234.5678'; lon = '8765.4321';
lat = char(string(lat));
lon = char(string(lon));
lat_deg = str2double(lat(:,1:2));
lon_deg = str2double(lon(:,1:2));
lat_min = str2double(lat(:,3:end));
lon_min = str2double(lon(:,3:end));
lat_nans = lat_deg + lat_min/60;
lon_nans = lon_deg + lon_min/60;
lat = lat_nans;
lon = lon_nans;
disp([lat lon])
12.5761 88.0905
I've also run the function with the 'omitnan' condition, and that didn't change the weird result.
So for that reason I expect that there is something wrong with defining the function, but everything in it seems to be okay. Is it possibly something weird about how str2double behaves within a function? I've had issues before where typing >> double('insert number here') will produce an unexpected array of two-digit numbers, and I suspect that isn't an error but more so something I don't understand. All the same, str2double doesn't cause any issues when I use it in the command window.
I assume this is probably something simple that I'm overlooking. Thanks in advance!
  2 件のコメント
Stephen23
Stephen23 2021 年 7 月 15 日
編集済み: Stephen23 2021 年 7 月 15 日
The reason for those strange values is that your output is simply calculated from the character codes:
V = [0.8167,0.8333,0.8500,0.8667,0.7667,0.8833,0.9000,0.9167,0.9333]
V = 1×9
0.8167 0.8333 0.8500 0.8667 0.7667 0.8833 0.9000 0.9167 0.9333
char(round(60*V))
ans = '1234.5678'
Possibly this is a flaw in your algorithm, or it may be a flaw in how you call it: e.g. it may be a bug that does not correctly handle both strings and (cell arrays of) char vectors (if you attempted to make you code work with both). You did not give enough context to debug this.
Matt Sprague
Matt Sprague 2021 年 7 月 15 日
I think I should take a look at character codes more generally. I assumed that using double() or char(), etc. would simply convert from one type to another - i.e. you could write
double('123456')
and simply get an output of 123456. (And that this would work as long as your argument had no letters, symbols, etc.)
Either way the method you provided works well, much appreciated.

サインインしてコメントする。

採用された回答

Stephen23
Stephen23 2021 年 7 月 15 日
編集済み: Stephen23 2021 年 7 月 15 日
I would avoid all of those superfluous and inefficient type conversions and messing around with indexing into character arrays. Just convert all of the values to numeric at once and then efficiently perform the required adjuments (as numeric operations). It is quite simple and much more efficient, e.g.:
[lat, lon] = latlon_decimal('1234.5678', '8765.4321')
lat = 12.5761
lon = 88.0905
[lat, lon] = latlon_decimal('0123.4567 1234.5678 2345.6789', '9876.5432 8765.4321 7654.3210')
lat = 1×3
1.3909 12.5761 23.7613
lon = 1×3
99.2757 88.0905 76.9053
function [lat, lon] = latlon_decimal(lat, lon, varargin)
lat = [1,1/60]*sscanf(lat,'%2d%f',[2,Inf]);
lon = [1,1/60]*sscanf(lon,'%2d%f',[2,Inf]);
if any(strcmpi(varargin,'omitnan'))
idx = isnan(lat)|isnan(lon);
lat = lat(~idx);
lon = lon(~idx);
end
end
  1 件のコメント
Matt Sprague
Matt Sprague 2021 年 7 月 15 日
Thank you, this seems to work. I had never seen sscanf before and probably would have used it if I had known.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeStructures についてさらに検索

製品


リリース

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by