Exponential increase - equation

I'm smashing my head from hours trying to achieve an exponential increase. I tried with second degree equation but the result is not what i expected. Let me explain.
I have a pay per use service based on credit balance. Users can upload funds anytime to their accounts. I want to incentivize clients to upload more funds to avoid micro-payments and higher transaction fees. To make it short the more you pay, the more bonus you get. For example an user could deposit 100$ in his account in two ways:
Jack: 10 transactions 10$ each
Paul: 2 transactions 50$ each
Mark: 1 transaction of 100$
Paul should get an higher bonus than Jack but less compared to Mark. Now I'm trying with this function.
for($amount=10;$amount<=5000;$amount +=10)
{
$rate=0.005;
$bonus=exp($rate*$amount);
echo "Deposit ".$amount."$ and gain ".$bonus." bonus<br>";
}
Minimum deposit is 10$ and Maximum deposit is 5000$ that's why i loop from 10 to 5000. The problem is simple.
Deposit 10$ and gain 1.05127109638 bonus
...
Deposit 100$ and gain 1.6487212707 bonus
...
Deposit 1000$ and gain 148.413159103 bonus
...
Deposit 2500$ and gain 268337.286521 bonus
...
Deposit 5000$ and gain 72004899337.4 bonus
You get a too little for small amounts and way too much for big amounts. I've also tried with different ranges for example 10 to 100$ with a certain rate, 200 to 1000 with another (...) but of course when you deposit an amount that is near to these limits you get less bonus. It's not logical.
Deposit 1000$ and gain 54.5981500331 bonus
... here starts the next range ...
Deposit 1250$ and gain 42.5210820001 bonus
I've also tried this approach:
function foo($wanted=1000, $rangeLow=10, $rangeHigh=5000){
$increment=($rangeHigh-$rangeLow)/($wanted+1);
$r=array();
for ($i=$rangeLow+$increment;$i<$rangeHigh;$i+=$increment)
$r[]=$i;
return $r;
}
I "spread" 1000 bonus points between 10$ and 5000$ but with this I get a linear increase while I need an exponential one. Probably the solution is mixing both approaches but I don't know how to.

I think you want the pow function instead of exp
pow Returns base raised to the power of exp.
exp Returns e raised to the power of arg.
e.g.
for($amount=10;$amount<=5000;$amount +=10)
{
$rate=0.05; //adjust as needed, 0.08 makes 5000 -> about x2
$bonus=pow($amount, $rate);
echo "Deposit ".$amount."$ and gain ".$bonus." bonus<br>\n";
}
Outputs:
Deposit 10$ and gain 1.122018454302 bonus
Deposit 20$ and gain 1.1615863496415 bonus
Deposit 30$ and gain 1.1853758165593 bonus
..
Deposit 1000$ and gain 1.4125375446228 bonus
..
Deposit 5000$ and gain 1.5309059120639 bonus

Don't you just need to keep your exp function but multiply it by a value less than 1? If I've got my maths right, that should flatten the exponential curve.

I finally managed to complete this task. It's not something that you can achieve only using PHP. You also need an equation otherwise you have no controls over the increases.
In my case i have an equation of parabola with 3 points given where have to define the lowest and the highest value. I wanted to give a maximum bonus of 1000 and a minimum of 0.1 for imports from 10 to 5000$. I did it on Excel with matrix product of a matrix inversion of values. Anyway I'm not going to share the whole formula since it's too specific. I prefer to share with you the PHP-side of the story.
I wanted to "convert" my Excel formula in PHP but it took me too much time to code matrix calculations then i decided look for an existing library. Pear has a Math_Matrix package. If you don't want to recompile your webserver to get Pear, you can probably use this PHP class. I tested matrix inversions and it works.
Said that i suggest you not to use any of the above solutions unless you use matrix math frequently. It's more convenient and efficient to you calculate all necessary values on Excel or with the "old" pen and paper so that you can pass to PHP simple calculations like +, -, *, ^2 etc.

Related

Is this gas fee calculation correct?

