schapplm

40 Reputation

5 Badges

4 years, 291 days

MaplePrimes Activity


These are questions asked by schapplm

Dear MaplePrimes community,

I am currently struggling to use the simplify-command in my toolbox for symbolic generation of robot dynamics.

I created a procedure which calls the simplify command with some extra checks. There are symbolic expressions in the term to be simplified that also occur in the workspace of the worksheet calling the procedure.

The simplify command (called from within the procedure) shall regard them as symbolic expressions unaware of the content of the variable in the workspace. Nevertheless, the simplifications are performed with the global variables, even though they are declared local to the procedure.

Minimal example: The variable "l1" stands for "length 1" in a mechanic problem as well as "length of the expression"

restart:
with(LinearAlgebra): with(ArrayTools): with(codegen): with(CodeGeneration): with(StringTools):
read proc_simplify2:
T := m2*(l1+l2)*(qD2)^2: # dummy-expression for kinetic energy
l1 := length(T);
T_simpl := simplify2(T):
l2 := length(T_simpl);

Code for the file proc_simplify2:

simplify2 := proc (Term)
  # Simplify a term. Additionally check if the simplification is advantageous.
  # In some cases the term gets longer after the simplification. Then discard.
  # Give the local procedure variable a long name. They must not be identical in Term.
  local simplify_tmpvar_c1, simplify_tmpvar_c1sum, simplify_tmpvar_c2, \
        simplify_tmpvar_c2sum, simplify_tmpvar_nms, simplify_tmpvar_k, Term2:
  # Assume all contents of the Term to be local variables to this procedure
  # Otherwise, variables like "l1" can be overwritten by occurences in the calling worksheet.
  simplify_tmpvar_nms:=convert(indets(Term,name),list): # get list of symbols
  for simplify_tmpvar_k from 1 to ColumnDimension(simplify_tmpvar_nms) do
    if simplify_tmpvar_nms[simplify_tmpvar_k] = Pi or simplify_tmpvar_nms[simplify_tmpvar_k] = 0 then
      next: # 0 and Pi can not be variables
    end if:
    eval(sprintf("local %s;", String(simplify_tmpvar_nms[simplify_tmpvar_k]))); # assume local
   end do:

  # Get computational effort before simplification
  simplify_tmpvar_c1:=add(cost~(Term)): 
  simplify_tmpvar_c1sum := diff(simplify_tmpvar_c1,functions)+ \
                           diff(simplify_tmpvar_c1,additions)+ \
                           diff(simplify_tmpvar_c1,multiplications)+\
                           diff(simplify_tmpvar_c1,divisions):
  # Perform simplification. Attention: tries to use global variables to simplify the expression (see above)
  Term2 := simplify(Term):
  # Get effort after simplification
  simplify_tmpvar_c2:=add(cost~(Term2)): 
  simplify_tmpvar_c2sum := diff(simplify_tmpvar_c2,functions)+\
                           diff(simplify_tmpvar_c2,additions)+\
                           diff(simplify_tmpvar_c2,multiplications)+\
                           diff(simplify_tmpvar_c2,divisions):
  if simplify_tmpvar_c2sum > simplify_tmpvar_c1sum then
    # The simplification was not successful. Take old version.
    Term2 := Term:
  end if:
  return Term2:
end proc:

I would be glad for suggestions how to define the symbolic expressions in Term as local to the procedure or perhaps a better way to perform simplifications. As my program extends over several worksheets and the user may define an input file, I would not like to have to control all names of temporary variables that may occur at some point in the project. Until I tried to use the simplify-command, there was no problem regarding variable names. Is it perhaps possible that the variables are now only declared local in the for loop and not in the procedure?

I am currently trying to evaluate the performance of different methods for the same calculation and use codegen:cost to give me an overview on the rough computational effort for the results. I stumbled over the function counts not matching my own count in the optimized Matlab code generated by Maple.

Minimal example:

with(codegen):
Fcn1 := sqrt(a):
cost(Fcn1);
Fcn2 := sqrt(sin(q)):
cost(Fcn2);

The first expression gives me "2*functions+multiplications", the second one "3*functions+multiplications".

So my question: Does anyone know, why the square root is counted as two functions while the sine is counted correctly as one?

I am currently trying to solve a geometric problem where I have to calculate angles in two connected four bar linkages parallel to a serial chain of rotatory joints (closed-loop kinematic chain).

The angle is calculated with

 > alpha:=arctan(exp_y, exp_x):

The expressions exp_y and exp_x contain long products of sines and cosines of 6 other time-dependant angles, square roots of these products, constant geometric lengths (not time-dependant) and constant geometric angles (not time-dependant).

The lenghts are already assumed positive

 > assume (l1>0): # similar for all lengths l2, l3, ...

The time dependant angles are defined as

> qJ_t := Matrix(6, 1, [qJ1(t), qJ2(t), qJ3(t), qJ4(t), qJ5(t), qJ6(t)]): # generalized coordinates of the system in the sense of technical mechanics

Other assumptions are not set, since the angles can be positive as well as negative.

Calculating this expression takes up to two days on a fast computer. In my opinion this takes much too long compared to other calculations with similar amount of variables (more complex robotic structures).Also, the arctan function does not "calculate" a result, it just writes down "arctan(...)".

Is there a way to speed up this calculation e.g. by using more assumptions?

On the arctan help page, the examples suggest that Maple is trying to already simplify the solution e.g. by drawing Pi out of the solution.

 

 

 





 



I am having trouble removing assumptions that are stored within expresssions.

Example code:

assume(l1>0): # this assumptions later helps to find a solution for a geometric problem with two four-bar-linkages
a := sqrt(l1);
save a, "test.m";
restart;
read "test.m"
a; # the assumptions are stored within the saved data
l1:='l1'; # try to remove the assumption
a; # assumption in a still existing
subs({l1=2}, a); # nothing happens: I can not access l1 any more
subs({l1~=2}, a); # This does not work either, nothing changes in a

So my question is: How do I remove the assumption within a stored expression?

My main problem lies in the handling of the expression with assumptions. At some point, I want to generate Matlab code, and the codegen-command gives me:

Warning, the following variable name replacements were made: l1~ -> cg

 

Variable exists but is not shown when using save/read with extension .m

My example maple code is

 

a:=b^2:

save a, "test1.m"

restart:

read "test1.m"

a;

 

after the read command, I can access the variable, but it is not shown under "Variables".

This lead to some confusion when debugging the worksheet. Can I change this somehow?

Using the input type file format is not a solution, since then reading takes forever for complicated expressions.

Further, in the read command documentation it says "This functionality is not intended for end users" for saving the file as .m. What does that mean?

Page 1 of 1