Hi,
I am interested in logarithmic frequencies like logfreq, only being able
to shift them in time:
logfreq : 1,2,3,10,20,30,100,200,300,...
new : x+1,x+2,x+3,x+10,x+20,x+30,... (with x being a constant shift
factor)
to achieve this, I added a new math function, which is nothing else then
an if statement:
picklarger(x,y): if x>y then x else y
with this I can generate the desired frequency (specifically
logfreq(10,9,10)):
variable cStep equal step
picklarger(offset,cStep)+10^floor(log(picklarger(cStep-offset,1)))
Ok, now the trouble is two-fold:
1. I had to allow the power operator to accept '0.0' as exponent. Is
there any reason why this was not allowed, apart from the 'it will give
you 1 for all arguments'?
2. The formula above can not be evaluated.
I get (log-file):
...
variable t equal
picklarger(100000,v_currentStep)+10^floor(log(picklarger(v_currentStep-100000,1)))
print $t
ERROR: Invalid syntax in variable formula
I tracked the problem to 'log(picklarger(v_currentStep-100000,1))'. When
I assign the argument of the logarithm to a new variable and give the
variable as the argument, everything works as expected:
variable temp equal picklarger(v_currentStep-100000,1)
log(v_temp)
Does anyone have an idea what goes wrong during the recursive
evaluation? - and it is nothing log-specific... e.g. with floor it does
not work either...
In the following I will print the added lines in variable.cpp, and I am
using LAMMPS version 15.4.2011.
Any help is greatly appreciated! I can use the code right now, but I
don't want to create a large number of unnecessary variables...
Cheers,
Anton
mostly I am using the already existing define statement:
#define MIN(A,B) ((A) < (B)) ? (A) : (B)
#define MAX(A,B) ((A) > (B)) ? (A) : (B)
line 50 :
enum{DONE,ADD,SUBTRACT,MULTIPLY,DIVIDE,CARAT,UNARY,
NOT,EQ,NE,LT,LE,GT,GE,AND,OR,
SQRT,EXP,LN,LOG,SIN,COS,TAN,ASIN,ACOS,ATAN,ATAN2,
RANDOM,NORMAL,CEIL,FLOOR,ROUND,RAMP,STAGGER,LOGFREQ,
VDISPLACE,SWIGGLE,CWIGGLE,GMASK,RMASK,GRMASK,
VALUE,ATOMARRAY,TYPEARRAY,INTARRAY,PICKSMALLER,PICKLARGER};
in function 'collapse_tree' :
if (tree->type == PICKSMALLER) {
arg1 = collapse_tree(tree->left);
arg2 = collapse_tree(tree->right);
if (tree->left->type != VALUE || tree->right->type != VALUE) return
0.0;
if (arg1 < arg2 ) {
tree->type = VALUE;
tree->value = arg1 ;
return tree->value;
}
tree->type = VALUE;
tree->value = arg2;
return tree->value;
}
if (tree->type == PICKLARGER) {
arg1 = collapse_tree(tree->left);
arg2 = collapse_tree(tree->right);
if (tree->left->type != VALUE || tree->right->type != VALUE) return
0.0;
if (arg1 > arg2 ) {
tree->type = VALUE;
tree->value = arg1 ;
return tree->value;
}
tree->type = VALUE;
tree->value = arg2;
return tree->value;
}
in function 'eval_tree':
if (tree->type == PICKSMALLER) {
arg1 = eval_tree(tree->left,i);
arg2 = eval_tree(tree->right,i);
return MIN(arg1,arg2);
}
if (tree->type == PICKLARGER) {
arg1 = eval_tree(tree->left,i);
arg2 = eval_tree(tree->right,i);
return MAX(arg1,arg2);
}
in function 'math_function':
if (strcmp(word,"sqrt") && strcmp(word,"exp") &&
strcmp(word,"ln") && strcmp(word,"log") &&
strcmp(word,"sin") && strcmp(word,"cos") &&
strcmp(word,"tan") && strcmp(word,"asin") &&
strcmp(word,"acos") && strcmp(word,"atan") &&
strcmp(word,"atan2") && strcmp(word,"random") &&
strcmp(word,"normal") && strcmp(word,"ceil") &&
strcmp(word,"floor") && strcmp(word,"round") &&
strcmp(word,"ramp") && strcmp(word,"stagger") &&
strcmp(word,"logfreq") && strcmp(word,"vdisplace") &&
strcmp(word,"swiggle") && strcmp(word,"cwiggle") &&
strcmp(word,"picksmaller") && strcmp(word,"picklarger"))
return 0;
later in the same function:
else if (strcmp(word,"picksmaller") == 0) {
if (narg != 2) error->all("Invalid math function in variable
formula");
if (tree) newtree->type = PICKSMALLER;
else
argstack[nargstack++] = MIN(value1,value2);
} else if (strcmp(word,"picklarger") == 0) {
if (narg != 2) error->all("Invalid math function in variable
formula");
if (tree) newtree->type = PICKLARGER;
else
argstack[nargstack++] = MAX(value1,value2);
}