cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Community Tip - Your Friends List is a way to easily have access to the community members that you interact with the most! X

Redefining an undefined variable

ojoshi-2
3-Visitor

Redefining an undefined variable

Hi,

I currently use a scripted function that redefines the earlier variable if it was undefined because of any reason. Please have a look at the attached file, and while opening the file, make sure you say "No" in the dialogue box that prompts you to disable the macros.

While this function works well for single line variables as is evident, but I can't use it in a variable that has more than one lines. Is there a way to solve this problem?

Thanks

Omkar

PS: I found the redefining function somewhere in the forums.

1 ACCEPTED SOLUTION

Accepted Solutions

I didn't look at your scripted file with the redefine() as I don't think you will need it nor is there a chance of getting it to work with local variables and/or single vector elements, i guess.

In your demo sheet I don't quite understand why you switch from spline to linear interpolation. splines tend to oscillate and usually won't give you that much more precison. So why not stick to linear interpolation?

Anyway, look if the attached worksheet does what you want.

I replaced the interpolation routines and those routines won't fail anymore. but even if they would, the way the function get_coeff() is written it wouldn't matter.

View solution in original post

23 REPLIES 23

The scripted component you found just works for worksheet variables and not for variables local to a program.

If you are just trying to trap division by zero errors or the like you may consider using the "on error" construct.

13.01.png

The function "Redefine" is better for checking that a variable has been defined.

If it hasn't then it provides the means to detect that & set up a default condition, rather than a work sheet showing red errors everywhere & this can be useful.

For the application that you have I think that the Mathcad built-in function "on error" will serve better:

Capture.PNG

NaN is then the default value which means NotANumber to Mathcad.

Regards

Andy

Thanks Werner/Andy, I thought of using the "on error" function but it doesn't work in a situation where the variable is not defined. For instance, if you delete the vector that is assigned to G_v, leaving it undefined, you will see that H_v will be undefined as well. This is what I want to mitigate actually, to redefine the variables local to the program.

Any thoughts?

Thanks

1) the variable H_v is not undefined because V[2 is undefined but because the execution of the program defining H_v failed (division by zero). If if ReDefine would work for local variables it would not be executed but the program is left immedeately after the error occurs. If you don't want that, you have to use "on error".

2) At the moment I can't think of a situation where a redefinition of a non-existing local variable could be necessary. Local variables are created by local assignments. So if you use "on error" for every assignment which could cause an error, you are on the safe side. If you are just sloppy and forget to assign a local variable or forget about the RHS in a local assignment and neverthelss try to use it afterwards, its better to get an error, fix it by making the assignment rather than programming something like "if I forgot to assign that variable - and I am too lazy to scroll upward to look if i did - I do a ReDefine() just as a precaution".

A ReDefine() can be useful in (I think rather rare) occasions where you set up a sheet to be used by someone else and want to provide default values for some variables even if the user deleted the defaults you had set at the top or typed something like A:= with a missing right hand side.

One of the cases where I have found this function to be of use was where I had a number of different worksheets that interacted & passed data to one another.

Opening any one of them would trigger the others to open automatically & the calculation would iterate until either equilibrium was reached or a number of cycles was exceeded.

If the correct data was not passed at the start of any of the programs it would crash causing incorrect data (or no data) to pass to the next & nothing would start.

By using a ReDefine function, a default start point for any program start point was established & it did <sort of> work (mathcad 12); with updates to Mathcad 15 some of this doesn't work now , but fortunately I haven't had the need to repeat the exercise. Yet.

I do sometimes call sub-sheets either from mathcad or embeded Excel & here again I feel a little more secure knonwing that there are default states.

I don't know if it would ever prompt a crash now; but previous experience of trying to read a variable in another (different) worksheet that hadn't been defined did crash mathcad to the point that a hard (turn the power off) machine re-boot was required.

It very much depends on what you are trying to achieve.

The bottom line is that you can never make anything 'foolproof'. Fools are far too inventive!!

Regards

Andy

I understand it may be rare but am currently facing its need. Wish I could share the file, but I can't, because of IP concerns and hence the long description.

