


extract information from solver result structure
Syntax: [outX outY] = extractDataFromPbeResult(taskString, propertyHandle, ...
resultStruct, pbeDefinition)
This function generates vectors or matrices that can be used to plot data
obtained by solvePbe. Therefore, the taskString specifies the type of
output where the task parameter selects a state variable, a property or
gives a custom function handle.
The following tasks return a time vector and a value vector of some kind:
bulkProperty - for taskParameter being an integer, the bulk property
defined in pbeDefinition is used. The taskParameter can also be a
function handle used for bulk properties in solvePbe @(P, N, x, t).
bulkState - the taskParameter is interpretet as an index to the state
vector.
integralProperty - taskParameter is the string 'number' or a string of
a measure contained in pbeDef.dec.measureData. The integral of that
measure (first row of Y) ingluding its standard deviation (second row
of Y) is calculated.
genericIntegral - the taskParameter is interpreted as a function handle
@(H, up), output is given as above.
propertyDistribution - task parameter is a cell array where {1} gives
the desired measure used on the y-axis of the distribution and {2}
gives the measure on the x-axis. {3} contains a matrix where the
first row represents the lower bound of each bin and the second row
the upper bound. Whether these bins overlap, are continuous between
two limits or where the pivot point is is not considered.
See also: solvePbe, executePbeCase, loadPbeCase

