Vector-valued ParametricNDSolve, solving for a combination

Define a quadratic form matrix:

form = {
    {0, 0, 0, 0, 0, 1},
    {0, 0, 0, 0, -1, 0},
    {0, 0, 0, 1, 0, 0},
    {0, 0, 1, 0, 0, 0},
    {0, -1, 0, 0, 0, 0},
    {1, 0, 0, 0, 0, 0}
};

Then:

YZsol2 = ParametricNDSolveValue[
    {Y'[x] == F[x,q,Y[x]], Y[xa]==Y0,
    Z'[x] == 1/k F[k x+c,q,Z[x]], Z[xa]==Z0},
    Y[xm] . form . Z[xm],
    {x,xa,xm},
    q
];

will produce the desired function. For example:

YZsol2 /@ Range[0, 4]
psi /@ Range[0, 4]

{-24.1853, -148.784, -6240.84, -7841.06, 12815.}

{-24.1853, -148.784, -6240.84, -7841.06, 12815.}

Another possibility is to include your desired output as an additional equation (constraint):

YZsol3 = ParametricNDSolveValue[
    {
    Y'[x] == F[x,q,Y[x]], Y[xa]==Y0,
    Z'[x] == 1/k F[k x+c,q,Z[x]], Z[xa]==Z0,
    U[x] == Y[x] . form . Z[x]
    },
    U[xm],
    {x,xa,xm},
    q
];

Check:

YZsol3 /@ Range[0, 4]

{-24.1853, -148.784, -6240.84, -7841.06, 12815.}

Note that there is a bug as of June 2019 with using this inside a FindRoot, which makes it much slower unless we add Method -> {"ParametricSensitivity" -> None} as detailed in Vector ParametricNDSolve and FindRoot interaction).


A hybrid of yours and @CarlWoll's approach seems to perform well after FindRoot.

Clear[YZsol, psi2]
form = Reverse@DiagonalMatrix@PadRight[{}, 6, {1, -1, 1}];
YZsol = ParametricNDSolveValue[{Y'[x] == F[x, q, Y[x]], Y[xa] == Y0, 
    Z'[x] == 1/k F[k x + c, q, Z[x]], Z[xa] == Z0}, {Y, Z}, {x, xa, 
    xm}, q];
psi2[q_?NumericQ] := (Y.form.Z) /. {Y :> YZsol[q][[1]][xm], 
    Z :> YZsol[q][[2]][xm]};
FindRoot[psi2[q], {q, 3}] 
AbsoluteTiming[psi2 /@ Range[20]]

Clear[YZsol2];
YZsol2 = ParametricNDSolveValue[{Y'[x] == F[x, q, Y[x]], Y[xa] == Y0, 
    Z'[x] == 1/k F[k x + c, q, Z[x]], Z[xa] == Z0}, 
   Y[xm].form.Z[xm], {x, xa, xm}, q];
AbsoluteTiming[YZsol2 /@ Range[20]]


Clear[YZsol3]; YZsol3 = 
 ParametricNDSolveValue[{Y'[x] == F[x, q, Y[x]], Y[xa] == Y0, 
   Z'[x] == 1/k F[k x + c, q, Z[x]], Z[xa] == Z0}, 
  Y[xm].form.Z[xm], {x, xa, xm}, q];
FindRoot[YZsol3[q], {q, 3}];
AbsoluteTiming[YZsol3 /@ Range[20]]
(* {q -> 3.55393} *)
(* {0.279002, {-148.784, -6240.84, -7841.06, 12815., 63393.7, 
  134180., 197976., 214749., 
  139054., -71335.6, -446840., -998422., -1.71155*10^6, -2.5422*10^6, \
-3.41516*10^6, -4.22468*10^6, -4.83742*10^6, -5.09767*10^6, \
-4.83432*10^6, -3.86961*10^6}} *)
(* {0.337883, {-148.784, -6240.84, -7841.06, 12815., 63393.7, 
  134180., 197976., 214749., 
  139054., -71335.6, -446840., -998422., -1.71155*10^6, -2.5422*10^6, \
-3.41516*10^6, -4.22468*10^6, -4.83742*10^6, -5.09767*10^6, \
-4.83432*10^6, -3.86961*10^6}} *)
(* {2.20664, {-148.785, -6240.83, -7841.05, 12815., 63393.6, 
  134180., 197976., 214748., 
  139054., -71335.6, -446840., -998421., -1.71155*10^6, -2.5422*10^6, \
-3.41516*10^6, -4.22467*10^6, -4.83742*10^6, -5.09767*10^6, \
-4.83432*10^6, -3.86961*10^6}} *)