PID controller - intuition for when error=0 - algorithm

I have simulated a PID controller with an input parameter that affects the output, and set Kp=0.2, Kp=0.5, Kd=0 which seemed to work best the values I expect in reality.
However one thing I could not figure out is the intuition of how the controller starts when the error is 0. I, for example, my target is 2, the output is 2, and the input variable is, say, 4 - the controller would setthe next input to be 0 - although 4 is a perfect value.
Is there some way that is theoretically sound to make the first steps of the algorithm take into account some "initial guess" and not go way off at the beginning of the process?

The only state in a PID controller is the current value of the integral, and it can be helpful to set this up to a nonzero value if you have some additional information about the likely steady state error.
In practice, you may simply want to use the PID controller a few times and see what value the integral typically takes, and use that as the starting value.
If you have some additional information, such as knowing that the correct output is y for an input of x, then you can invert the formula to find the correct integral as follows:
output = input * Kp + Integral * Ki
=> y = x * Kp + Integral * Ki
=> Integral = ( y - x * Kp) / Ki

Related

Doubts regarding this pseudocode for the perceptron algorithm

I am trying to implement the perceptron algorithm above. But I have two questions:
Why do we just update w (weight) variable once? Shouldn't there be separate w variables for each Xi? Also, not sure what w = 0d means mathematically in the initialization.
What is the mathematical meaning of
yi(< xi,w >+b)
I kinda know what the meaning inside the bracket is but not sure about the yi() part.
(2) You can think of 'yi' as a function that depends on w, xi and b.
let's say for a simple example, y is a line that separates two different classes. In that case, y can be represented as y = wx+b. Now, if you use
w = 0,x = 1 and b = 0 then y = 0.
For your given algorithm, you need to update your weight w, when the output of y is less than or equal to 0.
So, if you look carefully, you are not updating w once, as it is inside an if statement which is inside a for loop.
For your algorithm, you will get n numbers of output y based on n numbers of input x for each iteration of t. Here 'i' is used for indexing both input as xi and output as yi.
So, long story short, out of n numbers of input x, you only need to update the w when the output y for the corresponding input x will be less than or equal to zero (for each iteration of t).
(1) I have already mentioned w is not updated once.
Let's say you know that any output value greater(<) than 0 is the correct answer. So if you get an output which is less than or equal to zero then there is a mistake in your algorithm and you need to fix it. This is what your algorithm is doing by updating the w when the output is not matching the desired one.
Here w is represented as a vector and it is initialized as zero.

If Random variable is a function

The basic definition of random variable is that it is a function based on random experiment.the question is that if it is a function say f then how can it take numerical values..
Suppose if we toss two coins and X be random variable relating no. of heads with (0,1,2) .For event of two heads say w....we have X(w)=2 is value of function X at w. and not of X itself..
But sometimes it is written that x is a r .v taking values 0,1,2,....
Don't it sound wrong to say function and takes values?
A random variable is a well defined function X: E -> R, whose domain E is a probability space and its codomain is (generally speaking) the set of real numbers.
Intuitively, X is some kind of metric or measurement on the elements of E.
Example 1
Let E be the set of users of Stack Overflow at a given point in time, say right now. And let X be the function that assigns their reputation to every SO user. For example, you could calculate P(X >= 5000) which is the percent of SO users with a reputation of 5000 or more.
Notice that P(X >= 5000) is nothing but a compact notation for the subset of E defined as:
{u in E | X(u) >= 5000}
meaning the subset of SO users u with a reputation of 5000 or more.
Example 2
Let E be the set of questions in SO and X the function that assigns the number of votes (at certain point in time) to each question. If you pick one question q at random, X(q) would be its number of votes and we could ask for the probability of, say, X < 0 (down-voted questions.)
Here the subset of such questions is
{q in E | X(q) < 0}
i.e., the subset of questions q having a negative vote count.
Conclusion
There is nothing random in a Random variable. The randomness is in the way we pick elements (or subsets) from its domain.
Speaking of functions - Yes, it is safe to say that a function can take certain values. Speaking of random variables and probability, the definition I know is:
A random variable assigns a numerical value to each possible outcome of a random experiment
This definition does indeed say that X (aka random variable) is a function. In your case, where it is said that X (as in function) can take values 0,1,2 is basically saying that the subset of the codomain (or even the codomain or target set itself) of function X is the set {0,1,2}, or interval
[0,2] ⊂ ℕ.

