-3

I have a function and when i evaluate it i get "General::ivar: 0 is not a valid variable". it also decreases the speed tremendously. How can i increase the speed and get rid of this message? this message does not affect the accuracy of the result but rather the speed. Would appreciate any help.

MX[m1num10_, m2num10_, nx0_?NumericQ, lx0_?NumericQ, y1_, n_] := Block[
   {xx, x, xxinv, xxtrans, xxinvtrans, kx, kx1, Detxx, HX, kxbar, 
    kx1bar, q, ki, xxte, mkx, mmax, a, b, DATA, op1, m1, m2, CiJkL, 
    sol, i, J, j, k, L, m1num1 = m1num10, m2num1 = m2num10, nx = nx0, 
    lx = lx0, lambda, ss},
   xx := Table[Subscript[x, i, J], {i, 3}, {J, 3}];
   xxinv = Inverse[xx];
   xxtrans = Transpose[xx];
   xxinvtrans = Inverse[xxtrans];
   kx := Tr[xxtrans.xx];
   kx1 := 1/2 (Tr[xxtrans.xx]^2 - Tr[xxtrans.xx.xxtrans.xx]);
   Detxx := Det[xx];
   kxbar := kx/Detxx^(2/3);
   kx1bar := kx1/Detxx^(4/3);
   HX[nx_, lx_, kxbar_, Detxx_] := nx/2 (kxbar - 3) + lx*(Detxx - 1)^2;
   q = Table[
     D[HX[nx, lx, kxbar, Detxx], Subscript[x, i, J]], {i, 3}, {J, 3}];
   ki = Inverse[xx].q;
   xxte = {{m1, 0, 0}, {0, m2, 0}, {0, 0, m2}};
   Subscript[x, 1, 1] = xxte[[1, 1]];
   Subscript[x, 2, 2] = xxte[[2, 2]];
   Subscript[x, 3, 3] = xxte[[3, 3]];
   Subscript[x, 1, 2] = xxte[[1, 2]];
   Subscript[x, 1, 3] = xxte[[1, 3]];
   Subscript[x, 2, 3] = xxte[[2, 3]];
   Subscript[x, 2, 1] = xxte[[2, 1]];
   Subscript[x, 3, 1] = xxte[[3, 1]];
   Subscript[x, 3, 2] = xxte[[3, 2]];
   mkx = (1.0/Det[xxte])*(xxte.ki.Transpose[xxte]);
   For[i = 2, i <= n + 1, i++, 
    sol = FindRoot[
      mkx[[2, 2]] == 0 /. m1 -> m1num1[[i]], {m2, m2num1[[i - 1]]}, 
      MaxIterations -> 2500, AccuracyGoal -> 8];
    m2num1[[i]] := m2 /. sol;
    ];
   op1 = mkx[[1, 1]] /. {m1 -> m1num1, m2 -> m2num1};
   ss = Norm[op1 - y1]
   ];
la = 5;
testSize = 100;
numvariable = 2;
n = 99;
m1num10 = Table[1 + (la - 1)/n*i, {i, 0, n}];
m2num10 = Table[0, {i, 0, n}];
m2num10[[1]] = 1;
DATA = {{1, 0}, {1.04, 0.179882}, {1.08, 0.360228}, {1.14, 
    0.632594}, {1.23, 1.04777}, {1.365, 1.69152}, {1.5675, 
    2.71869}, {1.87125, 4.4266}, {2.32688, 7.41251}, {3.01031, 
    12.9046}, {4.03547, 23.4365}, {5., 35.7603}};
a = Table[DATA[[i, 1]], {i, 1, 12}];
b = Table[DATA[[i, 2]], {i, 1, 12}];
xx = Interpolation[Transpose[{a, b}], Method -> "Hermite"];
y1 = Table[xx[x], {x, m1num10}];
F[nx0_, lx0_] := MX[m1num10, m2num10, nx0, lx0, y1, n];
test = Reap[
    For[i = 1, i <= testSize, i++, 
      Sow[Table[0, {i, numvariable}]]];][[2, 1]];
test[[All, 1]] = RandomReal[{0, 5}, {100}];
test[[All, 2]] = RandomReal[{1, 1000}, {100}];
F @@@ test

The problem is not the derivatives as i mentioned. Instead of relating components of xx to xxte i related xx to xxte tensor, directly.However, to my surprise the defected version still performs faster. here is the full code:

MX[m1num10_, m2num10_, nx0_?NumericQ, lx0_?NumericQ, y1_, n_] := 
  Block[{xx, x, xxinv, xxtrans, xxinvtrans, kx, kx1, Detxx, HX, kxbar,
     kx1bar, q, ki, xxte, mkx, mmax, a, b, DATA, op1, m1, m2, CiJkL, 
    sol, i, J, j, k, L, m1num1 = m1num10, m2num1 = m2num10, nx = nx0, 
    lx = lx0, lambda, ss}, 
   xx := Table[Subscript[x, i, J], {i, 3}, {J, 3}];
   xxinv = Inverse[xx];
   xxtrans = Transpose[xx];
   xxinvtrans = Inverse[xxtrans];
   kx := Tr[xxtrans.xx];
   kx1 := 1/2 (Tr[xxtrans.xx]^2 - Tr[xxtrans.xx.xxtrans.xx]);
   Detxx := Det[xx];
   kxbar := kx/Detxx^(2/3);
   kx1bar := kx1/Detxx^(4/3);
   HX[nx_, lx_, kxbar_, Detxx_] := nx/2 (kxbar - 3) + lx*(Detxx - 1)^2;
   q = Table[
     D[HX[nx, lx, kxbar, Detxx], Subscript[x, i, J]], {i, 3}, {J, 3}];
   ki = Inverse[xx].q;
   xxte = {{m1, 0, 0}, {0, m2, 0}, {0, 0, m2}};
   mkx = (1.0/
       Det[xxte])*(xxte.(ki /. ToRules[xx == xxte]).Transpose[xxte]);
   For[i = 2, i <= n + 1, i++, 
    sol = FindRoot[
      mkx[[2, 2]] == 0 /. m1 -> m1num1[[i]], {m2, m2num1[[i - 1]]}, 
      MaxIterations -> 2500, AccuracyGoal -> 8];
    m2num1[[i]] := m2 /. sol;];
   op1 = mkx[[1, 1]] /. {m1 -> m1num1, m2 -> m2num1};
   ss = Norm[op1 - y1]];
la = 5;
testSize = 100;
numvariable = 2;
n = 99;
m1num10 = Table[1 + (la - 1)/n*i, {i, 0, n}];
m2num10 = Table[0, {i, 0, n}];
m2num10[[1]] = 1;
DATA = {{1, 0}, {1.04, 0.179882}, {1.08, 0.360228}, {1.14, 
    0.632594}, {1.23, 1.04777}, {1.365, 1.69152}, {1.5675, 
    2.71869}, {1.87125, 4.4266}, {2.32688, 7.41251}, {3.01031, 
    12.9046}, {4.03547, 23.4365}, {5., 35.7603}};
a = Table[DATA[[i, 1]], {i, 1, 12}];
b = Table[DATA[[i, 2]], {i, 1, 12}];
xx = Interpolation[Transpose[{a, b}], Method -> "Hermite"];
y1 = Table[xx[x], {x, m1num10}];
F[nx0_, lx0_] := MX[m1num10, m2num10, nx0, lx0, y1, n];
test = Reap[
    For[i = 1, i <= testSize, i++, 
      Sow[Table[0, {i, numvariable}]]];][[2, 1]];
test[[All, 1]] = RandomReal[{0, 5}, {testSize}];
test[[All, 2]] = RandomReal[{1, 1000}, {testSize}];
F @@@ test // AbsoluteTiming
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
user49047
  • 791
  • 5
  • 17

1 Answers1

2

The problem seems to be the derivative in the line

q = Table[D[HX[nx, lx, kxbar, Detxx], Subscript[x, i, J]], {i, 3}, {J, 3}];

in which, for some cases, Subscript[x, i, J] is evaluating to zero. You're essentially calling up syntax of the form

D[f[m1,m2],0]

which is presumably not something you intended to do.

It's very hard to read your code regarding what that derivative is meant to be doing, but your code is probably leaking side-effects that you might not have intended. As one such example, running your code and then running

Subscript[x, 1, 2]

will return 0, which is presumably the value being used in subsequent evaluations of F, and this is what's being used as a variable inside D (causing it to fail). You probably need to insulate better any assignment of values to the Subscript[x, i, J], or to include an additional Block around the differentiation to ensure it remains symbolic.

Emilio Pisanty
  • 10,255
  • 1
  • 36
  • 69
  • so it comes from xxte and this tensor has the correct form since i get expected answer for this tensorial derivative. i think your second part of the argument could be the answer but how can i include additional Block to ensure it remains symbolic? – user49047 Jul 31 '17 at 15:13
  • 3
    It's pretty much impossible to know because you're using x both as a symbolic variable and as a recipient for some kind of results, and then re-using it afterwards ─ in code that's inscrutable to anyone other than you. From what I can tell, all the calls in Subscript[x, i, j] = xxte[[i, j]] are superfluous and should probably be removed, but that depends on details that the code is too muddled for anyone but you to understand. – Emilio Pisanty Jul 31 '17 at 15:21
  • I think there is another problem. Because q and ki are both function of Table[Subscript[x, i, J], {i, 3}, {J, 3}],x_11,12,and so on and Subscript[x, 1, 1] = xxte[[1, 1]]; and so on... will update these values after derivation so why i have a derivative of zero ? I updated the previous assigned values only after derivation not during the derivation. Atleast you get the idea what i am trying to do. – user49047 Jul 31 '17 at 16:02
  • 1
    @user49047 I'm not sure how I can impress this strongly enough: the code is nowhere near clear enough for anyone to be able to help you beyond the general statements already provided. You need to embark on a full redesign of the flow of your program, thinking very carefully about what parts of the function evaluation have side-effects that will assign values to variables that you later intend to symbolically differentiate over. How you do that redesign will depend on variables (such as what it is you're trying to do, to begin with) that you have not provided, so we can't help there. – Emilio Pisanty Jul 31 '17 at 16:14
  • 1
    I can say, though, that it is likely that a single function call is probably fine, and it's only the subsequent calls that have to deal with the sludge of side-effects caused by a previous iteration. As a general principle, and unless you really know what you're doing, it is extremely unadvisable to have functions with side-effects in Mathematica. So: write functions without any side-effects, and this should in principle solve itself. – Emilio Pisanty Jul 31 '17 at 16:16