I have a program that calculates the some coefficient which is a function of Reynolds number (Re). Upto certain Re, it can be obtained by interpolating a matrix of database (coefficient vs Re). But beyond that Re, empircal formula needs to be used. I make this decision using if statement in a program.

Now, when the Re is beyond that said limit, the interpolation fails and the interpolated coeff becomes undefined. To mitigate this, I do the interpolation before the program and redefine the interpolated coefficient to another variable and use this in the program. Thus upon unsuccessful interpolation, since the redefined interpolated coefficient is STILL defined, program executes and calculates the coeff using the empirical formula. When Re is smaller than the limit, program obviously gives the interpolated coeff.

Now, situation gets convoluted when I have a series of Re. I use For loop for this and need to use the same logic there. But I am stumped because this magical script doesn't work with local variables

So basically, the problem is "invalid interpolation rendering variable undefined in For-loop". And I suppose I can't use "on error" function to mitigate this?

Even if you are not allowed to post the worksheet in question you may be able to set up a dummy sheet with dummy data and functions just to show the problem.

I guess I am missing the point as it looks too simple, but I'll give it a try anyway. You can setup a function f.interpolate(Re) with parameter Reynold number which return the coefficient by interpolation matrix data (and only works for Re in a specific range) and you can setup a function f.empiric(Re) which will use an empiric formula to get the coefficient and is to be used in case re is not in the predefined range.

So your function to get the coefficient correct for any Reynold could be

13.01.png

You may apply this function to a single scalar Re or (vectorized) to a vector of Re-values or, as you obviously have set up your sheet, using a for-loop.

If yot interpolation routine really throws an error for invalid Re's you may also use "on error"

Hmm - can't insert pics anymore in this post (getting "null" error), so I try to type the expression I am thinking of:

coeff(Re) := f.empiric(Re) on error f.interpolate(Re)

Something like the attached may help

Regards

Andy

Your solution fails if G_v IS defined on the worksheet level because your if condition make_s G_v a local variable, even if the condition is false and so if G_v is defined, the local G_v gets 0.

OK, needs to be a little more complex, seems to work both ways ; but needs a <ctrl> <F9> to force a re-calculate.

Regards

Andy

Yes, without using the worksheet variable in the program it works.

@Omkar: a vector is undefined as a whole if only one single component is undefined. So you wouldn't be able to pick the "good" defined elelemnts of a vector and treat the others with some kind of ReDefine().

Thanks guys.

Werner, when Re goes beyond the values available in the interpolation matrix, the f.interpolate(Re) becomes undefined, and thus coeff(Re) is undefined. I mitigate this by redefining f.interpolate(Re) before the program, but I am facing problem when I have a series of Re values in a For loop.

Andy, I have tried a similar tact as I said, by redefining the variable before the program and it works. But consider a scenario where you are making operation on individual components of the G_v vector in a For loop.

I will put some time to represent the situation with dummy variables tomorrow and attach it here. Hope that will throw light on exact problem.

Appreciate comments of you both

Werner, when Re goes beyond the values available in the interpolation matrix, the f.interpolate(Re) becomes undefined, and thus coeff(Re) is undefined.

No! f.interpolate(Re) is not called for values of Re outside the valid range due to the if condition in my first suggestion.

And if f.interpolate throws an error for invalid Re's then you can use "on error" to call f.empiric instead as in my second suggestion.

Guys

Please find attached two sheets that details the problem. I have used dummy variables and simplified the formulae. One sheet is without the scripted component and details how calculation fails. Second sheet is with the scripted component and details how calculation doesn't fail.

Werner, please have a look at the sheets, and correct my following statements if necessary.

No! f.interpolate(Re) is not called for values of Re outside the valid range due to the if condition in my first suggestion.

It does!? Please have a look at my sheet,redefine_without_script. The interpolation fails beyond Re and program stops. I think in if condition, even if the condition is not satisfied, the variable needs to be "calculatable".

And if f.interpolate throws an error for invalid Re's then you can use "on error" to call f.empiric instead as in my second suggestion.

You can't, because "on error" can not take care of "undefined" variables? In your case, f.interpolate becomes undefined when interpolation can't happen because of Re being beyond the dataset. Infact this was the prime reason I needed a scripted component!

