create a pdf of all bar-line plots appended together - pdf

i've created a series of plots using proc gbarline and I wish to export all plots to one pdf instead of just the first plot, I am having two issues:
the plot does not export to pdf unless I print the first plot twice, hence why I use the statement
%if &index. = 1 %then %do;
<statements>;
%end;
the pdf only contains the first plot
The code I use is below:
%macro test_pdf;
data snp (drop=i);
do i = 1 to 100;
y = ranuni(0);
x1 = ranuni(0) * 5;
x2 = ranuni(0) * 10;
x3 = ranuni(0) * 7;
x4 = ranuni(0) * 4;
x5 = ranuni(0) * 100;
x6 = ranuni(0) * 50;
x7 = ranuni(0) * 1000;
x8 = ranuni(0) * 10000;
x9 = ranuni(0) * 9999;
x10 = ranuni(0) * 5984;
x11 = ranuni(10) * 5;
x12 = ranuni(10) * 10;
x13 = ranuni(10) * 7;
x14 = ranuni(10) * 4;
x15 = ranuni(10) * 100;
x16 = ranuni(10) * 50;
x17 = ranuni(10) * 1000;
x18 = ranuni(10) * 10000;
x19 = ranuni(10) * 9999;
x20 = ranuni(10) * 5984;
x21 = ranuni(20) * 5;
x22 = ranuni(20) * 10;
x23 = ranuni(20) * 7;
x24 = ranuni(20) * 4;
x25 = ranuni(20) * 100;
x26 = ranuni(20) * 50;
x27 = ranuni(20) * 1000;
x28 = ranuni(20) * 10000;
x29 = ranuni(20) * 9999;
x30 = ranuni(20) * 5984;
x31 = ranuni(30) * 5;
x32 = ranuni(30) * 10;
x33 = ranuni(30) * 7;
x34 = ranuni(30) * 4;
x35 = ranuni(30) * 100;
x36 = ranuni(30) * 50;
x37 = ranuni(30) * 1000;
x38 = ranuni(30) * 10000;
x39 = ranuni(30) * 9999;
x40 = ranuni(30) * 5984;
output;
end;
run;
PROC CONTENTS DATA = snp OUT = snp_contents NOPRINT;
RUN;
PROC SQL NOPRINT;
SELECT name INTO: snp_factors
separated by " "
FROM snp_contents
WHERE varnum > 1;
SELECT name INTO: snp_response
FROM snp_contents
WHERE varnum = 1;
SELECT max(length(name)) INTO: max_length
FROM snp_contents;
QUIT;
ODS HTML CLOSE;
ODS HTML;
QUIT;
%LET timestamp = %sysfunc(putn(%sysfunc(date()),yymmddn8.));
%LET hourstamp = %sysfunc(compress(%sysfunc(TIME(),time.),%str( :)));
ODS TRACE ON;
ODS PDF FILE = "&ROOT\output_data\_&timestamp._&hourstamp._Histogram_gbarline.pdf";
ODS SELECT gbarlin;
%LET index = 1;
%DO %UNTIL (%SCAN(&snp_factors.,&index.," ")=);
%LET factors = %SCAN(&snp_factors.,&index.," ");
%IF &index. = 1 %THEN
%DO;
PROC GBARLINE DATA=snp
;
BAR &factors.
/
FRAME LEVELS=10
TYPE=PCT
MISSING
COUTLINE=BLACK
;
PLOT / SUMVAR=&snp_response.
TYPE=MEAN
;
RUN;
QUIT;
%END;
PROC GBARLINE DATA=snp
;
BAR &factors.
/
FRAME LEVELS=10
TYPE=PCT
MISSING
COUTLINE=BLACK
;
PLOT / SUMVAR=&snp_response.
TYPE=MEAN
;
RUN;
QUIT;
ODS PDF CLOSE;
%LET index = %EVAL(&Index + 1);
%END;
%mend;
%test_pdf;

