Hello World.
I am using a solve block in MathCAD 15, and it does not close around a constraint that a cross product of two vectors have a root of zero.
In this solve block there is some matrix algebra and some that functions, such that a vector (R0) starting out at one orientation, after two bounces (in two mirrors rotating on two orthogonal axes), ends up in another defined location. There are two mirror positions (alpha1 and alpha 2) which satisfy these conditions completely and uniquely as long as skewness of the initial vector is 'reasonable' for the physical arrangement (e.g. under 30 degrees). The clocking may be anything. In this example it is set at 90, which drives alpha 1 to the exact value of 45 degrees.
In this set of equations, when the root of a cross product between the vector between the last two points of the vector chain (a point of reflection off the last mirror and the destination point) and the unit vector for the reflection off the second mirror, is solved such that root is zero, then both mirror angles are found.
In the first example (blue) the Solve Block does not close, and the cross product error is large.
The second example (red) I solved the equation by manual search (this is not hard, but is slow), by perturbing the values of alpha1 and alpha 2 until the cross product was acceptably zero.
Why can't the solve block do automatically, what I find it relatively straight forward to do by hand?
I suspect that there is some kind of protocol error, but I don't see it. The whole file is attached, in compressed form. The green colored solve block is on page 8, the red colored is page 9.
Thanks,
Robert
Solved! Go to Solution.
Here. It's up to you to check it's actually calculating what you want ti to calculate! I did not spend the time to look through your worksheet in great detail. I just made the solve block work in what seems like a reasonable way.
Here is an image of page 8 in the file showing the solve box which does not close. The guesses of alpha 1 and 2 are very close to the known values, but the error is huge.
This set of calculations demonstrates that there are values of Alpha 1 & 2 which satisfy the constraints completely, driving the error down below six places to the right of the decimal. I found this solution manually by perturbing Alpha 1 and 2 until the error was acceptably small.
For those of you using earlier versions, here is the file saved as an M13 version.
The solve block which won't work is on page 8. Everything else seems to run fine.
Robert
A couple of things.
First, aside from the constraint issue, I am not sure that the solve block is doing what you think it is. Numerical assignments inside solve blocks are NOT part of the solve block. They didn't even used to be allowed. So if you think that somehow during the solve the value of n1, for example, is being changed every time alpha1 is changed, and that is then carried through to the equation for Pr1, it's not. I personally wish they had never allowed this, because it just leads to confusion. Take all the assignments outside of the solve block (that usually means before it). The only things you should have inside the solve block are equalities and inequalities. Nothing else, even if Mathcad happens to permit it. Your evaluation of the cross product is also NOT part of the solve block. The answer you are getting is just based on the guess values, not on the values the solver finds. Evaluate it after the solve block, based on the variables returned by the solve block, alpha1 and alpha2.
Second, the constraints in minerr are treated differently to those in, for example, minimize. The errors in the constraints are minimized along with everything else. In other words, they are soft constraints, not hard constraints. If you want them to act as hard constraints then you need to weight them very heavily. Replace the constraint with (R2 x r2_unit)*10^16=0. That will force the cross product to be effectively zero. This also applies to your constraints for alpha1 and alpha2.
Very interesting what you have to say about weighting the cross product. I have never seen that done, however I can see that it is quite powerful as a method.
I will try that immediately.
I don't think you will like the answer you get
I believe that's because of the other issues with the solve block though, which also need to be fixed.
Okay. I absolutely have been assuming that N1 would be updated sequentially, and that in turn would up date Pr1, which would update r1 and so on, just as it would in many programming languages. If it is not doing this, then what do people do to get around this limitation in a Solve Block I wonder? Do I have to put all of those functions in an "uber-function", set that to zero, and solve that? I wonder if this would be a good approach.
Robert
Okay. Weighting the cross product R2 x r2_unit by a factor of 10^10 changes the result, but only in the direction of the right answer. The initial 'guess' values still predominate. This is the very first time that I have heard about 'weighting' an equation inside a solve block, and I like the idea A LOT.
Now about what a solve block does: you are absolutely right. I have no idea what it does, aside from get me right answers (which I check by other means) most of the time (which is why I check them). So I am going to have to read your paragraph above very carefully, and try a few examples.
More soon.
Robert
Okay. Weighting the cross product R2 x r2_unit by a factor of 10^10 changes the result, but only in the direction of the right answer. The initial 'guess' values still predominate. This is the very first time that I have heard about 'weighting' an equation inside a solve block, and I like the idea A LOT.
This applies only to minerr.
Now about what a solve block does: you are absolutely right. I have no idea what it does, aside from get me right answers (which I check by other means) most of the time (which is why I check them). So I am going to have to read your paragraph above very carefully, and try a few examples.
Take all the assignments outside the solve block. If you think that will stop the solve block from doing what you want, then it wasn't doing what you want anyway
Create a set of functions that depend on the variables you wish to solve for: alpha1 and alpha2. So n1 is a function of alpha1. Pr1 is therefore also a function of alpha 1. etc. Your solve block should contain equalities and inequalities based on those functions and the variables alpha1 and alpha2.
Okay. I have a bit of work to do here to rework all these functions, as you suggest.
I wonder if it is possible to use a function as the argument of a function. Probably not.
This really does give me a clear direction in which to take this. I was attempting to use a solve block the way you would close a search loop around a collection of assignments when programming. Plainly this is not what the solve block does.
Best,
R.
Hmmm . . . it does seem to be possible to use a function as an argument of a function. Well this is very nice.
Hmmm . . . it does seem to be possible to use a function as an argument of a function. Well this is very nice.
You can pass a function of a variable to a function.
xx(a):=sin(a)*cos(a)
answer:=xx(ln(A))
But you can't define a function that way
xx(ln(a)):=sin(a)
makes no sense, and is not allowed.
You can in fact pass any valid expression to a function
answer:=xx(ln(A)+cos(A)-32)
is fine.
Okay. I am getting some very long and strange looking functions, which are the combined products of many other functions using yet other functions as arguments, and MathCAD is allow this. This is a capability I hadn't explored. Interesting.
I am getting some very long and strange looking functions, which are the combined products of many other functions using yet other functions as arguments
Please post an example. This doesn't sound right.
well, when I put expressions inside of expression they start to get vvvvvvveeeeerrrrrrryyyyy long. The attached image will give you an idea, and that is not even the whole thing.
That's not the right way to do it. It might work, but it is unnecessarily complicated. By several orders of magnitude. Please post what you have.
Good morning Richard,
The problem occurs as a consequence of nesting functions within functions. When you combine five functions into five more functions and combined them again into yet another equation, pretty soon you have a hundred terms or more, and this gets unweildly very quickly. You can see this in the second of thie MathCAD 15 file attached.
Cutting and pasting the expressions into one another so that ALL the inputs are in terms of alpha 1 and alpha 2, leads to a single expression which is eight A4 pages wide, and has lost all of ease of editing and checking which the individual functions once had.
So my question at this point is very different from where we started. The answer to the question posed is: Can you close a solve block around a vector cross product is a resolute "yes". For the benefit of the readers who follow I think that starting a new thread at this point is a good idea, so that the key words and title are all tied to the actual discussion.
I will start that thread with the title. Since re-assignments are prohibited within a solve block, how can expressions be kept to a manageable size. You were VERY helpful on this thread and I hope that you may be available to comment on the new one.
Thanks,
Robert
Please don't start a new thread. It's not necessary.
Understood about your preference on starting a new thread. I am a newbie to this list serve, still learning the expectations of the community and the written and unwritten rules. After 8 thousand plus posts, you are clearly one of the most experienced participants.
You do understand the problem however, that when you nest functions with five or so terms (a convenient and good modular size to test and verify independently) and then nest these expanded function inside another few functions in various ways, and them put this in cross product equation, in order to have everything in the solve block be a single expression (no re-assignments allowed in the solve block) that the resulting expression is HUGE. Just HUGE. At this point all the ease of use and transparency of documentation which is the main reason to use MathCAD is lost.
Kind regards,
Robert
If this was going to turn into a big discussion on nesting of functions vs functions calling other functions, I would agree with starting a new thread.
The way you are doing it is not necessary though. In fact, as you point out. it's highly undesirable because it makes it impossible to read, edit or debug. A function can depend on another function though, so the nesting is not necessary. See the example stuff highlighted in green. That's just an example, so you have a lot more work to do. You need to create this dependence on alpha1 in a sequence of functions all the way through the worksheet. You take the final functions, expressed as equalities, and put them in the solve block. If you have two such functions you can use Find rather than minerr, because you are solving for two variables. Then the constraints are hard constraints and you don't need to worry about the weighting. If you have more than two such functions you will have to use minerr.
This distinction between having one function 'nested' inside another as opposed to having a function 'call' another is an important one. You state this very clearly in your annotation. The latter configuration is MUCH more compact, and preserves the modularity which is so important to efficient verification of individual functions. I am looking forward to trying this out. Thanks again.
Robert
Here. It's up to you to check it's actually calculating what you want ti to calculate! I did not spend the time to look through your worksheet in great detail. I just made the solve block work in what seems like a reasonable way.
Hi Richard,
I think that we are probably on the same page here.
The solve block, and how to use it efficiently with a half dozen functions which rely on another half dozen functions, is really the important question in this whole thread. It is the core of how the problem emerged. I was using a re-assignment of a function in another function, which although *allowed* in MathCAD simply does not work. To get around this I 'nested' the arguments of functions in functions, and plainly the *clean* or the elegant way to do this is to 'call' the functions in the minor premises. In retrospect what you write seems really clear.
The rest of the file I shared in this thread is a specific application which will vary in the future, and will certainly be different for other readers. I am away from my work station at the moment, so I don't have access to a machine with which to try out what you suggest. This being said, the logic of what you wrote seems transparent.
Kind regards,
Robert
Hi Richard,
The method of using functions to call functions is new to me. As you explain it leads to a very compact notation. The solve block is now two lines long. Moreover it is the right answer.
For anyone who might be reading this in the future, I append the final solution below. The modularity of the functions is saved, and the result is very clean.
Thanks again.
Robert
.
Plainly this is not what the solve block does.
You are right. It doesn't
After nesting all those functions within functions, I have a single expression in term of alpha 1 and alpha 2 plus various constants. This single expression is now eight pages wide. However the 'find' function now does find an answer for alpha one and alpha two. It is not the right answer, but the solve block now does
return an answer rather than an error code. Perhaps I made an error in all that cutting and pasting.
I am tempted to put the whole thing in a programming box with a little search loop. I know that will work.
I am going to look at this again in the morning.
Thanks so much.
Robert