teh_allchemist

50 Reputation

6 Badges

12 years, 23 days

MaplePrimes Activity


These are replies submitted by teh_allchemist

@acer 

Thank you!  This is exactly what I was looking for.  I definately would not gotten this by myself.

@Carl Love 

Thanks Carl, this was exactly what I was looking for!

@acer 

Hi Acer,

Thanks for this approach.  I had never thought of using CodeGeneration[Matlab].  This sounds like a great option, because I may be able to keep most things in Matlab, and therefore won't run into Maple's memory problems.  Additionally, if I can use a faster language (ie, Fortran or C) I may be able to get a much needed speedup.

I'm having some problems figuring out the syntax, I've tried using similar code in the Maple help files:

http://www.maplesoft.com/support/help/Maple/view.aspx?path=examples/CodeGeneration

What I need to achieve is very similar to the last example.  I have a symbolic solution converted into a procedure using unapply().  In the online example, Codegeneration changes the piecewise function to an if-statement.  I tried downloading this sheet and running it in Maple 17.  I do not get the same output.

Here is what I get:

Fortran(p, declare = [v::float]);
Warning, the function names {piecewise} are not recognized in the target language
Warning, procedure/module options ignored
doubleprecision function p (v)
doubleprecision v
p = piecewise(v .lt. 0.1D1, 0.23D2 / 0.28D2 * v ** 3 + 0.5D1 / 0
#.28D2 * v, v .lt. 0.2D1, -0.59D2 / 0.28D2 * v ** 3 + 0.123D3 / 0.1
#4D2 * v ** 2 - 0.241D3 / 0.28D2 * v + 0.41D2 / 0.14D2, v .lt. 0.3D
#1, 0.45D2 / 0.28D2 * v ** 3 - 0.27D2 / 0.2D1 * v ** 2 + 0.1007D4 /
# 0.28D2 * v - 0.375D3 / 0.14D2, -0.9D1 / 0.28D2 * v ** 3 + 0.27D2
#/ 0.7D1 * v ** 2 - 0.451D3 / 0.28D2 * v + 0.177D3 / 0.7D1)
return
end

Here is a link to what I'm trying to achieve is very similar, except there are more than 1 piecewise function, and 5 inputs instead of one.  Series_addGear_codegen.mw

MCode:=CodeGeneration[Matlab](unapp, declare = [FD_T::float, FD_W::float, GB_R::float, ICE_T::float, ICE_W::float])

Warning, inserted missing semicolon at end of statement
Warning, the function names {piecewise} are not recognized in the target language
Warning, procedure/module options ignored
Warning, cannot translate set
Error, (in Print) invalid input: printtab[CodeGeneration:-Names:-Set] uses a 2nd argument, x, which is missing

Is there something I am missing, or does CodeGeneration not work anymore?

Thanks in advance for any advice!

 

EDIT:

I updated from Maple 17 to Maple 18 and the codegeneration works now.  However, I'm having problems putting the data in a format that I can use, and also that Matlab can understand.  I've created a new thread for this, which can be found:

http://www.mapleprimes.com/questions/201784-CodeGeneration--Outputting-Multiple-Entries?sq=201784

 

 

@itsme 

Thanks for the tip about the JAVAHEAP.  I found the entry, but I don't have administrator access to change the file so I will have to ask my Admin on Monday.

I ran the program up to 140k, and it froze.  I noticed tha the VSZ (virtual memory size) was huge.  I am unsure if this is a problem, but it does seem rather large at ~6GB.

 

@itsme 

So itsme, I took your advice and rewrote the dump part of my code, here is what it looks like now:

while tt < num_sys_eqs
%Increment and define solve range indexes
tt_min = tt+1;
tt_max = tt_min + Max_AnsVec_Size-1;
tt = tt_max;
if tt_max > num_sys_eqs
tt_max = num_sys_eqs;
end

%Clear memory and display times
if tt_min == 1 || tt_max == num_sys_eqs
disp(sprintf('Solving system %i to %i of %i',tt_min,tt_max,num_sys_eqs));
else
disp(sprintf('Solving system %i to %i of %i. Systems solved per second: %0.1f. Mins left: %0.2f. ',tt_min,tt_max,num_sys_eqs, ...
((tt_max-tt_min)/(solvertime_f-solvertime_i)),(num_sys_eqs-tt_min)/60/((tt_max-tt_min)/(solvertime_f-solvertime_i)) ));
end
solvertime_i = toc;

%Load controlpoints into maple
disp(sprintf('Loading controlpoints...'));
disp(sprintf('Maple memory: %.0f MB', int32(maple('kernelopts(bytesalloc)/1024/1024'))))
maple(['Contolpoints_vector := ', MatlabMatrix_toMapleMatrix(double(ControlPoints_Dataset(tt_min:tt_max,2:end))) ]);
maple(['BB_timevec := ', MatlabVec_to_MapleVec(ControlPoints_Dataset.time(tt_min:tt_max))]);
maple(['for i from 1 to Size(BB_timevec)[2] do ' ...
'BB_Driverlist_set(i):= convert(Equate(collected_component_input_eqs,Contolpoints_vector[i]),set) union {time = BB_timevec[i]}; ' ...
'od;']);

%Plug into drivers into solver
disp(sprintf('Solving via maple...'));
disp(sprintf('Maple memory: %.0f MB', int32(maple('kernelopts(bytesalloc)/1024/1024'))))

maple(['' ...
'for SimNum from 1 to Size(BB_timevec)[2] do ' ...
'Raw_Ans:= symb_sol(Contolpoints_vector[SimNum][])[1] union BB_Driverlist_set(SimNum); ' ...
'if SimNum = 1 then ' ...
'Ordered_Answer_Varnames:=[indets(Raw_Ans)[]];' ...
'AnsMatrix:=Matrix(',num2str(tt_max-tt_min+1),',nops(Ordered_Answer_Varnames), datatype=float[8])' ...
'fi;' ...
'for nVar from 1 to nops(Ordered_Answer_Varnames) do' ...
' AnsMatrix(SimNum,nVar):=rhs(Raw_Ans[nVar]);' ...
'end;' ...
'od;']);

%Turn into dataset and dump solutions
BatchDS = dataset();
for numVarnames = 1:int32(maple('nops(Ordered_Answer_Varnames)'))
VarName = char(maple(['Ordered_Answer_Varnames[',num2str(numVarnames),']']));
NumVec = single(maple(['AnsMatrix(1..-1,',num2str(numVarnames),')']));
tempDS = dataset({NumVec,VarName});
BatchDS = [BatchDS,tempDS];
end
VehicleStateSpace_LUT = [VehicleStateSpace_LUT;BatchDS];
clear BatchDS

disp(sprintf('Done solve...'));
disp(sprintf('Maple memory: %.0f MB', int32(maple('kernelopts(bytesalloc)/1024/1024'))))
solvertime_f = toc;
maple('AnsMatrix:=0');
maple('dummya:=0');
maple('dummyb:=0');
maple('dummyc:=0');
maple('gc();');
end

 

With a maximum matrix size of [50000 x n], it didn't seem to make much of a difference.  Here is the output:

There are 6 drivers and 12 unknowns
Solving system 1 to 50000 of 231192
Loading controlpoints...
Maple memory: 38 MB
Solving via maple...
Maple memory: 532 MB
Done solve...
Maple memory: 1020 MB
Solving system 50001 to 100000 of 231192.  Systems solved per second:  806.4.  Mins left: 3.75.
Loading controlpoints...
Maple memory: 1020 MB
Solving via maple...
Maple memory: 1020 MB
Done solve...
Maple memory: 1219 MB
Solving system 100001 to 150000 of 231192.  Systems solved per second:  1160.0.  Mins left: 1.88.
Loading controlpoints...
Maple memory: 1219 MB
Solving via maple...

...


Done solve...
Maple memory: 1553 MB
Solving system 200001 to 231192 of 231192
Loading controlpoints...
Maple memory: 1546 MB
Solving via maple...
Maple memory: 1546 MB
Done solve...
Maple memory: 1583 MB


It appears that the maximum memory would keep increasing without an upper bound.  I saw your second post, and tried decreasing the maximum matrix size to 1000.  Here is the output:

There are 6 drivers and 12 unknowns
Solving system 1 to 1000 of 231192
Loading controlpoints...
Maple memory: 38 MB
Solving via maple...
Maple memory: 70 MB
Done solve...
Maple memory: 70 MB
Solving system 1001 to 2000 of 231192. Systems solved per second: 1616.4. Mins left: 2.37.

...

Loading controlpoints...
Maple memory: 72 MB
Solving via maple...
Maple memory: 72 MB
Done solve...
Maple memory: 72 MB
Solving system 229001 to 230000 of 231192. Systems solved per second: 1237.0. Mins left: 0.03.
Loading controlpoints...
Maple memory: 72 MB
Solving via maple...
Maple memory: 72 MB
Done solve...
Maple memory: 72 MB
Solving system 230001 to 231000 of 231192. Systems solved per second: 1258.6. Mins left: 0.02.
Loading controlpoints...
Maple memory: 72 MB
Solving via maple...
Maple memory: 72 MB
Done solve...
Maple memory: 72 MB
Solving system 231001 to 231192 of 231192
Loading controlpoints...
Maple memory: 72 MB
Solving via maple...
Maple memory: 72 MB
Done solve...
Maple memory: 72 MB

Interesting enough, this somehow gotten rid of the memory increasing problem!  I don't know if I will still encounter the segmentation fault problem, but I will keep you updated :)

 

EDIT:  I tried this with a larger system, and the memory allocated to maple's kernel keeps increasing...  However it does increase at a much slower rate.  Still waiting for a crash.

@itsme 

Hi itsme, thanks for the feedback.  I really appreciate the time you've taken to look at my code :)

I am using the hybrid approach because, I have a dynamic program algorithm written in MATLAB that accepts the output of this algorithm.  It runs quite efficiently and I would like to keep using it.  I require symbolics because my equation formulation is based on the Graph Therorhetic Model (same fomulation that MapleSim uses), and the Maple solver works better than the Matlab symbolic toolbox.

The only variables I am casting in int32 is the matrix dimension.  Everything else is a list of floats.

The way I am calcuating Maple's memory usage is by comparing the values of maple('evalf(kernelopts(bytesused)/1024/1024)')) before and after the answer vector is created.  If garbage collection is working correctly, I would expect the behaviour:

LOOP

%Frees up the memory in the maple kernel
maple(['Ans:= Ans * 0']);

%Since the answer vector is consistent in every iteration, the memory allocation to maple should be the same.  However after each loop the memory allcoated to maple kernel increases

maple(['' ...
'for i from 1 to Size(BB_timevec)[2] do ' ...
'Ans[i]:= symb_sol(Contolpoints_vector[i][])[1] union BB_Driverlist_set(i); ' ...
'od;']);

END LOOP

 

Thanks for the coded solution, I see that we have come to a similar conclusion that where we export the matrix.  Inside the 'MapleToMatlabMemoryDump', I have a loop that exports the Maple solutions to Matlab.

%Export solutions to Matlab

for jj = 1:num_symvarnames
RawDataMatrix(:,jj)=double(maple(['convert(map(x->rhs(Ans(x)[',num2str(jj),']),Valid_ts),Vector)']));
end

 

I am unsure if this problem is related to the amount of memory that maple is allocating because the segmentation fault seems to occur even when the amount of memory allocated to Maple Kernel is within a reasonable amount of memory (1.2gb).

@itsme 

I've tried numerous times to get the Maple/Matlab link to work.  I've settled on using the toolbox, which works great for my condition, but crashes every so often.

Matlab stores the information much more efficiently.  For 50k systems of solutions, each with 20 variables, Matlab takes 7.63MB in memory to store this system in a Dataset (calculated using this code).  Maple takes ~300MB to store the same data in list form (calculated using maple('evalf(kernelopts(bytesused)/1024/1024)')).  From this, I can conclude that I should create a memory dump from Maple to Matlab.

For the Maple to Matlab dump, each system of equation solves in the form:

Ans = {{ICE_T = 10, BAT_P = 30, EM2_T = 50, EM2_W = 30 ....}, {ICE_T = 10, BAT_P = 30, EM2_T = 50, EM2_W = 40....}}

I parse this in Matlab and store it in a dataset array:

ICE_T     BAT_P     EM2_T     EM2_W     ....
10          30           50           30
10          30           50           40
...

As for code, this is a simplified version of what I'm doing.  The following is a matlab script that calls the maple solver.  I've walked through the code in bold.

 

%Solve for the system symbolically.  Create a function, where inputs are the points are the grid values %where the system is to be evaluated.

maple('symb_sol:=unapply(eliminate(SystemEquations_NoDriver,NotDriverVars),[DriverVars])');

while tt < num_sys_eqs
%Increment and define solve range indexes
tt_min = tt+1;
tt_max = tt_min + Max_AnsVec_Size-1;
tt = tt_max;
if tt_max > num_sys_eqs
tt_max = num_sys_eqs;
end

%(Re)initalize answer vector (Free memory)
if tt_min == 1 || tt_max == num_sys_eqs
maple(['Ans:= Vector[column](',num2str(tt_max-tt_min+1),');']);
else
maple(['Ans:= Ans * 0']); %Free up the memory in the Answer vector
maple(['Ans:= Vector[column](',num2str(tt_max-tt_min+1),');']); %Initalize answer vector as the size of the block
end
disp(sprintf('Solving system %i to %i of %i',tt_min,tt_max,num_sys_eqs));

%Load points to evaluate symbolic function into maple
maple(['Contolpoints_vector := ', MatlabMatrix_toMapleMatrix(double(ControlPoints_Dataset(tt_min:tt_max,2:end))) ]);
maple(['BB_timevec := ', MatlabVec_to_MapleVec(ControlPoints_Dataset.time(tt_min:tt_max))]);
maple(['for i from 1 to Size(BB_timevec)[2] do ' ...
'BB_Driverlist_set(i):= convert(Equate(collected_component_input_eqs,Contolpoints_vector[i]),set) union {time = BB_timevec[i]}; ' ...
'od;']);

%Plug drivers into solver
maple(['' ...
'for i from 1 to Size(BB_timevec)[2] do ' ...
'Ans[i]:= symb_sol(Contolpoints_vector[i][])[1] union BB_Driverlist_set(i); ' ...
'od;']);

%Dump solutions
if tt_min == 1 %First one
LUT_initialized = 1;
%MapleToMatlabMemoryDump takes the maple list of solutions, and makes it into a matlab dataset
VehicleStateSpace_LUT = MapleToMatlabMemoryDump('Ans',int32(maple('Size(Ans)[1]')));
else
VehicleStateSpace_LUT = cat(1,VehicleStateSpace_LUT,MapleToMatlabMemoryDump('Ans',int32(maple('Size(Ans)[1]'))));
end

end

 

I've also tried passing the variable in one at at time instead of making a solver range of 50000.  This approach still causes crashes.

I'm open to any suggestions!

 

Edit:

If I add

disp(sprintf('Maple memory: %.0f MB', int32(maple('kernelopts(bytesalloc)/1024/1024'))))

inside the loop.  It shows Maple allocating more and more memory.  It doesn't plateau as I would expect.

 

@Joe Riel 

Thanks Kitonum for the reply.

Looking around I found a post similar to what I'm trying to do:

http://www.mapleprimes.com/questions/200157-How-To-Map-A-Function-To-A-List-Where.

I've tried map and the loop, and it doesn't seem like either of them have much a speed difference.

@Joe Riel 

Hi Joe, thanks for the response.

My the output of f is usually a set of solutions, ie:

{BAT_A = 2.310501372, BAT_V = 271, EM2_A = .4811661557, EM2_P = 130.3960282, EM2_T = -1, EM2_V = 271, EM2_W = 1, GEN_A = -2.791667528, GEN_P = -756.5419000, GEN_T = -10, GEN_V = 271, GEN_W = 100, ICE_mdot_g = 1000}

If you would like to take a look at the function, I've attached a worksheet.  The function f, is named 'symb_sol2()' in this case, and it has 4 inputs.  The list of inputs is 'inputvec'

Series_noGear.mw

I've tried preallocating an array for this, which gives me a 20% speedup.  The array type i use is of type 'anything'.  Watching Maple's memory in task manager shows that the memory will grow as the array fills up.  Is there a way to specify the size of each array element so I could preallocate the memory more efficiently?

@Carl Love 

Hi Carl,

Thanks for this approach!  It is more robust and computes faster than solve :)