An address consumes 20,000 gas via SSTORE.
Given is a gas price of 35 Gwei.
If I store 10,000 addresses in a map, it will cost me:
20,000 gas * 10,000 = 200,000,000 gas
200,000,000 Gas * 35 Gwei = 7 Ether.
Is the calculation correct?
If I do the same on a layer2 chain, does the whole thing cost me 7 matic for example, or is there something else I need to consider?
Your calculation is correct.
I'm assuming you want to store the values in an array instead of 10k separate storage variables. If it's a dynamic-length array, you should also consider the cost of sstore while updating a (non-zero to non-zero) value of the slot holding the array length (currently 2900 gas for each .push() function resizing the array).
You should also consider the block gas limit - a transaction costing 200M gas is not going to fit into a block on probably any network, so any miner won't mine it.
So based on your use case, you might want to change the approach. For example, if the addresses are used for validation, you might be able to store just the merkle tree root (1 value instead of the 10k) and then validate against it using the address and its merkle proof.

Confused about Rewards in David Silver Lecture 2

While watching the Reinforcement Learning course by David Silver on youtube (and the slide: Lecture 2 MDP), I found the "Reward" and "Value Function" really confusing.
I tried to understand the "given rewards" marked on the slide (P11), but I cannot figure out why it is the case. Like, the "Class 1: R = -2" but "Pub: R = +1"
why the negative reward for Class and the positive reward for Pub? why the different value?
How to calculate the reward with the Discount Factor? (P17 and P18)
I think the lack of intuition for Reinforcement Learning is the main reason why I have encountered this kind of problem...
So, I'd really appreciate it if someone can give me a little hint.
You usually set the reward and the discount such that using RL you will drive the agent to solve a task.
In the student example the goal is to pass the exam. The student can spend his time attending a class, sleeping, on Facebook or at the pub. Attending a class is something "boring", so the student doesn't see the immediate benefits of doing it. Hence the negative reward. On the contrary, going to the pub is fun and gives a positive reward. However, only by attending all 3 classes the student can pass the exam and get the big final reward.
Now the question is: how much does the student value immediate vs future rewards? The discount factor tells you that: a small discount gives more importance to immediate rewards, because future rewards just "fade" in the long run. If we use a small discount, the student may prefer to always go to the pub or to sleep. With a discount close to 0, already after one step all rewards get close to 0 as well, so at each state the student will try to maximize the immediate reward, because after that "nothing else matter".
On the contrary, high discounts (max 1) value long-term rewards more: in this case the optimal student will attend all classes and pass the exam.
Choosing the discount can be tricky, especially if there is no terminal state (in this case "sleep" is terminal), because with a discount of 1 the agent may ignore the number of steps used to reach the highest reward. For instance, if classes would give a reward of -1 instead of -2, for the agent would be the same to spend time alternating between "class" and "pub" forever and at some point to pass the exam, because with discount 1 the rewards never fade, so even after 10 years the students will still get +10 for passing the exam.
Think also of a virtual agent having to reach a goal position. With discount 1, the agent would not learn to reach it in the least amount of steps: as long as it reaches it, it's the same for him.
Beside that, there is also a numerical problem with discount 1. Since the goal is to maximize the cumulative sum of the discounted reward, if rewards are not discounted (and the horizon is infinite) the sum will not converge.
Q1) First of all you should not forget that there rewards are given by the environment. The actions taken by the agent do not have an effect on the rewards of the environment, but of course it affects the reward gained by the followed trajectory.
In the example these +1 and -2 are just funny examples :) "As a student" you get bored during the class, so the reward of it is -2, while you have fun in the pub, so the reward is +1. Don't get confused with the reasons behind these numbers, they are environment given.
Q2) Let's do the calculation for the state with the value 4.1 in "Example: State-Value Function for Student MRP (2)":
v(s) = (-2) + 0.9 * [(0.4 * 1.9) + (0.6 * 10)] = (-2) + 6.084 =~ 4.1
Here David is using the Bellman Equation for MRPs. You can find it on the same slide.