Find the reverse algorithm to go back to initial value

I have a problem and try to solve it for hours. Here is a pseudocode:
x = 30
if x > 100 then max(function_1(x), function_2(x))
elseif x > 50 then max(function_3(x), function_4(x))
elseif x > 20 then max(function_5(x), function_6(x))
elseif x < 10 then function_7(x)
else function_8(x)
This was a code I run with different values of x. Then functions are mathematical formulas. Now, I have the result of the above for each x and I want to revert and go back to x again.
I found all the reversed mathematical formulas of functions. For example for function_1(x), I have a rev_function_1(y) that will get the result and will give me the initial x.
But, since the original code has a lot of cases, plus the MAX, I am not sure how I can run one code, for every value and return the original one.
Edit: All the functions are one-to-one
Edit2: It seems that the whole function is not one-to-one while each of them individually are. As a result, I have two x for every y and I cannot revert it.
You need to study the result space (or domain) of you functions.
There exists an inverse only if each x results in a unique f(x) that cannot be obtained for any other value of x. This property is called one-to-one
Let me give you an example:
Let's say that f(1) == 8 and that also f(10) == 8.
Then you don't know if the inverse of 8 is 1 or 10.
If the function is one-to-one the inverse will be a unique value. If it is not one-to-one the inverse may be more than one value.
The next step is to figure out which inverse to call.
One way to do it is to call the inverse of all subfunctions.
For each x value you get, calculate f(x). If f(x) gets back the value you wanted to inverse, then keep that x, otherwise throw it away.
When you have gone through all values you will have one (or more) matching x value.
Edit:
Another way is to pre-compute which function that corresponds to a certain interval of output values. You can store these in a database as the tuples:
lowerbound, upperbound, inverse_function
You can then find which function to use (assuming SQL):
SELECT inverse_function FROM lookup_table
WHERE :fx > lowerbound and :fx < upperbound
:fx is the value you want to inverse.
You have an output y for each x. If two xs produce the same y then you can't undo the mapping since y could have come from either x. If no two xs produce the same y then you know it came from that y's x.
NOTE: Since a reverse algorithm is required and OP have not made mandatory to use the original functions or their corresponding reverse functions so following method can be used.
"Now, I have the result of the above for each x and I want to revert and go back to x again.". Its seems that its a case of [Key] => [Value].
//one-to-many case.
if x > 100 then max(function_1(x), function_2(x))
elseif x > 50 then max(function_3(x), function_4(x))
Above piece of code tells that multiple different inputs "x" can produce same output "y".
So you can use std::multimap if you are using C++.
Now multimap can be directly used at input output level, that is, if given a input "x" and it produces an output "y" after running all the formulas then multimap.insert(std::pair<int,int>(y,x));
Therefore, now given an output "y" you can find all the prospective input "x" which could produce an output "y" as follows:
std::pair <std::multimap<int,int>::iterator, std::multimap<int,int>::iterator> ret;
ret = multimap.equal_range(y);
for (std::multimap<int,int>::iterator it=ret.first; it!=ret.second; ++it)
std::cout << ' ' << it->second;
If the relation between input "x" and its corresponding "y" is one-to-one then, std::map can be used.
I think that this is not possible, let's take this example
function_1(x) = x - 200
function_2(x) = x - 201
function_7(x) = x - 5
then for x = 200 => y =0 and for x = 5 => y =0
So for a given value of y we can have multiple values of x
There is no solution in the general case. Think about this set of formulas:
function_1(x) { return x }
function_2(x) { return x }
function_3(x) { return x }
....
I guess it's obvious why it can't work.

Optimize values in tree where tolerance is somewhere deep in

