+ Reply to Thread
Results 1 to 7 of 7

LINEST with an autopopulating array within VBA

Hybrid View

  1. #1
    Registered User
    Join Date
    03-22-2013
    Location
    reading, england
    MS-Off Ver
    Excel 2010
    Posts
    4

    LINEST with an autopopulating array within VBA

    Hi all,

    essentially I am trying to populate an array within a VBA code and then regress the line using the LINEST function

    Based on something I saw in one of these forums I tried the following


      Sub LinestTest()
    Dim Y As Variant, X As Variant
     
    ReDim Y(1 To 3, 1 To 1)
    ReDim X(1 To 3, 1 To 1)
     
    
    
    q = 4
    For i = 1 To 3
        Y(i, 1) = q
        q = q + 1
    Next
    
    
    Z = 4
    For i = 1 To 3
        X(i, 1) = Z
       Z = Z + 1
    Next
    
    
     
    C1 = Application.WorksheetFunction.Index(Application.WorksheetFunction.LinEst(Y, X ^ [1,2,3,4,5,6]), 1)
     
    
     
    End Sub

    however I get a mismatch error can anyone explain what is wrong with the code and what I need to do to extract the regressed coefficients (1-7)
    Last edited by grimster85; 03-22-2013 at 05:49 PM.

  2. #2
    Forum Guru
    Join Date
    04-13-2005
    Location
    North America
    MS-Off Ver
    2002/XP, 2007, 2024
    Posts
    16,345

    Re: LINEST with an autopopulating array within VBA

    This forum tends to be pretty strict about putting code inside of code tags (see the forum rules link for instructions on how to use code tags).

    This
    X ^ [1,2,3,4,5,6]
    is something VBA does not know how to do. As part of an array function, Excel knows how to take an array, raise each element to a power, and output an array based on the two input arrays. VBA, on the other hand, does not know how to do this.

    In order to do this in VBA, you need to build the entire X input matrix as a 2 dimensional array:

    x(1,1)=z(1)^1,x(1,2)=z(1)^2,x(1,3)=z(1)^3,...
    x(2,1)=z(2)^1,x(2,2)=z(2)^2,...
    ...
    Another error to note while you are testing -- you can't fit a 6th order polynomial with only 3 data points. You will need at least 7 data points to fit a 6th order polynomial.
    Quote Originally Posted by shg
    Mathematics is the native language of the natural world. Just trying to become literate.

  3. #3
    Registered User
    Join Date
    03-22-2013
    Location
    reading, england
    MS-Off Ver
    Excel 2010
    Posts
    4

    Re: LINEST with an autopopulating array within VBA

    sorry about the code I have now corrected this. I am not sure I under stand about the 2nd X array.

    I thought I was taking a set of known Y and X coordinates and regressing a curve much like what I do with that function in an excel cell. What purpose does the second X serve and should it be identical to the other X valuse?

  4. #4
    Forum Guru
    Join Date
    04-13-2005
    Location
    North America
    MS-Off Ver
    2002/XP, 2007, 2024
    Posts
    16,345

    Re: LINEST with an autopopulating array within VBA

    I'm not sure how best to explain this. Let's go back and review the LINEST function to understand how it works http://office.microsoft.com/en-us/ma...823.aspx?CTT=1

    The equation for the line is ... y = m1x1 + m2x2 + ... + b (if there are multiple ranges of x values)
    When we regress a polynomial like you are talking about, we are simply taking advantage of LINEST's ability to handle multiple independent variables. LINEST() thinks that each xi is an independent variable, we are simply creating a situation where each xi is a different function of our original x. What the A8:A48^{1,2,3,4,5,6} part of the function does is builds a matrix of values (one column for each power of x) that can be passed to the LINEST() function. (see attached sheet for an illustration).

    VBA does not know how to build the matrix for the known_x's argument the way that Excel does -- it cannot work with the "range^{array}" format like Excel. So, before we can invoke the LINEST() function from VBA, we have to build the matrix for the known_x's argument. Once that matrix is built (for a 6th order polynomial, it should be an nx6 matrix), it can be passed to the LINEST() function from VBA just fine.

    Using similar code to what you have:
    dim y(1 to 10,1 to 1), x(1 to 10, 1 to 6)
    for i=1 to 10
    y(i,1)=3+i
    x(i,1)=(3+i)^1
    x(i,2)=(3+i)^2
    ...'note that this particular data set will form a straight line and may not yield a proper 6th order polynomial
    next i
    result=application. ... .linest(y,x,1)
    Attached Files Attached Files

  5. #5
    Registered User
    Join Date
    03-22-2013
    Location
    reading, england
    MS-Off Ver
    Excel 2010
    Posts
    4

    Re: LINEST with an autopopulating array within VBA

    thanks for helping with this i really apreciate it. i will test this tonight and see if i fully understnad

    thanks again

  6. #6
    Forum Expert shg's Avatar
    Join Date
    06-20-2007
    Location
    The Great State of Texas
    MS-Off Ver
    2010, 2019
    Posts
    40,689

    Re: LINEST with an autopopulating array within VBA

    You could use either of these constructs:

        With Application
            C = .LinEst(Y, .Power(X, [{1, 2, 3, 4, 5, 6}]))
            C = .LinEst(Y, .Power(X, Array(1, 2, 3, 4, 5, 6)))
        End With
    Entia non sunt multiplicanda sine necessitate

  7. #7
    Registered User
    Join Date
    03-22-2013
    Location
    reading, england
    MS-Off Ver
    Excel 2010
    Posts
    4

    Re: LINEST with an autopopulating array within VBA

    Thank you both for helping me out and big kudos for MrShorty for helping me to understand what I was doing.

    Sub LinestTest()
    Dim y As Variant, x As Variant
     
    ReDim y(1 To 7, 1 To 1)
    ReDim x(1 To 7, 1 To 1)
     
    
    
    q = 4
    For i = 1 To 7
        y(i, 1) = q
        q = q + 1
    Next
    
     
    ' Load values of the first independent variable
    Z = 4
    For i = 1 To 7
        x(i, 1) = Z
       Z = Z + 1
    Next
    
    
     
    With Application
            C = .LinEst(y, .Power(x, Array(1, 2, 3, 4, 5, 6)))
        End With
     
        z1 = C(1)
        z2 = C(2)
        z3 = C(3)
        z4 = C(4)
        z5 = C(5)
        z6 = C(6)
        z7 = C(7)
        
        Range("A2").FormulaR1C1 = z1
        Range("A3").FormulaR1C1 = z2
        Range("A4").FormulaR1C1 = z3
        Range("A5").FormulaR1C1 = z4
        Range("A6").FormulaR1C1 = z5
        Range("A7").FormulaR1C1 = z6
        Range("A8").FormulaR1C1 = z7
     
    End Sub
    (Obviously with different equation populating the arrays)

+ Reply to Thread

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts

Search Engine Friendly URLs by vBSEO 3.6.0 RC 1