Ideal data type for currency rate in MySQL

What should I ideally use to store currency rate information in my MySQL database? Should I use:
double
decimal like (10,4)
float or
something else?
Currency rates are usually decimal numbers like 1.2362.
How precise do you need to be? I ask because the problem may go beyond the storage format of the conversion factor. For example, perhaps the rules might be to keep the factor to N decimal places, perform the multiplication (or division) to M places, then round. And the "round" might be "financial" -- 0.5 always rounds up, instead of IEEE-754, "round to nearest even".
Assuming you can afford to be off by one unit in the last place (cents or centimes or whatever), I would simply use DOUBLE.
I assume you won't be storing more than, say, 100 conversion factors, so the fact that DOUBLE occupies 8 bytes will not be an issue. If you are recording the conversion factors for every minute for the past 10 years, I would rethink this decision.
FLOAT gives you 6-7 significant digits (and takes 4 bytes); DOUBLE gives about 16. 12345 and 123.45 and 0.00012345 each have 5 "significant" digits.
For currency, itself, I think the maximum number of decimal places for any currency today is 4. That is, DECIMAL(nn, 4) should suffice for storing money.
However, that does not provide the necessary rounding.
ROUND(currency1 * factor, decimals)
where decimals is 2 for a target currency of USD and Euros (and many other currencies). As I pointed out above, this may differ from what a bank would compute by as much as one cent.
(Would you call this "opinion based"? Or something better?)

Function to dampen a value

I have a list of documents each having a relevance score for a search query. I need older documents to have their relevance score dampened, to try to introduce their date in the ranking process. I already tried fiddling with functions such as 1/(1+date_difference), but the reciprocal function is too discriminating for close recent dates.
I was thinking maybe a mathematical function with range (0..1) and domain(0..x) to amplify their score, where the x-axis is the age of a document. It's best to explain what I further need from the function by an image:
Decaying behavior is often modeled well by an exponentional function (many decaying processes in nature also follow it). You would use 2 positive parameters A and B and get
y(x) = A exp(-B x)
Since you want a y-range [0,1] set A=1. Larger B give slower decays.
If a simple 1/(1+x) decreases too quickly too soon, a sigmoid function like 1/(1+e^-x) or the error function might be better suited to your purpose. Let the current date be somewhere in the negative numbers for such a function, and you can get a value that is current for some configurable time and then decreases towards a base value.
log((x+1)-age_of_document)
Where the base of the logarithm is (x+1). Note the x is as per your diagram and is the "threshold". If the age of the document is greater than x the score goes negative. Multiply by the maximum possible score to introduce scaling.
E.g. Domain = (0,10) with a maximum score of 10: 10*(log(11-x))/log(11)
A bit late, but as thiton says, you might want to use a sigmoid function instead, since it has a "floor" value for your long tail data points. E.g.:
0.8/(1+5^(x-3)) + 0.2 - You can adjust the constants 5 and 3 to control the slope of the curve. The 0.2 is where the floor will be.

Determining edge weights given a list of walks in a graph

