So you're looking for a regular expression feature wherein a back-reference refers not to a preceding capture group but to the result of applying a mathematical function to a preceding capture group. I'm not aware of any regex engine capable of doing this. That doesn't mean one doesn't exist; there are some pretty exotic/complex operations possible in some engines. But this definitely can't be done with Vim's RE engine.
So that's the answer. But that's not satisfying at all. Can it be done in Vim some other way? It certainly can with a custom function. "Anything" can be done that way. That's where I'd start barring anything cleaner or more elegant coming to mind first. (In real life I'd also consider farming the work out to the shell/command-line tools but this is Vim territory.) Anyways, ...
func! FindDoubled()
while search('\v^\d+ \d+$', "W")
let l = matchlist(getline("."), '\v^(\d+) (\d+)$')
if l[2] == l[1] * 2
return
endif
endwhile
echom "Not match"
endfunc
This will match 10 20
and 20 40
in your example file. By match I mean the cursor will be positioned on the match and the function will return. You can repeatedly run it until the end of the file is reached.
It's all hardcoded, though, so not very interesting. To make it more useful you might parameterize the regex and/or the math operation. Something along these lines...
func! RelatedPairSearch(patt, rel)
while search(a:patt, "W")
let l = matchlist(getline("."), a:patt)
if len(l[1]) && len(l[2]) && l[2] == eval(printf(a:rel, l[1]))
return
endif
endwhile
echom "No match"
endfunc
This takes a pattern and a string that expresses a math operation to be applied to the first submatch from the pattern. The result is compared to whatever the second submatch is. It behaves like the first function, i.e. stopping on matches and displaying a message when no more matches are found.
A call that matches the same lines as the first function might look like:
call RelatedPairSearch('\v^(\d+) (\d+)$', '%d * 2')
Out of laziness I'm using a printf token to indicate where the first capture group (submatch) value should be placed inside the expression. (There's also no input validation, checking for capture groups in the pattern, say. The idea is not to post production ready code.)
(This is really just toy code at this point but the call actually works.)