You are closing the PDF inside the %DO %UNTIL loop.
Change
…
ODS PDF CLOSE;
%LET index = %EVAL(&Index + 1);
%END;
to
…
%LET index = %EVAL(&Index + 1);
%END;
ODS PDF CLOSE;
Because you closed inside the loop, only the first iteration was in the PDF output. The subsequent ODS PDF CLOSE statements inside the loop were accepted by SAS and discarded silently (no log messages) because the PDF destination was already closed.

Related

SAS solve optimization problem for each row of a dataset

I have a dataset like the following:
data have;
id=1; x1=10; x2=3; x3=5; y=220;
y1g=12; y2g=6; y3g=10;
output;
id=2; x1=7; x2=0; x3=3; y=100;
y1g=12; y2g=0; y3g=10;
output;
run;
for each record I want to had values for y1, y2, y3, such that
x1*y1+x2*y2+x3*y3=y
0=<y1<=12
0=<y2<=6
0=<y3<=10
I am not sure of which can be the objective function, but to fix the ideas
I might want that the solutions are as similar as possible to some initial guess, y1g ,y2g, y3g.
so for instance the objective might be:
min (y1-y1g)**2+(y2-y2g)**2+(y3-y3g)**2
I am using SAS9 M5 and have to apply the program to a dataset of about 100000 records.
can you suggest me with the proc optmodel code?
thank you very much in advance
Although your solution is infeasible with your constraints, this is what the optmodel code looks like:
proc optmodel;
set row;
num id;
num x1{row};
num x2{row};
num x3{row};
num y1g{row};
num y2g{row};
num y3g{row};
num y{row};
num y1sol{row};
num y2sol{row};
num y3sol{row};
var y1;
var y2;
var y3;
read data have into row=[id]
x1 x2 x3 y y1g y2g y3g
;
con con1: x1[id]*y1 + x2[id]*y2 + x3[id]*y3 = y[id];
con con2: 0 <= y1 <= 12;
con con3: 0 <= y2 <= 6;
con con4: 0 <= y3 <= 10;
min sum_squared_dif = ( (y1-y1g[id])**2+(y2-y2g[id])**2+(y3-y3g[id])**2 );
cofor {i in row} do;
id = i;
solve;
/* Save each individual solution */
y1sol[id] = y1.sol;
y2sol[id] = y2.sol;
y3sol[id] = y3.sol;
end;
print y1sol y1g y2sol y2g y3sol y3g;
quit;
Note that the first row has an infeasible solution.

Error when loading data into Postgres table from SAS(Invalid input syntax for integer)