These questions regard a set of data with lists of tasks performed in succession and the total time required to complete them. I've been wondering whether it would be possible to determine useful things about the tasks' lengths, either as they are or with some initial guesstimation based on appropriate domain knowledge. I've come to think graph theory would be the way to approach this problem in the abstract, and have a decent basic grasp of the stuff, but I'm unable to know for certain whether I'm on the right track. Furthermore, I think it's a pretty interesting question to crack. So here we go:
Is it possible to determine the weights of edges in a directed weighted graph, given a list of walks in that graph with the lengths (summed weights) of said walks? I recognize the amount and quality of permutations on the routes taken by the walks will dictate the quality of any possible answer, but let's assume all possible walks and their lengths are given. If a definite answer isn't possible, what kind of things can be concluded about the graph? How would you arrive at those conclusions?
What if there were several similar walks with possibly differing lengths given? Can you calculate a decent average (or other illustrative measure) for each edge, given enough permutations on different routes to take? How will discounting some permutations from the available data set affect the calculation's accuracy?
Finally, what if you had a set of initial guesses as to the weights and had to refine those using the walks given? Would that improve upon your guesstimation ability, and how could you apply the extra information?
EDIT: Clarification on the difficulties of a plain linear algebraic approach. Consider the following set of walks:
a = 5
b = 4
b + c = 5
a + b + c = 8
A matrix equation with these values is unsolvable, but we'd still like to estimate the terms. There might be some helpful initial data available, such as in scenario 3, and in any case we can apply knowledge of the real world - such as that the length of a task can't be negative. I'd like to know if you have ideas on how to ensure we get reasonable estimations and that we also know what we don't know - eg. when there's not enough data to tell a from b.
Seems like an application of linear algebra.
You have a set of linear equations which you need to solve. The variables being the lengths of the tasks (or edge weights).
For instance if the tasks lengths were t1, t2, t3 for 3 tasks.
And you are given
t1 + t2 = 2 (task 1 and 2 take 2 hours)
t1 + t2 + t3 = 7 (all 3 tasks take 7 hours)
t2 + t3 = 6 (tasks 2 and 3 take 6 hours)
Solving gives t1 = 1, t2 = 1, t3 = 5.
You can use any linear algebra techniques (for eg: http://en.wikipedia.org/wiki/Gaussian_elimination) to solve these, which will tell you if there is a unique solution, no solution or an infinite number of solutions (no other possibilities are possible).
If you find that the linear equations do not have a solution, you can try adding a very small random number to some of the task weights/coefficients of the matrix and try solving it again. (I believe falls under Perturbation Theory). Matrices are notorious for radically changing behavior with small changes in the values, so this will likely give you an approximate answer reasonably quickly.
Or maybe you can try introducing some 'slack' task in each walk (i.e add more variables) and try to pick the solution to the new equations where the slack tasks satisfy some linear constraints (like 0 < s_i < 0.0001 and minimize sum of s_i), using Linear Programming Techniques.
Assume you have an unlimited number of arbitrary characters to represent each edge. (a,b,c,d etc)
w is a list of all the walks, in the form of 0,a,b,c,d,e etc. (the 0 will be explained later.)
i = 1
if #w[i] ~= 1 then
replace w[2] with the LENGTH of w[i], minus all other values in w.
repeat forever.
Example:
0,a,b,c,d,e 50
0,a,c,b,e 20
0,c,e 10
So:
a is the first. Replace all instances of "a" with 50, -b,-c,-d,-e.
New data:
50, 50
50,-b,-d, 20
0,c,e 10
And, repeat until one value is left, and you finish! Alternatively, the first number can simply be subtracted from the length of each walk.
I'd forget about graphs and treat lists of tasks as vectors - every task represented as a component with value equal to it's cost (time to complete in this case.
In tasks are in different orderes initially, that's where to use domain knowledge to bring them to a cannonical form and assign multipliers if domain knowledge tells you that the ratio of costs will be synstantially influenced by ordering / timing. Timing is implicit initial ordering but you may have to make a function of time just for adjustment factors (say drivingat lunch time vs driving at midnight). Function might be tabular/discrete. In general it's always much easier to evaluate ratios and relative biases (hardnes of doing something). You may need a functional language to do repeated rewrites of your vectors till there's nothing more that romain knowledge and rules can change.
With cannonical vectors consider just presence and absence of task (just 0|1 for this iteratioon) and look for minimal diffs - single task diffs first - that will provide estimates which small number of variables. Keep doing this recursively, be ready to back track and have a heuristing rule for goodness or quality of estimates so far. Keep track of good "rounds" that you backtraced from.
When you reach minimal irreducible state - dan't many any more diffs - all vectors have the same remaining tasks then you can do some basic statistics like variance, mean, median and look for big outliers and ways to improve initial domain knowledge based estimates that lead to cannonical form. If you finsd a lot of them and can infer new rules, take them in and start the whole process from start.
Yes, this can cost a lot :-)