0
$\begingroup$

I have a simple module like

BCdet[x_, y_] := Module[
  {AuxMat},
  AuxMat = Mat /. {f -> x, A -> y};
  Det[AuxMat]
  ]

where Mat is a normal matrix 12x12 with parameters f and A. The above defined module returns a complex number and it works without any problems.

Then I would like to find root of its real part for given A=trailA and for a complex f

FindRoot[
 Re[BCdet[f, trialA]],
 {f, 2.5 + 0. I},
 StepMonitor :> Print["Step to f = ", f]
 ]

Unfortunately, this does not work at all. I cannot get any result. I use StepMonitor to check it, however, it does not give any output. Any idea where might be the problem?

$\endgroup$
1
  • $\begingroup$ But as I understood, this evaluates function only when its argument is a number. I think this must be obeyed in the example with FindRoot, isn't it? $\endgroup$
    – LLapsus
    Commented Jul 31, 2013 at 9:17

1 Answer 1

1
$\begingroup$

You may consider making Mat a function of f and A. Or if you wish to work with your code, make sure f and A do not have values. FindRoot temporarily gives f a value in your example. Therefore in your code the replacement rule for f will be broken. However, this is usually not a problem as f will be given its value simply by evaluation. But it does show the risk of making a function like this. If you give A a value, then it does not make a difference what you set trialA to, as the rule for A will be broken.

Fortunately we have

x /. {3.3 -> 5}

x

but it would be terrible if 3.3 would appear on the LHS of /., as you would then get an undesired replacement . This is not what makes your code fail to work however. Consider these definitions

Mat2[A_, f_] := {{A + I, f}, {A + f, A + f + 3 I}}

BCdet[x_, y_] := Module[
  {AuxMat},
  AuxMat = Mat2[y,x];
  Det[AuxMat]
  ]

Now, for me it works if we simply do

FindRoot[BCdet[x, trialA], {x, 5}]

-> {x -> 3.01955 + 7.45469 I}

And we have

Abs[BCdet[3.019546672440941` + 7.454686341385149` I, trialA]]

2.99373*10^-14

Which is pretty close to 0. However, you code does not work

FindRoot[Re[BCdet[x, trialA]], {x, 5}]

--messages--> The line search decreased the step size to within tolerance...

I suppose you can leave out the Re as without the Re FindRoot will find a solution with a small real part anyway. But that is a bit ugly.

Remarks

If you wish to do still use replacement rules, at least use HoldPattern. But first another suggestion. If you don't want to do

BCdet[f_, A_] :=  Det[{{A + I, f}, {A + f, A + f + 3 I}}]

Because Mat is so big, or because you want to reuse/change Mat, you can do something like

Clear[A, f]

Mat = {{A + I, f}, {A + f, A + f + 3 I}};

With[
      {Mat = Mat}
      ,
      BCdet[f_, A_] :=  Det[Mat]
 ]

I suggest you work with regular functions so I don't have to explain everything below :P. This would make your code work but it is really inconvenient:

Clear[A,f]
With[
 {Mat = {{A + I, f}, {A + f, A + f + 3 I}}}
 ,
 BCdet[x_, y_] := 
  Module[{AuxMat}, 
   AuxMat = Unevaluated[Mat] /. {HoldPattern[f] -> x, HoldPattern[A] -> y};
   Det[AuxMat]]
 ]
$\endgroup$
2
  • $\begingroup$ Thanks, I always use Clear[f,A]. Finally, it seems that adding BCdet[x_?NumericQ, y_?NumericQ] to the definition helped. Unfortunately, I do not understand why. I guess, the arguments always must be numbers. $\endgroup$
    – LLapsus
    Commented Jul 31, 2013 at 10:00
  • $\begingroup$ @LLapsus note that there is still a risk because f is given a value by FindRoot. You might get undesired replacements still, but it is very unlikely. $\endgroup$ Commented Jul 31, 2013 at 10:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.