Math in Dart - working with numbers other than base 10 - dart

I was trying to do some math in something other than base 10, and wanted to get some input from the Dart community on possible directions I can take.
So, for example, suppose p = 2. Then, looking at 100 in base 2:
100 = (1 · 26
) + (1 · 25
) + (0 · 24
) + (0 · 23
) + (1 · 22
) + (0 · 21
) + (0 · 20
)
so
100 base 2 = 1100100
Add 1 to each digit and multiply the answers together:
(1 + 1)(1 + 1)(0 + 1)(0 + 1)(1 + 1)(0 + 1)(0 + 1) = 8
Try it for 3:
100 = (1 · 34
) + (0 · 33
) + (2 · 32
) + (0 · 31
) + (1 · 30
)
so
100 base 3 = 10201
(1 + 1)(0 + 1)(2 + 1)(0 + 1)(1 + 1) = 12
In Dart, I came up with the following;
https://gist.github.com/anonymous/11345381
int rows = 1000000000;
int total = 0;
for(int i = 0 ; i < rows ; i++ ){
total += i.toRadixString(7)
.split('')
.map((s) => int.parse(s) + 1)
.reduce((prev,next) => prev*next);
}
print('${total} results');
This does work, and seems to be ok for small number of rows. But for larger numbers, it is really quite slow.
As shown, I am converting an int to a string (resulting in a string representation of a number), splitting it, mapping the split characters back to ints, adding 1 to each int, and then multiplying them all together.
Am I missing something when it comes to working with numbers in Dart, other than base 10?

Going through the string seems inefficient. How about doing it directly?
int digitProduct(int n, int base) { // non-negative n and base only
int product = 1;
while (n > 0) {
int digit = n % base;
n = n ~/ base;
product *= (digit + 1);
}
return product;
}
main() {
int rows = 1000000000;
int total = 0;
for (int i = 0; i < rows; i++) {
total += digitProduct(i, 7);
}
print("${total} results");
}
Also 1000000000 is a pretty big number. If it takes a microsecond per row, it will still take ~16 minutes to complete.
Division by arbitrary bases is slow. If you hardcode the base to be 7, it'll probably be significantly faster (I expect ~90% of the time spent in digitProduct to be used on ~/ and %).

Related

Is there a more succinct way of performing the same task below? Rounding down to nearest 1 or 5mod6

var n = 27;
void main() {
while (n>=5)
if ( (n) % 3==0 && (n) % 2==0 ){
print(n-1);
break;
}
else if ( (n) % 3==0 && (n) % 2!=0 ){
print(n-2);
break;
}
else if ((n) % 3!=0 && (n) % 2==0){
print((n/6).floor()*6 +(1));
break;
}
else { n=n+1;}
}
I was looking for a way to have an input reduced to the nearest 1 or 5mod6 (for n>=5) and came up with the code above in Dart (project is in flutter). Does anyone have any better way of doing the same thing?
The result (rounded down input) will then be passed to another function.
For the current n value of 27 the console will print 25... try other values 24 maps to 23, 23 to itself, 22,21,20 to 19, 19 to itself, 18 to 17, 17 to itself, 16,15,14 to 13.....and I hope you get the idea.
I would get rid of the loop by finding the next lower multiple of 6 and then adding 1 or 5. The code ends up being shorter, and I think it expresses your intent much more clearly than code involving % 3 and % 2.
int lowerMultiple(int n, int multipleOf) =>
((n - 1) / multipleOf).floor() * multipleOf;
void main() {
var n = 27;
var m = lowerMultiple(n, 6);
print((n - m) >= 5 ? (m + 5) : (m + 1));
}
The above code should work for integers less than 5 as well, including non-positive ones.

Why does memkind and numactl improve program performance a lot?

