Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Co pocita fcelinspace? #10

Open
s-m-i-t-a opened this issue Aug 17, 2020 · 12 comments
Open

Co pocita fcelinspace? #10

s-m-i-t-a opened this issue Aug 17, 2020 · 12 comments
Assignees

Comments

@s-m-i-t-a
Copy link
Collaborator

def linspace(min, max, step)
    when is_number(min) and is_number(max) and is_integer(step) and min < max and 1 < step do
  delta = :erlang.abs(max - min) / (step - 1)

  Enum.reduce(1..(step - 1), [min], fn x, acc ->
    acc ++ [min + x * delta]
  end)
end

Proc je pouzit Enum.reduce/3 a pocetne narocne spojovani listu, kdyz lze pouzit Enum.map/2.

Co je vystupem teto fce, tedy co reprezentuje vraceny seznam?

@ondrej-tucek
Copy link
Collaborator

Jak v kterych pripadech zda se, viz To use or not to use the ++ operator in Elixir. Neocekavam, ze by vystupni list mel byt nejak extremne velky.

Vraci list hodnot, ktere maji stejnou vzdalenost mezi sebou, viz napr numpy.

@s-m-i-t-a
Copy link
Collaborator Author

Vubec ti nevadi, ze ten reduce dela vypocet slozitejsi, kdy mas na vstupu list hodnota a vystupem je list hodnot stejne mohutnosti a prvky jsou na sobe nezavisle?

@s-m-i-t-a
Copy link
Collaborator Author

Muzes men vysvetlit toto. Pokud pouziji tvou fci linspace a vstupem je min=0, max=10, step=5, tak dostanu [0, 2.5, 5.0, 7.5, 10.0], ale ja to chtel rozdelit na 5 stejnych dilu, jenze tam jsou jen 4 dily [0, 2.5], [2.5, 5], [5, 7.5], [7.5, 10], coz teda uzivatel bude zirat, kde ty ticky ma (bude muset zadat, ze chce step=6). step je zde dost matouci, pkud by slo o krok (step), tak bys mel mit pro tvuj vysledek step=2.5.

@ondrej-tucek
Copy link
Collaborator

Tohle uz jsem objevil vcera, ze step musi byt +1. Oki predelam to s map. Zkusim to jeste pak hodit do benchee jak se to bude moc lisit...

@s-m-i-t-a
Copy link
Collaborator Author

s-m-i-t-a commented Aug 17, 2020

Add reduce - nejde tak ani o rychlost (v pripade malych listu), ale o antipattern. Iterovat nad listem a v kazdem kroku spojovat list je fuj. V pripade reduce listu o n prvcich bude slozitost O(n*n) a v pripade map to je jen O(n).

@s-m-i-t-a
Copy link
Collaborator Author

Cekal bych, ze to api bude prirozene. Chci interval rozdelit na n stejnych casti. Ano, muze byt zavadejici slovo count, protoze neni jasne, jestli to ma byt pocet ticku nebo casti, ale vetsina lidi to chape, jako stejny pocet casti.

@ondrej-tucek
Copy link
Collaborator

ondrej-tucek commented Aug 17, 2020

No od zacatku bylo count zamysleno jako pocet tech ticku, ne dilu. linspace funguje spravne, chyba je v tom ze pri tom generovani neni count + 1. Tak nevim jaky jiny nazev pouzit aby to davalo smysl. MajorTicks.count mi smysl dava.

S tim prepisem reduce na map

  def linspace_map(min, max, step)
    when is_number(min) and is_number(max) and is_integer(step) and min < max and 1 < step do
    delta = :erlang.abs(max - min) / (step - 1)
    
    Enum.map(0..(step - 1), fn i -> min + i * delta end)
  end

mi benchee dalo pro fn i -> linspace_XXX(0, 10, i)

##### With input list Enum.to_list(3..1_000_000) #####
Name                      ips        average  deviation         median         99th %
linspace_map          44.50 M       22.47 ns   ±895.01%          16 ns          48 ns
linspace_reduce       43.34 M       23.07 ns  ±1415.96%          17 ns          54 ns

Comparison: 
linspace_map          44.50 M
linspace_reduce       43.34 M - 1.03x slower +0.60 ns


##### With input list Enum.to_list(3..10_000)  #####
Name                      ips        average  deviation         median         99th %
linspace_map          20.07 M       49.83 ns ±29224.10%          17 ns          49 ns
linspace_reduce       18.03 M       55.46 ns ±34425.83%          17 ns          56 ns

Comparison: 
linspace_map          20.07 M
linspace_reduce       18.03 M - 1.11x slower +5.63 ns


##### With small list Enum.to_list(3..100) #####
Name                      ips        average  deviation         median         99th %
linspace_reduce       22.60 M       44.25 ns ±23637.72%          16 ns          49 ns
linspace_map          21.36 M       46.82 ns ±25684.51%          17 ns          46 ns

Comparison: 
linspace_reduce       22.60 M
linspace_map          21.36 M - 1.06x slower +2.56 ns

@s-m-i-t-a
Copy link
Collaborator Author

Ohanet se ted benchmarkem je zbytecne, ted jde o to, ze to je code antipattern. Neni vubec jasne, co to dela. Druhym faktem je, ze v linspace_reduce generujes s prvnim prvkem jiz vegenerovanym [min] a tim se tam neprovadi vypocet 0 + 0 * 0, takze ten vysledek neni vuci map az tak spravedlivy. Prepis ten reduce na Enum.reduce(0..(step-1), [], fn x, acc -> acc ++ [min + x * delta] end) a muzem se o tom bavit.

@s-m-i-t-a
Copy link
Collaborator Author

Proc tady to maji takto

https://observablehq.com/@d3/axis-ticks?collection=@d3/d3-axis

ikdyz popisuji to takto:

For linear and power scales, pass axis.ticks the desired tick count.

Oni pro min=0, max=1, count=5 dostanou ocekavane [0, 0.2, 0.4, 0.6, 0.8, 1] a ne [0, 0.25, 0.5, 0.75, 1.0]?

@ondrej-tucek
Copy link
Collaborator

ondrej-tucek commented Aug 17, 2020

Oni zda se nad tim jeste delaji nejakou chytristiku,

For linear and power scales, pass axis.ticks the desired tick count. This is just a hint: these scales only generate ticks at 1-, 2-, and 5-multiples of powers of ten, so the actual number of ticks may be different. (And to be precise, the scale tries to generate count + 1 ticks rather than count ticks. See d3.ticks.)

https://observablehq.com/@d3/d3-ticks:

count is only an indication. The actual number of ticks returned depends on what is necessary to go from start to end through nicely-rounded steps.
When start or stop are themselves equal to 0, 1, 2, 5 times a power of ten, they can be included as ticks. Otherwise the ticks will start after (and end before) these values. If end < start, the ticks are ordered in decreasing order.

@s-m-i-t-a
Copy link
Collaborator Author

jj, to jsem cetl, ale je to ocekavana vec, co uzivatel chce

@ondrej-tucek
Copy link
Collaborator

Jsem to opravil, ted uz by to melo fungovat ok.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants