![]() |
Array Declaration Problem ??
(This is a cross-post)
Hello; I'm trying to correctly pass the range B11:C14 to the Function MyRoots() and return the results by the array function to cells I11:J13. Notice the use of ReDim. Declaring Dim a(m+1,2) As Double in Function MyRoots() would produce a compile error: "Constant expresion required", and also I couldn't declare "a" as a 2D dynamic array! I suspect the array variables declaration in the following example is the problem. The array Function MyRoots() incorrectly returns 0.0 results to cells I11:J13. cell B8::3 cell B9: myTrue cells B11:C14 numerical values cells I11:J13:: array function {=MyRoots(B11:C14, B8, B9)} Function MyRoots (a, m As Integer, polish As String) ReDim a(m + 1, 2) As Double ReDim roots(m, 2) As Double Dim j As Integer, its As Integer Dim x(2) As Double ReDim ad(m + 1, 2) As Double .......................................my code............ For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j .......................................my code............ Call Laguer (ad, j, x, its) .......................................my code............ roots(j, 1) = x(1) roots(j, 2) = x(2) .......................................my code............ MyRoots = roots End Function Sub Laguer (a, m, x, its) Dim x1(2) As Double .......................................my code............ x(1) = x1(1) x(2) = x1(2) .......................................my code............ Exit Sub End Sub Your expert help would be greatly appreciated. Regards. |
Array Declaration Problem ??
Lately I have been using a lot of GLOBAL declarations to avoid some
complications in passing my variables... I typically would declare my variable (or array) like this at the top of the module I need to use it in: Public myArray(1 To 1000, 1 To 1000) As String Also I have been declaring my arrays to an upper bound number that should accommodate any scenario (ie - 10,000 or 100,000 depending on the situation). You should also be able to use a ReDim elsewhere in your code, but I do not used that feature myself. Then I can reference it anywhere in my module (a sub routine or a function) and never have to pass a variable. I know this is not the most efficient method, but it works out pretty good for me... Just a thought... NOTE: I do not use this method for all my variable (arrays)... Just the ones I need to reference in other sub-routines or functions. Mark Ivey "monir" wrote in message ... (This is a cross-post) Hello; I'm trying to correctly pass the range B11:C14 to the Function MyRoots() and return the results by the array function to cells I11:J13. Notice the use of ReDim. Declaring Dim a(m+1,2) As Double in Function MyRoots() would produce a compile error: "Constant expresion required", and also I couldn't declare "a" as a 2D dynamic array! I suspect the array variables declaration in the following example is the problem. The array Function MyRoots() incorrectly returns 0.0 results to cells I11:J13. cell B8::3 cell B9: myTrue cells B11:C14 numerical values cells I11:J13:: array function {=MyRoots(B11:C14, B8, B9)} Function MyRoots (a, m As Integer, polish As String) ReDim a(m + 1, 2) As Double ReDim roots(m, 2) As Double Dim j As Integer, its As Integer Dim x(2) As Double ReDim ad(m + 1, 2) As Double ......................................my code............ For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j ......................................my code............ Call Laguer (ad, j, x, its) ......................................my code............ roots(j, 1) = x(1) roots(j, 2) = x(2) ......................................my code............ MyRoots = roots End Function Sub Laguer (a, m, x, its) Dim x1(2) As Double ......................................my code............ x(1) = x1(1) x(2) = x1(2) ......................................my code............ Exit Sub End Sub Your expert help would be greatly appreciated. Regards. |
Array Declaration Problem ??
I am not clear what your code is doing, especially the ,,, my code ... bits,
but your array declaration is definitely wrong. Try this Function MyRoots(a, m As Integer, polish As String) Dim a As Variant, Roots As Variant Dim ad As Variant Dim j As Integer, its As Integer Dim x(2) As Double ReDim a(m + 1, 2) ReDim Roots(m, 2) ReDim ad(m + 1, 2) For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j Call Laguer(ad, j, x, its) Roots(j, 1) = x(1) Roots(j, 2) = x(2) MyRoots = Roots End Function -- HTH Bob (there's no email, no snail mail, but somewhere should be gmail in my addy) "monir" wrote in message ... (This is a cross-post) Hello; I'm trying to correctly pass the range B11:C14 to the Function MyRoots() and return the results by the array function to cells I11:J13. Notice the use of ReDim. Declaring Dim a(m+1,2) As Double in Function MyRoots() would produce a compile error: "Constant expresion required", and also I couldn't declare "a" as a 2D dynamic array! I suspect the array variables declaration in the following example is the problem. The array Function MyRoots() incorrectly returns 0.0 results to cells I11:J13. cell B8::3 cell B9: myTrue cells B11:C14 numerical values cells I11:J13:: array function {=MyRoots(B11:C14, B8, B9)} Function MyRoots (a, m As Integer, polish As String) ReDim a(m + 1, 2) As Double ReDim roots(m, 2) As Double Dim j As Integer, its As Integer Dim x(2) As Double ReDim ad(m + 1, 2) As Double ......................................my code............ For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j ......................................my code............ Call Laguer (ad, j, x, its) ......................................my code............ roots(j, 1) = x(1) roots(j, 2) = x(2) ......................................my code............ MyRoots = roots End Function Sub Laguer (a, m, x, its) Dim x1(2) As Double ......................................my code............ x(1) = x1(1) x(2) = x1(2) ......................................my code............ Exit Sub End Sub Your expert help would be greatly appreciated. Regards. |
Array Declaration Problem ??
Hi Mark;
Thank you for your thoughts. I think the declaration statement ReDim a(m+1,2) in my sample code Function MyRoots() should be removed altogether, since the array is passing to the function as an array argument ! Now I'm getting #VALUE! results instead of 0. Using global declarations and sizing arrays to the max expected are possible workarounds, but don't you agree that having the array declarations automatically adjusted to the situation "looks" more efficient ?? Regards. "Mark Ivey" wrote: Lately I have been using a lot of GLOBAL declarations to avoid some complications in passing my variables... I typically would declare my variable (or array) like this at the top of the module I need to use it in: Public myArray(1 To 1000, 1 To 1000) As String Also I have been declaring my arrays to an upper bound number that should accommodate any scenario (ie - 10,000 or 100,000 depending on the situation). You should also be able to use a ReDim elsewhere in your code, but I do not used that feature myself. Then I can reference it anywhere in my module (a sub routine or a function) and never have to pass a variable. I know this is not the most efficient method, but it works out pretty good for me... Just a thought... NOTE: I do not use this method for all my variable (arrays)... Just the ones I need to reference in other sub-routines or functions. Mark Ivey "monir" wrote in message ... (This is a cross-post) Hello; I'm trying to correctly pass the range B11:C14 to the Function MyRoots() and return the results by the array function to cells I11:J13. Notice the use of ReDim. Declaring Dim a(m+1,2) As Double in Function MyRoots() would produce a compile error: "Constant expresion required", and also I couldn't declare "a" as a 2D dynamic array! I suspect the array variables declaration in the following example is the problem. The array Function MyRoots() incorrectly returns 0.0 results to cells I11:J13. cell B8::3 cell B9: myTrue cells B11:C14 numerical values cells I11:J13:: array function {=MyRoots(B11:C14, B8, B9)} Function MyRoots (a, m As Integer, polish As String) ReDim a(m + 1, 2) As Double ReDim roots(m, 2) As Double Dim j As Integer, its As Integer Dim x(2) As Double ReDim ad(m + 1, 2) As Double ......................................my code............ For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j ......................................my code............ Call Laguer (ad, j, x, its) ......................................my code............ roots(j, 1) = x(1) roots(j, 2) = x(2) ......................................my code............ MyRoots = roots End Function Sub Laguer (a, m, x, its) Dim x1(2) As Double ......................................my code............ x(1) = x1(1) x(2) = x1(2) ......................................my code............ Exit Sub End Sub Your expert help would be greatly appreciated. Regards. |
Array Declaration Problem ??
Hi Bob;
Thank you kindly for your prompt reply. I've tried your suggestion. Function MyRoots(a, m As Integer, polish As String) Dim a As Variant, Roots As Variant Dim ad As Variant Dim j As Integer, its As Integer Dim x(2) As Double ReDim a(m + 1, 2) ReDim Roots(m, 2) ReDim ad(m + 1, 2) ..............................my code............ For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j ..............................my code............ Call Laguer (ad, j, x, its) ..............................my code............ Roots(j, 1) = x(1) Roots(j, 2) = x(2) MyRoots = Roots End Function It produces the compile error: "Duplicate declaration in current scope" with reference to the "a" declaration in: Dim a As Variant, Roots As Variant Any suggestion ?? Regards. "Bob Phillips" wrote: I am not clear what your code is doing, especially the ,,, my code ... bits, but your array declaration is definitely wrong. Try this Function MyRoots(a, m As Integer, polish As String) Dim a As Variant, Roots As Variant Dim ad As Variant Dim j As Integer, its As Integer Dim x(2) As Double ReDim a(m + 1, 2) ReDim Roots(m, 2) ReDim ad(m + 1, 2) For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j Call Laguer(ad, j, x, its) Roots(j, 1) = x(1) Roots(j, 2) = x(2) MyRoots = Roots End Function -- HTH Bob (there's no email, no snail mail, but somewhere should be gmail in my addy) "monir" wrote in message ... (This is a cross-post) Hello; I'm trying to correctly pass the range B11:C14 to the Function MyRoots() and return the results by the array function to cells I11:J13. Notice the use of ReDim. Declaring Dim a(m+1,2) As Double in Function MyRoots() would produce a compile error: "Constant expresion required", and also I couldn't declare "a" as a 2D dynamic array! I suspect the array variables declaration in the following example is the problem. The array Function MyRoots() incorrectly returns 0.0 results to cells I11:J13. cell B8::3 cell B9: myTrue cells B11:C14 numerical values cells I11:J13:: array function {=MyRoots(B11:C14, B8, B9)} Function MyRoots (a, m As Integer, polish As String) ReDim a(m + 1, 2) As Double ReDim roots(m, 2) As Double Dim j As Integer, its As Integer Dim x(2) As Double ReDim ad(m + 1, 2) As Double ......................................my code............ For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j ......................................my code............ Call Laguer (ad, j, x, its) ......................................my code............ roots(j, 1) = x(1) roots(j, 2) = x(2) ......................................my code............ MyRoots = roots End Function Sub Laguer (a, m, x, its) Dim x1(2) As Double ......................................my code............ x(1) = x1(1) x(2) = x1(2) ......................................my code............ Exit Sub End Sub Your expert help would be greatly appreciated. Regards. |
Array Declaration Problem ??
Sorry, missed the parameter
Function MyRoots(a As Variant, m As Integer, polish As String) Dim Roots As Variant Dim ad As Variant Dim j As Integer, its As Integer Dim x(2) As Double ReDim a(m + 1, 2) ReDim Roots(m, 2) ReDim ad(m + 1, 2) ' ..............................my code............ For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j ' ..............................my code............ Call Laguer(ad, j, x, its) ' ..............................my code............ Roots(j, 1) = x(1) Roots(j, 2) = x(2) MyRoots = Roots End Function -- __________________________________ HTH Bob "monir" wrote in message ... Hi Bob; Thank you kindly for your prompt reply. I've tried your suggestion. Function MyRoots(a, m As Integer, polish As String) Dim a As Variant, Roots As Variant Dim ad As Variant Dim j As Integer, its As Integer Dim x(2) As Double ReDim a(m + 1, 2) ReDim Roots(m, 2) ReDim ad(m + 1, 2) ..............................my code............ For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j ..............................my code............ Call Laguer (ad, j, x, its) ..............................my code............ Roots(j, 1) = x(1) Roots(j, 2) = x(2) MyRoots = Roots End Function It produces the compile error: "Duplicate declaration in current scope" with reference to the "a" declaration in: Dim a As Variant, Roots As Variant Any suggestion ?? Regards. "Bob Phillips" wrote: I am not clear what your code is doing, especially the ,,, my code ... bits, but your array declaration is definitely wrong. Try this Function MyRoots(a, m As Integer, polish As String) Dim a As Variant, Roots As Variant Dim ad As Variant Dim j As Integer, its As Integer Dim x(2) As Double ReDim a(m + 1, 2) ReDim Roots(m, 2) ReDim ad(m + 1, 2) For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j Call Laguer(ad, j, x, its) Roots(j, 1) = x(1) Roots(j, 2) = x(2) MyRoots = Roots End Function -- HTH Bob (there's no email, no snail mail, but somewhere should be gmail in my addy) "monir" wrote in message ... (This is a cross-post) Hello; I'm trying to correctly pass the range B11:C14 to the Function MyRoots() and return the results by the array function to cells I11:J13. Notice the use of ReDim. Declaring Dim a(m+1,2) As Double in Function MyRoots() would produce a compile error: "Constant expresion required", and also I couldn't declare "a" as a 2D dynamic array! I suspect the array variables declaration in the following example is the problem. The array Function MyRoots() incorrectly returns 0.0 results to cells I11:J13. cell B8::3 cell B9: myTrue cells B11:C14 numerical values cells I11:J13:: array function {=MyRoots(B11:C14, B8, B9)} Function MyRoots (a, m As Integer, polish As String) ReDim a(m + 1, 2) As Double ReDim roots(m, 2) As Double Dim j As Integer, its As Integer Dim x(2) As Double ReDim ad(m + 1, 2) As Double ......................................my code............ For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j ......................................my code............ Call Laguer (ad, j, x, its) ......................................my code............ roots(j, 1) = x(1) roots(j, 2) = x(2) ......................................my code............ MyRoots = roots End Function Sub Laguer (a, m, x, its) Dim x1(2) As Double ......................................my code............ x(1) = x1(1) x(2) = x1(2) ......................................my code............ Exit Sub End Sub Your expert help would be greatly appreciated. Regards. |
Array Declaration Problem ??
Hi Bob;
Thanks again. I've done the correction: Function MyRoots (a As Variant, m As Integer, polish As String) Dim Roots As Variant Dim ad As Variant Dim j As Integer, its As Integer Dim x(2) As Double ReDim a(m + 1, 2) ReDim Roots(m, 2) ReDim ad(m + 1, 2) ' ..............................my code............ For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j ' ..............................my code............ Call Laguer (ad, j, x, its) ' ..............................my code............ Roots(j, 1) = x(1) Roots(j, 2) = x(2) MyRoots = Roots End Function The array function MyRoots() returns all zeros (same as was posted originally). It seems to me that by declaring the incoming array "a" using: ReDim a(m+1,2) it sets all elements of matrix "a" to 0.0. The Immediate Window for MyRoots() confirms that. I even tried: ReDim Preserve a(m+1,2) with no change. (If you prefer, I would be glad to post or send you the function MyRoots() and its sub Laguer() code. Total ~ 40 lines.) Regards. "Bob Phillips" wrote: Sorry, missed the parameter Function MyRoots(a As Variant, m As Integer, polish As String) Dim Roots As Variant Dim ad As Variant Dim j As Integer, its As Integer Dim x(2) As Double ReDim a(m + 1, 2) ReDim Roots(m, 2) ReDim ad(m + 1, 2) ' ..............................my code............ For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j ' ..............................my code............ Call Laguer(ad, j, x, its) ' ..............................my code............ Roots(j, 1) = x(1) Roots(j, 2) = x(2) MyRoots = Roots End Function -- __________________________________ HTH Bob "monir" wrote in message ... Hi Bob; Thank you kindly for your prompt reply. I've tried your suggestion. Function MyRoots(a, m As Integer, polish As String) Dim a As Variant, Roots As Variant Dim ad As Variant Dim j As Integer, its As Integer Dim x(2) As Double ReDim a(m + 1, 2) ReDim Roots(m, 2) ReDim ad(m + 1, 2) ..............................my code............ For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j ..............................my code............ Call Laguer (ad, j, x, its) ..............................my code............ Roots(j, 1) = x(1) Roots(j, 2) = x(2) MyRoots = Roots End Function It produces the compile error: "Duplicate declaration in current scope" with reference to the "a" declaration in: Dim a As Variant, Roots As Variant Any suggestion ?? Regards. "Bob Phillips" wrote: I am not clear what your code is doing, especially the ,,, my code ... bits, but your array declaration is definitely wrong. Try this Function MyRoots(a, m As Integer, polish As String) Dim a As Variant, Roots As Variant Dim ad As Variant Dim j As Integer, its As Integer Dim x(2) As Double ReDim a(m + 1, 2) ReDim Roots(m, 2) ReDim ad(m + 1, 2) For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j Call Laguer(ad, j, x, its) Roots(j, 1) = x(1) Roots(j, 2) = x(2) MyRoots = Roots End Function -- HTH Bob (there's no email, no snail mail, but somewhere should be gmail in my addy) "monir" wrote in message ... (This is a cross-post) Hello; I'm trying to correctly pass the range B11:C14 to the Function MyRoots() and return the results by the array function to cells I11:J13. Notice the use of ReDim. Declaring Dim a(m+1,2) As Double in Function MyRoots() would produce a compile error: "Constant expresion required", and also I couldn't declare "a" as a 2D dynamic array! I suspect the array variables declaration in the following example is the problem. The array Function MyRoots() incorrectly returns 0.0 results to cells I11:J13. cell B8::3 cell B9: myTrue cells B11:C14 numerical values cells I11:J13:: array function {=MyRoots(B11:C14, B8, B9)} Function MyRoots (a, m As Integer, polish As String) ReDim a(m + 1, 2) As Double ReDim roots(m, 2) As Double Dim j As Integer, its As Integer Dim x(2) As Double ReDim ad(m + 1, 2) As Double ......................................my code............ For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j ......................................my code............ Call Laguer (ad, j, x, its) ......................................my code............ roots(j, 1) = x(1) roots(j, 2) = x(2) ......................................my code............ MyRoots = roots End Function Sub Laguer (a, m, x, its) Dim x1(2) As Double ......................................my code............ x(1) = x1(1) x(2) = x1(2) ......................................my code............ Exit Sub End Sub Your expert help would be greatly appreciated. Regards. |
Array Declaration Problem ??
Hello;
1) It appears that the issue is a bit more difficult than I initially thought. The latest version of the procedure is provided below. It returns #VALUE! to cells I11:J13, which in all probabilities is the result of incorrect declarations of the arrays. Notice that I commented out the declaration ReDim a(m + 1, 2) in Function MyRoots(), otherwise it would re-set all elements of the incoming matrix "a" to 0.0 and the array function would return 0.0s to cells I11:J13. 2) Here's the latest version: cell B8::3 cell B9: myTrue cells B11:C14 numerical values cells I11:J13:: array function {=MyRoots(B11:C14, B8, B9)} Function MyRoots (a As Variant, m As Integer, polish As String) Dim Roots As Variant Dim ad As Variant Dim j As Integer, its As Integer Dim x(2) As Double ' ReDim a(m + 1, 2) ReDim Roots(m, 2) ReDim ad(m + 1, 2) ' ..............................my code............ For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j ' ..............................my code............ Call Laguer (ad, j, x, its) ' ..............................my code............ Roots(j, 1) = x(1) Roots(j, 2) = x(2) MyRoots = Roots End Function Sub Laguer (a, m, x, its) Dim x1(2) As Double ' .................................my code............ x(1) = x1(1) x(2) = x1(2) '.................................my code............ Exit Sub End Sub 3) The following article deals specifically with the issue at hand: http://www.cpearson.com/Excel/Passin...ningArrays.htm The difficulty in the article is two folds. First: the article deals with passing and returning multi-dimensional arrays but it is written for the experts in VBA, and second: the described procedure deals with Subroutines calling Functions, and not the other way around! The general theme in the article, however, appears to be that dynamic arrays MUST be used. But what if the function is calling the subroutine ?? 4) If it helps, I would be glad to post or email the entire Function MyRoots() and Sub Laguer() (total ~ 40 lines), together with the w/s input values and the expected returned results. Thank you kindly. "monir" wrote: Hi Bob; Thanks again. I've done the correction: Function MyRoots (a As Variant, m As Integer, polish As String) Dim Roots As Variant Dim ad As Variant Dim j As Integer, its As Integer Dim x(2) As Double ReDim a(m + 1, 2) ReDim Roots(m, 2) ReDim ad(m + 1, 2) ' ..............................my code............ For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j ' ..............................my code............ Call Laguer (ad, j, x, its) ' ..............................my code............ Roots(j, 1) = x(1) Roots(j, 2) = x(2) MyRoots = Roots End Function The array function MyRoots() returns all zeros (same as was posted originally). It seems to me that by declaring the incoming array "a" using: ReDim a(m+1,2) it sets all elements of matrix "a" to 0.0. The Immediate Window for MyRoots() confirms that. I even tried: ReDim Preserve a(m+1,2) with no change. (If you prefer, I would be glad to post or send you the function MyRoots() and its sub Laguer() code. Total ~ 40 lines.) Regards. "Bob Phillips" wrote: Sorry, missed the parameter Function MyRoots(a As Variant, m As Integer, polish As String) Dim Roots As Variant Dim ad As Variant Dim j As Integer, its As Integer Dim x(2) As Double ReDim a(m + 1, 2) ReDim Roots(m, 2) ReDim ad(m + 1, 2) ' ..............................my code............ For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j ' ..............................my code............ Call Laguer(ad, j, x, its) ' ..............................my code............ Roots(j, 1) = x(1) Roots(j, 2) = x(2) MyRoots = Roots End Function -- __________________________________ HTH Bob "monir" wrote in message ... Hi Bob; Thank you kindly for your prompt reply. I've tried your suggestion. Function MyRoots(a, m As Integer, polish As String) Dim a As Variant, Roots As Variant Dim ad As Variant Dim j As Integer, its As Integer Dim x(2) As Double ReDim a(m + 1, 2) ReDim Roots(m, 2) ReDim ad(m + 1, 2) ..............................my code............ For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j ..............................my code............ Call Laguer (ad, j, x, its) ..............................my code............ Roots(j, 1) = x(1) Roots(j, 2) = x(2) MyRoots = Roots End Function It produces the compile error: "Duplicate declaration in current scope" with reference to the "a" declaration in: Dim a As Variant, Roots As Variant Any suggestion ?? Regards. "Bob Phillips" wrote: I am not clear what your code is doing, especially the ,,, my code ... bits, but your array declaration is definitely wrong. Try this Function MyRoots(a, m As Integer, polish As String) Dim a As Variant, Roots As Variant Dim ad As Variant Dim j As Integer, its As Integer Dim x(2) As Double ReDim a(m + 1, 2) ReDim Roots(m, 2) ReDim ad(m + 1, 2) For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j Call Laguer(ad, j, x, its) Roots(j, 1) = x(1) Roots(j, 2) = x(2) MyRoots = Roots End Function -- HTH Bob (there's no email, no snail mail, but somewhere should be gmail in my addy) "monir" wrote in message ... (This is a cross-post) Hello; I'm trying to correctly pass the range B11:C14 to the Function MyRoots() and return the results by the array function to cells I11:J13. Notice the use of ReDim. Declaring Dim a(m+1,2) As Double in Function MyRoots() would produce a compile error: "Constant expresion required", and also I couldn't declare "a" as a 2D dynamic array! I suspect the array variables declaration in the following example is the problem. The array Function MyRoots() incorrectly returns 0.0 results to cells I11:J13. cell B8::3 cell B9: myTrue cells B11:C14 numerical values cells I11:J13:: array function {=MyRoots(B11:C14, B8, B9)} Function MyRoots (a, m As Integer, polish As String) ReDim a(m + 1, 2) As Double ReDim roots(m, 2) As Double Dim j As Integer, its As Integer Dim x(2) As Double ReDim ad(m + 1, 2) As Double ......................................my code............ For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j ......................................my code............ Call Laguer (ad, j, x, its) ......................................my code............ roots(j, 1) = x(1) roots(j, 2) = x(2) ......................................my code............ MyRoots = roots End Function Sub Laguer (a, m, x, its) Dim x1(2) As Double ......................................my code............ x(1) = x1(1) x(2) = x1(2) ......................................my code............ Exit Sub End Sub Your expert help would be greatly appreciated. Regards. |
Array Declaration Problem ??
4) If it helps, I would be glad to post or email the entire Function
MyRoots() and Sub Laguer() (total ~ 40 lines), together with the w/s input values and the expected returned results. I don't know about anyone else, but doing this would be helpful for me in determining if I can help you out or not. And make sure you copy/paste your function and subroutine's code (do not simply retype them); also check to make sure you post the correct expected values for the example input values you give to us. Rick |
Array Declaration Problem ??
Hello;
In summary, I'm trying to correctly pass the range B11:C14 to Function Zroots() and return the results by the array function to cells I11:J13. Here's the latest attempt which returns #VALUE! error values to cells I11:J13, most likely because of the incorrect array declarations in the procedure. I'm reasonably confident about the math since I've the same procedure working perfectly in Fortran. Work Sheet values: cell B8::3 cell B9:: myTrue cells I11:J13:: array function {=Zroots(B11:C14, B8, B9)} cell B11::-80525640.7629787 cell C11:: 0.0 cell B12::-78862.110289658 cell C12:: 0.0 cell B13::660.968663533082 cell C13:: 0.0 cell B14::1.0 cell C14:: 0.0 Expected results: cell I11::-494.480795275 cell J11:: 31.6075878057 cell I12::-494.480795275 cell J12::-31.6075878057 cell I13:: 327.992927018 cell J13:: 0.0 Procedu .................................................. ................. Option Base 1 Option Explicit Function Zroots(a As Variant, m As Integer, polish As String) As Double Dim Roots As Variant Dim ad As Variant Dim j As Integer, its As Integer Dim x(2) As Double ' ReDim a(m + 1, 2) ReDim Roots(m, 2) ReDim ad(m + 1, 2) Dim EPS As Double Dim i As Integer, jj As Integer Dim b(2) As Double, c(2) As Double EPS = 0.000001 For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j For j = m To 1 Step -1 x(1) = 0# x(2) = 0# Call Laguer(ad, j, x, its) Debug.Print "step 001, Fun Zroots " & its & " Iterations, " & Time Debug.Print " Fun Zroots, real a(" & j & ",1)= " & a(j, 1) Debug.Print " Fun Zroots, imag a(" & j & ",2)= " & a(j, 2) If Abs(x(2)) <= 2# * EPS ^ 2 * Abs(x(1)) Then x(1) = x(1): x(2) = 0# Roots(j, 1) = x(1) Roots(j, 2) = x(2) b(1) = ad(j + 1, 1) b(2) = ad(j + 1, 2) For jj = j To 1 Step -1 c(1) = ad(jj, 1) c(2) = ad(jj, 2) ad(jj, 1) = b(1) ad(jj, 2) = b(2) b(1) = x(1) * b(1) - x(2) * b(2) + c(1) b(2) = x(1) * b(2) + x(2) * b(1) + c(2) Next jj Next j If polish = "myTrue" Then For j = 1 To m x(1) = Roots(j, 1) x(2) = Roots(j, 2) Call Laguer(a, m, x, its) Roots(j, 1) = x(1) Roots(j, 2) = x(2) Next j End If For j = 2 To m x(1) = Roots(j, 1) x(2) = Roots(j, 2) For i = j - 1 To 1 Step -1 If Roots(i, 1) <= x(1) Then GoTo MyLine1 Roots(i + 1, 1) = Roots(i, 1) Roots(i + 1, 2) = Roots(i, 2) Next i i = 0 MyLine1: Roots(i + 1, 1) = x(1) Roots(i + 1, 2) = x(2) Next j Zroots = Roots End Function .................................................. ................. Sub Laguer(a, m, x, its) Dim MAXIT As Integer, MT As Integer Dim EPSS As Double Dim iter As Integer, j As Integer Dim abx As Double, abp As Double, abm As Double, myErr As Double Dim frac(8) As Double Dim dx(2) As Double, x1(2) As Double, b(2) As Double, d(2) As Double, f(2) As Double, g(2) As Double Dim h(2) As Double, sq(2) As Double, gp(2) As Double, gm(2) As Double, g2(2) As Double Dim dxx As Double, b12 As Double Dim xsq As Double, ysq As Double, r As Double, theta As Double EPSS = 0.0000002 MT = 10 MAXIT = MT * 8 frac(1) = 0.5: frac(2) = 0.25: frac(3) = 0.75: frac(4) = 0.13: frac(5) = 0.38 frac(6) = 0.62: frac(7) = 0.88: frac(8) = 1# For iter = 1 To MAXIT its = iter b(1) = a(m + 1, 1) b(2) = a(m + 1, 2) myErr = (b(1) ^ 2 + b(2) ^ 2) ^ (1 / 2) d(1) = 0# d(2) = 0# f(1) = 0# f(2) = 0# abx = (x(1) ^ 2 + x(2) ^ 2) ^ (1 / 2) For j = m To 1 Step -1 f(1) = x(1) * f(1) - x(2) * f(2) + d(1) f(2) = x(1) * f(2) + x(2) * f(1) + d(2) d(1) = x(1) * d(1) - x(2) * d(2) + b(1) d(2) = x(1) * d(2) + x(2) * d(1) + b(2) b(1) = x(1) * b(1) - x(2) * b(2) + a(j, 1) b(2) = x(1) * b(2) + x(2) * b(1) + a(j, 2) myErr = (b(1) ^ 2 + b(2) ^ 2) ^ (1 / 2) + abx * myErr Next j myErr = EPSS * myErr If (b(1) ^ 2 + b(2) ^ 2) ^ (1 / 2) <= myErr Then Debug.Print "step 002, Sub Laguer, a root: a+bi = " & x(1) & "+" & x(2) & "i" Exit Sub Else b12 = (b(1) ^ 2 + b(2) ^ 2) g(1) = (d(1) * b(1) + d(2) * b(2)) / b12 g(2) = (d(2) * b(1) - d(1) * b(2)) / b12 g2(1) = g(1) ^ 2 - g(2) ^ 2 g2(2) = 2 * g(1) * g(2) h(1) = g2(1) - 2 * (f(1) * b(1) + f(2) * b(2)) / b12 h(2) = g2(2) - 2 * (f(2) * b(1) - f(1) * b(2)) / b12 xsq = (m - 1) * (m * h(1) - g2(1)) ysq = (m - 1) * (m * h(2) - g2(2)) r = (xsq ^ 2 + ysq ^ 2) ^ (1 / 2) theta = WorksheetFunction.Atan2(xsq, ysq) sq(1) = r ^ (1 / 2) * Cos(theta / 2) sq(2) = r ^ (1 / 2) * Sin(theta / 2) gp(1) = g(1) + sq(1) gp(2) = g(2) + sq(2) gm(1) = g(1) - sq(1) gm(2) = g(2) - sq(2) abp = (gp(1) ^ 2 + gp(2) ^ 2) ^ (1 / 2) abm = (gm(1) ^ 2 + gm(2) ^ 2) ^ (1 / 2) If abp < abm Then gp(1) = gm(1): gp(2) = gm(2) If WorksheetFunction.Max(abp, abm) 0# Then dx(1) = m * gp(1) / (gp(1) ^ 2 + gp(2) ^ 2) dx(2) = -m * gp(2) / (gp(1) ^ 2 + gp(2) ^ 2) Else dxx = WorksheetFunction.Cosh(WorksheetFunction.Ln(1# + abx)) + _ WorksheetFunction.Sinh(WorksheetFunction.Ln(1# + abx)) dx(1) = dxx * Cos(CDbl(iter)) dx(2) = dxx * Sin(CDbl(iter)) End If End If x1(1) = x(1) - dx(1) x1(2) = x(2) - dx(2) If x(1) = x1(1) And x(2) = x1(2) Then Exit Sub If iter - (Int(iter / MT) * MT) < 0 Then x(1) = x1(1) x(2) = x1(2) Else x(1) = x(1) - dx(1) * frac(Int(iter / MT)) x(2) = x(2) - dx(2) * frac(Int(iter / MT)) End If Next iter MsgBox "Too many iterations in Sub Laguer. Very unusual!" Exit Sub End Sub Thank you kindly, will very much appreciate your help. "Rick Rothstein (MVP - VB)" wrote: 4) If it helps, I would be glad to post or email the entire Function MyRoots() and Sub Laguer() (total ~ 40 lines), together with the w/s input values and the expected returned results. I don't know about anyone else, but doing this would be helpful for me in determining if I can help you out or not. And make sure you copy/paste your function and subroutine's code (do not simply retype them); also check to make sure you post the correct expected values for the example input values you give to us. Rick |
Array Declaration Problem ??
Hi Dana;
Thank you for your reply. I'm reasonably confident that once the problem of "array declaration throughout" is resolved, the procedure should nicely converge and find ALL roots of any polynomial of any degree and with real or complex coefficients. The roots could be complex, real, multiples or singles. The provided numerical example is for a simple case for easy typing! I would be glad to provide the results for a polynomial of degree 10 (or 20) and its 11 (or 21) complex coefficients. Regards. "Dana DeLouis" wrote: Would you like to solve for the real root with something like this, or do you need the complex roots as well? The idea here is that it converges quickly out to 15 digits (ie 327.992927017581) Sub Demo() Dim a, b, c, g Dim n, d Dim j a = 660.968663533082 b = -78862.110289658 c = -80525640.7629787 g = 100 'guess For j = 1 To 10 Debug.Print g n = c + g * (b + g * (a + g)) d = b + g * (2 * a + 3 * g) g = g - n / d Next j End Sub Output : 100 1069.64588967573 688.909098163029 464.672823258574 358.281635836135 329.999257173504 328.002630137227 327.99292724618 327.992927017581 327.992927017581 -- HTH :) Dana DeLouis "monir" wrote in message ... Hello; In summary, I'm trying to correctly pass the range B11:C14 to Function Zroots() and return the results by the array function to cells I11:J13. Here's the latest attempt which returns #VALUE! error values to cells I11:J13, most likely because of the incorrect array declarations in the procedure. I'm reasonably confident about the math since I've the same procedure working perfectly in Fortran. Work Sheet values: cell B8::3 cell B9:: myTrue cells I11:J13:: array function {=Zroots(B11:C14, B8, B9)} cell B11::-80525640.7629787 cell C11:: 0.0 cell B12::-78862.110289658 cell C12:: 0.0 cell B13::660.968663533082 cell C13:: 0.0 cell B14::1.0 cell C14:: 0.0 Expected results: cell I11::-494.480795275 cell J11:: 31.6075878057 cell I12::-494.480795275 cell J12::-31.6075878057 cell I13:: 327.992927018 cell J13:: 0.0 Procedu .................................................. ................ Option Base 1 Option Explicit Function Zroots(a As Variant, m As Integer, polish As String) As Double Dim Roots As Variant Dim ad As Variant Dim j As Integer, its As Integer Dim x(2) As Double ' ReDim a(m + 1, 2) ReDim Roots(m, 2) ReDim ad(m + 1, 2) Dim EPS As Double Dim i As Integer, jj As Integer Dim b(2) As Double, c(2) As Double EPS = 0.000001 For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j For j = m To 1 Step -1 x(1) = 0# x(2) = 0# Call Laguer(ad, j, x, its) Debug.Print "step 001, Fun Zroots " & its & " Iterations, " & Time Debug.Print " Fun Zroots, real a(" & j & ",1)= " & a(j, 1) Debug.Print " Fun Zroots, imag a(" & j & ",2)= " & a(j, 2) If Abs(x(2)) <= 2# * EPS ^ 2 * Abs(x(1)) Then x(1) = x(1): x(2) = 0# Roots(j, 1) = x(1) Roots(j, 2) = x(2) b(1) = ad(j + 1, 1) b(2) = ad(j + 1, 2) For jj = j To 1 Step -1 c(1) = ad(jj, 1) c(2) = ad(jj, 2) ad(jj, 1) = b(1) ad(jj, 2) = b(2) b(1) = x(1) * b(1) - x(2) * b(2) + c(1) b(2) = x(1) * b(2) + x(2) * b(1) + c(2) Next jj Next j If polish = "myTrue" Then For j = 1 To m x(1) = Roots(j, 1) x(2) = Roots(j, 2) Call Laguer(a, m, x, its) Roots(j, 1) = x(1) Roots(j, 2) = x(2) Next j End If For j = 2 To m x(1) = Roots(j, 1) x(2) = Roots(j, 2) For i = j - 1 To 1 Step -1 If Roots(i, 1) <= x(1) Then GoTo MyLine1 Roots(i + 1, 1) = Roots(i, 1) Roots(i + 1, 2) = Roots(i, 2) Next i i = 0 MyLine1: Roots(i + 1, 1) = x(1) Roots(i + 1, 2) = x(2) Next j Zroots = Roots End Function .................................................. ................ Sub Laguer(a, m, x, its) Dim MAXIT As Integer, MT As Integer Dim EPSS As Double Dim iter As Integer, j As Integer Dim abx As Double, abp As Double, abm As Double, myErr As Double Dim frac(8) As Double Dim dx(2) As Double, x1(2) As Double, b(2) As Double, d(2) As Double, f(2) As Double, g(2) As Double Dim h(2) As Double, sq(2) As Double, gp(2) As Double, gm(2) As Double, g2(2) As Double Dim dxx As Double, b12 As Double Dim xsq As Double, ysq As Double, r As Double, theta As Double EPSS = 0.0000002 MT = 10 MAXIT = MT * 8 frac(1) = 0.5: frac(2) = 0.25: frac(3) = 0.75: frac(4) = 0.13: frac(5) = 0.38 frac(6) = 0.62: frac(7) = 0.88: frac(8) = 1# For iter = 1 To MAXIT its = iter b(1) = a(m + 1, 1) b(2) = a(m + 1, 2) myErr = (b(1) ^ 2 + b(2) ^ 2) ^ (1 / 2) d(1) = 0# d(2) = 0# f(1) = 0# f(2) = 0# abx = (x(1) ^ 2 + x(2) ^ 2) ^ (1 / 2) For j = m To 1 Step -1 f(1) = x(1) * f(1) - x(2) * f(2) + d(1) f(2) = x(1) * f(2) + x(2) * f(1) + d(2) d(1) = x(1) * d(1) - x(2) * d(2) + b(1) d(2) = x(1) * d(2) + x(2) * d(1) + b(2) b(1) = x(1) * b(1) - x(2) * b(2) + a(j, 1) b(2) = x(1) * b(2) + x(2) * b(1) + a(j, 2) myErr = (b(1) ^ 2 + b(2) ^ 2) ^ (1 / 2) + abx * myErr Next j myErr = EPSS * myErr If (b(1) ^ 2 + b(2) ^ 2) ^ (1 / 2) <= myErr Then Debug.Print "step 002, Sub Laguer, a root: a+bi = " & x(1) & "+" & x(2) & "i" Exit Sub Else b12 = (b(1) ^ 2 + b(2) ^ 2) g(1) = (d(1) * b(1) + d(2) * b(2)) / b12 g(2) = (d(2) * b(1) - d(1) * b(2)) / b12 g2(1) = g(1) ^ 2 - g(2) ^ 2 g2(2) = 2 * g(1) * g(2) h(1) = g2(1) - 2 * (f(1) * b(1) + f(2) * b(2)) / b12 h(2) = g2(2) - 2 * (f(2) * b(1) - f(1) * b(2)) / b12 xsq = (m - 1) * (m * h(1) - g2(1)) ysq = (m - 1) * (m * h(2) - g2(2)) r = (xsq ^ 2 + ysq ^ 2) ^ (1 / 2) theta = WorksheetFunction.Atan2(xsq, ysq) sq(1) = r ^ (1 / 2) * Cos(theta / 2) sq(2) = r ^ (1 / 2) * Sin(theta / 2) gp(1) = g(1) + sq(1) gp(2) = g(2) + sq(2) gm(1) = g(1) - sq(1) gm(2) = g(2) - sq(2) abp = (gp(1) ^ 2 + gp(2) ^ 2) ^ (1 / 2) abm = (gm(1) ^ 2 + gm(2) ^ 2) ^ (1 / 2) If abp < abm Then gp(1) = gm(1): gp(2) = gm(2) If WorksheetFunction.Max(abp, abm) 0# Then dx(1) = m * gp(1) / (gp(1) ^ 2 + gp(2) ^ 2) dx(2) = -m * gp(2) / (gp(1) ^ 2 + gp(2) ^ 2) Else dxx = WorksheetFunction.Cosh(WorksheetFunction.Ln(1# + abx)) + _ WorksheetFunction.Sinh(WorksheetFunction.Ln(1# + abx)) dx(1) = dxx * Cos(CDbl(iter)) dx(2) = dxx * Sin(CDbl(iter)) End If End If x1(1) = x(1) - dx(1) x1(2) = x(2) - dx(2) If x(1) = x1(1) And x(2) = x1(2) Then Exit Sub If iter - (Int(iter / MT) * MT) < 0 Then x(1) = x1(1) x(2) = x1(2) Else x(1) = x(1) - dx(1) * frac(Int(iter / MT)) x(2) = x(2) - dx(2) * frac(Int(iter / MT)) End If Next iter MsgBox "Too many iterations in Sub Laguer. Very unusual!" Exit Sub End Sub Thank you kindly, will very much appreciate your help. "Rick Rothstein (MVP - VB)" wrote: 4) If it helps, I would be glad to post or email the entire Function MyRoots() and Sub Laguer() (total ~ 40 lines), together with the w/s input values and the expected returned results. I don't know about anyone else, but doing this would be helpful for me in determining if I can help you out or not. And make sure you copy/paste your function and subroutine's code (do not simply retype them); also check to make sure you post the correct expected values for the example input values you give to us. Rick |
Array Declaration Problem ??
Hi Dana;
1) If you re-examine my recently posted entire code (with sample w/s input and expected returned results, 6/23/2008 8:20 AM PST), you will notice that the declaration ReDim a(m+1,2) was commented out in Function Zroots(). 2) Keep in mind that I'm trying to (simply) pass the range B11:C14 to Function Zroots() and return the results by the array function to cells I11:J13. The main procedure is the Function Zroots() which calls Sub Laguer(). 3) I've also tried the following with no avail, the array function Zroots() still returns #VALUE!: (see items 4, 5, 6 below) Function Zroots(a As Range, m As Integer, polish As String) As Variant() Dim j As Integer, its As Integer Dim ad As Variant Dim x(2) As Double ' ReDim a(m + 1, 2) Dim Roots() As Variant ReDim ad(m + 1, 2) ............................my code1........... For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j For j = m To 1 Step -1 x(1) = 0# x(2) = 0# Call Laguer (ad, j, x, its) ' ............................my code2........... Next j ' ............................my code3........... Zroots = Roots End Function 4) Could it be that the concept of calling a subroutine from within a function is the problem here ?? I don't recall ever using such procedure, but I could be wrong. It's always the other way around, where the subroutine is the primary procedure calling the UDF. 5) Interestingly enough, the MS ref. book: "Microsoft Excel 2000 VBA Fundamentals", Microsoft Press, page 187, reads: "NOTE: A function used in a worksheet cell can include only those actions that can be executed while Excel is recalculating a worksheet. Actions such as opening files or displaying message boxes can be included in functions that are called from macros, if you include them (or similar) in a function that's called from a worksheet, the function simply returns the #VALUE! error value." 6) One may interpret the above MS Note to mean for example that calling Sub Laguer() from Function Zroots() "used in a w/s cell" IS NOT an "action" that can be "executed while Excel is recalculating a worksheet" and "the function simply returns the #VALUE! error value.". Or, is it and I'm misinterpreting the MS Note ?? Any thoughts ?? Kind regards. "Dana DeLouis" wrote: It seems to me that by declaring the incoming array "a" using: ReDim a(m+1,2) it sets all elements of matrix "a" to 0.0. The Immediate Window for MyRoots() confirms that. I even tried: ReDim Preserve a(m+1,2) with no change. Hi. I'm looking at ReDim a(m+1,2) I may be wrong, but I think you could skip this procedure because it looks like you are loading it into ad() Anyway, just for discussion, you can only "ReDim Preserve" the last index. Here is a workaround to show you one idea. Enter on a worksheet the function "MyRoots() and select a 4 Row*2 Column as the input range. Then step thru this code. The Input is a range, and the first thing we do is clean it up and only use the values. Function MyRoots(Rng) Dim A 'Just use values 'A is 4 * 2 A = Rng.Value With WorksheetFunction 'A is now 2 * 4 A = .Transpose(A) 'Redim last index to 5 ReDim Preserve A(1 To 2, 1 To 5) 'put back to 5 * 2 A = .Transpose(A) End With End Function Anyway, hope this helps a little. -- Dana DeLouis "monir" wrote in message ... Hi Bob; Thanks again. I've done the correction: Function MyRoots (a As Variant, m As Integer, polish As String) Dim Roots As Variant Dim ad As Variant Dim j As Integer, its As Integer Dim x(2) As Double ReDim a(m + 1, 2) ReDim Roots(m, 2) ReDim ad(m + 1, 2) ' ..............................my code............ For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j ' ..............................my code............ Call Laguer (ad, j, x, its) ' ..............................my code............ Roots(j, 1) = x(1) Roots(j, 2) = x(2) MyRoots = Roots End Function The array function MyRoots() returns all zeros (same as was posted originally). It seems to me that by declaring the incoming array "a" using: ReDim a(m+1,2) it sets all elements of matrix "a" to 0.0. The Immediate Window for MyRoots() confirms that. I even tried: ReDim Preserve a(m+1,2) with no change. (If you prefer, I would be glad to post or send you the function MyRoots() and its sub Laguer() code. Total ~ 40 lines.) Regards. "Bob Phillips" wrote: Sorry, missed the parameter Function MyRoots(a As Variant, m As Integer, polish As String) Dim Roots As Variant Dim ad As Variant Dim j As Integer, its As Integer Dim x(2) As Double ReDim a(m + 1, 2) ReDim Roots(m, 2) ReDim ad(m + 1, 2) ' ..............................my code............ For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j ' ..............................my code............ Call Laguer(ad, j, x, its) ' ..............................my code............ Roots(j, 1) = x(1) Roots(j, 2) = x(2) MyRoots = Roots End Function -- __________________________________ HTH Bob "monir" wrote in message ... Hi Bob; Thank you kindly for your prompt reply. I've tried your suggestion. Function MyRoots(a, m As Integer, polish As String) Dim a As Variant, Roots As Variant Dim ad As Variant Dim j As Integer, its As Integer Dim x(2) As Double ReDim a(m + 1, 2) ReDim Roots(m, 2) ReDim ad(m + 1, 2) ..............................my code............ For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j ..............................my code............ Call Laguer (ad, j, x, its) ..............................my code............ Roots(j, 1) = x(1) Roots(j, 2) = x(2) MyRoots = Roots End Function It produces the compile error: "Duplicate declaration in current scope" with reference to the "a" declaration in: Dim a As Variant, Roots As Variant Any suggestion ?? Regards. "Bob Phillips" wrote: I am not clear what your code is doing, especially the ,,, my code ... bits, but your array declaration is definitely wrong. Try this Function MyRoots(a, m As Integer, polish As String) Dim a As Variant, Roots As Variant Dim ad As Variant Dim j As Integer, its As Integer Dim x(2) As Double ReDim a(m + 1, 2) ReDim Roots(m, 2) ReDim ad(m + 1, 2) For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j Call Laguer(ad, j, x, its) Roots(j, 1) = x(1) Roots(j, 2) = x(2) MyRoots = Roots End Function -- HTH Bob (there's no email, no snail mail, but somewhere should be gmail in my addy) "monir" wrote in message ... (This is a cross-post) Hello; I'm trying to correctly pass the range B11:C14 to the Function MyRoots() and return the results by the array function to cells I11:J13. Notice the use of ReDim. Declaring Dim a(m+1,2) As Double in Function MyRoots() would produce a compile error: "Constant expresion required", and also I couldn't declare "a" as a 2D dynamic array! I suspect the array variables declaration in the following example is the problem. The array Function MyRoots() incorrectly returns 0.0 results to cells I11:J13. cell B8::3 cell B9: myTrue cells B11:C14 numerical values cells I11:J13:: array function {=MyRoots(B11:C14, B8, B9)} Function MyRoots (a, m As Integer, polish As String) ReDim a(m + 1, 2) As Double ReDim roots(m, 2) As Double Dim j As Integer, its As Integer Dim x(2) As Double ReDim ad(m + 1, 2) As Double ......................................my code............ For j = 1 To m + 1 ad(j, 1) = a(j, 1) ad(j, 2) = a(j, 2) Next j ......................................my code............ Call Laguer (ad, j, x, its) ......................................my code............ roots(j, 1) = x(1) roots(j, 2) = x(2) ......................................my code............ MyRoots = roots End Function Sub Laguer (a, m, x, its) Dim x1(2) As Double ......................................my code............ x(1) = x1(1) x(2) = x1(2) ......................................my code............ Exit Sub End Sub Your expert help would be greatly appreciated. Regards. |
Array Declaration Problem ??
Hi. I think I've copied your code & data correctly, but I keep getting the message ""Too many iterations..."
and them the program aborts near the end with Atan2(0,0) (thus causing an error) Feel free to send my your workbook. I'd be glad to take a look at it. Do you have a reference for the code? -- Dana DeLouis <snip |
Array Declaration Problem ??
Hi Dana;
Thank you once again for your continuing help. 1) Your finding: " ... the program aborts near the end with atan2(0,0) ... thus causing an error" That's a very surprising result and of utmost importance and crucial if it's true!! Did you actually encounter atan2(0,0) by running my procedure as is ?? How did you find error ?? I've never encountered "0,0" as arguments of the arctangent albeit I've run my code 100s of times and printed the intermediate values of almost all the variables. The algorithm should converge and return results before evaluating atan2(0,0). 2) Did you get the "... too many iterations ... " message and the #DIV/0! error value for the same run ?? I'm very anxious to find out the circumstances. Kind regards. "Dana DeLouis" wrote: Hi. I think I've copied your code & data correctly, but I keep getting the message ""Too many iterations..." and them the program aborts near the end with Atan2(0,0) (thus causing an error) Feel free to send my your workbook. I'd be glad to take a look at it. Do you have a reference for the code? -- Dana DeLouis <snip |
Array Declaration Problem ??
Hi Dana;
I couldn't access the link, but it most likely refers to my other post! Your idea is excellent and NEW. I selected the vba ref atpvbaen.xls and tried your demo (copy/paste). It produces Run-time error '438': Object doesn't support this property or method" and the statement: c = .Complex(3, 4) is highlighted. Is there something else beside the ref. atpvbaen.xls ?? (I'm using XL 2003, Win XP) Regards. "Dana DeLouis" wrote: As a side note, I noticed in the thread at: http://www.mrexcel.com/forum/printth...dc8769d9015ff0 5c420&t=322333 that near the end of the thread they mention it was not possible to translate the Fortran version directly because vba can not use Complex functions. Well, that's not entirely true. If one sets a vba reference to atpvbaen, then it is possible to do stuff like this. This returns the correct answer of 5. Sub Demo() Dim c As String With WorksheetFunction c = .Complex(3, 4) MsgBox .ImAbs(c) End With End Sub -- HTH :) Dana DeLouis "Dana DeLouis" wrote in message ... Hi. I think I've copied your code & data correctly, but I keep getting the message ""Too many iterations..." and them the program aborts near the end with Atan2(0,0) (thus causing an error) Feel free to send my your workbook. I'd be glad to take a look at it. Do you have a reference for the code? -- Dana DeLouis <snip |
Array Declaration Problem ??
Hi;
1) It seems that after setting the ref. in VBA to atpbaen.xls your Demo works fine without the WorkSheetFunction object and the With structu Sub Demo() Dim c As String c = complex(3, 4) MsgBox ImAbs(c) End Sub 2) Is this a general rule ?? ... i.e.; if one sets the ref. to atpbaen, then one should be able to use any XL w/s function in VBA ?? 3) Or, the atp ref. only allows the direct use (not through the WorkSheetFunction object) of those listed under: VBA Help::"Using Microsoft Excel Worksheet Functions in Visual Basic":: "List of Worksheet Functions Available to Visual Basic" Would appreciate your comments. Thank you. "monir" wrote: Hi Dana; I couldn't access the link, but it most likely refers to my other post! Your idea is excellent and NEW. I selected the vba ref atpvbaen.xls and tried your demo (copy/paste). It produces Run-time error '438': Object doesn't support this property or method" and the statement: c = .Complex(3, 4) is highlighted. Is there something else beside the ref. atpvbaen.xls ?? (I'm using XL 2003, Win XP) Regards. "Dana DeLouis" wrote: As a side note, I noticed in the thread at: http://www.mrexcel.com/forum/printth...dc8769d9015ff0 5c420&t=322333 that near the end of the thread they mention it was not possible to translate the Fortran version directly because vba can not use Complex functions. Well, that's not entirely true. If one sets a vba reference to atpvbaen, then it is possible to do stuff like this. This returns the correct answer of 5. Sub Demo() Dim c As String With WorksheetFunction c = .Complex(3, 4) MsgBox .ImAbs(c) End With End Sub -- HTH :) Dana DeLouis "Dana DeLouis" wrote in message ... Hi. I think I've copied your code & data correctly, but I keep getting the message ""Too many iterations..." and them the program aborts near the end with Atan2(0,0) (thus causing an error) Feel free to send my your workbook. I'd be glad to take a look at it. Do you have a reference for the code? -- Dana DeLouis <snip |
Array Declaration Problem ??
Hi;
Some clarifications. 1) The FORTRAN code of Zroots() and Laguer() comes from "Numerical Recipes" by Press et al, pages 366 & 367, as I correctly referenced in my earlier posts. The Fortran version works perfectly and as desired in all situations, and I have hade no problems with it whatsoever! 2) I posted the entire Fortran code of Zroots() and Laguer() here earlier (total ~ 60 lines), hoping some experts in VBA would help in its conversion to vba. I subsequently decided to convert the code myself to VBA and have since posted one of my latest attempts (not sure which one!), which returns #VALUE! 3) Although it may be a different issue altogether, my concern remains about the possibility of an error caused by a call to a Sub from a Function based on (my interpretation of) MS ref. book: "Microsoft Excel 2000 VBA Fundamentals", Microsoft Press, page 187), which reads: "NOTE: A function used in a worksheet cell can include only those actions that can be executed while Excel is recalculating a worksheet. Actions such as opening files or displaying message boxes can be included in functions that are called from macros, if you include them (or similar) in a function that's called from a worksheet, the function simply returns the #VALUE! error." In your latest example, Sub ProcA() calls Sub ProcB(), which in turn calls Function TimesTwo(). This, I believe, is the common/normal procedure where the Function is called from within the sub, and not the other way around where the function is the main procedure. Regards. "Dana DeLouis" wrote: Hi. I don't think I was totally correct in my statement because I am using Excel 2007. It's a little confusing, but I believe that in this version, most of the ATP functions were moved into the Worksheet function object. Hence, I do not have to set a vba reference to the atp. I believe older versions do need that reference set. I noticed that the code comes from the book "Numerical Recipes" I don't have the complete code, so I can't see where any code differences are. I did notice that in that link I mentioned, others could not get the code to work either. Hmmm. Sounds like something didn't get translated correctly. You asked about the possibility of an error caused by a call to a Sub, and not a Function. You may know this, but here's a little demo that shows how this works. This is just my thoughts on the subject. As we step thru ProcA, I find it hard to tell by looking (and especially without code documentation) that ProcB is going to change the value of a. This is what I believe is happening in your code. I find it a little hard to track. I find it a little easier to see with a function (TimesTwo) that we are trying to change the value of a. Sub ProcA() Dim a a = 5 Call ProcB(a) MsgBox a a = TimesTwo(a) MsgBox a End Sub Sub ProcB(z) z = 2 * z End Sub Function TimesTwo(n) TimesTwo = 2 * n End Function -- HTH :) Dana DeLouis "monir" wrote in message ... Hi; The answer to my questions 2 & 3: go to the VBA "Object Browser" window, then select the "atpvbaen.xls" library and the "VBA Functions and Subs" Class, and the list will display. Regards "monir" wrote: Hi; 1) It seems that after setting the ref. in VBA to atpbaen.xls your Demo works fine without the WorkSheetFunction object and the With structu Sub Demo() Dim c As String c = complex(3, 4) MsgBox ImAbs(c) End Sub 2) Is this a general rule ?? ... i.e.; if one sets the ref. to atpbaen, then one should be able to use any XL w/s function in VBA ?? 3) Or, the atp ref. only allows the direct use (not through the WorkSheetFunction object) of those listed under: VBA Help::"Using Microsoft Excel Worksheet Functions in Visual Basic":: "List of Worksheet Functions Available to Visual Basic" Would appreciate your comments. Thank you. "monir" wrote: Hi Dana; I couldn't access the link, but it most likely refers to my other post! Your idea is excellent and NEW. I selected the vba ref atpvbaen.xls and tried your demo (copy/paste). It produces Run-time error '438': Object doesn't support this property or method" and the statement: c = .Complex(3, 4) is highlighted. Is there something else beside the ref. atpvbaen.xls ?? (I'm using XL 2003, Win XP) Regards. "Dana DeLouis" wrote: As a side note, I noticed in the thread at: http://www.mrexcel.com/forum/printth...dc8769d9015ff0 5c420&t=322333 that near the end of the thread they mention it was not possible to translate the Fortran version directly because vba can not use Complex functions. Well, that's not entirely true. If one sets a vba reference to atpvbaen, then it is possible to do stuff like this. This returns the correct answer of 5. Sub Demo() Dim c As String With WorksheetFunction c = .Complex(3, 4) MsgBox .ImAbs(c) End With End Sub -- HTH :) Dana DeLouis "Dana DeLouis" wrote in message ... Hi. I think I've copied your code & data correctly, but I keep getting the message ""Too many iterations..." and them the program aborts near the end with Atan2(0,0) (thus causing an error) Feel free to send my your workbook. I'd be glad to take a look at it. Do you have a reference for the code? -- Dana DeLouis <snip |
Array Declaration Problem ??
Feel free to send my your workbook.
I'd be glad to take a look at it. - - Dana DeLouis 1) The FORTRAN code of Zroots() and Laguer() comes from "Numerical Recipes" by Press et al, pages 366 & 367, as I correctly referenced in my earlier posts. The Fortran version works perfectly and as desired in all situations, and I have hade no problems with it whatsoever! 2) I posted the entire Fortran code of Zroots() and Laguer() here earlier (total ~ 60 lines), hoping some experts in VBA would help in its conversion to vba. I subsequently decided to convert the code myself to VBA and have since posted one of my latest attempts (not sure which one!), which returns #VALUE! <snip |
Array Declaration Problem ??
Hi Dana;
Thank you again and I would be glad to send you a copy of the w/b. I've ironed out almost ALL the problems with the procedure, and I'm getting very encouraging results (the expected results). In addition to using the VBA atpvbaen.xls library to handle Complex variables by making w/s Complex functions available in vba (your brilliant idea!), I've changed the input array argument in the array Function Zroots2() from a 2D array to two 1D arrays. The only remaining difficulty is as follows. The results are calculated correctly in the array Function Zroots2(), but only the 1st element of the array is returned to the range of cells (instead of returning the array of results). Here's how the relevant sections of the array Function Zroots2() looks now. Notice that the function is declared as String and the array variable Roots() is also declared as String. I tried to declare the function Zroots2 and variable Roots as Variant, but realized that a Variant can't include String data type. Option Base 1 Option Explicit Function Zroots2(ar As Range, ai As Range, m As Integer, polish As String) As String() Dim EPS As Double Dim i As Integer, jj As Integer Dim b As String, c As String Dim j As Integer, its As Integer Dim x As String Dim Roots(100) As String Dim a(101) As String, ad(101) As String EPS = 0.000001 For j = 1 To m + 1 a(j) = complex(ar(j), ai(j)) ad(j) = a(j) Next j For j = m To 1 Step -1 x = complex(0, 0) Call Laguer2(ad, j, x, its) '.........................................my code1 Next j For j = 1 To m Call Laguer2(a, m, Roots(j), its) Next j '.........................................my code2 For j = 2 To m x = Roots(j) For i = j - 1 To 1 Step -1 '.........................................my code3 Roots(i + 1) = Roots(i) Next i '.........................................my code4 Next j Zroots2 = Roots() End Function Any suggestions ?? Thanks again. "Dana DeLouis" wrote: Feel free to send my your workbook. I'd be glad to take a look at it. - - Dana DeLouis 1) The FORTRAN code of Zroots() and Laguer() comes from "Numerical Recipes" by Press et al, pages 366 & 367, as I correctly referenced in my earlier posts. The Fortran version works perfectly and as desired in all situations, and I have hade no problems with it whatsoever! 2) I posted the entire Fortran code of Zroots() and Laguer() here earlier (total ~ 60 lines), hoping some experts in VBA would help in its conversion to vba. I subsequently decided to convert the code myself to VBA and have since posted one of my latest attempts (not sure which one!), which returns #VALUE! <snip |
Array Declaration Problem ??
Hi;
For clarification, the 3rd para. of my latest reply should read: "The only remaining difficulty is as follows. The array results are calculated correctly in the array Function Zroots2(), but only the 1st value of the 1D array Roots results is returned to the col range of cells (instead of returning the array of results)." Regards. "Dana DeLouis" wrote: The only remaining difficulty is as follows. The results are calculated correctly in the array Function Zroots2(), but only the 1st element of the array is returned to the range of cells (instead of returning the array of results). Just guessing, but if the results to the worksheet are a vertical array, then just transpose them. For this simple demo, select 3 vertical cells, and Ctrl+shift+Enter the following: { =Demo() } You should see all 3 results. Function Demo() Dim V 'Your Array of values V = Array(2, 4, 6) Demo = WorksheetFunction.Transpose(V) End Function I can't get the entire code from Numerical Recipes. I'd love to get a copy, and check out your code. I'm curious on the theory behind that code. -- HTH :) Dana DeLouis "monir" wrote in message ... Hi Dana; Thank you again and I would be glad to send you a copy of the w/b. I've ironed out almost ALL the problems with the procedure, and I'm getting very encouraging results (the expected results). In addition to using the VBA atpvbaen.xls library to handle Complex variables by making w/s Complex functions available in vba (your brilliant idea!), I've changed the input array argument in the array Function Zroots2() from a 2D array to two 1D arrays. The only remaining difficulty is as follows. The results are calculated correctly in the array Function Zroots2(), but only the 1st element of the array is returned to the range of cells (instead of returning the array of results). Here's how the relevant sections of the array Function Zroots2() looks now. Notice that the function is declared as String and the array variable Roots() is also declared as String. I tried to declare the function Zroots2 and variable Roots as Variant, but realized that a Variant can't include String data type. Option Base 1 Option Explicit Function Zroots2(ar As Range, ai As Range, m As Integer, polish As String) As String() Dim EPS As Double Dim i As Integer, jj As Integer Dim b As String, c As String Dim j As Integer, its As Integer Dim x As String Dim Roots(100) As String Dim a(101) As String, ad(101) As String EPS = 0.000001 For j = 1 To m + 1 a(j) = complex(ar(j), ai(j)) ad(j) = a(j) Next j For j = m To 1 Step -1 x = complex(0, 0) Call Laguer2(ad, j, x, its) '.........................................my code1 Next j For j = 1 To m Call Laguer2(a, m, Roots(j), its) Next j '.........................................my code2 For j = 2 To m x = Roots(j) For i = j - 1 To 1 Step -1 '.........................................my code3 Roots(i + 1) = Roots(i) Next i '.........................................my code4 Next j Zroots2 = Roots() End Function Any suggestions ?? Thanks again. "Dana DeLouis" wrote: Feel free to send my your workbook. I'd be glad to take a look at it. - - Dana DeLouis 1) The FORTRAN code of Zroots() and Laguer() comes from "Numerical Recipes" by Press et al, pages 366 & 367, as I correctly referenced in my earlier posts. The Fortran version works perfectly and as desired in all situations, and I have hade no problems with it whatsoever! 2) I posted the entire Fortran code of Zroots() and Laguer() here earlier (total ~ 60 lines), hoping some experts in VBA would help in its conversion to vba. I subsequently decided to convert the code myself to VBA and have since posted one of my latest attempts (not sure which one!), which returns #VALUE! <snip |
Array Declaration Problem ??
Hi Dana;
Sorry to bother you again, but problem solved at last!! Here's a summary: 1) On the w/s: cell B8::3 cell B9:: myTrue cells B11:B14:: numerical values cells C11:C14:: numerical values cells I11:I13:: array formula {=Zroots2(B11:B14,C11:C14,B8,B9)} Option Base 1 Option Explicit Function Zroots2 (ar As Range, ai As Range, m As Integer, polish As String) As String() Dim EPS As Double Dim i As Integer, jj As Integer Dim b As String, c As String Dim j As Integer, its As Integer Dim x As String ReDim Roots(m) As String ReDim a(m+1) As String, ad(m+1) As String '.........................................my code1 Zroots2 = Roots() End Function 3) In Function Zroots2(), array Roots() is calculated correctly, say, [1+i], [2+2i], [3+3i]. But the array function returned a single value [1+i] to the full range I11:I13, instead of returning the array 3 results to the 3 vertical cells. 4) In Function Zroots2(), replacing the statement: Zroots2 = Roots() with Zroots2 = WorksheetFunction.Transpose(Roots()) doesn't produce compile error but returns #VALUE! to cells I11:I13 5) Having instead the Transpose function in the array formula on the w/s: cells I11:I13:: array formula {=Transpose(Zroots2(B11:B14,C11:C14,B8,B9))} and leaving the Function Zroots2() statement unchanged: Zroots2 = Roots() S O L V E S the problem. I've successfully tested the VBA procedure for 1D polys up to degree 20, with real and complex coefficients. If there's interest, I'd be glad to post a demo w/b with the VBA procedure. Kind regards. "monir" wrote: Hi; For clarification, the 3rd para. of my latest reply should read: "The only remaining difficulty is as follows. The array results are calculated correctly in the array Function Zroots2(), but only the 1st value of the 1D array Roots results is returned to the col range of cells (instead of returning the array of results)." Regards. "Dana DeLouis" wrote: The only remaining difficulty is as follows. The results are calculated correctly in the array Function Zroots2(), but only the 1st element of the array is returned to the range of cells (instead of returning the array of results). Just guessing, but if the results to the worksheet are a vertical array, then just transpose them. For this simple demo, select 3 vertical cells, and Ctrl+shift+Enter the following: { =Demo() } You should see all 3 results. Function Demo() Dim V 'Your Array of values V = Array(2, 4, 6) Demo = WorksheetFunction.Transpose(V) End Function I can't get the entire code from Numerical Recipes. I'd love to get a copy, and check out your code. I'm curious on the theory behind that code. -- HTH :) Dana DeLouis "monir" wrote in message ... Hi Dana; Thank you again and I would be glad to send you a copy of the w/b. I've ironed out almost ALL the problems with the procedure, and I'm getting very encouraging results (the expected results). In addition to using the VBA atpvbaen.xls library to handle Complex variables by making w/s Complex functions available in vba (your brilliant idea!), I've changed the input array argument in the array Function Zroots2() from a 2D array to two 1D arrays. The only remaining difficulty is as follows. The results are calculated correctly in the array Function Zroots2(), but only the 1st element of the array is returned to the range of cells (instead of returning the array of results). Here's how the relevant sections of the array Function Zroots2() looks now. Notice that the function is declared as String and the array variable Roots() is also declared as String. I tried to declare the function Zroots2 and variable Roots as Variant, but realized that a Variant can't include String data type. Option Base 1 Option Explicit Function Zroots2(ar As Range, ai As Range, m As Integer, polish As String) As String() Dim EPS As Double Dim i As Integer, jj As Integer Dim b As String, c As String Dim j As Integer, its As Integer Dim x As String Dim Roots(100) As String Dim a(101) As String, ad(101) As String EPS = 0.000001 For j = 1 To m + 1 a(j) = complex(ar(j), ai(j)) ad(j) = a(j) Next j For j = m To 1 Step -1 x = complex(0, 0) Call Laguer2(ad, j, x, its) '.........................................my code1 Next j For j = 1 To m Call Laguer2(a, m, Roots(j), its) Next j '.........................................my code2 For j = 2 To m x = Roots(j) For i = j - 1 To 1 Step -1 '.........................................my code3 Roots(i + 1) = Roots(i) Next i '.........................................my code4 Next j Zroots2 = Roots() End Function Any suggestions ?? Thanks again. "Dana DeLouis" wrote: Feel free to send my your workbook. I'd be glad to take a look at it. - - Dana DeLouis 1) The FORTRAN code of Zroots() and Laguer() comes from "Numerical Recipes" by Press et al, pages 366 & 367, as I correctly referenced in my earlier posts. The Fortran version works perfectly and as desired in all situations, and I have hade no problems with it whatsoever! 2) I posted the entire Fortran code of Zroots() and Laguer() here earlier (total ~ 60 lines), hoping some experts in VBA would help in its conversion to vba. I subsequently decided to convert the code myself to VBA and have since posted one of my latest attempts (not sure which one!), which returns #VALUE! <snip |
All times are GMT +1. The time now is 11:28 AM. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
ExcelBanter.com