How to get the environment decimal separator in Octave - octave

I need to assign to a variable the environment decimal separator in Octave.
For example, if the pc is set in US format
>> decsep
ans = .
Instead if you run the script from a pc that has European decimal format the output will be
>> decsep
ans = ,

You can use Java to get the decimal separator:
Format = javaMethod( "getInstance", "java.text.DecimalFormat" );
Symbols = javaMethod( "getDecimalFormatSymbols", Format );
Sep = javaMethod( "getDecimalSeparator", Symbols )
Alternatively you can use the following PowerShell (powershell.exe or pwsh.exe) script:
[~, s] = system("pwsh -command (Get-Culture).NumberFormat.NumberDecimalSeparator");
Sep = s(1);

On Linux, you can use:
[~, s] = system('locale decimal_point'); %returns decimal separator and a '↵'
decsp = s(1); %Required answer

Related

How can I set the numbering of the x-axis of an Octave plot to engineering notation?

I made a very simple Octave script
a = [10e6, 11e6, 12e6];
b = [10, 11, 12];
plot(a, b, 'rd-')
which outputs the following graph.
Graph
Is it possible to set the numbering on the x-axis to engineering notation, rather than scientific, and have it display "10.5e+6, 11e+6, 11.5e+6" instead of "1.05e+7, 1.1e+7, 1.15+e7"?
While octave provides a 'short eng' formatting option, which does what you're asking for in terms of printing to the terminal, it does not appear to provide this functionality in plots or when formatting strings via sprintf.
Therefore you'll have to find a way to do this by yourself, with some creative string processing of the initial xticks, and substituting the plot's ticklabels accordingly. Thankfully it's not that hard :)
Using your example:
a = [10e6, 11e6, 12e6];
b = [10, 11, 12];
plot(a, b, 'rd-')
format short eng % display stdout in engineering format
TickLabels = disp( xticks ) % collect string as it would be displayed on the stdout
TickLabels = strsplit( TickLabels ) % tokenize at spaces
TickLabels = TickLabels( 2 : end - 1 ) % discard start and end empty tokens
TickLabels = regexprep( TickLabels, '\.0+e', 'e' ) % remove purely zero decimals using a regular expression
TickLabels = regexprep( TickLabels, '(\.[1-9]*)0+e', '$1e' ) % remove non-significant zeros in non-zero decimals using a regular expression
xticklabels( TickLabels ) % set the new ticklabels to the plot
format % reset short eng format back to default, if necessary

Why octave error with function huffmandeco about large index types?

I've got a little MatLab script, which I try to understand. It doesn't do very much. It only reads a text from a file and encode and decode it with the Huffman-functions.
But it throws an error while decoding:
"error: out of memory or dimension too large for Octave's index type
error: called from huffmandeco>dict2tree at line 95 column 19"
I don't know why, because I debugged it and don't see a large index type.
I added the part which calculates p from the input text.
%text is a random input text file in ASCII
%calculate the relative frequency of every Symbol
for i=0:127
nlet=length(find(text==i));
p(i+1)=nlet/length(text);
end
symb = 0:127;
dict = huffmandict(symb,p); % Create dictionary
compdata = huffmanenco(fdata,dict); % Encode the data
dsig = huffmandeco(compdata,dict); % Decode the Huffman code
I can oly use octave instead of MatLab. I don't know, if there is an unexpected error. I use the Octave Version 6.2.0 on Win10. I tried the version for large data, it didn't change anything.
Maybe anyone knows the error in this context?
EDIT:
I debugged the code again. In the function huffmandeco I found the following function:
function tree = dict2tree (dict)
L = length (dict);
lengths = zeros (1, L);
## the depth of the tree is limited by the maximum word length.
for i = 1:L
lengths(i) = length (dict{i});
endfor
m = max (lengths);
tree = zeros (1, 2^(m+1)-1)-1;
for i = 1:L
pointer = 1;
word = dict{i};
for bit = word
pointer = 2 * pointer + bit;
endfor
tree(pointer) = i;
endfor
endfunction
The maximum length m in this case is 82. So the function calculates:
tree = zeros (1, 2^(82+1)-1)-1.
So it's obvious why the error called a too large index type.
But there must be a solution or another error, because the code is tested before.
I haven't weeded through the code enough to know why yet, but huffmandict is not ignoring zero-probability symbols the way it claims to. Nor have I been able to find a bug report on Savannah, but again I haven't searched thoroughly.
A workaround is to limit the symbol list and their probabilities to only the symbols that actually occur. Using containers.Map would be ideal, but in Octave you can do that with a couple of the outputs from unique:
% Create a symbol table of the unique characters in the input string
% and the indices into the table for each character in the string.
[symbols, ~, inds] = unique(textstr);
inds = inds.'; % just make it easier to read
For the string
textstr = 'Random String Input.';
the result is:
>> symbols
symbols = .IRSadgimnoprtu
>> inds
inds =
Columns 1 through 19:
4 6 11 7 12 10 1 5 15 14 9 11 8 1 3 11 13 16 15
Column 20:
2
So the first symbol in the input string is symbols(4), the second is symbols(6), and so on.
From there, you just use symbols and inds to create the dictionary and encode/decode the signal. Here's a quick demo script:
textstr = 'Random String Input.';
fprintf("Starting string: %s\n", textstr);
% Create a symbol table of the unique characters in the input string
% and the indices into the table for each character in the string.
[symbols, ~, inds] = unique(textstr);
inds = inds.'; % just make it easier to read
% Calculate the frequency of each symbol in table
% max(inds) == numel(symbols)
p = histc(inds, 1:max(inds))/numel(inds);
dict = huffmandict(symbols, p);
compdata = huffmanenco(inds, dict);
dsig = huffmandeco(compdata, dict);
fprintf("Decoded string: %s\n", symbols(dsig));
And the output:
Starting string: Random String Input.
Decoded string: Random String Input.
To encode strings other than the original input string, you would have to map the characters to symbol indices (ensuring that all symbols in the string are actually present in the symbol table, obviously):
>> [~, s_idx] = ismember('trogdor', symbols)
s_idx =
15 14 12 8 7 12 14
>> compdata = huffmanenco(s_idx, dict);
>> dsig = huffmandeco(compdata, dict);
>> fprintf("Decoded string: %s\n", symbols(dsig));
Decoded string: trogdor

