It is very possible that I dont understand the lambda logic or do I? I have dataset A2:A5 like:
1
3
6
10
If I do: =SCAN(0, A2:A5, LAMBDA(aa, bb, aa+bb)) i get:
1
4
10
20
If I do: =SCAN(0, A2:A5, LAMBDA(aa, bb, ROW(bb)-1)) I get
1
2
3
4
if I run: =SCAN(0, A2:A5, LAMBDA(aa, bb, (aa+bb)*(ROW(bb)-1))) the result is
1
8
42
208
Why there is 42 and 208 ? How this results in such values? How can it be 42 and 208 ?
Expected result is
1
8
30
80
And I can get it with:
=ArrayFormula(SCAN(0, A2:A5, LAMBDA(aa, bb, aa+bb))*(ROW(A2:A5)-1))
But not with
=SCAN(0, A2:A5, LAMBDA(aa, bb, (aa+bb)*(ROW(bb)-1)))
SCAN is a great intermediate results function. To understand how SCAN operates, you need to understand how REDUCE operates. The syntax is:
=REDUCE(initial_value, array, LAMBDA(accumulator, current_value, some_function()))
Going through =SCAN(0, A2:A5, LAMBDA(aa, bb, (aa+bb)*(ROW(bb)-1))) step by step,
A2:A5 is 1,3,6,10
Step 1:
aa = 0(initial_value)
bb = 1(current_value:A2)
Result((aa+bb)*(ROW(bb)-1)): (0+1)*(2-1)=1
Step 2:
aa = 1(accumulator(previous return value))
bb = 3(current_value:A3)
Result((aa+bb)*(ROW(bb)-1)): (1+3)*(3-1)=8
Step 3:
aa = 8(accumulator(previous return value))
bb = 6(current_value:A4)
Result((aa+bb)*(ROW(bb)-1)): (8+6)*(4-1)=42
Step 4:
aa = 42(accumulator(previous return value))
bb = 10(current_value:A5)
Result((aa+bb)*(ROW(bb)-1)): (42+10)*(5-1)=52*4=208
aa stores the result of the previous calculation, so you have:
above answers pretty much contain all so I will add only this:
you probably expected that by doing (aa+bb)*(ROW(bb)-1) you will get:
(aa+bb)
*
(ROW(bb)-1)
1
*
1
=
1
4
*
2
=
8
10
*
3
=
30
20
*
4
=
80
but that's not how it works. to get your expected result and by not using your formula where ROW is outside of SCAN:
=ArrayFormula(SCAN(0, A2:A5, LAMBDA(aa, bb, aa+bb))*(ROW(A2:A5)-1))
you would need to do:
=INDEX(MAP(SCAN(0, A2:A5, LAMBDA(aa, bb, (aa+bb))), ROW(A2:A5)-1, LAMBDA(cc, dd, cc*dd)))
where cc is the entire SCAN and dd is ROW(A2:A5)-1 eg. first do the running total and then multiplication, which is not so feasible length-wise.
or shorter but with SEQUENCE:
=MAP(SCAN(0, A2:A5, LAMBDA(aa, bb, (aa+bb))), SEQUENCE(4), LAMBDA(cc, dd, cc*dd))
Related
I have the following data
X f1 f2 f3
1 20 20/5/2 3
2 0 10/5/0 7
3 15 20/2/1 3
4 30 80/0/9 3
I want to make SUM() of all values in f2 column but it gives me an error because of the /.
How can I take each value, separately?
Plus, how to get each relative percentage of each cell in f2? For example, the first cell of f2 would be 74,07 / 18,52 / 7,41 taken from doing (20/27 - 5/27- 2/27)
use:
=INDEX(SUM(IFERROR(SPLIT(F1:F; "/"); 0)*1))
update:
=ARRAYFORMULA(IF(C1:C="";;SUBSTITUTE(FLATTEN(QUERY(TRANSPOSE(ROUND(
IFERROR(SPLIT(C1:C; "/")/MMULT(1*IFERROR(SPLIT(C1:C; "/"));
SEQUENCE(COLUMNS(SPLIT(C1:C; "/")); 1;;)^0))*100; 2));;9^9)); " "; " / ")))
Consider the following data in GAMS:
set i / 1,2,3 /
j / 1,2,3 /;
parameter stock(i,j);
stock(i,j) = 10;
Consider the following mapping:
set jagg / b1,b2 /
map2(j,jagg) / 1.b1, 2.b1, 3.b2, 4.b2 /;
I can easily mapping using:
parameter stockagg(i,jagg);
stockagg(i,jagg) = sum(map2(j,jagg),stock(i,j));
However, I don't want to map if set i is equal to set j.
That is, I want the following data as my result:
1 1 10
1 b1 10
1 b2 20
2 b1 10
2 2 10
2 b2 20
3 b1 20
3 3 10
3 b2 10
4 b1 20
4 b2 10
4 4 10
Is there an easy way to do that in GAMS?
Not sure, if I got your question completely right, but this give you the result you posted:
set i / 1,2,3,4 /
j / 1,2,3,4,b1,b2 /;
Alias(j,jj);
parameter stock(i,j);
stock(i,j) = 10;
set jagg(j) / b1,b2 /
map2(j,jj) / 1.b1, 2.b1, 3.b2, 4.b2 /;
parameter stockagg(i,j);
stockagg(i,j) = sum(map2(jj,jagg(j))$(not sameas(i,jj)),stock(i,j))$(not sameas(i,j))
+ stock(i,j) $( sameas(i,j));
display stockagg;
In the code snipped below, functions f and g are returning different values. From reading the code, you would expect them to behave the same. I am guessing it is to do with closure of v -> innerprodfn(m, v). How do I do it to get the desired behaviour where f and g return the same values.
type Mat{T<:Number}
data::Matrix{T}
end
innerprodfn{T}(m::Mat{T}, v::Array{T}) = i -> (m.data*v)[i]
innerprodfn{T}(m::Mat{T}, vv::Matrix{T}) = mapslices(v->innerprodfn(m, v), vv, 1)
m = Mat(collect(reshape(0:5, 2, 3)))
v = collect(reshape(0:11, 3, 4))
f = innerprodfn(m, v[:,1])
g = innerprodfn(m, v)[1]
m.data * v
# 10 28 46 64
# 13 40 67 94
[f(1) g(1); f(2) g(2)]
# 10 64
# 13 94
I don't have an explanation for the observed behavior, but on a recent nightly version of Julia one gets the expected result.
On 0.5, a workaround is to use a comprehension:
innerprodfn{T}(m::Mat{T}, vv::Matrix{T}) = [innerprodfn(m, vv[:,i]) for i in indices(vv, 2)]
Of course, this works on 0.6 as well.
How do i create a Set in F# with elements from 1111 to 6666 without any values being 0, 7 or higher.
E.g. [1111,1112,1113,1114,1115,1116,1121]
I'd like to make it a set.
Thanks in advance
You can use a sequence comprehension:
let values = seq {
for i in 1110 .. 10 .. 6660 do
for j in 1 .. 6 do
yield i + j
}
and create a set using Set.ofSeq e.g.
let s = Set.ofSeq values
There must be an easier way than:
let values = seq {
for a in 1000 .. 1000 .. 6000 do
for b in 100 .. 100 .. 600 do
for c in 10 .. 10 .. 60 do
for d in 1 .. 6 do
yield a + b + c + d
}
I want to make a script that takes any number, counts up to them and returns them in a format.
so like this
for i = 1,9 do
print(i)
end
will return
1
2
3
4
5
6
7
8
9
however I want it to print like this
1 2 3
4 5 6
7 8 9
and I want it to work even with things more than 9 so things like 20 would be like this
1 2 3
4 5 6
7 8 9
10 11 12
13 14 15
16 17 18
19 20
I'm sure it can be done using the string library in lua but I am not sure how to use that library.
Any help?
function f(n,per_line)
per_line = per_line or 3
for i = 1,n do
io.write(i,'\t')
if i % per_line == 0 then io.write('\n') end
end
end
f(9)
f(20)
The for loop takes an optional third step:
for i = 1, 9, 3 do
print(string.format("%d %d %d", i, i + 1, i + 2))
end
I can think of 2 ways to do this:
local NUMBER = 20
local str = {}
for i=1,NUMBER-3,3 do
table.insert(str,i.." "..i+1 .." "..i+2)
end
local left = {}
for i=NUMBER-NUMBER%3+1,NUMBER do
table.insert(left,i)
end
str = table.concat(str,"\n").."\n"..table.concat(left," ")
And another one using gsub:
local NUMBER = 20
local str = {}
for i=1,NUMBER do
str[i] = i
end
-- Makes "1 2 3 4 ..."
str = table.concat(str," ")
-- Divides it per 3 numbers
-- "%d+ %d+ %d+" matches 3 numbers divided by spaces
-- (You can replace the spaces (including in concat) with "\t")
-- The (...) capture allows us to get those numbers as %1
-- The "%s?" at the end is to remove any trailing whitespace
-- (Else each line would be "N N N " instead of "N N N")
-- (Using the '?' as the last triplet might not have a space)
-- ^ e.g. NUMBER = 6 would make it end with "4 5 6"
-- The "%1\n" just gets us our numbers back and adds a newline
str = str:gsub("(%d+ %d+ %d+)%s?","%1\n")
print(str)
I've benchmarked both code snippets. The upper one is a tiny bit faster, although the difference is almost nothing:
Benchmarked using 10000 interations
NUMBER 20 20 20 100 100
Upper 256 ms 276 ms 260 ms 1129 ms 1114 ms
Lower 284 ms 280 ms 282 ms 1266 ms 1228 ms
Use a temporary table to contain the values until you print them:
local temp = {}
local cols = 3
for i = 1,9 do
if #temp == cols then
print(table.unpack(temp))
temp = {}
end
temp[#temp + 1] = i
end
--Last minute check for leftovers
if #temp > 0 then
print(table.unpack(temp))
end
temp = nil