do someone know a command or fuction module in ABAP who allows
logarithm a variable to the base of an other variable?
You can compute it with this logic:
DATA: num TYPE i,
base TYPE i,
res TYPE float.
num = 81.
base = 3.
res = log( num ) / log( base ).
The result is 4.
Related
The OCaml manual, Chapter 2, says
a structure and is introduced by the struct…end construct, which contains an arbitrary sequence of definitions. The structure is usually given a name with the module binding.
Is there any use case for the creating a struct and not giving it a module name.
If not, then we always use
module Name =
struct
...
end
and so the struct keyword seems a bit redundant.
It's possible and even common (in my code at least) to use nameless structures. One example:
module MyStrSet =
Set.Make(struct type t = string let compare a b = compare b a end)
To expand slightly on Jeffrey's answer, an OCaml functor maps a module to another module. It doesn't care about the module's name.
Consider the following trivial example.
module type SIG =
sig
val x : int
end
module A (B : SIG) =
struct
let y = B.x * 2
end
I've defined a functor A which takes a module B that fulfills the module type SIG. Now, I could define a module Twenty_one that supplies an x value of 21, and then give that to the functor A to create module C.
module Twenty_one =
struct
let x = 21
end
module C = A (Twenty_one)
Or I could directly use an anonymous structure.
module C = A (struct let x = 21 end)
We don't even need to name SIG.
module A (B : sig val x : int end) =
struct
let y = B.x * 2
end
module C = A (struct let x = 21 end)
Strongly into opinion territory, but you may want to give these things names in your code, if it aids with reuse and expressivess.
E.g.
module Int =
struct
type t = int
let compare = compare
end
module Int_map = Map.Make (Int)
Vs.
module Int_map = Map.Make (struct type t = int let compare = compare end)
Another thing you can do with an anonymous structure, that's more relevant to recent (as of 4.08.0) OCaml, is the ability to use open with it, for a syntactically-cheap way to hide names in your namespace (until you write an interface file anyway):
open struct
type hidden_type = string
let hidden_name = 42
end
This feature is called generalized-open, and the relevant manual page for it is here.
In the code below, lv_sum_openamount should be 3.45 but the program rounds the number as 3.
I want lv_sum_openamount as 3.
How can I do that ?
DATA(lv_sum_openamount) = REDUCE dmbtr_cs( INIT sum = 0 FOR wa_amnt IN <fs_comp> NEXT sum += wa_amnt-open_amount.
LOOP AT <fs_comp> ASSIGNING <fs_comp_alv>.
TRY.
<fs_comp_alv>-pull_amount = ( <fs_pack>-reamount / lv_sum_openamount ) * <fs_comp_alv>-open_amount.
CATCH cx_sy_zerodivide.
<fs_comp_alv>-pull_amount = 0.
ENDTRY.
ENDLOOP.
The culprit is the part INIT sum = 0.
0 is an integer, so the type for sum gets automatically derived as an integer. That means that the REDUCE-loop then uses integer arithmetic, so its output is rounded down.
Try INIT sum = CONV dmbtr_cs( 0 ) instead. This will convert the literal of 0 to the type you need and in turn force sum to also get that type.
I am declaring a variable with inline declaration 50 * ( 2 / 5 ). The problem is that output result is 0 instead of expected 20.
DATA(exact_result) = 50 * ( 2 / 5 ) .
cl_demo_output=>display( exact_result ).
Can anyone suggest why the result is zero where as 50 * (2/5) = 20.
regards,
Umar Abdullah
The inline declaration assigns a data type depending on the type from the Right-Hand Side (RHS) expression. With an arithmetic expression, the compiler determines a data type based on the overall calculation type.
First, 2 and 5 are considered as type I (4 bytes integer), so the result is also of type I even if the operator is a division (integer division in that precise case).
Then, 50 is also considered as type I, and because it's used with another I-type data object (result of subexpression 2 / 5 which is of type I) the result is also of type I.
So, in your example, EXACT_RESULT is assigned the type I.
At run time, because both LHS and RHS data objects are of type I, then the calculation type is I too. Consequently, 2 / 5 equals 0.4 which is rounded to 0 because it's an integer division and the default ABAP rounding is "half up" (rounding of 0.4 gives 0, but 0.5 gives 1).
The workaround is to define explicitly the data type of EXACT_RESULT as having digits after the decimal point (DECFLOAT16, DECFLOAT34, P type with decimals, F and even C because then the calculation type is P !), because the type of the LHS will have a higher priority than the type of the RHS (I), so the calculation will be deduced from the type of the LHS variable.
DATA(exact_result) = CONV decfloat16( 50 * ( 2 / 5 ) ).
Be careful with this next solution : as I said, C leads to a calculation with type P and many decimals, so we could think this example is a good solution :
DATA(exact_result) = '50' * ( 2 / 5 ). " equals 20
But with inline declarations, a P calculation type leads to a data object of type P but with 0 digits after the decimal point, so the result is truncated with other numbers (8 instead of 50 here) :
DATA(exact_result) = '8' * ( 2 / 5 ). " rounded ! (3 instead of 3.2)
I was writing a function with user-defined types in OCaml when I encountered an error message that I don't understand.
I'm currently using the OCaml interactive toplevel and also Visual Studio Code to write my code. The strange thing is that when I run the code in Visual Studio Code, it compiles fine but encounters the error in the interactive toplevel.
The OCaml code that I am referring to is as follows:
type loc = int;;
type id = string;;
type value =
| Num of int
| Bool of bool
| Unit
| Record of (id -> loc)
;;
type memory = (loc * value) list;;
exception NotInMemory;;
let rec memory_lookup : (memory * loc) -> value
= fun (mem, l) ->
match mem with
| [] -> raise NotInMemory
| hd :: tl -> (match hd with
| (x, a) -> if x = l then a else (memory_lookup (tl, l))
)
;;
The code that I wrote is basically my rudimentary attempt at implementing/emulating looking up memory and returning corresponding values.
Here's an example input:
memory1 = [ (1, Num 1) ; (2, Bool true) ; (3, Unit) ];;
Here's the expected output:
memory_lookup (memory1, 2);;
- : value = Bool true
However, here's the actual output:
Characters: 179-180:
| (x, a) -> if x = l then "a" else (memory_lookup (tl, l)))
Error: This expression has type value/1076
but an expression was expected of type value/1104
(Just for clarification: the error is regarding character a)
Does anybody know what type value/1076 and type value/1104 mean? Also, if there is anything wrong with the code that I wrote, would anybody be kind enough to point it out?
Thank you.
This kind of error happens in the toplevel when a type is defined multiple times, and some values of the old type are left in scope. A simple example is
type t = A
let x = A;;
type t = A
let y = A;;
x = y;;
Error: This expression has type t/1012 but an expression was expected of type
t/1009
The numerical part after the type name in value/1076 is a binding time for the type value. This binding time is used as a last resort to differentiate between two different types that happens to have the same name. Thus
Error: This expression has type value/1076
but an expression was expected of type value/1104
means that the value memory1 was defined with a type value defined at time 1076, whereas the function memory_lookup expected values of the type value defined at a later date (aka at time 1104). The binding times are a bit arbitrary , so they may be replaced by simply value/1 and value/2 in OCaml 4.08 .
Is there a way to generate normally distributed series in BQ? ideally specifying the mean and sd of the distribution.
I found a way using Marsaglia polar method , but it is not ideal for I do not want polar coordinates of the distribution but to generate an array that follows the parameters specified for it to be normally distributed.
Thank you in advance.
This query gives you the euclidean coordinates of the normal distribution centred in 0. You can adjust both the mean (mean variable) or the sd (variance variable) and the x-axis values (GENERATE_ARRAY(beginning,end,step)) :
CREATE TEMPORARY FUNCTION normal(x FLOAT64)
RETURNS FLOAT64
LANGUAGE js AS """
var mean=0;
var variance=1;
var x0=1/(Math.sqrt(2*Math.PI*variance));
var x1=-Math.pow(x-mean,2)/(2*Math.pow(variance,2));
return x0*Math.pow(Math.E,x1);
""";
WITH numbers AS
(SELECT x FROM UNNEST(GENERATE_ARRAY(-10, 10,0.5)) AS x)
SELECT x, normal(x) as normal
FROM numbers;
For doing that, I used "User Defined Funtions" [1]. They are used when you want to have another SQL expression or when you want to use Java Script (as I did).
NOTE: I used the probability density function of the normal distribution, if you want to use another you'd need to change variables x0,x1 and the return (I wrote them separately so it's clearer).
Earlier answers give the probability distribution function of a normal rv. Here I modify previous answers to give a random number generated with the desired distribution, in BQ standard SQL, using the 'polar coordinates' method. The question asks not to use polar coordinates, which is an odd request, since polar coordinates are not use in the generation of the normally distributed random number.
CREATE TEMPORARY FUNCTION rnorm ( mu FLOAT64, sigma FLOAT64 ) AS
(
(select mu + sigma*(sqrt( 2*abs(
log( RAND())
)
)
)*cos( 2*ACOS(-1)*RAND())
)
)
;
select
num ,
rnorm(-1, 5.3) as RAND_NORM
FROM UNNEST(GENERATE_ARRAY(1, 17) ) AS num
The easiest way to do it in BQ is by creating a custom function:
CREATE OR REPLACE FUNCTION
`your_project.functions.normal_distribution_pdf`
(x ANY TYPE, mu ANY TYPE, sigma ANY TYPE) AS (
(
SELECT
safe_divide(1,sigma * power(2 * ACOS(-1),0.5)) * exp(-0.5 * power(safe_divide(x-mu,sigma),2))
)
);
Next you only need to apply the function:
with inputs as (
SELECT 1 as x, 0 as mu, 1 as sigma
union all
SELECT 1.5 as x, 1 as mu, 2 as sigma
union all
SELECT 2 as x , 2 as mu, 3 as sigma
)
SELECT x,
`your_project.functions.normal_distribution_pdf`(x, mu, sigma) as normal_pdf
from
inputs