including internally created strings in octave system/unix command?

I have a script like:
#!/opt/bin/octave -qf
xin = dlmread(argv(){1},",");
tim = dlmread("Time");
fileout = [argv(){1} "-" "avg"];
## calcs to create xtemp and time matrices
dlmwrite("Time-avg",time);
dlmwrite(fileout,xtemp,",");
## ?? unix("paste -d',' Time-avg fileout > DATCOARSE");
This all works fine until the last line. I create fileout inside the script to correlate with the input datafile, and fileout prints out fine.
Is there some kind of dereferencing operator in octave to use "fileout" in the unix or system command?
You can use sprintf to create the command string:
cmd_str = sprintf ("paste -d',' Time-avg %s > DATCOARSE", fileout);
unix (cmd_str)
But you don't have to use "paste" at all. You can just concatenate the matrices in octave
dlmwrite ("DATCOARSE", [time, xtemp], ",");

How to read gzip-File with fopen in octave 3.2.4?

I need to open a gzip file with fopen. The manual (help fopen) explains to add b and z to the mode string:
[f, msg] = fopen('file.gz', 'rbz')
results to the error:
f = -1
msg =
rb and r work separately, but not with z. Do i misunderstand the manual?
An example file can be generated by
echo -e "1,2\n2,3\n3,4\n4,3\n5,5" | gzip > file.gz
The octave version 3.2.4 is caused by my operating system: Ubuntu 12.04.3 LTS
function data = zcatcsvfile(filename, firstline)
data = [];
[status, content] = system(cstrcat('zcat ', filename, ' | tail -n +', num2str(firstline)));
data = str2num(content);
endfunction
Use this function to read a gzipped file filename and read as first line firstline. If the file has a header of 5 lines:
data=zcatcsvfile('data.gz', 6)

64-bit integers changed to floating point using JSON::XS::encode_json in Perl

My Perl version supports 64 bits. I'm receiving JSON data from multiple sources, then I'm decoding it, processing it, and then I re-encode it in order to save the data in a MySQL queue for further processing by a different server.
All the data includes 64-bit integers as identifiers. Sometimes, under some circumstances which I don't understand, the 64-bit integers are changed to floating point values by JSON::XS::encode_json. For instance, 393074769794314240 would be changed for 3.93074769794314e+17.
How can I prevent this from happening?
Thank you.
I can replicate the problem if the integer is used somewhere in a floating point context. It's sufficient to use the number in a floating point operation, e.g. adding another float to it. Here's a sample script:
use strict;
use JSON::XS qw(encode_json);
use Devel::Peek;
{
my $x = { number => 4_999_999_999_999_999};
Dump $x->{number};
warn encode_json $x; # encodes number as integer
}
{
my $x = { number => 4_999_999_999_999_999};
my $y = $x->{number} + 0.1;
Dump $x->{number};
warn encode_json $x; # encodes number as float
}
On my FreeBSD amd64 system I get
SV = IV(0x80180a458) at 0x80180a468
REFCNT = 1
FLAGS = (IOK,pIOK)
IV = 4999999999999999
{"number":4999999999999999} at /tmp/json3.pl line 22.
SV = PVNV(0x80184d930) at 0x801813408
REFCNT = 1
FLAGS = (IOK,NOK,pIOK,pNOK)
IV = 4999999999999999
NV = 5e+15
PV = 0
{"number":5e+15} at /tmp/json3.pl line 29.
A workaround is to use something like $x->{number} += 0; before the encode_json call — this would remove the NV value (the floating point value), and JSON::XS would again see only a IV (integer value).
I can't replicate your problem.
use Config qw( %Config );
use Devel::Peek qw( Dump );
use JSON::XS qw( encode_json decode_json );
print $Config{uvsize} * 8, "-bit ints\n";
my $n = 393074769794314240;
printf("%.20g\n", 0+$n);
Dump($n);
my $json = encode_json([$n]);
print "$json\n";
Dump(decode_json($json)->[0]);
Outputs:
64-bit ints
393074769794314240
SV = IV(0x4c8d90) at 0x4c8da0
REFCNT = 1
FLAGS = (PADMY,IOK,pIOK)
IV = 393074769794314240
[393074769794314240]
SV = IV(0x1dd130) at 0x1dd140
REFCNT = 1
FLAGS = (IOK,pIOK)
IV = 393074769794314240
Unless I use it as a floating point number, say by replacing
printf("%.20g\n", 0+$n);
with
printf("%.20g\n", $n);
Going forward:
It's unlikely to help, but you could try upgrading JSON::XS.
Provide a minimal, runnable demonstration of the problem.
Provide the output of perl -V:ivsize.