How is the best way to integrate using loops - integration

I'm using Mathematica, and I want to integrate a function f[wr] in wr using some method that works with a Table/Do/For in the variable wr.
I tried to use something like the Riemann's sum, to evaluate the function in some point wr_0 times the spacing (in this case 0.01). The problem is that wr depends on "[Micro]" and for each value of Micro, the integral in wr would change its limits (from [Micro] - 50*kt to [Micro] + 50*kt).
kb = 8.61*10^-5;
Te = 300;
kt = kb*Te;
sum = 0;
sum1 = 0;
data = Table[
{
Table[
{
sum = sum + (f[wr]*0.01);
sum1 = sum1 + (f[wr]*(wr - \[Micro])*0.01);
}
, {wr, \[Micro] - 50*kt, \[Micro] + 50*kt, 0.01}];
\[Micro], sum1/(Te*sum)
}
, {\[Micro], -0.4, 0.4, 0.1}];
I think this code, is not doing what I want. That is, for each value of Micro, calculate the integral (sum1 and sum) for a range of wr's and store, then for other value of Micro, do it all again, at the end i want the output of the quotient of these integrals. How could I implement that?

Related

Converting cell coordinates without using a column number to column letter method?

I'm trying to figure out what my options are here when I need to use a column number in a formula, and if I really need to write a column number to column letter method to accomplish what I'm trying to do.
See this method I have here:
createFormulas(lookupField, lookupColumns) {
// Iterate through the lookupColumn array
lookupColumns.forEach(value => {
let columnNumber = this.getColumn(this.headers, value);
let range = this.sheet.getRange(2, columnNumber, this.lastRow - 1, 1);
// range.setFormula('=$A2');
range.setFormula('=' + columnNumber + '2' ); // doesn't work obviously
})
}
I'm trying to add formulas in a column based on the column.
this.getColumn() returns the column number based on the column name being passed in.
let range sets the range I want to set the formula in
range.setFormula('=$A2') pastes this formula into range and updates the reference accordingly (i.e., $A3, $A4, etc.). This isn't the formula I ultimately want to use, just a simplified example.
I need to set the column in the reference dynamically, however.
What I have obviously won't work: range.setFormula('=' + columnNumber + '2' );. That would just result in something like 72 where 7 is the column number.
I know I can write a method that will convert the column number into a letter. I'm just surprised there isn't a built in method for doing that or some other native way of accomplishing this.
For example, in Excel VBA I think you can do something like "=" & Cells(2, columnNumber).Address or something like that (been a while, I could be wrong), which should equate to =A2, =A3, =A4, etc. in the range.
So before writing this column number to letter method, I just wanted to check: is that the only way to accomplish what I'm after or is there a native way of handling this that I'm just not seeing?
Actually, was able to do this using .getA1Notation().
Refactored to the following and it works as expected:
createFormulas(lookupField, lookupColumns) {
// Iterate through the lookupColumn array
lookupColumns.forEach(value => {
let columnNumber = this.getColumn(this.headers, value);
let formulaRange = this.sheet.getRange(2, columnNumber, this.lastRow - 1, 1);
let referenceRange = this.sheet.getRange(2, this.idColumn, this.lastRow - 1, 1);
formulaRange.setFormula("=" + referenceRange.getCell(1, 1).getA1Notation());
})
}
Column To Letters
I followed Yuri's path to the numbers to letter functions and I'm a bit baffled that we have forgotten that there are 26 letters in the alphabet and so after looking at the various functions at that reference none of them seem to have worked for me. So here's my replacement:
function colToletters(num) {
let a = " ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (num < 27) return a[num % a.length];
if (num > 26) {
num--;
let letters = '';
while (num >= 0) {
letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[num % 26] + letters;
num = Math.floor(num / 26) - 1;
}
return letters;
}
}
This will calculate the column letters for 1 to 1000 and I check all the way to 703 where the letters go to AAA and they look good all the way.
Just in case. Based on https://stackoverflow.com/a/64456745/14265469
function numberToLetters(num) {
// num--; // if you need 1 --> A, 2 --> B, 26 --> Z
let letters = '';
while (num >= 0) {
letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[num % 26] + letters;
num = (num - num % 26) / 26 - 1;
}
return letters;
}
console.log(numberToLetters(0)); // --> A
console.log(numberToLetters(25)); // --> Z
console.log(numberToLetters(26)); // --> AA

Percentage Calculation In SSRS