According to the course https://www.coursera.org/learn/parallelism-ia/home/welcome, there is one example which tried to illustrate the improvement from memkind API by using hbw_posix_memalign((void**)&pixel, 64, sizeof(P)*width*height); I think this API only provides us aligned memory allocation. I do not know why this can help improve the GPflops so much as the following shows.
The part of coding is as the following. Here the memory which stores img_in is allocated by memkind API.
template<typename P>
void ApplyStencil(ImageClass<P> & img_in, ImageClass<P> & img_out) {
const int width = img_in.width;
const int height = img_in.height;
P * in = img_in.pixel;
P * out = img_out.pixel;
#pragma omp parallel for
for (int i = 1; i < height-1; i++)
#pragma omp simd
for (int j = 1; j < width-1; j++) {
P val = -in[(i-1)*width + j-1] - in[(i-1)*width + j] - in[(i-1)*width + j+1]
-in[(i )*width + j-1] + 8*in[(i )*width + j] - in[(i )*width + j+1]
-in[(i+1)*width + j-1] - in[(i+1)*width + j] - in[(i+1)*width + j+1];
val = (val < 0 ? 0 : val);
val = (val > 255 ? 255 : val);
out[i*width + j] = val;
}
}
My questions are as the follwing:
Is it only because we can use less memory operation to get our data and then we can improve the performance almost 5 times?
In terms of numaclt, based on the linux documentation, it allows us to bind the processes with specific nodes or cpus. When we use the command numactl -m 1, we can get the improvement 5 times. I not sure if the improvement comes from NUMA communication delay.

How to avoid Round-up from NormalizeDouble and OrderSend Pending Order (SELLLIMIT, BUYLIMIT) get Error -1 Invalid stops

