In Matlab this takes my two 1x102 variables (in1 and in2) and makes one that's 2x102 (out).
out = [in1 in2]
When I try this in VB/ILnumerics - with two well-formed 1x102 inputs - the output is 2x1 with both values being 0.
I'm doing it in VB like this:
Dim out As ILArray(Of Double) = {in1, in2}
It feels like I might have to extract all of the values, put them in double arrays, and pass those back in to get the results I want. What do you think?
You have theses options:
in1.concat(in2,1);
ILMath.horzcat(in1,in2);
There is also ILMath.vertcat<T>(a,b) available.
General ILArray documentation: http://ilnumerics.net/Arrays.html
Related
I am trying to improve the performance of my code by removing any sources of type instability.
For example, I have several instances of Array{Any} declarations, which I know generally destroy performance. Here is a minimal example (greatly simplified compared to my code) of a 2D Array of LinearInterpolation objects, i.e
n,m=5,5
abstract_arr=Array{Any}(undef,n+1,m+1)
arr_x=LinRange(1,10,100)
for l in 1:n
for alpha in 1:m
abstract_arr[l,alpha]=LinearInterpolation(arr_x,alpha.*arr_x.^n)
end
end
so that typeof(abstract_arr) gives Array{Any,2}.
How can I initialize abstract_arr to avoid using Array{Any} here?
And how can I do this in general for Arrays whose entries are structures like Dicts() where the Dicts() are dictionaries of 2-tuples of Float64?
If you make a comprehension, the type will be figured out for you:
arr = [LinearInterpolation(arr_x, ;alpha.*arr_x.^n) for l in 1:n, alpha in 1:m]
isconcretetype(eltype(arr)) # true
When it can predict the type & length, it will make the right array the first time. When it cannot, it will widen or extend it as necessary. So probably some of these will be Vector{Int}, and some Vector{Union{Nothing, Int}}:
[rand()>0.8 ? nothing : 0 for i in 1:3]
[rand()>0.8 ? nothing : 0 for i in 1:3]
[rand()>0.8 ? nothing : 0 for i in 1:10]
The main trick is that you just need to know the type of the object that is returned by LinearInterpolation, and then you can specify that instead of Any when constructing the array. To determine that, let's look at the typeof one of these objects
julia> typeof(LinearInterpolation(arr_x,arr_x.^2))
Interpolations.Extrapolation{Float64, 1, ScaledInterpolation{Float64, 1, Interpolations.BSplineInterpolation{Float64, 1, Vector{Float64}, BSpline{Linear{Throw{OnGrid}}}, Tuple{Base.OneTo{Int64}}}, BSpline{Linear{Throw{OnGrid}}}, Tuple{LinRange{Float64}}}, BSpline{Linear{Throw{OnGrid}}}, Throw{Nothing}}
This gives a fairly complicated type, but we don't necessarily need to use the whole thing (though in some cases it might be more efficient to). So for instance, we can say
using Interpolations
n,m=5,5
abstract_arr=Array{Interpolations.Extrapolation}(undef,n+1,m+1)
arr_x=LinRange(1,10,100)
for l in 1:n
for alpha in 1:m
abstract_arr[l,alpha]=LinearInterpolation(arr_x,alpha.*arr_x.^n)
end
end
which gives us a result of type
julia> typeof(abstract_arr)
Matrix{Interpolations.Extrapolation} (alias for Array{Interpolations.Extrapolation, 2})
Since the return type of this LinearInterpolation does not seem to be of known size, and
julia> isbitstype(typeof(LinearInterpolation(arr_x,arr_x.^2)))
false
each assignment to this array will still trigger allocations, and consequently there actually may not be much or any performance gain from the added type stability when it comes to filling the array. Nonetheless, there may still be performance gains down the line when it comes to using values stored in this array (depending on what is subsequently done with them).
I have a use case where I would like to pass two arguments to a function generated by Function.ScalarVector (see https://learn.microsoft.com/en-us/powerquery-m/function-scalarvector).
I would like the second argument to, optionally, capture two or more columns of a table, e.g. ScalarFun([Col1], {[Col2], [Col3]}). I would expect this to pass a list of lists to the function itself. Alas, it does not.
Consider this example, if I define a function to simply capture the generated input list (which we'd normally pass on to a function doing something useful with the list) we can see that passing a list of two values and a concatenation of two values generate very different behaviour:
let
ScalarFun =
Function.ScalarVector(
type function (col as any) as any,
(t) =>
let
buf = Table.Buffer(t)
in
List.Transform(buf[col], each List.Distinct(buf[col]))
),
TestTable = Table.FromColumns(
{{"a","b","c"}, {"x","y","z"}},
{"Col2", "Col3"}
),
#"List syntax" = Table.AddColumn(
TestTable,
"List1",
each Text.Combine(List.First(ScalarFun({[Col2],[Col3]})), ";")
),
#"Concactenation syntax" = Table.AddColumn(
#"List syntax",
"List2",
each Text.Combine(ScalarFun([Col2] & [Col3]), ";")
)
in
#"Concactenation syntax"
Given this output I can see that the syntax where we combine two values into a list ScalarFun([Col1], {[Col2], [Col3]}) actually operate row by row. Concatenating two text values however works just fine (the function gets passed a list containing the entire column).
A list is just a value like any other, so I don't understand why my preferred syntax doesn't work?
Update:
It's clear to me that the function does not behave in the way I anticipated due to lazy evaluation. I see the same issue if I try to use a record. Passing a list in this rather convoluted way 'works' however:
Text.Split(Text.Combine({[Col2],[Col3]}, ";"),";")
I'm not going to post this as an answer because I don't fully understand why this (silently, without an error) breaks the intended behaviour of Function.ScalarVector.
A list of lists is not the same as concatenated lists so I don't see any reason to expect them to behave the same way.
{TestTable[Col2], TestTable[Col3]} = {{a,b,c},{x,y,z}}
TestTable[Col2] & TestTable[Col3] = {a,b,c,x,y,z}
I am trying to make an HTTP request in JMeter that contains multiple random numbers within a fixed range (specifically 0-50). With each request, I need to send out about 45 different integers, so on any given request, there are six integers within said range that are not included. Obviously {__Random()} doesn't work, as it will inevitably generate some equal values. My idea, and please bear with me because I am very new to this, was to create an array with the integers, such as:
String line = "0, 1, 2, 3, 4, 5.....";
String[] numbers = line.split(",");
and then assign them fixed variable names to include in the request. I can do this with counter with CSV data, but I'm unsure about how to do this with an array.
vars.put("VAR_" + counter, line);
VAR_1 = 1
VAR_2 = 2
and so on...
then shuffle the array (which I do not know how to do in Beanshell) and generate something like:
VAR_1 = 16
VAR_2 = 27
...
to send with the next request.
If anyone could help me with this, or suggest a simpler way, I would great appreciate it. Thanks.
To shuffle the list just use Collections.shuffle() method
Consider using JSR223 Test Elements and Groovy language instead of Beanshell as it is:
More Java compliant
Has better performance
Has built-in support of JSON, XML and some "syntax sugar" which minimises and simplifies code
Check out Groovy Is the New Black article for more details
I figured it out. It's kind of ugly and cumbersome, but fairly simple and does exactly what I needed it to do. In JSR223 PreProcessor, my code is
def list = [0,1,2,3,4,5,.....];
Collections.shuffle(list);
String VAR_1 = Integer.toString(list.getAt(0));
vars.put("VAR_1", VAR_1);
String VAR_2 = Integer.toString(list.getAt(1));
vars.put("VAR_2", VAR_2);
String VAR_3 = Integer.toString(list.getAt(2));
and so on.....
I had to input the 50 variables manually. I'm sure there was a simpler way, but I'm quite satisfied. Thanks for the suggestions.
I'm trying to create a random number generator in Lua. I found out that I can just use math.random(1,100) to randomize a number between 1 and 100 and that should be sufficient.
But I don't really understand how to use the randomize number as variables in the script.
Tried this but of course it didn't work.
$randomCorr = math.random(1,100);
http.request_batch({
{"POST", "https://store.thestore.com/priceAndOrder/selectProduct", headers={["Content-Type"]="application/json;charset=UTF-8"}, data="{\"ChoosenPhoneModelId\":4,\"PricePlanId\":\"phone\",\"CorrelationId\":\"$randomCorr\",\"DeliveryTime\":\"1 vecka\",\"$$hashKey\":\"006\"},\"ChoosenAmortization\":{\"AmortizationLength\":0,\"ChoosenDataPackage\":{\"Description\":\"6 GB\",\"PricePerMountInKr\":245,\"DataAmountInGb\":6,\"$$hashKey\":\"00W\"},\"ChoosenPriceplan\":{\"IsPostpaid\":true,\"Title\":\"Fastpris\",\"Description\":\"Fasta kostnader till fast pris\",\"MonthlyAmount\":0,\"AvailiableDataPackages\":null,\"SubscriptionBinding\":0,\"$$hashKey\":\"00K\"}}", auto_decompress=true},
{"GET", "https://store.thestore.com/api/checkout/getproduct?correlationId=$randomCorr", auto_decompress=true},
})
In Lua, you can not start a variable name with $. This is where your main issue is at. Once the $ is removed from your code, we can easily see how to refer to variables in Lua.
randomCorr = math.random(100)
print("The random number:", randomCorr)
randomCorr = math.random(100)
print("New Random Number:", randomCorr)
Also, concatenation does not work the way you are implying it into your Http array. You have to concatenate the value in using .. in Lua
Take a look at the following example:
ran = math.random(100)
data = "{\""..ran.."\"}"
print(data)
--{"14"}
The same logic can be implied into your code:
data="{\"ChoosenPhoneModelId\":4,\"PricePlanId\":\"phone\",\"CorrelationId\":\""..randomCorr.."\",\"DeliveryTime\":\"1 vecka\",\"$$hashKey\":\"006\"},\"ChoosenAmortization\":{\"AmortizationLength\":0,\"ChoosenDataPackage\":{\"Description\":\"6 GB\",\"PricePerMountInKr\":245,\"DataAmountInGb\":6,\"$$hashKey\":\"00W\"},\"ChoosenPriceplan\":{\"IsPostpaid\":true,\"Title\":\"Fastpris\",\"Description\":\"Fasta kostnader till fast pris\",\"MonthlyAmount\":0,\"AvailiableDataPackages\":null,\"SubscriptionBinding\":0,\"$$hashKey\":\"00K\"}}"
Or you can format the value in using one of the methods provided by the string library
Take a look at the following example:
ran = math.random(100)
data = "{%q}"
print(string.format(data,ran))
--{"59"}
The %q specifier will take whatever you put as input, and safely surround it with quotations
The same logic can be applied to your Http Data.
Here is a corrected version of the code snippet:
local randomCorr = math.random(1,100)
http.request_batch({
{"POST", "https://store.thestore.com/priceAndOrder/selectProduct", headers={["Content-Type"]="application/json;charset=UTF-8"}, data="{\"ChoosenPhoneModelId\":4,\"PricePlanId\":\"phone\",\"CorrelationId\":\"" .. randomCorr .. "\",\"DeliveryTime\":\"1 vecka\",\"$$hashKey\":\"006\"},\"ChoosenAmortization\":{\"AmortizationLength\":0,\"ChoosenDataPackage\":{\"Description\":\"6 GB\",\"PricePerMountInKr\":245,\"DataAmountInGb\":6,\"$$hashKey\":\"00W\"},\"ChoosenPriceplan\":{\"IsPostpaid\":true,\"Title\":\"Fastpris\",\"Description\":\"Fasta kostnader till fast pris\",\"MonthlyAmount\":0,\"AvailiableDataPackages\":null,\"SubscriptionBinding\":0,\"$$hashKey\":\"00K\"}}", auto_decompress=true},
{"GET", "https://store.thestore.com/api/checkout/getproduct?correlationId=" .. randomCorr, auto_decompress=true},
})
There is something called $$hashKey also, in the quoted string. Not sure if that is supposed to be referencing a variable or not. If it is, it also needs to be concatenated into the resulting string, using the .. operator (just like with the randomCorr variable).
Is there a more direct way to transform the type of the elements in a list than via Table.TransformColumnTypes (which would add an additional clumsy transformation step)?
Using List.Transform (List, each _ as text) for example will return errors for number values. Is there a correct syntax for performing that transformation directly on a list (aim is to use Text.Combine in order to concatenate the list's values)?
To convert a number to a text value, use Number.ToText. You can use something like this to use Text.Combine with your numeric list:
= Text.Combine(List.Transform(List, each Number.ToText(_)), "separator")