Bad Rounding of simtime_t values using the CSV export - omnet++

Used Versions: OMNeT++ 5.0 with iNET 3.4.0
During some data analysis I noticed that the CSV-export of the analysis tool rounds values like 0.01146575 to 0.0114658. Even if I set the precision to the maximum value of 18.
Here some parts of my code:
In .ned I declared the recording using the type 'simtime_t':
#signal[timestamp](type="simtime_t");
#statistic[timestamp](title="timestamp"; record=mean);
At the top of my .cc I declared the signals:
simsignal_t timestampSignal;
timestampSignal = registerSignal("timestamp");
and somewhere in my code I got:
sintime_t myTime = ...
emit(timestamp, myTime);
Browsing my results in the .anf file I see the right timestamps, but when i export the data via CSV-export I get the bad rounding.
I think myTime is internally converted to a double value. I don't really know the reason, because I set the type of my signal to 'simtime_t'. The mentioned export-precision of '18' should normally be precise enough to display such values.
Is there anything I can do to avoid the rounding of my values? The .octave-exports seems to work fine, but I can't process this file-format in the way I want to.

Related

Freemarker: How to write a BigDecimal's value that can be used in a BigDecimal constructor

I would like to use freemarker to generate java code that instantiates a BigDecimal.
The value of the BigDecimal is present at generation time.
the BigDecimal API would work like this:
BigDecimal copy = new BigDecimal(original.toString());
Alas, the freemarker magic uses numeric conversion on my value of original, so this does not work (in a freemarkter template):
BigDecimal copy = new BigDecimal("${original?c}");
None of the numeric conversions (percent, number, computer, ...) works - c/computer most interestingly, because it outputs 0 if the value becomes too big.
With considerable pain, I might be able to wrap the BigDecimal in another Object that just gives me a toString and is not a number, so freemarker might leave its value untouched and my generated BigDecimal is correct, but that's only a last resort.
Maybe there is a way to invoke the toString() method and print the result into the target document?
ERRATUM:
because it outputs 0 if the value becomes too big should read because it outputs 0 if the value becomes too small (see #ddkany's answer)
Update: FreeMarker 2.3.32 now supports lossless formatting with ?c, which is not based on DecimalFormat, but mostly on toString. To use that, you have to set the c_format configuration setting to any other value than its backward compatible default, "legacy". Like setting it to "JavaScript or JSON" is fine for most projects (that's also the default if you just set the incompatible_improvements configuration setting to 2.3.32). See the fine details of how numers are formatted in the documentation of the c built-in: https://freemarker.apache.org/docs/ref_builtins_number.html#ref_builtin_c
Old answer, for 2.3.31 and before:
What FreeMarke does by default is whatever Java's DecimalFormat does (for the localized medium format by default, again defined by the Java platform).
?c uses new DecimalFormat("0.################") with fixed US locale (and some more symbol adjustments for INF and NaN). So I don't know how that gives 0 for a huge BigDecimal number. Are you sure about that? I guess it was actually a very small number, so it was rounded down. Well, switching to "scientific" format would make more sense then, though.
To have whatever formatting logic you need, you can register your own number formatter like, in this case, configuration.setCustomNumberFormats(Map.of("toString", new MyToStringTemplateNumberFormatFactory()), and then you can use ${original?string.#toString}. Or rather, you can set the number_format to #toString, and then just use ${original}.

Configure larger limit of columns on Format module

The Format module
The Format module is used to model and combine pretty printers with a syntactic extension that allows typed formats and it helps a lot when you are writing something like a code generator or a data structure printer.
The problem
However, there is a limit of 78 columns that is initialized on the margin of the formatter and will pull to the left anything that takes more than this limit.
I'm printing a lighter version of a Yojson.Basic.json program using the Format module, but when the input is too large, the output is collapsed, and that is not really "prettily".
Preview
Here is how it is is formatted when it is short:
Here is how it is formatted when the indentation becomes too large
I've been trying to exceed and configure this limit to 120 columns, but didn't have any success.
What have I tried?
Using Format.pp_set_margin ppf 120 to reconfigure
Using Format.pp_set_max_indent to a larger value
But they doesn't seem to have any effect and there is no documentation easily available about this limit. I've discovered it only by reading the source code.
What am I doing?
let string_of_cst program =
let ppf = Format.str_formatter in
(* I've enabled colors. *)
Format.pp_set_tags ppf colors;
Format.pp_set_formatter_tag_functions ppf with_colors;
(* [print_json] is my printer. *)
print_json ppf program;
(* Get string out of printer. *)
Format.flush_str_formatter ()
How can I configure a larger limit?
The issue is that the values for margin and max_indent are implicitly constrained to the cone 1 < max_indent < margin and the function set_max_indent silently fails and does nothing if this constraint is not respected.
To avoid this issue, in OCaml ≥4.08, it would be possible to use the new set_geometry function that requires to set both value simultaneously and fails with an exception if the required max_indent is greater than the margin.
Otherwise, you should always set both values at the same time, and always in the order
margin first, and max_indent second. If you don't know which value to chose for max_indent, margin - 10 is generally an alright choice.

VBScript - RANDOMIZE (Cbyte(Left(Right(Time(),5),2))) throws 500 for ES locales

Using a standard VBScript Randomize statement (below) which works fine -- most of the time.
...RANDOMIZE (Cbyte(Left(Right(Time(),5),2)))
RANDOMIZE...
It took a bit, but in digging thru log files, I've noticed that it throws this 500 error:
Type mismatch: 'Cbyte'
when the users' languages are non-English.
I tried changing the Session.LCID (I'm using Classic ASP) in a test page but no effect.
Any suggestions for fixing or a work-around? Thank you...
It appears you're trying to randomise based on the seconds-within-the-minute value:
12:34:56 AM
|---|
56 AM (right(5))
||
56 (left(2))
Now I have no idea of the top of my head what Time() would return in a Spanish locale, but it may well be something like 12:34:56 de la mañana.
What I do know is that relying on a specific presentation format in a globalised world is a bad idea. In your case, it may involve trying to convert left(right("12:34:56 de la mañana",5),2), or "añ", into a numeric value, something it's not going to be happy with.
If you want a true root cause analysis, I'd suggest catching the conversion error and actually logging what Time() is presenting itself as when it errors.
If you just want to fix it, find a way to get the seconds that doesn't depend on locale, for example:
secs = Second(Time())
As an aside, I'm not sure why you think this is even needed. The documentation for the VBScript Randomise function states that, if an argument is not given, the value returned by the system timer is used as the new seed value. Hence it's already based on the current time.

MATLAB ConnectedComponentLabeler does not work in for loop

I am trying to get a set of binary images' eccentricity and solidity values using the regionprops function. I obtain the label matrix using the vision.ConnectedComponentLabeler function.
This is the code I have so far:
files = getFiles('images');
ecc = zeros(length(files)); %eccentricity values
sol = zeros(length(files)); %solidity values
ccl = vision.ConnectedComponentLabeler;
for i=1:length(files)
I = imread(files{i});
[L NUM] = step(ccl, I);
for j=1:NUM
L = changem(L==j, 1, j); %*
end
stats = regionprops(L, 'all');
ecc(i) = stats.Eccentricity;
sol(i) = stats.Solidity;
end
However, when I run this, I get an error says indicating the line marked with *:
Error using ConnectedComponentLabeler/step
Variable-size input signals are not supported when the OutputDataType property is set to 'Automatic'.'
I do not understand what MATLAB is talking about and I do not have any idea about how to get rid of it.
Edit
I have returned back to bwlabel function and have no problems now.
The error is a bit hard to understand, but I can explain what exactly it means. When you use the CVST Connected Components Labeller, it assumes that all of your images that you're going to use with the function are all the same size. That error happens because it looks like the images aren't... hence the notion about "Variable-size input signals".
The "Automatic" property means that the output data type of the images are automatic, meaning that you don't have to worry about whether the data type of the output is uint8, uint16, etc. If you want to remove this error, you need to manually set the output data type of the images produced by this labeller, or the OutputDataType property to be static. Hopefully, the images in the directory you're reading are all the same data type, so override this field to be a data type that this function accepts. The available types are uint8, uint16 and uint32. Therefore, assuming your images were uint8 for example, do this before you run your loop:
ccl = vision.ConnectedComponentLabeler;
ccl.OutputDataType = 'uint8';
Now run your code, and it should work. Bear in mind that the input needs to be logical for this to have any meaningful output.
Minor comment
Why are you using the CVST Connected Component Labeller when the Image Processing Toolbox bwlabel function works exactly the same way? As you are using regionprops, you have access to the Image Processing Toolbox, so this should be available to you. It's much simpler to use and requires no setup: http://www.mathworks.com/help/images/ref/bwlabel.html

run time error '6' Overflow in visual basic 6.0

I am getting a run time error '6' Over Flow in vb 6
The "Overflow" error means that you are trying to put a number into a variable (or property etc), and the data type of the variable doesn't allow numbers that large.
Make sure that numbers used in calculations that are coerced into integers do not have results larger than integers.
What is the type of the data in the database?
My guess is that ADO returns it as either a String or a Decimal, and Decimal values only "fit into" a Variant in VB6.
VB6 has no syntax for a Decimal literal, however you can use something like:
CDec(111010114289#)
... inline, or declare a Const as in:
Private Const BigVal As Currency = 111010114289#
I you have to put a large number in a small variable, like C, check Remove integer bound check in project properties (if you are not compiling as PCode)

Resources