Error when loading data into Postgres table from SAS(Invalid input syntax for integer)
I am using SAS Data Integration Studio with SCD Type 1 loader to load data into PostGres Table.
First of all, the issue that I am facing is the error message:
ERROR: CLI execute error: ERROR: invalid input syntax for integer: "1372.8"; Error while executing the query
I've searched the entire table(170 rows) and there is no data with the value of 1372.8 or even close to it.
The postgres table has a few non-nullable columns and i have made sure all 170 records contain values. There is no record with missing value.
However, I am getting this strange error. I have also browse through stackoverflow but it seems like this has nothing to do with SAS but postgres. However, the value that i load into postgres is of same data type, always numeric and i have no clue why is this error prompting.
Log file:
NOTE: Appending WORK.WVVOL13 to NETCAP.MasterAssetRenewable.
NOTE: FORCE is specified, so dropping/truncating will occur.
NOTE: There were 18 observations read from the data set WORK.WVVOL13.
NOTE: 17 observations added.
NOTE: The data set NETCAP.MasterAssetRenewable has . observations and 18 variables.
ERROR: CLI execute error: ERROR: invalid input syntax for integer: "1372.8";
Code from SCD Type 1 Loader:
/*==========================================================================*
* Step: SCD Type 1 A5KQQF32.C20002Y5 *
* Transform: SCD Type 1 *
* Description: *
* *
* Source Table: User Written - A5KQQF32.C90001ZV *
* work.ncp_asset_re_toloadnew *
* Target Tables: MasterAssetRenewable - A5KQQF32.BE0000X2 *
* netcap.MasterAssetRenewable *
* Cross reference - A5KQQF32.C90001ZW *
* work.MasterAssetRenewable_xref *
* Changed records - work.WVVOJQO A5KQQF32.C90001ZX *
* New records - work.WVVOL13 A5KQQF32.C90001ZY *
*==========================================================================*/
options VALIDVARNAME = ANY VALIDMEMNAME = EXTEND;
%let transformID = %quote(A5KQQF32.C20002Y5);
%let trans_rc = 0;
%let etls_stepStartTime = %sysfunc(datetime(), datetime20.);
%let SYSLAST = %nrquote(work."ncp_asset_re_toloadnew"n);
%macro etls_scd_type_1;
/*---- Delete any pre-existing work tables ----*/
proc datasets lib = work nolist nowarn memtype = (data view);
delete etls_xref;
quit;
proc datasets lib = work nolist nowarn memtype = (data view);
delete "WVVOJQO"n;
quit;
proc datasets lib = work nolist nowarn memtype = (data view);
delete "WVVOL13"n;
quit;
/* Determine if the table exists */
%let etls_tableExist = %eval(%sysfunc(exist(netcap."MasterAssetRenewable"n, DATA)) or
%sysfunc(exist(netcap."MasterAssetRenewable"n, VIEW)));
/*---- Create a new table ----*/
%if (&etls_tableExist eq 0) %then
%do; /* if table does not exist */
%put %str(NOTE: Creating table ...);
data netcap."MasterAssetRenewable"n
(dbnull = (
"Id"n = NO
"DetailType"n = NO
"DependableFactor"n = NO
"StatusType"n = NO
"DeclaredGenerationMd"n = NO
"ActualGenerationMd"n = NO
"BusinessAreaId"n = YES
"PmuId"n = YES
"PpuId"n = YES
"CreatedFromId"n = YES
"CustomerName"n = YES
"CustomerNumber"n = YES
"SsuId"n = YES
"FeederNo"n = YES
"Lat"n = YES
"Lng"n = YES
"ReCapacity"n = NO
"TargetCommDate"n = NO));
attrib "Id"n length = 8
format = 20.
informat = 20.
label = 'Id';
attrib "DetailType"n length = 8
format = 11.
informat = 11.
label = 'DetailType';
attrib "DependableFactor"n length = 8
label = 'DependableFactor';
attrib "StatusType"n length = 8
format = 11.
informat = 11.
label = 'StatusType';
attrib "DeclaredGenerationMd"n length = 8
label = 'DeclaredGenerationMd';
attrib "ActualGenerationMd"n length = 8
label = 'ActualGenerationMd';
attrib "BusinessAreaId"n length = 8
format = 20.
informat = 20.
label = 'BusinessAreaId';
attrib "PmuId"n length = 8
format = 20.
informat = 20.
label = 'PmuId';
attrib "PpuId"n length = 8
format = 20.
informat = 20.
label = 'PpuId';
attrib "CreatedFromId"n length = 8
format = 20.
informat = 20.
label = 'CreatedFromId';
attrib "CustomerName"n length = $1024
format = $1024.
informat = $1024.
label = 'CustomerName';
attrib "CustomerNumber"n length = $1024
format = $1024.
informat = $1024.
label = 'CustomerNumber';
attrib "SsuId"n length = 8
format = 20.
informat = 20.
label = 'SsuId';
attrib "FeederNo"n length = $1024
format = $1024.
informat = $1024.
label = 'FeederNo';
attrib "Lat"n length = 8
label = 'Lat';
attrib "Lng"n length = 8
label = 'Lng';
attrib "ReCapacity"n length = 8
format = 11.
informat = 11.
label = 'ReCapacity';
attrib "TargetCommDate"n length = 8
format = DATETIME25.6
informat = DATETIME25.6
label = 'TargetCommDate';
call missing(of _all_);
stop;
run;
%rcSet(&syserr);
/*---- Create the indexes for a table ----*/
%put %str(NOTE: Creating indexes ...);
%macro etls_createIndexes;
proc sql;
connect to POSTGRES
(
DATABASE=netcap SERVER="unadevsaswas01.hq.tnb.com.my" AUTHDOMAIN="NetcapAuth"
);
reset noprint;
execute
(
create index "IX_MasterAssetRenewable_PpuId"
on "MasterAssetRenewable"
("PpuId")
) by POSTGRES;
%rcSet(&sqlrc);
execute
(
create index "IX_MasterAssetRenewable_PmuId"
on "MasterAssetRenewable"
("PmuId")
) by POSTGRES;
%rcSet(&sqlrc);
execute
(
create index "IX_MasterAssetRenewable_CreatedFromId"
on "MasterAssetRenewable"
("CreatedFromId")
) by POSTGRES;
%rcSet(&sqlrc);
execute
(
create index "IX_MasterAssetRenewable_BusinessAreaId"
on "MasterAssetRenewable"
("BusinessAreaId")
) by POSTGRES;
%rcSet(&sqlrc);
execute
(
create index "IX_MasterAssetRenewable_SsuId"
on "MasterAssetRenewable"
("SsuId")
) by POSTGRES;
%rcSet(&sqlrc);
disconnect from POSTGRES;
quit;
%rcSet(&sqlrc);
%mend etls_createIndexes;
%etls_createIndexes;
/*---- Create the integrity constraints for a table ----*/
%put %str(NOTE: Creating integrity constraints ...);
proc sql;
connect to POSTGRES
(
DATABASE=netcap SERVER="unadevsaswas01.hq.tnb.com.my" AUTHDOMAIN="NetcapAuth"
);
reset noprint;
execute
(
alter table "MasterAssetRenewable"
add primary key ("Id")
) by POSTGRES;
%rcSet(&sqlrc);
execute
(
alter table "MasterAssetRenewable"
add foreign key ("PmuId") references "MasterAssetPmu"
) by POSTGRES;
%rcSet(&sqlrc);
execute
(
alter table "MasterAssetRenewable"
add foreign key ("PpuId") references "MasterAssetPpu"
) by POSTGRES;
%rcSet(&sqlrc);
disconnect from POSTGRES;
quit;
%rcSet(&sqlrc);
%end; /* if table does not exist */
/* Determine if the table exists */
%let etls_tableExist = %eval(%sysfunc(exist(work."MasterAssetRenewable_xref"n, DATA)) or
%sysfunc(exist(work."MasterAssetRenewable_xref"n, VIEW)));
/*---- Create a new table ----*/
%if (&etls_tableExist eq 0) %then
%do; /* if table does not exist */
%put %str(NOTE: Creating table ...);
data work."MasterAssetRenewable_xref"n;
attrib "Id"n length = 8
format = 20.
informat = 20.
label = 'Id';
attrib "compare_digest"n length = $32
format = $32.
informat = $32.;
call missing(of _all_);
stop;
run;
%rcSet(&syserr);
/*---- Create the integrity constraints for a table ----*/
%put %str(NOTE: Creating integrity constraints ...);
proc datasets library=work nolist;
modify "MasterAssetRenewable_xref"n;
ic create not null ("Id"n);
quit;
%rcSet(&syserr);
%end; /* if table does not exist */
proc datasets lib = work nolist nowarn memtype = (data view);
delete W159RVJL;
quit;
proc sql;
create view work.W159RVJL as
select
"Id"n
format = 20.
informat = 20.,
"DetailType"n,
"DependableFactor"n,
"StatusType"n,
"DeclaredGenerationMd"n,
"ActualGenerationMd"n,
"BusinessAreaId"n,
"PmuId"n
format = 20.
informat = 20.,
"PpuId"n
format = 20.
informat = 20.,
"CreatedFromId"n,
"CustomerName"n length = 1024
format = $1024.
informat = $1024.,
"CustomerNumber"n length = 1024
format = $1024.
informat = $1024.,
"SsuId"n,
"FeederNo"n length = 1024
format = $1024.
informat = $1024.,
"Lat"n,
"Lng"n,
"ReCapacity"n
format = 11.
informat = 11.,
"TargetCommDate"n
format = DATETIME25.6
informat = DATETIME25.6
from work."ncp_asset_re_toloadnew"n
;
quit;
%let SYSLAST = work.W159RVJL;
/* create work xref table */
data work.etls_xref(keep = Id compare_digest);
length compare_digest $ 32;
set netcap."MasterAssetRenewable"n( keep = Id ReCapacity FeederNo DeclaredGenerationMd);
/* create digest - version 2.1 */
compare_digest = put(md5(catq(' ', ReCapacity, FeederNo, DeclaredGenerationMd)), $hex32.);
run;
%rcSet(&syscc);
/*---- SCD Type 1 processing: hash lookup method ----*/
data
/* Changed Records Table */
work."WVVOJQO"n( keep = Id ReCapacity FeederNo DeclaredGenerationMd compare_digest)
/* New Records Table */
work."WVVOL13"n;
drop source_digest;
length source_digest $ 32;
if 0 then
set work.etls_xref;
if _N_ eq 1 then
do;
declare hash hct(dataset: 'work.etls_xref', hashexp: 10);
hct.defineKey("Id");
hct.defineData("Id", "compare_digest");
hct.defineDone();
end;
set work.W159RVJL;
/* create digest - version 2.1 */
source_digest = put(md5(catq(' ', ReCapacity, FeederNo, DeclaredGenerationMd)), $hex32.);
/* match */
if hct.find() eq 0 then
do;
/* scd type 1 records */
if source_digest ne compare_digest then
do;
compare_digest = source_digest;
output work."WVVOJQO"n;
end;
end;
/* new records */
else if hct.find() ne 0 then
do;
compare_digest = source_digest;
output work."WVVOL13"n;
end;
run;
%rcSet(&syscc);
/* changed records table - record check */
%let etls_recCheckExist = 0;
%let etls_change_rows = 0;
%macro etls_recordCheck;
%let etls_recCheckExist = %eval(%sysfunc(exist(work."WVVOJQO"n, DATA)) or
%sysfunc(exist(work."WVVOJQO"n, VIEW)));
%if (&etls_recCheckExist) %then
%do;
%local etls_syntaxcheck;
%let etls_syntaxcheck = %sysfunc(getoption(syntaxcheck));
/* Turn off syntaxcheck option to perform following steps */
options nosyntaxcheck;
data _null_;
set work."WVVOJQO"n( obs=1 );
call symput("etls_change_rows",'1');
run;
/* Reset syntaxcheck option to previous setting */
options &etls_syntaxcheck;
%end;
%mend etls_recordCheck;
%etls_recordCheck;
%rcSet(&syscc);
/* new records table - record check */
%let etls_recCheckExist = 0;
%let etls_new_rows = 0;
%macro etls_recordCheck;
%let etls_recCheckExist = %eval(%sysfunc(exist(work."WVVOL13"n, DATA)) or
%sysfunc(exist(work."WVVOL13"n, VIEW)));
%if (&etls_recCheckExist) %then
%do;
%local etls_syntaxcheck;
%let etls_syntaxcheck = %sysfunc(getoption(syntaxcheck));
/* Turn off syntaxcheck option to perform following steps */
options nosyntaxcheck;
data _null_;
set work."WVVOL13"n( obs=1 );
call symput("etls_new_rows",'1');
run;
/* Reset syntaxcheck option to previous setting */
options &etls_syntaxcheck;
%end;
%mend etls_recordCheck;
%etls_recordCheck;
%rcSet(&syscc);
/*---- target table: update/append rows ----*/
/* target table: update change rows */
%if &etls_change_rows ge 1 %then
%do;
proc sql;
update netcap."MasterAssetRenewable"n as m
set "ReCapacity"n = (select "ReCapacity"n from work."WVVOJQO"n as t
where m."Id"n = t."Id"n),
"FeederNo"n = (select "FeederNo"n from work."WVVOJQO"n as t
where m."Id"n = t."Id"n),
"DeclaredGenerationMd"n = (select "DeclaredGenerationMd"n from work."WVVOJQO"n as t
where m."Id"n = t."Id"n)
where exists (select * from work."WVVOJQO"n as t
where m."Id"n = t."Id"n);
quit;
%rcSet(&syscc);
%end;
/* target table - append new rows */
%if &etls_new_rows ge 1 %then
%do;
proc append base = netcap."MasterAssetRenewable"n
data = work."WVVOL13"n force nowarn;
run;
%rcSet(&syscc);
%end;
/*---- cross reference table: update/append rows ----*/
/* cross reference table: update change rows */
%if &etls_change_rows ge 1 %then
%do;
proc sql;
update work."MasterAssetRenewable_xref"n as m
set compare_digest = (select compare_digest from work."WVVOJQO"n as t
where m."Id"n = t."Id"n)
where exists (select * from work."WVVOJQO"n as t
where m."Id"n = t."Id"n);
quit;
%rcSet(&syscc);
%end;
/* cross reference table - append new rows */
%if &etls_new_rows ge 1 %then
%do;
proc append base = work."MasterAssetRenewable_xref"n
data = work."WVVOL13"n( keep = Id compare_digest)
force nowarn;
run;
%rcSet(&syscc);
%end;
/* Delete work.etls_xref table */
proc datasets lib = work nolist nowarn memtype = (data view);
delete etls_xref;
quit;
%mend etls_scd_type_1;
/* execute etls_scd_type_1 */
%etls_scd_type_1
/** Step end SCD Type 1 **/