I am currently doing some calculations with trees. Each node has 5 values I am trying to calculate and a type deciding how these values are calculated. Some calculations can be pretty complicated algorithms. All calculations within a node depend solely on the values of its child nodes, so I am doing calculations from down to top. For each node type, a value depends on different values of the childnodes. I am interested mainly in the 5 values in the root node, which depend on all values in all other nodes ofc. All this is working just fine. A node can only have 1 or 2 childnodes, and the tree usually is no deeper than 5 levels.
For some node-types, there is a tolerance; meaning some values there would not matter, see this picture, I marked those with XX. Sometimes even, some values would be in relation, like C = XX * A. Currently, these values are just set to some default values. Sometimes there would be a complicated relationship even, like multiple possible solutions of an algorithm like Newton's Method, depending on starting values.
Now there is a rating I can apply on the values of the root node. What I would like is to optimize this rating by adjusting the XX-values deep within the tree. The calculations within each node can be a range of many possible formulas and the tolerance can be one of many possible patterns, so I cannot just figure out some formula but I would need some algorithm which is very flexible. I do not know of such an algorithm. Does anyone have an idea?
/Edit: To clarify, it is unclear how many values in the tree will be free. There is not just one XX, but there may be any number of them (I guess max. 10), so my first step would be identifying these values. Also, I will be doing this on many generated trees within a time window, so speed is not unimportant as well. Thanks:)
If you have 3 input values XX, YY, and ZZ, you are searching a 3 dimension space. What you are looking to do is to apply an optimisation algorithm, or Heuristic algorithm. Your choice of algorithm is key, a cost benefit between your time and the computer's time. I am guessing that you just want to do this once.
What ever method you use, you need to understand the problem, which means to understand how your algorithm changes with different input values. Some solutions have a very nice minimum that is easy to find (e.g. using Newton's Method), some don't.
I suggest starting simple. One of the most basic is just to do an iterative search. It's slow, but it works. You need to make sure that your iteration step is not too large, such that you don't miss some sweet spots.
For XX = XXmin to XXmax
For YY = YYmin to YYmax
For ZZ = ZZmin to ZZmax
result = GetRootNodeValue(XX, YY, ZZ)
If result < best_result then
print result, XX, YY, ZZ
best_result = result
End if
End For
End For
End For
Below is another method, it's a stochastic optimisation method (uses random points to converge on the best solution), it's results are reasonable for most conditions. I have used this successfully and it's good at converging to the minimum value. This is good to use if there is no clear global minimum. You will have to configure the parameters for your problem.
' How long to search for, a larger value will result in long search time
max_depth = 20000
' Initial values
x0 = initial XX value
y0 = initial YY value
z0 = initial ZZ value
' These are the delta values, how far should the default values range
dx = 5
dy = 5
dz = 5
' Set this at a large value (assuming the best result is a small number)
best_result = inf
' Loop for a long time
For i = 1 To max_depth
' New random values near the best result
xx = x0 + dx * (Rnd() - 0.5) * (Rnd() - 0.5)
yy = y0 + dy * (Rnd() - 0.5) * (Rnd() - 0.5)
zz = y0 + dy * (Rnd() - 0.5) * (Rnd() - 0.5)
' Do the test
result = GetRootNodeValue(xx, yy, zz)
' We have found the best solution so far
If result < best_result Then
x0 = xx
y0 = yy
z0 = zz
best_result = result
End If
Print progress
Next i
There are many optimisation algorithms to choose from. Above are some very simple ones, but they may not be the best for your problem.
As another answer has pointed out, this looks like a optimization problem. You may consider using a genetic algorithm. Basically, you try to mimic the evolution process by "mating" different individuals (in your case trees) with different traits (in your case the values on the leaves) and make them survive based on an objective function (in your case, what you obtain on the root node). The algorithm can be improved by adding mutations to your populations (as in nature's evolution).

Why does Math.Log crash only inside my for loop?

I have the below code
A = 1.0
B = 0.20
N = 8.0
for i in 1..Total
t = Maxt * rand
x = A * Math.cos(t) / (Math.log(B*Math.tan(t/(2*N))))
y = A * Math.sin(t) / (Math.log(B*Math.tan(t/(2*N))))
end
If I comment out the For loop it executes fine and produces 1 of the results I want. If I don't comment out the for loop, it generates the below. I am a newbie with Ruby and am mainly curious why it only breaks when the for loop is present.
rubyfile.rb:22:in `log': Numerical argument out of domain - log (Errno::EDOM)
from rubyfile.rb:22
from rubyfile.rb:20:in `each'
from rubyfile.rb:20
Math.log represents the logarithm function, which is undefined for negative numbers. Math.tan, however, represents the tangent function, which can return negative numbers. So, if Math.tan comes out to a negative number, the Math.log will tell you that its argument is "out of domain", meaning that there is no logarithm for that number.
I'm betting the fact that your input is random means that, when you loop, you are far more likely to get that error than if you just run the script once. If you were the remove the loop then run the script multiple times, I bet you'd get that error eventually.
Find out why your math involves negative numbers when it shouldn't, and you're good to go :)
B*Math.tan(t/(2*N))) will take negative values and log is undefined for x < 0. As the error states, you're out of domain.

Resources