Please advice me how to solve problem when OrderSend Pending Order ( BUYLIMIT, SELLLIMIT) got error -1 Invalid stops.
also tell me the rule of BUYLIMIT and SELLLIMIT.
the simple code like below:
`
double digit = MarketInfo(symbol,MODE_DIGITS);
POPRICE = NormalizeDouble(BBMVAL[0],digit);
TPPRICE = NormalizeDouble(POPRICE + (30*point),digit)
SLPRICE = NormalizeDouble(POPRICE - (30*point),digit)
ticket1=OrderSend(symbol,OP_BUYLIMIT,0.1, POPRICE,Slippage,SLPRICE,TPPRICE,BUYLIMIT,magic,(TimeCurrent()+(3600*2)),CLR_NONE);
Sleep(10);
while(IsTradeContextBusy()) Sleep(100);
RefreshRates();
if(ticket1 < 0)
{
SendMail
(
symbol+"-"+ IntegerToString(Period())+"-" + "FAILED-BUYLIMIT ",
symbol+"-"+ IntegerToString(Period())+"-" + "FAILED-BUYLIMIT "+"(#PO-Price:"+POPRICE+"#TP:"+TPPRICE++"#SL:"+SLPRICE+"#RespID:"+ticket1+"#Status: "+ErrorDescription(GetLastError())+")"
);
ticket1 = 0;
}
if (ticket1 > 0)
{
b_Status = 1;
SendMail
(
symbol+"-"+ IntegerToString(Period())+"-" + "SUCCESSED-BUYLIMIT ",
symbol+"-"+ IntegerToString(Period())+"-" + "SUCCESSED-BUYLIMIT "+"(#PO- Price:"+POPRICE+"#TP:"+TPPRICE+"#SL:"+SLPRICE+"#RespID:"+ticket1+"#Status: "+ErrorDescription(GetLastError())+")"
);
ticket1 = 0;
}
the objective is :
If the pair EURUSD 5-digit, How to make the SLPRICE, POPRICE, TPPRICE always with 5-digit. sometimes with 5 digit and sometime roundup with 4-digit. is it right to use NormalizeDouble ? how to avoid the roundup.
when got Failed ( tiket1 < 0 ), the error is -1 ( invalid stops), what is the real reason of this error. sometimes successed and sometime failed. what is the rules of selllimit and the buylimit.
and when got Failed, there are many emails send to email-address. how to avoid this problem too.
THank you very much.
It is perfectly okay to have a 4 digit price when 5 digit decimal is expected, but since double is a floating-point number, sometimes you don't get the exact price you might expect,
for example:
let's say you are calculating TP for a long trade, 1.10000 + 0.0020 = 1.10020(expected) but you might get something like this 1.10020001, in these cases the price level is rejected, causing errors. That is why price normalizing is important.
In some pairs, you might find that NormalizeDouble() sometimes gives false values, in those cases use the following function.
double NP(const double price)
{
double tickSize = SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_SIZE);
return (MathRound(price / tickSize) * tickSize );
}
As for getting the many emails: you can limit the number of emails per period of time.
Here I made it so that you get 1 email per new candle:
if(ticket1 < 0)
{
static datetime prevTime = 0;
if(Time[0] > prevTime)
{
SendMail
(
symbol + "-" + IntegerToString(Period()) + "-" + "FAILED-BUYLIMIT ",
symbol + "-" + IntegerToString(Period()) + "-" + "FAILED-BUYLIMIT " + "(#PO-Price:" + POPRICE + "#TP:" + TPPRICE++"#SL:" + SLPRICE + "#RespID:" + ticket1 + "#Status: " + ErrorDescription(GetLastError()) + ")"
);
prevTime = Time[0];
}
ticket1 = 0;
}

Runtime of while loop pseudocode

I have a pseudocode which I'm trying to make a detailed analysis, analyze runtime, and asymptotic analysis:
sum = 0
i = 1
while (i ≤ n){
sum = sum + i
i = 2i
}
return sum
My assignment requires that I write the cost/runtime for every line, add these together, and find a Big-Oh notation for the runtime. My analysis looks like this for the moment:
sum = 0 1
long i = 1 1
while (i ≤ n){ log n + 1
sum = sum + i n log n
i = 2i n log n
}
return sum 1
=> 2 n log n + log n + 4 O(n log n)
is this correct ? Also: should I use n^2 on the while loop instead ?
Because of integer arithmetic, the runtime is
O(floor(ln(n))+1) = O(ln(n)).
Let's step through your pseudocode. Consider the case that n = 5.
iteration# i ln(i) n
-------------------------
1 1 0 5
2 2 1 5
3 4 2 5
By inspection we see that
iteration# = ln(i)+1
So in summary:
sum = 0 // O(1)
i = 1 // O(1)
while (i ≤ n) { // O(floor(ln(n))+1)
sum = sum + i // 1 flop + 1 mem op = O(1)
i = 2i // 1 flop + 1 mem op = O(1)
}
return sum // 1 mem op = O(1)

Calculated nCr mod m (n choose r) for large values of n (10^9)

Now that CodeSprint 3 is over, I've been wondering how to solve this problem. We need to simply calculate nCr mod 142857 for large values of r and n (0<=n<=10^9 ; 0<=r<=n). I used a recursive method which goes through min(r, n-r) iterations to calculate the combination. Turns out this wasn't efficient enough. I've tried a few different methods, but they all seem to not be efficient enough. Any suggestions?
For non-prime mod, factor it (142857 = 3^3 * 11 * 13 * 37) and compute C(n,k) mod p^q for each prime factor of the mod using the general Lucas theorem, and combine them using Chinese remainder theorem.
For example, C(234, 44) mod 142857 = 6084, then
C(234, 44) mod 3^3 = 9
C(234, 44) mod 11 = 1
C(234, 44) mod 13 = 0
C(234, 44) mod 37 = 16
The Chinese Remainder theorem involves finding x such that
x = 9 mod 3^3
x = 1 mod 11
x = 0 mod 13
x = 16 mod 37
The result is x = 6084.
Example
C(234, 44) mod 3^3
First convert n, k, and n-k to base p
n = 234_10 = 22200_3
k = 44_10 = 1122_3
r = n-k = 190_10 = 21001_3
Next find the number of carries
e[i] = number of carries from i to end
e 4 3 2 1 0
1 1
r 2 1 0 0 1
k 1 1 2 2
n 2 2 2 0 0
Now create the factorial function needed for general Lucas
def f(n, p):
r = 1
for i in range(1, n+1):
if i % p != 0:
r *= i
return r
Since q = 3, you will consider only three digits of the base p representation at a time
So
f(222_3, 3)/[f(210_3, 3) * f(011_3, 3)] *
f(220_3, 3)/[f(100_3, 3) * f(112_3, 3)] *
f(200_3, 3)/[f(001_3, 3) * f(122_3, 3)] = 6719344775 / 7
Now
s = 1 if p = 2 and q >= 3 else -1
Then
p^e[0] * s * 6719344775 / 7 mod 3^3
e[0] = 2
p^e[0] = 3^2 = 9
s = -1
p^e[0] * s * 6719344775 = -60474102975
Now you have
-60474102975 / 7 mod 3^3
This is a linear congruence and can be solved with
ModularInverse(7, 3^3) = 4
4 * -60474102975 mod 27 = 9
Hence C(234, 44) mod 3^3 = 9

Resources