*
;
options nosource;
%macro differ3d ( data, out, x, y, z, m, sorts );
options nosource nostimer nonotes nosymbolgen;
/* developed by Arnold Schick, ACC at the University of Marburg/Germany
22. Dec. 1992 */
%if &data = and &out = %then %do;
%put ;
%put macro-call : DIFFER3D(in,out, x,y,z, m, sort);
%put ;
%put this macro differs Z=F(X,Y) to X.;
%put M corrects a slope on Z at X by that given value of M.;
%put SORT directs macro for sorting input data set IN by X Y.;
%put The result is written into dataset OUT.;
%put ;
%goto final;
%end;
%if &data = or &data = . %then %let data = _LAST_ ;
%if &out = or &out = . %then %goto quit;
%if &x = or &x = . %then %let x=x;
%if &y = or &y = . %then %let y=y;
%if &z = or &z = . %then %let z=z;
data _null_;
b = symget ('m') / 1;
if b = . then b = 0;
call symput('m',b);
run;
%if &sorts = sort or &sorts = . or &sorts = %then %do;
proc sort data = &data out = &out;
by &x &y;
run;
%end;
%else %do;
data &out;
set &data;
run;
%end;
data _null_ ;
set &out;
if _N_ = 1 then call symput('y_1', &y);
if _N_ = 2 then call symput('y_2', &y);
if _N_ = 3 then do; call symput('y_3', &y); stop; end;
run;
data anfang(keep= &x dz_start);
set &out ;
x1 = lag( &x );
y1 = lag( &y );
z1 = lag( &z ) + &m * &y;
if y1 = &y then delete;
if &y_2 = &y or &y_3 = &y then do;
dz = ( &z + &m * &y - z1 )/( &y - y1 );
dz_b = lag(dz);
if &y_3 = &y then do;
dz_start = 2*dz_b - dz;
output anfang;
end;
end;
run;
data &out;
set &out;
merge &out anfang;
by &x;
length z_diff 8 ;
y_previo = lag( &y );
z_previo = lag( &z ) + &m * &y;
if &y = y_previo then delete;
if &y_1 = &y then z_diff = dz_start;
else if &m ^= 0 then z_diff = -(z_previo - &z + &y * &m)
/( &y - y_previo);
else z_diff = -(z_previo - &z)
/( &y - y_previo);
drop y_previo z_previo dz_start;
run;
%goto final ;
%quit : %put HALT: please define OUT data set (2nd parameter) ;
%final : ;
options source stimer notes;
%mend differ3d; options source;
/*
*Example;
data eins; * data-example one;
do x=0 to 1 by 0.05;
do y=0 to 2 by 0.1;
z=exp(-x*y)/(2-cos(x*y))*sin(y-x);
output;
end;
end;
run;
data eins; * data-example two;
do x=-5 to 5 by 0.25;
do y=-5 to 5 by 0.25;
z = sin(sqrt(x*x + y*y));
output;
end;
end;
run;
data eins; *data-example three;
do i=1 to 30;
x=10*ranuni(33)-5;
y=10*ranuni(35)-5;
z=sin(sqrt(x*x + y*y));
output;
end;
run;
proc g3grid data=eins out=eins;
grid x*y=z / spline
axis1=-5 to 5 by 0.25
axis2=-5 to 5 by 0.25;
run;
proc sort data=eins out=eins;
by x y;
run; *end of data-example three;
%differ3d; *produces info;
%differ3d (eins, zwei, x, y, z,-0.0025,nosort); *F(x,y)/dx;
%differ3d (eins, drei, y, x, z,.,sort); *F(x,y)/dy;
%differ3d (drei, sechs, x, y, z_diff,0,sort); *F(x,y)/dx/dy;
%differ3d (zwei, fuenf, y, x, z_diff,,sort); *F(x,y)/dy/dx;
title 'orginal function';
proc g3d data=eins;
plot y*x=z;
run;
title 'deriviation partial to X';
proc g3d data=zwei;
plot y*x=z_diff ;
run;
title 'deriviation partial to Y';
proc g3d data=drei;
plot y*x=z_diff;
run;
title 'deriviation partial to XY';
proc g3d data=fuenf;
plot y*x=z_diff;
run;
title 'deriviation partial to YX';
proc g3d data=sechs;
plot y*x=z_diff;
run;
*building of total deriviation;
proc sort data=drei out=drei; by x y; run;
data vier;
set drei (rename=(z_diff=zz_diff));
merge drei zwei;
by x y;
z_diff = zz_diff+z_diff;
run;
title 'deriviation total to X and Y';
proc g3d data=vier;
plot y*x=z_diff;
run;
*End of Example;
*/
*;