Debugging a fitness calculator with multiple nested IF statements - google-sheets

I'm using the Harris Benedict Equation to calculate people's TDEE. I'm using Google Sheets to create a sort of form for this but Google Sheets is sort of difficult to work with. I'm getting a formula parse error. Formatting is pretty bad sorry about that.
I know I'm making a small comma or parenthesis error somewhere but I'm not sure where.
The code is supposed to ask if people prefer metric/imperial, male/female, height, weight, activity level, and age.
Here's how Google Sheets does if statements. It pretty much is:
IF(A2 = "foo","A2 is foo")
Syntax is:
IF(logical_expression, value_if_true, value_if_false)
=IF (D9=”Imperial”,
IF(D10=”Male”,
IF(D16=”Sedentary (no exercise)”,
66 + ( 6.2 x D14 ) + ( 12.7 x (D13x12+G13) ) – ( 6.76 x D12 )x1.2,
IF(D16=”Lightly Active (1-3 days of exercise/week)”,
66 + ( 6.2 x D14 ) + ( 12.7 x (D13x12+G13) ) – ( 6.76 x D12 )x1.375,
IF(D16=”Moderately Active (3-5 days of exercise/week)”,
66 + ( 6.2 x D14 ) + ( 12.7 x (D13x12+G13) ) – ( 6.76 x D12 )x1.55,
IF(D16=”Very Active(6-7 days of exercise/week)”,
66 + ( 6.2 x D14 ) + ( 12.7 x (D13x12+G13) ) – ( 6.76 x D12 )x1.725,
IF(D16=”Extremely Active(exercise twice a day)”,
66 + ( 6.2 x D14 ) + ( 12.7 x (D13x12+G13) ) – ( 6.76 x D12 )x1.9,
“ “)))))
IF(D16=”Sedentary (no exercise)”,
655.1 + ( 4.35 x D14 ) + ( 4.7 x (D13x12+G13) ) - ( 4.7 x D12 ) x1.2,
IF(Lightly Active (1-3 days of exercise/week)”,
655.1 + ( 4.35 x D14 ) + ( 4.7 x (D13x12+G13) ) - ( 4.7 x D12 ) x1.375,
IF(Moderately Active (3-5 days of exercise/week)”,
655.1 + ( 4.35 x D14 ) + ( 4.7 x (D13x12+G13) ) - ( 4.7 x D12 ) x1.55,
IF(D16=”Very Active(6-7 days of exercise/week)”,
655.1 + ( 4.35 x D14 ) + ( 4.7 x (D13x12+G13) ) - ( 4.7 x D12 ) x1.725,
IF(D16=”Extremely Active(exercise twice a day)”,
655.1 + ( 4.35 x D14 ) + ( 4.7 x (D13x12+G13) ) - ( 4.7 x D12 ) x1.9,
“ “))))))
IF(D10=”Male”,
IF(D16=”Sedentary (no exercise)”,
66.5 + ( 13.75 x D14 ) + ( 5.003 x D13 ) – ( 6.755 x D12 )x1.2,
IF(Lightly Active (1-3 days of exercise/week)”,
66.5 + ( 13.75 x D14 ) + ( 5.003 x D13 ) – ( 6.755 x D12 )x1.375,
IF(Moderately Active (3-5 days of exercise/week)”,
66.5 + ( 13.75 x D14 ) + ( 5.003 x D13 ) – ( 6.755 x D12 )x1.55,
IF(D16=”Very Active(6-7 days of exercise/week)”
66.5 + ( 13.75 x D14 ) + ( 5.003 x D13 ) – ( 6.755 x D12 )x1.725,
IF(D16=”Extremely Active(exercise twice a day)”,
66.5 + ( 13.75 x D14 ) + ( 5.003 x D13 ) – ( 6.755 x D12 )x1.9,
“ “)))))
IF(D16=”Sedentary (no exercise)”,
655.1 + ( 9.563 x D14 ) + ( 1.850 x D13 ) – ( 4.676 x D12 ) x1.2,
IF(Lightly Active (1-3 days of exercise/week)”,
655.1 + ( 9.563 x D14 ) + ( 1.850 x D13 ) – ( 4.676 x D12 ) x1.375,
IF(Moderately Active (3-5 days of exercise/week)”,
655.1 + ( 9.563 x D14 ) + ( 1.850 x D13 ) – ( 4.676 x D12 ) x1.55,
IF(D16=”Very Active(6-7 days of exercise/week)”,
655.1 + ( 9.563 x D14 ) + ( 1.850 x D13 ) – ( 4.676 x D12 ) x1.725,
IF(D16=”Extremely Active(exercise twice a day)”,
655.1 + ( 9.563 x D14 ) + ( 1.850 x D13 ) – ( 4.676 x D12 ) x1.9,
“ “))))))
)