Adam

Using the piecewise functions:

 

eq_c[3] := EM2_P = piecewise( EM2_T  =0,0,EM2_W = 0, 0, EM2_W*EM2_T < 0,-1 * EM2_ReqPow_eq, EM2_ReqPow_eq)

eq_c[5] := GEN_P = piecewise( GEN_T =0,0,GEN_W = 0, 0, GEN_W*GEN_T < 0,-1 * GEN_ReqPow_eq, GEN_ReqPow_eq);

 

results in 5 piecewise-solution having the conditions:

And(ICE_T*GB_R = 0, FD_T = 0)
And(ICE_T*GB_R = 0, 0 < FD_W*FD_T)
And(ICE_T*GB_R = 0, FD_W = 0, FD_T <> 0)
And(ICE_T*GB_R = 0, FD_T <> 0, FD_W <> 0, FD_W*FD_T <= 0)
Otherwise, []

this is not useful, as most of the places I will evaluate the problem are in the 'otherwise' condition.

I assume that reducing the number of piecewise functions would be useful to save solve time so I made the changes,  

eq_c[3] := EM2_P = piecewise( EM2_T  *EM2_W = 0, 0, EM2_W*EM2_T < 0,-1 * EM2_ReqPow_eq, EM2_ReqPow_eq)

eq_c[5] := GEN_P = piecewise( GEN_T *GEN_W = 0, 0, GEN_W*GEN_T < 0,-1 * GEN_ReqPow_eq, GEN_ReqPow_eq);

but now, evaluating the solve returns:

sol:=(solve(sys_eqs,not_drivers) assuming real)

     sol:=

which I assume means there is no solution.

 

@Carl Love 

Hi Carl,

Thanks!  This works great for my application!  Once again, Carl to the rescue :)

Adam

@Carl Love 

Hi Carl,

Thanks for the insight.  It is very helpful to know that this equation can be solved!  Unforunately, on my dual core 2.2Ghz, 4Gb RAM computer, I've run this for 4+ hours and it STILL hasn't solved.  Is there anything I can do to speed up the solve?  I'm thinking along the lines of using assume(), or refomulating my equations so that they solve quicker ...

Thanks again.  You've really been a great help.

Adam

@Carl Love This was exactly what I was looking for!  I forgot to mention that I had piecewise equations, but it still works with this approach.  Thank you!  You've saved me so much time =)

@Carl Love 

No, I am not using _Z as a variable.

Thank you Carl and Markiyan for the comment on RealDomain.  This is exactly what I was looking for.

1 2 Page 1 of 2