Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Math test

    I'm trying to find the real-valued x in (0,1) that solves this polynomial:
    \[ Nx^{N-1} - (N-1)x^N = y \] where y is in (0,1) and N is a given integer. I can get solutions using Mata's polyroots function for a given value of y:
    Code:
    mata
       c = -y, rangen(0, 0, N)', N, N-1
       polyroots(c)
    end
    But this gives me a bunch of complex solutions that fall outside my desired range. Is there a way to extract a certain restricted value from the solutions vector? I can of course look at the solutions and copy them directly, but I want to run this as part of an ado-file and so need a way to automate the process.
    Last edited by John Shannon; 10 Apr 2017, 09:10.

  • #2
    I wanted to try generating a variable drawn uniformly from the real numbers, but I found that runiform() actually has a much smaller functional range than listed in the help manual. Specifically, the manual says that runiform(a,b) can accept "a" as low as c(mindouble) and "b" as large as c(maxdouble) (i.e. +/- 8.99e+307) and has a range of a+c(epsdouble) to b-c(epsdouble). However, when I type
    Code:
    gen randtest = runiform(c(mindouble),c(maxdouble))
    sum randtest
    I see that there are zero observations.

    I was curious about what exactly the computational limits were, so I wrote up the following code to test it:
    Code:
    clear
    set obs 10000
    gen rangemin = .
    gen rangemax = .
    gen obs = .
    forval i = 10/300 {
     local a = -1e+`i'
     local b =  1e+`i'
     quietly {
      gen rangetest`i' = runiform(`a',`b')
      sum rangetest`i'
      replace rangemin = r(min) in `i'
      replace rangemax = r(max) in `i'
      replace obs   = r(N)   in `i'
      drop rangetest`i'
     }
    }
    *Show values for which runiform() fails to generate a full dataset before it stops working completely
    list obs if obs!=_N & obs!=. & obs!=0
    
    *Show values where the range of runiform() starts to degenerate
    gen log_rangemin = ln(-rangemin)/ln(10)
    gen log_rangemax = ln(rangemax)/ln(10)
    gen range = _n
    gen diff_rangemax = log_rangemax - range
    gen diff_rangemin = log_rangemin - range
    keep if log_rangemin != . & log_rangemax != 0
    list diff_rangemax range if abs(diff_rangemax) > 0.1
    list diff_rangemin range if abs(diff_rangemin) > 0.1
    I've run this a number of times, and it seems that runiform() always starts to break down at 1.00e+39 and completely breaks before 1.00e+44, i.e. it starts generating a less-than-full set of observations before generating nothing at all.

    It doesn't seem like anyone else has had this problem, but I just thought I'd document it.

    Comment


    • #3
      Usually whatever is posted here is deemed to be a trial run and just ignored, but I stumbled across this.

      I just looked at the first line. By (default) default you are generating floats, so the largest and smallest values that could fit in a double are outsize.

      A quick scan of the longer block of code suggests that nothing there can fix the first problem.. If you want doubles, you need to ask for them (unless exceptionally you have set the default numeric type to double).

      Comment

      Working...
      X