Essentially the main problem is, I CAN'T PROCESS A SERIES OF Re (A VECTOR) BECAUSE I CAN'T HAVE SCRIPTED COMPONENT IN FOR LOOP. SO ANY Re BEYOND THE RANGE OF DATABASE WILL FAIL

What I had in mind was to write a function get_coeff(Re) which calculates the coefficient for just any single scalar value of Re. This function could then be used (vectorized) for any vector of Re's.

In your demo file you replaced the empirical formula you were talking about by NaN, right?

Given that the program (or function) has if conditions, it isn't an explicit function of Re, can this be used directly for any vector? I would have thought that a program with if condition can only be used for a scalar? Hence, you may need to pass each single scalar from vector one by one, which would require a FOR loop?

Omkar Joshi wrote:

Given that the program (or function) has if conditions, it isn't an explicit function of Re, can this be used directly for any vector? I would have thought that a program with if condition can only be used for a scalar?

Correct, but this is what vectorization is for. Basically vectorization is an implicit for-loop which works on the single elements of the vector and collects the result in a result vector.

In my demo file, I don't want "coeff_linear" to fail, so that "coeff" doesnt fail and "Parameter" doesn't fail, without a redefine scripted routine. "NA" is just to satisfy the "otherwise" scenario. If I don't have it, then coeff will remain undefined, hence have to put something there.

Currently, with the redefine routine, the variable coeff_linear_redefined takes care of any incosnistencies in interpolation of coeff_linear and hence coeff always has an answer. Thus Parameter always has an answer. But I can't use it in in FOR loop. This is the gist of the problem.

I didn't look at your scripted file with the redefine() as I don't think you will need it nor is there a chance of getting it to work with local variables and/or single vector elements, i guess.

In your demo sheet I don't quite understand why you switch from spline to linear interpolation. splines tend to oscillate and usually won't give you that much more precison. So why not stick to linear interpolation?

Anyway, look if the attached worksheet does what you want.

I replaced the interpolation routines and those routines won't fail anymore. but even if they would, the way the function get_coeff() is written it wouldn't matter.

In your demo sheet I don't quite understand why you switch from spline to linear interpolation. splines tend to oscillate and usually won't give you that much more precison. So why not stick to linear interpolation?

In cases, linear interpolation was overpredicting the data and the actual formulae have powers of it this coeff, so it introduced error. Hence I decided to go for spline. But in a a ramge of Reynolds numbers near 1e5, I have observed negative values of the coeff, which are the artifacts of oscillation of splines (going below X axis) as you mention. And I don't have more data to in that section to "discipline" the spline, hence the switch to linear interpolation.

Thanks for the attached file, appreciate it. I will need some time to digest it though, since I am new to Mathcad. Will post my thoughts soon.

Cheers

Omkar

In cases, linear interpolation was overpredicting the data and the actual formulae have powers of it this coeff, so it introduced error. Hence I decided to go for spline. But in a a ramge of Reynolds numbers near 1e5, I have observed negative values of the coeff, which are the artifacts of oscillation of splines (going below X axis) as you mention. And I don't have more data to in that section to "discipline" the spline, hence the switch to linear interpolation.

Depending on the actual formula it may be an option to use approximation instead of interpolation. Depends upon your knowledge about which kind of function you expect for a constant f resp. a constant Re. Would make the table lookup routine more complicated of course.

I have perused your file and I realised that the whole problem in mine was the use of "v" (which identifies the column in the Matrix) to create a submatrix around the value I want (The primitive "Excel" way). "v" fails when Re is beyond limit, hence local matrix can not be formned and linear interpolation fails (because there is no matrix). But I now realise I can just use the whole matrix for the 2D interpolation, just like spline interpolation, instead of creating local matrix. And linear interpolation will never fail. This should make the code rather simpler.

Guess the old Excel habits are still haunting me!

Thanks for your help.

Omkar

I think your function g() failed. It searches a value in the data matrix which is bigger than the parameter given. If the parameter is to high, the index gets bigger than allowed for the matrix and so the routine and all which depend on it fail.

Top Tags