You have things like IF(Lightly Active (1-3 days of exercise/week)” which obviously aren't going to work. This sort of nesting of IFs shouldn't be there in the first place, it's a minefield of typos. Use hlookup or vlookup instead. Example of vlookup replacing five nested IFs:
=if(D9=”Imperial”,
if(D10=”Male”,
vlookup(D16, {
”Sedentary (no exercise)”,
66 + ( 6.2 x D14 ) + ( 12.7 x (D13x12+G13) ) – ( 6.76 x D12 )x1.2;
”Lightly Active (1-3 days of exercise/week)”,
66 + ( 6.2 x D14 ) + ( 12.7 x (D13x12+G13) ) – ( 6.76 x D12 )x1.375;
”Moderately Active (3-5 days of exercise/week)”,
66 + ( 6.2 x D14 ) + ( 12.7 x (D13x12+G13) ) – ( 6.76 x D12 )x1.55;
”Very Active(6-7 days of exercise/week)”,
66 + ( 6.2 x D14 ) + ( 12.7 x (D13x12+G13) ) – ( 6.76 x D12 )x1.725;
”Extremely Active(exercise twice a day)”,
66 + ( 6.2 x D14 ) + ( 12.7 x (D13x12+G13) ) – ( 6.76 x D12 )x1.9,
}, 2, false)
....
Notice that you can put 15 instead of 5 options here, and no new parentheses will be needed.
Depending on how your data is structured, you may be able to put this reference tables elsewhere in the sheet, say in Table!A1:B5, Table!A6:B11, etc:
=if(D9=”Imperial”,
if(D10=”Male”,
vlookup(D16, Table!A1:B5, 2, false),
vlookup(D16, Table!A6:B11, 2, false)
),
if(D10=”Male”,
vlookup(D16, Table!A12:B16, 2, false),
vlookup(D16, Table!A17:B21, 2, false)
)
)
One can wrap each vlookup in iferror so that when the input data is not of expected kind, you get blank output instead of #N/A! error (though the latter is more informative).

Related

Inverse Discrete Fourier Transform with Real to Real functions

I have a DFT (real_to_complex) output (5x8) that I want to inverse transform using r2r (real to real) functions, instead of iDFT, because the coefficients are all favorably real:
[0.000000] [0.000000] [0.000000] [0.000000] [0.000000]
[0.000000] [-0.000039] [-5.228421] [1.999998] [0.000000]
[0.000000] [10.456858] [-0.000000] [-0.329559] [0.000000]
[0.000000] [-6.000002] [0.494339] [-0.000000] [0.000000]
[0.000000] [0.000000] [0.000000] [0.000000] [0.000000]
[0.000000] [12.000002] [-2.471695] [2.402020] [0.000000]
[0.000000] [-31.370562] [4.000000] [-1.647797] [0.000000]
[0.000000] [81.597977] [-15.685284] [4.000000] [0.000000]
The problem is with symmetry, the X-axis is fine; following the pattern of odd-symmetric DST-I 0,a,b,c,0,-c,-b,-a (we don't see the -c,-b,-a because this is "real_to_complex" output ). However, the Y-axis is not following DST pattern or the DCT-I pattern a,b,c,d,e,d,c,b. I don't see it being symmetric however, because the coefficients are real and the output is real, we should be able to calculate this with only real values.
The iDFT 8x8 output is the following:
[1.694307] [1.331561] [0.590346] [-1.331561] [-2.874999] [-1.331561] [0.590346] [1.331561]
[1.331561] [1.625000] [1.256080] [-0.281785] [-2.168437] [-1.968213] [-0.419204] [0.624999]
[0.590346] [1.580797] [2.125001] [1.212098] [-0.840346] [-2.048974] [-1.875001] [-0.743921]
[-1.331561] [1.031788] [2.951028] [4.125000] [2.168437] [-1.875002] [-3.787904] [-3.281786]
[-2.874999] [-2.168437] [-0.840346] [2.168437] [4.555690] [2.168437] [-0.840346] [-2.168437]
[-1.331561] [-3.281786] [-3.787904] [-1.875002] [2.168437] [4.125000] [2.951028] [1.031788]
[0.590346] [-0.743921] [-1.875001] [-2.048974] [-0.840346] [1.212098] [2.125001] [1.580797]
[1.331561] [0.624999] [-0.419204] [-1.968213] [-2.168437] [-0.281785] [1.256080] [1.625000]
The complex_to_real DFT assumes complex conjugate symmetry for the 8*5 matrix.
When we expand this matrix into 8-point DFTs of Columns and Rows, the columns do not meet the odd symmetry criteria [0,a,b,c,0,-c,-b,-a] and as such seek contribution from the cosine basis, producing a complex value.
However when we examine the columns in frequency space, there is somewhat an odd symmetry amongst complex values.
In Matlab we define the matrix R1 as follows:
0 0 0 0 0 0 0 0
0 -0.000039 -5.228421 1.999998 0 -1.999998 5.228421 0.000039
0 10.456858 -0 -0.329559 0 0.329559 0 -10.456858
0 -6.000002 0.494339 -0 0 0 -0.494339 6.000002
0 0 0 0 0 0 0 0
0 12.000002 -2.471695 2.40202 0 -2.40202 2.471695 -12.000002
0 -31.370562 4 -1.647797 0 1.647797 -4 31.370562
0 81.597977 -15.685284 4 0 -4 15.685284 -81.597977
Then the colFFR2=ifft(R1 ) produces the output;
0.000000 + 0.000000i 8.335529 + 0.000000i -2.361383 + 0.000000i 0.8030828 + 0.000000i 0.000000 + 0.000000i -0.8030828 + 0.000000i 2.361383 + 0.000000i -8.335529 + 0.000000i
0.000000 + 0.000000i 6.681977 - 3.574877i -1.673753 + 0.6864277i 0.3180193 - 0.2243077i 0.000000 + 0.000000i -0.3180193 + 0.2243077i 1.673753 - 0.6864277i -6.681977 + 3.574877i
0.000000 + 0.000000i 2.614213 - 7.949751i -0.5000000 + 0.9363536i 0.2471695 + 0.05025225i 0.000000 + 0.000000i -0.2471695 - 0.05025225i 0.5000000 - 0.9363536i -2.614213 + 7.949751i
0.000000 + 0.000000i -6.681977 - 14.03173i 1.673753 + 1.686428i -0.3180193 - 0.5538672i 0.000000 + 0.000000i 0.3180193 + 0.5538672i -1.673753 - 1.686428i 6.681977 + 14.03173i
0.000000 + 0.000000i -13.56396 + 0.000000i 3.361383 + 0.000000i -1.297422 + 0.000000i 0.000000 + 0.000000i 1.297422 + 0.000000i -3.361383 + 0.000000i 13.56396 + 0.000000i
0.000000 + 0.000000i -6.681977 + 14.03173i 1.673753 - 1.686428i -0.3180193 + 0.5538672i 0.000000 + 0.000000i 0.3180193 - 0.5538672i -1.673753 + 1.686428i 6.681977 - 14.03173i
0.000000 + 0.000000i 2.614213 + 7.949751i -0.5000000 - 0.9363536i 0.2471695 - 0.05025225i 0.000000 + 0.000000i -0.2471695 + 0.05025225i 0.5000000 + 0.9363536i -2.614213 - 7.949751i
0.000000 + 0.000000i 6.681977 + 3.574877i -1.673753 - 0.6864277i 0.3180193 + 0.2243077i 0.000000 + 0.000000i -0.3180193 - 0.2243077i 1.673753 + 0.6864277i -6.681977 - 3.574877i
Finally ifft(colFFR2.', 'symmetric') provides the matching iDFT.

Decrease font size in "nodes near coords" in bar chart #tikzpicture #pgfplots

I was trying to decrease the size of the font in nodes near coords in the following code, but the only solution that I found to avoid the nodes numbers overlap was to decrease their number of decimal digits.
Any suggestions on how to decrease the font of nodes near coords ?
\newcommand{\figureHeight}{0.5625} %% 16:9
\pgfplotsset{
compat = 1.13,
grid = major,
enlarge x limits = 0,
cycle list name = tum,
major grid style = {dotted},
minor grid style = {dotted},
width = \hsize,
%width = \hsize * 0.9,
height = \hsize * 0.9 * \figureHeight,
legend style = { at = {(0.98,0.96)}, anchor = north east,}
}
\begin{figure}[thb]
\centering
\begin{tikzpicture}
\begin{axis}[
ybar = 5pt, % configures `bar shift'
xmajorgrids = false,
x tick label style = {
/pgf/number format/1000 sep =},
xtick = { 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018},
ylabel = Energy Produced in TWh,
enlarge x limits = 0.1,
ymin = 0,
ymax = 125,
bar width = 4pt,
legend style={at={(0.02,0.96)},anchor=north west},
nodes near coords
]
%Hidro
\addplot coordinates { ( 2011 , 18 ) ( 2012 , 21 ) ( 2013 , 23 ) ( 2014 , 19 ) ( 2015 , 19 ) ( 2016 , 21 ) ( 2017 , 20 ) ( 2018 , 19 )};
\addlegendentry{Hydro}
%Biomass
\addplot coordinates { ( 2011 , 34 ) ( 2012 , 40 ) ( 2013 , 41 ) ( 2014 , 43 ) ( 2015 , 44 ) ( 2016 , 45 ) ( 2017 , 45 ) ( 2018 , 45 )};
\addlegendentry{Biomass}
%Wind
\addplot coordinates { ( 2011 , 50 ) ( 2012 , 52 ) ( 2013 , 53 ) ( 2014 , 59 ) ( 2015 , 81 ) ( 2016 , 80 ) ( 2017 , 106 ) ( 2018 , 111 )};
\addlegendentry{Wind}
%Solar
\addplot coordinates { ( 2011 , 20 ) ( 2012 , 26 ) ( 2013 , 31 ) ( 2014 , 36 ) ( 2015 , 40 ) ( 2016 , 38 ) ( 2017 , 39 ) ( 2018 , 46 )};
\addlegendentry{Solar}
\end{axis}
\end{tikzpicture}
\caption{Energy from renewable sources in Germany}
\label{fig:EnergyFromRenewablesGermany}
\end{figure}
You can change the style with nodes near coords style={font=\tiny} (or whatever size you like)
\documentclass{book}
\usepackage{pgfplots}
\newcommand{\figureHeight}{0.5625} %% 16:9
\pgfplotsset{
compat = 1.13,
grid = major,
enlarge x limits = 0,
% cycle list name = tum,
major grid style = {dotted},
minor grid style = {dotted},
width = \hsize,
%width = \hsize * 0.9,
height = \hsize * 0.9 * \figureHeight,
legend style = { at = {(0.98,0.96)}, anchor = north east,},
}
\begin{document}
\begin{figure}[thb]
\centering
\begin{tikzpicture}
\begin{axis}[
ybar = 5pt, % configures `bar shift'
xmajorgrids = false,
x tick label style = {
/pgf/number format/1000 sep =},
xtick = { 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018},
ylabel = Energy Produced in TWh,
enlarge x limits = 0.1,
ymin = 0,
ymax = 125,
bar width = 4pt,
legend style={at={(0.02,0.96)},anchor=north west},
nodes near coords,
nodes near coords style={font=\tiny}
]
%Hidro
\addplot coordinates { ( 2011 , 18 ) ( 2012 , 21 ) ( 2013 , 23 ) ( 2014 , 19 ) ( 2015 , 19 ) ( 2016 , 21 ) ( 2017 , 20 ) ( 2018 , 19 )};
\addlegendentry{Hydro}
%Biomass
\addplot coordinates { ( 2011 , 34 ) ( 2012 , 40 ) ( 2013 , 41 ) ( 2014 , 43 ) ( 2015 , 44 ) ( 2016 , 45 ) ( 2017 , 45 ) ( 2018 , 45 )};
\addlegendentry{Biomass}
%Wind
\addplot coordinates { ( 2011 , 50 ) ( 2012 , 52 ) ( 2013 , 53 ) ( 2014 , 59 ) ( 2015 , 81 ) ( 2016 , 80 ) ( 2017 , 106 ) ( 2018 , 111 )};
\addlegendentry{Wind}
%Solar
\addplot coordinates { ( 2011 , 20 ) ( 2012 , 26 ) ( 2013 , 31 ) ( 2014 , 36 ) ( 2015 , 40 ) ( 2016 , 38 ) ( 2017 , 39 ) ( 2018 , 46 )};
\addlegendentry{Solar}
\end{axis}
\end{tikzpicture}
\caption{Energy from renewable sources in Germany}
\label{fig:EnergyFromRenewablesGermany}
\end{figure}
\end{document}

Weird crash on present modally a view controller on iOS 7

I developed an app using a iOS 9 device for testing and everything is fine, but I need the compatibility with iOS 7 also.
At the start I load a view controller with some buttons, one of them should present modally another controller but on iOS 7 device I get a very weird crash:
Objective: {objective 0x165f98c0: <> +
<750:-6.61817e-08>*0x16569cd0.negError{id: 118} +
<999:2>*0x16569ec0.negError{id: 175} + <999:2>0x16570520.negError{id:
172} + <999:1>_UILayoutGuide:0x1655a6c0.Width{id: 176} +
<999:1>*_UILayoutGuide:0x165a3c70.Width{id: 173}} 2016-04-27
15:38:07.483 191PerTe[502:60b] *** Terminating app due to uncaught
exception 'NSInternalInconsistencyException', reason: '{ Rows: 0x16569ec0.posErrorMarker{id: 174} == 0 +
1*0x16569ec0.negError{id: 175} + 1*_UILayoutGuide:0x1655a6c0.Width{id:
176} 0x16570520.posErrorMarker{id: 171} == 0 +
1*0x16570520.negError{id: 172} + 1*_UILayoutGuide:0x165a3c70.Width{id:
173} UITransitionView:0x165a21d0.Height{id: 159} == 960 +
1*0x165f11b0.marker{id: 150} + 2*0x1655ed20.marker{id: 168}
UITransitionView:0x165a21d0.Width{id: 154} == 640 +
1*0x1655f650.marker{id: 164} UITransitionView:0x165a21d0.minX{id:
162} == 0 + 2*0x1658f790.marker{id: 161} + -0.5*0x1655f650.marker{id:
164} UITransitionView:0x165a21d0.minY{id: 163} == 0 +
2*0x1655f080.marker{id: 167} + -1*0x1655ed20.marker{id: 168}
UIView:0x1659fb60.Height{id: 185} == 960 + 1*0x165f11b0.marker{id:
150} + 2*0x1655ed20.marker{id: 168} + 2*0x16559660.marker{id: 194}
UIView:0x1659fb60.Width{id: 188} == 640 + 1*0x1655f650.marker{id:
164} + 2*0x1656b160.marker{id: 190} UIView:0x1659fb60.minX{id: 187}
== 0 + 2*0x165596b0.marker{id: 186} + -1*0x1656b160.marker{id: 190} UIView:0x1659fb60.minY{id: 189} == 0 + 2*0x1656b190.marker{id: 193} +
-1*0x16559660.marker{id: 194} UIWindow:0x165a6fe0.Height{id: 141} == 960 + 1*0x165f11b0.marker{id: 150} UIWindow:0x165a6fe0.Width{id: 136}
== 640 + 1*0x165ae3a0.marker{id: 147} UIWindow:0x165a6fe0.minX{id: 144} == 0 + 2*0x16588c90.marker{id: 143} + -0.5*0x165ae3a0.marker{id:
147} UIWindow:0x165a6fe0.minY{id: 146} == 0 + 2*0x165f4e20.marker{id:
145} + -0.5*0x165f11b0.marker{id: 150}
_UILayoutGuide:0x1655a6c0.Height{id: 182} == 0 +
1*0x1656c6a0.marker{id: 181} _UILayoutGuide:0x1655a6c0.minY{id: 184}
== 960 + 1*0x165f11b0.marker{id: 150} + 2*0x1655ed20.marker{id: 168} + -1*0x1656c6a0.marker{id: 181} + 1*0x1656b5f0.marker{id: 183} + 2*0x16559660.marker{id: 194} _UILayoutGuide:0x165a3c70.Height{id:
178} == 40 + 1*0x1656af20.marker{id: 177}
_UILayoutGuide:0x165a3c70.minY{id: 180} == 0 +
1*0x165676a0.marker{id: 179} objective{id: 1} == {objective
0x165f98c0: <> + <750:-6.61817e-08>*0x16569cd0.negError{id: 118} +
<999:2>*0x16569ec0.negError{id: 175} + <999:2>0x16570520.negError{id:
172} + <999:1>_UILayoutGuide:0x1655a6c0.Width{id: 176} +
<999:1>*_UILayoutGuide:0x165a3c70.Width{id: 173}}
Constraints: Marker:0x16559660.marker{id: 194}
Marker:0x165596b0.marker{id: 186}
(Integralization adjustment:3.20747e-06)
Marker:0x1655ed20.marker{id: 168}
Marker:0x1655f080.marker{id: 167}
Marker:0x1655f650.marker{id:
164} Marker:0x1656b160.marker{id: 190}
(Integralization adjustment:6.41495e-06)
Marker:0x1656b190.marker{id: 193}
Marker:0x1658f790.marker{id: 161}
Marker:0x165ae3a0.marker{id: 147}
Marker:0x165f11b0.marker{id: 150}
<_UILayoutSupportConstraint:0x165676a0
V:|-(0)-[_UILayoutGuide:0x165a3c70] (Names: '|':UIView:0x1659fb60
)> Marker:0x165676a0.marker{id: 179}
<_UILayoutSupportConstraint:0x16569ec0
H:[_UILayoutGuide:0x1655a6c0(0#999)]
priority:999> Marker:0x16569ec0.posErrorMarker{id: 174}
<_UILayoutSupportConstraint:0x1656af20
V:[_UILayoutGuide:0x165a3c70(20)]> Marker:0x1656af20.marker{id: 177}
<_UILayoutSupportConstraint:0x1656b5f0
_UILayoutGuide:0x1655a6c0.bottom == UIView:0x1659fb60.bottom> Marker:0x1656b5f0.marker{id: 183}
<_UILayoutSupportConstraint:0x1656c6a0
V:[_UILayoutGuide:0x1655a6c0(0)]> Marker:0x1656c6a0.marker{id: 181}
<_UILayoutSupportConstraint:0x16570520
H:[_UILayoutGuide:0x165a3c70(0#999)]
priority:999> Marker:0x16570520.posErrorMarker{id: 171}
<_UIWindowAnchoringConstraint:0x16588c90 h=--- v=---
UIWindow:0x165a6fe0.midX == + 160> Marker:0x16588c90.marker{id: 143}
<_UIWindowAnchoringConstraint:0x165f4e20 h=--- v=---
UIWindow:0x165a6fe0.midY == + 240> Marker:0x165f4e20.marker{id: 145}
Integralization Adjustments: 0x165596b0.marker{id: 186}
[] ->
0.000003 0x1656b160.marker{id: 190} [] ->
0.000006
Statistics: 18 rows. Variable counts:
1 -> 6
2 -> 10
3 -> 1
5 -> 1 }: internal error. Cannot find an outgoing row head for incoming head 0x16569cd0.negError{id: 118}, which should never
happen.'
*** First throw call stack: (0x2f3cef83 0x39b7fccf 0x2f3ceec5 0x2fd3a315 0x2fd39e57 0x2fd35b95 0x31beacd3 0x31e832ab 0x31be9bc1
0x31d02f4f 0x31c23d57 0x31c23c73 0x31870111 0x3a06781f 0x3a067777
0x2f3998a1 0x2f398175 0x2f302ebf 0x2f302ca3 0x34208663 0x31c4f14d
0x28f3f 0x3a08cab7) libc++abi.dylib: terminating with uncaught
exception of type NSException (lldb)
I already tried to:
disable size classes
reset all constraints on the other controller, present modally a blank view controller
obviously everything is working on iOS 8/9
Some advice?

Try to simulate a neural network in MATLAB by myself

I tried to create a neural network to estimate y = x ^ 2. So I created a fitting neural network and gave it some samples for input and output. I tried to build this network in C++. But the result is different than I expected.
With the following inputs:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 -1
-2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71
and the following outputs:
0 1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289 324 361 400
441 484 529 576 625 676 729 784 841 900 961 1024 1089 1156 1225 1296
1369 1444 1521 1600 1681 1764 1849 1936 2025 2116 2209 2304 2401 2500
2601 2704 2809 2916 3025 3136 3249 3364 3481 3600 3721 3844 3969 4096
4225 4356 4489 4624 4761 4900 5041 1 4 9 16 25 36 49 64 81 100 121 144
169 196 225 256 289 324 361 400 441 484 529 576 625 676 729 784 841
900 961 1024 1089 1156 1225 1296 1369 1444 1521 1600 1681 1764 1849
1936 2025 2116 2209 2304 2401 2500 2601 2704 2809 2916 3025 3136 3249
3364 3481 3600 3721 3844 3969 4096 4225 4356 4489 4624 4761 4900 5041
I used fitting tool network. with matrix rows. Training is 70%, validation is 15% and testing is 15% as well. The number of hidden neurons is two. Then in command lines I wrote this:
purelin(net.LW{2}*tansig(net.IW{1}*inputTest+net.b{1})+net.b{2})
Other information :
My net.b[1] is: -1.16610230053776 1.16667147712026
My net.b[2] is: 51.3266249426358
And net.IW(1) is: 0.344272596370387 0.344111217766824
net.LW(2) is: 31.7635369693519 -31.8082184881063
When my inputTest is 3, the result of this command is 16, while it should be about 9. Have I made an error somewhere?
I found the Stack Overflow post Neural network in MATLAB that contains a problem like my problem, but there is a little difference, and the differences is in that problem the ranges of input and output are same, but in my problem is no. That solution says I need to scale out the results, but how can I scale out my result?
You are right about scaling. As was mentioned in the linked answer, the neural network by default scales the input and output to the range [-1,1]. This can be seen in the network processing functions configuration:
>> net = fitnet(2);
>> net.inputs{1}.processFcns
ans =
'removeconstantrows' 'mapminmax'
>> net.outputs{2}.processFcns
ans =
'removeconstantrows' 'mapminmax'
The second preprocessing function applied to both input/output is mapminmax with the following parameters:
>> net.inputs{1}.processParams{2}
ans =
ymin: -1
ymax: 1
>> net.outputs{2}.processParams{2}
ans =
ymin: -1
ymax: 1
to map both into the range [-1,1] (prior to training).
This means that the trained network expects input values in this range, and outputs values also in the same range. If you want to manually feed input to the network, and compute the output yourself, you have to scale the data at input, and reverse the mapping at the output.
One last thing to remember is that each time you train the ANN, you will get different weights. If you want reproducible results, you need to fix the state of the random number generator (initialize it with the same seed each time). Read the documentation on functions like rng and RandStream.
You also have to pay attention that if you are dividing the data into training/testing/validation sets, you must use the same split each time (probably also affected by the randomness aspect I mentioned).
Here is an example to illustrate the idea (adapted from another post of mine):
%%# data
x = linspace(-71,71,200); %# 1D input
y_model = x.^2; %# model
y = y_model + 10*randn(size(x)).*x; %# add some noise
%%# create ANN, train, simulate
net = fitnet(2); %# one hidden layer with 2 nodes
net.divideFcn = 'dividerand';
net.trainParam.epochs = 50;
net = train(net,x,y);
y_hat = net(x);
%%# plot
plot(x, y, 'b.'), hold on
plot(x, x.^2, 'Color','g', 'LineWidth',2)
plot(x, y_hat, 'Color','r', 'LineWidth',2)
legend({'data (noisy)','model (x^2)','fitted'})
hold off, grid on
%%# manually simulate network
%# map input to [-1,1] range
[~,inMap] = mapminmax(x, -1, 1);
in = mapminmax('apply', x, inMap);
%# propagate values to get output (scaled to [-1,1])
hid = tansig( bsxfun(#plus, net.IW{1}*in, net.b{1}) ); %# hidden layer
outLayerOut = purelin( net.LW{2}*hid + net.b{2} ); %# output layer
%# reverse mapping from [-1,1] to original data scale
[~,outMap] = mapminmax(y, -1, 1);
out = mapminmax('reverse', outLayerOut, outMap);
%# compare against MATLAB output
max( abs(out - y_hat) ) %# this should be zero (or in the order of `eps`)
I opted to use the mapminmax function, but you could have done that manually as well. The formula is a pretty simply linear mapping:
y = (ymax-ymin)*(x-xmin)/(xmax-xmin) + ymin;

Criteria: "undefined offset"

i have this schema below, i have generated the classes using symfony
and created a pair of objects using the form class generated.
moto:
marca: { type: varchar(255), required: true }
matricula: { type: integer, required: true }
Now i have this criteria:
$c = new Criteria();
$c->addSelectColumn('MAX('.MotoPeer::MATRICULA.')');
$max_matricula = MotoPeer::doSelect($c);
var_dump($max_matricula);
return $max_matricula;
When i call the criteria code It works ok, but these three notices
below are showed.
Any idea?
sf 1.4/propel 1.4
( ! ) Notice: Undefined offset: 2 in
/opt/lampp/htdocs/prueba/lib/
model/om/BaseMotoPeer.php on line 379
Call Stack
Time Memory Function Location 1 0.0008 328076
{main}( ) ../frontend_dev.php:0
2 0.1974 4333236
sfContext->dispatch( )
../frontend_dev.php:13 3 0.1974
4333264
sfFrontWebController->dispatch( )
../ sfContext.class.php:170 4
0.1981 4350256 sfController->forward( ) ../
sfFrontWebController.class.php:48 5
0.2134 4641000 sfFilterChain->execute( )
../sfController.class.php: 238 6
0.2138 4641808 sfRenderingFilter->execute( )
../ sfFilterChain.class.php:53 7
0.2138 4641808 sfFilterChain->execute( ) ../
sfRenderingFilter.class.php:33 8
0.2143 4642588 sfExecutionFilter->execute( )
../ sfFilterChain.class.php:53 9
0.2144 4643308 sfExecutionFilter->handleAction( )
../ sfExecutionFilter.class.php:42 10
0.2144 4643308 sfExecutionFilter->executeAction( )
../ sfExecutionFilter.class.php:78 11
0.2144 4643336 sfActions->execute( ) ../sfExecutionFilter.class.php: 92 12
0.2147 4644160 motoActions->executePrueba( )
../sfActions.class.php: 60 13
0.2212 5026172 MotoPeer::prueba( ) ../actions.class.php:14 14 0.2254
5285592 BaseMotoPeer::doSelect( )
../MotoPeer.php:26 15 0.2493
5756176 BaseMotoPeer::populateObjects(
) ../BaseMotoPeer.php: 241 16
0.2493 5756568 BaseMotoPeer::getPrimaryKeyHashFromRow(
) ../ BaseMotoPeer.php:400
( ! ) Notice: Undefined offset: 1 in
/opt/lampp/htdocs/prueba/lib/
model/om/BaseMoto.php on line 184 Call
Stack
Time Memory Function Location 1 0.0008 328076
{main}( ) ../frontend_dev.php:0
2 0.1974 4333236
sfContext->dispatch( )
../frontend_dev.php:13 3 0.1974
4333264
sfFrontWebController->dispatch( )
../ sfContext.class.php:170 4
0.1981 4350256 sfController->forward( ) ../
sfFrontWebController.class.php:48 5
0.2134 4641000 sfFilterChain->execute( )
../sfController.class.php: 238 6
0.2138 4641808 sfRenderingFilter->execute( )
../ sfFilterChain.class.php:53 7
0.2138 4641808 sfFilterChain->execute( ) ../
sfRenderingFilter.class.php:33 8
0.2143 4642588 sfExecutionFilter->execute( )
../ sfFilterChain.class.php:53 9
0.2144 4643308 sfExecutionFilter->handleAction( )
../ sfExecutionFilter.class.php:42 10
0.2144 4643308 sfExecutionFilter->executeAction( )
../ sfExecutionFilter.class.php:78 11
0.2144 4643336 sfActions->execute( ) ../sfExecutionFilter.class.php: 92 12
0.2147 4644160 motoActions->executePrueba( )
../sfActions.class.php: 60 13
0.2212 5026172 MotoPeer::prueba( ) ../actions.class.php:14 14 0.2254
5285592 BaseMotoPeer::doSelect( )
../MotoPeer.php:26 15 0.2493
5756176 BaseMotoPeer::populateObjects(
) ../BaseMotoPeer.php: 241 16
0.2578 5953424 BaseMoto->hydrate( ) ../BaseMotoPeer.php:408
( ! ) Notice: Undefined offset: 2 in
/opt/lampp/htdocs/prueba/lib/
model/om/BaseMoto.php on line 185 Call
Stack
Time Memory Function Location 1 0.0008 328076
{main}( ) ../frontend_dev.php:0
2 0.1974 4333236
sfContext->dispatch( )
../frontend_dev.php:13 3 0.1974
4333264
sfFrontWebController->dispatch( )
../ sfContext.class.php:170 4
0.1981 4350256 sfController->forward( ) ../
sfFrontWebController.class.php:48 5
0.2134 4641000 sfFilterChain->execute( )
../sfController.class.php: 238 6
0.2138 4641808 sfRenderingFilter->execute( )
../ sfFilterChain.class.php:53 7
0.2138 4641808 sfFilterChain->execute( ) ../
sfRenderingFilter.class.php:33 8
0.2143 4642588 sfExecutionFilter->execute( )
../ sfFilterChain.class.php:53 9
0.2144 4643308 sfExecutionFilter->handleAction( )
../ sfExecutionFilter.class.php:42 10
0.2144 4643308 sfExecutionFilter->executeAction( )
../ sfExecutionFilter.class.php:78 11
0.2144 4643336 sfActions->execute( ) ../sfExecutionFilter.class.php: 92 12
0.2147 4644160 motoActions->executePrueba( )
../sfActions.class.php: 60 13
0.2212 5026172 MotoPeer::prueba( ) ../actions.class.php:14 14 0.2254
5285592 BaseMotoPeer::doSelect( )
../MotoPeer.php:26 15 0.2493
5756176 BaseMotoPeer::populateObjects(
) ../BaseMotoPeer.php: 241 16
0.2578 5953424 BaseMoto->hydrate( ) ../BaseMotoPeer.php:408
EDIT: the first notice appears because i didn't write "id: ~" before the fields of the model. Here it goes the lines that causes the second and the third notices:
/**
* Hydrates (populates) the object variables with values from the database resultset.
*
* An offset (0-based "start column") is specified so that objects can be hydrated
* with a subset of the columns in the resultset rows. This is needed, for example,
* for results of JOIN queries where the resultset row includes columns from two or
* more tables.
*
* #param array $row The row returned by PDOStatement->fetch(PDO::FETCH_NUM)
* #param int $startcol 0-based offset column which indicates which restultset column to start with.
* #param boolean $rehydrate Whether this object is being re-hydrated from the database.
* #return int next starting column
* #throws PropelException - Any caught Exception will be rewrapped as a PropelException.
*/
public function hydrate($row, $startcol = 0, $rehydrate = false)
{
try {
var_dump($row);
$this->id = ($row[$startcol + 0] !== null) ? (int) $row[$startcol + 0] : null;
$this->marca = ($row[$startcol + 1] !== null) ? (string) $row[$startcol + 1] : null;//184
$this->matricula = ($row[$startcol + 2] !== null) ? (int) $row[$startcol + 2] : null;//185
I think, the second and the third notices are showed because in the criteria I'm just getting one column (maatricula). But how to do it so?
Javier
If you use the "AddSelectColumn" method:
$c->addSelectColumn('MAX('.MotoPeer::MATRICULA.')');
you cannot hydrate the object - you are not selecting all the columns. Hence do not call:
MotoPeer::doSelect($c);
Instead do this:
$c->addSelectColumn('MAX('.MotoPeer::MATRICULA.')');
$stmt = MotoPeer::doSelectStmt($c);
$max_matricula = $stmt->fetchColumn(0);
Here you execute the SQL statement and fetch the single value that you're interested in into the variable $max_matricula.

Resources