when i am calculating like given below in SSRS 2008
=SUM(IIF(Fields!REMARKS.Value = "GOOD",1,0))/((SUM(IIF(Fields!REMARKS.Value = "GOOD",1,0))+ SUM(IIF(Fields!REMARKS.Value = "BAD",1,0))))*100
getting result like 34.9632565235
but i am trying to get result like 34.97%
Please share your expertise.
Thanks
Try:
=FORMAT(
SUM(IIF(Fields!REMARKS.Value = "GOOD",1,0))/
((SUM(IIF(Fields!REMARKS.Value = "GOOD",1,0)) +
SUM(IIF(Fields!REMARKS.Value = "BAD",1,0)))),"P2")
Or you can use a custom string format:
=FORMAT(
SUM(IIF(Fields!REMARKS.Value = "GOOD",1,0)) /
((SUM(IIF(Fields!REMARKS.Value = "GOOD",1,0)) +
SUM(IIF(Fields!REMARKS.Value = "BAD",1,0)))*100)
,"0.00") & "%"
Let me know if this helps.
You can also use the Round function in your expression. With this function =ROUND(..., 1) you will have one number after the decimal point. If you want two numbers after the decimal point then enter 2, and so on. (So you need 2).
Also check the link : Percentage SSRS
Where the example is used :
=Round(((SUM(Fields!FirstCallResolution.Value) / COUNT(Fields!CommunicationId.Value)) * 100),1)

Remove NaN in Nested iif in SSRS expression