How do I transpose only single column keeping one column the same?

How do I transpose like this?
I know to Transpose it altogether but this one i am not familiar with.
This should do the job:
data a;
cust = "A";
channels = 20;
output;
cust = "A";
channels = 30;
output;
cust = "A";
channels = 40;
output;
cust = "B";
channels = 200;
output;
cust = "B";
channels = 300;
output;
cust = "B";
channels = 0;
output;
run;
proc transpose data=a out=b;
by cust;
var channels;
run;

OpenCL kernel doesn't finish executing

I am writing a simple monte carlo code for simulation of electron scattering. I ran the Kernel for 10 million electron and it runs fine, but when I increase the number of electrons to a higher number, say 50 million, the code just wouldn't finish and the computer freezes. I wanted to know if this is a hardware issue or if there is a possible bug in the code. I am running the code on a iMac with ATI Radeon HD 5870.
int rand_r (unsigned int seed)
{
unsigned int next = seed;
int result;
next *= 1103515245;
next += 12345;
result = (unsigned int) (next / 65536) % 2048;
next *= 1103515245;
next += 12345;
result <<= 10;
result ^= (unsigned int) (next / 65536) % 1024;
next *= 1103515245;
next += 12345;
result <<= 10;
result ^= (unsigned int) (next / 65536) % 1024;
seed = next;
return result;
}
__kernel void MC(const float E, __global float* bse, const int count) {
int tx, ty;
tx = get_global_id(0);
ty = get_global_id(1);
float RAND_MAX = 2147483647.0f;
int rand_seed;
int seed = count*ty + tx;
float rand;
float PI;
PI = 3.14159f;
float z;
z = 28.0f;
float rho;
rho = 8.908f;
float A;
A = 58.69f;
int num;
num = 10000000/(count*count);
int counter, counter1, counter2;
counter = 0;
float4 c_new, r_new;
float E_new, alpha, de_ds, phi, psi, mfp,sig_eNA,step, dsq, dsqi, absc0z;
float J;
J = (9.76f*z + 58.5f*powr(z,-0.19f))*1E-3f;
float4 r0 = (float4)(0.0f, 0.0f, 0.0f, 0.0f);
float2 tilt = (float2)((70.0f/180.0f)*PI , 0.0f);
float4 c0 = (float4)(cos(tilt.y)*sin(tilt.x), sin(tilt.y)*sin(tilt.x), cos(tilt.x), 0.0f);
for (int i = 0; i < num; ++i){
rand_seed = rand_r(seed);
seed = rand_seed;
rand = rand_seed/RAND_MAX; //some random no. generator in gpu
r0 = (float4)(0.0f, 0.0f, 0.0f, 0.0f);
c0 = (float4)(cos(tilt.y)*sin(tilt.x), sin(tilt.y)*sin(tilt.x), cos(tilt.x), 0.0f);
E_new = E;
c_new = c0;
alpha = (3.4E-3f)*powr(z,0.67f)/E_new;
sig_eNA = (5.21f * 602.3f)*((z*z)/(E_new*E_new))*((4.0f*PI)/(alpha*(1+alpha)))*((E_new + 511.0f)*(E_new + 511.0f)/((E_new + 1024.0f)*(E_new + 1024.0f)));
mfp = A/(rho*sig_eNA);
step = -mfp * log(rand);
r_new = (float4)(r0.x + step*c_new.x, r0.y + step*c_new.y, r0.z + step*c_new.z, 0.0f);
r0 = r_new;
counter1 = 0;
counter2 = 0;
while (counter1 < 1000){
alpha = (3.4E-3f)*powr(z,0.67f)/E_new;
sig_eNA = (5.21f * 602.3f)*((z*z)/(E_new*E_new))*((4*PI)/(alpha*(1+alpha)))*((E_new + 511.0f)*(E_new + 511.0f)/((E_new + 1024.0f)*(E_new + 1024.0f)));
mfp = A/(rho*sig_eNA);
rand_seed = rand_r(seed);
seed = rand_seed;
rand = rand_seed/RAND_MAX; //some random no. generator in gpu
step = -mfp * log(rand);
de_ds = -78500.0f*(z/(A*E_new)) * log((1.66f*(E_new + 0.85f*J))/J);
rand_seed = rand_r(seed);
seed = rand_seed;
rand = rand_seed/RAND_MAX; //new random no.
phi = acos(1 - ((2*alpha*rand)/(1 + alpha - rand)));
rand_seed = rand_r(seed);
seed = rand_seed;
rand = rand_seed/RAND_MAX; //third random no.
psi = 2*PI*rand;
if ((c0.z >= 0.999f) || (c0.z <= -0.999f) ){
absc0z = abs(c0.z);
c_new = (float4)(sin(phi) * cos(psi), sin(phi) * sin(psi), (c0.z/absc0z)*cos(phi), 0.0f);
}
else {
dsq = sqrt(1-c0.z*c0.z);
dsqi = 1/dsq;
c_new = (float4)(sin(phi)*(c0.x*c0.z*cos(psi) - c0.y*sin(psi))*dsqi + c0.x*cos(phi), sin(phi) * (c0.y * c0.z * cos(psi) + c0.x * sin(psi)) * dsqi + c0.y * cos(phi), -sin(phi) * cos(psi) * dsq + c0.z * cos(phi), 0.0f);
}
r_new = (float4)(r0.x + step*c_new.x, r0.y + step*c_new.y, r0.z + step*c_new.z, 0.0f);
r0 = r_new;
c0 = c_new;
E_new += step*rho*de_ds;
if (r0.z <= 0 && counter2 == 0){
counter++ ;
counter2 = 1;
}
counter1++ ;
}
}
bse[count*ty + tx] = counter;
}