0001 function [outX, outY] = extractDataFromPbeResult(taskString, taskParameter, ... 0002 resultStruct, pbeDef) 0003 % extract information from solver result structure 0004 % 0005 % Syntax: [outX outY] = extractDataFromPbeResult(taskString, propertyHandle, ... 0006 % resultStruct, pbeDefinition) 0007 % 0008 % This function generates vectors or matrices that can be used to plot data 0009 % obtained by solvePbe. Therefore, the taskString specifies the type of 0010 % output where the task parameter selects a state variable, a property or 0011 % gives a custom function handle. 0012 % 0013 % The following tasks return a time vector and a value vector of some kind: 0014 % bulkProperty - for taskParameter being an integer, the bulk property 0015 % defined in pbeDefinition is used. The taskParameter can also be a 0016 % function handle used for bulk properties in solvePbe @(P, N, x, t). 0017 % bulkState - the taskParameter is interpretet as an index to the state 0018 % vector. 0019 % integralProperty - taskParameter is the string 'number' or a string of 0020 % a measure contained in pbeDef.dec.measureData. The integral of that 0021 % measure (first row of Y) ingluding its standard deviation (second row 0022 % of Y) is calculated. 0023 % genericIntegral - the taskParameter is interpreted as a function handle 0024 % @(H, up), output is given as above. 0025 % propertyDistribution - task parameter is a cell array where {1} gives 0026 % the desired measure used on the y-axis of the distribution and {2} 0027 % gives the measure on the x-axis. {3} contains a matrix where the 0028 % first row represents the lower bound of each bin and the second row 0029 % the upper bound. Whether these bins overlap, are continuous between 0030 % two limits or where the pivot point is is not considered. 0031 % 0032 % See also: solvePbe, executePbeCase, loadPbeCase 0033 0034 % The elk-library: convex geometry applied to crystallization modeling. 0035 % Copyright (C) 2012 Alexander Reinhold 0036 % 0037 % This program is free software: you can redistribute it and/or modify it 0038 % under the terms of the GNU General Public License as published by the 0039 % Free Software Foundation, either version 3 of the License, or (at your 0040 % option) any later version. 0041 % 0042 % This program is distributed in the hope that it will be useful, but 0043 % WITHOUT ANY WARRANTY; without even the implied warranty of 0044 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0045 % General Public License for more details. 0046 % 0047 % You should have received a copy of the GNU General Public License along 0048 % with this program. If not, see <http://www.gnu.org/licenses/>. 0049 0050 %% catch empty result 0051 if isempty(resultStruct) 0052 error('elk:pbeSolver:wrongInput', 'PBE result structure is empty') 0053 end 0054 0055 %% for measure computation 0056 % mappingToMeasComputation = eye(pbeDef.dec.nC); 0057 % if pbeDef.dec.isProper || ~pbeDef.optionStruct.useEmbeddingPartitions 0058 % dec = pbeDef.dec; 0059 % elseif pbeDef.dec.isComplete 0060 % dec = pbeDef.dec.properData; 0061 % mappingToMeasComputation = pbeDef.dec.properData.mappingNewToProper; 0062 % else 0063 % % incomplete dec 0064 % dec = pbeDef.dec; 0065 % end 0066 dec = pbeDef.dec; 0067 0068 switch lower(taskString) 0069 %% bulk property 0070 case 'bulkproperty' 0071 if isa(taskParameter, 'function_handle') 0072 % given function handle evaluates bulk property 0073 thisFunHandle = @(info)(taskParameter(info.P, info.N, ... 0074 info.x, info.time)); 0075 0076 elseif (taskParameter > 0) && (mod(taskParameter, 1) == 0) 0077 % taskString indicates existing property 0078 thisFunHandle = @(info)(subsref(... 0079 pbeDef.bulkProperty(info.P, info.N, info.x, info.time), ... 0080 struct('type', '()', 'subs', {{taskParameter}}))); 0081 0082 else 0083 error('elk:pbeSolver:wrongInput', ['task parameter ' ... 0084 'must be a function handle or a positive integer']); 0085 end 0086 [outX, outY] = obtainTimeEvolution(... 0087 resultStruct, thisFunHandle); 0088 0089 %% bulk state 0090 case 'bulkstate' 0091 if (taskParameter > 0) && (mod(taskParameter, 1) == 0) 0092 % taskString indicates existing state 0093 thisFunHandle = @(info)(info.x(taskParameter)); 0094 else 0095 error('elk:pbeSolver:wrongInput', ['task parameter ' ... 0096 'must be a positive integer']); 0097 end 0098 [outX, outY] = obtainTimeEvolution(... 0099 resultStruct, thisFunHandle); 0100 0101 %% master integral evaluation 0102 case 'masterintegral' 0103 % integral: note that the core integral is already evaluated as 0104 % extra information so that it is easily reused for the error 0105 % estimates. The real integral is, therefore, given in the last 0106 % line of this case. 0107 thisFunHandle = @(info)([info.extra(end).data; ... 0108 sqrt(info.nSample/(info.nSample-1) * (... 0109 sum((... 0110 info.extra(end-1).data .* ... 0111 (ones(size(info.extra(end-1).data, 1), 1)*info.N) - ... 0112 (info.extra(end).data*... 0113 ones(1, size(info.extra(end-1).data, 2)))/info.nSample ... 0114 ).^2, 2) + ... 0115 info.nZero/info.nSample.^2*info.extra(end).data.^2 ... 0116 ))]); 0117 0118 % allow for multiple parameter input 0119 if ~iscell(taskParameter) 0120 taskParameter = {taskParameter}; 0121 end 0122 % call the subroutine that crawls through the time steps in 0123 % resultStruct. This line also includes the evaluation of the 0124 % integral 0125 [outX, outY] = obtainTimeEvolution(... 0126 resultStruct, thisFunHandle, taskParameter{:}, ... 0127 @(info)(info.extra(end).data*info.N')); 0128 0129 %% integral property (generic) 0130 case 'genericintegralproperty' 0131 % integrand 0132 integrandHandle = @(info)(taskParameter(info.H, info.up)); 0133 % evaluate 0134 [outX, outY] = extractDataFromPbeResult('masterIntegral', ... 0135 integrandHandle, resultStruct, pbeDef); 0136 0137 %% integal property (string, index) 0138 case 'integralproperty' 0139 % integrand 0140 if strcmpi(taskParameter, 'number') 0141 integrandHandle = @(info)(ones(size(info.N))); 0142 elseif ischar(taskParameter) 0143 integrandHandle = @(info)(computeMeasureDec(dec, 'hC', ... 0144 {info.up, info.H}, taskParameter, [], 0, 1)); 0145 elseif iscell(taskParameter) 0146 integrandHandle = @(info)(computeMeasureDec(dec, 'hC', ... 0147 {info.up, info.H}, {taskParameter{1}, taskParameter{2}}, [], 0, 1)); 0148 elseif isnumeric(taskParameter) && taskParameter == 0 0149 integrandHandle = @(info)(info.H); 0150 elseif isnumeric(taskParameter) && taskParameter < 0 0151 disp('yup') 0152 integrandHandle = @(info)(info.H(-1*taskParameter, :)); 0153 else 0154 integrandHandle = @(info)(info.P(taskParameter, :)); 0155 end 0156 % evaluate 0157 [outX, outY] = extractDataFromPbeResult('masterIntegral', ... 0158 integrandHandle, resultStruct, pbeDef); 0159 0160 %% property distribution 0161 case 'propertydistribution' 0162 % yAxis property 0163 if ~ischar(taskParameter{1}) 0164 yAxisHandle = @(info)(info.P(taskParameter{1}, :)); 0165 elseif strcmpi(taskParameter{1}, 'number') 0166 yAxisHandle = @(info)(ones(size(info.N))); 0167 else 0168 yAxisHandle = @(info)(computeMeasureDec(dec, 'hC', ... 0169 {info.up, info.H(1:pbeDef.nDecCoordinate,:)}, taskParameter{1}, [], 0, 1)); 0170 end 0171 % xAxis property 0172 if ~ischar(taskParameter{2}) 0173 xAxisHandle = @(info)(info.P(taskParameter{2}, :)); 0174 elseif strcmpi(taskParameter{2}, 'number') 0175 xAxisHandle = @(info)(ones(size(info.N))); 0176 else 0177 xAxisHandle = @(info)(computeMeasureDec(dec, 'hC', ... 0178 {info.up, info.H(1:pbeDef.nDecCoordinate,:)}, taskParameter{2}, [], 0, 1)); 0179 end 0180 % integrand: time evolution will evaluate yAxisProperty and 0181 % xAxisProperty in info.extra(1).data and info.extra(2) so that 0182 % the integrand can be constructed on these information. The 0183 % integrand looks like: 0184 % yProperty*(xProperty > lowerBound)*(xProperty <= upperBound) 0185 % Now consider that yProperty is the vector as given by 0186 % yAxisHandle. While yProperty is a row vector, the boundary 0187 % filters can be written as matrices that are multiplied from the 0188 % right: 0189 % yProperty*boundaryFilterMatrix 0190 % so that the result of the integral will become a column vector. 0191 % Hence, we construct the boundary filter, first. 0192 boundaryFilter = @(info)(... 0193 bsxfun(@gt, info.extra(2).data, taskParameter{3}(1,:)') .* ... 0194 bsxfun(@le, info.extra(2).data, taskParameter{3}(2,:)')); 0195 % integrand 0196 integrandHandle = @(info)(info.extra(3).data .* ... 0197 (ones(size(info.extra(3).data, 1), 1)*info.extra(1).data)); 0198 % call master integral 0199 [outX, outY] = extractDataFromPbeResult('masterIntegral', ... 0200 {yAxisHandle, xAxisHandle, boundaryFilter, integrandHandle}, ... 0201 resultStruct, pbeDef); 0202 % make density values 0203 size(outY) 0204 size(taskParameter{3}(2,:)) 0205 outY = bsxfun(@rdivide, outY, ... 0206 [(taskParameter{3}(2,:) - taskParameter{3}(1,:))'; 0207 (taskParameter{3}(2,:) - taskParameter{3}(1,:))']); 0208 0209 0210 otherwise 0211 error('elk:populationBalance:wrongInput', 'Specified task is unknown.') 0212 end 0213 0214 end