New to SQL-SSRS
How do I add functionality to the below code to change returned NaN values to 0 or blank? What I think is happening is in situations that the sum of Agreed and Disagreed = 0 I am getting this Nan. I think this would be easier for me if I wasnt dealing with the Agreed and Disagreed categories. Again, new to SQL programming. Any help would be greatly appreciated.
=(Sum(iif(Fields!Response.Value = "Agreed",Fields!Days.Value,0)) + Sum(iif(Fields!Response.Value = "Disagreed",Fields!Days.Value,0)))/(Sum(iif(Fields!Response.Value = "Agreed",Fields!Fq.Value,0)) + Sum(iif(Fields!Response.Value = "Disagreed",Fields!Fq.Value,0)))
Try something like below,
=Replace((Sum(IIF(Fields!Response.Value = "Agreed",Fields!Days.Value,0)) +
Sum(IIF(Fields!Response.Value = "Disagreed",Fields!Days.Value,0))),"NaN","0")
/ Replace((Sum(IIF(Fields!Response.Value = "Agreed",Fields!Fq.Value,0))
+ Sum(IIF(Fields!Response.Value = "Disagreed",Fields!Fq.Value,0))),"NaN","0")
Also, look at this
Rather than replacing the text returned from dividing by zero, you should handle the DIV 0 issue in the expression:
=IIF(
SUM(IIF(Fields!Response.Value = "Agreed" OR Fields!Response.Value = "Disagreed", Fields!Fq.Value, 0)) = 0, 0,
SUM(IIF(Fields!Response.Value = "Agreed" OR Fields!Response.Value = "Disagreed", Fields!Days.Value, 0)))
/IIF(
SUM(IIF(Fields!Response.Value = "Agreed" OR Fields!Response.Value = "Disagreed", Fields!Fq.Value, 0)) = 0, 1,
SUM(IIF(Fields!Response.Value = "Agreed" OR Fields!Response.Value = "Disagreed", Fields!Fq.Value, 0)))
If the SUM is zero, the calculation is 0 / 1 otherwise it's the SUM(Days) / SUM(Fq) where the Response is Agreed or Disagreed.
And rather than two sum, just use an OR in the one.
Public Function Divider (ByVal Dividend As Double, ByVal Divisor As Double)
If IsNothing(Divisor) Or Divisor = 0
Return 0
Else
Return Dividend/Divisor
End If
End Function
this function enables you to write a custom code which fixes all problems with Nan .
this can be called by below
=Code.Divider(Fields!FieldA.Value, Fields!FieldB.Value)
your code is as below
=Code.Divider(((Sum(iif(Fields!Response.Value = "Agreed",Fields!Days.Value,0)) + Sum(iif(Fields!Response.Value = "Disagreed",Fields!Days.Value,0))), ((Sum(iif(Fields!Response.Value = "Agreed",Fields!Fq.Value,0)) + Sum(iif(Fields!Response.Value = "Disagreed",Fields!Fq.Value,0)))))

Matlab fminsearch options/restrictions

I have this function in Matlab which is supposed to find the smallest value possible for minValuePossible, by varying the two initial set values of inValues. How can I set the fmin search function to NOT try negative values while trying to find the minimum? Also how can I set the number of different variations the fminsearch function performs while trying to find the minimum? Because currently it tries somewhere around 20 different combinations of the two inValues and then completes. Maybe define the amount by which it changes each value? How would I do that?
function Valueminimiser
inValues = [50,50];
minValuePossible = fminsearch(#minimiser, inValues);
function result = minimiser(inValues)
x=inValues(1);
y=inValues(2);
RunMode = 2;
ValueOne = x;
ValueTwo = y;
[maxSCRAout] = main(RunMode,ValueOne,ValueTwo);
result = minValuePossible;
end
end
How can I set the fmin search function to NOT try negative values while trying to find the minimum?
Add the constrains of the values of your minimiser function at its beginning. If you meet this constrains then return a huge function value of minimizer. This will prevent fminsearch consider numbers which are not in your interest:
function result = minimiser(inValues)
if (sum(inValues < 0) > 1) % check if there is any negative number in input variable
result = hugeValue; % give a big value to the result
return; % return to fminsearch - do not execute the rest of the code
end
x=inValues(1);
y=inValues(2);
RunMode = 2;
ValueOne = x;
ValueTwo = y;
[maxSCRAout] = main(RunMode,ValueOne,ValueTwo);
result = minValuePossible;
Also how can I set the number of different variations the fminsearch function performs while trying to find the minimum?
You can define options of fminsearch by using optimset function. The parameter of optimset 'MaxFunEvals' is the maximum number of evaluations -- notice that this cout even the values you constrained, so maybe setting 'TolX' as advised by #slayton might be better if you are concerned about the accuarcy.
options = optimset('MaxFunEvals',numberOfVariations);
minValuePossible = fminsearch(#minimiser, inValues,options);
The docs for fminsearch don't describe a way to restrict the domain of the function you want to minimize.
If you want to restrict the range to all non-negative numbers then you can simply wrap your function in a call to abs, depending on the syntax .
minValuePossible = fminsearch( #(x)(minimiser( abs(x) ) ), inValues);
If you are worried about it constantly converging to the same minima then try a variety of different initial values.
Lastly you can alter the termination tolerances for X and minValuePossible using the TolX and TolFun input parameters. This is done with standard param value syntax: function(...., 'Param', value)
fminsearch( #(x)(minimiser(abs(x))), inValues, 'TolX', x_tolerance);

Tips for function inside while loop and i=i+1, Matlab

I have a problem with a function in matlab. This specific function is for filtering light signals. As you can see below I added the coding I’ve used in the function and in the while loop itself. The code is written for a NXT Lego robot.
Is there any tip how to get the count variable ( i = i + 1 ) to work in the function, so we can plot Light(i)? Because we’re getting a bunch of error messages when we try different codes to make it work.
function [light] = filter_func( i)
lightI(i) = GetLight(SENSOR_3);
if i==1
light(i)=lightI(i)
elseif i==2
light(i) = 0.55*lightI(i) + 0.45*lightI(i-1)
else
light(i) = 0.4*lightI(i) + 0.3*lightI(i-1) + 0.3*lightI(i-2);
end
end
i=1
while true
lightI(i) = GetLight(SENSOR_3); % Get’s a lightvalue between 0 and 1024.
if i>2
light =filter_func(i)
light=round(light);
else
light(i) = GetLight(SENSOR_3);;
end
i=1+i
plot(light(end-90:end), 'r-');
title('Lightvalue')
axis([0 100 0 1023]) ;
end
You probably mainly get errors because you are not allowed to mix script and functions like this in MATLAB (like you are in Python).
Your filter function is only used when i>2 so why are you doing the first 2 tests? It seems like you want lightI as a global variable, but that is not what you have done. The lightI inside the function is not the same as the one in the while loop.
Since your while loop runs forever, maybe you don't need to worry about updating the plot the first two times. In that case you can do this:
filter = [0.4 0.3 0.3]';
latest_filtered_light = nan(90,1);
lightI = [];
p = plot(latest_filtered_light, 'r-');
title('Lightvalue')
axis([0 100 0 1023]) ;
while True
lightI(end+1,1) = rand*1024; % Get’s a lightvalue between 0 and 1024.
if i>=3
new_val = lightI(end-2:end,1)'*filter;
latest_filtered_light = [latest_filtered_light(2:end);...
new_val];
set(p, 'ydata', latest_filtered_light)
drawnow
end
end
I think it is an important point to not call plot every time - at least if you are the least concerned about performance.