Return CATransform3D to map quadrilateral to quadrilateral

I'm trying to derive a CATransform3D that will map a quad with 4 corner points to another quad with 4 new corner points. I've spent a little bit of time researching this and it seems the steps involve converting the original Quad to a Square, and then converting that Square to the new Quad. My methods look like this (code borrowed from here):
- (CATransform3D)quadFromSquare_x0:(float)x0 y0:(float)y0 x1:(float)x1 y1:(float)y1 x2:(float)x2 y2:(float)y2 x3:(float)x3 y3:(float)y3 {
float dx1 = x1 - x2, dy1 = y1 - y2;
float dx2 = x3 - x2, dy2 = y3 - y2;
float sx = x0 - x1 + x2 - x3;
float sy = y0 - y1 + y2 - y3;
float g = (sx * dy2 - dx2 * sy) / (dx1 * dy2 - dx2 * dy1);
float h = (dx1 * sy - sx * dy1) / (dx1 * dy2 - dx2 * dy1);
float a = x1 - x0 + g * x1;
float b = x3 - x0 + h * x3;
float c = x0;
float d = y1 - y0 + g * y1;
float e = y3 - y0 + h * y3;
float f = y0;
CATransform3D mat;
mat.m11 = a;
mat.m12 = b;
mat.m13 = 0;
mat.m14 = c;
mat.m21 = d;
mat.m22 = e;
mat.m23 = 0;
mat.m24 = f;
mat.m31 = 0;
mat.m32 = 0;
mat.m33 = 1;
mat.m34 = 0;
mat.m41 = g;
mat.m42 = h;
mat.m43 = 0;
mat.m44 = 1;
return mat;
}
- (CATransform3D)squareFromQuad_x0:(float)x0 y0:(float)y0 x1:(float)x1 y1:(float)y1 x2:(float)x2 y2:(float)y2 x3:(float)x3 y3:(float)y3 {
CATransform3D mat = [self quadFromSquare_x0:x0 y0:y0 x1:x1 y1:y1 x2:x2 y2:y2 x3:x3 y3:y3];
// invert through adjoint
float a = mat.m11, d = mat.m21, /* ignore */ g = mat.m41;
float b = mat.m12, e = mat.m22, /* 3rd col*/ h = mat.m42;
/* ignore 3rd row */
float c = mat.m14, f = mat.m24;
float A = e - f * h;
float B = c * h - b;
float C = b * f - c * e;
float D = f * g - d;
float E = a - c * g;
float F = c * d - a * f;
float G = d * h - e * g;
float H = b * g - a * h;
float I = a * e - b * d;
// Probably unnecessary since 'I' is also scaled by the determinant,
// and 'I' scales the homogeneous coordinate, which, in turn,
// scales the X,Y coordinates.
// Determinant = a * (e - f * h) + b * (f * g - d) + c * (d * h - e * g);
float idet = 1.0f / (a * A + b * D + c * G);
mat.m11 = A * idet; mat.m21 = D * idet; mat.m31 = 0; mat.m41 = G * idet;
mat.m12 = B * idet; mat.m22 = E * idet; mat.m32 = 0; mat.m42 = H * idet;
mat.m13 = 0 ; mat.m23 = 0 ; mat.m33 = 1; mat.m43 = 0 ;
mat.m14 = C * idet; mat.m24 = F * idet; mat.m34 = 0; mat.m44 = I * idet;
return mat;
}
After calculating both matrices, multiplying them together, and assigning to the view in question, I end up with a transformed view, but it is wildly incorrect. In fact, it seems to be sheared like a parallelogram no matter what I do. What am I missing?
UPDATE 2/1/12
It seems the reason I'm running into issues may be that I need to accommodate for FOV and focal length into the model view matrix (which is the only matrix I can alter directly in Quartz.) I'm not having any luck finding documentation online on how to calculate the proper matrix, though.
I was able to achieve this by porting and combining the quad warping and homography code from these two URLs:
http://forum.openframeworks.cc/index.php/topic,509.30.html
http://forum.openframeworks.cc/index.php?topic=3121.15
UPDATE: I've open sourced a small class that does this: https://github.com/dominikhofmann/DHWarpView